[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Linphone-developers] odd sip UA 2xx response handling
From: |
K.S.Chen |
Subject: |
[Linphone-developers] odd sip UA 2xx response handling |
Date: |
Wed, 07 Jan 2004 14:48:29 +0800 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020605 |
Hi,
I suffered a problem with an odd SIP UA. (In fact, it is an Intel HMP IP
media demo program). It responses INVITE almost everything right, except
a header field, Content-Type: application/SDP.
linphone-0.12.1 (or libosip-0.9.7) treats application/SDP and
application/sdp as two content-types, so no 'ACK' request sent.
I trace down the problem, and find a place in ict_callbacks.c to change
to make this odd sip ua happy.
could you apply the change ? or do you have any other solution ?
Thanks.
K.S.Chen
--- osipua/src/ict_callbacks.c.orig Tue Feb 4 00:52:01 2003
+++ osipua/src/ict_callbacks.c Wed Jan 7 14:40:45 2004
@@ -110,6 +110,10 @@
if (body->content_type==NULL){
//osip_trace(OSIP_INFO2,("The content-type is not explicitely set.\n"));
/*try using the content type*/
+
{
+
unsigned char *_p = sipmsg->content_type->subtype;
+
while (*_p) { *_p = tolower(*_p); _p++; }
+
}
ctt=msg_getcontent_type(sipmsg);
if (ctt==NULL){
osip_trace(OSIP_WARNING,("There is no content-type !"));
/*
The osipua library is a library based on oSIP that implements CallLeg and
User Agent
level.
Copyright (C) 2001 Simon MORLAT address@hidden
Aymeric MOIZARD address@hidden
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <errno.h>
#include "osipua.h"
#include <osip/sdp.h>
#include "utils.h"
#include "uatransaction.h"
void ict_kill_transaction(transaction_t*trn)
{
osip_trace (OSIP_INFO1,("Transaction %i killed.\n",
trn->transactionid));
ua_transaction_free (trn);
}
void ict_1xx_received(transaction_t* trn, sip_t* msg)
{
OsipDialog *call;
OsipUA *ua;
int inf;
char *strinf;
osip_trace (OSIP_INFO1, ("OnEvent_New_Incoming1xxResponse!\n"));
call = ua_transaction_get_dialog (trn);
if (call == NULL)
{
osip_trace (OSIP_WARNING,
("1xx response for an inexistant call leg! \n"));
return;
}
strinf = msg->strtline->statuscode;
if (strinf != NULL)
inf = satoi (strinf);
if (inf==180) call->resp180_count++;
ua = (OsipUA *) call->ua;
if (call->resp180_count<2){
if (ua->informative != NULL)
ua->informative (call, trn, msg, (void*)&inf);
}
return; /* ok */
}
void ict_2xx_received(transaction_t* trn, sip_t* sipmsg)
{
OsipDialog *call;
OsipUA *ua;
int pos;
body_t *body;
osip_trace (OSIP_INFO1, ("OnEvent_New_Incoming2xxResponse!\n"));
call = ua_transaction_get_dialog (trn);
if (call != NULL)
{
/* This is not the correct place for refusing 2xx.
oSIP has already processed the 2xx for INVITE
and the answer for cancel should not be a higher code. */
if (call->out_cancel_tr!=NULL) {
return;
}
if (call->dialog==NULL)
{
int i;
i = dialog_init_as_uac(&(call->dialog), sipmsg);
if (i!=0) {
osip_trace (OSIP_WARNING,
("200 OK is probably incomplete!\n"));
return;
}
}
else
dialog_update_route_set_as_uac(call->dialog, sipmsg);
/* an existing call-leg was found, so process it */
ua = osip_dialog_get_ua (call);
if (MSG_IS_INVITE (trn->orig_request))
{
call->status = DIALOG_ESTABLISHED;
/* invoke the body handlers for all bodies in the 200
Ok */
pos = 0;
while (msg_getbody (sipmsg, pos, &body) == 0)
{
BodyHandler *info;
BodyContext *bh;
char *mime;
content_type_t *ctt;
if (body->content_type==NULL){
//osip_trace(OSIP_INFO2,("The
content-type is not explicitely set.\n"));
/*try using the content type*/
{
unsigned char *_p =
sipmsg->content_type->subtype;
while (*_p) { *_p =
tolower(*_p); _p++; }
}
ctt=msg_getcontent_type(sipmsg);
if (ctt==NULL){
osip_trace(OSIP_WARNING,("There
is no content-type !"));
/* do something better here */
break;
}
mime=content_type_get_type(ctt);
}else
mime=content_type_get_type(body->content_type);
osip_trace (OSIP_INFO1,("Found body
%s\n",mime));
/* try to get a body handler already present
for the call-leg */
bh=osip_dialog_get_body_context(call,mime,-1);
if (bh==NULL){
info = osip_ua_find_handler (ua,mime);
if (info == NULL)
{
osip_trace
(OSIP_WARNING,("Could not find a body handler.\n"));
return;
}
osip_trace(OSIP_INFO1,("Creating a new
body context.\n"));
bh=body_handler_create_context(info,call);
}
sfree(mime);
body_context_notify_inc_response(bh,sipmsg,body->body);
pos++;
}
/* indicate the user of the acceptation of the invite */
if (ua->invite_accepted != NULL)
ua->invite_accepted (call, trn ,sipmsg,
(void *) NULL);
/* respond ACK to the server */
osip_dialog_ack (call, trn);
//osip_trace (OSIP_INFO1, ("Sending ACK!\n"));
}
}
else
{
osip_trace (OSIP_WARNING,
("200 OK for an inexistant call-leg !\n"));
}
return; /* ok */
}
void ict_3xx_received(transaction_t* trn, sip_t* sipmsg)
{
char *strinf, *tmp;
int code = 0, err;
OsipDialog *call;
OsipUA *ua;
contact_t *contact = NULL;
osip_trace (OSIP_INFO1, ("OnEvent_New_Incoming3xxResponse!\n"));
call = ua_transaction_get_dialog (trn);
if (call == NULL)
{
osip_trace (OSIP_WARNING,
("3xx response for an inexistant call leg! \n"));
return;
}
ua = osip_dialog_get_ua (call);
if (call->dialog!=NULL && call->dialog->state==DIALOG_EARLY)
{
dialog_free(call->dialog);
sfree(call->dialog);
call->dialog=NULL;
}
strinf = sipmsg->strtline->statuscode;
if (strinf != NULL)
code = satoi (strinf);
if (ua->informative != NULL)
ua->informative (call, trn, sipmsg, (void*)&code);
switch (code)
{
case 300: /*Multiples choices */
break;
case 301: /*Moved permanently */
break;
case 302: /*Moved temporarily */
osip_trace (OSIP_INFO1, ("User has moved temporarily.\n"));
/* get first contact field */
err = msg_getcontact (sipmsg, 0, &contact);
if (contact != NULL)
{ /* do redirection */
BodyContext *bc;
char *mime=NULL;
call->status = DIALOG_NEW;
/* remove params like action=redirect */
listofchar_free (contact->gen_params);
contact_2char (contact, &tmp);
/* re invite with the same body*/
bc=(BodyContext*)list_get(&call->body_contexts,0);
if (bc!=NULL){
mime=body_context_get_mime(bc);
}
osip_dialog_invite (call, tmp, mime);
sfree (tmp);
}
break;
case 305: /* Use proxy */
break;
}
/* then we invite using the address in the contact header */
return; /* ok */
}
void ict_4xx_received(transaction_t* trn, sip_t* sipmsg)
{
OsipDialog *call;
OsipUA *ua;
char *strerr;
int error;
osip_trace (OSIP_INFO1, ("OnEvent_New_Incoming4xxResponse!\n"));
call = ua_transaction_get_dialog (trn);
if (call == NULL)
{
osip_trace (OSIP_WARNING,
("4xx response for an inexistant dialog! \n"));
return;
}
ua = osip_dialog_get_ua (call);
if (call->dialog!=NULL && call->dialog->state==DIALOG_EARLY)
{
dialog_free(call->dialog);
sfree(call->dialog);
call->dialog=NULL;
}
strerr = sipmsg->strtline->statuscode;
if (strerr != NULL)
error = satoi (strerr);
switch (error)
{
case 407:
case 401:
if (call->inv_auth_count==0){
osip_trace (OSIP_INFO1,
("User need to authenticate to INVITE!\n"));
call->status = DIALOG_NEW;
osip_dialog_reinvite_with_authentication
(call,sipmsg,ua->reg_passwd);
call->inv_auth_count++;
}
else
{
osip_trace (OSIP_INFO1,("Authentification aborted.\n"));
break;
}
return;
}
if (ua->faillure != NULL)
ua->faillure (call, trn,sipmsg, (void*)&error);
osip_dialog_release (call);
return; /* ok */
}
void ict_5xx_received(transaction_t* trn, sip_t* sipmsg)
{
OsipDialog *call;
OsipUA *ua;
char *strerr;
int error;
osip_trace (OSIP_INFO1, ("ict_5xx_received():\n"));
call = ua_transaction_get_dialog (trn);
if (call == NULL)
{
osip_trace (OSIP_WARNING,
("5xx response for an inexistant call leg! \n"));
return;
}
ua = osip_dialog_get_ua (call);
if (call->dialog!=NULL && call->dialog->state==DIALOG_EARLY)
{
dialog_free(call->dialog);
sfree(call->dialog);
call->dialog=NULL;
}
strerr = sipmsg->strtline->statuscode;
if (strerr != NULL)
error = satoi (strerr);
if (ua->faillure != NULL)
ua->faillure (call, trn, sipmsg, (void*)&error);
osip_dialog_release (call);
return; /* ok */
}
void ict_6xx_received(transaction_t* trn, sip_t* sipmsg)
{
OsipDialog *call;
OsipUA *ua;
char *strerr;
int error;
osip_trace (OSIP_INFO1, ("OnEvent_New_Incoming6xxResponse!\n"));
call = ua_transaction_get_dialog (trn);
if (call == NULL)
{
osip_trace (OSIP_WARNING,
("6xx response for an inexistant call leg! \n"));
return;
}
ua = osip_dialog_get_ua (call);
if (call->dialog!=NULL && call->dialog->state==DIALOG_EARLY)
{
dialog_free(call->dialog);
sfree(call->dialog);
call->dialog=NULL;
}
strerr = sipmsg->strtline->statuscode;
if (strerr != NULL)
error = satoi (strerr);
if (ua->faillure != NULL)
ua->faillure (call, trn, sipmsg, (void*)&error);
osip_dialog_release (call);
return; /* ok */
}
- [Linphone-developers] odd sip UA 2xx response handling,
K.S.Chen <=