Hi,

I solved the problem. I was using 'ddd' to debug and so I saw how the
sofia-sip thread was getting a SIGINT signal.

Before going completely nuts I saw a light from heaven and commented out one
line in the code which I had inherited from another similar program. This
solved my problem:

//                   NUTAG_AUTOACK(0), /* no automatic ACK send */


and now it works fine.

Regards,

Jordi



2009/4/24 Jordi Jaen Pallares <jord...@gmail.com>

> Hi,
>
> I am trying to write a small program with sofia-sip and glib.
>
>
> GUI <----> Sofia-SIP Stack <----------------> SIP Media Server
>
>
> The Sofia-SIP Stack program has a socket control interface fro the GUI that
> will provision the commands "INVITE" or "BYE" to the Sofia-SIP Stack. The
> other socket is used to communicate with a SIP Media Server.
>
> The Sofia-SIP stack receives the "INVITE" command from the GUI and sends
> successfully a SIP INVITE to the media server, but then the 200 OK from the
> Media Server are not received (any of the retransmissions) so at the end I
> have an ACK timeout at the media server.
>
> The function init_listening_socket creates a socket and bind it to a
> IOChannel. I define a io_callback function to handle the GUI commands. The
> main procedure initialized the sofia-sip-ua-glib main loop as in the example
> I found in the documentation.
>
> The Sofia-SIP stack does not print the nua_i_state "INVITE sent", so
> probably the threads do not return correctly to the g_main_loop. What is
> missing ? Does anybody have a suggestion ?
>
> Here is the code I am using:
>
>
>
> ************************
>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <sofia-sip/nua.h>
> #include <sofia-sip/su.h>
> #include <sofia-sip/sip_status.h>
> #include <sofia-sip/sdp.h>
> #include <sofia-sip/su_localinfo.h>
> #include <sofia-sip/sdp_tag.h>
>
> #include <sofia-sip/su_glib.h>
>
> #include <glib.h>
>
> #include "conveho_cfg.h"
>
> #define SECONDS_S "15"
> #define SMF_LISTEN 5060
> #define SMF_LISTEN_S "5060"
>
> #define GUI_SENDPORT 7020
>
>
> nua_t *nua;
> nua_handle_t *handle;
>
> static int local_port;
>
> /* This callback will be called by SIP stack to
>  * process incoming events
>  */
> void event_callback(nua_event_t   event,
>                     int           status,
>                     char const   *phrase,
>                     nua_t        *nua,
>                     nua_magic_t  *magic,
>                     nua_handle_t *nh,
>                     nua_hmagic_t *hmagic,
>                     sip_t const  *sip,
>                     tagi_t        tags[])
> {
>
>   switch (event) {
>           case nua_i_invite:
>                   printf ("nua_i_invite %p: %d %s\n",
>                                   nh, status, phrase);
>
>                   break;
>           case nua_r_invite:
>                   printf ("nua_r_invite %p: %d %s\n",
>                                   nh, status, phrase);
>
>                   if (status == 200) {
>                           printf ("Received INVITE with status 200 !\n");
>                           nua_ack (nh,
>                           TAG_END());
>                   }
>
>                   break;
>           case nua_i_state:
>                   printf ("nua_i_state %p: %d %s\n",
>                                   nh, status, phrase);
>                   break;
>           case nua_i_active:
>                   printf ("nua_active %p: %d %s\n",
>                                   nh, status, phrase);
>                   //
>                   // handle call
>                   //
>
>                   break;
>           case nua_i_ack:
>                   // this is an ACK to an incoming call event
>                   printf ("nua_i_ack %p: %d %s\n",
>                                   nh, status, phrase);//mp_i_ack (event,
> status, phrase, nua, magic, nh, hmagic, sip, tags);
>                   break;
>           case nua_r_ack:
>                   // this is an ACK to an incoming call event
>                   printf ("nua_r_ack %p: %d %s\n",
>                                   nh, status, phrase);//mp_r_ack (event,
> status, phrase, nua, magic, nh, hmagic, sip, tags);
>                   break;
>           case nua_r_bye:
>                   // this is the response to BYE
>                   printf ("nua_r_bye %p: %d %s\n",
>                                   nh, status, phrase);//mp_r_bye (event,
> status, phrase, nua, magic, nh, hmagic, sip, tags);
>                   break;
>          case nua_i_terminated:
>                   // this is the response to BYE
>                   printf ("Terminated %p: %d %s\n",
>                                   nh, status, phrase);
>                   // destroy handle
>                   exit(0);
>                   break;
>           case nua_r_shutdown:
>                   // this is called after a nua_shutdown
>                   printf ("[DEBUG] nua_r_shutdown %p: %d %s\n",
>                                   nh, status, phrase);
>                   printf ("[DEBUG] shutting down...\n");
>                   nua_destroy (nua);
>                   break;
>           default:
>                   printf ("Received an event %s status %d %s\n",
>                                   nua_event_name (event), status, phrase);
>                   break;
>   }
> }
>
> static void
> stream_relay_live ()
> {
>       char str[128];
>
>       memset(str, 0, sizeof(str));
>       sprintf(str, "sip:re...@%s:%s", "127.0.0.1", "7018");
>
>       g_print ("[DEBUG] Sending 'INVITE' to %s\n ", str);
>       handle = nua_handle (nua,
>                         NULL,
>                         SIPTAG_USER_AGENT_STR("Test Program 0.99"),
>                         SIPTAG_TO_STR (str),
>                         TAG_END()
>         );
>
>       if (handle == NULL) {
>                     printf ("Can't create operation handle, quitting..\n");
>                     exit(1);
>       }
>
>         nua_invite (handle,
>                         SIPTAG_CONTENT_TYPE_STR("application/sdp"), // must
> be present
>                         SIPTAG_PAYLOAD_STR( // must be present
>                                 "v=0\r\n" // protocol version
>                                 //<username> <session id> <version>
> <network type> <address type> <address>
>                                 "o=SMF 2280 22800 IN IP4 10.147.65.83\r\n"
> // creator and session identifier
>                                 "s=SMF stream from webcam in H.263 and
> MPEG2 video\r\n" // session name
>                                 "t=0 0\r\n" // start and stop times
> //                              "c=IN IP4 239.255.255.201\r\n" //
> originator IP address
>                                 "c=IN IP4 127.0.0.1\r\n" // originator IP
> address
>                                 "a=sendonly\r\n" // defined by c-mobile
>                                 "a=crid:koe20090320_westermann.ts\r\n" //
> content ID
>                                 "m=video 1236 RTP/AVP 33\r\n" // MPEGTS
>                                 "a=rtpmap:33 MP2T/90000\r\n"
>                                 ),
>                         TAG_END()
>                    );
> }
>
> static void
> send_bye ()
> {
>   g_print ("send_bye: handle: %p\n", handle);
>   nua_handle_destroy (handle);
>   //nua_bye (handle, TAG_END() );
>
> }
>
>
> /* Parse GUI command */
> void
> parse_command (gchar *buf)
> {
>   if (!strcmp (buf, "INVITE\n")) {
>     g_print ("Creating new INVITE handle\n");
>     stream_relay_live ();
>     return;
>   }
>
>   if (!strcmp (buf, "BYE\n")) {
>     g_print ("Sending BYE\n");
>     send_bye ();
>     return;
>   }
>
>   g_print ("unknown command !\n");
>   return;
> }
>
> #define BUFSIZE 64
>
> gboolean
> io_callback(GIOChannel *ioch, GIOCondition cond, gpointer data)
> {
>   GIOStatus ret;
>   gsize bytes_read;
>   gchar *buf;
>
>   GError *err = NULL;
>
>   g_print ("io_callback. handle: %p\n", handle);
>
>   if (cond & G_IO_ERR) {
>     g_print ("GUI socket connection error\n");
>     exit(EXIT_FAILURE);
>   }
>
>   ret = g_io_channel_read_line (ioch, &buf, &bytes_read, NULL, &err);
>   if (ret == G_IO_STATUS_ERROR)
>     g_error ("error reading: %s\n", err->message);
>
>   if (bytes_read) {
>     g_print ("[DEBUG] received gui command: %s\n", buf);
>     parse_command (buf);
>     g_free (buf);
>   }
>
>   g_print ("leaving io_callback\n");
>
>   return TRUE;
> }
>
> void init_listening_socket (void)
> {
>   int sock = 0;
>   GIOChannel *gui_read;
>
>   struct sockaddr_in sa;
>
>   memset(&sa, 0, sizeof(sa));
>   sa.sin_family = AF_INET;
>   sa.sin_addr.s_addr = INADDR_ANY;
>   sa.sin_port = htons(GUI_SENDPORT);
>
>   sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
>
>   if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(struct sockaddr)))
>   {
>     perror("error bind failed");
>     close(sock);
>     exit(EXIT_FAILURE);
>   }
>
>  // create IOChannel
>   gui_read =  g_io_channel_unix_new (sock);
>   if (!g_io_add_watch (gui_read, G_IO_IN | G_IO_ERR, io_callback, NULL))
>     g_error ("Cannot add watch on GIOChannel!\n");
>
>   g_print ("[DEBUG] Listening socket ready...\n");
>
>   return;
> }
>
> int
> main (int argc, char *argv[])
> {
>   GMainLoop *ptr = g_main_loop_new(NULL, FALSE);
>   GSource *gsource;
>   su_root_t *sofia_event_loop;
>   su_timer_t *timer;
>
>   /* create a sofia event loop using su-glib function
> su_glib_root_source_create() */
>   sofia_event_loop = su_glib_root_create(NULL);
>
>   /* attach the created GSource to glib event loop */
>   gsource = su_glib_root_gsource(sofia_event_loop);
>   g_source_attach(gsource, g_main_loop_get_context(ptr));
>
>   /* use the sofia event loop with libsofia-sip-ua modules */
>   timer = su_timer_create(su_root_task(sofia_event_loop), 200L);
>
>   local_port = SMF_LISTEN;
>   printf ("ConVeHo application listening on %d\n", local_port);
>   /* Create a user agent instance. Caller and callee should bind to
> different
>    * address to avoid conflicts. The stack will call the 'event_callback()'
>    * callback when events such as succesful registration to network,
>    * an incoming call, etc, occur.
>    */
>   nua = nua_create(sofia_event_loop, /* Event loop */
>                    event_callback, /* Callback for processing events */
>                    NULL, /* Additional data to pass to callback */
>                    NUTAG_URL("sip:0.0.0.0:" SMF_LISTEN_S), /* Address to
> bind to IPv4 */
> //                   NUTAG_URL("sip:[::]:5060"), /* Address to bind to IPv6
> */
>                    NUTAG_MEDIA_ENABLE(0), /* disable built-in SDP
> offer-answer model */
>                    NUTAG_AUTOACK(0), /* no automatic ACK send */
>                    TAG_END()); /* Last tag should always finish the
> sequence */
>
>   /* open second control socket and bind it to g_main_loop */
>   init_listening_socket ();
>
>   /* Run event loop */
>   printf ("[DEBUG] Entering main loop\n");
>   /* run the glib mainloop */
>   g_main_loop_run(ptr);
>
>   /* Destroy allocated resources */
>   nua_destroy (nua);
>   su_root_destroy (sofia_event_loop);
> //  su_deinit ();
>
>   return 0;
> }
>
>
> ************
>
> Best regards,
>
> Jordi
>
------------------------------------------------------------------------------
Crystal Reports &#45; New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty&#45;free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Sofia-sip-devel mailing list
Sofia-sip-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel

Reply via email to