WARNING: The online documentation has moved to https://docs.pjsip.org.

Visit the new documentation at https://docs.pjsip.org:

BLOG | DOCUMENTATION | GITHUB

Home --> Documentations --> PJSIP Reference

Samples: Simple PJSUA

Very simple SIP User Agent with registration, call, and media, all in under 200 lines of code.

00001 /* $Id: simple_pjsua.c 3553 2011-05-05 06:14:19Z nanang $ */
00002 /* 
00003  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
00004  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
00019  */
00020 
00041 #include <pjsua-lib/pjsua.h>
00042 
00043 #define THIS_FILE       "APP"
00044 
00045 #define SIP_DOMAIN      "example.com"
00046 #define SIP_USER        "alice"
00047 #define SIP_PASSWD      "secret"
00048 
00049 
00050 /* Callback called by the library upon receiving incoming call */
00051 static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
00052                              pjsip_rx_data *rdata)
00053 {
00054     pjsua_call_info ci;
00055 
00056     PJ_UNUSED_ARG(acc_id);
00057     PJ_UNUSED_ARG(rdata);
00058 
00059     pjsua_call_get_info(call_id, &ci);
00060 
00061     PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
00062                          (int)ci.remote_info.slen,
00063                          ci.remote_info.ptr));
00064 
00065     /* Automatically answer incoming calls with 200/OK */
00066     pjsua_call_answer(call_id, 200, NULL, NULL);
00067 }
00068 
00069 /* Callback called by the library when call's state has changed */
00070 static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
00071 {
00072     pjsua_call_info ci;
00073 
00074     PJ_UNUSED_ARG(e);
00075 
00076     pjsua_call_get_info(call_id, &ci);
00077     PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
00078                          (int)ci.state_text.slen,
00079                          ci.state_text.ptr));
00080 }
00081 
00082 /* Callback called by the library when call's media state has changed */
00083 static void on_call_media_state(pjsua_call_id call_id)
00084 {
00085     pjsua_call_info ci;
00086 
00087     pjsua_call_get_info(call_id, &ci);
00088 
00089     if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
00090         // When media is active, connect call to sound device.
00091         pjsua_conf_connect(ci.conf_slot, 0);
00092         pjsua_conf_connect(0, ci.conf_slot);
00093     }
00094 }
00095 
00096 /* Display error and exit application */
00097 static void error_exit(const char *title, pj_status_t status)
00098 {
00099     pjsua_perror(THIS_FILE, title, status);
00100     pjsua_destroy();
00101     exit(1);
00102 }
00103 
00104 /*
00105  * main()
00106  *
00107  * argv[1] may contain URL to call.
00108  */
00109 int main(int argc, char *argv[])
00110 {
00111     pjsua_acc_id acc_id;
00112     pj_status_t status;
00113 
00114     /* Create pjsua first! */
00115     status = pjsua_create();
00116     if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);
00117 
00118     /* If argument is specified, it's got to be a valid SIP URL */
00119     if (argc > 1) {
00120         status = pjsua_verify_url(argv[1]);
00121         if (status != PJ_SUCCESS) error_exit("Invalid URL in argv", status);
00122     }
00123 
00124     /* Init pjsua */
00125     {
00126         pjsua_config cfg;
00127         pjsua_logging_config log_cfg;
00128 
00129         pjsua_config_default(&cfg);
00130         cfg.cb.on_incoming_call = &on_incoming_call;
00131         cfg.cb.on_call_media_state = &on_call_media_state;
00132         cfg.cb.on_call_state = &on_call_state;
00133 
00134         pjsua_logging_config_default(&log_cfg);
00135         log_cfg.console_level = 4;
00136 
00137         status = pjsua_init(&cfg, &log_cfg, NULL);
00138         if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
00139     }
00140 
00141     /* Add UDP transport. */
00142     {
00143         pjsua_transport_config cfg;
00144 
00145         pjsua_transport_config_default(&cfg);
00146         cfg.port = 5060;
00147         status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
00148         if (status != PJ_SUCCESS) error_exit("Error creating transport", status);
00149     }
00150 
00151     /* Initialization is done, now start pjsua */
00152     status = pjsua_start();
00153     if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
00154 
00155     /* Register to SIP server by creating SIP account. */
00156     {
00157         pjsua_acc_config cfg;
00158 
00159         pjsua_acc_config_default(&cfg);
00160         cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
00161         cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
00162         cfg.cred_count = 1;
00163         cfg.cred_info[0].realm = pj_str(SIP_DOMAIN);
00164         cfg.cred_info[0].scheme = pj_str("digest");
00165         cfg.cred_info[0].username = pj_str(SIP_USER);
00166         cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
00167         cfg.cred_info[0].data = pj_str(SIP_PASSWD);
00168 
00169         status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
00170         if (status != PJ_SUCCESS) error_exit("Error adding account", status);
00171     }
00172 
00173     /* If URL is specified, make call to the URL. */
00174     if (argc > 1) {
00175         pj_str_t uri = pj_str(argv[1]);
00176         status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
00177         if (status != PJ_SUCCESS) error_exit("Error making call", status);
00178     }
00179 
00180     /* Wait until user press "q" to quit. */
00181     for (;;) {
00182         char option[10];
00183 
00184         puts("Press 'h' to hangup all calls, 'q' to quit");
00185         if (fgets(option, sizeof(option), stdin) == NULL) {
00186             puts("EOF while reading stdin, will quit now..");
00187             break;
00188         }
00189 
00190         if (option[0] == 'q')
00191             break;
00192 
00193         if (option[0] == 'h')
00194             pjsua_call_hangup_all();
00195     }
00196 
00197     /* Destroy pjsua */
00198     pjsua_destroy();
00199 
00200     return 0;
00201 }

 


PJSIP Open Source, high performance, small footprint, and very very portable SIP stack
Copyright (C) 2006-2008 Teluu Inc.