linphone-developers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Linphone-developers] segmentation faults


From: Sagaert Johan
Subject: [Linphone-developers] segmentation faults
Date: Fri, 10 Apr 2015 13:51:34 +0200

 
Hi

I am using the latest git pulls,
My application is using libwebsockets to communicate with a (local)webpage 
acting as a user interface on an embedded linux
Device...
I just started using liblinphone and I get randow segfaults.
80% of calls work fine(I have bidirectional audio communication and the ringing 
sound also works) but for the rest it gives
segfaults, and as I noticed
It seems to be when something changes in the SIP stack state.(when I 
hangup,accept,or initiate the call )

Tracking them down to the belle sip lib:
 
static void belle_sip_object_loose_weak_refs(belle_sip_object_t *obj){
        weak_ref_t *ref,*next;
        for(ref=obj->weak_refs;ref!=NULL;ref=next){
                next=ref->next;              // <<---------------
                ref->notify(ref->userpointer,obj);
                belle_sip_free(ref);
        }
        obj->weak_refs=NULL;
}


--------------------------------------------------------------------------------------------------------------------
When using strace :

send(14, "\201\37{\"callstatus\":{\"state\":\"idle\"}"..., 33, 0) = 33
gettimeofday({1428666009, 938930}, NULL) = 0
send(15, "\201\37{\"callstatus\":{\"state\":\"idle\"}"..., 33, 0) = 33
nanosleep({0, 5000000}, 0x7ee07b6c)     = 0
gettimeofday({1428666009, 944555}, NULL) = 0
clock_gettime(CLOCK_MONOTONIC, {4139, 933197718}) = 0
clock_gettime(CLOCK_MONOTONIC, {4139, 933359762}) = 0
poll([{fd=9, events=POLLIN}, {fd=10, events=POLLIN}, {fd=11, events=POLLIN}], 
3, 0) = 1 ([{fd=9, revents=POLLIN}])
clock_gettime(CLOCK_MONOTONIC, {4139, 933761902}) = 0
recvfrom(9, "SIP/2.0 487 Request Terminated\r\n"..., 4096, MSG_PEEK, 
{sa_family=AF_INET, sin_port=htons(5060), sin_addr=inet_addr("1
92.168.1.199")}, [16]) = 506
clock_gettime(CLOCK_MONOTONIC, {4139, 934461219}) = 0
clock_gettime(CLOCK_MONOTONIC, {4139, 934602610}) = 0
recvfrom(9, "SIP/2.0 487 Request Terminated\r\n"..., 65534, 0, 
{sa_family=AF_INET, sin_port=htons(5060), sin_addr=inet_addr("192.168
.1.199")}, [16]) = 506
clock_gettime(CLOCK_MONOTONIC, {4139, 941199380}) = 0
sendto(9, "ACK sip:address@hidden SIP/2."..., 367, 0, {sa_family=AF_INET, 
sin_port=htons(5060), sin_addr=inet_addr("192.168.1.199
")}, 16) = 367
clock_gettime(CLOCK_MONOTONIC, {4139, 941736911}) = 0
clock_gettime(CLOCK_MONOTONIC, {4139, 941983810}) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xffffffff} ---
+++ killed by SIGSEGV +++
Segmentation fault
#

----------------------------



This is my current source :

/*
 * main.c
 *
 *  Created on: March 23, 2015
 *      Author: Sagaert Johan
 */


/*
 This program is a very simple usage example of liblinphone. Desmonstrating how 
to initiate a SIP registration from a sip uri
identity passed from the command line. first argument must be like 
sip:address@hidden , second must be password .
 ex registration sip:address@hidden secret
 Registration is cleared on SIGINT

 Copyright (C) 2010 Belledonne Communications SARL
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 This program 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 General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

//#define VER36
#define DEBUG


#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

#include "linphone/linphonecore.h"
#include <signal.h>


#include <syslog.h>
#include "libwebsockets.h"

#include <json-c/json.h>

/*
 * Linphone core object
 */
LinphoneCore *lc;


/*****************************************************************
 * global websocket object
 */
struct lws_context_creation_info info;
struct libwebsocket_context *context;
int start_websocket_service(int port);
void handle_websocket_service(void);
/****************************************************************/

char jsondata[256];
struct libwebsocket_protocols protocols[];


LinphoneCall *incomingcall;

int getjsondata(char * string );
void announce_incomingcall(char * from);
void announce_ring_terminated(void);
void announce_streaming(void);
void announce_remotering(char * to);

static bool_t running = TRUE;

static void stop(int signum)
{
        running = FALSE;
}

static void global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, 
const char *message)
{
        printf("\nglobalStateChanged %s [%i] \n",message,gstate);
}

static void buddy_info_updated(struct _LinphoneCore *lc, LinphoneFriend *lf)
{
        printf("\nbuddy_info_updated \n");
}


/*
 * messge received
 */
static void messageReceived(LinphoneCore *lc, LinphoneChatRoom *room, 
LinphoneChatMessage *message)
{
        printf("\nMessge Received 
[%s]\n",linphone_chat_message_get_text(message));
}

void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const 
LinphoneAddress *from, const char *message)
{
        printf(" Message [%s] received from [%s] 
\n",message,linphone_address_as_string (from));
}
/*
 * Dtmf received
 */
static void dtmf_received(struct _LinphoneCore* lc, LinphoneCall *call, int 
dtmf)
{
        printf("\nDTMF Received [%i]\n",dtmf);
}

static void registration_state_changed(struct _LinphoneCore *lc,
                LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate,     
const char *message)
{
        printf("\nRegistration state : %s for user id [%s] at proxy [%s]\n",
                        linphone_registration_state_to_string(cstate),
                        linphone_proxy_config_get_identity(cfg),
                        linphone_proxy_config_get_addr(cfg));
}

int con=0;

static void call_state_changed (struct _LinphoneCore *lc,
                LinphoneCall *call,LinphoneCallState cstate,const char *message)
{
        //printf("\n call_state_changed : %s call [%s]  message: [%s]\n",
        ////                    linphone_call_state_to_string(cstate)
        //                      
,linphone_call_get_remote_address_as_string(call)
        //                      ,message);


        switch (cstate)
        {
        case LinphoneCallOutgoingProgress:
                printf("LinphoneCallOutgoingProgress !\n");
                break;
        case LinphoneCallOutgoingRinging:
                printf("It is now ringing remotely !\n");
                incomingcall=call;
                {
                        LinphoneAddress *u;
                        u=linphone_call_get_remote_address(call);
                        printf("calling %s 
!\n",linphone_address_get_username(u));
                        announce_remotering(linphone_address_get_username(u));
                }
                break;
        case LinphoneCallOutgoingEarlyMedia:
                printf("Receiving some early media\n");
                break;
        case LinphoneCallConnected:
                printf("LinphoneCallConnected !\n");
                break;
        case LinphoneCallStreamsRunning:
                printf("LinphoneCallStreamsRunning !\n");
                announce_streaming();
                break;
        case LinphoneCallEnd:
                printf("CLinphoneCallEnd !\n");
                announce_ring_terminated();
                break;
        case LinphoneCallError:
                printf("LinphoneCallError !");
                break;
        case LinphoneCallIdle:                                  /**<Initial 
call state */
                printf("LinphoneCallIdle !\n");
                break;
        case LinphoneCallIncomingReceived:
                printf("LinphoneCallIncomingReceived !\n");
                {
                        LinphoneAddress *u;
                        u=linphone_call_get_remote_address(call);
                        //printf("LinphoneCallIncomingReceived  from 
[%s]!\n",linphone_address_get_display_name (u));
                        printf("LinphoneCallIncomingReceived  from 
[%s]!\n",linphone_address_get_username(u));
                        incomingcall=call;
                        announce_incomingcall(linphone_address_get_username(u));
                }




                //incomingcall=linphone_address_clone  ( call );

                //printf("gebeld door 
[%s]\n",linphone_call_get_remote_address_as_string(incomingcall));
                //printf("gebeld door [%s]\n", 
linphone_address_get_display_name (call));
                //printf("gebeld door [%s]\n",linphone_address_get_username 
(call));
                //printf("gebeld door [%s]\n", linphone_call_get_remote_contact 
(call));

                //linphone_call_get_remote_address_as_string
                break;
        case LinphoneCallReleased:
                printf("LinphoneCallReleased !\n");
                incomingcall=NULL;
                break;
        case LinphoneCallOutgoingInit:
                printf("LinphoneCallOutgoingInit !\n");
                break;
        default:
                printf("Unhandled notification %i\n", cstate);
        }
}

LinphoneChatRoom* chat_room;

void cleanupchat(void)
{
        if(chat_room)
        {
                linphone_chat_room_destroy(chat_room);
        }
}

void createchat(void)
{
        //char* dest_friend="sip:address@hidden"; //NOK
        //char* dest_friend="203"; //NOK
        char* dest_friend="sip:address@hidden"; //OK !
        /*Next step is to create a chat root*/

#ifdef VER36
        chat_room = linphone_core_create_chat_room(lc,dest_friend);
#else
        chat_room =linphone_core_get_chat_room_from_uri (lc,dest_friend);
#endif
        linphone_chat_room_send_message(chat_room,"Hello world"); /*sending 
message*/
}

//#define DEBUG

void config_audio(float mic,float speaker)
{
        printf("current micro gain %f\n",linphone_core_get_mic_gain_db(lc));
        linphone_core_set_mic_gain_db(lc,mic);
        linphone_core_set_playback_gain_db (lc, speaker);

        linphone_core_set_play_level(lc,0);//?? werkt niet : 
linphone_core_set_playback_gain_db gebruiken !!

        linphone_core_set_ring_level(lc,100); //0...100

        //linphone_core_set_ring(lc,"/usr/share/sounds/linphone/ringback.wav");
        
linphone_core_set_ring(lc,"/usr/share/sounds/linphone/rings/oldphone.wav");
        
//linphone_core_set_ring(lc,"/usr/share/sounds/linphone/rings/sweet.wav");

        //linphone_core_enable_echo_limiter (LinphoneCore *lc, bool_t val);
        //linphone_core_enable_mic (LinphoneCore *lc, bool_t enable);
        //linphone_call_enable_echo_limiter (LinphoneCall *call, bool_t val);
        //linphone_core_enable_echo_cancellation (LinphoneCore *lc, bool_t val);


}

int main(int argc, char *argv[])
{
        LinphoneCoreVTable vtable = { 0 };
        LinphoneProxyConfig* proxy_cfg;
        LinphoneAddress *from;
        LinphoneAuthInfo *info;

        LinphoneCall *call = NULL;

        int i=0;

        char* identity = "sip:address@hidden";
        char* password = "123456";
        const char* server_addr="192.168.1.199";

        chat_room=NULL;

        signal(SIGINT, stop);
#ifdef DEBUG
        linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif

        // start the Websocket Server
        start_websocket_service(7654);

        /*
         Fill the LinphoneCoreVTable with application callbacks.
         All are optional. Here we only use the registration_state_changed 
callbacks
         in order to get notifications about the progress of the registration.
         */
        vtable.global_state_changed=global_state_changed;
        vtable.registration_state_changed = registration_state_changed;
        vtable.call_state_changed = call_state_changed;
        vtable.dtmf_received=dtmf_received;
        vtable.message_received=messageReceived;
        //vtable.text_received=text_received;
        //vtable.buddy_info_updated=buddy_info_updated;

        //vtable.notify_recv =notifyReceived;
        //vtable.notify_presence_recv=notify_presence_recv;



        /*
         Instanciate a LinphoneCore object given the LinphoneCoreVTable
         */
        //lc = linphone_core_new(&vtable, "/home/linphone", NULL, NULL);
        lc = linphone_core_new(&vtable, NULL, NULL, NULL);


        /*create proxy config*/
        proxy_cfg = linphone_proxy_config_new();

        /*parse identity*/
        from = linphone_address_new(identity);
        if (from == NULL)
        {
                printf( "%s not a valid sip uri, must be like 
sip:address@hidden \n",identity);
                goto end;
        }

        if (password != NULL)
        {
                /* create authentication structure from identity*/
                printf("Gets the username %s -> 
%s\n","from",linphone_address_get_username(from));
#ifdef VER36
                info = 
linphone_auth_info_new(linphone_address_get_username(from), NULL,password, 
NULL, NULL);
#else
                info = 
linphone_auth_info_new(linphone_address_get_username(from), NULL,password, 
NULL, NULL,NULL);
#endif
                /* add authentication info to LinphoneCore*/
                linphone_core_add_auth_info(lc, info);
        }

        // configure proxy entries
        /* set identity with user name and domain*/
        linphone_proxy_config_set_identity(proxy_cfg, identity);

        /* extract domain address from identity*/
        server_addr = linphone_address_get_domain(from);

        /* we assume domain = proxy server address*/
        linphone_proxy_config_set_server_addr(proxy_cfg, server_addr);

        /* activate registration for this proxy config*/
        linphone_proxy_config_enable_register(proxy_cfg, TRUE);

        /* release resource*/
        linphone_address_destroy(from);

        /* add proxy config to linphone core*/
        linphone_core_add_proxy_config(lc, proxy_cfg);

        /* set to default proxy*/
        linphone_core_set_default_proxy(lc, proxy_cfg);

        linphone_core_set_log_level(0);
        //ortp_set_log_level_mask(0);


        config_audio(-4,0);

        //linphone_core_set_use_rfc2833_for_dtmf(lc,'0');
        //linphone_core_set_use_info_for_dtmf(lc,'0');




        /* main loop for receiving notifications and doing background 
linphonecore work: */
        while (running)
        {
                //char dest[]="sip:address@hidden";
                char dest[]="203"; //OK

                /* first iterate initiates registration */
                linphone_core_iterate(lc);

                handle_websocket_service();

                //printf("sleep... \n");
                //ms_usleep(50000);
                ms_usleep(5000);



                if(i==-50)
                {
                        createchat();
                        printf("sent chat message\n");
                }

                if(i==-100)
                {
                        if (dest)
                        {
                                /*Place an outgoing call  */
                                call = linphone_core_invite(lc, dest);
                                if (call==NULL)
                                {
                                        printf("Could not place call to 
%s\n",dest);
                                        goto end;
                                }
                                else
                                        printf("Call to %s is in progress...", 
dest);
                                linphone_call_ref(call);
                        }
                }
                if(i==-2000)
                {
                        if (call!=NULL)
                        {
                                linphone_core_terminate_call(lc, call);
                                printf("oproep beindigd\n");
                        }
                }

                i++;
                //printf("i=%i\n",i);
        }

        // if there is a call busy, then terminate it
        if (call && linphone_call_get_state(call) != LinphoneCallEnd)
        {
                /* terminate the call */
                printf("Terminating the call...\n");
                linphone_core_terminate_call(lc, call);

                /*at this stage we don't need the call object */
                linphone_call_unref(call);
        }

        /* get default proxy config*/
        linphone_core_get_default_proxy(lc, &proxy_cfg);

        /* start editing proxy configuration*/
        linphone_proxy_config_edit(proxy_cfg);

        /* de-activate registration for this proxy config*/
        linphone_proxy_config_enable_register(proxy_cfg, FALSE);

        /* initiate REGISTER with expire = 0*/
        linphone_proxy_config_done(proxy_cfg);
        while (linphone_proxy_config_get_state(proxy_cfg) != 
LinphoneRegistrationCleared)
        {
                /* to make sure we receive call backs before shutting down*/
                linphone_core_iterate(lc);
                ms_usleep(50000);
        }



end:
        printf("Shutting down...\n");
        cleanupchat();
        linphone_core_destroy(lc);
        printf("Exited\n");
        return 0;
}


/*********************************************************
 *
 **********************************************************/
enum libwebsocket_callback_reasons oldreason;

#define WEBSOCKET_PORT 7654
#define MAX_ECHO_PAYLOAD 1400

struct per_session_data__echo
{
        unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD
                        + LWS_SEND_BUFFER_POST_PADDING];
        unsigned int len;
        //html5ws_clients_linkedlist_t *premote_client;
//time_t        connectionstarttime;
//unsigned int index;
};

static int callback_echo(struct libwebsocket_context *context,
                struct libwebsocket *wsi, enum libwebsocket_callback_reasons 
reason,
                void *user, void *in, size_t len)
{
        struct per_session_data__echo *per_sessie_data =(struct 
per_session_data__echo *) user;
        int n;

        switch (reason)
        {
        case LWS_CALLBACK_CLOSED:
                //printf("connection closed ---------------- 
%s\n",per_sessie_data->premote_client->ip);
                printf("connection closed ---------------- \n");

                //remove_remote(per_sessie_data->premote_client);
                //pwsi=NULL;
                break;

        case LWS_CALLBACK_ESTABLISHED:
                printf("connection established++++++++++++\n");
                //pwsi=wsi;

                {
                        char tb[64] = "";
                        char tb2[64];
                        
//libwebsockets_get_peer_addresses(context,wsi,libwebsocket_get_socket_fd(wsi),tb,0,tb2,64);
                        libwebsockets_get_peer_addresses(context, 
wsi,libwebsocket_get_socket_fd(wsi), tb, 32, tb2, 64);
                        printf("remote peer=[%s]\n", tb2);
                        //per_sessie_data->premote_client=addremote(tb2);
                        //printf("connection created ---------------- 
%s\n",per_sessie_data->premote_client->ip);
                }
                break;

                /* when the callback is used for server operations --> */
        case LWS_CALLBACK_SERVER_WRITEABLE:

                //n = libwebsocket_write(wsi, 
&per_sessie_data->buf[LWS_SEND_BUFFER_PRE_PADDING],per_sessie_data->len,
LWS_WRITE_TEXT);

                n = libwebsocket_write(wsi, &jsondata,strlen(jsondata), 
LWS_WRITE_TEXT);

                n=0;

                //only sent to authenticated clients
                //only sent to clients  if it was requested
                //if(per_sessie_data->premote_client->requestsentdata)
                //{
                        //n = libwebsocket_write(wsi, (unsigned char *) 
jsondata,       strlen((char*) jsondata), LWS_WRITE_TEXT);
                //      n = libwebsocket_write(wsi, (unsigned char *) 
per_sessie_data->premote_client->datatosent,
                //                      
per_sessie_data->premote_client->datalen, LWS_WRITE_TEXT);
                //      per_sessie_data->premote_client->requestsentdata=0; // 
reset request
#if DEBUGLEVEL > 5
                        printf("wrote %i 
(%i)\n",per_sessie_data->premote_client->datalen,n);
#endif
        //      }

                //n = libwebsocket_write(wsi,testtxt2,strlen((char*)testtxt2), 
LWS_WRITE_TEXT);

                
//libwebsockets_serve_http_file(context,wsi,"/test.jpg","image/jpeg","");

                //lws_b64_encode_string()
                //printf("writable ---------------- %s
auth=%i\n",per_sessie_data->premote_client->ip,per_sessie_data->premote_client->authenicated);
#if DEBUGLEVEL > 5
                printf("writable websocket ---------------- 
%s\n",per_sessie_data->premote_client->ip);
#endif

                if (n < 0)
                {
                        lwsl_err("ERROR %d writing to socket, hanging up\n", n);
                        return 1;
                }
                //if (n < (int) per_sessie_data->len)
                //{
                        //lwsl_err("Partial write\n");
                        //return -1;
                //}
#if DEBUGLEVEL > 5
                if (in)
                        printf("LWS_CALLBACK_SERVER_WRITEABLE data ontvangen : 
[%s] %i %p  per sessie ptr%p\n\r",
                                        (char*) in, n, wsi, per_sessie_data);
#endif
                break;

        case LWS_CALLBACK_RECEIVE:
                if (len > MAX_ECHO_PAYLOAD)
                {
                        lwsl_err("Server received packet bigger than %u, 
hanging up\n",MAX_ECHO_PAYLOAD);
                        return 1;
                }
                //if(per_sessie_data->premote_client)
                //      per_sessie_data->premote_client->authenicated=1;

                //memcpy(&per_sessie_data->buf[LWS_SEND_BUFFER_PRE_PADDING], 
in, len);
                //per_sessie_data->len = (unsigned int) len;

                //libwebsocket_callback_on_writable(context, wsi);
                printf("LWS_CALLBACK_RECEIVE %i bytes data ontvangen : [%s] 
\n\r",len,(char*)in);

                //printf("received from websocket ---------------- %s
auth=%i\n",per_sessie_data->premote_client->ip,per_sessie_data->premote_client->authenicated);

#if DEBUGLEVEL > 5
                printf("received from websocket ---------------- %s 
\n",per_sessie_data->premote_client->ip);
#endif


                getjsondata(in);

                //only receive from authenticated clients
                //if(per_sessie_data->premote_client->authenicated)
                        // TODO data verwerken
                //      return process_received_webclient_data(in, 
len,per_sessie_data->premote_client);
                //else
                        return 0;
                break;

        case LWS_CALLBACK_FILTER_NETWORK_CONNECTION://16  this is the place to 
check the blacklist
                break;
        case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:           //19
                {
                char buf[256];

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_GET_URI);
                printf("WSI_TOKEN_GET_URI[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_ORIGIN);
                printf("WSI_TOKEN_ORIGIN[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_DRAFT);
                printf("WSI_TOKEN_DRAFT[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_KEY);
                printf("WSI_TOKEN_KEY[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_CONNECTION);
                printf("WSI_TOKEN_CONNECTION[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_HOST);
                printf("WSI_TOKEN_HOST[%s]\n", buf);

                lws_hdr_copy(wsi, buf, sizeof buf, WSI_TOKEN_PROTOCOL);
                printf("WSI_TOKEN_PROTOCOL[%s]\n", buf);
                }
                break;
        case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED:
        case LWS_CALLBACK_WSI_CREATE:   //28
        case LWS_CALLBACK_WSI_DESTROY:  //29
        case LWS_CALLBACK_GET_THREAD_ID:  //30
        case LWS_CALLBACK_ADD_POLL_FD:
        case LWS_CALLBACK_DEL_POLL_FD:
        case LWS_CALLBACK_CHANGE_MODE_POLL_FD: //33
        case LWS_CALLBACK_LOCK_POLL:
        case LWS_CALLBACK_UNLOCK_POLL:
                break;

        default:
                //printf("undefined data ontvangen :\n\r");
                if (reason != oldreason)
                {
                        printf("reason: %i\n\r", reason);
                        oldreason = reason;
                }
                break;
        }

        return 0;
}

struct libwebsocket_protocols protocols[] =
{
        /* first protocol must always be HTTP handler */
        {
                "sipcomm", /* name */
                callback_echo, /* callback */
                sizeof(struct per_session_data__echo), /* per_session_data_size 
*/
                0, /* max frame size / rx buffer */
                0 /* no_buffer_all_partial_tx leave 0*/
        },
        { NULL, NULL, 0, 0 } /* terminator */
};

int start_websocket_service(int port)
{
        int opts = 0;
        const char *interface = NULL;
        int debug_level = 7;


        int syslog_options = LOG_PID | LOG_PERROR;
        /*
         * Clear the structure
         */
        memset(&info, 0, sizeof info);

        /*
         * normally lock path would be /var/lock/lwsts or similar, to
         * simplify getting started without having to take care about
         * permissions or running as root, set to /tmp/.lwsts-lock
         */

        /* we will only try to log things according to our debug_level */
        setlogmask(LOG_UPTO(LOG_DEBUG));
        openlog("lwsts", syslog_options, LOG_DAEMON);

        /* tell the library what debug level to emit and to send it to syslog */
        lws_set_log_level(debug_level, lwsl_emit_syslog);

        info.port = port;
        info.iface = interface;
        info.protocols = protocols;
        info.extensions = libwebsocket_get_internal_extensions();

        info.gid = -1;
        info.uid = -1;
        info.options = opts;

        //html5websocket_clients=NULL;

        // create the libwebsocket contect object.
        context = libwebsocket_create_context(&info);
        if (context == NULL)
        {
                lwsl_err("libwebsocket init failed\n");
                return -1;
        }

        printf("Websocket server started at port %i for protocol 
%s\n",port,protocols[0].name);

        return 0;
}

void handle_websocket_service(void)
{
        int n;
        n = libwebsocket_service(context, 10);
        if (n!=0)
                printf("wat gebeurd er met %i\n",n);
}


int getjsondata(char * string )
{
        int result=0;
        int i;
        json_object * jobj = json_tokener_parse(string);

        char buffer[256];

        enum json_type type = json_object_get_type(jobj);

        if (type==json_type_object)
        {
                struct json_object* newjsonobj;

                newjsonobj=json_object_object_get(jobj,"door");
                if (newjsonobj!=NULL)
                {
                        strcpy(buffer,json_object_get_string(newjsonobj));
                        json_object_put(newjsonobj);
                        printf("--->>door : [%s]\n", buffer);
                        result=1;

                        if (strcmp(buffer,"open")==0)
                        {
                                printf("Open the door \n");
                        }
                }


                newjsonobj=json_object_object_get(jobj,"dial");
                if (newjsonobj!=NULL)
                {
                        strcpy(buffer,json_object_get_string(newjsonobj));
                        json_object_put(newjsonobj);
                        printf("--->>dial : [%s]\n", buffer);
                        result=1;
                        if (strlen(buffer)>0)  // minimum nummer lengte 1 digit
                        {
                                LinphoneCall *call;
                                /*Place an outgoing call  */
                                call = linphone_core_invite(lc, buffer);
                                if (call==NULL)
                                        printf("Could not place call to 
%s\n",buffer);
                                else
                                        printf("Call to %s is in progress...", 
buffer);
                                linphone_call_ref(call);
                        }
                }


                newjsonobj=json_object_object_get(jobj,"dtmf");
                if (newjsonobj!=NULL)
                {
                        strcpy(buffer,json_object_get_string(newjsonobj));
                        json_object_put(newjsonobj);
                        printf("--->>dtmf : [%s]\n", buffer);

                        linphone_call_send_dtmf(incomingcall,buffer[0]);

                        //linphone_call_send_dtmf(incomingcall,buffer[0]);

                        //linphone_call_send_dtmf(incomingcall,'0');
                        result=1;
                }


                newjsonobj=json_object_object_get(jobj,"call");
                if (newjsonobj!=NULL)
                {
                        //copy
                        strcpy(buffer,json_object_get_string(newjsonobj));
                        json_object_put(newjsonobj);

                        if (strcmp(buffer,"accept")==0)
                        {
                                if(incomingcall!=NULL)
                                        
linphone_core_accept_call(lc,incomingcall);
                        }
                        else if  (strcmp(buffer,"reject")==0)
                        {
                                if(incomingcall!=NULL)
                                        
linphone_core_decline_call(lc,incomingcall,LinphoneReasonDeclined);
                        }
                        else if  (strcmp(buffer,"hangup")==0)
                        {
                                if(incomingcall!=NULL)
                                        linphone_core_terminate_call(lc, 
incomingcall);
                        }
                        else if  (strcmp(buffer,"cancel")==0)
                        {
                                if(incomingcall!=NULL)
                                        linphone_core_terminate_call(lc, 
incomingcall);
                        }



                        printf("--->>call : [%s]\n", buffer);
                        result=1;
                }
        }
        else
                printf("WAS NOT JSON DATA [%s]\n",string);

        // free
        if(jobj)
                json_object_put(jobj);

        return result;
}

void announce_incomingcall(char * from)
{
        sprintf(jsondata, 
"{\"callstatus\":{\"state\":\"%s\",\"CID\":\"%s\"}}","ring",from);
        libwebsocket_callback_on_writable_all_protocol(&protocols[0]);
}

void announce_ring_terminated(void)
{
        sprintf(jsondata, "{\"callstatus\":{\"state\":\"%s\"}}","idle");
        libwebsocket_callback_on_writable_all_protocol(&protocols[0]);
}

void announce_streaming(void)
{
        sprintf(jsondata, "{\"callstatus\":{\"state\":\"%s\"}}","stream");
        libwebsocket_callback_on_writable_all_protocol(&protocols[0]);
}

void announce_remotering(char * to)
{
        sprintf(jsondata, 
"{\"callstatus\":{\"state\":\"%s\",\"CID\":\"%s\"}}","remotering",to);
        libwebsocket_callback_on_writable_all_protocol(&protocols[0]);
}


Any idea ?
Is there something with ref counting objects ?


Sagaert Johan






reply via email to

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