source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/examples/snmp/snmp_private_mib/lwip_prvmib.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.4 KB
Line 
1/**
2 * @file
3 * lwip Private MIB
4 *
5 * @todo create MIB file for this example
6 * @note the lwip enterprise tree root (26381) is owned by the lwIP project.
7 * It is NOT allowed to allocate new objects under this ID (26381) without our,
8 * the lwip developers, permission!
9 *
10 * Please apply for your own ID with IANA: http://www.iana.org/numbers.html
11 *
12 * lwip OBJECT IDENTIFIER ::= { enterprises 26381 }
13 * example OBJECT IDENTIFIER ::= { lwip 1 }
14 */
15
16/*
17 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without modification,
21 * are permitted provided that the following conditions are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright notice,
24 * this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright notice,
26 * this list of conditions and the following disclaimer in the documentation
27 * and/or other materials provided with the distribution.
28 * 3. The name of the author may not be used to endorse or promote products
29 * derived from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
32 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
34 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40 * OF SUCH DAMAGE.
41 *
42 * Author: Christiaan Simons <christiaan.simons@axon.tv>
43 */
44
45#include "private_mib.h"
46
47#if LWIP_SNMP
48
49/** Directory where the sensor files are */
50#define SENSORS_DIR "w:\\sensors"
51/** Set to 1 to read sensor values from files (in directory defined by SENSORS_DIR) */
52#define SENSORS_USE_FILES 0
53/** Set to 1 to search sensor files at startup (in directory defined by SENSORS_DIR) */
54#define SENSORS_SEARCH_FILES 0
55
56#if SENSORS_SEARCH_FILES
57#include <sys/stat.h>
58#include <sys/types.h>
59#include <unistd.h>
60#include <fcntl.h>
61#include <dirent.h>
62#endif /* SENSORS_SEARCH_FILES */
63
64#include <string.h>
65#include <stdio.h>
66
67#include "lwip/apps/snmp_table.h"
68#include "lwip/apps/snmp_scalar.h"
69
70#if !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES
71/** When not using & searching files, defines the number of sensors */
72#define SENSOR_COUNT 4
73#endif /* !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES */
74
75/*
76 This example presents a table for a few (at most 10) sensors.
77 Sensor detection takes place at initialization (once only).
78 Sensors may and can not be added or removed after agent
79 has started. Note this is only a limitation of this crude example,
80 the agent does support dynamic object insertions and removals.
81
82 You'll need to manually create a directory called "sensors" and
83 a few single line text files with an integer temperature value.
84 The files must be called [0..9].txt.
85
86 ./sensors/0.txt [content: 20]
87 ./sensors/3.txt [content: 75]
88
89 The sensor values may be changed in runtime by editing the
90 text files in the "sensors" directory.
91*/
92
93#define SENSOR_MAX 10
94#define SENSOR_NAME_LEN 20
95
96struct sensor_inf
97{
98 u8_t num;
99
100 char file[SENSOR_NAME_LEN + 1];
101
102#if !SENSORS_USE_FILES
103 /** When not using files, contains the value of the sensor */
104 s32_t value;
105#endif /* !SENSORS_USE_FILES */
106};
107
108static struct sensor_inf sensors[SENSOR_MAX];
109
110static s16_t sensor_count_get_value(struct snmp_node_instance* instance, void* value);
111static snmp_err_t sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
112static snmp_err_t sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
113static s16_t sensor_table_get_value(struct snmp_node_instance* instance, void* value);
114static snmp_err_t sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value);
115
116/* sensorentry .1.3.6.1.4.1.26381.1.1.1 (.level0.level1)
117 where level 0 is the table column (temperature/file name)
118 and level 1 the table row (sensor index) */
119static const struct snmp_table_col_def sensor_table_columns[] = {
120 { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE },
121 { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }
122};
123
124/* sensortable .1.3.6.1.4.1.26381.1.1 */
125static const struct snmp_table_node sensor_table = SNMP_TABLE_CREATE(
126 1, sensor_table_columns,
127 sensor_table_get_cell_instance, sensor_table_get_next_cell_instance,
128 sensor_table_get_value, snmp_set_test_ok, sensor_table_set_value);
129
130/* sensorcount .1.3.6.1.4.1.26381.1.2 */
131static const struct snmp_scalar_node sensor_count = SNMP_SCALAR_CREATE_NODE_READONLY(
132 2, SNMP_ASN1_TYPE_INTEGER, sensor_count_get_value);
133
134/* example .1.3.6.1.4.1.26381.1 */
135static const struct snmp_node* const example_nodes[] = {
136 &sensor_table.node.node,
137 &sensor_count.node.node
138};
139static const struct snmp_tree_node example_node = SNMP_CREATE_TREE_NODE(1, example_nodes);
140
141static const u32_t prvmib_base_oid[] = { 1,3,6,1,4,1,26381,1 };
142const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &example_node.node);
143
144#if 0
145/* for reference: we could also have expressed it like this: */
146
147/* lwip .1.3.6.1.4.1.26381 */
148static const struct snmp_node* const lwip_nodes[] = {
149 &example_node.node
150};
151static const struct snmp_tree_node lwip_node = SNMP_CREATE_TREE_NODE(26381, lwip_nodes);
152
153/* enterprises .1.3.6.1.4.1 */
154static const struct snmp_node* const enterprises_nodes[] = {
155 &lwip_node.node
156};
157static const struct snmp_tree_node enterprises_node = SNMP_CREATE_TREE_NODE(1, enterprises_nodes);
158
159/* private .1.3.6.1.4 */
160static const struct snmp_node* const private_nodes[] = {
161 &enterprises_node.node
162};
163static const struct snmp_tree_node private_root = SNMP_CREATE_TREE_NODE(4, private_nodes);
164
165static const u32_t prvmib_base_oid[] = { 1,3,6,1,4 };
166const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &private_root.node);
167#endif
168
169/**
170 * Initialises this private MIB before use.
171 * @see main.c
172 */
173void
174lwip_privmib_init(void)
175{
176#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
177 char *buf, *ebuf, *cp;
178 size_t bufsize;
179 int nbytes;
180 struct stat sb;
181 struct dirent *dp;
182 int fd;
183#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
184 u8_t i;
185#endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
186
187 memset(sensors, 0, sizeof(sensors));
188
189 printf("SNMP private MIB start, detecting sensors.\n");
190
191#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
192 /* look for sensors in sensors directory */
193 fd = open(SENSORS_DIR, O_RDONLY);
194 if (fd > -1)
195 {
196 fstat(fd, &sb);
197 bufsize = sb.st_size;
198 if (bufsize < (size_t)sb.st_blksize)
199 {
200 bufsize = sb.st_blksize;
201 }
202 buf = (char*)malloc(bufsize);
203 if (buf != NULL)
204 {
205 do
206 {
207 long base;
208
209 nbytes = getdirentries(fd, buf, bufsize, &base);
210 if (nbytes > 0)
211 {
212 ebuf = buf + nbytes;
213 cp = buf;
214 while (cp < ebuf)
215 {
216 dp = (struct dirent *)cp;
217 if (lwip_isdigit(dp->d_name[0]))
218 {
219 unsigned char idx = dp->d_name[0] - '0';
220
221 sensors[idx].num = idx+1;
222 strncpy(&sensors[idx].file[0], dp->d_name, SENSOR_NAME_LEN);
223 printf("%s\n", sensors[idx].file);
224 }
225 cp += dp->d_reclen;
226 }
227 }
228 }
229 while (nbytes > 0);
230
231 free(buf);
232 }
233 close(fd);
234 }
235#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
236 for (i = 0; i < SENSOR_COUNT; i++) {
237 sensors[i].num = (u8_t)(i + 1);
238 snprintf(sensors[i].file, sizeof(sensors[i].file), "%d.txt", i);
239
240#if !SENSORS_USE_FILES
241 /* initialize sensor value to != zero */
242 sensors[i].value = 11 * (i+1);
243#endif /* !SENSORS_USE_FILES */
244 }
245#endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */
246}
247
248/* sensorcount .1.3.6.1.4.1.26381.1.2 */
249static s16_t
250sensor_count_get_value(struct snmp_node_instance* instance, void* value)
251{
252 size_t count = 0;
253 u32_t *uint_ptr = (u32_t*)value;
254
255 LWIP_UNUSED_ARG(instance);
256
257 for(count=0; count<LWIP_ARRAYSIZE(sensors); count++) {
258 if(sensors[count].num == 0) {
259 *uint_ptr = (u32_t)count;
260 return sizeof(*uint_ptr);
261 }
262 }
263
264 return 0;
265}
266
267/* sensortable .1.3.6.1.4.1.26381.1.1 */
268/* list of allowed value ranges for incoming OID */
269static const struct snmp_oid_range sensor_table_oid_ranges[] = {
270 { 1, SENSOR_MAX+1 }
271};
272
273static snmp_err_t
274sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance)
275{
276 u32_t sensor_num;
277 size_t i;
278
279 LWIP_UNUSED_ARG(column);
280
281 /* check if incoming OID length and if values are in plausible range */
282 if(!snmp_oid_in_range(row_oid, row_oid_len, sensor_table_oid_ranges, LWIP_ARRAYSIZE(sensor_table_oid_ranges))) {
283 return SNMP_ERR_NOSUCHINSTANCE;
284 }
285
286 /* get sensor index from incoming OID */
287 sensor_num = row_oid[0];
288
289 /* find sensor with index */
290 for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
291 if(sensors[i].num != 0) {
292 if(sensors[i].num == sensor_num) {
293 /* store sensor index for subsequent operations (get/test/set) */
294 cell_instance->reference.u32 = (u32_t)i;
295 return SNMP_ERR_NOERROR;
296 }
297 }
298 }
299
300 /* not found */
301 return SNMP_ERR_NOSUCHINSTANCE;
302}
303
304static snmp_err_t
305sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance)
306{
307 size_t i;
308 struct snmp_next_oid_state state;
309 u32_t result_temp[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
310
311 LWIP_UNUSED_ARG(column);
312
313 /* init struct to search next oid */
314 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(sensor_table_oid_ranges));
315
316 /* iterate over all possible OIDs to find the next one */
317 for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
318 if(sensors[i].num != 0) {
319 u32_t test_oid[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
320
321 test_oid[0] = sensors[i].num;
322
323 /* check generated OID: is it a candidate for the next one? */
324 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(sensor_table_oid_ranges), (void*)i);
325 }
326 }
327
328 /* did we find a next one? */
329 if(state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
330 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
331 /* store sensor index for subsequent operations (get/test/set) */
332 cell_instance->reference.u32 = LWIP_CONST_CAST(u32_t, state.reference);
333 return SNMP_ERR_NOERROR;
334 }
335
336 /* not found */
337 return SNMP_ERR_NOSUCHINSTANCE;
338}
339
340static s16_t
341sensor_table_get_value(struct snmp_node_instance* instance, void* value)
342{
343 u32_t i = instance->reference.u32;
344 s32_t *temperature = (s32_t *)value;
345
346 switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id))
347 {
348 case 1: /* sensor value */
349#if SENSORS_USE_FILES
350 FILE* sensf;
351 char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
352
353 strncpy(&senspath[sizeof(SENSORS_DIR)],
354 sensors[i].file,
355 SENSOR_NAME_LEN);
356 sensf = fopen(senspath,"r");
357 if (sensf != NULL)
358 {
359 fscanf(sensf,"%"S32_F,temperature);
360 fclose(sensf);
361 }
362#else /* SENSORS_USE_FILES */
363 *temperature = sensors[i].value;
364#endif /* SENSORS_USE_FILES */
365 return sizeof(s32_t);
366 case 2: /* file name */
367 MEMCPY(value, sensors[i].file, strlen(sensors[i].file));
368 return (s16_t)strlen(sensors[i].file);
369 default:
370 return 0;
371 }
372}
373
374static snmp_err_t
375sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
376{
377 u32_t i = instance->reference.u32;
378 s32_t *temperature = (s32_t *)value;
379#if SENSORS_USE_FILES
380 FILE* sensf;
381 char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
382
383 strncpy(&senspath[sizeof(SENSORS_DIR)],
384 sensors[i].file,
385 SENSOR_NAME_LEN);
386 sensf = fopen(senspath, "w");
387 if (sensf != NULL)
388 {
389 fprintf(sensf, "%"S32_F, *temperature);
390 fclose(sensf);
391 }
392#else /* SENSORS_USE_FILES */
393 sensors[i].value = *temperature;
394#endif /* SENSORS_USE_FILES */
395
396 LWIP_UNUSED_ARG(len);
397
398 return SNMP_ERR_NOERROR;
399}
400
401#endif /* LWIP_SNMP */
Note: See TracBrowser for help on using the repository browser.