linphone-developers
[Top][All Lists]
Advanced

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

Re: [Linphone-developers] Linphone program on Raspberry Pi using C++


From: David Desopper
Subject: Re: [Linphone-developers] Linphone program on Raspberry Pi using C++
Date: Wed, 23 Jul 2014 16:12:39 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0

First of all, thanks for your reply.

As I wrote, I wasn't able to compile directly on my Pi. The instructions I found aren't detailed enough or just simply don't work. I don't suppose you have a detailed description of the steps you followed?

Greetings

On 2014-07-23 14:04, Sylvain Berfini wrote:
Hi David,

Why don't you compile directly the latest linphone (and it's dependencies like belle-sip, ortp and mediastreamer) directly on your PI ? We've done it some time ago it works well.

Cheers.

---
Sylvain Berfini
Software Engineer @ Belledonne Communications

Le 2014-07-23 13:53, David Desopper a écrit :
Hi,

I'm for my master thesis I'm developing an application that runs on the
Raspberry Pi. I altered a program written by my mentor that worked
almost perfectly. He used a .linphonerc file to read all his data, but I
needed to use a database where the information for my friends and users
are stored. But when I altered everything, something went horribly
wrong. I can subscribe, I can see the status of my friends and appear
online for my friends. But when I place a call or when someone calls me,
the linphone_core_itterate() function block's somewhere. This doesn't
crash my program because I call the function in a thread, but I ofcourse
need the thread for further execution. I have no idea what I'm doing
wrong because everything is more or less the same as when the program
functioned.

I'm using liblinphone4 because that's what you can install on wheezy
with apt-get install. So that's why you will see me use depricated
functions. I tried cross compiling a newer version of linphone, but
because I'm pretty much a linux and cross-compiling newbie, I find it
very difficult and keep hitting a wall.

More info:
- Cross compiling using Ubuntu
- Running on Raspberry Pi (armV6) using Wheezy

Any help would be greatly appreciated.

Here is the source code that is giving me the headache, the
internalthread method is causing the problem:

#include "SipImplemantation.h"
#include "ConfigManager.h"
#include "LinphoneUser.h"
#include "Contacts.h"
#include "hiberlite/hiberlite.h"

SipImplemantation * impl = NULL;
Actions actions = {};

/*declarations for linphone vtable*/
static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall
*call, LinphoneCallState st, const char *msg)
{
    std::cout << "Callback linephonec_call_state_changed" << std::endl;

    char * from =
linphone_address_as_string_uri_only(linphone_call_get_remote_address(call));

    std::cout << " Call state changed, source: " << from << std::endl;

    switch(st)
    {
    case LinphoneCallIncomingReceived:
        impl->incomingcall(std::string(from));
        break;
    case LinphoneCallOutgoingRinging:
        std::cout << "It is now ringing remotely !" << std::endl;
        break;
    case LinphoneCallConnected:
        std::cout << "We are connected !" << std::endl;
        break;
    case LinphoneCallEnd:
        std::cout << "Call is terminated." << std::endl;
        break;
    case LinphoneCallError:
        std::cout << "Call failure !" << std::endl;
        break;
    default:
        std::cout << "Unhandled notification " << msg << std::endl;
        break;
    }

    ms_free(from);
}

static void linphonec_prompt_for_auth(LinphoneCore *lc, const char
*realm, const char *username)
{
    std::cout << "prompt for auth: " << realm << ", " << username <<
std::endl;
}

static void linphonec_display_refer (LinphoneCore * lc, const char
*refer_to)
{
    std::cout << "display refer: " << refer_to << std::endl;
}

static void linphonec_display_something (LinphoneCore * lc, const char
*something)
{
    std::cout << "display something: " << something << std::endl;
}

static void linphonec_display_url (LinphoneCore * lc, const char
*something, const char *url)
{
std::cout << "display url: " << something << ", " << url << std::endl;
}

static void linphonec_display_warning (LinphoneCore * lc, const char
*something)
{
    std::cout << "display warning: " << something << std::endl;
}

static void linphonec_notify_presence_received(LinphoneCore
*lc,LinphoneFriend *fid)
{
    std::cout << "Callback linphonec_notify_presence_received" <<
std::endl;

    const LinphoneAddress* friendAddress =
linphone_friend_get_address(fid);

bool online = linphone_friend_get_status(fid) != LinphoneStatusOffline;
    std::string friendUsername
(linphone_address_get_username(friendAddress));
    impl->friendstatus(friendUsername, online);

    std::cout << "New state: " <<
linphone_online_status_to_string(linphone_friend_get_status(fid)) << "
for user id " << friendUsername << std::endl;

}

static void linphonec_new_unknown_subscriber(LinphoneCore *lc,
                LinphoneFriend *lf, const char *url)

