Hi,

I have written a very simple multi-threaded sip proxy using cloned
task.  Basically, I am following the advices from this list as well.

In the request_handler, I would create a new cloned task, that will
create the b-leg and forward the INVITE to b-leg.

then, when uas replies with 180 or 200, I would send it back to the
a-leg by sending a message back to the root task ( called
root_msg_handler ) in my source code.

Inside the root task, I would treply the 180 or 200 back to the
original uac, but it crashes in the line:
                       nta_incoming_treply(irq, SIP_180_RINGING, TAG_END());

Does anyone know what is wrong with my logic?
===============================source code below =============================




#include <stdio.h>
#include <stdlib.h>
typedef struct session_t session_t;
#define NTA_LEG_MAGIC_T      session_t
#define NTA_OUTGOING_MAGIC_T session_t
#define NTA_INCOMING_MAGIC_T session_t
#define SU_MSG_ARG_T struct message
#define NTA_DEBUG  9

#include <sofia-sip/nta.h>
#include <sofia-sip/sip_status.h>

#ifndef ME
#define ME "sip:me-savshzn5fh8qmp+wyrx...@192.168.1.102"
#endif

#ifndef YOU
#define YOU "sip:me-savshzn5fh8qmp+wyrx...@192.168.1.102"
#endif

su_root_t *root;
nta_agent_t *nta;
struct session_t {


        nta_incoming_t *irq ;

};
struct message {

       nta_incoming_t *irq;
       sip_t const *sip;
       session_t* session;
};

int response_to_invite(session_t *session,
                          nta_outgoing_t *request,
                          sip_t const *sip);

int task_init(su_root_t* root, su_root_magic_t* magic)
{
  int i;
  printf("task init...\n");

  return 0;
}


void task_deinit(su_root_t* root, su_root_magic_t* magic)
{
  int i;
  printf("task deinit...\n");

}

void reply_handler(su_root_magic_t *magic, su_msg_r msg,struct message *m)
{
       const sip_t * sip = m->sip;
       printf("reply_handler::sip method = [%i]\n",
sip->sip_request->rq_method);



//      nta_incoming_treply(m->irq, SIP_180_RINGING, TAG_END());
}


int b_leg_request_handler(session_t* session, nta_leg_t *leg,
nta_incoming_t *irq, sip_t const *sip)
{
       printf("b_leg request handler rq_method=[%i]
call_id=[%s]\n",sip->sip_request->rq_method, sip->sip_call_id->i_id);
}
void msg_handler(su_root_magic_t *magic, su_msg_r msg, struct message *m) {



       const sip_t * sip = m->sip;
       printf("msg_handler::sip method = [%i]\n", sip->sip_request->rq_method);


       session_t *new_session;
       nta_leg_t      *b_leg;
       new_session  =   malloc(sizeof(struct session_t));


       nta_outgoing_t* nta_oreq = NULL;
       b_leg = nta_leg_tcreate(nta, b_leg_request_handler,
NULL,SIPTAG_FROM_STR(ME), SIPTAG_TO_STR(YOU), TAG_END());
       nta_oreq = nta_outgoing_tcreate( b_leg,
                  response_to_invite,  new_session ,
                    URL_STRING_MAKE("sip:192.168.1.102:5063"),
                   SIP_METHOD_INVITE,
                    NULL,
                     SIPTAG_EXPIRES_STR("0"),
                       TAG_NULL());



}


void root_msg_handler(su_root_magic_t *magic, su_msg_r msg, struct message *m) {
       const sip_t * sip = m->sip;
       nta_incoming_t *irq = m->irq;
       printf("in root_msg_handler status=[%i]\n", sip->sip_status->st_status);


       switch (sip->sip_status->st_status) {

               case 180:
                       printf("before sending back 180\n");

                       nta_incoming_treply(irq, SIP_180_RINGING, TAG_END());

                       break;
               case 200:
                       printf("before sending back 200\n");
                       nta_incoming_treply(irq, SIP_200_OK, TAG_END());
                       break;

               default:
                       break;

       }

}

int response_to_invite(session_t *session,
                          nta_outgoing_t *request,
                          sip_t const *sip)
{
       int status = sip->sip_status->st_status;
       printf("response_to_invite::call_id=[%s] status=[%i]\n",
sip->sip_call_id->i_id,status);
        switch (status) {

               case 180:
                       {
                               su_msg_r  reply;

                               if (su_msg_new (reply,   sizeof(struct
message)) == 0) {
                                        su_msg_data(reply)->irq = session->irq ;

                                       su_msg_data(reply)->sip =  sip ;

                                        su_msg_send_to(reply,
su_root_task(root), root_msg_handler)  ;

                               }

                       break;
                       }
               case 200:
                       {
                               su_msg_r  reply;

                               if (su_msg_new (reply,   sizeof(struct
message)) == 0) {
                                       su_msg_data(reply)->irq = session->irq ;

                                       su_msg_data(reply)->sip =  sip ;

                                        su_msg_send_to(reply,
su_root_task(root), root_msg_handler)  ;

                               }


                       break;
                       }
               default:

                       break;

       }



}





int request_handler(session_t* session, nta_leg_t *leg, nta_incoming_t
*irq, sip_t const *sip)
{
       su_clone_r ping = SU_CLONE_R_INIT;
       printf("in request_handler rq_method=[%i]
call_id=[%s]\n",sip->sip_request->rq_method, sip->sip_call_id->i_id);
       if (sip->sip_request->rq_method==sip_method_invite) {
               nta_incoming_treply(irq, SIP_100_TRYING, TAG_END());

               if (su_clone_start(root,
                       ping,
                       NULL,
                       &task_init,
                       &task_deinit)==-1) {
                               printf("session clone create not success\n");
               }else {
                       su_msg_r msg = SU_MSG_R_INIT;
                       if (su_msg_create(msg,
su_clone_task(ping),su_root_task(root),msg_handler,  sizeof(struct
message)) ==0) {
                               su_msg_data(msg)->irq = irq;
                               su_msg_data(msg)->sip= sip;
                               su_msg_send(msg);
                       }
               }


       }else {

               printf("message is not an invite\n");
       }
}
int main (int argc, char *argv[])
{

 nta_leg_t *defleg;

 /* Initialize Sofia-SIP library and create event loop */

 root = su_root_create (NULL);
 su_root_threading(root, 1);
 nta =  nta_agent_create(root,
                                 URL_STRING_MAKE("sip:0.0.0.0:5062"),
                                 NULL, NULL,
                                 NTATAG_UA(0),
                                 NTATAG_CANCEL_487(0),
                                 NTATAG_SERVER_RPORT(1),
                                 NTATAG_CLIENT_RPORT(1),
                                NULL);

       if (nta) {

               defleg = nta_leg_tcreate(nta, request_handler,
NULL,NTATAG_NO_DIALOG(1), TAG_END());
               su_root_run(root);

       }

       su_root_destroy(root);



}

------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share
of $1 Million in cash or HP Products. Visit us here for more details:
http://p.sf.net/sfu/dev2dev-palm
_______________________________________________
Sofia-sip-devel mailing list
Sofia-sip-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel

Reply via email to