3 * Copyright (C) 2015 Voxbone SA
5 * This file is part of SIP-Router, a free SIP server.
7 * SIP-Router is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version
12 * SIP-Router is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "../../core/sr_module.h"
25 #include "../../core/parser/parse_param.h"
26 #include "../../core/data_lump.h"
27 #include "../../core/mem/mem.h"
28 #include "../../core/mod_fix.h"
29 #include "../../core/parser/parse_content.h"
30 #include "../../core/parser/parse_body.h"
31 #include "../../core/parser/parser_f.h"
32 #include "../../core/trim.h"
41 static int sipt_set_bci_1(struct sip_msg *msg, char *_charge_indicator, char *_called_status, char * _called_category, char * _e2e_indicator);
42 static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char * _nai);
43 static int sipt_destination2(struct sip_msg *msg, char *_destination, char *_hops, char * _nai, char * _terminator);
44 static int sipt_forwarding(struct sip_msg *msg, char *_fwdnumber, char * _nai);
45 static int sipt_set_calling(struct sip_msg *msg, char *_origin, char *_nai, char *_pres, char * _screen);
46 static int sipt_get_hop_counter(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
47 static int sipt_get_event_info(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
48 static int sipt_get_cpc(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
49 static int sipt_get_calling_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
50 static int sipt_get_calling_party(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
51 static int sipt_get_presentation(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
52 static int sipt_get_screening(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
53 static int sipt_get_called_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
54 static int sipt_get_called_party(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
55 static int sipt_get_charge_indicator(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
57 static int sipt_get_redirection_info(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
58 static int sipt_get_redirection_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
59 static int sipt_get_redirection_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
61 static int sipt_get_redirection_reason(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
62 static int sipt_get_original_redirection_reason(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
63 static int sipt_get_redirecting_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
64 static int sipt_get_redirecting_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
65 static int sipt_get_original_called_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
66 static int sipt_get_original_called_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
67 static int sipt_get_generic_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
68 static int sipt_get_generic_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
70 static int sipt_has_isup_body(struct sip_msg *msg, char *type, char *str2 );
73 int sipt_parse_pv_name(pv_spec_p sp, str *in);
74 static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
76 typedef struct _sipt_pv {
81 typedef struct sipt_header_map
85 struct sipt_subtype_map
92 static sipt_header_map_t sipt_header_mapping[] =
94 {"CALLING_PARTY_CATEGORY", ISUP_PARM_CALLING_PARTY_CAT,
96 {"CPC", ISUP_PARM_CALLING_PARTY_CAT,
98 {"CALLING_PARTY_NUMBER", ISUP_PARM_CALLING_PARTY_NUM,
99 {{"NATURE_OF_ADDRESS", 1},
105 {"CALLED_PARTY_NUMBER", ISUP_PARM_CALLED_PARTY_NUM,
106 {{"NATURE_OF_ADDRESS", 1},
110 {"HOP_COUNTER", ISUP_PARM_HOP_COUNTER,
112 {"EVENT_INFO", ISUP_PARM_EVENT_INFO,
114 {"BACKWARD_CALL_INDICATOR", ISUP_PARM_BACKWARD_CALL_IND,
115 {{"CHARGE_INDICATOR", 1},
118 {"REDIRECTION_INFO", ISUP_PARM_DIVERSION_INFORMATION,
120 {"REDIRECTION_NUMBER", ISUP_PARM_REDIRECTION_NUMBER,
121 {{"NATURE_OF_ADDRESS", 1},
125 {"REDIRECTION_INFORMATION", ISUP_PARM_REDIRECTION_INFO,
127 {"ORIGINAL_REASON", 2},
130 {"REDIRECTING_NUMBER", ISUP_PARM_REDIRECTING_NUMBER,
131 {{"NATURE_OF_ADDRESS", 1},
135 {"ORIGINAL_CALLED_NUMBER", ISUP_PARM_ORIGINAL_CALLED_NUM,
136 {{"NATURE_OF_ADDRESS", 1},
140 {"GENERIC_NUMBER", ISUP_PARM_GENERIC_ADDR,
141 {{"NATURE_OF_ADDRESS", 1},
150 static int mod_init(void);
151 static void mod_destroy(void);
155 static int fixup_str_str_str(void** param, int param_no)
157 if(param_no == 1 || param_no == 2 || param_no == 3 || param_no == 4)
159 return fixup_str_null(param, 1);
164 static int fixup_free_str_str_str(void** param, int param_no)
166 if(param_no == 1 || param_no == 2 || param_no == 3 || param_no == 4)
168 return fixup_free_str_null(param, 1);
174 static cmd_export_t cmds[]={
175 {"sipt_destination", /* action name as in scripts */
176 (cmd_function)sipt_destination, /* C function name */
177 3, /* number of parameters */
178 fixup_str_str_str, fixup_free_str_str_str, /* */
179 /* can be applied to original requests */
180 REQUEST_ROUTE|BRANCH_ROUTE},
181 {"sipt_destination", /* action name as in scripts */
182 (cmd_function)sipt_destination2, /* C function name */
183 4, /* number of parameters */
184 fixup_str_str_str, fixup_free_str_str_str, /* */
185 /* can be applied to original requests */
186 REQUEST_ROUTE|BRANCH_ROUTE},
187 {"sipt_forwarding", /* action name as in scripts */
188 (cmd_function)sipt_forwarding, /* C function name */
189 2, /* number of parameters */
190 fixup_str_str_str, fixup_free_str_str_str, /* */
191 /* can be applied to original requests */
192 REQUEST_ROUTE|BRANCH_ROUTE},
193 {"sipt_set_calling", /* action name as in scripts */
194 (cmd_function)sipt_set_calling, /* C function name */
195 4, /* number of parameters */
196 fixup_str_str_str, fixup_free_str_str_str, /* */
197 /* can be applied to original requests */
198 REQUEST_ROUTE|BRANCH_ROUTE},
199 {"sipt_set_bci_1", /* action name as in scripts */
200 (cmd_function)sipt_set_bci_1, /* C function name */
201 4, /* number of parameters */
202 fixup_str_str_str, fixup_free_str_str_str, /* */
203 /* can be applied to original requests */
205 {"sipt_has_isup_body", /* action name as in scripts */
206 (cmd_function)sipt_has_isup_body, /* C function name */
207 0, /* number of parameters */
209 /* can be applied to original requests */
214 static param_export_t params[]={
218 static pv_export_t mod_items[] = {
219 { {"sipt_presentation", sizeof("sipt_presentation")-1}, PVT_OTHER, sipt_get_presentation, 0,
221 { {"sipt_screening", sizeof("sipt_screening")-1}, PVT_OTHER, sipt_get_screening, 0,
223 { {"sipt_hop_counter", sizeof("sipt_hop_counter")-1}, PVT_OTHER, sipt_get_hop_counter, 0,
225 { {"sipt_cpc", sizeof("sipt_cpc")-1}, PVT_OTHER, sipt_get_cpc, 0,
227 { {"sipt_calling_party_nai", sizeof("sipt_calling_party_nai")-1}, PVT_OTHER, sipt_get_calling_party_nai, 0,
229 { {"sipt_called_party_nai", sizeof("sipt_called_party_nai")-1}, PVT_OTHER, sipt_get_called_party_nai, 0,
231 { {"sipt", sizeof("sipt")-1}, PVT_OTHER, sipt_get_pv, 0,
232 sipt_parse_pv_name, 0, 0, 0 },
233 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
236 struct module_exports exports = {
237 "sipt", /* module name */
238 DEFAULT_DLFLAGS, /* dlopen flags */
239 cmds, /* exported functions */
240 params, /* exported parameters */
241 0, /* exported RPC methods */
242 mod_items, /* exported pseudo-variables */
243 0, /* response function*/
244 mod_init, /* module initialization function */
245 0, /* per-child init function */
246 mod_destroy /* destroy function */
249 static inline int sipt_check_IAM(struct sip_msg *msg, str *body)
251 body->s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP, &body->len);
255 LM_INFO("No ISUP Message Found");
259 if(body->s[0] != ISUP_IAM)
261 LM_DBG("message not an IAM\n");
267 static inline int sipt_check_ACM_CPG(struct sip_msg *msg, str *body)
269 body->s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP, &body->len);
273 LM_INFO("No ISUP Message Found");
277 if((body->s[0] != ISUP_ACM) && (body->s[0] != ISUP_CPG))
279 LM_DBG("message not an ACM or CPG\n");
286 static int sipt_get_hop_counter(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
290 if(sipt_check_IAM(msg, &body) != 1)
292 LM_INFO("could not check IAM\n");
296 pv_get_sintval(msg, param, res, isup_get_hop_counter((unsigned char*)body.s, body.len));
300 static int sipt_get_event_info(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
303 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
307 LM_INFO("No ISUP Message Found");
311 if(body.s[0] != ISUP_CPG)
313 LM_DBG("message not an CPG\n");
317 pv_get_sintval(msg, param, res, isup_get_event_info((unsigned char*)body.s, body.len));
321 static int sipt_get_cpc(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
325 if(sipt_check_IAM(msg, &body) != 1)
327 LM_INFO("could not check IAM\n");
331 pv_get_sintval(msg, param, res, isup_get_cpc((unsigned char*)body.s, body.len));
335 static int sipt_get_calling_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
339 if(sipt_check_IAM(msg, &body) != 1)
341 LM_INFO("could not check IAM\n");
345 pv_get_sintval(msg, param, res, isup_get_calling_party_nai((unsigned char*)body.s, body.len));
349 static int sipt_get_calling_party(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
351 static char sb_s_buf[26];
353 memset(sb_s_buf, 0, 26);
355 if(sipt_check_IAM(msg, &body) != 1)
357 LM_INFO("could not check IAM\n");
361 isup_get_calling_party((unsigned char*)body.s, body.len, sb_s_buf);
363 if (strlen(sb_s_buf) > 0)
365 pv_get_strzval(msg, param, res, sb_s_buf);
367 pv_get_sintval(msg, param, res, -1);
372 static int sipt_get_redirection_info(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
375 if(sipt_check_ACM_CPG(msg, &body) != 1)
377 LM_INFO("could not check ACM or CPG\n");
381 pv_get_sintval(msg, param, res, isup_get_redirection_info((unsigned char*)body.s, body.len));
385 static int sipt_get_redirection_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
388 if(sipt_check_ACM_CPG(msg, &body) != 1)
390 LM_INFO("could not check ACM or CPG\n");
394 pv_get_sintval(msg, param, res, isup_get_redirection_number_nai((unsigned char*)body.s, body.len));
398 static int sipt_get_redirection_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
400 static char sb_s_buf[26];
402 memset(sb_s_buf, 0, 26);
403 if(sipt_check_ACM_CPG(msg, &body) != 1)
405 LM_INFO("could not check ACM or CPG\n");
409 isup_get_redirection_number((unsigned char*)body.s, body.len, sb_s_buf);
411 if (strlen(sb_s_buf) > 0)
413 pv_get_strzval(msg, param, res, sb_s_buf);
415 pv_get_sintval(msg, param, res, -1);
420 static int sipt_get_redirection_reason(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
424 if(sipt_check_IAM(msg, &body) != 1)
426 LM_INFO("could not check IAM\n");
430 pv_get_sintval(msg, param, res, isup_get_redirection_reason((unsigned char*)body.s, body.len));
434 static int sipt_get_original_redirection_reason(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
438 if(sipt_check_IAM(msg, &body) != 1)
440 LM_INFO("could not check IAM\n");
444 pv_get_sintval(msg, param, res, isup_get_original_redirection_reason((unsigned char*)body.s, body.len));
448 static int sipt_get_redirecting_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
452 if(sipt_check_IAM(msg, &body) != 1)
454 LM_INFO("could not check IAM\n");
458 pv_get_sintval(msg, param, res, isup_get_redirecting_number_nai((unsigned char*)body.s, body.len));
462 static int sipt_get_redirecting_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
464 static char sb_s_buf[26];
466 memset(sb_s_buf, 0, 26);
468 if(sipt_check_IAM(msg, &body) != 1)
470 LM_INFO("could not check IAM\n");
474 isup_get_redirecting_number((unsigned char*)body.s, body.len, sb_s_buf);
476 if (strlen(sb_s_buf) > 0)
478 pv_get_strzval(msg, param, res, sb_s_buf);
480 pv_get_sintval(msg, param, res, -1);
485 static int sipt_get_original_called_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
489 if(sipt_check_IAM(msg, &body) != 1)
491 LM_INFO("could not check IAM\n");
495 pv_get_sintval(msg, param, res, isup_get_original_called_number_nai((unsigned char*)body.s, body.len));
499 static int sipt_get_original_called_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
501 static char sb_s_buf[26];
503 memset(sb_s_buf, 0, 26);
505 if(sipt_check_IAM(msg, &body) != 1)
507 LM_INFO("could not check IAM\n");
511 isup_get_original_called_number((unsigned char*)body.s, body.len, sb_s_buf);
513 if (strlen(sb_s_buf) > 0)
515 pv_get_strzval(msg, param, res, sb_s_buf);
517 pv_get_sintval(msg, param, res, -1);
522 static int sipt_get_generic_number_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
526 if(sipt_check_IAM(msg, &body) != 1)
528 LM_INFO("could not check IAM\n");
532 pv_get_sintval(msg, param, res, isup_get_generic_number_nai((unsigned char*)body.s, body.len));
536 static int sipt_get_generic_number(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
538 static char sb_s_buf[26];
540 memset(sb_s_buf, 0, 26);
541 if(sipt_check_IAM(msg, &body) != 1)
543 LM_INFO("could not check IAM\n");
546 isup_get_generic_number((unsigned char*)body.s, body.len, sb_s_buf);
548 if (strlen(sb_s_buf) > 0)
550 pv_get_strzval(msg, param, res, sb_s_buf);
552 pv_get_sintval(msg, param, res, -1);
557 static int sipt_get_presentation(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
560 if(sipt_check_IAM(msg, &body) != 1)
562 LM_INFO("could not check IAM\n");
566 pv_get_sintval(msg, param, res, isup_get_presentation((unsigned char*)body.s, body.len));
570 static int sipt_get_screening(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
573 if(sipt_check_IAM(msg, &body) != 1)
575 LM_INFO("could not check IAM\n");
579 LM_DBG("about to get screening\n");
581 pv_get_sintval(msg, param, res, isup_get_screening((unsigned char*)body.s, body.len));
585 static int sipt_get_charge_indicator(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
588 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
592 LM_INFO("No ISUP Message Found");
596 if(body.s[0] != ISUP_COT && body.s[0] != ISUP_ACM)
598 LM_DBG("message not a COT or ACM\n");
601 LM_DBG("about to get charge indicator\n");
603 pv_get_sintval(msg, param, res, isup_get_charging_indicator((unsigned char*)body.s, body.len));
607 static int sipt_get_called_party_nai(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
610 if(sipt_check_IAM(msg, &body) != 1)
612 LM_INFO("could not check IAM\n");
616 pv_get_sintval(msg, param, res, isup_get_called_party_nai((unsigned char*)body.s, body.len));
620 static int sipt_get_called_party(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
622 static char sb_s_buf[26];
624 memset(sb_s_buf, 0, 26);
625 if(sipt_check_IAM(msg, &body) != 1)
627 LM_INFO("could not check IAM\n");
631 isup_get_called_party((unsigned char*)body.s, body.len, sb_s_buf);
633 if (strlen(sb_s_buf) > 0)
635 pv_get_strzval(msg, param, res, sb_s_buf);
637 pv_get_sintval(msg, param, res, -1);
642 static int sipt_has_isup_body(struct sip_msg *msg, char* foo, char* bar)
645 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
646 return (body.s == NULL)?-1:1;
649 int sipt_parse_pv_name(pv_spec_p sp, str *in)
655 if(sp==NULL || in==NULL || in->len<=0)
658 spv = (sipt_pv_t*)pkg_malloc(sizeof(sipt_pv_t));
662 memset(spv, 0, sizeof(sipt_pv_t));
666 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
668 if(p>in->s+in->len || *p=='\0')
673 while(p < in->s + in->len)
675 if(*p=='.' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
679 pvtype.len = p - pvtype.s;
680 if(p>in->s+in->len || *p=='\0')
682 // only one parameter stop parsing
685 goto parse_parameters;
690 while(p<in->s+in->len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
692 if(p>in->s+in->len || *p=='\0' || *p!='.')
694 // only one parameter w trailing whitespace
697 goto parse_parameters;
702 pvsubtype.len = in->len - (int)(p - in->s);
707 LM_DBG("sipt type[%.*s] - subtype[%.*s]\n", pvtype.len, pvtype.s,
708 pvsubtype.len, pvsubtype.s);
711 for(i=0;sipt_header_mapping[i].name != NULL; i++)
713 if(strncasecmp(pvtype.s, sipt_header_mapping[i].name, pvtype.len) == 0)
715 spv->type = sipt_header_mapping[i].type;
717 if(pvsubtype.len == 0)
720 for(j=0;sipt_header_mapping[i].subtypes[j].name != NULL;j++)
722 if(strncasecmp(pvsubtype.s, sipt_header_mapping[i].subtypes[j].name, pvsubtype.len) == 0)
723 spv->sub_type = sipt_header_mapping[i].subtypes[j].type;
725 if(spv->sub_type == 0)
727 LM_ERR("Unknown SIPT subtype [%.*s]\n", pvsubtype.len, pvsubtype.s);
734 LM_DBG("Type=%d subtype=%d\n",spv->type, spv->sub_type);
737 LM_ERR("Unknown SIPT type [%.*s]\n",pvtype.len, pvtype.s);
741 sp->pvp.pvn.u.dname = (void*)spv;
742 sp->pvp.pvn.type = PV_NAME_OTHER;
746 LM_ERR("error at PV sipt name: %.*s\n", in->len, in->s);
752 static int sipt_get_pv(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
756 if(msg==NULL || param==NULL)
759 spv = (sipt_pv_t*)param->pvn.u.dname;
765 case ISUP_PARM_CALLING_PARTY_CAT:
766 return sipt_get_cpc(msg, param, res);
767 case ISUP_PARM_CALLING_PARTY_NUM:
768 switch(spv->sub_type)
771 return sipt_get_calling_party(msg, param, res);
773 return sipt_get_calling_party_nai(msg, param, res);
774 case 2: /* SCREENIG */
775 return sipt_get_screening(msg, param, res);
776 case 3: /* PRESENTATION */
777 return sipt_get_presentation(msg, param, res);
780 case ISUP_PARM_CALLED_PARTY_NUM:
781 switch(spv->sub_type)
784 return sipt_get_called_party(msg, param, res);
786 return sipt_get_called_party_nai(msg, param, res);
789 case ISUP_PARM_HOP_COUNTER:
790 return sipt_get_hop_counter(msg, param, res);
791 case ISUP_PARM_EVENT_INFO:
792 return sipt_get_event_info(msg, param, res);
793 case ISUP_PARM_BACKWARD_CALL_IND:
794 switch(spv->sub_type)
796 case 1: /* charge_indicator */
797 return sipt_get_charge_indicator(msg, param, res);
800 case ISUP_PARM_DIVERSION_INFORMATION:
801 return sipt_get_redirection_info(msg, param, res);
802 case ISUP_PARM_REDIRECTION_NUMBER:
803 switch(spv->sub_type)
806 return sipt_get_redirection_number(msg, param, res);
808 return sipt_get_redirection_number_nai(msg, param, res);
811 case ISUP_PARM_REDIRECTION_INFO:
812 switch(spv->sub_type)
815 return sipt_get_redirection_reason(msg, param, res);
816 case 2: /* ORIGINAL_REASON */
817 return sipt_get_original_redirection_reason(msg, param, res);
820 case ISUP_PARM_REDIRECTING_NUMBER:
821 switch(spv->sub_type)
824 return sipt_get_redirecting_number(msg, param, res);
826 return sipt_get_redirecting_number_nai(msg, param, res);
829 case ISUP_PARM_GENERIC_ADDR:
830 switch(spv->sub_type)
833 return sipt_get_generic_number(msg, param, res);
835 return sipt_get_generic_number_nai(msg, param, res);
838 case ISUP_PARM_ORIGINAL_CALLED_NUM:
839 switch(spv->sub_type)
842 return sipt_get_original_called_number(msg, param, res);
844 return sipt_get_original_called_number_nai(msg, param, res);
852 static int sipt_set_bci_1(struct sip_msg *msg, char *_charge_indicator, char *_called_status, char * _called_category, char * _e2e_indicator)
854 str * str_charge_indicator = (str*)_charge_indicator;
855 unsigned int charge_indicator = 0;
856 str2int(str_charge_indicator, &charge_indicator);
857 str * str_called_status = (str*)_called_status;
858 unsigned int called_status = 0;
859 str2int(str_called_status, &called_status);
860 str * str_called_category = (str*)_called_category;
861 unsigned int called_category = 0;
862 str2int(str_called_category, &called_category);
863 str * str_e2e_indicator = (str*)_e2e_indicator;
864 unsigned int e2e_indicator = 0;
865 str2int(str_e2e_indicator, &e2e_indicator);
866 struct sdp_mangler mangle;
868 // update forwarded iam
870 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
874 LM_INFO("No ISUP Message Found");
878 sdp.s = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &sdp.len);
880 unsigned char newbuf[1024];
881 memset(newbuf, 0, 1024);
883 LM_ERR("failed to get the message body\n");
886 body.len = msg->len -(int)(body.s-msg->buf);
888 LM_DBG("message body has zero length\n");
892 if(body.s[0] != ISUP_ACM && body.s[0] != ISUP_COT)
894 LM_DBG("message not an ACM or COT\n");
899 mangle.body_offset = (int)(body.s - msg->buf);
903 int res = isup_update_bci_1(&mangle, charge_indicator, called_status, called_category, e2e_indicator, (unsigned char*)body.s, body.len);
906 LM_DBG("error updating ACM\n");
913 static int sipt_destination(struct sip_msg *msg, char *_destination, char *_hops, char * _nai) {
914 str terminator = str_init("1");
915 return sipt_destination2(msg, _destination, _hops, _nai, (char*)&terminator);
918 static int sipt_destination2(struct sip_msg *msg, char *_destination, char *_hops, char * _nai, char * _terminator)
920 str * str_hops = (str*)_hops;
921 unsigned int hops = 0;
922 str2int(str_hops, &hops);
923 str * nai = (str*)_nai;
924 unsigned int int_nai = 0;
925 str2int(nai, &int_nai);
926 str * terminator = (str*)_terminator;
927 unsigned int int_terminator = 0; /* if the str2int later fail */
928 str2int(terminator, &int_terminator);
929 str * destination = (str*)_destination;
930 struct sdp_mangler mangle;
932 // update forwarded iam
934 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
938 LM_INFO("No ISUP Message Found");
942 sdp.s = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &sdp.len);
944 unsigned char newbuf[1024];
945 memset(newbuf, 0, 1024);
947 LM_ERR("failed to get the message body\n");
950 body.len = msg->len -(int)(body.s-msg->buf);
952 LM_DBG("message body has zero length\n");
956 if(body.s[0] != ISUP_IAM)
958 LM_DBG("message not an IAM\n");
963 mangle.body_offset = (int)(body.s - msg->buf);
966 char * digits = calloc(1,destination->len+2);
967 memcpy(digits, destination->s, destination->len);
969 if (int_terminator) {
970 digits[destination->len] = '#';
973 int res = isup_update_destination(&mangle, digits, hops, int_nai, (unsigned char*)body.s, body.len);
977 LM_DBG("error updating IAM\n");
984 static int sipt_set_calling(struct sip_msg *msg, char *_origin, char *_nai, char * _pres, char *_screen)
986 unsigned int pres = 0;
987 str * str_pres = (str*)_pres;
988 str2int(str_pres, &pres);
989 unsigned int screen = 0;
990 str * str_screen = (str*)_screen;
991 str2int(str_screen, &screen);
992 str * nai = (str*)_nai;
993 unsigned int int_nai = 0;
994 str2int(nai, &int_nai);
995 str * origin = (str*)_origin;
996 struct sdp_mangler mangle;
998 // update forwarded iam
1000 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
1004 LM_INFO("No ISUP Message Found");
1009 LM_ERR("failed to get the message body\n");
1012 body.len = msg->len -(int)(body.s-msg->buf);
1014 LM_DBG("message body has zero length\n");
1018 if(body.s[0] != ISUP_IAM)
1020 LM_DBG("message not an IAM\n");
1026 mangle.body_offset = (int)(body.s - msg->buf);
1028 char * digits = calloc(1,origin->len+2);
1029 memcpy(digits, origin->s, origin->len);
1031 int res = isup_update_calling(&mangle, digits, int_nai, pres, screen, (unsigned char*)body.s, body.len);
1035 LM_DBG("error updating IAM\n");
1042 static int sipt_forwarding(struct sip_msg *msg, char *_fwdnumber, char * _nai)
1044 str * nai = (str*)_nai;
1045 unsigned int int_nai = 0;
1046 str2int(nai, &int_nai);
1047 str * fwdnumber = (str*)_fwdnumber;
1048 struct sdp_mangler mangle;
1050 // update forwarded iam
1052 body.s = get_body_part(msg, TYPE_APPLICATION,SUBTYPE_ISUP,&body.len);
1056 LM_INFO("No ISUP Message Found");
1060 sdp.s = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP, &sdp.len);
1062 unsigned char newbuf[1024];
1063 memset(newbuf, 0, 1024);
1065 LM_ERR("failed to get the message body\n");
1068 body.len = msg->len -(int)(body.s-msg->buf);
1070 LM_DBG("message body has zero length\n");
1074 if(body.s[0] != ISUP_IAM)
1076 LM_DBG("message not an IAM\n");
1081 mangle.body_offset = (int)(body.s - msg->buf);
1083 char * digits = calloc(1,fwdnumber->len+2);
1084 memcpy(digits, fwdnumber->s, fwdnumber->len);
1086 int res = isup_update_forwarding(&mangle, digits, int_nai, (unsigned char*)body.s, body.len);
1090 LM_DBG("error updating IAM\n");
1098 static int mod_init(void)
1104 static void mod_destroy(void)