Skip to content

Instantly share code, notes, and snippets.

@mikelnrd
Last active October 4, 2016 10:26
Show Gist options
  • Save mikelnrd/6b8b4986d6529ae751ebd2af5bf4d29f to your computer and use it in GitHub Desktop.
Save mikelnrd/6b8b4986d6529ae751ebd2af5bf4d29f to your computer and use it in GitHub Desktop.

Revisions

  1. @MikeLeonard MikeLeonard revised this gist Oct 4, 2016. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions key_piece_of_code_taken_from_whole_app.c
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    //!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!//////!!//////!!//////!!//////!!//
    // Scroll down in this gist to see the run logs and the full entire app as this is just the key snippet where I've likely made a mistake! Thanks :)
    //!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!////!!//////!!//////!!//////!!//////!!//

    /////////////////////////////////////////////////////////////////////////////////
    // key piece of code
    /////////////////////////////////////////////////////////////////////////////////
  2. @MikeLeonard MikeLeonard revised this gist Oct 4, 2016. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
  3. @MikeLeonard MikeLeonard created this gist Oct 4, 2016.
    387 changes: 387 additions & 0 deletions entire_app.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,387 @@
    #pragma GCC diagnostic ignored "-Wwrite-strings"

    #include <pjlib.h>
    #include <pjlib-util.h>
    #include <pjmedia.h>
    #include <pjmedia-codec.h>
    #include <pjsip.h>
    #include <pjsip_simple.h>
    #include <pjsip_ua.h>
    #include <pjsua-lib/pjsua.h>

    #define THIS_FILE "APP"

    #define SIP_DOMAIN "example.com"
    #define SIP_USER "mike"
    #define SIP_PASSWD "secret"

    // global helper vars
    int app_exiting = 0;

    // struct for app configuration settings
    struct app_config {
    char *sip_domain;
    char *sip_user;
    char *sip_password;
    char *phone_number;
    char *tts;
    char *tts_file;
    int record_call;
    char *record_file;
    int repetition_limit;
    int silent_mode;
    } app_cfg;

    // helper for logging messages to console (disabled if silent mode is active)
    static void log_message(char *message)
    {
    if (!app_cfg.silent_mode)
    {
    fprintf(stderr, message);
    }
    }

    // clean application exit
    static void app_exit(char *message)
    {
    log_message(message);
    if (!app_exiting)
    {
    app_exiting = 1;
    log_message("Stopping application ... ");

    // hangup open calls and stop pjsua
    pjsua_call_hangup_all();
    pjsua_destroy();

    log_message("Done.\n");

    exit(0);
    }
    }

    // display error and exit application
    static void error_exit(const char *title, pj_status_t status)
    {
    if (!app_exiting)
    {
    app_exiting = 1;

    pjsua_perror("SIP Call", title, status);

    // hangup open calls and stop pjsua
    pjsua_call_hangup_all();
    pjsua_destroy();

    exit(1);
    }
    }


    /////////////////////////////////////////////////////////////////////////////////
    // key piece of code
    /////////////////////////////////////////////////////////////////////////////////
    struct call_data {
    pj_pool_t *pool;
    pjmedia_conf *conf;
    pjmedia_port *cport;
    pjmedia_port *null;
    pjmedia_port *writer;
    pjmedia_port *player;
    pjmedia_master_port *m;
    unsigned int call_slot;
    unsigned int writer_slot;
    unsigned int player_slot;
    };

    static void call_media_init(pjsua_call_id call_id){
    log_message("RUNNING... call_media_init\n");

    pj_pool_t *pool;
    struct call_data *cd;
    pj_status_t status;

    pool = pjsua_pool_create("mycall", 4000, 4000);
    cd = PJ_POOL_ZALLOC_T(pool, struct call_data);
    cd->pool = pool;

    pjsua_call_set_user_data(call_id, (void*)cd);

    pjsua_media_config media_cfg;
    pjsua_media_config_default(&media_cfg);

    status = pjmedia_conf_create(
    cd->pool,
    media_cfg.max_media_ports, //max media ports
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    PJMEDIA_CONF_NO_DEVICE | PJMEDIA_CONF_NO_MIC, //options
    &cd->conf //pointer to conference bridge instance
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    cd->cport = pjmedia_conf_get_master_port(cd->conf);

    status = pjmedia_null_port_create(
    cd->pool,
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    &cd->null);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_master_port_create(cd->pool, cd->null, cd->cport, 0, &cd->m);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_master_port_start(cd->m);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    //todo(mike) handle errors, see pjsua_aud.c


    /* wav writer */
    status = pjmedia_wav_writer_port_create(
    cd->pool,
    "testingtesting.wav", //path
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    0, //options
    0, //buf_size defaults to 4kb if set to 0
    &cd->writer //yes this should be a pjmedia_port **
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->writer, NULL, &cd->writer_slot);
    if (status != PJ_SUCCESS) {
    pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
    pjmedia_port_destroy(cd->writer);
    }

    pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->writer_slot, 0);

    /* wav player */
    status = pjmedia_wav_player_port_create(
    cd->pool,
    "message.wav",
    media_cfg.audio_frame_ptime,
    0,
    0,
    &cd->player //yes this should be a pjmedia_port **
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}

    status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->player, NULL, &cd->player_slot);
    if (status != PJ_SUCCESS) {
    pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
    pjmedia_port_destroy(cd->player);
    }

    pjmedia_conf_connect_port(cd->conf, cd->player_slot, cd->call_slot, 0);

    //uncomment to loop back remote audio (also doesn't work)
    //pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->call_slot, 0);
    }


    static void call_media_deinit(pjsua_call_id call_id){
    log_message("RUNNING... call_media_deinit\n");
    struct call_data *cd;

    cd = (struct call_data*) pjsua_call_get_user_data(call_id);
    if (!cd)
    return;

    pjmedia_master_port_stop(cd->m);
    pjmedia_master_port_destroy(cd->m, PJ_FALSE);

    pjmedia_conf_destroy(cd->conf);
    pjmedia_port_destroy(cd->null);
    pjmedia_port_destroy(cd->writer);

    log_message("Called call_media_deinit.\n");

    pjsua_call_set_user_data(call_id, NULL);
    }


    /////////////////////////////////////////////////////////////////////////////////
    // on_ functions
    /////////////////////////////////////////////////////////////////////////////////

    static void on_call_state(pjsua_call_id call_id, pjsip_event *e){
    log_message("RUNNING... on_call_state\n");
    pjsua_call_info call_info;

    pjsua_call_get_info(call_id, &call_info);

    PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
    (int)call_info.state_text.slen,
    call_info.state_text.ptr));

    if (call_info.state == PJSIP_INV_STATE_CALLING) {
    log_message("Call state is CALLING.\n");
    call_media_init(call_id);
    }

    if (call_info.state == PJSIP_INV_STATE_CONFIRMED) {
    log_message("Call state is CONFIRMED.\n");
    }
    if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) {
    log_message("Call state is DISCONNECTED.\n");
    call_media_deinit(call_id);
    }
    }

    static void on_call_media_state(pjsua_call_id call_id){
    log_message("RUNNING... on_call_media_state\n");

    pjsua_call_info call_info;
    pjsua_call_get_info(call_id, &call_info);

    if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
    log_message("Media state is ACTIVE.\n");
    //call_media_init(call_id); //doesn't work here either!
    }
    }

    static void on_stream_created(pjsua_call_id call_id,
    pjmedia_stream *strm,
    unsigned stream_idx,
    pjmedia_port **p_port){
    log_message("RUNNING... on_stream_created\n");
    struct call_data *cd;
    cd = (struct call_data*) pjsua_call_get_user_data(call_id);
    if (!cd)
    return;
    pjmedia_conf_add_port(cd->conf, cd->pool, *p_port, NULL, &cd->call_slot);
    }

    static void on_stream_destroyed(pjsua_call_id call_id,
    pjmedia_stream *strm,
    unsigned stream_idx){
    log_message("RUNNING... on_stream_destroyed\n");
    struct call_data *cd;
    cd = (struct call_data*) pjsua_call_get_user_data(call_id);
    if (!cd)
    return;
    pjmedia_conf_remove_port(cd->conf, cd->call_slot);
    }

    /////////////////////////////////////////////////////////////////////////////////
    // main()
    /////////////////////////////////////////////////////////////////////////////////
    //argv[1] may contain URL to call.
    int main(int argc, char *argv[]){

    pjsua_acc_id acc_id;
    app_cfg.tts_file = "message.wav";
    app_cfg.record_call = 1;
    app_cfg.record_file = "recording.wav";
    app_cfg.repetition_limit = 250;
    app_cfg.silent_mode = 0;
    pj_status_t status;

    /* Create pjsua first! */
    status = pjsua_create();
    if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()", status);

    /* If argument is specified, it's got to be a valid SIP URL */
    if (argc > 1) {
    status = pjsua_verify_url(argv[1]);
    if (status != PJ_SUCCESS) error_exit("Invalid URL in argv", status);
    } else {
    PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", status));
    }

    /* Init pjsua */
    {
    pjsua_config cfg;
    pjsua_logging_config log_cfg;

    pjsua_config_default(&cfg); //see pjsua.h
    //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;
    cfg.cb.on_stream_created = &on_stream_created;
    cfg.cb.on_stream_destroyed = &on_stream_destroyed;

    pjsua_logging_config_default(&log_cfg);
    log_cfg.console_level = 4;

    pjsua_media_config media_cfg;
    pjsua_media_config_default(&media_cfg);
    //media_cfg.snd_play_latency = 160; //default 2000
    //media_cfg.snd_rec_latency = 160; //default 2000
    //media_cfg.clock_rate = 16000;
    //media_cfg.snd_clock_rate = 16000;
    media_cfg.quality = 10;
    media_cfg.ec_tail_len = 0;
    //media_cfg.ptime = 100; //100 milliseconds //default seems to be 20?

    status = pjsua_init(&cfg, &log_cfg, NULL);
    if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()", status);
    }

    /* 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_exit("Error creating transport", status);
    }

    /* Initialization is done, now start pjsua */
    status = pjsua_start();
    if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);

    // pjsua_set_null_snd_dev() now not used, because instead using pjsua_set_no_snd_dev() (see below)
    // disable sound - use null sound device
    //status = pjsua_set_null_snd_dev();
    //if (status != PJ_SUCCESS) error_exit("Error disabling audio", status);

    pjmedia_port* mainconfbridgeport;
    mainconfbridgeport = pjsua_set_no_snd_dev();

    /* Register to SIP server by creating SIP account. */
    {
    pjsua_acc_config cfg;

    pjsua_acc_config_default(&cfg);
    cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);

    status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
    if (status != PJ_SUCCESS) error_exit("Error adding account", status);
    }

    /* If URL is specified, make call to the URL. */
    if (argc > 1) {
    pj_str_t uri = pj_str(argv[1]);
    status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
    if (status != PJ_SUCCESS) error_exit("Error making call", status);
    }

    //Wait until user press "q" to quit.
    for (;;) {
    char option[10];

    puts("Press 'h' to hangup all calls, 'q' to quit");
    if (fgets(option, sizeof(option), stdin) == NULL) {
    puts("EOF while reading stdin, will quit now..");
    break;
    }

    if (option[0] == 'q')
    break;

    if (option[0] == 'h')
    pjsua_call_hangup_all();

    }

    /* Destroy pjsua */
    pjsua_destroy();

    return 0;
    }
    124 changes: 124 additions & 0 deletions key_piece_of_code_taken_from_entire_app.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    /////////////////////////////////////////////////////////////////////////////////
    // key piece of code
    /////////////////////////////////////////////////////////////////////////////////
    struct call_data {
    pj_pool_t *pool;
    pjmedia_conf *conf;
    pjmedia_port *cport;
    pjmedia_port *null;
    pjmedia_port *writer;
    pjmedia_port *player;
    pjmedia_master_port *m;
    unsigned int call_slot;
    unsigned int writer_slot;
    unsigned int player_slot;
    };

    static void call_media_init(pjsua_call_id call_id){
    log_message("RUNNING... call_media_init\n");

    pj_pool_t *pool;
    struct call_data *cd;
    pj_status_t status;

    pool = pjsua_pool_create("mycall", 4000, 4000);
    cd = PJ_POOL_ZALLOC_T(pool, struct call_data);
    cd->pool = pool;

    pjsua_call_set_user_data(call_id, (void*)cd);

    pjsua_media_config media_cfg;
    pjsua_media_config_default(&media_cfg);

    status = pjmedia_conf_create(
    cd->pool,
    media_cfg.max_media_ports, //max media ports
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    PJMEDIA_CONF_NO_DEVICE | PJMEDIA_CONF_NO_MIC, //options
    &cd->conf //pointer to conference bridge instance
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    cd->cport = pjmedia_conf_get_master_port(cd->conf);

    status = pjmedia_null_port_create(
    cd->pool,
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    &cd->null);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_master_port_create(cd->pool, cd->null, cd->cport, 0, &cd->m);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_master_port_start(cd->m);
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    //todo(mike) handle errors, see pjsua_aud.c


    /* wav writer */
    status = pjmedia_wav_writer_port_create(
    cd->pool,
    "testingtesting.wav", //path
    media_cfg.clock_rate,
    media_cfg.channel_count,
    media_cfg.clock_rate * media_cfg.channel_count * media_cfg.audio_frame_ptime / 1000, //mconf_cfg.samples_per_frame,
    16, //mconf_cfg.bits_per_sample,
    0, //options
    0, //buf_size defaults to 4kb if set to 0
    &cd->writer //yes this should be a pjmedia_port **
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}
    status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->writer, NULL, &cd->writer_slot);
    if (status != PJ_SUCCESS) {
    pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
    pjmedia_port_destroy(cd->writer);
    }

    pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->writer_slot, 0);

    /* wav player */
    status = pjmedia_wav_player_port_create(
    cd->pool,
    "message.wav",
    media_cfg.audio_frame_ptime,
    0,
    0,
    &cd->player //yes this should be a pjmedia_port **
    );
    if (status != PJ_SUCCESS) {pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);}

    status = pjmedia_conf_add_port(cd->conf, cd->pool, cd->player, NULL, &cd->player_slot);
    if (status != PJ_SUCCESS) {
    pjsua_perror(THIS_FILE, "STATUS ERROR: ", status);
    pjmedia_port_destroy(cd->player);
    }

    pjmedia_conf_connect_port(cd->conf, cd->player_slot, cd->call_slot, 0);

    //uncomment to loop back remote audio (also doesn't work)
    //pjmedia_conf_connect_port(cd->conf, cd->call_slot, cd->call_slot, 0);
    }


    static void call_media_deinit(pjsua_call_id call_id){
    log_message("RUNNING... call_media_deinit\n");
    struct call_data *cd;

    cd = (struct call_data*) pjsua_call_get_user_data(call_id);
    if (!cd)
    return;

    pjmedia_master_port_stop(cd->m);
    pjmedia_master_port_destroy(cd->m, PJ_FALSE);

    pjmedia_conf_destroy(cd->conf);
    pjmedia_port_destroy(cd->null);
    pjmedia_port_destroy(cd->writer);

    log_message("Called call_media_deinit.\n");

    pjsua_call_set_user_data(call_id, NULL);
    }
    1 change: 1 addition & 0 deletions link_to_relevant_pjsip_faq.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    https://trac.pjsip.org/repos/wiki/FAQ#pjsua-lib-perf
    172 changes: 172 additions & 0 deletions log.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,172 @@
    09:59:05.474 os_core_unix.c !pjlib 2.5.5 for POSIX initialized
    09:59:05.490 sip_endpoint.c .Creating endpoint instance...
    09:59:05.516 pjlib .select() I/O Queue created (0x26aaae0)
    09:59:05.517 sip_endpoint.c .Module "mod-msg-print" registered
    09:59:05.517 sip_transport. .Transport manager created.
    09:59:05.517 pjsua_core.c .PJSUA state changed: NULL --> CREATED
    09:59:05.517 sip_endpoint.c .Module "mod-pjsua-log" registered
    09:59:05.517 sip_endpoint.c .Module "mod-tsx-layer" registered
    09:59:05.517 sip_endpoint.c .Module "mod-stateful-util" registered
    09:59:05.517 sip_endpoint.c .Module "mod-ua" registered
    09:59:05.517 sip_endpoint.c .Module "mod-100rel" registered
    09:59:05.517 sip_endpoint.c .Module "mod-pjsua" registered
    09:59:05.528 sip_endpoint.c .Module "mod-invite" registered
    09:59:05.528 pjlib ..select() I/O Queue created (0x26b6a78)
    09:59:05.531 sip_endpoint.c .Module "mod-evsub" registered
    09:59:05.531 sip_endpoint.c .Module "mod-presence" registered
    09:59:05.531 sip_endpoint.c .Module "mod-mwi" registered
    09:59:05.531 sip_endpoint.c .Module "mod-refer" registered
    09:59:05.531 sip_endpoint.c .Module "mod-pjsua-pres" registered
    09:59:05.531 sip_endpoint.c .Module "mod-pjsua-im" registered
    09:59:05.531 sip_endpoint.c .Module "mod-pjsua-options" registered
    09:59:05.531 pjsua_core.c .1 SIP worker threads created
    09:59:05.531 pjsua_core.c .pjsua version 2.5.5 for Linux-4.4.20/x86_64/glibc-2.19 initialized
    09:59:05.531 pjsua_core.c .PJSUA state changed: CREATED --> INIT
    09:59:05.532 pjsua_core.c SIP UDP socket reachable at 172.XX.X.X:5060
    09:59:05.532 udp0x26c52b0 SIP UDP transport started, published address is 172.XX.X.X:5060
    09:59:05.532 pjsua_core.c PJSUA state changed: INIT --> STARTING
    09:59:05.532 sip_endpoint.c .Module "mod-unsolicited-mwi" registered
    09:59:05.533 pjsua_core.c .PJSUA state changed: STARTING --> RUNNING
    09:59:05.533 pjsua_acc.c Adding account: id=sip:[email protected]
    09:59:05.533 pjsua_acc.c .Account sip:[email protected] added with id 0
    09:59:05.533 pjsua_call.c Making call with acc #0 to sip:[email protected]
    09:59:05.533 pjsua_media.c .Call 0: initializing media..
    09:59:05.533 pjsua_media.c ..RTP socket reachable at 172.XX.X.X:4000
    09:59:05.533 pjsua_media.c ..RTCP socket reachable at 172.XX.X.X:4001
    09:59:05.533 pjsua_media.c ..Media index 0 selected for audio call 0
    09:59:05.562 pjsua_core.c ....TX 918 bytes Request msg INVITE/cseq=16428 (tdta0x26d0b60) to UDP 54.XXX.XX.X:5060:
    INVITE sip:[email protected] SIP/2.0
    Via: SIP/2.0/UDP 172.XX.X.X:5060;rport;branch=z9hG4bKPj2741734a-4b02-4331-871b-cb41d745aa8e
    Max-Forwards: 70
    From: sip:[email protected];tag=75982d61-bd17-4567-8d20-af80f715ac2e
    To: sip:[email protected]
    Contact: <sip:[email protected]:5060;ob>
    Call-ID: cad2b1f2-08a4-43b9-adfa-63a7af1250b3
    CSeq: 16428 INVITE
    Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
    Supported: replaces, 100rel, timer, norefersub
    Session-Expires: 1800
    Min-SE: 90
    Content-Type: application/sdp
    Content-Length: 289

    v=0
    o=- 3684563945 3684563945 IN IP4 172.XX.X.X
    s=pjmedia
    b=AS:84
    t=0 0
    a=X-nat:0
    m=audio 4000 RTP/AVP 0 8 96
    c=IN IP4 172.XX.X.X
    b=TIAS:64000
    a=rtcp:4001 IN IP4 172.XX.X.X
    a=sendrecv
    a=rtpmap:0 PCMU/8000
    a=rtpmap:8 PCMA/8000
    a=rtpmap:96 telephone-event/8000
    a=fmtp:96 0-16

    --end msg--
    09:59:05.565 APP .......Call 0 state=CALLING
    09:59:05.572 wav_writer.c .......File writer 'testingtesting.wav' created: samp.rate=16000, bufsize=4KB
    09:59:05.572 conference.c .......Port 0 (Master/sound) transmitting to port 1 (testingtesting.wav)
    09:59:05.579 wav_player.c .......File player 'message.wav' created: samp.rate=16000, ch=1, bufsize=4KB, filesize=56KB
    09:59:05.579 conference.c .......Port 2 (message.wav) transmitting to port 0 (Master/sound)
    Press 'h' to hangup all calls, 'q' to quit
    09:59:05.990 pjsua_core.c .RX 374 bytes Response msg 100/INVITE/cseq=16428 (rdata0x26c6d38) from UDP 54.XXX.XX.X:5060:
    SIP/2.0 100 Giving a try
    Via: SIP/2.0/UDP 172.XX.X.X:5060;received=82.X.XX.XXX;rport=57477;branch=z9hG4bKPj2741734a-4b02-4331-871b-cb41d745aa8e
    From: sip:[email protected];tag=75982d61-bd17-4567-8d20-af80f715ac2e
    To: sip:[email protected]
    Call-ID: cad2b1f2-08a4-43b9-adfa-63a7af1250b3
    CSeq: 16428 INVITE
    Server: Twilio Gateway
    Content-Length: 0


    --end msg--
    09:59:10.230 pjsua_core.c .RX 945 bytes Response msg 183/INVITE/cseq=16428 (rdata0x7fb4b8000908) from UDP 54.XXX.XX.X:5060:
    SIP/2.0 183 Session progress
    CSeq: 16428 INVITE
    Call-ID: cad2b1f2-08a4-43b9-adfa-63a7af1250b3
    From: <sip:[email protected]>;tag=75982d61-bd17-4567-8d20-af80f715ac2e
    To: <sip:[email protected]>;tag=96764593_6772d868_ea2d552b-fe2b-4932-90e9-c559976ed365
    Via: SIP/2.0/UDP 172.XX.X.X:5060;received=82.X.XX.XXX;rport=57477;branch=z9hG4bKPj2741734a-4b02-4331-871b-cb41d745aa8e
    Record-Route: <sip:54.XXX.XX.X:5060;lr;ftag=75982d61-bd17-4567-8d20-af80f715ac2e;twnat=sip:82.X.XX.XXX:57477>
    Server: Twilio
    Contact: <sip:172.XX.X.XXX:5060>
    Content-Type: application/sdp
    X-Twilio-CallSid: CA5f210920c6XXXXXXaa4e4bcf5fXXXXXX
    Content-Length: 280

    v=0
    o=- 863029107 863029107 IN IP4 54.XXX.XX.XXX
    s=Twilio Media Gateway
    c=IN IP4 54.XXX.XX.XXX
    t=0 0
    m=audio 10060 RTP/AVP 0 96
    a=rtpmap:0 PCMU/8000
    a=rtpmap:96 telephone-event/8000
    a=fmtp:96 0-15
    a=maxptime:20
    a=ptime:20
    a=sendrecv
    a=rtcp:10061 IN IP4 54.XXX.XX.XXX

    --end msg--
    09:59:10.230 APP .....Call 0 state=EARLY
    09:59:10.230 pjsua_media.c .....Call 0: updating media..
    09:59:10.230 pjsua_aud.c ......Audio channel update..
    09:59:10.230 strm0x7fb4b800 .......VAD temporarily disabled
    09:59:10.232 strm0x7fb4b800 .......Encoder stream started
    09:59:10.233 strm0x7fb4b800 .......Decoder stream started
    09:59:10.233 pjsua_media.c ......Audio updated, stream #0: PCMU (sendrecv)
    09:59:10.867 strm0x7fb4b800 !VAD re-enabled
    09:59:12.876 pjsua_core.c .RX 623 bytes Response msg 180/INVITE/cseq=16428 (rdata0x7fb4b8000908) from UDP 54.XXX.XX.X:5060:
    SIP/2.0 180 Ringing
    CSeq: 16428 INVITE
    Call-ID: cad2b1f2-08a4-43b9-adfa-63a7af1250b3
    From: <sip:[email protected]>;tag=75982d61-bd17-4567-8d20-af80f715ac2e
    To: <sip:[email protected]>;tag=96764593_6772d868_ea2d552b-fe2b-4932-90e9-c559976ed365
    Via: SIP/2.0/UDP 172.XX.X.X:5060;received=82.X.XX.XXX;rport=57477;branch=z9hG4bKPj2741734a-4b02-4331-871b-cb41d745aa8e
    Record-Route: <sip:54.XXX.XX.X:5060;lr;ftag=75982d61-bd17-4567-8d20-af80f715ac2e;twnat=sip:82.X.XX.XXX:57477>
    Server: Twilio
    Contact: <sip:172.XX.X.XXX:5060>
    X-Twilio-CallSid: CA5f210920c6XXXXXXaa4e4bcf5fXXXXXX
    Content-Length: 0


    --end msg--
    09:59:12.876 APP .....Call 0 state=EARLY
    09:59:14.227 pjsua_core.c .RX 931 bytes Response msg 200/INVITE/cseq=16428 (rdata0x7fb4b8000908) from UDP 54.XXX.XX.X:5060:
    SIP/2.0 200 OK
    CSeq: 16428 INVITE
    Call-ID: cad2b1f2-08a4-43b9-adfa-63a7af1250b3
    From: <sip:[email protected]>;tag=75982d61-bd17-4567-8d20-af80f715ac2e
    To: <sip:[email protected]>;tag=96764593_6772d868_ea2d552b-fe2b-4932-90e9-c559976ed365
    Via: SIP/2.0/UDP 172.XX.X.X:5060;received=82.X.XX.XXX;rport=57477;branch=z9hG4bKPj2741734a-4b02-4331-871b-cb41d745aa8e
    Record-Route: <sip:54.XXX.XX.X:5060;lr;ftag=75982d61-bd17-4567-8d20-af80f715ac2e;twnat=sip:82.X.XX.XXX:57477>
    Server: Twilio
    Contact: <sip:172.XX.X.XXX:5060>
    Content-Type: application/sdp
    X-Twilio-CallSid: CA5f210920c6XXXXXXaa4e4bcf5fXXXXXX
    Content-Length: 280

    v=0
    o=- 950195842 950195842 IN IP4 54.XXX.XX.XXX
    s=Twilio Media Gateway
    c=IN IP4 54.XXX.XX.XXX
    t=0 0
    m=audio 10060 RTP/AVP 0 96
    a=rtpmap:0 PCMU/8000
    a=rtpmap:96 telephone-event/8000
    a=fmtp:96 0-15
    a=maxptime:20
    a=ptime:20
    a=sendrecv
    a=rtcp:10061 IN IP4 54.XXX.XX.XXX

    --end msg--
    09:59:14.227 APP .....Call 0 state=CONNECTING
    09:59:14.227 inv0x26c9548 ....SDP negotiation done, message body is ignored
    09:59:14.228 pjsua_core.c .....TX 511 bytes Request msg ACK/cseq=16428 (tdta0x7fb4b8009db0
    19 changes: 19 additions & 0 deletions output_to_screen.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    ./myapp sip:[email protected] >> log.txt
    WARNING: no real random source present!
    RUNNING... on_call_state
    Call state is CALLING.
    RUNNING... call_media_init
    RUNNING... on_call_state
    RUNNING... on_stream_created
    RUNNING... on_call_media_state
    Media state is ACTIVE.
    RUNNING... on_call_state
    RUNNING... on_call_state
    RUNNING... on_call_state
    Call state is CONFIRMED.
    RUNNING... on_call_state
    Call state is DISCONNECTED.
    RUNNING... call_media_deinit
    Called call_media_deinit.
    RUNNING... on_stream_destroyed
    ^C