{
    std::cout << "new unknown subscriber: " << url << std::endl;
const LinphoneAddress* friendAddress = linphone_friend_get_address(lf);
    std::cout << linphone_address_as_string (friendAddress) << " wants
to see your status, accepting " << std::endl;
    linphone_friend_edit(lf); /* start editing friend */
linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPAccept); /*
Accept incoming subscription request for this friend*/
    linphone_friend_done(lf); /*commit change*/
    linphone_core_add_friend(lc,lf); /* add this new friend to the
buddy list*/
}

static void linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr,
                const LinphoneAddress *from, const char *msg)

{
    std::cout << "text received: " << msg << std::endl;
}

static void linphonec_display_status (LinphoneCore * lc, const char
*something)
{
    std::cout << "display status: " << something << std::endl;
}

static void linphonec_dtmf_received(LinphoneCore *lc, LinphoneCall
*call, int dtmf)
{
    std::cout << "dtmf received" << std::endl;
}

static void linphonec_call_encryption_changed(LinphoneCore *lc,
LinphoneCall *call, bool_t encrypted, const char *auth_token)
{
    std::cout << "call encryption changed" << std::endl;
}

static void registration_state_changed(struct _LinphoneCore *lc,
LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char
*message)
{
    std::cout << "New registration state " <<
linphone_registration_state_to_string(cstate) << " for user id " <<
linphone_proxy_config_get_identity(cfg) << " at proxy " <<
linphone_proxy_config_get_addr(cfg) << std::endl;
}

void SipImplemantation::actionHandler()
{

    std::lock_guard<std::mutex> lock(actionmutex);

    if (actions.ToDial.size() > 0)
    {
        linphone_core_invite(linphonec, actions.ToDial.c_str());
        std::cout << "Calling " << actions.ToDial << std::endl;
        actions.ToDial = "";
    }

    if (actions.pickup)
    {
        actions.pickup = false;
        linphone_core_accept_call(linphonec,
linphone_core_get_current_call(linphonec));
    }

    if (actions.hangup)
    {
        actions.hangup = false;
        std::cout << "Trying to hangup call " << std::endl;
        if(linphone_core_terminate_all_calls(linphonec)>0)
            std::cout << "Terminated all calls " << std::endl;
        else
            std::cout << "Unable to terminate calls : " << std::endl;
    }
}

void SipImplemantation::internalthread()
{
    std::chrono::milliseconds dura(200);

    this->running = true;

    while (this->running)
    {
        std::cout << "Linphone core iterate" << std::endl;

        linphone_core_iterate(linphonec);

        std::cout << "Iterate done" << std::endl;

        actionHandler();

        std::this_thread::sleep_for(dura);

        //std::cout << "Running = " << this->running << std::endl;
    }
}

void SipImplemantation::call(const std::string& calllocation)
{
    std::lock_guard<std::mutex> lock(actionmutex);
    actions.ToDial = calllocation;
}

void SipImplemantation::pickup(const int callindex)
{
    std::lock_guard<std::mutex> lock(actionmutex);
    actions.pickup = true;
}

void SipImplemantation::hangup(const int callindex)
{
    std::lock_guard<std::mutex> lock(actionmutex);
    actions.hangup = true;
    //linphone_core_terminate_all_calls(linphonec);
    //linphone_core_iterate(linphonec);
    std::cout << "Hangup: actions.hangup = " << actions.hangup <<
std::endl;
}

void SipImplemantation::mute()
{

}

void SipImplemantation::setIncomingCallEvent(std::function<void(const
std::string&)> incomingcall)
{
    this->incomingcall = incomingcall;
}

void SipImplemantation::setFriendStatusEvent(std::function<void(const
std::string&, bool online)> friendstatus)
{
    this->friendstatus = friendstatus;
}

void SipImplemantation::addBuddy(std::string username)
{
    LinphoneFriend* myFriend = NULL;
    std::string friendIdentity;
    friendIdentity.append("sip:");
    friendIdentity.append(username);
    friendIdentity.append("@sip.linphone.org");
    myFriend = linphone_friend_new_with_addr(friendIdentity.c_str());
/*creates friend object for buddy joe*/
    linphone_friend_set_ref_key(myFriend, username.c_str());
    linphone_friend_enable_subscribes(myFriend,TRUE); /*configure this
friend to emit SUBSCRIBE message after being added to LinphoneCore*/
linphone_friend_set_inc_subscribe_policy(myFriend,LinphoneSPAccept); /*
accept Incoming subscription request for this friend*/
    linphone_core_add_friend(linphonec,myFriend);
    //linphone_friend_destroy(myFriend);
    std::cout << "Buddy " << friendIdentity << " added to linphonecore"
<< std::endl;
}

