Question

Im pretty much new in sip development and trying to implement a windows phone 8 client using pjsip.

ive build the sample application from pjsip ,which creates pjsua app with telnet connectivity.

Right now ,what i dont get is,how will i use this library and integrate in my app without telnet,

i just need to put a manual dial pad and call from there,to accomplish this,what is going to be the procedure?

pjsip for android or iphone has two sample application ,csipsimple and siphon ,but pjsip for windows phone 8 has no application like this.

any help regarding the way to go ahead would be very helpful.

Thanks

Was it helpful?

Solution

Since you mention that you've tried the windows phone telnet app sample, I assume you've downloaded the PJSIP winphone source as mentioned in their wp8 getting started guide. To create a simple app that perform outgoing and receive incoming call as you mentioned, you can simply reuse this winphone project.

Open the winphone project and do:

  1. Create new Windows Phone project and set this as startup project (let's call this project SIP_UI). This will serve as the UI. You can just create a "Call button" that will perform outgoing call later.
  2. Follow the existing pjsua_wp WMAppManifest.xml settings for this SIP_UI. Especially the capabilities part. Your app won't work if you simply use the default settings.
  3. Create new Windows Phone Runtime project (let's call this SIP_WINPRT). Create a class and a method inside of this class that will perform the actual call later.
  4. Change property setting for SIP_WINPRT (right click SIP_WINPRT project -> property) by following the existing pjsua_wp_backend's. Change especially on the References, Additional include directories, and preprocessor definitions. Adjust the path accordingly.
  5. Search for simple_pjsua.c in the winphone sample. And try to implement that in the class you've created in SIP_WINPRT. Sample that I've created:

    #include "pch.h"
    #include "backend.h"
    #include "pjsua.h"
    
    #define SIP_DOMAIN  "dogdomain"
    #define SIP_USER    "dog"
    #define SIP_PASSWD  "dog"
    
    using namespace backend;
    using namespace Platform;
    
    SipletRuntimeComponent::SipletRuntimeComponent()
    {
    }
    
    /* Display error and exit application */
    static void error_exit(const char *title, pj_status_t status)
    {
        //pjsua_perror(THIS_FILE, title, status);
        pjsua_destroy();
        exit(1);
    }
    
    /* Callback called by the library upon receiving incoming call */
    static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
                     pjsip_rx_data *rdata)
    {
        pjsua_call_info ci;
    
        PJ_UNUSED_ARG(acc_id);
        PJ_UNUSED_ARG(rdata);
    
        pjsua_call_get_info(call_id, &ci);
    
        //PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
        //       (int)ci.remote_info.slen,
        //       ci.remote_info.ptr));
    
        /* Automatically answer incoming calls with 200/OK */
        pjsua_call_answer(call_id, 200, NULL, NULL);
    }
    
    /* Callback called by the library when call's media state has changed */
    static void on_call_media_state(pjsua_call_id call_id)
    {
        pjsua_call_info ci;
    
        pjsua_call_get_info(call_id, &ci);
    
        if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
        // When media is active, connect call to sound device.
        pjsua_conf_connect(ci.conf_slot, 0);
        pjsua_conf_connect(0, ci.conf_slot);
        }
    }
    
    /* Callback called by the library when call's state has changed */
    static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
    {
        pjsua_call_info ci;
    
        PJ_UNUSED_ARG(e);
    
        pjsua_call_get_info(call_id, &ci);
        //PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
        //       (int)ci.state_text.slen,
        //       ci.state_text.ptr));
    }
    
    
    int SipletRuntimeComponent::SipCall(int address)
    {
        /* Create pjsua */
        pj_status_t status;
        status = pjsua_create();
        if (status != PJ_SUCCESS){
            //Error in pjsua_create()
            return -1;
        }
    
        /* Validate the URL*/
        char url[50] = "sip:cat:cat@catdomain:5060";
        status = pjsua_verify_url(url);
        if (status != PJ_SUCCESS){
            //Invalid URL given
            return -1;
        }
    
        /* Init pjsua */
        {
            pjsua_config cfg;
            pjsua_logging_config log_cfg;
    
            pjsua_config_default(&cfg);
            cfg.cb.on_incoming_call = &on_incoming_call;
            cfg.cb.on_call_media_state = &on_call_media_state;
            cfg.cb.on_call_state = &on_call_state;
    
            pjsua_logging_config_default(&log_cfg);
            log_cfg.console_level = 4;
    
            status = pjsua_init(&cfg, &log_cfg, NULL);
            if (status != PJ_SUCCESS){
                //Error in pjsua_init()
                pjsua_destroy();
                return -1;
            }
        }
    
        /* Add UDP transport. */
        {
            pjsua_transport_config cfg;
    
            pjsua_transport_config_default(&cfg);
            cfg.port = 5060;
            status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
            if (status != PJ_SUCCESS){
                //Error creating transport
                pjsua_destroy();
                return -1;
            }
        }
    
        /* Initialization is done, now start pjsua */
        status = pjsua_start();
        if (status != PJ_SUCCESS){
            //Error starting pjsua
            pjsua_destroy();
            return -1;
        }
    
        /* Register to SIP server by creating SIP account. */
        pjsua_acc_id acc_id;
        {
            pjsua_acc_config cfg;
    
            pjsua_acc_config_default(&cfg);
            cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
            cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
            cfg.cred_count = 1;
            cfg.cred_info[0].realm = pj_str(SIP_DOMAIN);
            cfg.cred_info[0].scheme = pj_str("digest");
            cfg.cred_info[0].username = pj_str(SIP_USER);
            cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
            cfg.cred_info[0].data = pj_str(SIP_PASSWD);
    
            status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
    
            if (status != PJ_SUCCESS){          
                //Error adding account
                pjsua_destroy();
                return -1;
            }
        }
    
        /* make call to the URL. */
        pj_str_t uri = pj_str(url);
        status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
        if (status != PJ_SUCCESS){
            //Error making call
            pjsua_destroy();
            return -1;
        }
    
        return address + 1;
    }
    
  6. Add SIP_WINPRT as a reference in SIP_UI project.

  7. Call the SIP_WINPRT when the Call button is pressed.

OTHER TIPS

Well, your problems doesn't seem to be related with PJSip but with UI Development. I suggest that you create your UI (using XAML/C# or XAML/C++ and don't forget it must be a Windows Phone 8.0 Silverlight project). Then you start referencing the PJSip library.

Hope it helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top