📄 sip_xfer.c
字号:
refer_to_uri = &xfer->refer_to_uri; } else { pj_strdup(xfer->dlg->pool, &xfer->refer_to_uri, refer_to_uri); } /* Create and add Refer-To header. */ hdr = pjsip_generic_string_hdr_create(tdata->pool, &refer_to, refer_to_uri); if (!hdr) { pjsip_tx_data_dec_ref(tdata); status = PJ_ENOMEM; goto on_return; } pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); /* Done. */ *p_tdata = tdata; status = PJ_SUCCESS;on_return: pjsip_dlg_dec_lock(xfer->dlg); return status;}/* * Accept the incoming REFER request by sending 2xx response. * */PJ_DEF(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub, pjsip_rx_data *rdata, int st_code, const pjsip_hdr *hdr_list ){ /* * Don't need to add custom headers, so just call basic * evsub response. */ return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );}/* * For notifier, create NOTIFY request to subscriber, and set the state * of the subscription. */PJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub, pjsip_evsub_state state, int xfer_st_code, const pj_str_t *xfer_st_text, pjsip_tx_data **p_tdata){ pjsip_tx_data *tdata; pjsip_xfer *xfer; const pj_str_t reason = { "noresource", 10 }; char *body; int bodylen; pjsip_msg_body *msg_body; pj_status_t status; /* Check arguments. */ PJ_ASSERT_RETURN(sub, PJ_EINVAL); /* Get the xfer object. */ xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION); /* Lock object. */ pjsip_dlg_inc_lock(xfer->dlg); /* Create the NOTIFY request. * Note that reason is only used when state is TERMINATED, and * the defined termination reason for REFER is "noresource". */ status = pjsip_evsub_notify( sub, state, NULL, &reason, &tdata); if (status != PJ_SUCCESS) goto on_return; /* Check status text */ if (xfer_st_text==NULL || xfer_st_text->slen==0) xfer_st_text = pjsip_get_status_text(xfer_st_code); /* Save st_code and st_text, for current_notify() */ xfer->last_st_code = xfer_st_code; pj_strdup(xfer->dlg->pool, &xfer->last_st_text, xfer_st_text); /* Create sipfrag content. */ body = pj_pool_alloc(tdata->pool, 128); bodylen = pj_ansi_snprintf(body, 128, "SIP/2.0 %u %.*s", xfer_st_code, (int)xfer_st_text->slen, xfer_st_text->ptr); PJ_ASSERT_ON_FAIL(bodylen > 0 && bodylen < 128, {status=PJ_EBUG; pjsip_tx_data_dec_ref(tdata); goto on_return; }); /* Create SIP message body. */ msg_body = pj_pool_zalloc(tdata->pool, sizeof(pjsip_msg_body)); msg_body->content_type.type = STR_MESSAGE; msg_body->content_type.subtype = STR_SIPFRAG; msg_body->content_type.param = STR_SIPFRAG_VERSION; msg_body->data = body; msg_body->len = bodylen; msg_body->print_body = &pjsip_print_text_body; msg_body->clone_data = &pjsip_clone_text_data; /* Attach sipfrag body. */ tdata->msg->body = msg_body; /* Done. */ *p_tdata = tdata;on_return: pjsip_dlg_dec_lock(xfer->dlg); return status;}/* * Send current state and the last sipfrag body. */PJ_DEF(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub, pjsip_tx_data **p_tdata ){ pjsip_xfer *xfer; pj_status_t status; /* Check arguments. */ PJ_ASSERT_RETURN(sub, PJ_EINVAL); /* Get the xfer object. */ xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION); pjsip_dlg_inc_lock(xfer->dlg); status = pjsip_xfer_notify(sub, pjsip_evsub_get_state(sub), xfer->last_st_code, &xfer->last_st_text, p_tdata); pjsip_dlg_dec_lock(xfer->dlg); return status;}/* * Send request message. */PJ_DEF(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub, pjsip_tx_data *tdata){ return pjsip_evsub_send_request(sub, tdata);}/* * This callback is called by event subscription when subscription * state has changed. */static void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_evsub_state) (*xfer->user_cb.on_evsub_state)(sub, event);}/* * Called when transaction state has changed. */static void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_tsx_state) (*xfer->user_cb.on_tsx_state)(sub, tsx, event);}/* * Called when REFER is received to refresh subscription. */static void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_rx_refresh) { (*xfer->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text, res_hdr, p_body); } else { /* Implementors MUST send NOTIFY if it implements on_rx_refresh * (implementor == "us" from evsub point of view. */ pjsip_tx_data *tdata; pj_status_t status; if (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) { status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_TERMINATED, xfer->last_st_code, &xfer->last_st_text, &tdata); } else { status = pjsip_xfer_current_notify(sub, &tdata); } if (status == PJ_SUCCESS) pjsip_xfer_send_request(sub, tdata); }}/* * Called when NOTIFY is received. */static void xfer_on_evsub_rx_notify( pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_rx_notify) (*xfer->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text, res_hdr, p_body);}/* * Called when it's time to send SUBSCRIBE. */static void xfer_on_evsub_client_refresh(pjsip_evsub *sub){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_client_refresh) { (*xfer->user_cb.on_client_refresh)(sub); } else { pj_status_t status; pjsip_tx_data *tdata; status = pjsip_xfer_initiate(sub, NULL, &tdata); if (status == PJ_SUCCESS) pjsip_xfer_send_request(sub, tdata); }}/* * Called when no refresh is received after the interval. */static void xfer_on_evsub_server_timeout(pjsip_evsub *sub){ pjsip_xfer *xfer; xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id); PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;}); if (xfer->user_cb.on_server_timeout) { (*xfer->user_cb.on_server_timeout)(sub); } else { pj_status_t status; pjsip_tx_data *tdata; status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED, xfer->last_st_code, &xfer->last_st_text, &tdata); if (status == PJ_SUCCESS) pjsip_xfer_send_request(sub, tdata); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -