Ignore:
Timestamp:
Jun 13, 2006 10:57:13 PM (18 years ago)
Author:
bennylp
Message:

-- REWRITE OF PJSUA API --

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c

    r492 r503  
    1818 */ 
    1919#include <pjsua-lib/pjsua.h> 
    20 #include <pj/log.h> 
    21 #include "pjsua_imp.h" 
    22  
    23 /* 
    24  * pjsua_im.c 
    25  * 
    26  * To handle incoming MESSAGE outside dialog. 
    27  * Incoming MESSAGE inside dialog is hanlded in pjsua_call.c. 
    28  */ 
    29  
    30 #define THIS_FILE   "pjsua_im.c" 
     20#include <pjsua-lib/pjsua_internal.h> 
     21 
     22 
     23#define THIS_FILE   "pjsua_im.h" 
    3124 
    3225 
     
    5043/* Proto */ 
    5144static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata); 
     45 
    5246 
    5347/* The module instance. */ 
     
    137131 *          This may trigger pjsua_ui_on_pager() or pjsua_ui_on_typing(). 
    138132 */ 
    139 void pjsua_im_process_pager(int call_index, const pj_str_t *from, 
     133void pjsua_im_process_pager(int call_id, const pj_str_t *from, 
    140134                            const pj_str_t *to, pjsip_rx_data *rdata) 
    141135{ 
     136    pjsip_contact_hdr *contact_hdr; 
     137    pj_str_t contact; 
    142138    pjsip_msg_body *body = rdata->msg_info.msg->body; 
    143139 
    144140    /* Body MUST have been checked before */ 
    145141    pj_assert(body != NULL); 
     142 
     143 
     144    /* Build remote contact */ 
     145    contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 
     146                                     NULL); 
     147    if (contact_hdr) { 
     148        contact.ptr = pj_pool_alloc(rdata->tp_info.pool,  
     149                                    PJSIP_MAX_URL_SIZE); 
     150        contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, 
     151                                       contact_hdr->uri, contact.ptr, 
     152                                       PJSIP_MAX_URL_SIZE); 
     153    } else { 
     154        contact.slen = 0; 
     155    } 
     156 
    146157 
    147158    if (pj_stricmp(&body->content_type.type, &STR_MIME_TEXT)==0 && 
    148159        pj_stricmp(&body->content_type.subtype, &STR_MIME_PLAIN)==0) 
    149160    { 
    150         pj_str_t text; 
    151  
    152         /* Build the text. */ 
    153         text.ptr = rdata->msg_info.msg->body->data; 
    154         text.slen = rdata->msg_info.msg->body->len; 
    155  
    156         if (pjsua.cb.on_pager) 
    157             (*pjsua.cb.on_pager)(call_index, from, to, &text); 
     161        const pj_str_t mime_text_plain = pj_str("text/plain"); 
     162        pj_str_t text_body; 
     163         
     164        /* Save text body */ 
     165        text_body.ptr = rdata->msg_info.msg->body->data; 
     166        text_body.slen = rdata->msg_info.msg->body->len; 
     167 
     168        if (pjsua_var.ua_cfg.cb.on_pager) { 
     169            (*pjsua_var.ua_cfg.cb.on_pager)(call_id, from, to, &contact,  
     170                                            &mime_text_plain, &text_body); 
     171        } 
    158172 
    159173    } else { 
    160  
    161174        /* Expecting typing indication */ 
    162  
    163175        pj_status_t status; 
    164176        pj_bool_t is_typing; 
     
    172184        } 
    173185 
    174         if (pjsua.cb.on_typing) 
    175             (*pjsua.cb.on_typing)(call_index, from, to, is_typing); 
     186        if (pjsua_var.ua_cfg.cb.on_typing) { 
     187            (*pjsua_var.ua_cfg.cb.on_typing)(call_id, from, to, &contact, 
     188                                             is_typing); 
     189        } 
    176190    } 
    177191 
     
    211225        pj_list_push_back(&hdr_list, accept_hdr); 
    212226 
    213         pjsip_endpt_respond_stateless(pjsua.endpt, rdata,  
     227        pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata,  
    214228                                      PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL,  
    215229                                      &hdr_list, NULL); 
     
    220234     * the UI takes too long to process the message.  
    221235     */ 
    222     status = pjsip_endpt_respond( pjsua.endpt, NULL, rdata, 200, NULL, 
     236    status = pjsip_endpt_respond( pjsua_var.endpt, NULL, rdata, 200, NULL, 
    223237                                  NULL, NULL, NULL); 
    224238 
     
    262276static void im_callback(void *token, pjsip_event *e) 
    263277{ 
    264     pj_str_t *text = token; 
     278    pjsua_im_data *im_data = token; 
    265279 
    266280    if (e->type == PJSIP_EVENT_TSX_STATE) { 
    267281 
    268282        pjsip_transaction *tsx = e->body.tsx_state.tsx; 
     283 
     284        /* Ignore provisional response, if any */ 
     285        if (tsx->status_code < 200) 
     286            return; 
     287 
     288 
     289        /* Handle authentication challenges */ 
     290        if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && 
     291            (tsx->status_code == 401 || tsx->status_code == 407))  
     292        { 
     293            pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 
     294            pjsip_tx_data *tdata; 
     295            pjsip_auth_clt_sess auth; 
     296            pj_status_t status; 
     297 
     298            PJ_LOG(4,(THIS_FILE, "Resending IM with authentication")); 
     299 
     300            /* Create temporary authentication session */ 
     301            pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0); 
     302     
     303            pjsip_auth_clt_set_credentials(&auth,  
     304                pjsua_var.acc[im_data->acc_id].cred_cnt, 
     305                pjsua_var.acc[im_data->acc_id].cred); 
     306 
     307            status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 
     308                                               &tdata); 
     309            if (status == PJ_SUCCESS) { 
     310                pjsua_im_data *im_data2; 
     311 
     312                /* Must duplicate im_data */ 
     313                im_data2 = pjsua_im_data_dup(tdata->pool, im_data); 
     314 
     315                /* Re-send request */ 
     316                status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
     317                                                   im_data2, &im_callback); 
     318                if (status == PJ_SUCCESS) { 
     319                    /* Done */ 
     320                    return; 
     321                } 
     322            } 
     323        } 
    269324 
    270325        if (tsx->status_code/100 == 2) { 
    271326            PJ_LOG(4,(THIS_FILE,  
    272327                      "Message \'%s\' delivered successfully", 
    273                       text->ptr)); 
     328                      im_data->body.ptr)); 
    274329        } else { 
    275330            PJ_LOG(3,(THIS_FILE,  
    276                       "Failed to deliver message \'%s\': %s [st_code=%d]", 
    277                       text->ptr, 
    278                       pjsip_get_status_text(tsx->status_code)->ptr, 
    279                       tsx->status_code)); 
     331                      "Failed to deliver message \'%s\': %d/%.*s", 
     332                      im_data->body.ptr, 
     333                      tsx->status_code, 
     334                      (int)tsx->status_text.slen, 
     335                      tsx->status_text.ptr)); 
    280336        } 
    281     } 
    282 } 
    283  
    284  
    285 /** 
    286  * Send IM outside dialog. 
    287  */ 
    288 PJ_DEF(pj_status_t) pjsua_im_send(int acc_index, const pj_str_t *dst_uri,  
    289                                   const pj_str_t *str) 
     337 
     338        if (pjsua_var.ua_cfg.cb.on_pager_status) 
     339            pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id,  
     340                                                &im_data->to, 
     341                                                &im_data->body, 
     342                                                im_data->user_data, 
     343                                                tsx->status_code, 
     344                                                &tsx->status_text); 
     345    } 
     346} 
     347 
     348 
     349/* Outgoing typing indication callback.  
     350 * (used to reauthenticate request) 
     351 */ 
     352static void typing_callback(void *token, pjsip_event *e) 
     353{ 
     354    pjsua_im_data *im_data = token; 
     355 
     356    if (e->type == PJSIP_EVENT_TSX_STATE) { 
     357 
     358        pjsip_transaction *tsx = e->body.tsx_state.tsx; 
     359 
     360        /* Ignore provisional response, if any */ 
     361        if (tsx->status_code < 200) 
     362            return; 
     363 
     364        /* Handle authentication challenges */ 
     365        if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && 
     366            (tsx->status_code == 401 || tsx->status_code == 407))  
     367        { 
     368            pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 
     369            pjsip_tx_data *tdata; 
     370            pjsip_auth_clt_sess auth; 
     371            pj_status_t status; 
     372 
     373            PJ_LOG(4,(THIS_FILE, "Resending IM with authentication")); 
     374 
     375            /* Create temporary authentication session */ 
     376            pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0); 
     377     
     378            pjsip_auth_clt_set_credentials(&auth,  
     379                pjsua_var.acc[im_data->acc_id].cred_cnt, 
     380                pjsua_var.acc[im_data->acc_id].cred); 
     381 
     382            status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 
     383                                               &tdata); 
     384            if (status == PJ_SUCCESS) { 
     385                pjsua_im_data *im_data2; 
     386 
     387                /* Must duplicate im_data */ 
     388                im_data2 = pjsua_im_data_dup(tdata->pool, im_data); 
     389 
     390                /* Re-send request */ 
     391                status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, 
     392                                                   im_data2, &typing_callback); 
     393                if (status == PJ_SUCCESS) { 
     394                    /* Done */ 
     395                    return; 
     396                } 
     397            } 
     398        } 
     399 
     400    } 
     401} 
     402 
     403 
     404/* 
     405 * Send instant messaging outside dialog, using the specified account for 
     406 * route set and authentication. 
     407 */ 
     408PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id,  
     409                                   const pj_str_t *to, 
     410                                   const pj_str_t *mime_type, 
     411                                   const pj_str_t *content, 
     412                                   const pjsua_msg_data *msg_data, 
     413                                   void *user_data) 
    290414{ 
    291415    pjsip_tx_data *tdata; 
     416    const pj_str_t mime_text_plain = pj_str("text/plain"); 
    292417    const pj_str_t STR_CONTACT = { "Contact", 7 }; 
    293     const pj_str_t mime_text = pj_str("text"); 
    294     const pj_str_t mime_plain = pj_str("plain"); 
    295     pj_str_t *text; 
     418    pjsip_media_type media_type; 
     419    pjsua_im_data *im_data; 
    296420    pj_status_t status; 
    297421 
     422    /* To and message body must be specified. */ 
     423    PJ_ASSERT_RETURN(to && content, PJ_EINVAL); 
     424 
    298425    /* Create request. */ 
    299     status = pjsip_endpt_create_request(pjsua.endpt, &pjsip_message_method, 
    300                                         dst_uri,  
    301                                         &pjsua.config.acc_config[acc_index].id, 
    302                                         dst_uri, NULL, NULL, -1, NULL, &tdata); 
     426    status = pjsip_endpt_create_request(pjsua_var.endpt,  
     427                                        &pjsip_message_method, to,  
     428                                        &pjsua_var.acc[acc_id].cfg.id, 
     429                                        to, NULL, NULL, -1, NULL, &tdata); 
    303430    if (status != PJ_SUCCESS) { 
    304431        pjsua_perror(THIS_FILE, "Unable to create request", status); 
     
    314441        pjsip_generic_string_hdr_create(tdata->pool,  
    315442                                        &STR_CONTACT, 
    316                                         &pjsua.config.acc_config[acc_index].contact)); 
    317  
    318     /* Duplicate text. 
    319      * We need to keep the text because we will display it when we fail to 
    320      * send the message. 
     443                                        &pjsua_var.acc[acc_id].cfg.contact)); 
     444 
     445    /* Create IM data to keep message details and give it back to 
     446     * application on the callback 
    321447     */ 
    322     text = pj_pool_alloc(tdata->pool, sizeof(pj_str_t)); 
    323     pj_strdup_with_null(tdata->pool, text, str); 
     448    im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); 
     449    im_data->acc_id = acc_id; 
     450    im_data->call_id = PJSUA_INVALID_ID; 
     451    pj_strdup_with_null(tdata->pool, &im_data->to, to); 
     452    pj_strdup_with_null(tdata->pool, &im_data->body, content); 
     453    im_data->user_data = user_data; 
     454 
     455 
     456    /* Set default media type if none is specified */ 
     457    if (mime_type == NULL) { 
     458        mime_type = &mime_text_plain; 
     459    } 
     460 
     461    /* Parse MIME type */ 
     462    pjsua_parse_media_type(tdata->pool, mime_type, &media_type); 
    324463 
    325464    /* Add message body */ 
    326     tdata->msg->body = pjsip_msg_body_create( tdata->pool, &mime_text, 
    327                                               &mime_plain, text); 
     465    tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type, 
     466                                              &media_type.subtype,  
     467                                              &im_data->body); 
    328468    if (tdata->msg->body == NULL) { 
    329469        pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM); 
     
    332472    } 
    333473 
     474    /* Add additional headers etc. */ 
     475    pjsua_process_msg_data(tdata, msg_data); 
     476 
     477    /* Add route set */ 
     478    pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set); 
     479 
    334480    /* Send request (statefully) */ 
    335     status = pjsip_endpt_send_request( pjsua.endpt, tdata, -1,  
    336                                        text, &im_callback); 
     481    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1,  
     482                                       im_data, &im_callback); 
    337483    if (status != PJ_SUCCESS) { 
    338484        pjsua_perror(THIS_FILE, "Unable to send request", status); 
     
    344490 
    345491 
    346 /** 
     492/* 
    347493 * Send typing indication outside dialog. 
    348494 */ 
    349 PJ_DEF(pj_status_t) pjsua_im_typing(int acc_index, const pj_str_t *dst_uri,  
    350                                     pj_bool_t is_typing) 
     495PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id,  
     496                                     const pj_str_t *to,  
     497                                     pj_bool_t is_typing, 
     498                                     const pjsua_msg_data *msg_data) 
    351499{ 
    352500    const pj_str_t STR_CONTACT = { "Contact", 7 }; 
     501    pjsua_im_data *im_data; 
    353502    pjsip_tx_data *tdata; 
    354503    pj_status_t status; 
    355504 
    356505    /* Create request. */ 
    357     status = pjsip_endpt_create_request( pjsua.endpt, &pjsip_message_method, 
    358                                          dst_uri,  
    359                                          &pjsua.config.acc_config[acc_index].id, 
    360                                          dst_uri, NULL, NULL, -1, NULL, &tdata); 
     506    status = pjsip_endpt_create_request( pjsua_var.endpt, &pjsip_message_method, 
     507                                         to, &pjsua_var.acc[acc_id].cfg.id, 
     508                                         to, NULL, NULL, -1, NULL, &tdata); 
    361509    if (status != PJ_SUCCESS) { 
    362510        pjsua_perror(THIS_FILE, "Unable to create request", status); 
     
    374522        pjsip_generic_string_hdr_create(tdata->pool,  
    375523                                        &STR_CONTACT, 
    376                                         &pjsua.config.acc_config[acc_index].contact)); 
     524                                        &pjsua_var.acc[acc_id].cfg.contact)); 
    377525 
    378526 
     
    381529                                                      NULL, NULL, -1); 
    382530 
     531    /* Add additional headers etc. */ 
     532    pjsua_process_msg_data(tdata, msg_data); 
     533 
     534    /* Create data to reauthenticate */ 
     535    im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); 
     536    im_data->acc_id = acc_id; 
     537 
    383538    /* Send request (statefully) */ 
    384     status = pjsip_endpt_send_request( pjsua.endpt, tdata, -1,  
    385                                        NULL, NULL); 
     539    status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1,  
     540                                       im_data, &typing_callback); 
    386541    if (status != PJ_SUCCESS) { 
    387542        pjsua_perror(THIS_FILE, "Unable to send request", status); 
     
    402557 
    403558    /* Register module */ 
    404     status = pjsip_endpt_register_module(pjsua.endpt, &mod_pjsua_im); 
     559    status = pjsip_endpt_register_module(pjsua_var.endpt, &mod_pjsua_im); 
    405560    if (status != PJ_SUCCESS) 
    406561        return status; 
    407562 
    408563    /* Register support for MESSAGE method. */ 
    409     pjsip_endpt_add_capability( pjsua.endpt, &mod_pjsua_im, PJSIP_H_ALLOW, 
     564    pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW, 
    410565                                NULL, 1, &msg_tag); 
    411566 
Note: See TracChangeset for help on using the changeset viewer.