... | ... |
@@ -8,13 +8,6 @@ auto_gen= |
8 | 8 |
NAME=acc.so |
9 | 9 |
LIBS= |
10 | 10 |
|
11 |
-# set ENABLE_DIAMETER_ACC to true if you wish to enable DIAMETER accounting |
|
12 |
-# (uncomment next line or 'ENABLE_DIAMETER_ACC=true make all') |
|
13 |
-#ENABLE_DIAMETER_ACC=true |
|
14 |
-ifeq ($(ENABLE_DIAMETER_ACC),true) |
|
15 |
-DEFS+=-DDIAM_ACC |
|
16 |
-endif |
|
17 |
- |
|
18 | 11 |
DEFS+=-DKAMAILIO_MOD_INTERFACE |
19 | 12 |
|
20 | 13 |
SERLIBPATH=../../lib |
... | ... |
@@ -47,23 +47,11 @@ |
47 | 47 |
#include "acc_logic.h" |
48 | 48 |
#include "acc_api.h" |
49 | 49 |
|
50 |
-#ifdef DIAM_ACC |
|
51 |
-#include "diam_dict.h" |
|
52 |
-#include "diam_message.h" |
|
53 |
-#include "diam_tcp.h" |
|
54 |
-#endif |
|
55 |
- |
|
56 | 50 |
extern struct acc_extra *log_extra; |
57 | 51 |
extern struct acc_extra *leg_info; |
58 | 52 |
extern struct acc_enviroment acc_env; |
59 | 53 |
extern char *acc_time_format; |
60 | 54 |
|
61 |
-#ifdef DIAM_ACC |
|
62 |
-extern char *diameter_client_host; |
|
63 |
-extern int diameter_client_port; |
|
64 |
-extern struct acc_extra *dia_extra; |
|
65 |
-#endif |
|
66 |
- |
|
67 | 55 |
static db_func_t acc_dbf; |
68 | 56 |
static db1_con_t* db_handle=0; |
69 | 57 |
extern struct acc_extra *db_extra; |
... | ... |
@@ -111,7 +99,7 @@ int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals) |
111 | 99 |
/* from/to URI and TAG */ |
112 | 100 |
if (req->msg_flags&FL_REQ_UPSTREAM) { |
113 | 101 |
LM_DBG("the flag UPSTREAM is set -> swap F/T\n"); \ |
114 |
- from = acc_env.to; |
|
102 |
+ from = acc_env.to; |
|
115 | 103 |
to = req->from; |
116 | 104 |
} else { |
117 | 105 |
from = req->from; |
... | ... |
@@ -252,8 +240,8 @@ int acc_log_request( struct sip_msg *rq) |
252 | 240 |
} |
253 | 241 |
} |
254 | 242 |
} while (p!=log_msg_end && (n=legs2strar(leg_info,rq,val_arr+m, |
255 |
- int_arr+m,type_arr+m, |
|
256 |
- 0))!=0); |
|
243 |
+ int_arr+m,type_arr+m, |
|
244 |
+ 0))!=0); |
|
257 | 245 |
} |
258 | 246 |
|
259 | 247 |
/* terminating line */ |
... | ... |
@@ -262,15 +250,15 @@ int acc_log_request( struct sip_msg *rq) |
262 | 250 |
|
263 | 251 |
if(acc_time_mode==1) { |
264 | 252 |
LM_GEN2(log_facility, log_level, "%.*stimestamp=%lu;%s=%u%s", |
265 |
- acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
266 |
- acc_time_exten.s, (unsigned int)acc_env.tv.tv_usec, |
|
267 |
- log_msg); |
|
253 |
+ acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
254 |
+ acc_time_exten.s, (unsigned int)acc_env.tv.tv_usec, |
|
255 |
+ log_msg); |
|
268 | 256 |
} else if(acc_time_mode==2) { |
269 | 257 |
dtime = (double)acc_env.tv.tv_usec; |
270 | 258 |
dtime = (dtime / 1000000) + (double)acc_env.tv.tv_sec; |
271 | 259 |
LM_GEN2(log_facility, log_level, "%.*stimestamp=%lu;%s=%.3f%s", |
272 |
- acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
273 |
- acc_time_attr.s, dtime, log_msg); |
|
260 |
+ acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
261 |
+ acc_time_attr.s, dtime, log_msg); |
|
274 | 262 |
} else if(acc_time_mode==3 || acc_time_mode==4) { |
275 | 263 |
if(acc_time_mode==3) { |
276 | 264 |
t = localtime(&acc_env.ts); |
... | ... |
@@ -282,14 +270,14 @@ int acc_log_request( struct sip_msg *rq) |
282 | 270 |
acc_time_format_buf[0] = '\0'; |
283 | 271 |
} |
284 | 272 |
LM_GEN2(log_facility, log_level, "%.*stimestamp=%lu;%s=%s%s", |
285 |
- acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
286 |
- acc_time_attr.s, |
|
287 |
- acc_time_format_buf, |
|
288 |
- log_msg); |
|
273 |
+ acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
274 |
+ acc_time_attr.s, |
|
275 |
+ acc_time_format_buf, |
|
276 |
+ log_msg); |
|
289 | 277 |
} else { |
290 | 278 |
LM_GEN2(log_facility, log_level, "%.*stimestamp=%lu%s", |
291 |
- acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
292 |
- log_msg); |
|
279 |
+ acc_env.text.len, acc_env.text.s,(unsigned long)acc_env.ts, |
|
280 |
+ log_msg); |
|
293 | 281 |
} |
294 | 282 |
/* free memory allocated by extra2strar */ |
295 | 283 |
free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); |
... | ... |
@@ -510,7 +498,7 @@ int acc_db_request( struct sip_msg *rq) |
510 | 498 |
} |
511 | 499 |
} |
512 | 500 |
}while ( (n=legs2strar(leg_info,rq,val_arr+m,int_arr+m, |
513 |
- type_arr+m,0))!=0 ); |
|
501 |
+ type_arr+m,0))!=0 ); |
|
514 | 502 |
} |
515 | 503 |
|
516 | 504 |
/* free memory allocated by extra2strar */ |
... | ... |
@@ -522,266 +510,6 @@ error: |
522 | 510 |
return -1; |
523 | 511 |
} |
524 | 512 |
|
525 |
- |
|
526 |
-/************ RADIUS & DIAMETER helper functions **************/ |
|
527 |
-#if defined (DIAM_ACC) |
|
528 |
-#ifndef UINT4 |
|
529 |
-#define UINT4 uint32_t |
|
530 |
-#endif |
|
531 |
-inline static UINT4 phrase2code(str *phrase) |
|
532 |
-{ |
|
533 |
- UINT4 code; |
|
534 |
- int i; |
|
535 |
- |
|
536 |
- if (phrase->len<3) return 0; |
|
537 |
- code=0; |
|
538 |
- for (i=0;i<3;i++) { |
|
539 |
- if (!(phrase->s[i]>='0' && phrase->s[i]<'9')) |
|
540 |
- return 0; |
|
541 |
- code=code*10+phrase->s[i]-'0'; |
|
542 |
- } |
|
543 |
- return code; |
|
544 |
-} |
|
545 |
-#endif |
|
546 |
- |
|
547 |
- |
|
548 |
- |
|
549 |
-/******************************************** |
|
550 |
- * DIAMETER ACCOUNTING |
|
551 |
- ********************************************/ |
|
552 |
-#ifdef DIAM_ACC |
|
553 |
- |
|
554 |
-#define AA_REQUEST 265 |
|
555 |
-#define AA_ANSWER 265 |
|
556 |
- |
|
557 |
-#define ACCOUNTING_REQUEST 271 |
|
558 |
-#define ACCOUNTING_ANSWER 271 |
|
559 |
- |
|
560 |
-static int diam_attrs[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG]; |
|
561 |
- |
|
562 |
-int acc_diam_init() |
|
563 |
-{ |
|
564 |
- int n; |
|
565 |
- int m; |
|
566 |
- |
|
567 |
- n = 0; |
|
568 |
- /* caution: keep these aligned to core acc output */ |
|
569 |
- diam_attrs[n++] = AVP_SIP_METHOD; |
|
570 |
- diam_attrs[n++] = AVP_SIP_FROM_TAG; |
|
571 |
- diam_attrs[n++] = AVP_SIP_TO_TAG; |
|
572 |
- diam_attrs[n++] = AVP_SIP_CALLID; |
|
573 |
- diam_attrs[n++] = AVP_SIP_STATUS; |
|
574 |
- |
|
575 |
- m = extra2int( dia_extra, diam_attrs+n); |
|
576 |
- if (m<0) { |
|
577 |
- LM_ERR("extra names for DIAMETER must be integer AVP codes\n"); |
|
578 |
- return -1; |
|
579 |
- } |
|
580 |
- n += m; |
|
581 |
- |
|
582 |
- m = extra2int( leg_info, diam_attrs+n); |
|
583 |
- if (m<0) { |
|
584 |
- LM_ERR("leg info names for DIAMTER must be integer AVP codes\n"); |
|
585 |
- return -1; |
|
586 |
- } |
|
587 |
- n += m; |
|
588 |
- |
|
589 |
- return 0; |
|
590 |
-} |
|
591 |
- |
|
592 |
- |
|
593 |
-inline unsigned long diam_status(struct sip_msg *rq, int code) |
|
594 |
-{ |
|
595 |
- if ((rq->REQ_METHOD==METHOD_INVITE || rq->REQ_METHOD==METHOD_ACK) |
|
596 |
- && code>=200 && code<300) |
|
597 |
- return AAA_ACCT_START; |
|
598 |
- |
|
599 |
- if ((rq->REQ_METHOD==METHOD_BYE || rq->REQ_METHOD==METHOD_CANCEL)) |
|
600 |
- return AAA_ACCT_STOP; |
|
601 |
- |
|
602 |
- if (code>=200 && code <=300) |
|
603 |
- return AAA_ACCT_EVENT; |
|
604 |
- |
|
605 |
- return -1; |
|
606 |
-} |
|
607 |
- |
|
608 |
- |
|
609 |
-int acc_diam_request( struct sip_msg *req ) |
|
610 |
-{ |
|
611 |
- int attr_cnt; |
|
612 |
- int cnt; |
|
613 |
- AAAMessage *send = NULL; |
|
614 |
- AAA_AVP *avp; |
|
615 |
- struct sip_uri puri; |
|
616 |
- str *uri; |
|
617 |
- int ret; |
|
618 |
- int i; |
|
619 |
- int status; |
|
620 |
- char tmp[2]; |
|
621 |
- unsigned int mid; |
|
622 |
- int m; |
|
623 |
- int o; |
|
624 |
- |
|
625 |
- attr_cnt = core2strar( req, val_arr, int_arr, type_arr ); |
|
626 |
- /* last value is not used */ |
|
627 |
- attr_cnt--; |
|
628 |
- |
|
629 |
- if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) { |
|
630 |
- LM_ERR("failed to create new AAA request\n"); |
|
631 |
- return -1; |
|
632 |
- } |
|
633 |
- |
|
634 |
- m = 0; |
|
635 |
- o = 0; |
|
636 |
- /* AVP_ACCOUNTIG_RECORD_TYPE */ |
|
637 |
- if( (status = diam_status(req, acc_env.code))<0) { |
|
638 |
- LM_ERR("status unknown\n"); |
|
639 |
- goto error; |
|
640 |
- } |
|
641 |
- tmp[0] = status+'0'; |
|
642 |
- tmp[1] = 0; |
|
643 |
- if( (avp=AAACreateAVP(AVP_Accounting_Record_Type, 0, 0, tmp, |
|
644 |
- 1, AVP_DUPLICATE_DATA)) == 0) { |
|
645 |
- LM_ERR("failed to create AVP:no more free memory!\n"); |
|
646 |
- goto error; |
|
647 |
- } |
|
648 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
649 |
- LM_ERR("avp not added \n"); |
|
650 |
- AAAFreeAVP(&avp); |
|
651 |
- goto error; |
|
652 |
- } |
|
653 |
- /* SIP_MSGID AVP */ |
|
654 |
- mid = req->id; |
|
655 |
- if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid), |
|
656 |
- sizeof(mid), AVP_DUPLICATE_DATA)) == 0) { |
|
657 |
- LM_ERR("failed to create AVP:no more free memory!\n"); |
|
658 |
- goto error; |
|
659 |
- } |
|
660 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
661 |
- LM_ERR("avp not added \n"); |
|
662 |
- AAAFreeAVP(&avp); |
|
663 |
- goto error; |
|
664 |
- } |
|
665 |
- |
|
666 |
- /* SIP Service AVP */ |
|
667 |
- if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_ACCOUNTING, |
|
668 |
- SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) { |
|
669 |
- LM_ERR("failed to create AVP:no more free memory!\n"); |
|
670 |
- goto error; |
|
671 |
- } |
|
672 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
673 |
- LM_ERR("avp not added \n"); |
|
674 |
- AAAFreeAVP(&avp); |
|
675 |
- goto error; |
|
676 |
- } |
|
677 |
- |
|
678 |
- /* also the extra attributes */ |
|
679 |
- o = extra2strar( dia_extra, req, val_arr, int_arr, type_arr); |
|
680 |
- attr_cnt += o; |
|
681 |
- m = attr_cnt; |
|
682 |
- |
|
683 |
- /* add attributes */ |
|
684 |
- for(i=0; i<attr_cnt; i++) { |
|
685 |
- if((avp=AAACreateAVP(diam_attrs[i], 0,0, val_arr[i].s, val_arr[i].len, |
|
686 |
- AVP_DUPLICATE_DATA)) == 0) { |
|
687 |
- LM_ERR("failed to create AVP: no more free memory!\n"); |
|
688 |
- goto error; |
|
689 |
- } |
|
690 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
691 |
- LM_ERR("avp not added \n"); |
|
692 |
- AAAFreeAVP(&avp); |
|
693 |
- goto error; |
|
694 |
- } |
|
695 |
- } |
|
696 |
- |
|
697 |
- /* and the leg attributes */ |
|
698 |
- if ( leg_info ) { |
|
699 |
- cnt = legs2strar(leg_info,req,val_arr,int_arr,type_arr,1); |
|
700 |
- do { |
|
701 |
- for (i=0; i<cnt; i++) { |
|
702 |
- if((avp=AAACreateAVP(diam_attrs[attr_cnt+i], 0, 0, |
|
703 |
- val_arr[i].s, val_arr[i].len, AVP_DUPLICATE_DATA)) == 0) { |
|
704 |
- LM_ERR("failed to create AVP: no more free memory!\n"); |
|
705 |
- goto error; |
|
706 |
- } |
|
707 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
708 |
- LM_ERR("avp not added \n"); |
|
709 |
- AAAFreeAVP(&avp); |
|
710 |
- goto error; |
|
711 |
- } |
|
712 |
- } |
|
713 |
- } while ( (cnt=legs2strar(leg_info,req,val_arr,int_arr, |
|
714 |
- type_arr,0))!=0 ); |
|
715 |
- } |
|
716 |
- |
|
717 |
- if (get_uri(req, &uri) < 0) { |
|
718 |
- LM_ERR("failed to get uri, From/To URI not found\n"); |
|
719 |
- goto error; |
|
720 |
- } |
|
721 |
- |
|
722 |
- if (parse_uri(uri->s, uri->len, &puri) < 0) { |
|
723 |
- LM_ERR("failed to parse From/To URI\n"); |
|
724 |
- goto error; |
|
725 |
- } |
|
726 |
- |
|
727 |
- /* Destination-Realm AVP */ |
|
728 |
- if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s, |
|
729 |
- puri.host.len, AVP_DUPLICATE_DATA)) == 0) { |
|
730 |
- LM_ERR("failed to create AVP:no more free memory!\n"); |
|
731 |
- goto error; |
|
732 |
- } |
|
733 |
- |
|
734 |
- if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) { |
|
735 |
- LM_ERR("avp not added \n"); |
|
736 |
- AAAFreeAVP(&avp); |
|
737 |
- goto error; |
|
738 |
- } |
|
739 |
- |
|
740 |
- /* prepare the message to be sent over the network */ |
|
741 |
- if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) { |
|
742 |
- LM_ERR("message buffer not created\n"); |
|
743 |
- goto error; |
|
744 |
- } |
|
745 |
- |
|
746 |
- if(sockfd==AAA_NO_CONNECTION) { |
|
747 |
- sockfd = init_mytcp(diameter_client_host, diameter_client_port); |
|
748 |
- if(sockfd==AAA_NO_CONNECTION) { |
|
749 |
- LM_ERR("failed to reconnect to Diameter client\n"); |
|
750 |
- goto error; |
|
751 |
- } |
|
752 |
- } |
|
753 |
- |
|
754 |
- /* send the message to the DIAMETER client */ |
|
755 |
- ret = tcp_send_recv(sockfd, send->buf.s, send->buf.len, rb, req->id); |
|
756 |
- if(ret == AAA_CONN_CLOSED) { |
|
757 |
- LM_NOTICE("connection to Diameter client closed.It will be " |
|
758 |
- "reopened by the next request\n"); |
|
759 |
- close(sockfd); |
|
760 |
- sockfd = AAA_NO_CONNECTION; |
|
761 |
- goto error; |
|
762 |
- } |
|
763 |
- |
|
764 |
- if(ret != ACC_SUCCESS) { |
|
765 |
- /* a transmission error occurred */ |
|
766 |
- LM_ERR("message sending to the DIAMETER backend authorization " |
|
767 |
- "server failed\n"); |
|
768 |
- goto error; |
|
769 |
- } |
|
770 |
- |
|
771 |
- AAAFreeMessage(&send); |
|
772 |
- /* free memory allocated by extra2strar */ |
|
773 |
- free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); |
|
774 |
- return 1; |
|
775 |
- |
|
776 |
-error: |
|
777 |
- AAAFreeMessage(&send); |
|
778 |
- /* free memory allocated by extra2strar */ |
|
779 |
- free_strar_mem( &(type_arr[m-o]), &(val_arr[m-o]), o, m); |
|
780 |
- return -1; |
|
781 |
-} |
|
782 |
- |
|
783 |
-#endif |
|
784 |
- |
|
785 | 513 |
/** |
786 | 514 |
* @brief execute all acc engines for a SIP request event |
787 | 515 |
*/ |
... | ... |
@@ -13,8 +13,8 @@ |
13 | 13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | 14 |
* GNU General Public License for more details. |
15 | 15 |
* |
16 |
- * You should have received a copy of the GNU General Public License |
|
17 |
- * along with this program; if not, write to the Free Software |
|
16 |
+ * You should have received a copy of the GNU General Public License |
|
17 |
+ * along with this program; if not, write to the Free Software |
|
18 | 18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | 19 |
* |
20 | 20 |
*/ |
... | ... |
@@ -66,7 +66,7 @@ typedef struct acc_extra { |
66 | 66 |
} acc_extra_t; |
67 | 67 |
|
68 | 68 |
typedef int (*core2strar_f)( struct sip_msg *req, str *c_vals, |
69 |
- int *i_vals, char *t_vals); |
|
69 |
+ int *i_vals, char *t_vals); |
|
70 | 70 |
typedef int (*extra2strar_f)(struct acc_extra *extra, struct sip_msg *rq, str *val_arr, |
71 | 71 |
int *int_arr, char *type_arr); |
72 | 72 |
typedef int (*legs2strar_f)( struct acc_extra *legs, struct sip_msg *rq, str *val_arr, |
... | ... |
@@ -52,14 +52,14 @@ |
52 | 52 |
/* Solaris does not provide timersub macro in <sys/time.h> */ |
53 | 53 |
#ifdef __OS_solaris |
54 | 54 |
#define timersub(tvp, uvp, vvp) \ |
55 |
- do { \ |
|
56 |
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ |
|
57 |
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ |
|
58 |
- if ((vvp)->tv_usec < 0) { \ |
|
59 |
- (vvp)->tv_sec--; \ |
|
60 |
- (vvp)->tv_usec += 1000000; \ |
|
61 |
- } \ |
|
62 |
- } while (0) |
|
55 |
+ do { \ |
|
56 |
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ |
|
57 |
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ |
|
58 |
+ if ((vvp)->tv_usec < 0) { \ |
|
59 |
+ (vvp)->tv_sec--; \ |
|
60 |
+ (vvp)->tv_usec += 1000000; \ |
|
61 |
+ } \ |
|
62 |
+ } while (0) |
|
63 | 63 |
#endif // __OS_solaris |
64 | 64 |
|
65 | 65 |
#define TIME_STR_BUFFER_SIZE 20 |
... | ... |
@@ -92,34 +92,34 @@ static int string2time( str* time_str, struct timeval* time_value); |
92 | 92 |
|
93 | 93 |
/* write all basic information to buffers(e.g. start-time ...) */ |
94 | 94 |
static int cdr_core2strar( struct dlg_cell* dlg, |
95 |
- str* values, |
|
96 |
- int* unused, |
|
97 |
- char* types) |
|
95 |
+ str* values, |
|
96 |
+ int* unused, |
|
97 |
+ char* types) |
|
98 | 98 |
{ |
99 |
- str* start = NULL; |
|
100 |
- str* end = NULL; |
|
101 |
- str* duration = NULL; |
|
99 |
+ str* start = NULL; |
|
100 |
+ str* end = NULL; |
|
101 |
+ str* duration = NULL; |
|
102 | 102 |
|
103 |
- if( !dlg || !values || !types) |
|
104 |
- { |
|
105 |
- LM_ERR( "invalid input parameter!\n"); |
|
106 |
- return 0; |
|
107 |
- } |
|
103 |
+ if( !dlg || !values || !types) |
|
104 |
+ { |
|
105 |
+ LM_ERR( "invalid input parameter!\n"); |
|
106 |
+ return 0; |
|
107 |
+ } |
|
108 | 108 |
|
109 |
- start = dlgb.get_dlg_var( dlg, (str*)&cdr_start_str); |
|
110 |
- end = dlgb.get_dlg_var( dlg, (str*)&cdr_end_str); |
|
111 |
- duration = dlgb.get_dlg_var( dlg, (str*)&cdr_duration_str); |
|
109 |
+ start = dlgb.get_dlg_var( dlg, (str*)&cdr_start_str); |
|
110 |
+ end = dlgb.get_dlg_var( dlg, (str*)&cdr_end_str); |
|
111 |
+ duration = dlgb.get_dlg_var( dlg, (str*)&cdr_duration_str); |
|
112 | 112 |
|
113 |
- values[0] = ( start != NULL ? *start : empty_string); |
|
114 |
- types[0] = ( start != NULL ? TYPE_DATE : TYPE_NULL); |
|
113 |
+ values[0] = ( start != NULL ? *start : empty_string); |
|
114 |
+ types[0] = ( start != NULL ? TYPE_DATE : TYPE_NULL); |
|
115 | 115 |
|
116 |
- values[1] = ( end != NULL ? *end : empty_string); |
|
117 |
- types[1] = ( end != NULL ? TYPE_DATE : TYPE_NULL); |
|
116 |
+ values[1] = ( end != NULL ? *end : empty_string); |
|
117 |
+ types[1] = ( end != NULL ? TYPE_DATE : TYPE_NULL); |
|
118 | 118 |
|
119 |
- values[2] = ( duration != NULL ? *duration : empty_string); |
|
120 |
- types[2] = ( duration != NULL ? TYPE_DOUBLE : TYPE_NULL); |
|
119 |
+ values[2] = ( duration != NULL ? *duration : empty_string); |
|
120 |
+ types[2] = ( duration != NULL ? TYPE_DOUBLE : TYPE_NULL); |
|
121 | 121 |
|
122 |
- return MAX_CDR_CORE; |
|
122 |
+ return MAX_CDR_CORE; |
|
123 | 123 |
} |
124 | 124 |
|
125 | 125 |
/* caution: keys need to be aligned to core format */ |
... | ... |
@@ -128,7 +128,7 @@ static db_val_t db_cdr_vals[ MAX_CDR_CORE + MAX_CDR_EXTRA]; |
128 | 128 |
|
129 | 129 |
/* collect all crd data and write it to a syslog */ |
130 | 130 |
static int db_write_cdr( struct dlg_cell* dialog, |
131 |
- struct sip_msg* message) |
|
131 |
+ struct sip_msg* message) |
|
132 | 132 |
{ |
133 | 133 |
int m = 0; |
134 | 134 |
int n = 0; |
... | ... |
@@ -154,9 +154,9 @@ static int db_write_cdr( struct dlg_cell* dialog, |
154 | 154 |
|
155 | 155 |
/* get default values */ |
156 | 156 |
m = cdr_core2strar( dialog, |
157 |
- cdr_value_array, |
|
158 |
- cdr_int_array, |
|
159 |
- cdr_type_array); |
|
157 |
+ cdr_value_array, |
|
158 |
+ cdr_int_array, |
|
159 |
+ cdr_type_array); |
|
160 | 160 |
|
161 | 161 |
for(i=0; i<m; i++) { |
162 | 162 |
db_cdr_keys[i] = &cdr_attrs[i]; |
... | ... |
@@ -203,24 +203,24 @@ static int db_write_cdr( struct dlg_cell* dialog, |
203 | 203 |
} |
204 | 204 |
} |
205 | 205 |
|
206 |
- /* get extra values */ |
|
207 |
- if (message) |
|
208 |
- { |
|
206 |
+ /* get extra values */ |
|
207 |
+ if (message) |
|
208 |
+ { |
|
209 | 209 |
n += extra2strar( cdr_extra, |
210 |
- message, |
|
211 |
- cdr_value_array + m, |
|
212 |
- cdr_int_array + m, |
|
213 |
- cdr_type_array + m); |
|
210 |
+ message, |
|
211 |
+ cdr_value_array + m, |
|
212 |
+ cdr_int_array + m, |
|
213 |
+ cdr_type_array + m); |
|
214 | 214 |
m += n; |
215 |
- } else if (cdr_expired_dlg_enable){ |
|
216 |
- LM_WARN( "fallback to dlg_only search because of message doesn't exist.\n"); |
|
217 |
- m += extra2strar_dlg_only( cdr_extra, |
|
218 |
- dialog, |
|
219 |
- cdr_value_array + m, |
|
220 |
- cdr_int_array + m, |
|
221 |
- cdr_type_array +m, |
|
222 |
- &dlgb); |
|
223 |
- } |
|
215 |
+ } else if (cdr_expired_dlg_enable){ |
|
216 |
+ LM_WARN( "fallback to dlg_only search because of message doesn't exist.\n"); |
|
217 |
+ m += extra2strar_dlg_only( cdr_extra, |
|
218 |
+ dialog, |
|
219 |
+ cdr_value_array + m, |
|
220 |
+ cdr_int_array + m, |
|
221 |
+ cdr_type_array +m, |
|
222 |
+ &dlgb); |
|
223 |
+ } |
|
224 | 224 |
|
225 | 225 |
for( ; i<m; i++) { |
226 | 226 |
db_cdr_keys[i] = &cdr_attrs[i]; |
... | ... |
@@ -256,106 +256,106 @@ static int db_write_cdr( struct dlg_cell* dialog, |
256 | 256 |
return 0; |
257 | 257 |
|
258 | 258 |
error: |
259 |
- /* Free memory allocated by acc_extra.c/extra2strar */ |
|
259 |
+ /* Free memory allocated by acc_extra.c/extra2strar */ |
|
260 | 260 |
free_strar_mem( &(cdr_type_array[m-n]), &(cdr_value_array[m-n]), n, m); |
261 |
- return -1; |
|
261 |
+ return -1; |
|
262 | 262 |
} |
263 | 263 |
|
264 | 264 |
/* collect all crd data and write it to a syslog */ |
265 | 265 |
static int log_write_cdr( struct dlg_cell* dialog, |
266 |
- struct sip_msg* message) |
|
266 |
+ struct sip_msg* message) |
|
267 | 267 |
{ |
268 |
- static char cdr_message[ MAX_SYSLOG_SIZE]; |
|
269 |
- static char* const cdr_message_end = cdr_message + |
|
270 |
- MAX_SYSLOG_SIZE - |
|
271 |
- 2;// -2 because of the string ending '\n\0' |
|
272 |
- char* message_position = NULL; |
|
273 |
- int message_index = 0; |
|
268 |
+ static char cdr_message[ MAX_SYSLOG_SIZE]; |
|
269 |
+ static char* const cdr_message_end = cdr_message + |
|
270 |
+ MAX_SYSLOG_SIZE - |
|
271 |
+ 2;// -2 because of the string ending '\n\0' |
|
272 |
+ char* message_position = NULL; |
|
273 |
+ int message_index = 0; |
|
274 | 274 |
int extra_index = 0; |
275 |
- int counter = 0; |
|
275 |
+ int counter = 0; |
|
276 | 276 |
|
277 | 277 |
if(cdr_log_enable==0) |
278 | 278 |
return 0; |
279 | 279 |
|
280 |
- /* get default values */ |
|
281 |
- message_index = cdr_core2strar( dialog, |
|
282 |
- cdr_value_array, |
|
283 |
- cdr_int_array, |
|
284 |
- cdr_type_array); |
|
285 |
- |
|
286 |
- /* get extra values */ |
|
287 |
- if (message) |
|
288 |
- { |
|
289 |
- extra_index += extra2strar( cdr_extra, |
|
290 |
- message, |
|
291 |
- cdr_value_array + message_index, |
|
292 |
- cdr_int_array + message_index, |
|
293 |
- cdr_type_array + message_index); |
|
294 |
- } else if (cdr_expired_dlg_enable){ |
|
295 |
- LM_DBG("fallback to dlg_only search because of message does not exist.\n"); |
|
296 |
- message_index += extra2strar_dlg_only( cdr_extra, |
|
297 |
- dialog, |
|
298 |
- cdr_value_array + message_index, |
|
299 |
- cdr_int_array + message_index, |
|
300 |
- cdr_type_array + message_index, |
|
301 |
- &dlgb); |
|
302 |
- } |
|
303 |
- message_index += extra_index; |
|
280 |
+ /* get default values */ |
|
281 |
+ message_index = cdr_core2strar( dialog, |
|
282 |
+ cdr_value_array, |
|
283 |
+ cdr_int_array, |
|
284 |
+ cdr_type_array); |
|
304 | 285 |
|
305 |
- for( counter = 0, message_position = cdr_message; |
|
306 |
- counter < message_index ; |
|
307 |
- counter++ ) |
|
308 |
- { |
|
309 |
- const char* const next_message_end = message_position + |
|
310 |
- 2 + // ', ' -> two letters |
|
311 |
- cdr_attrs[ counter].len + |
|
312 |
- 1 + // '=' -> one letter |
|
313 |
- cdr_value_array[ counter].len; |
|
286 |
+ /* get extra values */ |
|
287 |
+ if (message) |
|
288 |
+ { |
|
289 |
+ extra_index += extra2strar( cdr_extra, |
|
290 |
+ message, |
|
291 |
+ cdr_value_array + message_index, |
|
292 |
+ cdr_int_array + message_index, |
|
293 |
+ cdr_type_array + message_index); |
|
294 |
+ } else if (cdr_expired_dlg_enable){ |
|
295 |
+ LM_DBG("fallback to dlg_only search because of message does not exist.\n"); |
|
296 |
+ message_index += extra2strar_dlg_only( cdr_extra, |
|
297 |
+ dialog, |
|
298 |
+ cdr_value_array + message_index, |
|
299 |
+ cdr_int_array + message_index, |
|
300 |
+ cdr_type_array + message_index, |
|
301 |
+ &dlgb); |
|
302 |
+ } |
|
303 |
+ message_index += extra_index; |
|
314 | 304 |
|
315 |
- if( next_message_end >= cdr_message_end || |
|
316 |
- next_message_end < message_position) |
|
317 |
- { |
|
318 |
- LM_WARN("cdr message too long, truncating..\n"); |
|
319 |
- message_position = cdr_message_end; |
|
320 |
- break; |
|
321 |
- } |
|
305 |
+ for( counter = 0, message_position = cdr_message; |
|
306 |
+ counter < message_index ; |
|
307 |
+ counter++ ) |
|
308 |
+ { |
|
309 |
+ const char* const next_message_end = message_position + |
|
310 |
+ 2 + // ', ' -> two letters |
|
311 |
+ cdr_attrs[ counter].len + |
|
312 |
+ 1 + // '=' -> one letter |
|
313 |
+ cdr_value_array[ counter].len; |
|
314 |
+ |
|
315 |
+ if( next_message_end >= cdr_message_end || |
|
316 |
+ next_message_end < message_position) |
|
317 |
+ { |
|
318 |
+ LM_WARN("cdr message too long, truncating..\n"); |
|
319 |
+ message_position = cdr_message_end; |
|
320 |
+ break; |
|
321 |
+ } |
|
322 | 322 |
|
323 |
- if( counter > 0) |
|
324 |
- { |
|
325 |
- *(message_position++) = A_SEPARATOR_CHR; |
|
326 |
- *(message_position++) = A_SEPARATOR_CHR_2; |
|
327 |
- } |
|
323 |
+ if( counter > 0) |
|
324 |
+ { |
|
325 |
+ *(message_position++) = A_SEPARATOR_CHR; |
|
326 |
+ *(message_position++) = A_SEPARATOR_CHR_2; |
|
327 |
+ } |
|
328 | 328 |
|
329 |
- memcpy( message_position, |
|
330 |
- cdr_attrs[ counter].s, |
|
331 |
- cdr_attrs[ counter].len); |
|
329 |
+ memcpy( message_position, |
|
330 |
+ cdr_attrs[ counter].s, |
|
331 |
+ cdr_attrs[ counter].len); |
|
332 | 332 |
|
333 |
- message_position += cdr_attrs[ counter].len; |
|
333 |
+ message_position += cdr_attrs[ counter].len; |
|
334 | 334 |
|
335 |
- *( message_position++) = A_EQ_CHR; |
|
335 |
+ *( message_position++) = A_EQ_CHR; |
|
336 | 336 |
|
337 |
- memcpy( message_position, |
|
338 |
- cdr_value_array[ counter].s, |
|
339 |
- cdr_value_array[ counter].len); |
|
337 |
+ memcpy( message_position, |
|
338 |
+ cdr_value_array[ counter].s, |
|
339 |
+ cdr_value_array[ counter].len); |
|
340 | 340 |
|
341 |
- message_position += cdr_value_array[ counter].len; |
|
342 |
- } |
|
341 |
+ message_position += cdr_value_array[ counter].len; |
|
342 |
+ } |
|
343 | 343 |
|
344 |
- /* terminating line */ |
|
345 |
- *(message_position++) = '\n'; |
|
346 |
- *(message_position++) = '\0'; |
|
344 |
+ /* terminating line */ |
|
345 |
+ *(message_position++) = '\n'; |
|
346 |
+ *(message_position++) = '\0'; |
|
347 | 347 |
|
348 |
- LM_GEN2( cdr_facility, log_level, "%s", cdr_message); |
|
348 |
+ LM_GEN2( cdr_facility, log_level, "%s", cdr_message); |
|
349 | 349 |
|
350 | 350 |
/* free memory allocated by extra2strar, nothing is done in case no extra strings were found by extra2strar */ |
351 |
- free_strar_mem( &(cdr_type_array[message_index-extra_index]), &(cdr_value_array[message_index-extra_index]), |
|
352 |
- extra_index, message_index); |
|
353 |
- return 0; |
|
351 |
+ free_strar_mem( &(cdr_type_array[message_index-extra_index]), &(cdr_value_array[message_index-extra_index]), |
|
352 |
+ extra_index, message_index); |
|
353 |
+ return 0; |
|
354 | 354 |
} |
355 | 355 |
|
356 | 356 |
/* collect all crd data and write it to a syslog */ |
357 | 357 |
static int write_cdr( struct dlg_cell* dialog, |
358 |
- struct sip_msg* message) |
|
358 |
+ struct sip_msg* message) |
|
359 | 359 |
{ |
360 | 360 |
int ret = 0; |
361 | 361 |
|
... | ... |
@@ -377,377 +377,377 @@ static int write_cdr( struct dlg_cell* dialog, |
377 | 377 |
|
378 | 378 |
/* convert a string into a timeval struct */ |
379 | 379 |
static int string2time( str* time_str, struct timeval* time_value) |
380 |
-{ |
|
381 |
- char* dot_address = NULL; |
|
382 |
- int dot_position = -1; |
|
383 |
- char zero_terminated_value[TIME_STR_BUFFER_SIZE]; |
|
384 |
- |
|
385 |
- if( !time_str) |
|
386 |
- { |
|
387 |
- LM_ERR( "time_str is empty!"); |
|
388 |
- return -1; |
|
389 |
- } |
|
390 |
- |
|
391 |
- if( time_str->len >= TIME_STR_BUFFER_SIZE) |
|
392 |
- { |
|
393 |
- LM_ERR( "time_str is too long %d >= %d!", |
|
394 |
- time_str->len, |
|
395 |
- TIME_STR_BUFFER_SIZE); |
|
396 |
- return -1; |
|
397 |
- } |
|
398 |
- |
|
399 |
- memcpy( zero_terminated_value, time_str->s, time_str->len); |
|
400 |
- zero_terminated_value[time_str->len] = '\0'; |
|
401 |
- |
|
402 |
- dot_address = strchr( zero_terminated_value, time_separator); |
|
403 |
- |
|
404 |
- if( !dot_address) |
|
405 |
- { |
|
406 |
- LM_ERR( "failed to find separator('%c') in '%s'!\n", |
|
407 |
- time_separator, |
|
408 |
- zero_terminated_value); |
|
409 |
- return -1; |
|
410 |
- } |
|
411 |
- |
|
412 |
- dot_position = dot_address-zero_terminated_value + 1; |
|
413 |
- |
|
414 |
- if( dot_position >= strlen(zero_terminated_value) || |
|
415 |
- strchr(dot_address + 1, time_separator)) |
|
416 |
- { |
|
417 |
- LM_ERR( "invalid time-string '%s'\n", zero_terminated_value); |
|
418 |
- return -1; |
|
419 |
- } |
|
420 |
- |
|
421 |
- time_value->tv_sec = strtol( zero_terminated_value, (char **)NULL, 10); |
|
422 |
- time_value->tv_usec = strtol( dot_address + 1, (char **)NULL, 10) * 1000; // restore usec precision |
|
423 |
- return 0; |
|
380 |
+{ |
|
381 |
+ char* dot_address = NULL; |
|
382 |
+ int dot_position = -1; |
|
383 |
+ char zero_terminated_value[TIME_STR_BUFFER_SIZE]; |
|
384 |
+ |
|
385 |
+ if( !time_str) |
|
386 |
+ { |
|
387 |
+ LM_ERR( "time_str is empty!"); |
|
388 |
+ return -1; |
|
389 |
+ } |
|
390 |
+ |
|
391 |
+ if( time_str->len >= TIME_STR_BUFFER_SIZE) |
|
392 |
+ { |
|
393 |
+ LM_ERR( "time_str is too long %d >= %d!", |
|
394 |
+ time_str->len, |
|
395 |
+ TIME_STR_BUFFER_SIZE); |
|
396 |
+ return -1; |
|
397 |
+ } |
|
398 |
+ |
|
399 |
+ memcpy( zero_terminated_value, time_str->s, time_str->len); |
|
400 |
+ zero_terminated_value[time_str->len] = '\0'; |
|
401 |
+ |
|
402 |
+ dot_address = strchr( zero_terminated_value, time_separator); |
|
403 |
+ |
|
404 |
+ if( !dot_address) |
|
405 |
+ { |
|
406 |
+ LM_ERR( "failed to find separator('%c') in '%s'!\n", |
|
407 |
+ time_separator, |
|
408 |
+ zero_terminated_value); |
|
409 |
+ return -1; |
|
410 |
+ } |
|
411 |
+ |
|
412 |
+ dot_position = dot_address-zero_terminated_value + 1; |
|
413 |
+ |
|
414 |
+ if( dot_position >= strlen(zero_terminated_value) || |
|
415 |
+ strchr(dot_address + 1, time_separator)) |
|
416 |
+ { |
|
417 |
+ LM_ERR( "invalid time-string '%s'\n", zero_terminated_value); |
|
418 |
+ return -1; |
|
419 |
+ } |
|
420 |
+ |
|
421 |
+ time_value->tv_sec = strtol( zero_terminated_value, (char **)NULL, 10); |
|
422 |
+ time_value->tv_usec = strtol( dot_address + 1, (char **)NULL, 10) * 1000; // restore usec precision |
|
423 |
+ return 0; |
|
424 | 424 |
} |
425 | 425 |
|
426 | 426 |
/* convert a timeval struct into a string */ |
427 | 427 |
static int time2string( struct timeval* time_value, str* time_str) |
428 | 428 |
{ |
429 |
- int buffer_length; |
|
430 |
- |
|
431 |
- if( !time_value) |
|
432 |
- { |
|
433 |
- LM_ERR( "time_value or any of its fields is empty!\n"); |
|
434 |
- return -1; |
|
435 |
- } |
|
436 |
- |
|
437 |
- buffer_length = snprintf( time_buffer, |
|
438 |
- TIME_BUFFER_LENGTH, |
|
439 |
- "%ld%c%03d", |
|
440 |
- (long int)time_value->tv_sec, |
|
441 |
- time_separator, |
|
442 |
- (int)(time_value->tv_usec/1000)); |
|
443 |
- |
|
444 |
- if( buffer_length < 0) |
|
445 |
- { |
|
446 |
- LM_ERR( "failed to write to buffer.\n"); |
|
447 |
- return -1; |
|
448 |
- } |
|
449 |
- |
|
450 |
- time_str->s = time_buffer; |
|
451 |
- time_str->len = buffer_length; |
|
452 |
- return 0; |
|
429 |
+ int buffer_length; |
|
430 |
+ |
|
431 |
+ if( !time_value) |
|
432 |
+ { |
|
433 |
+ LM_ERR( "time_value or any of its fields is empty!\n"); |
|
434 |
+ return -1; |
|
435 |
+ } |
|
436 |
+ |
|
437 |
+ buffer_length = snprintf( time_buffer, |
|
438 |
+ TIME_BUFFER_LENGTH, |
|
439 |
+ "%ld%c%03d", |
|
440 |
+ (long int)time_value->tv_sec, |
|
441 |
+ time_separator, |
|
442 |
+ (int)(time_value->tv_usec/1000)); |
|
443 |
+ |
|
444 |
+ if( buffer_length < 0) |
|
445 |
+ { |
|
446 |
+ LM_ERR( "failed to write to buffer.\n"); |
|
447 |
+ return -1; |
|
448 |
+ } |
|
449 |
+ |
|
450 |
+ time_str->s = time_buffer; |
|
451 |
+ time_str->len = buffer_length; |
|
452 |
+ return 0; |
|
453 | 453 |
} |
454 | 454 |
|
455 | 455 |
/* set the duration in the dialog struct */ |
456 | 456 |
static int set_duration( struct dlg_cell* dialog) |
457 | 457 |
{ |
458 |
- struct timeval start_time; |
|
459 |
- struct timeval end_time; |
|
460 |
- struct timeval duration_time; |
|
461 |
- str duration_str; |
|
462 |
- |
|
463 |
- if( !dialog) |
|
464 |
- { |
|
465 |
- LM_ERR("dialog is empty!\n"); |
|
466 |
- return -1; |
|
467 |
- } |
|
468 |
- |
|
469 |
- if ( string2time( dlgb.get_dlg_var( dialog, (str*)&cdr_start_str), &start_time) < 0) { |
|
470 |
- LM_ERR( "failed to extract start time\n"); |
|
471 |
- return -1; |
|
472 |
- } |
|
473 |
- if ( string2time( dlgb.get_dlg_var( dialog, (str*)&cdr_end_str), &end_time) < 0) { |
|
474 |
- LM_ERR( "failed to extract end time\n"); |
|
475 |
- return -1; |
|
476 |
- } |
|
477 |
- |
|
478 |
- timersub(&end_time, &start_time, &duration_time); |
|
479 |
- |
|
480 |
- if( time2string(&duration_time, &duration_str) < 0) { |
|
481 |
- LM_ERR( "failed to convert current time to string\n"); |
|
482 |
- return -1; |
|
483 |
- } |
|
484 |
- |
|
485 |
- if( dlgb.set_dlg_var( dialog, |
|
486 |
- (str*)&cdr_duration_str, |
|
487 |
- (str*)&duration_str) != 0) |
|
488 |
- { |
|
489 |
- LM_ERR( "failed to set duration time"); |
|
490 |
- return -1; |
|
491 |
- } |
|
492 |
- |
|
493 |
- return 0; |
|
458 |
+ struct timeval start_time; |
|
459 |
+ struct timeval end_time; |
|
460 |
+ struct timeval duration_time; |
|
461 |
+ str duration_str; |
|
462 |
+ |
|
463 |
+ if( !dialog) |
|
464 |
+ { |
|
465 |
+ LM_ERR("dialog is empty!\n"); |
|
466 |
+ return -1; |
|
467 |
+ } |
|
468 |
+ |
|
469 |
+ if ( string2time( dlgb.get_dlg_var( dialog, (str*)&cdr_start_str), &start_time) < 0) { |
|
470 |
+ LM_ERR( "failed to extract start time\n"); |
|
471 |
+ return -1; |
|
472 |
+ } |
|
473 |
+ if ( string2time( dlgb.get_dlg_var( dialog, (str*)&cdr_end_str), &end_time) < 0) { |
|
474 |
+ LM_ERR( "failed to extract end time\n"); |
|
475 |
+ return -1; |
|
476 |
+ } |
|
477 |
+ |
|
478 |
+ timersub(&end_time, &start_time, &duration_time); |
|
479 |
+ |
|
480 |
+ if( time2string(&duration_time, &duration_str) < 0) { |
|
481 |
+ LM_ERR( "failed to convert current time to string\n"); |
|
482 |
+ return -1; |
|
483 |
+ } |
|
484 |
+ |
|
485 |
+ if( dlgb.set_dlg_var( dialog, |
|
486 |
+ (str*)&cdr_duration_str, |
|
487 |
+ (str*)&duration_str) != 0) |
|
488 |
+ { |
|
489 |
+ LM_ERR( "failed to set duration time"); |
|
490 |
+ return -1; |
|
491 |
+ } |
|
492 |
+ |
|
493 |
+ return 0; |
|
494 | 494 |
} |
495 | 495 |
|
496 | 496 |
/* set the current time as start-time in the dialog struct */ |
497 | 497 |
static int set_start_time( struct dlg_cell* dialog) |
498 | 498 |
{ |
499 |
- struct timeval current_time; |
|
500 |
- str start_time; |
|
501 |
- |
|
502 |
- if( !dialog) |
|
503 |
- { |
|
504 |
- LM_ERR("dialog is empty!\n"); |
|
505 |
- return -1; |
|
506 |
- } |
|
507 |
- |
|
508 |
- if( gettimeofday( ¤t_time, NULL) < 0) |
|
509 |
- { |
|
510 |
- LM_ERR( "failed to get current time!\n"); |
|
511 |
- return -1; |
|
512 |
- } |
|
513 |
- |
|
514 |
- if( time2string(¤t_time, &start_time) < 0) { |
|
515 |
- LM_ERR( "failed to convert current time to string\n"); |
|
516 |
- return -1; |
|
517 |
- } |
|
518 |
- |
|
519 |
- if( dlgb.set_dlg_var( dialog, |
|
520 |
- (str*)&cdr_start_str, |
|
521 |
- (str*)&start_time) != 0) |
|
522 |
- { |
|
523 |
- LM_ERR( "failed to set start time\n"); |
|
524 |
- return -1; |
|
525 |
- } |
|
526 |
- |
|
527 |
- if( dlgb.set_dlg_var( dialog, |
|
528 |
- (str*)&cdr_end_str, |
|
529 |
- (str*)&start_time) != 0) |
|
530 |
- { |
|
531 |
- LM_ERR( "failed to set initiation end time\n"); |
|
532 |
- return -1; |
|
533 |
- } |
|
534 |
- |
|
535 |
- if( dlgb.set_dlg_var( dialog, |
|
536 |
- (str*)&cdr_duration_str, |
|
537 |
- (str*)&zero_duration) != 0) |
|
538 |
- { |
|
539 |
- LM_ERR( "failed to set initiation duration time\n"); |
|
540 |
- return -1; |
|
541 |
- } |
|
542 |
- |
|
543 |
- return 0; |
|
499 |
+ struct timeval current_time; |
|
500 |
+ str start_time; |
|
501 |
+ |
|
502 |
+ if( !dialog) |
|
503 |
+ { |
|
504 |
+ LM_ERR("dialog is empty!\n"); |
|
505 |
+ return -1; |
|
506 |
+ } |
|
507 |
+ |
|
508 |
+ if( gettimeofday( ¤t_time, NULL) < 0) |
|
509 |
+ { |
|
510 |
+ LM_ERR( "failed to get current time!\n"); |
|
511 |
+ return -1; |
|
512 |
+ } |
|
513 |
+ |
|
514 |
+ if( time2string(¤t_time, &start_time) < 0) { |
|
515 |
+ LM_ERR( "failed to convert current time to string\n"); |
|
516 |
+ return -1; |
|
517 |
+ } |
|
518 |
+ |
|
519 |
+ if( dlgb.set_dlg_var( dialog, |
|
520 |
+ (str*)&cdr_start_str, |
|
521 |
+ (str*)&start_time) != 0) |
|
522 |
+ { |
|
523 |
+ LM_ERR( "failed to set start time\n"); |
|
524 |
+ return -1; |
|
525 |
+ } |
|
526 |
+ |
|
527 |
+ if( dlgb.set_dlg_var( dialog, |
|
528 |
+ (str*)&cdr_end_str, |
|
529 |
+ (str*)&start_time) != 0) |
|
530 |
+ { |
|
531 |
+ LM_ERR( "failed to set initiation end time\n"); |
|
532 |
+ return -1; |
|
533 |
+ } |
|
534 |
+ |
|
535 |
+ if( dlgb.set_dlg_var( dialog, |
|
536 |
+ (str*)&cdr_duration_str, |
|
537 |
+ (str*)&zero_duration) != 0) |
|
538 |
+ { |
|
539 |
+ LM_ERR( "failed to set initiation duration time\n"); |
|
540 |
+ return -1; |
|
541 |
+ } |
|
542 |
+ |
|
543 |
+ return 0; |
|
544 | 544 |
} |
545 | 545 |
|
546 | 546 |
/* set the current time as end-time in the dialog struct */ |
547 | 547 |
static int set_end_time( struct dlg_cell* dialog) |
548 | 548 |
{ |
549 |
- struct timeval current_time; |
|
550 |
- str end_time; |
|
551 |
- |
|
552 |
- if( !dialog) |
|
553 |
- { |
|
554 |
- LM_ERR("dialog is empty!\n"); |
|
555 |
- return -1; |
|
556 |
- } |
|
557 |
- |
|
558 |
- if( gettimeofday( ¤t_time, NULL) < 0) |
|
559 |
- { |
|
560 |
- LM_ERR( "failed to set time!\n"); |
|
561 |
- return -1; |
|
562 |
- } |
|
563 |
- |
|
564 |
- if( time2string(¤t_time, &end_time) < 0) { |
|
565 |
- LM_ERR( "failed to convert current time to string\n"); |
|
566 |
- return -1; |
|
567 |
- } |
|
568 |
- |
|
569 |
- if( dlgb.set_dlg_var( dialog, |
|
570 |
- (str*)&cdr_end_str, |
|
571 |
- (str*)&end_time) != 0) |
|
572 |
- { |
|
573 |
- LM_ERR( "failed to set start time"); |
|
574 |
- return -1; |
|
575 |
- } |
|
576 |
- |
|
577 |
- return 0; |
|
549 |
+ struct timeval current_time; |
|
550 |
+ str end_time; |
|
551 |
+ |
|
552 |
+ if( !dialog) |
|
553 |
+ { |
|
554 |
+ LM_ERR("dialog is empty!\n"); |
|
555 |
+ return -1; |
|
556 |
+ } |
|
557 |
+ |
|
558 |
+ if( gettimeofday( ¤t_time, NULL) < 0) |
|
559 |
+ { |
|
560 |
+ LM_ERR( "failed to set time!\n"); |
|
561 |
+ return -1; |
|
562 |
+ } |
|
563 |
+ |
|
564 |
+ if( time2string(¤t_time, &end_time) < 0) { |
|
565 |
+ LM_ERR( "failed to convert current time to string\n"); |
|
566 |
+ return -1; |
|
567 |
+ } |
|
568 |
+ |
|
569 |
+ if( dlgb.set_dlg_var( dialog, |
|
570 |
+ (str*)&cdr_end_str, |
|
571 |
+ (str*)&end_time) != 0) |
|
572 |
+ { |
|
573 |
+ LM_ERR( "failed to set start time"); |
|
574 |
+ return -1; |
|
575 |
+ } |
|
576 |
+ |
|
577 |
+ return 0; |
|
578 | 578 |
} |
579 | 579 |
|
580 | 580 |
/* callback for a confirmed (INVITE) dialog. */ |
581 | 581 |
static void cdr_on_start( struct dlg_cell* dialog, |
582 |
- int type, |
|
583 |
- struct dlg_cb_params* params) |
|
582 |
+ int type, |
|
583 |
+ struct dlg_cb_params* params) |
|
584 | 584 |
{ |
585 |
- if( !dialog ) |
|
586 |
- { |
|
587 |
- LM_ERR("invalid values\n!"); |
|
588 |
- return; |
|
589 |
- } |
|
590 |
- |
|
591 |
- if( cdr_start_on_confirmed == 0) |
|
592 |
- { |
|
593 |
- return; |
|
594 |
- } |
|
595 |
- |
|
596 |
- if( set_start_time( dialog) != 0) |
|
597 |
- { |
|
598 |
- LM_ERR( "failed to set start time!\n"); |
|
599 |
- return; |
|
600 |
- } |
|
585 |
+ if( !dialog ) |
|
586 |
+ { |
|
587 |
+ LM_ERR("invalid values\n!"); |
|
588 |
+ return; |
|
589 |
+ } |
|
590 |
+ |
|
591 |
+ if( cdr_start_on_confirmed == 0) |
|
592 |
+ { |
|
593 |
+ return; |
|
594 |
+ } |
|
595 |
+ |
|
596 |
+ if( set_start_time( dialog) != 0) |
|
597 |
+ { |
|
598 |
+ LM_ERR( "failed to set start time!\n"); |
|
599 |
+ return; |
|
600 |
+ } |
|
601 | 601 |
} |
602 | 602 |
|
603 | 603 |
/* callback for a failure during a dialog. */ |
604 | 604 |
static void cdr_on_failed( struct dlg_cell* dialog, |
605 |
- int type, |
|
606 |
- struct dlg_cb_params* params) |
|
605 |
+ int type, |
|
606 |
+ struct dlg_cb_params* params) |
|
607 | 607 |
{ |
608 |
- struct sip_msg* msg = 0; |
|
609 |
- |
|
610 |
- if( !dialog || !params) |
|
611 |
- { |
|
612 |
- LM_ERR("invalid values\n!"); |
|
613 |
- return; |
|
614 |
- } |
|
615 |
- |
|
616 |
- if( params->rpl && params->rpl != FAKED_REPLY) |
|
617 |
- { |
|
618 |
- msg = params->rpl; |
|
619 |
- } |
|
620 |
- else if( params->req) |
|
621 |
- { |
|
622 |
- msg = params->req; |
|
623 |
- } |
|
624 |
- else |
|
625 |
- { |
|
626 |
- LM_ERR( "request and response are invalid!"); |
|
627 |
- return; |
|
628 |
- } |
|
629 |
- |
|
630 |
- if( write_cdr( dialog, msg) != 0) |
|
631 |
- { |
|
632 |
- LM_ERR( "failed to write cdr!\n"); |
|
633 |
- return; |
|
634 |
- } |
|
608 |
+ struct sip_msg* msg = 0; |
|
609 |
+ |
|
610 |
+ if( !dialog || !params) |
|
611 |
+ { |
|
612 |
+ LM_ERR("invalid values\n!"); |
|
613 |
+ return; |
|
614 |
+ } |
|
615 |
+ |
|
616 |
+ if( params->rpl && params->rpl != FAKED_REPLY) |
|
617 |
+ { |
|
618 |
+ msg = params->rpl; |
|
619 |
+ } |
|
620 |
+ else if( params->req) |
|
621 |
+ { |
|
622 |
+ msg = params->req; |
|
623 |
+ } |
|
624 |
+ else |
|
625 |
+ { |
|
626 |
+ LM_ERR( "request and response are invalid!"); |
|
627 |
+ return; |
|
628 |
+ } |
|
629 |
+ |
|
630 |
+ if( write_cdr( dialog, msg) != 0) |
|
631 |
+ { |
|
632 |
+ LM_ERR( "failed to write cdr!\n"); |
|
633 |
+ return; |
|
634 |
+ } |
|
635 | 635 |
} |
636 | 636 |
|
637 | 637 |
/* callback for the finish of a dialog (reply to BYE). */ |
638 | 638 |
void cdr_on_end_confirmed( struct dlg_cell* dialog, |
639 |
- int type, |
|
640 |
- struct dlg_cb_params* params) |
|
639 |
+ int type, |
|
640 |
+ struct dlg_cb_params* params) |
|
641 | 641 |
{ |
642 |
- if( !dialog || !params ) |
|
643 |
- { |
|
644 |
- LM_ERR("invalid values\n!"); |
|
645 |
- return; |
|
646 |
- } |
|
647 |
- |
|
648 |
- if( write_cdr( dialog, params->req) != 0) |
|
649 |
- { |
|
650 |
- LM_ERR( "failed to write cdr!\n"); |
|
651 |
- return; |
|
652 |
- } |
|
642 |
+ if( !dialog || !params ) |
|
643 |
+ { |
|
644 |
+ LM_ERR("invalid values\n!"); |
|
645 |
+ return; |
|
646 |
+ } |
|
647 |
+ |
|
648 |
+ if( write_cdr( dialog, params->req) != 0) |
|
649 |
+ { |
|
650 |
+ LM_ERR( "failed to write cdr!\n"); |
|
651 |
+ return; |
|
652 |
+ } |
|
653 | 653 |
} |
654 | 654 |
|
655 | 655 |
/* callback for the end of a dialog (BYE). */ |
656 | 656 |
static void cdr_on_end( struct dlg_cell* dialog, |
657 |
- int type, |
|
658 |
- struct dlg_cb_params* params) |
|
657 |
+ int type, |
|
658 |
+ struct dlg_cb_params* params) |
|
659 | 659 |
{ |
660 |
- if( !dialog ) |
|
661 |
- { |
|
662 |
- LM_ERR("invalid values\n!"); |
|
663 |
- return; |
|
664 |
- } |
|
665 |
- |
|
666 |
- if( set_end_time( dialog) != 0) |
|
667 |
- { |
|
668 |
- LM_ERR( "failed to set end time!\n"); |
|
669 |
- return; |
|
670 |
- } |
|
671 |
- |
|
672 |
- if( set_duration( dialog) != 0) |
|
673 |
- { |
|
674 |
- LM_ERR( "failed to set duration!\n"); |
|
675 |
- return; |
|
676 |
- } |
|
660 |
+ if( !dialog ) |
|
661 |
+ { |
|
662 |
+ LM_ERR("invalid values\n!"); |
|
663 |
+ return; |
|
664 |
+ } |
|
665 |
+ |
|
666 |
+ if( set_end_time( dialog) != 0) |
|
667 |
+ { |
|
668 |
+ LM_ERR( "failed to set end time!\n"); |
|
669 |
+ return; |
|
670 |
+ } |
|
671 |
+ |
|
672 |
+ if( set_duration( dialog) != 0) |
|
673 |
+ { |
|
674 |
+ LM_ERR( "failed to set duration!\n"); |
|
675 |
+ return; |
|
676 |
+ } |
|
677 | 677 |
} |
678 | 678 |
|
679 | 679 |
/* callback for an expired dialog. */ |
680 | 680 |
static void cdr_on_expired( struct dlg_cell* dialog, |
681 |
- int type, |
|
682 |
- struct dlg_cb_params* params) |
|
681 |
+ int type, |
|
682 |
+ struct dlg_cb_params* params) |
|
683 | 683 |
{ |
684 |
- if( !dialog || !params) |
|
685 |
- { |
|
686 |
- LM_ERR("invalid values\n!"); |
|
687 |
- return; |
|
688 |
- } |
|
689 |
- |
|
690 |
- LM_DBG("dialog '%p' expired!\n", dialog); |
|
691 |
- /* compute duration for timed out acknowledged dialog */ |
|
684 |
+ if( !dialog || !params) |
|
685 |
+ { |
|
686 |
+ LM_ERR("invalid values\n!"); |
|
687 |
+ return; |
|
688 |
+ } |
|
689 |
+ |
|
690 |
+ LM_DBG("dialog '%p' expired!\n", dialog); |
|
691 |
+ /* compute duration for timed out acknowledged dialog */ |
|
692 | 692 |
if ( params && params->dlg_data ) { |
693 | 693 |
if ( (void*)CONFIRMED_DIALOG_STATE == params->dlg_data) { |
694 | 694 |
if( set_end_time( dialog) != 0) |
695 | 695 |
{ |
696 | 696 |
LM_ERR( "failed to set end time!\n"); |
697 | 697 |
return; |
698 |
- } |
|
699 |
- |
|
698 |
+ } |
|
699 |
+ |
|
700 | 700 |
if( set_duration( dialog) != 0) |
701 | 701 |
{ |
702 | 702 |
LM_ERR( "failed to set duration!\n"); |
703 | 703 |
return; |
704 | 704 |
} |
705 |
- |
|
705 |
+ |
|
706 | 706 |
} |
707 | 707 |
} |
708 | 708 |
|
709 |
- if( cdr_expired_dlg_enable && (write_cdr( dialog, 0) != 0)) |
|
710 |
- { |
|
711 |
- LM_ERR( "failed to write cdr!\n"); |
|
712 |
- return; |
|
713 |
- } |
|
709 |
+ if( cdr_expired_dlg_enable && (write_cdr( dialog, 0) != 0)) |
|
710 |
+ { |
|
711 |
+ LM_ERR( "failed to write cdr!\n"); |
|
712 |
+ return; |
|
713 |
+ } |
|
714 | 714 |
} |
715 | 715 |
|
716 | 716 |
/* callback for the cleanup of a dialog. */ |
717 | 717 |
static void cdr_on_destroy( struct dlg_cell* dialog, |
718 |
- int type, |
|
719 |
- struct dlg_cb_params* params) |
|
718 |
+ int type, |
|
719 |
+ struct dlg_cb_params* params) |
|
720 | 720 |
{ |
721 |
- if( !dialog ) |
|
722 |
- { |
|
723 |
- LM_ERR("invalid values\n!"); |
|
724 |
- return; |
|
725 |
- } |
|
721 |
+ if( !dialog ) |
|
722 |
+ { |
|
723 |
+ LM_ERR("invalid values\n!"); |
|
724 |
+ return; |
|
725 |
+ } |
|
726 | 726 |
|
727 |
- LM_DBG("dialog '%p' destroyed!\n", dialog); |
|
727 |
+ LM_DBG("dialog '%p' destroyed!\n", dialog); |
|
728 | 728 |
} |
729 | 729 |
|
730 | 730 |
/* callback for the creation of a dialog. */ |
731 | 731 |
static void cdr_on_create( struct dlg_cell* dialog, |
732 |
- int type, |
|
733 |
- struct dlg_cb_params* params) |
|
732 |
+ int type, |
|
733 |
+ struct dlg_cb_params* params) |
|
734 | 734 |
{ |
735 |
- if( !dialog ) |
|
736 |
- { |
|
737 |
- LM_ERR( "invalid values\n!"); |
|
738 |
- return; |
|
739 |
- } |
|
740 |
- |
|
741 |
- if( cdr_enable == 0) |
|
742 |
- { |
|
743 |
- return; |
|
744 |
- } |
|
745 |
- |
|
746 |
- if( dlgb.register_dlgcb( dialog, DLGCB_CONFIRMED, cdr_on_start, 0, 0) != 0) |
|
747 |
- { |
|
748 |
- LM_ERR("can't register create dialog CONFIRM callback\n"); |
|
749 |
- return; |
|
750 |
- } |
|
735 |
+ if( !dialog ) |
|
736 |
+ { |
|
737 |
+ LM_ERR( "invalid values\n!"); |
|
738 |
+ return; |
|
739 |
+ } |
|
740 |
+ |
|
741 |
+ if( cdr_enable == 0) |
|
742 |
+ { |
|
743 |
+ return; |
|
744 |
+ } |
|
745 |
+ |
|
746 |
+ if( dlgb.register_dlgcb( dialog, DLGCB_CONFIRMED, cdr_on_start, 0, 0) != 0) |
|
747 |
+ { |
|
748 |
+ LM_ERR("can't register create dialog CONFIRM callback\n"); |
|
749 |
+ return; |
|
750 |
+ } |
|
751 | 751 |
|
752 | 752 |
if(_acc_cdr_on_failed==1) { |
753 | 753 |
if( dlgb.register_dlgcb( dialog, DLGCB_FAILED, cdr_on_failed, 0, 0) != 0) |
... | ... |
@@ -757,60 +757,60 @@ static void cdr_on_create( struct dlg_cell* dialog, |
757 | 757 |
} |
758 | 758 |
} |
759 | 759 |
|
760 |
- if( dlgb.register_dlgcb( dialog, DLGCB_TERMINATED, cdr_on_end, 0, 0) != 0) |
|
761 |
- { |
|
762 |
- LM_ERR("can't register create dialog TERMINATED callback\n"); |
|
763 |
- return; |
|
764 |
- } |
|
765 |
- |
|
766 |
- if( dlgb.register_dlgcb( dialog, DLGCB_TERMINATED_CONFIRMED, cdr_on_end_confirmed, 0, 0) != 0) |
|
767 |
- { |
|
768 |
- LM_ERR("can't register create dialog TERMINATED CONFIRMED callback\n"); |
|
769 |
- return; |
|
770 |
- } |
|
< |