4 * Stats reporting code. It reports through SIG_USR1 and if loaded
5 * through the SNMP module
7 * Copyright (C) 2001-2003 FhG Fokus
9 * This file is part of ser, a free SIP server.
11 * ser is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version
16 * For a license to use the ser software under conditions
17 * other than those described here, or to purchase support for this
18 * software, please contact iptel.org by e-mail at the following addresses:
21 * ser is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 * 2003-03-19: added support for route type in find_export (janakj)
42 #include <sys/types.h>
45 #include "mem/shm_mem.h"
46 #include "sr_module.h"
49 #include "modules/snmp/snmp_handler.h"
50 #include "modules/snmp/sipCommonStatsMethod.h"
51 #include "modules/snmp/sipCommonStatusCode.h"
53 struct stats_s *stats; /* per process stats structure */
54 char *stat_file = NULL; /* set by the parser */
56 /* private variables */
57 static struct stats_s *global_stats=NULL;
58 static int stats_segments=-1; /*used also to determine if we've been init'ed*/
60 /* adds up global statistics and puts them into passed struct.
61 * -1 returned on failure */
62 static int collect_stats(struct stats_s *s);
64 /***********************8 SNMP Stuff **************************/
65 /* a small structure we use to pass around the functions needed by
66 * all the registration functions */
68 int (*reg_func)(const char *, struct sip_snmp_handler*);
69 struct sip_snmp_handler* (*new_func)(size_t);
70 void (*free_func)(struct sip_snmp_handler*);
73 /* SNMP Handler registration functions */
74 static int sipSummaryStatsTable_register(const struct stats_funcs *f);
75 static int sipMethodStatsTable_register(const struct stats_funcs *f);
76 static int sipStatusCodesTable_register(const struct stats_funcs *f);
79 static int collect_InReqs(struct sip_snmp_obj *, enum handler_op);
80 static int collect_OutReqs(struct sip_snmp_obj *, enum handler_op);
81 static int collect_InResp(struct sip_snmp_obj *, enum handler_op);
82 static int collect_OutResp(struct sip_snmp_obj *, enum handler_op);
83 static int sipStatsMethod_handler(struct sip_snmp_obj *o, enum handler_op op);
84 static int sipStatusCodes_handler(struct sip_snmp_obj *o, enum handler_op op);
86 int init_stats(int nr_of_processes)
88 LOG(L_DBG,"init_stats(): initializing stats for %d processes\n",
92 global_stats = shm_malloc(nr_of_processes*sizeof(struct stats_s));
94 LOG(L_ERR, "Out of memory\n");
97 stats_segments = nr_of_processes;
99 if(stats_register() == -1)
100 LOG(L_WARN, "init_stats(): Couldn't register stats"
101 " with snmp module\n");
107 /* sets the stats pointer for the passed process */
108 void setstats(int child_index)
110 if(stats_segments == -1 || !global_stats) {
111 LOG(L_ERR, "Stats not initialized. Cannot set them\n");
115 if(child_index < 0 || child_index >= stats_segments) {
117 LOG(L_ERR, "Invalid index %d while setting statistics. Only have "
118 "space for %d processes\n", child_index, stats_segments);
121 stats = global_stats+child_index;
122 stats->process_index = child_index;
123 /* can't use pids[] because we may be called before the corresponding
124 * slot in pids[] is initialized (chk main_loop()) */
125 stats->pid = getpid();
126 stats->start_time = time(NULL);
129 /* printheader is used to print pid, date and index */
130 int dump_statistic(FILE *fp, struct stats_s *istats, int printheader)
134 if(stats_segments == -1 || !global_stats) {
135 LOG(L_ERR, "Stats \"engine\" not initialized\n");
140 localtime_r(&istats->start_time, &res);
141 strftime(t, 255, "%c", &res);
143 fprintf(fp, "stats for process %d (pid %d) started at %s\n",
144 istats->process_index, istats->pid, t);
147 fprintf(fp, "received requests:\ninv: %ld\tack: %ld\tcnc: %ld\t"
148 "bye: %ld\tother: %ld\n",
149 istats->received_requests_inv,
150 istats->received_requests_ack,
151 istats->received_requests_cnc,
152 istats->received_requests_bye,
153 istats->received_requests_other);
154 fprintf(fp, "sent requests:\n"
155 "inv: %ld\tack: %ld\tcnc: %ld\tbye: %ld\tother: %ld\n",
156 istats->sent_requests_inv,
157 istats->sent_requests_ack,
158 istats->sent_requests_cnc,
159 istats->sent_requests_bye,
160 istats->sent_requests_other);
161 fprintf(fp, "received responses:\n"
162 "1: %ld\t2: %ld\t3: %ld\t4: %ld\t5: %ld\t6: %ld\tother: %ld\t"
164 istats->received_responses_1,
165 istats->received_responses_2,
166 istats->received_responses_3,
167 istats->received_responses_4,
168 istats->received_responses_5,
169 istats->received_responses_6,
170 istats->received_responses_other,
171 istats->received_drops);
172 fprintf(fp, "sent responses:\n"
173 "1: %ld\t2: %ld\t3: %ld\t4: %ld\t5: %ld\t6: %ld\n",
174 istats->sent_responses_1,
175 istats->sent_responses_2,
176 istats->sent_responses_3,
177 istats->sent_responses_4,
178 istats->sent_responses_5,
179 istats->sent_responses_6);
180 fprintf(fp, "processed requests: %ld\t\tprocessed responses: %ld\n"
181 "acc req time: %ld\t\t\tacc res time: %ld\nfailed on send: %ld\n\n",
182 istats->processed_requests,
183 istats->processed_responses,
184 istats->acc_req_time,
185 istats->acc_res_time,
186 istats->failed_on_send);
190 int dump_all_statistic()
193 register struct stats_s *c;
194 static struct stats_s *g = NULL;
198 FILE *stat_fp = NULL;
200 if(stats_segments == -1 || !global_stats) {
201 LOG(L_ERR, "%s: Can't dump statistics, not initialized!\n", __func__);
206 LOG(L_ERR, "%s: Can't dump statistics, invalid stats file\n", __func__);
210 stat_fp = fopen(stat_file, "a");
212 LOG(L_ERR, "%s: Couldn't open stats file %s: %s\n", __func__, stat_file,
217 /* time stamp them since we're appending to the file */
219 localtime_r(&ts, &res);
220 strftime(t, 255, "%c", &res);
221 fprintf(stat_fp, "#### stats @ %s #####\n", t);
224 for(i=0; i<stats_segments; i++) {
225 if(dump_statistic(stat_fp, c, 1) == -1) {
226 LOG(L_ERR, "Error dumping statistics for process %d\n", i);
232 fprintf(stat_fp, "## Global Stats ##\n");
234 g = calloc(1, sizeof(struct stats_s));
236 LOG(L_ERR, "Couldn't dump global stats: %s\n", strerror(errno));
240 if(collect_stats(g) == -1) {
241 LOG(L_ERR, "%s: Couldn't dump global stats\n", __func__);
244 if(dump_statistic(stat_fp, g, 0) == -1) {
245 LOG(L_ERR, "Couldn't dump global stats\n");
249 fprintf(stat_fp, "\n");
255 static int collect_stats(struct stats_s *s)
258 register struct stats_s *c;
260 LOG(L_ERR, "collect_stats(): Invalid stats pointer passed\n");
263 if(!global_stats || stats_segments == -1) {
264 LOG(L_ERR, "Can't collect statistics, not initialized!!\n");
269 memset(s, '\0', sizeof(struct stats_s));
270 for(i=0; i<stats_segments; i++) {
271 s->received_requests_inv += c->received_requests_inv;
272 s->received_requests_ack += c->received_requests_ack;
273 s->received_requests_cnc += c->received_requests_cnc;
274 s->received_requests_bye += c->received_requests_bye;
275 s->received_requests_other += c->received_requests_other;
276 s->received_responses_1 += c->received_responses_1;
277 s->received_responses_2 += c->received_responses_2;
278 s->received_responses_3 += c->received_responses_3;
279 s->received_responses_4 += c->received_responses_4;
280 s->received_responses_5 += c->received_responses_5;
281 s->received_responses_6 += c->received_responses_6;
282 s->received_responses_other += c->received_responses_other;
283 s->received_drops += c->received_drops;
284 s->sent_requests_inv += c->sent_requests_inv;
285 s->sent_requests_ack += c->sent_requests_ack;
286 s->sent_requests_cnc += c->sent_requests_cnc;
287 s->sent_requests_bye += c->sent_requests_bye;
288 s->sent_requests_other += c->sent_requests_other;
289 s->sent_responses_1 += c->sent_responses_1;
290 s->sent_responses_2 += c->sent_responses_2;
291 s->sent_responses_3 += c->sent_responses_3;
292 s->sent_responses_4 += c->sent_responses_4;
293 s->sent_responses_5 += c->sent_responses_5;
294 s->sent_responses_6 += c->sent_responses_6;
295 s->processed_requests += c->processed_requests;
296 s->processed_responses += c->processed_responses;
297 s->acc_req_time += c->acc_req_time;
298 s->acc_res_time += c->acc_res_time;
299 s->failed_on_send += c->failed_on_send;
301 c++; /* next, please... */
307 /*************************** SNMP Stuff ***********************/
309 /* ##### Registration Functions ####### */
311 /* Registers the handlers for:
312 * - sipSummaryStatsTable
313 * - sipMethodStatsTable
314 * - sipStatusCodesTable
315 * - sipCommonStatusCodeTable
317 * Returns 0 if snmp module not present, -1 on error, 1 on successful
322 if(t##_register(&f) == -1) { \
323 LOG(L_ERR, "%s: Failed registering SNMP handlers\n", func); \
329 const char *func = __FUNCTION__;
330 struct stats_funcs f;
332 f.reg_func = (void*) find_export("snmp_register_handler", 2, 0);
333 f.new_func = (void*) find_export("snmp_new_handler", 1, 0);
334 f.free_func = (void*) find_export("snmp_free_handler", 1, 0);
335 if(!f.reg_func || !f.new_func || !f.free_func) {
336 LOG(L_INFO, "%s: Couldn't find SNMP module\n", func);
337 LOG(L_INFO, "%s: Not reporting stats through SNMP\n", func);
341 reg(sipSummaryStatsTable);
342 reg(sipMethodStatsTable);
343 reg(sipStatusCodesTable);
348 /* Receives the function used to register SNMP handlers. Returns 0
349 * on success, -1 on error */
351 * - sipSummaryInRequests
352 * - sipSummaryOutRequests
353 * - sipSummaryInResponses
354 * - sipSummaryOutResponses
355 * => sipSummaryTotalTransactions is handled by the tm module */
356 static int sipSummaryStatsTable_register(const struct stats_funcs *f)
358 register struct sip_snmp_handler *h;
359 register struct sip_snmp_obj *o;
360 const char *func = __FUNCTION__;
362 h = f->new_func(sizeof(unsigned long));
364 LOG(L_ERR, "%s: Error creating handler\n", func);
369 /* this is the same for all of our objects */
370 o->type = SER_COUNTER;
371 *o->value.integer = 0; /* default value. The real one is computed on
373 o->val_len = sizeof(unsigned long);
375 /* sipSummaryInRequests */
376 h->on_get = collect_InReqs;
377 h->on_set = h->on_end = NULL;
378 if(f->reg_func("sipSummaryInRequests", h) == -1) {
379 LOG(L_ERR, "%s: Error registering sipSummaryInRequests\n", func);
384 /* sipSummaryOutRequests */
385 h->on_get = collect_OutReqs;
386 if(f->reg_func("sipSummaryOutRequests", h) == -1) {
387 LOG(L_ERR, "%s: Error registering sipSummaryOutRequests\n", func);
392 /* sipSummaryInResponses */
393 h->on_get = collect_InResp;
394 if(f->reg_func("sipSummaryInResponses", h) == -1) {
395 LOG(L_ERR, "%s: Error registering sipSummaryInResponses\n", func);
400 /* sipSummaryOutResponses */
401 h->on_get = collect_OutResp;
402 if(f->reg_func("sipSummaryOutResponses", h) == -1) {
403 LOG(L_ERR, "%s: Error registering sipSummaryOutResponses\n", func);
413 static int sipMethodStatsTable_register(const struct stats_funcs *f)
415 const char* objs[] = {
417 "sipStatsInviteOuts",
424 #if 0 /* we don't know about these */
425 "sipStatsOptionsIns",
426 "sipStatsOptionsOuts",
427 "sipStatsRegisterIns",
428 "sipStatsRegisterOuts",
434 const char *func = __FUNCTION__;
435 register struct sip_snmp_handler *h;
436 register struct sip_snmp_obj *o;
438 h = f->new_func(sizeof(unsigned long));
440 LOG(L_ERR, "%s: Error creating handler\n", func);
444 o->type = SER_COUNTER;
445 *o->value.integer = 0;
446 o->val_len = sizeof(unsigned long);
448 h->on_get = sipStatsMethod_handler;
449 h->on_set = h->on_end = NULL;
451 for(i=0; i<num; i++) {
452 if(f->reg_func(objs[i], h) == -1) {
453 LOG(L_ERR, "%s: Error registering %s\n", func, objs[i]);
464 static int sipStatusCodesTable_register(const struct stats_funcs *f)
466 const char *objs[] = {
467 "sipStatsInfoClassIns",
468 "sipStatsInfoClassOuts",
469 "sipStatsSuccessClassIns",
470 "sipStatsSuccessClassOuts",
471 "sipStatsRedirClassIns",
472 "sipStatsRedirClassOuts",
473 "sipStatsReqFailClassIns",
474 "sipStatsReqFailClassOuts",
475 "sipStatsServerFailClassIns",
476 "sipStatsServerFailClassOuts",
477 "sipStatsGlobalFailClassIns",
478 "sipStatsGlobalFailClassOuts",
479 "sipStatsOtherClassesIns",
480 "sipStatsOtherClassesOuts"
483 const char *func = __FUNCTION__;
484 register struct sip_snmp_handler *h;
485 register struct sip_snmp_obj *o;
487 h = f->new_func(sizeof(unsigned long));
489 LOG(L_ERR, "%s: Error creating handler\n", func);
493 o->type = SER_COUNTER;
494 *o->value.integer = 0;
495 o->val_len = sizeof(unsigned long);
497 h->on_get = sipStatusCodes_handler;
498 h->on_set = h->on_end = NULL;
500 for(i=0; i<num; i++) {
501 if(f->reg_func(objs[i], h) == -1) {
502 LOG(L_ERR, "%s: Error registering %s\n", func, objs[i]);
512 /* ########################## SNMP Handlers ######################### */
514 /*** Handlers for sipSummaryStatsTable */
515 static int collect_InReqs(struct sip_snmp_obj *o, enum handler_op op)
518 register struct stats_s *c;
519 register unsigned long t1, t2, t3, t4, t5;
520 const char *func = __FUNCTION__;
522 if(!global_stats || stats_segments == -1) {
523 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized."
524 "Did you call init_stats()?\n", func);
529 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
533 if(!o->value.integer) {
534 o->value.integer = calloc(1, sizeof(unsigned long));
535 if(!o->value.integer) {
536 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
542 t1 = t2 = t3 = t4 = t5 = 0;
543 for(i=0; i<stats_segments; i++, c++) {
544 t1 += c->received_requests_inv;
545 t2 += c->received_requests_ack;
546 t3 += c->received_requests_cnc;
547 t4 += c->received_requests_bye;
548 t5 += c->received_requests_other;
551 *o->value.integer = t1 + t2 + t3 + t4 + t5;
552 o->val_len = sizeof(unsigned long);
553 o->type = SER_COUNTER;
558 static int collect_OutReqs(struct sip_snmp_obj *o, enum handler_op op)
561 register struct stats_s *c;
562 register unsigned long t1, t2, t3, t4, t5;
563 const char *func = __FUNCTION__;
565 if(!global_stats || stats_segments == -1) {
566 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized."
567 "Did you call init_stats()?\n", func);
572 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
576 if(!o->value.integer) {
577 o->value.integer = calloc(1, sizeof(unsigned long));
578 if(!o->value.integer) {
579 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
585 t1 = t2 = t3 = t4 = t5 = 0;
586 for(i=0; i<stats_segments; i++, c++) {
587 t1 += c->sent_requests_inv;
588 t2 += c->sent_requests_ack;
589 t3 += c->sent_requests_cnc;
590 t4 += c->sent_requests_bye;
591 t5 += c->sent_requests_other;
594 *o->value.integer = t1 + t2 + t3 + t4 + t5;
595 o->val_len = sizeof(unsigned long);
596 o->type = SER_COUNTER;
601 static int collect_InResp(struct sip_snmp_obj *o, enum handler_op op)
604 register struct stats_s *c;
605 register unsigned long t1, t2, t3, t4, t5, t6, t7;
606 const char *func = __FUNCTION__;
608 if(!global_stats || stats_segments == -1) {
609 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized."
610 "Did you call init_stats()?\n", func);
615 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
619 if(!o->value.integer) {
620 o->value.integer = calloc(1, sizeof(unsigned long));
621 if(!o->value.integer) {
622 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
628 t1 = t2 = t3 = t4 = t5 = t6 = t7 = 0;
629 for(i=0; i<stats_segments; i++, c++) {
630 t1 += c->received_responses_1;
631 t2 += c->received_responses_2;
632 t3 += c->received_responses_3;
633 t4 += c->received_responses_4;
634 t5 += c->received_responses_5;
635 t6 += c->received_responses_6;
636 t7 += c->received_responses_other;
639 *o->value.integer = t1 + t2 + t3 + t4 + t5 + t6 + t7;
640 o->val_len = sizeof(unsigned long);
641 o->type = SER_COUNTER;
646 static int collect_OutResp(struct sip_snmp_obj *o, enum handler_op op)
649 register struct stats_s *c;
650 register unsigned long t1, t2, t3, t4, t5, t6, t7;
651 const char *func = __FUNCTION__;
653 if(!global_stats || stats_segments == -1) {
654 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized\n",
660 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
664 if(!o->value.integer) {
665 o->value.integer = calloc(1, sizeof(unsigned long));
666 if(!o->value.integer) {
667 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
673 t1 = t2 = t3 = t4 = t5 = t6 = t7 = 0;
674 for(i=0; i<stats_segments; i++, c++) {
675 t1 += c->sent_responses_1;
676 t2 += c->sent_responses_2;
677 t3 += c->sent_responses_3;
678 t4 += c->sent_responses_4;
679 t5 += c->sent_responses_5;
680 t6 += c->sent_responses_6;
681 /* XXX: Not in stats struct
682 t7 += c->sent_responses_other;
686 *o->value.integer = t1 + t2 + t3 + t4 + t5 + t6 + t7;
687 o->val_len = sizeof(unsigned long);
688 o->type = SER_COUNTER;
693 /***** Handlers for sipMethodStatsTable ******/
694 /* Collects the specified stat and puts the result in total. s defines
695 * the starting point in the stats array, normally global_stats */
696 #define collect_this_stat(stat, total, s) \
697 for(i=0; i<stats_segments; i++) \
700 static int sipStatsMethod_handler(struct sip_snmp_obj *o, enum handler_op op)
702 register struct stats_s *c;
703 register unsigned long total;
705 const char *func = __FUNCTION__;
708 LOG(L_ERR, "%s: Invalid sip SNMP object passed\n", func);
712 if(!global_stats || stats_segments == -1) {
713 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized\n",
719 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
723 if(!o->value.integer) {
724 o->value.integer = calloc(1, sizeof(unsigned long));
725 if(!o->value.integer) {
726 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
734 /* these definitions are taken from sipMethodStatsHandler */
735 case COLUMN_SIPSTATSINVITEINS:
736 collect_this_stat(received_requests_inv, total, c);
738 case COLUMN_SIPSTATSINVITEOUTS:
739 collect_this_stat(sent_requests_inv, total, c);
741 case COLUMN_SIPSTATSACKINS:
742 collect_this_stat(received_requests_ack, total, c);
744 case COLUMN_SIPSTATSACKOUTS:
745 collect_this_stat(sent_requests_ack, total, c);
747 case COLUMN_SIPSTATSBYEINS:
748 collect_this_stat(received_requests_bye, total, c);
750 case COLUMN_SIPSTATSBYEOUTS:
751 collect_this_stat(sent_requests_bye, total, c);
753 case COLUMN_SIPSTATSCANCELINS:
754 collect_this_stat(received_requests_cnc, total, c);
756 case COLUMN_SIPSTATSCANCELOUTS:
757 collect_this_stat(sent_requests_cnc, total, c);
759 /* ser doesn't have notion for these. We don't
760 * register them with snmp. Here just as remainder */
762 case COLUMN_SIPSTATSOPTIONSINS:
763 case COLUMN_SIPSTATSOPTIONSOUTS:
764 case COLUMN_SIPSTATSREGISTERINS:
765 case COLUMN_SIPSTATSREGISTEROUTS:
766 case COLUMN_SIPSTATSINFOINS:
767 case COLUMN_SIPSTATSINFOOUTS:
772 *o->value.integer = total;
773 o->val_len = sizeof(unsigned long);
774 o->type = SER_COUNTER;
779 static int sipStatusCodes_handler(struct sip_snmp_obj *o, enum handler_op op)
781 register struct stats_s *c;
782 register unsigned long total;
784 const char *func = __FUNCTION__;
787 LOG(L_ERR, "%s: Invalid sip SNMP object passed\n", func);
791 if(!global_stats || stats_segments == -1) {
792 LOG(L_ERR, "%s: Can't collect stats, they have not been initialized\n",
798 LOG(L_ERR, "%s: Invalid handler operation passed\n", func);
802 if(!o->value.integer) {
803 o->value.integer = calloc(1, sizeof(unsigned long));
804 if(!o->value.integer) {
805 LOG(L_ERR, "%s: %s\n", func, strerror(errno));
813 case COLUMN_SIPSTATSINFOCLASSINS:
814 collect_this_stat(received_responses_1, total, c);
816 case COLUMN_SIPSTATSINFOCLASSOUTS:
817 collect_this_stat(sent_responses_1, total, c);
819 case COLUMN_SIPSTATSSUCCESSCLASSINS:
820 collect_this_stat(received_responses_2, total, c);
822 case COLUMN_SIPSTATSSUCCESSCLASSOUTS:
823 collect_this_stat(sent_responses_2, total, c);
825 case COLUMN_SIPSTATSREDIRCLASSINS:
826 collect_this_stat(received_responses_3, total, c);
828 case COLUMN_SIPSTATSREDIRCLASSOUTS:
829 collect_this_stat(sent_responses_3, total, c);
831 case COLUMN_SIPSTATSREQFAILCLASSINS:
832 collect_this_stat(received_responses_4, total, c);
834 case COLUMN_SIPSTATSREQFAILCLASSOUTS:
835 collect_this_stat(sent_responses_4, total, c);
837 case COLUMN_SIPSTATSSERVERFAILCLASSINS:
838 collect_this_stat(received_responses_5, total, c);
840 case COLUMN_SIPSTATSSERVERFAILCLASSOUTS:
841 collect_this_stat(sent_responses_5, total, c);
843 case COLUMN_SIPSTATSGLOBALFAILCLASSINS:
844 collect_this_stat(received_responses_6, total, c);
846 case COLUMN_SIPSTATSGLOBALFAILCLASSOUTS:
847 collect_this_stat(sent_responses_6, total, c);
849 case COLUMN_SIPSTATSOTHERCLASSESINS:
850 collect_this_stat(received_responses_other, total, c);
852 case COLUMN_SIPSTATSOTHERCLASSESOUTS:
853 /* FIXME: For some reason this is not defined in
854 * struct stats_s... */
855 /* collect_this_stat(sent_responses_other, total, c); */
860 *o->value.integer = total;
861 o->val_len = sizeof(unsigned long);
862 o->type = SER_COUNTER;