diff --git a/core/plug-in/sipctrl/SipCtrlInterface.cpp b/core/plug-in/sipctrl/SipCtrlInterface.cpp index 9ad3139f..1d6b9f0d 100644 --- a/core/plug-in/sipctrl/SipCtrlInterface.cpp +++ b/core/plug-in/sipctrl/SipCtrlInterface.cpp @@ -496,13 +496,13 @@ void SipCtrlInterface::handle_sip_request(const char* tid, sip_msg* msg) req.port = int2str(ntohs(((sockaddr_in*)(&msg->local_ip))->sin_port)); req.r_uri = c2stlstr(msg->u.request->ruri_str); - if(msg->contact){ + if(get_contact(msg)){ sip_nameaddr na; - const char* c = msg->contact->value.s; - if(parse_nameaddr(&na,&c,msg->contact->value.len) < 0){ + const char* c = get_contact(msg)->value.s; + if(parse_nameaddr(&na,&c,get_contact(msg)->value.len) < 0){ WARN("Contact parsing failed\n"); - WARN("\tcontact = '%.*s'\n",msg->contact->value.len,msg->contact->value.s); + WARN("\tcontact = '%.*s'\n",get_contact(msg)->value.len,get_contact(msg)->value.s); WARN("\trequest = '%.*s'\n",msg->len,msg->buf); } else { @@ -514,7 +514,7 @@ void SipCtrlInterface::handle_sip_request(const char* tid, sip_msg* msg) } req.from_uri = c2stlstr(na.addr); - req.contact = c2stlstr(msg->contact->value); + req.contact = c2stlstr(get_contact(msg)->value); } } else { @@ -571,12 +571,13 @@ void SipCtrlInterface::handle_sip_reply(sip_msg* msg) reply.code = msg->u.reply->code; reply.reason = c2stlstr(msg->u.reply->reason); - if(msg->contact){ + if(get_contact(msg)){ - const char* c = msg->contact->value.s; + // parse the first contact + const char* c = get_contact(msg)->value.s; sip_nameaddr na; - int err = parse_nameaddr(&na,&c,msg->contact->value.len); + int err = parse_nameaddr(&na,&c,get_contact(msg)->value.len); if(err < 0) { ERROR("Contact nameaddr parsing failed\n"); @@ -584,8 +585,13 @@ void SipCtrlInterface::handle_sip_reply(sip_msg* msg) } // 'Contact' header? - reply.next_request_uri = c2stlstr(na.addr); - reply.contact = c2stlstr(msg->contact->value); + reply.next_request_uri = c2stlstr(na.addr); + + list::iterator c_it = msg->contacts.begin(); + reply.contact = c2stlstr((*c_it)->value); + for(;c_it!=msg->contacts.end(); ++c_it){ + reply.contact += "," + c2stlstr((*c_it)->value); + } } reply.callid = c2stlstr(msg->callid->value); @@ -596,12 +602,6 @@ void SipCtrlInterface::handle_sip_reply(sip_msg* msg) reply.dstip = get_addr_str(((sockaddr_in*)(&msg->local_ip))->sin_addr); //FIXME: IPv6 reply.port = int2str(ntohs(((sockaddr_in*)(&msg->local_ip))->sin_port)); - //if( (get_cseq(msg)->method == sip_request::INVITE) - // && (msg->u.reply->code >= 200) - // && (msg->u.reply->code < 300) ){ - // tl->send_200_ack(msg); - //} - prepare_routes_uac(msg->record_route, reply.route); for (list::iterator it = msg->hdrs.begin(); diff --git a/core/plug-in/sipctrl/parse_header.cpp b/core/plug-in/sipctrl/parse_header.cpp index 32849ac5..db4e07eb 100644 --- a/core/plug-in/sipctrl/parse_header.cpp +++ b/core/plug-in/sipctrl/parse_header.cpp @@ -112,7 +112,7 @@ static int parse_header_type(sip_msg* msg, sip_header* h) } break; case 'm': { // Contact h->type = sip_header::H_CONTACT; - msg->contact = h; + msg->contacts.push_back(h); } break; // case 'e': // Content-Encoding // {} break; @@ -209,7 +209,7 @@ static int parse_header_type(sip_msg* msg, sip_header* h) case 'O': if(!lower_cmp(h->name.s+2,CONTACT_lc+2,CONTACT_len-2)){ h->type = sip_header::H_CONTACT; - msg->contact = h; + msg->contacts.push_back(h); } break; diff --git a/core/plug-in/sipctrl/sip_parser.cpp b/core/plug-in/sipctrl/sip_parser.cpp index f73a1e08..d86e8a8e 100644 --- a/core/plug-in/sipctrl/sip_parser.cpp +++ b/core/plug-in/sipctrl/sip_parser.cpp @@ -46,7 +46,7 @@ sip_msg::sip_msg(char* msg_buf, int msg_len) cseq(NULL), via1(NULL),via_p1(NULL), callid(NULL), - contact(NULL), + contacts(), route(), record_route(), content_type(NULL), @@ -73,7 +73,7 @@ sip_msg::sip_msg() cseq(NULL), via1(NULL),via_p1(NULL), callid(NULL), - contact(NULL), + contacts(), route(), record_route(), content_type(NULL), diff --git a/core/plug-in/sipctrl/sip_parser.h b/core/plug-in/sipctrl/sip_parser.h index 5ee71a01..05d8b655 100644 --- a/core/plug-in/sipctrl/sip_parser.h +++ b/core/plug-in/sipctrl/sip_parser.h @@ -111,7 +111,8 @@ struct sip_msg sip_via_parm* via_p1; sip_header* callid; - sip_header* contact; + + list contacts; list route; list record_route; sip_header* content_type; @@ -130,6 +131,8 @@ struct sip_msg int parse_method(int* method, const char* beg, int len); int parse_sip_msg(sip_msg* msg); +#define get_contact(msg) (msg->contacts.empty() ? NULL : (*msg->contacts.begin())) + #endif /** EMACS ** diff --git a/core/plug-in/sipctrl/trans_layer.cpp b/core/plug-in/sipctrl/trans_layer.cpp index 8cb8a1a9..0a481f75 100644 --- a/core/plug-in/sipctrl/trans_layer.cpp +++ b/core/plug-in/sipctrl/trans_layer.cpp @@ -653,7 +653,7 @@ int trans_layer::cancel(trans_bucket* bucket, sip_trans* t) + copy_hdr_len(req->callid) + cseq_len(get_cseq(req)->num_str,cancel_str) + copy_hdrs_len(req->route) - + copy_hdr_len(req->contact); + + copy_hdrs_len(req->contacts); request_len += 2/* CRLF end-of-headers*/; @@ -673,7 +673,7 @@ int trans_layer::cancel(trans_bucket* bucket, sip_trans* t) copy_hdr_wr(&c,req->callid); cseq_wr(&c,get_cseq(req)->num_str,cancel_str); copy_hdrs_wr(&c,req->route); - copy_hdr_wr(&c,req->contact); + copy_hdrs_wr(&c,req->contacts); *c++ = CR; *c++ = LF; @@ -1156,14 +1156,14 @@ void trans_layer::send_200_ack(sip_msg* reply, sip_trans* t) { // Set request URI // TODO: use correct R-URI instead of just 'Contact' - if(!reply->contact) { + if(!get_contact(reply)) { DBG("Sorry, reply has no Contact header: could not send ACK\n"); return; } sip_nameaddr na; - const char* c = reply->contact->value.s; - if(parse_nameaddr(&na,&c,reply->contact->value.len) < 0){ + const char* c = get_contact(reply)->value.s; + if(parse_nameaddr(&na,&c,get_contact(reply)->value.len) < 0){ DBG("Sorry, reply's Contact parsing failed: could not send ACK\n"); return; }