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:[email protected]"
#endif
#ifndef YOU
#define YOU "sip:[email protected]"
#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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel