📄 publishc.c
字号:
while (route != &pubc->route_set) { pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, route); pj_list_insert_after(route_pos, new_hdr); route_pos = new_hdr; route = route->next; } } /* Add Event header */ hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_EVENT, &pubc->event); if (hdr) pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); /* Add SIP-If-Match if we have etag */ if (pubc->etag.slen) { const pj_str_t STR_HNAME = { "SIP-If-Match", 12 }; hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_HNAME, &pubc->etag); if (hdr) pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); } /* Done. */ *p_tdata = tdata; return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc, pj_bool_t auto_refresh, pjsip_tx_data **p_tdata){ pj_status_t status; pjsip_tx_data *tdata; PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); status = create_request(pubc, &tdata); if (status != PJ_SUCCESS) return status; /* Add Expires header */ if (pubc->expires_hdr) { pjsip_hdr *dup; dup = pjsip_hdr_shallow_clone(tdata->pool, pubc->expires_hdr); if (dup) pjsip_msg_add_hdr(tdata->msg, dup); } /* Cancel existing timer */ if (pubc->timer.id != 0) { pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); pubc->timer.id = 0; } pubc->auto_refresh = auto_refresh; /* Done */ *p_tdata = tdata; return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc, pjsip_tx_data **p_tdata){ pjsip_tx_data *tdata; pjsip_msg *msg; pjsip_expires_hdr *expires; pj_status_t status; PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); if (pubc->timer.id != 0) { pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); pubc->timer.id = 0; } status = create_request(pubc, &tdata); if (status != PJ_SUCCESS) return status; msg = tdata->msg; /* Add Expires:0 header */ expires = pjsip_expires_hdr_create(tdata->pool, 0); pjsip_msg_add_hdr( msg, (pjsip_hdr*)expires); *p_tdata = tdata; return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_publishc_update_expires( pjsip_publishc *pubc, pj_uint32_t expires ){ PJ_ASSERT_RETURN(pubc, PJ_EINVAL); set_expires( pubc, expires ); return PJ_SUCCESS;}static void call_callback(pjsip_publishc *pubc, pj_status_t status, int st_code, const pj_str_t *reason, pjsip_rx_data *rdata, pj_int32_t expiration){ struct pjsip_publishc_cbparam cbparam; cbparam.pubc = pubc; cbparam.token = pubc->token; cbparam.status = status; cbparam.code = st_code; cbparam.reason = *reason; cbparam.rdata = rdata; cbparam.expiration = expiration; (*pubc->cb)(&cbparam);}static void pubc_refresh_timer_cb( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry){ pjsip_publishc *pubc = entry->user_data; pjsip_tx_data *tdata; pj_status_t status; PJ_UNUSED_ARG(timer_heap); entry->id = 0; status = pjsip_publishc_publish(pubc, 1, &tdata); if (status == PJ_SUCCESS) { status = pjsip_publishc_send(pubc, tdata); } if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); call_callback(pubc, status, 400, &reason, NULL, -1); }}static void tsx_callback(void *token, pjsip_event *event){ pj_status_t status; pjsip_publishc *pubc = token; pjsip_transaction *tsx = event->body.tsx_state.tsx; /* Decrement pending transaction counter. */ pj_assert(pubc->pending_tsx > 0); --pubc->pending_tsx; /* If publication data has been deleted by user then remove publication * data from transaction's callback, and don't call callback. */ if (pubc->_delete_flag) { /* Nothing to do */ ; } else if (tsx->status_code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED || tsx->status_code == PJSIP_SC_UNAUTHORIZED) { pjsip_rx_data *rdata = event->body.tsx_state.src.rdata; pjsip_tx_data *tdata; status = pjsip_auth_clt_reinit_req( &pubc->auth_sess, rdata, tsx->last_tx, &tdata); if (status == PJ_SUCCESS) { status = pjsip_publishc_send(pubc, tdata); } if (status != PJ_SUCCESS) { call_callback(pubc, status, tsx->status_code, &rdata->msg_info.msg->line.status.reason, rdata, -1); } return; } else { pjsip_rx_data *rdata; pj_int32_t expiration = 0xFFFF; if (tsx->status_code/100 == 2) { pjsip_msg *msg; pjsip_expires_hdr *expires; pjsip_generic_string_hdr *etag_hdr; const pj_str_t STR_ETAG = { "SIP-ETag", 8 }; rdata = event->body.tsx_state.src.rdata; msg = rdata->msg_info.msg; /* Save ETag value */ etag_hdr = (pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(msg, &STR_ETAG, NULL); if (etag_hdr) { pj_strdup(pubc->pool, &pubc->etag, &etag_hdr->hvalue); } else { pubc->etag.slen = 0; } /* Update expires value */ expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL); if (expires) expiration = expires->ivalue; if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) { pj_time_val delay = { 0, 0}; delay.sec = expiration - DELAY_BEFORE_REFRESH; if (pubc->expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED && delay.sec > (pj_int32_t)pubc->expires) { delay.sec = pubc->expires; } if (delay.sec < DELAY_BEFORE_REFRESH) delay.sec = DELAY_BEFORE_REFRESH; pubc->timer.cb = &pubc_refresh_timer_cb; pubc->timer.id = REFRESH_TIMER; pubc->timer.user_data = pubc; pjsip_endpt_schedule_timer( pubc->endpt, &pubc->timer, &delay); pj_gettimeofday(&pubc->last_refresh); pubc->next_refresh = pubc->last_refresh; pubc->next_refresh.sec += delay.sec; } } else { rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ? event->body.tsx_state.src.rdata : NULL; } /* Call callback. */ if (expiration == 0xFFFF) expiration = -1; call_callback(pubc, PJ_SUCCESS, tsx->status_code, (rdata ? &rdata->msg_info.msg->line.status.reason : pjsip_get_status_text(tsx->status_code)), rdata, expiration); } /* Delete the record if user destroy pubc during the callback. */ if (pubc->_delete_flag && pubc->pending_tsx==0) { pjsip_publishc_destroy(pubc); }}PJ_DEF(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, pjsip_tx_data *tdata){ pj_status_t status; pjsip_cseq_hdr *cseq_hdr; pj_uint32_t cseq; /* Make sure we don't have pending transaction. */ if (pubc->pending_tsx) { PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another " "transaction pending")); pjsip_tx_data_dec_ref( tdata ); return PJSIP_EBUSY; } /* Invalidate message buffer. */ pjsip_tx_data_invalidate_msg(tdata); /* Increment CSeq */ cseq = ++pubc->cseq_hdr->cseq; cseq_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL); cseq_hdr->cseq = cseq; /* Increment pending transaction first, since transaction callback * may be called even before send_request() returns! */ ++pubc->pending_tsx; status = pjsip_endpt_send_request(pubc->endpt, tdata, -1, pubc, &tsx_callback); if (status!=PJ_SUCCESS) { --pubc->pending_tsx; PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status)); } return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -