Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 196789) +++ channels/chan_sip.c (working copy) @@ -1297,6 +1297,16 @@ struct ast_tcptls_session_instance *tcptls_session; /* If tcp or tls, a socket manager */ }; +struct isup_data +{ + int found; + char called_party_no[25]; + char calling_party_no[25]; + char jurisdiction[7]; + char hop_counter[3]; + char originating_line[3]; +}; + /*! \brief sip_request: The data grabbed from the UDP socket * * \verbatim @@ -20346,6 +20356,144 @@ return res; } +static struct isup_data find_sipt_isup(struct sip_request *req) +{ + int isup_start = 0; + int isup_end = 0; + struct isup_data isup = {0}; + int optional_parameter; + char multipart_message_boundary[30]; + unsigned char *cptr; + char content_type_isup[35] = "Content-Type: application/isup\0"; + int k = 0, i = 0; + + cptr = req->data->str; + multipart_message_boundary[0] = '\0'; + for(i = 0; i < strlen(req->data->str) - 8; i++, cptr++) + { + if(!strncmp("boundary", cptr, 8)) { + while(req->data->str[k+i+9] != '\r') + { + multipart_message_boundary[k] = req->data->str[k+i+9]; + k++; + } + multipart_message_boundary[k] = '\0'; + k = 0; + break; + } + } + + i = 0; + do{ + if((unsigned char)(req->data->str[i]) == content_type_isup[k]) { + if(k == 0) { + isup_start = i; + } + i++; + k++; + } + else{ + i++; + k = 0; + isup_start = 0; + } + }while((i < req->len) && (k < strlen(content_type_isup))); + + cptr = &req->data->str[i]; + + if(isup_start != 0) { + do{ + if(strncmp(cptr, "\r\n\r\n", 4)) { + i += 4; + cptr = &req->data->str[i]; + break; + } + else{ + i++; + } + }while((i < req->len - 3)); + isup_start = i; + } + + if(isup_start != 0) { + k = 0; + i = isup_start+1; + do{ + if((unsigned char)(req->data->str[i]) == multipart_message_boundary[k]){ + if (k == 0) { + isup_end = i - 4; + } + i++; + k++; + } + else{ + i++; + k = 0; + isup_end = 0; + } + }while((i < req->len) && (k < strlen(multipart_message_boundary))); + + if((int)((unsigned char)(req->data->str[isup_start])) == 1){ + int isup_offset; + isup.found = 1; + isup_offset = isup_start + 13; + k = 0; + for(i = isup_offset + 1; i < isup_offset + (int)((unsigned char)(req->data->str[isup_offset-1])); i++) { + isup.called_party_no[k] = 48 + (int)((unsigned char)(req->data->str[i])) % 16; + isup.called_party_no[k+1] = 48 + (int)((unsigned char)(req->data->str[i])) / 16; + k += 2; + } + isup.called_party_no[k] = '\0'; + isup_offset += (int)((unsigned char)(req->data->str[isup_offset-1])); + optional_parameter = (int)((unsigned char)(req->data->str[isup_offset])); + + while(optional_parameter != 0) { + switch(optional_parameter) { + case 10: + k = 0; + for(i=isup_offset + 3; i < isup_offset + ((int) ((unsigned char)(req->data->str[isup_offset+1]))) + 2; i++) { + isup.calling_party_no[k] = 48 + (int)((unsigned char)(req->data->str[i])) % 16; + isup.calling_party_no[k+1] = 48 + (int)((unsigned char)(req->data->str[i])) / 16; + k += 2; + } + isup.calling_party_no[k] = '\0'; + isup_offset += (int)((unsigned char)(req->data->str[isup_offset+1])) + 3; + break; + case 61: + k = 0; + isup.hop_counter[k] = 48 + (int)((unsigned char)(req->data->str[isup_offset+1])) / 10; + isup.hop_counter[k+1] = 48 + (int)((unsigned char)(req->data->str[isup_offset+1])) % 10; + isup.hop_counter[k+2] = '\0'; + isup_offset += 3; + break; + case 196: + k = 0; + for(i=isup_offset + 1; i < isup_offset + 4; i++) { + isup.jurisdiction[k] = 48 + (int)((unsigned char)(req->data->str[i])) % 16; + isup.jurisdiction[k+1] = 48 + (int)((unsigned char)(req->data->str[i])) / 16; + k += 2; + } + isup.jurisdiction[k] = '\0'; + isup_offset += 5; + break; + case 234: + k = 0; + isup.originating_line[k] = 48 + (int)((unsigned char)(req->data->str[isup_offset+1])) / 10; + isup.originating_line[k+1] = 48 + (int)((unsigned char)(req->data->str[isup_offset+1])) % 10; + isup.originating_line[k+2] = '\0'; + isup_offset += 3; + break; + default: + isup_offset += (int)((unsigned char)(req->data->str[isup_offset])) + 2; + break; + } + optional_parameter = (int)((unsigned char)(req->data->str[isup_offset-1])); + } + } + } + return isup; +} + /*! \brief Find all call legs and bridge transferee with target * called from handle_request_refer */ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) @@ -21879,6 +22027,7 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin) { struct sip_pvt *p; + struct isup_data isup; int recount = 0; int nounlock = 0; int lockretry; @@ -21893,6 +22042,7 @@ ntohs(sin->sin_port), req->data->str); } + isup = find_sipt_isup(req); if (parse_request(req) == -1) { /* Bad packet, can't parse */ ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */ return 1; @@ -21977,6 +22127,14 @@ if (recount) ast_update_use_count(); + if(isup.found == 1) { + pbx_builtin_setvar_helper(p->owner, "CALLED_PARTY_NO", isup.called_party_no); + pbx_builtin_setvar_helper(p->owner, "CALLING_PARTY_NO", isup.calling_party_no); + pbx_builtin_setvar_helper(p->owner, "JURISDICTION", isup.jurisdiction); + pbx_builtin_setvar_helper(p->owner, "HOP_COUNTER", isup.hop_counter); + pbx_builtin_setvar_helper(p->owner, "ORIGINATING_LINE", isup.originating_line); + } + if (p->owner && !nounlock) ast_channel_unlock(p->owner); sip_pvt_unlock(p);