📄 pjsua_im.c
字号:
pjsua_var.acc[im_data->acc_id].cred); status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, &tdata); if (status == PJ_SUCCESS) { pjsua_im_data *im_data2; /* Must duplicate im_data */ im_data2 = pjsua_im_data_dup(tdata->pool, im_data); /* Re-send request */ status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, im_data2, &im_callback); if (status == PJ_SUCCESS) { /* Done */ return; } } } if (tsx->status_code/100 == 2) { PJ_LOG(4,(THIS_FILE, "Message \'%s\' delivered successfully", im_data->body.ptr)); } else { PJ_LOG(3,(THIS_FILE, "Failed to deliver message \'%s\': %d/%.*s", im_data->body.ptr, tsx->status_code, (int)tsx->status_text.slen, tsx->status_text.ptr)); } if (pjsua_var.ua_cfg.cb.on_pager_status) pjsua_var.ua_cfg.cb.on_pager_status(im_data->call_id, &im_data->to, &im_data->body, im_data->user_data, tsx->status_code, &tsx->status_text); }}/* Outgoing typing indication callback. * (used to reauthenticate request) */static void typing_callback(void *token, pjsip_event *e){ pjsua_im_data *im_data = token; if (e->type == PJSIP_EVENT_TSX_STATE) { pjsip_transaction *tsx = e->body.tsx_state.tsx; /* Ignore provisional response, if any */ if (tsx->status_code < 200) return; /* Handle authentication challenges */ if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG && (tsx->status_code == 401 || tsx->status_code == 407)) { pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; pjsip_tx_data *tdata; pjsip_auth_clt_sess auth; pj_status_t status; PJ_LOG(4,(THIS_FILE, "Resending IM with authentication")); /* Create temporary authentication session */ pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0); pjsip_auth_clt_set_credentials(&auth, pjsua_var.acc[im_data->acc_id].cred_cnt, pjsua_var.acc[im_data->acc_id].cred); status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, &tdata); if (status == PJ_SUCCESS) { pjsua_im_data *im_data2; /* Must duplicate im_data */ im_data2 = pjsua_im_data_dup(tdata->pool, im_data); /* Re-send request */ status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, im_data2, &typing_callback); if (status == PJ_SUCCESS) { /* Done */ return; } } } }}/* * Send instant messaging outside dialog, using the specified account for * route set and authentication. */PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, const pj_str_t *to, const pj_str_t *mime_type, const pj_str_t *content, const pjsua_msg_data *msg_data, void *user_data){ pjsip_tx_data *tdata; const pj_str_t mime_text_plain = pj_str("text/plain"); const pj_str_t STR_CONTACT = { "Contact", 7 }; pjsip_media_type media_type; pjsua_im_data *im_data; pj_str_t contact; pj_status_t status; /* To and message body must be specified. */ PJ_ASSERT_RETURN(to && content, PJ_EINVAL); /* Create request. */ status = pjsip_endpt_create_request(pjsua_var.endpt, &pjsip_message_method, to, &pjsua_var.acc[acc_id].cfg.id, to, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to create request", status); return status; } /* If account is locked to specific transport, then set transport to * the request. */ if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { pjsip_tpselector tp_sel; pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); pjsip_tx_data_set_transport(tdata, &tp_sel); } /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); /* Add contact. */ status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); pjsip_tx_data_dec_ref(tdata); return status; } pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, &STR_CONTACT, &contact)); /* Create IM data to keep message details and give it back to * application on the callback */ im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); im_data->acc_id = acc_id; im_data->call_id = PJSUA_INVALID_ID; pj_strdup_with_null(tdata->pool, &im_data->to, to); pj_strdup_with_null(tdata->pool, &im_data->body, content); im_data->user_data = user_data; /* Set default media type if none is specified */ if (mime_type == NULL) { mime_type = &mime_text_plain; } /* Parse MIME type */ pjsua_parse_media_type(tdata->pool, mime_type, &media_type); /* Add message body */ tdata->msg->body = pjsip_msg_body_create( tdata->pool, &media_type.type, &media_type.subtype, &im_data->body); if (tdata->msg->body == NULL) { pjsua_perror(THIS_FILE, "Unable to create msg body", PJ_ENOMEM); pjsip_tx_data_dec_ref(tdata); return PJ_ENOMEM; } /* Add additional headers etc. */ pjsua_process_msg_data(tdata, msg_data); /* Add route set */ pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set); /* Send request (statefully) */ status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, im_data, &im_callback); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to send request", status); return status; } return PJ_SUCCESS;}/* * Send typing indication outside dialog. */PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, const pj_str_t *to, pj_bool_t is_typing, const pjsua_msg_data *msg_data){ const pj_str_t STR_CONTACT = { "Contact", 7 }; pjsua_im_data *im_data; pjsip_tx_data *tdata; pj_str_t contact; pj_status_t status; /* Create request. */ status = pjsip_endpt_create_request( pjsua_var.endpt, &pjsip_message_method, to, &pjsua_var.acc[acc_id].cfg.id, to, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to create request", status); return status; } /* If account is locked to specific transport, then set transport to * the request. */ if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { pjsip_tpselector tp_sel; pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); pjsip_tx_data_set_transport(tdata, &tp_sel); } /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); /* Add contact. */ status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); pjsip_tx_data_dec_ref(tdata); return status; } pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, &STR_CONTACT, &contact)); /* Create "application/im-iscomposing+xml" msg body. */ tdata->msg->body = pjsip_iscomposing_create_body( tdata->pool, is_typing, NULL, NULL, -1); /* Add additional headers etc. */ pjsua_process_msg_data(tdata, msg_data); /* Add route set */ pjsua_set_msg_route_set(tdata, &pjsua_var.acc[acc_id].route_set); /* Create data to reauthenticate */ im_data = pj_pool_zalloc(tdata->pool, sizeof(*im_data)); im_data->acc_id = acc_id; /* Send request (statefully) */ status = pjsip_endpt_send_request( pjsua_var.endpt, tdata, -1, im_data, &typing_callback); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to send request", status); return status; } return PJ_SUCCESS;}/* * Init pjsua IM module. */pj_status_t pjsua_im_init(void){ const pj_str_t msg_tag = { "MESSAGE", 7 }; const pj_str_t STR_MIME_TEXT_PLAIN = { "text/plain", 10 }; const pj_str_t STR_MIME_APP_ISCOMPOSING = { "application/im-iscomposing+xml", 30 }; pj_status_t status; /* Register module */ status = pjsip_endpt_register_module(pjsua_var.endpt, &mod_pjsua_im); if (status != PJ_SUCCESS) return status; /* Register support for MESSAGE method. */ pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW, NULL, 1, &msg_tag); /* Register support for "application/im-iscomposing+xml" content */ pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT, NULL, 1, &STR_MIME_APP_ISCOMPOSING); /* Register support for "text/plain" content */ pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT, NULL, 1, &STR_MIME_TEXT_PLAIN); return PJ_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -