Changes between Initial Version and Version 1 of PJSIP_Tutorial


Ignore:
Timestamp:
Jan 8, 2007 12:37:13 AM (17 years ago)
Author:
bennylp
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PJSIP_Tutorial

    v1 v1  
     1= PJSIP Tutorial (Using PJSUA-API) = 
     2 
     3As you can see from the diagram in [/docs.htm PJSIP Documentation] page, PJSIP software consists of multiple API abstractions. This tutorial uses [/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-API], the highest layer of abstraction of all, which combines PJSIP (the SIP stack library) and PJMEDIA (the media stack library). 
     4 
     5 
     6== A Simple SIP User Agent == 
     7 
     8Is it possible to create a simple but rather complete SIP user agent, with registration, digest authentication, SDP negotiation, and fully featured media in under than 100 lines of code? 
     9 
     10Well, lets see. 
     11 
     12{{{ 
     13#include <pjsua-lib/pjsua.h> 
     14 
     15#define THIS_FILE   "APP" 
     16 
     17static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, 
     18                             pjsip_rx_data *rdata) 
     19{ 
     20    pjsua_call_info ci; 
     21 
     22    pjsua_call_get_info(call_id, &ci); 
     23 
     24    PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!", 
     25                         (int)ci.remote_info.slen, 
     26                         ci.remote_info.ptr)); 
     27 
     28    // Automatically answer incoming call with 200/OK 
     29    pjsua_call_answer(call_id, 200, NULL, NULL); 
     30} 
     31 
     32static void on_call_media_state(pjsua_call_id call_id) 
     33{ 
     34    pjsua_call_info ci; 
     35 
     36    pjsua_call_get_info(call_id, &ci); 
     37 
     38    if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) { 
     39        // When media is active, connect call to sound device. 
     40        pjsua_conf_connect(ci.conf_slot, 0); 
     41        pjsua_conf_connect(0, ci.conf_slot); 
     42    } 
     43} 
     44 
     45static void on_call_state(pjsua_call_id call_id, pjsip_event *e) 
     46{ 
     47    pjsua_call_info ci; 
     48 
     49    pjsua_call_get_info(call_id, &ci); 
     50    PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id, 
     51                         (int)ci.state_text.slen, 
     52                         ci.state_text.ptr)); 
     53} 
     54 
     55static void error_exit(const char *title, pj_status_t status) 
     56{ 
     57    pjsua_perror(THIS_FILE, title, status); 
     58    pjsua_destroy(); 
     59    exit(1); 
     60} 
     61 
     62int main(int argc, char *argv[]) 
     63{ 
     64    pjsua_acc_id acc_id; 
     65    pj_status_t status; 
     66 
     67    // Create pjsua first! 
     68    status = pjsua_create(); 
     69    if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status); 
     70 
     71    // If argument is specified, it's got to be a valid SIP URL 
     72    if (argc > 1) { 
     73        status = pjsua_verify_sip_url(argv[1]); 
     74        if (status != PJ_SUCCESS) error_exit("Invalid URL in argument", status); 
     75    } 
     76 
     77    // Init pjsua 
     78    { 
     79        pjsua_config cfg; 
     80        pjsua_logging_config log_cfg; 
     81 
     82        pjsua_config_default(&cfg); 
     83        cfg.cb.on_incoming_call = &on_incoming_call; 
     84        cfg.cb.on_call_media_state = &on_call_media_state; 
     85        cfg.cb.on_call_state = &on_call_state; 
     86 
     87        pjsua_logging_config_default(&log_cfg); 
     88        log_cfg.console_level = 4; 
     89 
     90        status = pjsua_init(&cfg, &log_cfg, NULL); 
     91        if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status); 
     92    } 
     93 
     94    // Add UDP transport. 
     95    { 
     96        pjsua_transport_config cfg; 
     97 
     98        pjsua_transport_config_default(&cfg); 
     99        cfg.port = 5060; 
     100        status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL); 
     101        if (status != PJ_SUCCESS) error_exit("Error creating transport", status); 
     102    } 
     103 
     104    // Initialization is done, now start pjsua 
     105    status = pjsua_start(); 
     106    if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status); 
     107 
     108    // Register to SIP account. 
     109    { 
     110        pjsua_acc_config cfg; 
     111 
     112        pjsua_acc_config_default(&cfg); 
     113        cfg.id = pj_str("sip:bulukucing@iptel.org"); 
     114        cfg.reg_uri = pj_str("sip:iptel.org"); 
     115        cfg.cred_count = 1; 
     116        cfg.cred_info[0].realm = pj_str("iptel.org"); 
     117        cfg.cred_info[0].scheme = pj_str("digest"); 
     118        cfg.cred_info[0].username = pj_str("bulukucing"); 
     119        cfg.cred_info[0].data_type = 0; 
     120        cfg.cred_info[0].data = pj_str("netura"); 
     121 
     122        status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id); 
     123        if (status != PJ_SUCCESS) error_exit("Error adding account", status); 
     124    } 
     125 
     126    // If URL is specified, make call to the URL. 
     127    if (argc > 1) { 
     128        pj_str_t uri = pj_str(argv[1]); 
     129        status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL); 
     130        if (status != PJ_SUCCESS) error_exit("Error making call", status); 
     131    } 
     132 
     133    // Wait until user press "q" to quit. 
     134    for (;;) { 
     135        char option[10]; 
     136 
     137        puts("Press 'q' to quit"); 
     138        fgets(option, sizeof(option), stdin); 
     139        if (option[0] == 'q') 
     140            break; 
     141    } 
     142 
     143    // Destroy pjsua 
     144    pjsua_destroy(); 
     145 
     146    return 0; 
     147} 
     148}}} 
     149