void SipImplemantation::authenticate()
{
    LinphoneUser linphoneUser =
ConfigManager::getInstance().getFirstUser();
    linphoneAuthInfo =
linphone_auth_info_new(linphoneUser.getUsername().data(),
linphoneUser.getUsername().data(), linphoneUser.getPassword().data(),
NULL, "sip.linphone.org");
    linphone_core_add_auth_info(linphonec, linphoneAuthInfo);

    std::cout << "SIP authentication added " << std::endl;

    linphoneProxyConfig = linphone_proxy_config_new();
    linphone_proxy_config_set_server_addr(linphoneProxyConfig,
"sip:sip.linphone.org");
    linphone_proxy_config_set_route(linphoneProxyConfig,
"<sip:sip.linphone.org>;transport=tls");
    std::string proxyIdentity;
    proxyIdentity.append("sip:");
    proxyIdentity.append(linphoneUser.getUsername());
    proxyIdentity.append("@sip.linphone.org");
    linphone_proxy_config_set_identity(linphoneProxyConfig,
proxyIdentity.data());
    //linphone_proxy_config_set_expires(linphoneProxyConfig, 3600);
    linphone_proxy_config_enable_register(linphoneProxyConfig, 1);
    linphone_proxy_config_enable_publish(linphoneProxyConfig, 1);
linphone_proxy_config_set_dial_escape_plus(linphoneProxyConfig, 0);
    linphone_core_add_proxy_config(linphonec, linphoneProxyConfig);
    linphone_core_set_default_proxy(linphonec, linphoneProxyConfig);

    std::cout << "SIP proxy added" << std::endl;
}

void SipImplemantation::init()
{
    impl = this;

    actions.ToDial = "";
    actions.pickup = false;
    actions.hangup = true;

    linphonec_vtable = {0};

    linphonec_vtable.call_state_changed = linphonec_call_state_changed;
    linphonec_vtable.notify_presence_recv =
linphonec_notify_presence_received;
    linphonec_vtable.new_subscription_request =
linphonec_new_unknown_subscriber;
    linphonec_vtable.auth_info_requested = linphonec_prompt_for_auth;
    linphonec_vtable.display_status = linphonec_display_status;
linphonec_vtable.display_message=linphonec_display_something;
    linphonec_vtable.display_warning=linphonec_display_warning;
    linphonec_vtable.display_url=linphonec_display_url;
    linphonec_vtable.text_received=linphonec_text_received;
    linphonec_vtable.dtmf_received=linphonec_dtmf_received;
    linphonec_vtable.refer_received=linphonec_display_refer;
linphonec_vtable.call_encryption_changed=linphonec_call_encryption_changed;
linphonec_vtable.registration_state_changed=registration_state_changed;
/*just in case sip proxy is used*/

    //linphonec=linphone_core_new (&linphonec_vtable, NULL,
"/home/pi/.linphonerc", NULL);
    linphonec=linphone_core_new (&linphonec_vtable, NULL, NULL, NULL);

    //Authentication from database and add proxies for user
    authenticate();

    std::chrono::milliseconds dura(500);

    do
    {
        linphone_core_iterate(linphonec);
        std::cout << "Wait for registration process " << std::endl;
        std::this_thread::sleep_for(dura);
    }while( running &&
linphone_proxy_config_get_state(linphoneProxyConfig) ==
LinphoneRegistrationProgress);

    //Read friends from database
    std::vector<hiberlite::bean_ptr<Contact> > contacts =
ConfigManager::getInstance().readFriends();
    for(ContactBeans::iterator it = contacts.begin(); it !=
contacts.end(); it++){
        addBuddy((*it)->getUsername());
        linphone_core_iterate(linphonec);
    }


    //linphone_core_enable_logs(fopen("./phonelog", "+w"));
    //linphone_core_enable_logs(NULL);
    linphone_core_disable_logs();
    linphone_core_enable_video(linphonec, false, false);

const MSList * authlist = linphone_core_get_auth_info_list(linphonec);

    for (;authlist!=NULL;authlist=authlist->next)
    {
        LinphoneAuthInfo *authinfo=(LinphoneAuthInfo*)authlist->data;

        std::cout << "auth info: " <<
linphone_auth_info_get_username(authinfo) << std::endl;
    }

    std::cout << "Starting internal thread" << std::endl;

    thethread = std::thread(&SipImplemantation::internalthread, this);

}

void SipImplemantation::destroy()
{
    running = false;

    std::cout << "Waiting on the thread " << std::endl;
    actionmutex.unlock();
    thethread.join();

    std::cout << "Terminating all calls" << std::endl;
    linphone_core_terminate_all_calls(linphonec);
    std::cout << "Calls terminated" << std::endl;

    /**TODO controle free**/
    //linphone_auth_info_destroy(linphoneAuthInfo);
    //linphone_proxy_config_destroy(linphoneProxyConfig);

    linphone_core_destroy(linphonec);
}




_______________________________________________
Linphone-developers mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/linphone-developers

!DSPAM:53cfa36817241272912377!




reply via email to

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