00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include <time.h>
00028 #include <ctype.h>
00029 #include <errno.h>
00030 #include <assert.h>
00031 #include <sys/time.h>
00032 #include <sys/types.h>
00033 #include <sys/socket.h>
00034 #include <sys/select.h>
00035 #include <sys/un.h>
00036
00037 #include "../../sr_module.h"
00038 #include "../../mem/mem.h"
00039 #include "../../dprint.h"
00040 #include "../../str.h"
00041 #include "../../pvar.h"
00042 #include "../../ut.h"
00043 #include "../../script_cb.h"
00044 #include "../../parser/digest/digest.h"
00045 #include "../../parser/parse_from.h"
00046 #include "../dialog/dlg_load.h"
00047 #include "../dialog/dlg_hash.h"
00048
00049
00050 MODULE_VERSION
00051
00052 #define FL_USE_CALL_CONTROL (1<<28) // use call control for a dialog
00053
00054 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
00055 # define INLINE inline
00056 #else
00057 # define INLINE
00058 #endif
00059
00060 #define CANONICAL_URI_AVP_SPEC "$avp(s:can_uri)"
00061 #define SIGNALING_IP_AVP_SPEC "$avp(s:signaling_ip)"
00062
00063
00064
00065
00066
00067 #ifndef AF_LOCAL
00068 # define AF_LOCAL AF_UNIX
00069 #endif
00070
00071
00072 #ifndef MSG_NOSIGNAL
00073 # define MSG_NOSIGNAL 0
00074 #endif
00075
00076
00077
00078 typedef int Bool;
00079 #define True 1
00080 #define False 0
00081
00082
00083 typedef struct AVP_Param {
00084 str spec;
00085 int_str name;
00086 unsigned short type;
00087 } AVP_Param;
00088
00089 typedef struct AVP_List {
00090 pv_spec_p pv;
00091 str name;
00092 struct AVP_List *next;
00093 } AVP_List;
00094
00095 #define RETRY_INTERVAL 10
00096 #define BUFFER_SIZE 8192
00097
00098 typedef struct CallControlSocket {
00099 char *name;
00100 int sock;
00101 int timeout;
00102 time_t last_failure;
00103 char data[BUFFER_SIZE];
00104 } CallControlSocket;
00105
00106
00107
00108 static int CallControl(struct sip_msg *msg, char *str1, char *str2);
00109
00110 static int mod_init(void);
00111 static int child_init(int rank);
00112 static void destroy(void);
00113 static int postprocess_request(struct sip_msg *, unsigned int, void *);
00114
00115 int parse_param_init(unsigned int type, void *val);
00116 int parse_param_start(unsigned int type, void *val);
00117 int parse_param_stop(unsigned int type, void *val);
00118
00119
00120 static CallControlSocket callcontrol_socket = {
00121 "/var/run/callcontrol/socket",
00122 -1,
00123 500,
00124 0,
00125 ""
00126 };
00127
00128 static int disable = False;
00129 static int diverter_avp_id = 805;
00130
00131
00132 static AVP_Param canonical_uri_avp = {str_init(CANONICAL_URI_AVP_SPEC), {0}, 0};
00133
00134
00135 static AVP_Param signaling_ip_avp = {str_init(SIGNALING_IP_AVP_SPEC), {0}, 0};
00136
00137
00138 struct dlg_binds dlg_api;
00139 static int dialog_flag = -1;
00140
00141 AVP_List *cc_init_avps = NULL, *cc_start_avps = NULL, *cc_stop_avps = NULL;
00142
00143 pv_elem_t *model;
00144
00145 static cmd_export_t commands[] = {
00146 {"call_control", (cmd_function)CallControl, 0, 0, 0, REQUEST_ROUTE },
00147 {0, 0, 0, 0, 0, 0}
00148 };
00149
00150 static param_export_t parameters[] = {
00151 {"init", STR_PARAM | USE_FUNC_PARAM, parse_param_init},
00152 {"start", STR_PARAM | USE_FUNC_PARAM, parse_param_start},
00153 {"stop", STR_PARAM | USE_FUNC_PARAM, parse_param_stop},
00154 {"disable", INT_PARAM, &disable},
00155 {"socket_name", STR_PARAM, &(callcontrol_socket.name)},
00156 {"socket_timeout", INT_PARAM, &(callcontrol_socket.timeout)},
00157 {"diverter_avp_id", INT_PARAM, &diverter_avp_id},
00158 {"canonical_uri_avp", STR_PARAM, &(canonical_uri_avp.spec.s)},
00159 {"signaling_ip_avp", STR_PARAM, &(signaling_ip_avp.spec.s)},
00160 {0, 0, 0}
00161 };
00162
00163 struct module_exports exports = {
00164 "call_control",
00165 DEFAULT_DLFLAGS,
00166 commands,
00167 parameters,
00168 NULL,
00169 NULL,
00170 NULL,
00171 NULL,
00172 mod_init,
00173 NULL,
00174 destroy,
00175 child_init
00176 };
00177
00178
00179
00180 typedef enum CallControlAction {
00181 CAInitialize = 1,
00182 CAStart,
00183 CAStop
00184 } CallControlAction;
00185
00186
00187 typedef struct Contact {
00188 str username;
00189 str ip;
00190 str port;
00191 } Contact;
00192
00193 typedef struct DialogID {
00194 unsigned int h_entry;
00195 unsigned int h_id;
00196 } DialogID;
00197
00198 typedef struct CallInfo {
00199 CallControlAction action;
00200 DialogID dialog_id;
00201 str ruri;
00202 str diverter;
00203 str source_ip;
00204 str callid;
00205 str from;
00206 str from_tag;
00207 } CallInfo;
00208
00209
00210
00211 #define CHECK_COND(cond) \
00212 if ((cond) == 0) { \
00213 LM_ERR("malformed modparam\n"); \
00214 return -1; \
00215 }
00216
00217 #define CHECK_ALLOC(p) \
00218 if (!(p)) { \
00219 LM_ERR("no memory left\n"); \
00220 return -1; \
00221 }
00222
00223
00224 void
00225 destroy_list(AVP_List *list) {
00226 AVP_List *cur, *next;
00227
00228 cur = list;
00229 while (cur) {
00230 next = cur->next;
00231 pkg_free(cur);
00232 cur = next;
00233 }
00234 }
00235
00236
00237 int
00238 parse_param(void *val, AVP_List** avps) {
00239
00240 char *p;
00241 str *s, content;
00242 AVP_List *mp = NULL;
00243
00244
00245
00246 content.s = (char*) val;
00247 content.len = strlen(content.s);
00248
00249
00250 p = (char*) pkg_malloc (content.len + 1);
00251 CHECK_ALLOC(p);
00252
00253 p[content.len] = '\0';
00254 memcpy(p, content.s, content.len);
00255
00256 s = (str*) pkg_malloc(sizeof(str));
00257 CHECK_ALLOC(s);
00258
00259 for (;*p != '\0';) {
00260
00261 mp = (AVP_List*) pkg_malloc (sizeof(AVP_List));
00262 CHECK_ALLOC(mp);
00263 mp->next = *avps;
00264 mp->pv = (pv_spec_p) pkg_malloc (sizeof(pv_spec_t));
00265 CHECK_ALLOC(mp->pv);
00266
00267 for (; isspace(*p); p++);
00268 CHECK_COND(*p != '\0');
00269
00270 mp->name.s = p;
00271
00272 for(; isgraph(*p) && *p != '='; p++)
00273 CHECK_COND(*p != '\0');
00274
00275 mp->name.len = p - mp->name.s;
00276
00277 for (; isspace(*p); p++);
00278 CHECK_COND(*p != '\0' && *p == '=');
00279 p++;
00280
00281
00282
00283 for (; isspace(*p); p++);
00284 CHECK_COND(*p != '\0' && *p == '$');
00285
00286 s->s = p;
00287 s->len = strlen(p);
00288
00289 p = pv_parse_spec(s, mp->pv);
00290
00291 for (; isspace(*p); p++);
00292 *avps = mp;
00293 }
00294
00295 return 0;
00296 }
00297
00298
00299 int
00300 parse_param_init(unsigned int type, void *val) {
00301 if (parse_param(val, &cc_init_avps) == -1)
00302 return E_CFG;
00303 return 0;
00304 }
00305
00306 int
00307 parse_param_start(unsigned int type, void *val) {
00308 if (parse_param(val, &cc_start_avps) == -1)
00309 return E_CFG;
00310 return 0;
00311 }
00312
00313 int
00314 parse_param_stop(unsigned int type, void *val) {
00315 if (parse_param(val, &cc_stop_avps) == -1)
00316 return E_CFG;
00317 return 0;
00318 }
00319
00320
00321
00322
00323
00324
00325 static inline void
00326 ltrim(str *string)
00327 {
00328 while (string->len>0 && isspace((int)*(string->s))) {
00329 string->len--;
00330 string->s++;
00331 }
00332 }
00333
00334
00335 static inline void
00336 rtrim(str *string)
00337 {
00338 char *ptr;
00339
00340 ptr = string->s + string->len - 1;
00341 while (string->len>0 && (*ptr==0 || isspace((int)*ptr))) {
00342 string->len--;
00343 ptr--;
00344 }
00345 }
00346
00347
00348 static inline void
00349 trim(str *string)
00350 {
00351 ltrim(string);
00352 rtrim(string);
00353 }
00354
00355
00356
00357
00358
00359 static Bool
00360 has_to_tag(struct sip_msg *msg)
00361 {
00362 str tag;
00363
00364 if (!msg->to) {
00365 if (parse_headers(msg, HDR_TO_F, 0)==-1) {
00366 LOG(L_ERR, "cannot parse 'To' header\n");
00367 return False;
00368 }
00369 if (!msg->to) {
00370 LOG(L_ERR, "missing 'To' header\n");
00371 return False;
00372 }
00373 }
00374
00375 tag = get_to(msg)->tag_value;
00376
00377 if (tag.s==NULL || tag.len==0) {
00378 return False;
00379 }
00380
00381 return True;
00382 }
00383
00384
00385
00386 static str
00387 get_canonical_request_uri(struct sip_msg* msg)
00388 {
00389 int_str value;
00390
00391 if (!search_first_avp(canonical_uri_avp.type | AVP_VAL_STR,
00392 canonical_uri_avp.name, &value, NULL) ||
00393 value.s.s==NULL || value.s.len==0) {
00394
00395 return *GET_RURI(msg);
00396 }
00397
00398 return value.s;
00399 }
00400
00401
00402
00403 static str
00404 get_signaling_ip(struct sip_msg* msg)
00405 {
00406 int_str value;
00407
00408 if (!search_first_avp(signaling_ip_avp.type | AVP_VAL_STR,
00409 signaling_ip_avp.name, &value, NULL) ||
00410 !value.s.s || value.s.len==0) {
00411
00412 value.s.s = ip_addr2a(&msg->rcv.src_ip);
00413 value.s.len = strlen(value.s.s);
00414 }
00415
00416 return value.s;
00417 }
00418
00419
00420 static str
00421 get_diverter(struct sip_msg *msg)
00422 {
00423 struct hdr_field *header;
00424 dig_cred_t *credentials;
00425 int_str avpname, avpvalue;
00426 static str diverter;
00427
00428 diverter.s = "None";
00429 diverter.len = 4;
00430
00431 avpname.n = diverter_avp_id;
00432
00433 if (search_first_avp(AVP_VAL_STR, avpname, &avpvalue, NULL)) {
00434
00435 diverter = avpvalue.s;
00436 } else {
00437 get_authorized_cred(msg->proxy_auth, &header);
00438 if (header) {
00439 credentials = &((auth_body_t*)(header->parsed))->digest;
00440 } else {
00441 if (parse_headers(msg, HDR_PROXYAUTH_F, 0) == -1) {
00442 LOG(L_ERR, "cannot parse Proxy-Authorization header\n");
00443 return diverter;
00444 }
00445 if (!msg->proxy_auth)
00446 return diverter;
00447 if (parse_credentials(msg->proxy_auth) != 0) {
00448 LOG(L_ERR, "cannot parse credentials\n");
00449 return diverter;
00450 }
00451 credentials = &((auth_body_t*)(msg->proxy_auth->parsed))->digest;
00452 }
00453
00454 if (credentials->username.user.len > 0 &&
00455 credentials->username.domain.len > 0 &&
00456 credentials->realm.len == 0 &&
00457 credentials->nonce.len == 0 &&
00458 credentials->response.len == 0) {
00459
00460
00461 diverter = credentials->username.whole;
00462 }
00463 }
00464
00465 return diverter;
00466 }
00467
00468
00469 static CallInfo*
00470 get_call_info(struct sip_msg *msg, CallControlAction action)
00471 {
00472 static CallInfo call_info;
00473 int headers;
00474
00475 memset(&call_info, 0, sizeof(struct CallInfo));
00476
00477 switch (action) {
00478 case CAInitialize:
00479 headers = HDR_CALLID_F|HDR_FROM_F;
00480 break;
00481 case CAStart:
00482 case CAStop:
00483 headers = HDR_CALLID_F;
00484 break;
00485 default:
00486
00487 assert(False);
00488 return NULL;
00489 }
00490
00491 if (parse_headers(msg, headers, 0) == -1) {
00492 LOG(L_ERR, "cannot parse required headers\n");
00493 return NULL;
00494 }
00495
00496 if (headers & HDR_CALLID_F) {
00497 if (msg->callid == NULL) {
00498 LOG(L_ERR, "missing Call-ID header\n");
00499 return NULL;
00500 }
00501
00502 call_info.callid = msg->callid->body;
00503 trim(&call_info.callid);
00504 }
00505
00506 if (headers & HDR_FROM_F) {
00507 struct to_body *from;
00508
00509 if (msg->from == NULL) {
00510 LOG(L_ERR, "missing From header\n");
00511 return NULL;
00512 }
00513 if (!msg->from->parsed && parse_from_header(msg)==-1) {
00514 LOG(L_ERR, "cannot parse From header\n");
00515 return NULL;
00516 }
00517
00518 from = get_from(msg);
00519
00520 if (from->body.s==NULL || from->body.len==0) {
00521 LOG(L_ERR, "missing From\n");
00522 return NULL;
00523 }
00524 if (from->tag_value.s==NULL || from->tag_value.len==0) {
00525 LOG(L_ERR, "missing From tag\n");
00526 return NULL;
00527 }
00528
00529 call_info.from = from->body;
00530 call_info.from_tag = from->tag_value;
00531 }
00532
00533 if (action == CAInitialize) {
00534 call_info.ruri = get_canonical_request_uri(msg);
00535 call_info.diverter = get_diverter(msg);
00536 call_info.source_ip = get_signaling_ip(msg);
00537 }
00538
00539 call_info.action = action;
00540
00541 return &call_info;
00542 }
00543
00544 static char*
00545 make_custom_request(struct sip_msg *msg, CallInfo *call)
00546 {
00547 static char request[8192];
00548 int len = 0;
00549 AVP_List *al;
00550 pv_value_t pt;
00551
00552 switch (call->action) {
00553 case CAInitialize:
00554 al = cc_init_avps;
00555 break;
00556 case CAStart:
00557 al = cc_start_avps;
00558 break;
00559 case CAStop:
00560 al = cc_stop_avps;
00561 break;
00562 default:
00563
00564 assert(False);
00565 return NULL;
00566 }
00567
00568 for (; al; al = al->next) {
00569 pv_get_spec_value(msg, al->pv, &pt);
00570 if (pt.flags & PV_VAL_INT) {
00571 len += snprintf(request + len, sizeof(request),
00572 "%.*s = %d ", al->name.len, al->name.s,
00573 pt.ri);
00574 } else if (pt.flags & PV_VAL_STR) {
00575 len += snprintf(request + len, sizeof(request),
00576 "%.*s = %.*s ", al->name.len, al->name.s,
00577 pt.rs.len, pt.rs.s);
00578 }
00579
00580 if (len >= sizeof(request)) {
00581 LM_ERR("callcontrol request is longer than %ld bytes\n", (unsigned long)sizeof(request));
00582 return NULL;
00583 }
00584 }
00585
00586
00587 return request;
00588 }
00589
00590
00591 static char*
00592 make_default_request(CallInfo *call)
00593 {
00594 static char request[8192];
00595 int len;
00596
00597 switch (call->action) {
00598 case CAInitialize:
00599 len = snprintf(request, sizeof(request),
00600 "init\r\n"
00601 "ruri: %.*s\r\n"
00602 "diverter: %.*s\r\n"
00603 "sourceip: %.*s\r\n"
00604 "callid: %.*s\r\n"
00605 "from: %.*s\r\n"
00606 "fromtag: %.*s\r\n"
00607 "\r\n",
00608 call->ruri.len, call->ruri.s,
00609 call->diverter.len, call->diverter.s,
00610 call->source_ip.len, call->source_ip.s,
00611 call->callid.len, call->callid.s,
00612 call->from.len, call->from.s,
00613 call->from_tag.len, call->from_tag.s);
00614
00615 if (len >= sizeof(request)) {
00616 LOG(L_ERR, "callcontrol request is longer than %ld bytes\n", (unsigned long)sizeof(request));
00617 return NULL;
00618 }
00619
00620 break;
00621
00622 case CAStart:
00623 len = snprintf(request, sizeof(request),
00624 "start\r\n"
00625 "callid: %.*s\r\n"
00626 "dialogid: %d:%d\r\n"
00627 "\r\n",
00628 call->callid.len, call->callid.s,
00629 call->dialog_id.h_entry, call->dialog_id.h_id);
00630
00631 if (len >= sizeof(request)) {
00632 LOG(L_ERR, "callcontrol request is longer than %ld bytes\n", (unsigned long)sizeof(request));
00633 return NULL;
00634 }
00635
00636 break;
00637
00638 case CAStop:
00639 len = snprintf(request, sizeof(request),
00640 "stop\r\n"
00641 "callid: %.*s\r\n"
00642 "\r\n",
00643 call->callid.len, call->callid.s);
00644
00645 if (len >= sizeof(request)) {
00646 LOG(L_ERR, "callcontrol request is longer than %ld bytes\n", (unsigned long)sizeof(request));
00647 return NULL;
00648 }
00649
00650 break;
00651
00652 default:
00653
00654 assert(False);
00655 return NULL;
00656 }
00657
00658 return request;
00659 }
00660
00661
00662
00663
00664
00665 static Bool
00666 callcontrol_connect(void)
00667 {
00668 struct sockaddr_un addr;
00669
00670 if (callcontrol_socket.sock >= 0)
00671 return True;
00672
00673 if (callcontrol_socket.last_failure + RETRY_INTERVAL > time(NULL))
00674 return False;
00675
00676 memset(&addr, 0, sizeof(addr));
00677 addr.sun_family = AF_LOCAL;
00678 strncpy(addr.sun_path, callcontrol_socket.name, sizeof(addr.sun_path) - 1);
00679 #ifdef HAVE_SOCKADDR_SA_LEN
00680 addr.sun_len = strlen(addr.sun_path);
00681 #endif
00682
00683 callcontrol_socket.sock = socket(AF_LOCAL, SOCK_STREAM, 0);
00684 if (callcontrol_socket.sock < 0) {
00685 LOG(L_ERR, "can't create socket\n");
00686 callcontrol_socket.last_failure = time(NULL);
00687 return False;
00688 }
00689 if (connect(callcontrol_socket.sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00690 LOG(L_ERR, "failed to connect to %s: %s\n", callcontrol_socket.name, strerror(errno));
00691 close(callcontrol_socket.sock);
00692 callcontrol_socket.sock = -1;
00693 callcontrol_socket.last_failure = time(NULL);
00694 return False;
00695 }
00696
00697 return True;
00698 }
00699
00700 static void
00701 callcontrol_disconnect(void)
00702 {
00703 if (callcontrol_socket.sock < 0)
00704 return;
00705
00706 close(callcontrol_socket.sock);
00707 callcontrol_socket.sock = -1;
00708 callcontrol_socket.last_failure = time(NULL);
00709 }
00710
00711 static char*
00712 send_command(char *command)
00713 {
00714 int cmd_len, bytes, tries, sent, received, count;
00715 struct timeval timeout;
00716 fd_set rset;
00717
00718 if (!callcontrol_connect())
00719 return NULL;
00720
00721 cmd_len = strlen(command);
00722
00723 for (sent=0, tries=0; sent<cmd_len && tries<3; tries++, sent+=bytes) {
00724 do
00725 bytes = send(callcontrol_socket.sock, command+sent, cmd_len-sent, MSG_DONTWAIT|MSG_NOSIGNAL);
00726 while (bytes == -1 && errno == EINTR);
00727 if (bytes == -1) {
00728 switch (errno) {
00729 case ECONNRESET:
00730 case EPIPE:
00731 callcontrol_disconnect();
00732 callcontrol_socket.last_failure = 0;
00733 if (callcontrol_connect()) {
00734 sent = bytes = 0;
00735 continue;
00736 } else {
00737 LOG(L_ERR, "connection with callcontrol did die\n");
00738 }
00739 break;
00740 case EACCES:
00741 LOG(L_ERR, "permission denied sending to %s\n", callcontrol_socket.name);
00742 break;
00743 case EWOULDBLOCK:
00744
00745
00746 LOG(L_ERR, "sending command would block!\n");
00747 break;
00748 default:
00749 LOG(L_ERR, "%d: %s\n", errno, strerror(errno));
00750 break;
00751 }
00752 callcontrol_disconnect();
00753 return NULL;
00754 }
00755 }
00756 if (sent < cmd_len) {
00757 LOG(L_ERR, "couldn't send complete command after 3 tries\n");
00758 callcontrol_disconnect();
00759 return NULL;
00760 }
00761
00762 callcontrol_socket.data[0] = 0;
00763 received = 0;
00764 while (True) {
00765 FD_ZERO(&rset);
00766 FD_SET(callcontrol_socket.sock, &rset);
00767 timeout.tv_sec = callcontrol_socket.timeout / 1000;
00768 timeout.tv_usec = (callcontrol_socket.timeout % 1000) * 1000;
00769
00770 do
00771 count = select(callcontrol_socket.sock + 1, &rset, NULL, NULL, &timeout);
00772 while (count == -1 && errno == EINTR);
00773
00774 if (count == -1) {
00775 LOG(L_ERR, "select failed: %d: %s\n", errno, strerror(errno));
00776 callcontrol_disconnect();
00777 return NULL;
00778 } else if (count == 0) {
00779 LOG(L_ERR, "did timeout waiting for an answer\n");
00780 callcontrol_disconnect();
00781 return NULL;
00782 } else {
00783 do
00784 bytes = recv(callcontrol_socket.sock, callcontrol_socket.data+received, BUFFER_SIZE-1-received, 0);
00785 while (bytes == -1 && errno == EINTR);
00786 if (bytes == -1) {
00787 LOG(L_ERR, "failed to read answer: %d: %s\n", errno, strerror(errno));
00788 callcontrol_disconnect();
00789 return NULL;
00790 } else if (bytes == 0) {
00791 LOG(L_ERR, "connection with callcontrol closed\n");
00792 callcontrol_disconnect();
00793 return NULL;
00794 } else {
00795 callcontrol_socket.data[received+bytes] = 0;
00796 if (strstr(callcontrol_socket.data+received, "\r\n")!=NULL) {
00797 break;
00798 }
00799 received += bytes;
00800 }
00801 }
00802 }
00803
00804 return callcontrol_socket.data;
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 static int
00818 call_control_initialize(struct sip_msg *msg)
00819 {
00820 CallInfo *call;
00821 char *message, *result = NULL;
00822
00823
00824 call = get_call_info(msg, CAInitialize);
00825 if (!call) {
00826 LOG(L_ERR, "can't retrieve call info\n");
00827 return -5;
00828 }
00829
00830
00831 if (!cc_init_avps)
00832 message = make_default_request(call);
00833 else
00834 message = make_custom_request(msg, call);
00835
00836 if (!message)
00837 return -5;
00838
00839 result = send_command(message);
00840
00841 if (result==NULL) {
00842 return -5;
00843 } else if (strcasecmp(result, "No limit\r\n")==0) {
00844 return 2;
00845 } else if (strcasecmp(result, "Limited\r\n")==0) {
00846 return 1;
00847 } else if (strcasecmp(result, "No credit\r\n")==0) {
00848 return -1;
00849 } else if (strcasecmp(result, "Locked\r\n")==0) {
00850 return -2;
00851 } else {
00852 return -5;
00853 }
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863 static int
00864 call_control_start(struct sip_msg *msg, struct dlg_cell *dlg)
00865 {
00866 CallInfo *call;
00867 char *message, *result;
00868
00869 call = get_call_info(msg, CAStart);
00870 if (!call) {
00871 LOG(L_ERR, "can't retrieve call info\n");
00872 return -5;
00873 }
00874
00875 call->dialog_id.h_entry = dlg->h_entry;
00876 call->dialog_id.h_id = dlg->h_id;
00877
00878 if (!cc_start_avps)
00879 message = make_default_request(call);
00880 else
00881 message = make_custom_request(msg, call);
00882
00883 if (!message)
00884 return -5;
00885
00886 result = send_command(message);
00887
00888 if (result==NULL) {
00889 return -5;
00890 } else if (strcasecmp(result, "Ok\r\n")==0) {
00891 return 1;
00892 } else if (strcasecmp(result, "Not found\r\n")==0) {
00893 return -1;
00894 } else {
00895 return -5;
00896 }
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906 static int
00907 call_control_stop(struct sip_msg *msg, str callid)
00908 {
00909 CallInfo call;
00910 char *message, *result;
00911
00912 call.action = CAStop;
00913 call.callid = callid;
00914
00915 if (!cc_stop_avps)
00916 message = make_default_request(&call);
00917 else
00918 message = make_custom_request(msg, &call);
00919
00920 if (!message)
00921 return -5;
00922
00923 result = send_command(message);
00924
00925 if (result==NULL) {
00926 return -5;
00927 } else if (strcasecmp(result, "Ok\r\n")==0) {
00928 return 1;
00929 } else if (strcasecmp(result, "Not found\r\n")==0) {
00930 return -1;
00931 } else {
00932 return -5;
00933 }
00934 }
00935
00936
00937
00938
00939
00940 typedef enum {
00941 CCInactive = 0,
00942 CCActive
00943 } CallControlState;
00944
00945
00946 static void
00947 __dialog_replies(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
00948 {
00949 struct sip_msg *reply = _params->rpl;
00950
00951 if (reply!=FAKED_REPLY && reply->REPLY_STATUS==200) {
00952 call_control_start(reply, dlg);
00953 }
00954 }
00955
00956
00957 static void
00958 __dialog_ended(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
00959 {
00960 if ((int)(long)*_params->param == CCActive) {
00961 struct sip_msg* msg = _params->rpl;
00962 if( !msg || msg == FAKED_REPLY)
00963 msg = _params->req;
00964 call_control_stop(msg, dlg->callid);
00965 *_params->param = CCInactive;
00966 }
00967 }
00968
00969
00970 static void
00971 __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
00972 {
00973 struct sip_msg *request = _params->req;
00974
00975 if (request->REQ_METHOD != METHOD_INVITE)
00976 return;
00977
00978 if ((request->msg_flags & FL_USE_CALL_CONTROL) == 0)
00979 return;
00980
00981 if (dlg_api.register_dlgcb(dlg, DLGCB_RESPONSE_FWDED, __dialog_replies, NULL, NULL) != 0)
00982 LOG(L_ERR, "cannot register callback for dialog confirmation\n");
00983 if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED | DLGCB_DESTROY, __dialog_ended, (void*)CCActive, NULL) != 0)
00984 LOG(L_ERR, "cannot register callback for dialog termination\n");
00985
00986
00987 request->msg_flags &= ~FL_USE_CALL_CONTROL;
00988 }
00989
00990
00991 static void
00992 __dialog_loaded(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
00993 {
00994 if (dlg_api.register_dlgcb(dlg, DLGCB_RESPONSE_FWDED, __dialog_replies, NULL, NULL) != 0)
00995 LOG(L_ERR, "cannot register callback for dialog confirmation\n");
00996 if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED | DLGCB_DESTROY, __dialog_ended, (void*)CCActive, NULL) != 0)
00997 LOG(L_ERR, "cannot register callback for dialog termination\n");
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 static int
01012 CallControl(struct sip_msg *msg, char *str1, char *str2)
01013 {
01014 int result;
01015
01016 if (disable)
01017 return 2;
01018
01019 if (msg->first_line.type!=SIP_REQUEST || msg->REQ_METHOD!=METHOD_INVITE || has_to_tag(msg)) {
01020 LOG(L_WARN, "call_control should only be called for the first INVITE\n");
01021 return -5;
01022 }
01023
01024 result = call_control_initialize(msg);
01025 if (result == 1) {
01026
01027 msg->msg_flags |= FL_USE_CALL_CONTROL;
01028 setflag(msg, dialog_flag);
01029 }
01030
01031 return result;
01032 }
01033
01034
01035
01036
01037
01038 static int
01039 mod_init(void)
01040 {
01041 pv_spec_t avp_spec;
01042 int *param;
01043 modparam_t type;
01044
01045
01046
01047 if (canonical_uri_avp.spec.s==NULL || *(canonical_uri_avp.spec.s)==0) {
01048 LOG(L_ERR, "missing/empty canonical_uri_avp parameter. using default.\n");
01049 canonical_uri_avp.spec.s = CANONICAL_URI_AVP_SPEC;
01050 }
01051 canonical_uri_avp.spec.len = strlen(canonical_uri_avp.spec.s);
01052 if (pv_parse_spec(&(canonical_uri_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
01053 LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
01054 return -1;
01055 }
01056 if (pv_get_avp_name(0, &(avp_spec.pvp), &(canonical_uri_avp.name), &(canonical_uri_avp.type))!=0) {
01057 LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
01058 return -1;
01059 }
01060
01061
01062 if (signaling_ip_avp.spec.s==NULL || *(signaling_ip_avp.spec.s)==0) {
01063 LOG(L_ERR, "missing/empty signaling_ip_avp parameter. using default.\n");
01064 signaling_ip_avp.spec.s = SIGNALING_IP_AVP_SPEC;
01065 }
01066 signaling_ip_avp.spec.len = strlen(signaling_ip_avp.spec.s);
01067 if (pv_parse_spec(&(signaling_ip_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
01068 LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
01069 return -1;
01070 }
01071 if (pv_get_avp_name(0, &(avp_spec.pvp), &(signaling_ip_avp.name), &(signaling_ip_avp.type))!=0) {
01072 LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
01073 return -1;
01074 }
01075
01076
01077 if (load_dlg_api(&dlg_api)!=0) {
01078 LOG(L_CRIT, "cannot load the dialog module API\n");
01079 return -1;
01080 }
01081
01082
01083 param = find_param_export(find_module_by_name("dialog"), "dlg_flag", INT_PARAM, &type);
01084 if (!param) {
01085 LOG(L_CRIT, "cannot find dlg_flag parameter in the dialog module\n");
01086 return -1;
01087 }
01088 if (type != INT_PARAM) {
01089 LOG(L_CRIT, "dlg_flag parameter found but with wrong type: %d\n", type);
01090 return -1;
01091 }
01092
01093 dialog_flag = *param;
01094
01095
01096 if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) {
01097 LOG(L_CRIT, "cannot register callback for dialog creation\n");
01098 return -1;
01099 }
01100
01101
01102 if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) {
01103 LOG(L_ERR, "cannot register callback for dialogs loaded from the database\n");
01104 }
01105
01106
01107 if (register_script_cb(postprocess_request, POST_SCRIPT_CB|REQUEST_CB, 0) != 0) {
01108 LOG(L_CRIT, "ERROR:call_control:mod_init: could not register request postprocessing callback\n");
01109 return -1;
01110 }
01111
01112 return 0;
01113 }
01114
01115
01116 static int
01117 child_init(int rank)
01118 {
01119
01120 if (!disable)
01121 callcontrol_connect();
01122
01123 return 0;
01124 }
01125
01126
01127 static void
01128 destroy(void) {
01129 if (cc_init_avps)
01130 destroy_list(cc_init_avps);
01131
01132 if (cc_start_avps)
01133 destroy_list(cc_start_avps);
01134
01135 if (cc_stop_avps)
01136 destroy_list(cc_stop_avps);
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 static int
01150 postprocess_request(struct sip_msg *msg, unsigned int flags, void *_param)
01151 {
01152 CallInfo *call;
01153
01154 if ((msg->msg_flags & FL_USE_CALL_CONTROL) == 0)
01155 return 1;
01156
01157
01158
01159 LOG(L_WARN, "dialog to trace controlled call was not created. discarding callcontrol.");
01160
01161 call = get_call_info(msg, CAStop);
01162 if (!call) {
01163 LOG(L_ERR, "can't retrieve call info\n");
01164 return -1;
01165 }
01166 call_control_stop(msg, call->callid);
01167
01168 return 1;
01169 }
01170
01171