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