linphone-developers
[Top][All Lists]
Advanced

[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 */
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]