mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-22 13:48:09 +00:00
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@1 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
1264 lines
34 KiB
C
1264 lines
34 KiB
C
/*
|
|
eXosip - This is the eXtended osip library.
|
|
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
|
|
|
eXosip is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
eXosip is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#ifdef ENABLE_MPATROL
|
|
#include <mpatrol.h>
|
|
#endif
|
|
|
|
#include "eXosip2.h"
|
|
#include <eXosip_cfg.h>
|
|
|
|
extern eXosip_t eXosip;
|
|
|
|
/* Private functions */
|
|
static char *generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd,
|
|
osip_message_t *orig_request, char *local_sdp_port);
|
|
|
|
int
|
|
eXosip_build_response_default(int jid, int status)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
_eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog,
|
|
int status, osip_message_t *request)
|
|
{
|
|
osip_generic_param_t *tag;
|
|
osip_message_t *response;
|
|
int pos;
|
|
int i;
|
|
|
|
if (request==NULL) return -1;
|
|
|
|
i = osip_message_init(&response);
|
|
if (i!=0)
|
|
return -1;
|
|
/* initialise osip_message_t structure */
|
|
/* yet done... */
|
|
|
|
response->sip_version = (char *)osip_malloc(8*sizeof(char));
|
|
sprintf(response->sip_version,"SIP/2.0");
|
|
osip_message_set_status_code(response, status);
|
|
|
|
/* handle some internal reason definitions. */
|
|
if (MSG_IS_NOTIFY(request) && status==481)
|
|
{
|
|
response->reason_phrase = osip_strdup("Subcription Does Not Exist");
|
|
}
|
|
else if (MSG_IS_SUBSCRIBE(request) && status==202)
|
|
{
|
|
response->reason_phrase = osip_strdup("Accepted subscription");
|
|
}
|
|
else
|
|
{
|
|
response->reason_phrase = osip_strdup(osip_message_get_reason(status));
|
|
if (response->reason_phrase==NULL)
|
|
{
|
|
if (response->status_code == 101)
|
|
response->reason_phrase = osip_strdup("Dialog Establishement");
|
|
else
|
|
response->reason_phrase = osip_strdup("Unknown code");
|
|
}
|
|
response->req_uri = NULL;
|
|
response->sip_method = NULL;
|
|
}
|
|
|
|
i = osip_to_clone(request->to, &(response->to));
|
|
if (i!=0) goto grd_error_1;
|
|
|
|
i = osip_to_get_tag(response->to,&tag);
|
|
if (i!=0)
|
|
{ /* we only add a tag if it does not already contains one! */
|
|
if ((dialog!=NULL) && (dialog->local_tag!=NULL))
|
|
/* it should contain the local TAG we created */
|
|
{ osip_to_set_tag(response->to, osip_strdup(dialog->local_tag)); }
|
|
else
|
|
{
|
|
if (status!=100)
|
|
osip_to_set_tag(response->to, osip_to_tag_new_random());
|
|
}
|
|
}
|
|
|
|
i = osip_from_clone(request->from, &(response->from));
|
|
if (i!=0) goto grd_error_1;
|
|
|
|
pos = 0;
|
|
while (!osip_list_eol(request->vias,pos))
|
|
{
|
|
osip_via_t *via;
|
|
osip_via_t *via2;
|
|
via = (osip_via_t *)osip_list_get(request->vias,pos);
|
|
i = osip_via_clone(via, &via2);
|
|
if (i!=-0) goto grd_error_1;
|
|
osip_list_add(response->vias, via2, -1);
|
|
pos++;
|
|
}
|
|
|
|
i = osip_call_id_clone(request->call_id, &(response->call_id));
|
|
if (i!=0) goto grd_error_1;
|
|
i = osip_cseq_clone(request->cseq, &(response->cseq));
|
|
if (i!=0) goto grd_error_1;
|
|
|
|
if (MSG_IS_SUBSCRIBE(request))
|
|
{
|
|
osip_header_t *exp;
|
|
osip_message_set_header(response, "Event", "presence");
|
|
i = osip_message_get_expires(request, 0, &exp);
|
|
if (exp==NULL)
|
|
{
|
|
osip_header_t *cp;
|
|
i = osip_header_clone(exp, &cp);
|
|
if (cp!=NULL)
|
|
osip_list_add(response->headers, cp, 0);
|
|
}
|
|
}
|
|
|
|
osip_message_set_allow(response, "INVITE");
|
|
osip_message_set_allow(response, "ACK");
|
|
osip_message_set_allow(response, "OPTIONS");
|
|
osip_message_set_allow(response, "CANCEL");
|
|
osip_message_set_allow(response, "BYE");
|
|
osip_message_set_allow(response, "SUBSCRIBE");
|
|
osip_message_set_allow(response, "NOTIFY");
|
|
osip_message_set_allow(response, "MESSAGE");
|
|
osip_message_set_allow(response, "INFO");
|
|
|
|
*dest = response;
|
|
return 0;
|
|
|
|
grd_error_1:
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
complete_answer_that_establish_a_dialog(osip_message_t *response, osip_message_t *request)
|
|
{
|
|
int i;
|
|
int pos=0;
|
|
char contact[1000];
|
|
#ifdef SM
|
|
char *locip=NULL;
|
|
#else
|
|
char locip[50];
|
|
#endif
|
|
/* 12.1.1:
|
|
copy all record-route in response
|
|
add a contact with global scope
|
|
*/
|
|
while (!osip_list_eol(request->record_routes, pos))
|
|
{
|
|
osip_record_route_t *rr;
|
|
osip_record_route_t *rr2;
|
|
rr = osip_list_get(request->record_routes, pos);
|
|
i = osip_record_route_clone(rr, &rr2);
|
|
if (i!=0) return -1;
|
|
osip_list_add(response->record_routes, rr2, -1);
|
|
pos++;
|
|
}
|
|
|
|
#ifdef SM
|
|
eXosip_get_localip_from_via(response,&locip);
|
|
#else
|
|
eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49);
|
|
#endif
|
|
|
|
if (eXosip.answer_contact[0])
|
|
snprintf(contact,1000, "%s", eXosip.answer_contact);
|
|
else if (request->to->url->username==NULL)
|
|
snprintf(contact,1000, "<sip:%s:%s>", locip, eXosip.localport);
|
|
else
|
|
snprintf(contact,1000, "<sip:%s@%s:%s>", request->to->url->username,
|
|
locip, eXosip.localport);
|
|
|
|
if (eXosip.j_firewall_ip[0]!='\0')
|
|
{
|
|
osip_contact_t *con = (osip_contact_t *) osip_list_get (request->contacts, 0);
|
|
if (con!=NULL && con->url!=NULL && con->url->host!=NULL)
|
|
{
|
|
char *c_address = con->url->host;
|
|
|
|
struct addrinfo *addrinfo;
|
|
struct __eXosip_sockaddr addr;
|
|
i = eXosip_get_addrinfo(&addrinfo, con->url->host, 5060);
|
|
if (i==0)
|
|
{
|
|
memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
|
|
freeaddrinfo (addrinfo);
|
|
c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_INFO1, NULL,
|
|
"eXosip: here is the resolved destination host=%s\n", c_address));
|
|
}
|
|
|
|
/* If c_address is a PUBLIC address, the request was
|
|
coming from the PUBLIC network. */
|
|
if (eXosip_is_public_address(c_address))
|
|
{
|
|
if (request->to->url->username==NULL)
|
|
snprintf(contact,1000, "<sip:%s:%s>", eXosip.j_firewall_ip,
|
|
eXosip.localport);
|
|
else
|
|
snprintf(contact,1000, "<sip:%s@%s:%s>", request->to->url->username,
|
|
eXosip.j_firewall_ip, eXosip.localport);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef SM
|
|
osip_free(locip);
|
|
#endif
|
|
|
|
osip_message_set_contact(response, contact);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static char *
|
|
generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd,
|
|
osip_message_t *orig_request, char *local_sdp_port)
|
|
{
|
|
sdp_message_t *local_sdp = NULL;
|
|
char *local_body = NULL;
|
|
char *size;
|
|
int i;
|
|
|
|
jc->c_ack_sdp = 1;
|
|
if(osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &local_sdp, local_sdp_port, NULL) != 0)
|
|
return NULL;
|
|
|
|
if (local_sdp!=NULL)
|
|
{
|
|
int pos=0;
|
|
while (!sdp_message_endof_media (local_sdp, pos))
|
|
{
|
|
int k = 0;
|
|
char *tmp = sdp_message_m_media_get (local_sdp, pos);
|
|
if (0 == strncmp (tmp, "audio", 5))
|
|
{
|
|
char *payload = NULL;
|
|
do {
|
|
payload = sdp_message_m_payload_get (local_sdp, pos, k);
|
|
if (payload == NULL)
|
|
{
|
|
}
|
|
else if (0==strcmp("110",payload))
|
|
{
|
|
sdp_message_a_attribute_add (local_sdp,
|
|
pos,
|
|
osip_strdup ("AS"),
|
|
osip_strdup ("110 20"));
|
|
}
|
|
else if (0==strcmp("111",payload))
|
|
{
|
|
sdp_message_a_attribute_add (local_sdp,
|
|
pos,
|
|
osip_strdup ("AS"),
|
|
osip_strdup ("111 20"));
|
|
}
|
|
k++;
|
|
} while (payload != NULL);
|
|
}
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
i = sdp_message_to_str(local_sdp, &local_body);
|
|
|
|
if (local_body!=NULL)
|
|
{
|
|
size= (char *)osip_malloc(7*sizeof(char));
|
|
#ifdef __APPLE_CC__
|
|
sprintf(size,"%li",strlen(local_body));
|
|
#else
|
|
sprintf(size,"%i",strlen(local_body));
|
|
#endif
|
|
osip_message_set_content_length(orig_request, size);
|
|
osip_free(size);
|
|
|
|
osip_message_set_body(orig_request, local_body, strlen(local_body));
|
|
osip_message_set_content_type(orig_request, "application/sdp");
|
|
}
|
|
else
|
|
osip_message_set_content_length(orig_request, "0");
|
|
|
|
osip_negotiation_ctx_set_local_sdp(jc->c_ctx, local_sdp);
|
|
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL,"200 OK w/ SDP (RESPONSE TO INVITE w/ NO SDP)=\n%s\n", local_body));
|
|
|
|
return local_body;
|
|
}
|
|
|
|
char *
|
|
generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context)
|
|
{
|
|
sdp_message_t *remote_sdp;
|
|
sdp_message_t *local_sdp = NULL;
|
|
int i;
|
|
char *local_body;
|
|
if (context==NULL)
|
|
return NULL;
|
|
|
|
local_body = NULL;
|
|
if (MSG_IS_INVITE(request)||MSG_IS_OPTIONS(request)||MSG_IS_RESPONSE_FOR(request, "INVITE"))
|
|
{
|
|
osip_body_t *body;
|
|
body = (osip_body_t *)osip_list_get(request->bodies,0);
|
|
if(body == NULL)
|
|
return NULL;
|
|
|
|
/* remote_sdp = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t)); */
|
|
i = sdp_message_init(&remote_sdp);
|
|
if (i!=0) return NULL;
|
|
|
|
/* WE ASSUME IT IS A SDP BODY AND THAT */
|
|
/* IT IS THE ONLY ONE, OF COURSE, THIS IS */
|
|
/* NOT TRUE */
|
|
i = sdp_message_parse(remote_sdp,body->body);
|
|
if (i!=0) return NULL;
|
|
|
|
i = osip_negotiation_ctx_set_remote_sdp(context, remote_sdp);
|
|
|
|
i = osip_negotiation_ctx_execute_negotiation(eXosip.osip_negotiation, context);
|
|
if (i==200)
|
|
{
|
|
local_sdp = osip_negotiation_ctx_get_local_sdp(context);
|
|
|
|
if (eXosip.j_firewall_ip[0]!='\0')
|
|
{
|
|
char *c_address = NULL;
|
|
int pos=0;
|
|
/* If remote message contains a Public IP, we have to replace the SDP
|
|
connection address */
|
|
c_address = sdp_message_c_addr_get(remote_sdp, -1, 0);
|
|
while (c_address==NULL)
|
|
{
|
|
c_address = sdp_message_c_addr_get(remote_sdp, pos, 0);
|
|
pos++;
|
|
if (pos>10)
|
|
break;
|
|
}
|
|
if (c_address!=NULL) /* found a connection address: check if it is public */
|
|
{
|
|
|
|
struct addrinfo *addrinfo;
|
|
struct __eXosip_sockaddr addr;
|
|
i = eXosip_get_addrinfo(&addrinfo, c_address, 5060);
|
|
if (i==0)
|
|
{
|
|
memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
|
|
freeaddrinfo (addrinfo);
|
|
c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr);
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_INFO1, NULL,
|
|
"eXosip: here is the resolved destination host=%s\n", c_address));
|
|
}
|
|
|
|
if (eXosip_is_public_address(c_address))
|
|
{
|
|
/* replace the IP with our firewall ip */
|
|
sdp_connection_t *conn;
|
|
pos=-1;
|
|
conn = sdp_message_connection_get(local_sdp, pos, 0);
|
|
while (conn!=NULL)
|
|
{
|
|
if (conn->c_addr!=NULL )
|
|
{
|
|
osip_free(conn->c_addr);
|
|
conn->c_addr = osip_strdup(eXosip.j_firewall_ip);
|
|
}
|
|
pos++;
|
|
conn = sdp_message_connection_get(local_sdp, pos, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
i = sdp_message_to_str(local_sdp, &local_body);
|
|
|
|
remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
|
|
sdp_message_free(remote_sdp);
|
|
osip_negotiation_ctx_set_remote_sdp(context, NULL);
|
|
|
|
if (i!=0) {
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not parse local SDP answer %i\n",i));
|
|
return NULL;
|
|
}
|
|
return local_body;
|
|
}
|
|
else if (i==415)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"WARNING: Unsupported media %i\n",i));
|
|
}
|
|
else
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: while building answer to SDP (%i)\n",i));
|
|
}
|
|
remote_sdp = osip_negotiation_ctx_get_remote_sdp(context);
|
|
sdp_message_free(remote_sdp);
|
|
osip_negotiation_ctx_set_remote_sdp(context, NULL);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_transaction_t *tr;
|
|
osip_message_t *response;
|
|
int i;
|
|
|
|
tr = eXosip_find_last_inc_options(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd!=NULL)
|
|
{
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
}
|
|
else
|
|
{
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
}
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for OPTIONS\n"));
|
|
return -1;
|
|
}
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_transaction_t *tr;
|
|
osip_message_t *response;
|
|
sdp_message_t *sdp;
|
|
char *body;
|
|
char size[10];
|
|
int i;
|
|
|
|
tr = eXosip_find_last_inc_options(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL);
|
|
if (sdp==NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
if (jd!=NULL)
|
|
{
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
}
|
|
else
|
|
{
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
}
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n"));
|
|
sdp_message_free(sdp); /* not used */
|
|
return -1;
|
|
}
|
|
i = sdp_message_to_str(sdp, &body);
|
|
sdp_message_free(sdp);
|
|
if (i!=0) {
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
i = osip_message_set_body(response, body, strlen(body));
|
|
if (i!=0) {
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
#ifdef __APPLE_CC__
|
|
snprintf(size, 9,"%li",strlen(body));
|
|
#else
|
|
snprintf(size, 9,"%i",strlen(body));
|
|
#endif
|
|
i = osip_message_set_content_length(response, size);
|
|
if (i!=0) {
|
|
osip_free(body);
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
osip_free(body);
|
|
i = osip_message_set_content_type(response, "application/sdp");
|
|
if (i!=0) {
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_transaction_t *tr;
|
|
osip_message_t *response;
|
|
int i;
|
|
tr = eXosip_find_last_inc_options(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd!=NULL)
|
|
{
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
}
|
|
else
|
|
{
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
}
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (300<=code<=399)
|
|
{
|
|
/* Should add contact fields */
|
|
/* ... */
|
|
osip_message_set_contact(response, jc->c_redirection);
|
|
}
|
|
|
|
osip_message_set_content_length(response, "0");
|
|
/* send message to transaction layer */
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
_eXosip2_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
|
|
{
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n"));
|
|
return -2;
|
|
}
|
|
|
|
osip_message_set_content_length(*answer, "0");
|
|
/* send message to transaction layer */
|
|
|
|
if (code>100)
|
|
{
|
|
i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
_eXosip2_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
|
|
{
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
|
|
if (tr==NULL || tr->orig_request==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd!=NULL && jd->d_dialog==NULL)
|
|
{ /* element previously removed */
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot answer this closed transaction\n"));
|
|
return -1;
|
|
}
|
|
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(answer, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
|
|
return -1;
|
|
}
|
|
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
{
|
|
i = complete_answer_that_establish_a_dialog(*answer, tr->orig_request);
|
|
if (i!=0) goto g2atii_error_1;; /* ?? */
|
|
}
|
|
|
|
return 0;
|
|
|
|
g2atii_error_1:
|
|
osip_message_free(*answer);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
_eXosip2_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer)
|
|
{
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
i = _eXosip_build_response_default(answer, jd->d_dialog, code, tr->orig_request);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (300<=code<=399)
|
|
{
|
|
/* Should add contact fields */
|
|
/* ... */
|
|
}
|
|
|
|
osip_message_set_content_length(*answer, "0");
|
|
/* send message to transaction layer */
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for invite\n"));
|
|
return -2;
|
|
}
|
|
|
|
osip_message_set_content_length(response, "0");
|
|
/* send message to transaction layer */
|
|
|
|
if (code>100)
|
|
{
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
|
|
|
|
if (jd==NULL)
|
|
{
|
|
i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot create dialog!\n"));
|
|
}
|
|
ADD_ELEMENT(jc->c_dialogs, jd);
|
|
}
|
|
}
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
char *size;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
|
|
if (tr==NULL || tr->orig_request==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd!=NULL && jd->d_dialog==NULL)
|
|
{ /* element previously removed */
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot answer this closed transaction\n"));
|
|
return -1;
|
|
}
|
|
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
|
|
code = 500; /* ? which code to use? */
|
|
return -1;
|
|
}
|
|
|
|
if (code==488)
|
|
{
|
|
osip_message_set_content_length(response, "0");
|
|
/* TODO: send message to transaction layer */
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
}
|
|
|
|
i = osip_message_set_body(response, body, strlen(body));
|
|
if (i!=0) {
|
|
goto g2atii_error_1;
|
|
}
|
|
size = (char *) osip_malloc(6*sizeof(char));
|
|
sprintf(size,"%i",strlen(body));
|
|
i = osip_message_set_content_length(response, size);
|
|
osip_free(size);
|
|
if (i!=0) goto g2atii_error_1;
|
|
i = osip_message_set_content_type(response, bodytype);
|
|
if (i!=0) goto g2atii_error_1;
|
|
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
{
|
|
i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
|
|
if (i!=0) goto g2atii_error_1;; /* ?? */
|
|
}
|
|
/* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
|
|
/* this response must be stored at the upper layer!!! (it will be destroyed*/
|
|
/* right after being sent! */
|
|
|
|
if (jd==NULL)
|
|
{
|
|
i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot create dialog!\n"));
|
|
return -1;
|
|
}
|
|
ADD_ELEMENT(jc->c_dialogs, jd);
|
|
}
|
|
|
|
eXosip_dialog_set_200ok(jd, response);
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
|
|
osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
|
|
g2atii_error_1:
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
char *size;
|
|
char *body = NULL;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
|
|
if (tr==NULL || tr->orig_request==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (jd!=NULL && jd->d_dialog==NULL)
|
|
{ /* element previously removed */
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot answer this closed transaction\n"));
|
|
return -1;
|
|
}
|
|
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
/* WE SHOULD LOOK FOR A SDP PACKET!! */
|
|
if(NULL != osip_list_get(tr->orig_request->bodies,0))
|
|
{
|
|
body = generating_sdp_answer(tr->orig_request, jc->c_ctx);
|
|
if (body==NULL)
|
|
code = 488; /* bad sdp */
|
|
}
|
|
else
|
|
{
|
|
if(local_sdp_port==NULL)
|
|
code = 488; /* session description in the request is not acceptable. */
|
|
else
|
|
/* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */
|
|
body = generating_no_sdp_answer(jc, jd, tr->orig_request, local_sdp_port);
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
|
|
code = 500; /* ? which code to use? */
|
|
osip_free(body); /* not used */
|
|
return -1;
|
|
}
|
|
|
|
if (code==488)
|
|
{
|
|
osip_message_set_content_length(response, "0");
|
|
/* TODO: send message to transaction layer */
|
|
osip_free(body);
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
}
|
|
|
|
i = osip_message_set_body(response, body, strlen(body));
|
|
if (i!=0) {
|
|
goto g2atii_error_1;
|
|
}
|
|
size = (char *) osip_malloc(6*sizeof(char));
|
|
#ifdef __APPLE_CC__
|
|
sprintf(size,"%li",strlen(body));
|
|
#else
|
|
sprintf(size,"%i",strlen(body));
|
|
#endif
|
|
i = osip_message_set_content_length(response, size);
|
|
osip_free(size);
|
|
if (i!=0) goto g2atii_error_1;
|
|
i = osip_message_set_content_type(response, "application/sdp");
|
|
if (i!=0) goto g2atii_error_1;
|
|
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
{
|
|
i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
|
|
if (i!=0) goto g2atii_error_1;; /* ?? */
|
|
}
|
|
|
|
osip_free(body);
|
|
/* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
|
|
/* this response must be stored at the upper layer!!! (it will be destroyed*/
|
|
/* right after being sent! */
|
|
|
|
if (jd==NULL)
|
|
{
|
|
i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot create dialog!\n"));
|
|
return -1;
|
|
}
|
|
ADD_ELEMENT(jc->c_dialogs, jd);
|
|
}
|
|
|
|
eXosip_dialog_set_200ok(jd, response);
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
|
|
osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
|
|
g2atii_error_1:
|
|
osip_free(body);
|
|
osip_message_free(response);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_invite(jc, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return -1;
|
|
}
|
|
/* is the transaction already answered? */
|
|
if (tr->state==IST_COMPLETED
|
|
|| tr->state==IST_CONFIRMED
|
|
|| tr->state==IST_TERMINATED)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: transaction already answered\n"));
|
|
return -1;
|
|
}
|
|
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
|
|
return -1;
|
|
}
|
|
|
|
if (300<=code<=399)
|
|
{
|
|
/* Should add contact fields */
|
|
/* ... */
|
|
osip_message_set_contact(response, jc->c_redirection);
|
|
}
|
|
|
|
osip_message_set_content_length(response, "0");
|
|
/* send message to transaction layer */
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
eXosip_notify_answer_subscribe_1xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_subscribe(jn, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL,"ERROR: Could not create response for subscribe\n"));
|
|
return;
|
|
}
|
|
|
|
if (code>100)
|
|
{
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
|
|
|
|
if (jd==NULL)
|
|
{
|
|
i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot create dialog!\n"));
|
|
}
|
|
ADD_ELEMENT(jn->n_dialogs, jd);
|
|
}
|
|
}
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return ;
|
|
}
|
|
|
|
void
|
|
eXosip_notify_answer_subscribe_2xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_subscribe(jn, jd);
|
|
|
|
if (tr==NULL || tr->orig_request==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer\n"));
|
|
return;
|
|
}
|
|
|
|
if (jd!=NULL && jd->d_dialog==NULL)
|
|
{ /* element previously removed, this is a no hop! */
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot answer this closed transaction\n"));
|
|
return ;
|
|
}
|
|
|
|
if (jd==NULL)
|
|
i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
|
|
else
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n"));
|
|
code = 500; /* ? which code to use? */
|
|
return;
|
|
}
|
|
|
|
/* request that estabish a dialog: */
|
|
/* 12.1.1 UAS Behavior */
|
|
{
|
|
i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
|
|
if (i!=0) goto g2atii_error_1;; /* ?? */
|
|
}
|
|
|
|
/* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
|
|
/* this response must be stored at the upper layer!!! (it will be destroyed*/
|
|
/* right after being sent! */
|
|
|
|
if (jd==NULL)
|
|
{
|
|
i = eXosip_dialog_init_as_uas(&jd, tr->orig_request, response);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot create dialog!\n"));
|
|
return;
|
|
}
|
|
ADD_ELEMENT(jn->n_dialogs, jd);
|
|
}
|
|
|
|
eXosip_dialog_set_200ok(jd, response);
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
|
|
osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
|
|
return ;
|
|
|
|
g2atii_error_1:
|
|
osip_message_free(response);
|
|
return ;
|
|
}
|
|
|
|
void
|
|
eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn, eXosip_dialog_t *jd, int code)
|
|
{
|
|
osip_event_t *evt_answer;
|
|
osip_message_t *response;
|
|
int i;
|
|
osip_transaction_t *tr;
|
|
tr = eXosip_find_last_inc_subscribe(jn, jd);
|
|
if (tr==NULL)
|
|
{
|
|
OSIP_TRACE (osip_trace
|
|
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
|
"eXosip: cannot find transaction to answer"));
|
|
return;
|
|
}
|
|
i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);
|
|
if (i!=0)
|
|
{
|
|
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for subscribe\n"));
|
|
return;
|
|
}
|
|
|
|
if (300<=code<=399)
|
|
{
|
|
/* Should add contact fields */
|
|
/* ... */
|
|
}
|
|
|
|
evt_answer = osip_new_outgoing_sipmessage(response);
|
|
evt_answer->transactionid = tr->transactionid;
|
|
|
|
osip_transaction_add_event(tr, evt_answer);
|
|
__eXosip_wakeup();
|
|
return ;
|
|
}
|