and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / Rmon / alarm.c
1 /**************************************************************
2  * Copyright (C) 2001 Alex Rozin, Optical Access
3  * 
4  *                     All Rights Reserved
5  * 
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation for any purpose and without fee is hereby granted,
8  * provided that the above copyright notice appear in all copies and that
9  * both that copyright notice and this permission notice appear in
10  * supporting documentation. 
11  * 
12  * ALEX ROZIN DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
14  * ALEX ROZIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
15  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
16  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
17  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
18  * SOFTWARE. 
19  ******************************************************************/
20
21 #include <stdlib.h>
22 #include <sys/time.h>
23 #include <unistd.h>
24 #include <net-snmp/net-snmp-config.h>
25 #include <net-snmp/net-snmp-includes.h>
26 #include <net-snmp/agent/net-snmp-agent-includes.h>
27 #include "util_funcs.h"
28 #include "alarm.h"
29     /*
30      * Implementation headers 
31      */
32 #include "agutil_api.h"
33 #include "row_api.h"
34     /*
35      * File scope definitions section 
36      */
37     /*
38      * from MIB compilation 
39      */
40 #define alarmEntryFirstIndexBegin       11
41 #define MMM_MAX                         0xFFFFFFFFl
42 #define IDalarmIndex                    1
43 #define IDalarmInterval                 2
44 #define IDalarmVariable                 3
45 #define IDalarmSampleType               4
46 #define IDalarmValue                    5
47 #define IDalarmStartupAlarm             6
48 #define IDalarmRisingThreshold          7
49 #define IDalarmFallingThreshold         8
50 #define IDalarmRisingEventIndex         9
51 #define IDalarmFallingEventIndex        10
52 #define IDalarmOwner                    11
53 #define IDalarmStatus                   12
54 #define MIN_alarmEventIndex             0
55 #define MAX_alarmEventIndex             65535
56      typedef enum {
57          SAMPLE_TYPE_ABSOLUTE =
58              1,
59          SAMPLE_TYPE_DELTE
60      } SAMPLE_TYPE_T;
61
62      typedef enum {
63          ALARM_NOTHING =
64              0,
65          ALARM_RISING,
66          ALARM_FALLING,
67          ALARM_BOTH
68      } ALARM_TYPE_T;
69
70      typedef struct {
71          u_long
72              interval;
73          u_long
74              timer_id;
75          VAR_OID_T
76              var_name;
77          SAMPLE_TYPE_T
78              sample_type;
79          ALARM_TYPE_T
80              startup_type;      /* RISING | FALLING | BOTH */
81
82          u_long
83              rising_threshold;
84          u_long
85              falling_threshold;
86          u_long
87              rising_event_index;
88          u_long
89              falling_event_index;
90
91          u_long
92              last_abs_value;
93          u_long
94              value;
95          ALARM_TYPE_T
96              prev_alarm;        /* NOTHING | RISING | FALLING */
97      } CRTL_ENTRY_T;
98
99 /*
100  * Main section 
101  */
102
103      static TABLE_DEFINTION_T
104          AlarmCtrlTable;
105      static TABLE_DEFINTION_T *
106          table_ptr = &
107          AlarmCtrlTable;
108
109 #if 0                           /* KUKU */
110      static u_long
111          kuku_sum =
112          0,
113          kuku_cnt =
114          0;
115 #endif
116
117 /*
118  * find & enjoy it in event.c 
119  */
120      extern int
121      event_api_send_alarm(u_char is_rising,
122                           u_long alarm_index,
123                           u_long event_index,
124                           oid * alarmed_var,
125                           size_t alarmed_var_length,
126                           u_long sample_type,
127                           u_long value,
128                           u_long the_threshold, char *alarm_descr);
129
130      static int
131      fetch_var_val(oid * name, size_t namelen, u_long * new_value)
132 {
133     netsnmp_subtree *tree_ptr;
134     size_t          var_len;
135     WriteMethod    *write_method;
136     struct variable called_var;
137     register struct variable *s_var_ptr;
138     register int    iii;
139     register u_char *access;
140
141
142     tree_ptr = netsnmp_subtree_find(name, namelen, NULL, "");
143     if (!tree_ptr) {
144         return SNMP_ERR_NOSUCHNAME;
145     }
146
147     memcpy(called_var.name, tree_ptr->name_a,
148            tree_ptr->namelen * sizeof(oid));
149     s_var_ptr = tree_ptr->variables;
150     for (iii = 0; iii < tree_ptr->variables_len; iii++) {
151         if (s_var_ptr->namelen) {
152             if (0 >= snmp_oidtree_compare(name + tree_ptr->namelen,
153                                           namelen - tree_ptr->namelen,
154                                           s_var_ptr->name,
155                                           s_var_ptr->namelen)) {
156                 memcpy(called_var.name + tree_ptr->namelen,
157                        s_var_ptr->name, s_var_ptr->namelen * sizeof(oid));
158                 called_var.namelen =
159                     tree_ptr->namelen + s_var_ptr->namelen;
160                 called_var.type = s_var_ptr->type;
161                 called_var.magic = s_var_ptr->magic;
162                 called_var.acl = s_var_ptr->acl;
163                 called_var.findVar = s_var_ptr->findVar;
164
165                 access =
166                     (*(s_var_ptr->findVar)) (&called_var, name, &namelen,
167                                              1, &var_len, &write_method);
168                 if (access
169                     && snmp_oid_compare(name, namelen, tree_ptr->end_a,
170                                         tree_ptr->end_len) > 0) {
171                     memcpy(name, tree_ptr->end_a, tree_ptr->end_len);
172                     access = 0;
173                     ag_trace("access := 0");
174                 }
175
176                 if (access) {
177
178                     /*
179                      * check 'var_len' ? 
180                      */
181
182                     /*
183                      * check type 
184                      */
185                     switch (called_var.type) {
186                     case ASN_INTEGER:
187                     case ASN_COUNTER:
188                     case ASN_TIMETICKS:
189                     case ASN_GAUGE:
190                     case ASN_COUNTER64:
191                         break;
192                     default:
193                         ag_trace("invalid type: %d",
194                                  (int) called_var.type);
195                         return SNMP_ERR_GENERR;
196                     }
197                     *new_value = *(u_long *) access;
198                     return SNMP_ERR_NOERROR;
199                 }
200             }
201         }
202
203         s_var_ptr =
204             (struct variable *) ((char *) s_var_ptr +
205                                  tree_ptr->variables_width);
206     }
207
208     return SNMP_ERR_NOSUCHNAME;
209 }
210
211 static void
212 alarm_check_var(unsigned int clientreg, void *clientarg)
213 {
214     RMON_ENTRY_T   *hdr_ptr;
215     CRTL_ENTRY_T   *body;
216     u_long          new_value;
217     int             ierr;
218
219     hdr_ptr = (RMON_ENTRY_T *) clientarg;
220     if (!hdr_ptr) {
221         ag_trace
222             ("Err: history_get_backet: hdr_ptr=NULL ? (Inserted in shock)");
223         return;
224     }
225
226     body = (CRTL_ENTRY_T *) hdr_ptr->body;
227     if (!body) {
228         ag_trace
229             ("Err: history_get_backet: body=NULL ? (Inserted in shock)");
230         return;
231     }
232
233     if (RMON1_ENTRY_VALID != hdr_ptr->status) {
234         ag_trace("Err: history_get_backet when entry %d is not valid ?!!",
235                  (int) hdr_ptr->ctrl_index);
236         snmp_alarm_unregister(body->timer_id);
237         return;
238     }
239
240     ierr = fetch_var_val(body->var_name.objid,
241                          body->var_name.length, &new_value);
242     if (SNMP_ERR_NOERROR != ierr) {
243         ag_trace("Err: Can't fetch var_name");
244         return;
245     }
246
247     body->value = (SAMPLE_TYPE_ABSOLUTE == body->sample_type) ?
248         new_value : new_value - body->last_abs_value;
249     body->last_abs_value = new_value;
250     /*
251      * ag_trace ("fetched value=%ld check %ld", (long) new_value, (long) body->value); 
252      */
253 #if 0                           /* KUKU */
254     kuku_sum += body->value;
255     kuku_cnt++;
256 #endif
257
258     if (ALARM_RISING != body->prev_alarm &&
259         body->value >= body->rising_threshold &&
260         SNMP_ERR_NOERROR == event_api_send_alarm(1, hdr_ptr->ctrl_index,
261                                                  body->rising_event_index,
262                                                  body->var_name.objid,
263                                                  body->var_name.length,
264                                                  ALARM_RISING, body->value,
265                                                  body->rising_threshold,
266                                                  "Rising"))
267         body->prev_alarm = ALARM_RISING;
268     else if (ALARM_FALLING != body->prev_alarm &&
269              body->value <= body->falling_threshold &&
270              SNMP_ERR_NOERROR == event_api_send_alarm(0,
271                                                       hdr_ptr->ctrl_index,
272                                                       body->
273                                                       falling_event_index,
274                                                       body->var_name.objid,
275                                                       body->var_name.
276                                                       length, ALARM_RISING,
277                                                       body->value,
278                                                       body->
279                                                       falling_threshold,
280                                                       "Falling"))
281         body->prev_alarm = ALARM_FALLING;
282 }
283
284 /*
285  * Control Table RowApi Callbacks 
286  */
287
288 int
289 alarm_Create(RMON_ENTRY_T * eptr)
290 {                               /* create the body: alloc it and set defaults */
291     CRTL_ENTRY_T   *body;
292     static VAR_OID_T DEFAULT_VAR = { 12,        /* etherStatsPkts.1 */
293         {1, 3, 6, 1, 2, 1, 16, 1, 1, 1, 5, 1}
294     };
295
296
297     eptr->body = AGMALLOC(sizeof(CRTL_ENTRY_T));
298     if (!eptr->body)
299         return -3;
300     body = (CRTL_ENTRY_T *) eptr->body;
301
302     /*
303      * set defaults 
304      */
305     body->interval = 1;
306     memcpy(&body->var_name, &DEFAULT_VAR, sizeof(VAR_OID_T));
307     body->sample_type = SAMPLE_TYPE_ABSOLUTE;
308     body->startup_type = ALARM_BOTH;
309     body->rising_threshold = MMM_MAX;
310     body->falling_threshold = 0;
311     body->rising_event_index = body->falling_event_index = 0;
312
313     body->prev_alarm = ALARM_NOTHING;
314
315     return 0;
316 }
317
318 int
319 alarm_Validate(RMON_ENTRY_T * eptr)
320 {
321     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
322
323     if (body->rising_threshold <= body->falling_threshold) {
324         ag_trace("alarm_Validate failed: %lu must be > %lu",
325                  body->rising_threshold, body->falling_threshold);
326         return SNMP_ERR_BADVALUE;
327     }
328
329     return 0;
330 }
331
332 int
333 alarm_Activate(RMON_ENTRY_T * eptr)
334 {
335     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
336     int             ierr;
337
338 #if 0                           /* KUKU */
339     kuku_sum = 0;
340     kuku_cnt = 0;
341 #endif
342     ierr = fetch_var_val(body->var_name.objid,
343                          body->var_name.length, &body->last_abs_value);
344     if (SNMP_ERR_NOERROR != ierr) {
345         ag_trace("Can't fetch var_name");
346         return ierr;
347     }
348
349     if (SAMPLE_TYPE_ABSOLUTE != body->sample_type) {
350         /*
351          * check startup alarm 
352          */
353         if (ALARM_RISING == body->startup_type ||
354             ALARM_BOTH == body->startup_type) {
355             if (body->last_abs_value >= body->rising_threshold) {
356                 event_api_send_alarm(1, eptr->ctrl_index,
357                                      body->rising_event_index,
358                                      body->var_name.objid,
359                                      body->var_name.length,
360                                      ALARM_RISING, body->value,
361                                      body->rising_threshold,
362                                      "Startup Rising");
363             }
364         }
365
366         if (ALARM_FALLING == body->startup_type ||
367             ALARM_BOTH == body->startup_type) {
368             if (body->last_abs_value <= body->falling_threshold) {
369                 event_api_send_alarm(0, eptr->ctrl_index,
370                                      body->falling_event_index,
371                                      body->var_name.objid,
372                                      body->var_name.length,
373                                      ALARM_RISING, body->value,
374                                      body->falling_threshold,
375                                      "Startup Falling");
376             }
377         }
378
379     }
380
381     body->timer_id = snmp_alarm_register(body->interval, SA_REPEAT,
382                                          alarm_check_var, eptr);
383     return 0;
384 }
385
386 int
387 alarm_Deactivate(RMON_ENTRY_T * eptr)
388 {
389     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
390
391     snmp_alarm_unregister(body->timer_id);
392 #if 0                           /* KUKU */
393     ag_trace("kuku_sum=%ld kuku_cnt=%ld sp=%ld",
394              (long) kuku_sum, (long) kuku_cnt,
395              (long) (kuku_sum / kuku_cnt));
396 #endif
397     return 0;
398 }
399
400 int
401 alarm_Copy(RMON_ENTRY_T * eptr)
402 {
403     CRTL_ENTRY_T   *body = (CRTL_ENTRY_T *) eptr->body;
404     CRTL_ENTRY_T   *clone = (CRTL_ENTRY_T *) eptr->tmp;
405
406     if (RMON1_ENTRY_VALID == eptr->status &&
407         clone->rising_threshold <= clone->falling_threshold) {
408         ag_trace("alarm_Copy failed: invalid thresholds");
409         return SNMP_ERR_BADVALUE;
410     }
411
412     if (clone->interval != body->interval) {
413         if (RMON1_ENTRY_VALID == eptr->status) {
414             snmp_alarm_unregister(body->timer_id);
415             body->timer_id =
416                 snmp_alarm_register(clone->interval, SA_REPEAT,
417                                     alarm_check_var, eptr);
418         }
419         body->interval = clone->interval;
420     }
421
422     if (snmp_oid_compare(clone->var_name.objid, clone->var_name.length,
423                          body->var_name.objid, body->var_name.length)) {
424         memcpy(&body->var_name, &clone->var_name, sizeof(VAR_OID_T));
425     }
426
427     body->sample_type = clone->sample_type;
428     body->startup_type = clone->startup_type;
429     body->sample_type = clone->sample_type;
430     body->rising_threshold = clone->rising_threshold;
431     body->falling_threshold = clone->falling_threshold;
432     body->rising_event_index = clone->rising_event_index;
433     body->falling_event_index = clone->falling_event_index;
434     /*
435      * ag_trace ("alarm_Copy: rising_threshold=%lu falling_threshold=%lu",
436      * body->rising_threshold, body->falling_threshold); 
437      */
438     return 0;
439 }
440
441 static int
442 write_alarmEntry(int action, u_char * var_val, u_char var_val_type,
443                  size_t var_val_len, u_char * statP,
444                  oid * name, size_t name_len)
445 {
446     long            long_tmp;
447     int             leaf_id, snmp_status;
448     static int      prev_action = COMMIT;
449     RMON_ENTRY_T   *hdr;
450     CRTL_ENTRY_T   *cloned_body;
451     CRTL_ENTRY_T   *body;
452
453     switch (action) {
454     case RESERVE1:
455     case FREE:
456     case UNDO:
457     case ACTION:
458     case COMMIT:
459     default:
460         return ROWAPI_do_another_action(name, alarmEntryFirstIndexBegin,
461                                         action, &prev_action,
462                                         table_ptr, sizeof(CRTL_ENTRY_T));
463     case RESERVE2:
464         /*
465          * get values from PDU, check them and save them in the cloned entry 
466          */
467         long_tmp = name[alarmEntryFirstIndexBegin];
468         leaf_id = (int) name[alarmEntryFirstIndexBegin - 1];
469         hdr = ROWAPI_find(table_ptr, long_tmp); /* it MUST be OK */
470         cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
471         body = (CRTL_ENTRY_T *) hdr->body;
472         switch (leaf_id) {
473         case IDalarmInterval:
474             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
475                                                var_val_len,
476                                                0, MMM_MAX, &long_tmp);
477             if (SNMP_ERR_NOERROR != snmp_status) {
478                 return snmp_status;
479             }
480             cloned_body->interval = long_tmp;
481             break;
482         case IDalarmVariable:
483             snmp_status = AGUTIL_get_oid_value(var_val, var_val_type,
484                                                var_val_len,
485                                                &cloned_body->var_name);
486             if (SNMP_ERR_NOERROR != snmp_status) {
487                 return snmp_status;
488             }
489             if (RMON1_ENTRY_UNDER_CREATION != hdr->status &&
490                 snmp_oid_compare(cloned_body->var_name.objid,
491                                  cloned_body->var_name.length,
492                                  body->var_name.objid,
493                                  body->var_name.length))
494                 return SNMP_ERR_BADVALUE;
495             break;
496
497             break;
498         case IDalarmSampleType:
499             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
500                                                var_val_len,
501                                                SAMPLE_TYPE_ABSOLUTE,
502                                                SAMPLE_TYPE_DELTE,
503                                                &long_tmp);
504             if (SNMP_ERR_NOERROR != snmp_status) {
505                 return snmp_status;
506             }
507             cloned_body->sample_type = long_tmp;
508             break;
509         case IDalarmStartupAlarm:
510             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
511                                                var_val_len,
512                                                ALARM_RISING,
513                                                ALARM_BOTH, &long_tmp);
514             if (SNMP_ERR_NOERROR != snmp_status) {
515                 return snmp_status;
516             }
517             cloned_body->startup_type = long_tmp;
518             break;
519         case IDalarmRisingThreshold:
520             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
521                                                var_val_len,
522                                                0, MMM_MAX, &long_tmp);
523             if (SNMP_ERR_NOERROR != snmp_status) {
524                 return snmp_status;
525             }
526             cloned_body->rising_threshold = long_tmp;
527             break;
528         case IDalarmFallingThreshold:
529             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
530                                                var_val_len,
531                                                0, 0xFFFFFFFFl, &long_tmp);
532             if (SNMP_ERR_NOERROR != snmp_status) {
533                 return snmp_status;
534             }
535             cloned_body->falling_threshold = long_tmp;
536             break;
537         case IDalarmRisingEventIndex:
538             snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0,   /* min. value */
539                                                0,       /* max. value */
540                                                &long_tmp);
541             if (SNMP_ERR_NOERROR != snmp_status) {
542                 return snmp_status;
543             }
544             cloned_body->rising_event_index = long_tmp;
545             break;
546         case IDalarmFallingEventIndex:
547             snmp_status = AGUTIL_get_int_value(var_val, var_val_type, var_val_len, 0,   /* min. value */
548                                                0,       /* max. value */
549                                                &long_tmp);
550             if (SNMP_ERR_NOERROR != snmp_status) {
551                 return snmp_status;
552             }
553             cloned_body->falling_event_index = long_tmp;
554             break;
555         case IDalarmOwner:
556             if (hdr->new_owner)
557                 AGFREE(hdr->new_owner);
558             hdr->new_owner = AGMALLOC(MAX_OWNERSTRING);;
559             if (!hdr->new_owner)
560                 return SNMP_ERR_TOOBIG;
561             snmp_status = AGUTIL_get_string_value(var_val, var_val_type,
562                                                   var_val_len,
563                                                   MAX_OWNERSTRING,
564                                                   1, NULL, hdr->new_owner);
565             if (SNMP_ERR_NOERROR != snmp_status) {
566                 return snmp_status;
567             }
568
569             break;
570         case IDalarmStatus:
571             snmp_status = AGUTIL_get_int_value(var_val, var_val_type,
572                                                var_val_len,
573                                                RMON1_ENTRY_VALID,
574                                                RMON1_ENTRY_INVALID,
575                                                &long_tmp);
576             if (SNMP_ERR_NOERROR != snmp_status) {
577                 return snmp_status;
578             }
579             hdr->new_status = long_tmp;
580             break;
581         default:
582             ag_trace("%s:unknown leaf_id=%d\n", table_ptr->name,
583                      (int) leaf_id);
584             return SNMP_ERR_NOSUCHNAME;
585         }                       /* of switch by 'leaf_id' */
586
587         break;
588     }                           /* of switch by actions */
589
590     prev_action = action;
591     return SNMP_ERR_NOERROR;
592 }
593
594 u_char         *
595 var_alarmEntry(struct variable * vp, oid * name, size_t * length,
596                int exact, size_t * var_len, WriteMethod ** write_method)
597 {
598     static long     long_return;
599     static CRTL_ENTRY_T theEntry;
600     RMON_ENTRY_T   *hdr;
601
602     *write_method = write_alarmEntry;
603     hdr = ROWAPI_header_ControlEntry(vp, name, length, exact, var_len,
604                                      table_ptr,
605                                      &theEntry, sizeof(CRTL_ENTRY_T));
606     if (!hdr)
607         return NULL;
608
609     *var_len = sizeof(long);    /* default */
610
611     switch (vp->magic) {
612     case IDalarmIndex:
613         long_return = hdr->ctrl_index;
614         return (u_char *) & long_return;
615     case IDalarmInterval:
616         long_return = theEntry.interval;
617         return (u_char *) & long_return;
618     case IDalarmVariable:
619         *var_len = sizeof(oid) * theEntry.var_name.length;
620         return (unsigned char *) theEntry.var_name.objid;
621         return (u_char *) & long_return;
622     case IDalarmSampleType:
623         long_return = theEntry.sample_type;
624         return (u_char *) & long_return;
625     case IDalarmValue:
626         long_return = theEntry.value;
627         return (u_char *) & long_return;
628     case IDalarmStartupAlarm:
629         long_return = theEntry.startup_type;
630         return (u_char *) & long_return;
631     case IDalarmRisingThreshold:
632         long_return = theEntry.rising_threshold;
633         return (u_char *) & long_return;
634     case IDalarmFallingThreshold:
635         long_return = theEntry.falling_threshold;
636         return (u_char *) & long_return;
637     case IDalarmRisingEventIndex:
638         long_return = theEntry.rising_event_index;
639         return (u_char *) & long_return;
640     case IDalarmFallingEventIndex:
641         long_return = theEntry.falling_event_index;
642         return (u_char *) & long_return;
643     case IDalarmOwner:
644         if (hdr->owner) {
645             *var_len = strlen(hdr->owner);
646             return (unsigned char *) hdr->owner;
647         } else {
648             *var_len = 0;
649             return (unsigned char *) "";
650         }
651
652     case IDalarmStatus:
653         long_return = hdr->status;
654         return (u_char *) & long_return;
655     default:
656         ag_trace("%s: unknown vp->magic=%d", table_ptr->name,
657                  (int) vp->magic);
658         ERROR_MSG("");
659     };                          /* of switch by 'vp->magic' */
660
661     return NULL;
662 }
663
664 /*
665  * Registration & Initializatio section 
666  */
667
668 oid             oidalarmVariablesOid[] = { 1, 3, 6, 1, 2, 1, 16, 3 };
669
670 struct variable7 oidalarmVariables[] = {
671     {IDalarmIndex, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 1}},
672     {IDalarmInterval, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 2}},
673     {IDalarmVariable, ASN_OBJECT_ID, RWRITE, var_alarmEntry, 3, {1, 1, 3}},
674     {IDalarmSampleType, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 4}},
675     {IDalarmValue, ASN_INTEGER, RONLY, var_alarmEntry, 3, {1, 1, 5}},
676     {IDalarmStartupAlarm, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
677      {1, 1, 6}},
678     {IDalarmRisingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
679      {1, 1, 7}},
680     {IDalarmFallingThreshold, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
681      {1, 1, 8}},
682     {IDalarmRisingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
683      {1, 1, 9}},
684     {IDalarmFallingEventIndex, ASN_INTEGER, RWRITE, var_alarmEntry, 3,
685      {1, 1, 10}},
686     {IDalarmOwner, ASN_OCTET_STR, RWRITE, var_alarmEntry, 3, {1, 1, 11}},
687     {IDalarmStatus, ASN_INTEGER, RWRITE, var_alarmEntry, 3, {1, 1, 12}}
688 };
689
690 void
691 init_alarm(void)
692 {
693     REGISTER_MIB("alarmTable", oidalarmVariables, variable7,
694                  oidalarmVariablesOid);
695
696     ROWAPI_init_table(&AlarmCtrlTable, "Alarm", 0, &alarm_Create, NULL, /* &alarm_Clone, */
697                       NULL,     /* &alarm_Delete, */
698                       &alarm_Validate,
699                       &alarm_Activate, &alarm_Deactivate, &alarm_Copy);
700 }
701
702 /*
703  * end of file alarm.c 
704  */