⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nua_publish.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 2 页
字号:
int nua_stack_publish(nua_t *nua,		     nua_handle_t *nh,		     nua_event_t e,		     tagi_t const *tags){  return nua_client_create(nh, e, &nua_publish_client_methods, tags);}static int nua_publish_client_template(nua_client_request_t *cr,				       msg_t **return_msg,				       tagi_t const *tags){  nua_dialog_usage_t *du;  if (cr->cr_event == nua_r_publish)    return 0;  du = nua_dialog_usage_get(cr->cr_owner->nh_ds, nua_publish_usage, NULL);  if (du && du->du_cr) {    if (nua_client_set_target(cr, du->du_cr->cr_target) < 0)      return -1;    *return_msg = msg_copy(du->du_cr->cr_msg);    return 1;  }  return 0;}static int nua_publish_client_init(nua_client_request_t *cr,				   msg_t *msg, sip_t *sip,				   tagi_t const *tags){  nua_handle_t *nh = cr->cr_owner;  nua_dialog_usage_t *du;  struct publish_usage *pu;  if (cr->cr_event == nua_r_publish) {    du = nua_dialog_usage_add(nh, nh->nh_ds, nua_publish_usage, NULL);    if (!du)      return -1;    pu = nua_dialog_usage_private(du);    pu->pu_published = 0;    if (sip->sip_if_match) {      pu->pu_etag = sip_etag_dup(nh->nh_home, sip->sip_if_match);      if (!pu->pu_etag)	return -1;      sip_header_remove(msg, sip, (sip_header_t *)sip->sip_if_match);    }  }  else    du = nua_dialog_usage_get(nh->nh_ds, nua_publish_usage, NULL);  cr->cr_usage = du;  return 0;}staticint nua_publish_client_request(nua_client_request_t *cr,			       msg_t *msg, sip_t *sip,			       tagi_t const *tags){  nua_dialog_usage_t *du = cr->cr_usage;  int un, done;  sip_etag_t const *etag = NULL;  un = cr->cr_terminating ||    cr->cr_event != nua_r_publish ||    (du && du->du_shutdown) ||    (sip->sip_expires && sip->sip_expires->ex_delta == 0);  cr->cr_terminating = un;  done = un;  if (du) {    struct publish_usage *pu = nua_dialog_usage_private(du);    if (nua_client_bind(cr, du) < 0)      return -1;    if (pu->pu_published)      done = 1;    etag = pu->pu_etag;  }  return nua_base_client_trequest(cr, msg, sip,				  SIPTAG_IF_MATCH(etag),				  TAG_IF(done, SIPTAG_PAYLOAD(NONE)),				  TAG_IF(done, SIPTAG_CONTENT_TYPE(NONE)),				  TAG_IF(un, SIPTAG_EXPIRES_STR("0")),				  TAG_NEXT(tags));}static int nua_publish_client_check_restart(nua_client_request_t *cr,					    int status, char const *phrase,					    sip_t const *sip){  char const *restarting = NULL;  if (cr->cr_terminating || !cr->cr_usage)    ;  else if (status == 412)    restarting = phrase;  else if (200 <= status && status < 300 && 	   sip->sip_expires && sip->sip_expires->ex_delta == 0)    restarting = "Immediate re-PUBLISH";  if (restarting) {    struct publish_usage *pu = nua_dialog_usage_private(cr->cr_usage);    if (pu) {      pu->pu_published = 0;      su_free(cr->cr_owner->nh_home, pu->pu_etag), pu->pu_etag = NULL;      if (nua_client_restart(cr, 100, restarting))	return 0;    }  }  return nua_base_client_check_restart(cr, status, phrase, sip);}static int nua_publish_client_response(nua_client_request_t *cr,				       int status, char const *phrase,				       sip_t const *sip){  nua_handle_t *nh = cr->cr_owner;  nua_dialog_usage_t *du = cr->cr_usage;  if (!cr->cr_terminated && du && sip) {    struct publish_usage *pu = nua_dialog_usage_private(du);    sip_expires_t const *ex = sip->sip_expires;    /* Reset state */    pu->pu_published = 0;    if (pu->pu_etag)      su_free(nh->nh_home, pu->pu_etag), pu->pu_etag = NULL;    if (status < 300) {      pu->pu_published = 1;      pu->pu_etag = sip_etag_dup(nh->nh_home, sip->sip_etag);      if (!ex || ex->ex_delta == 0 || !pu->pu_etag) {	cr->cr_terminated = 1;	if (!ex || ex->ex_delta == 0)	  SET_STATUS(900, "Received Invalid Expiration Time");	else	  SET_STATUS1(NUA_ERROR_AT(__FILE__, __LINE__));      }      else	nua_dialog_usage_set_refresh(du, ex->ex_delta);    }  }  return nua_base_client_response(cr, status, phrase, sip, NULL);}static void nua_publish_usage_refresh(nua_handle_t *nh,				     nua_dialog_state_t *ds,				     nua_dialog_usage_t *du,				     sip_time_t now){  nua_client_request_t *cr = du->du_cr;  if (cr) {    if (nua_client_resend_request(cr, 0) >= 0)      return;  }  nua_stack_event(nh->nh_nua, nh, NULL,		  nua_r_publish, NUA_ERROR_AT(__FILE__, __LINE__),		  NULL);  nua_dialog_usage_remove(nh, ds, du, NULL, NULL);}/** @interal Shut down PUBLISH usage. * * @retval >0  shutdown done * @retval 0   shutdown in progress * @retval <0  try again later */static int nua_publish_usage_shutdown(nua_handle_t *nh,				     nua_dialog_state_t *ds,				     nua_dialog_usage_t *du){  nua_client_request_t *cr = du->du_cr;  if (cr) {    if (nua_client_resend_request(cr, 1) >= 0)      return 0;  }  /* XXX - report to user */  nua_dialog_usage_remove(nh, ds, du, NULL, NULL);  return 200;}/* ---------------------------------------------------------------------- *//* Server side *//** @NUA_EVENT nua_i_publish * * Incoming PUBLISH request. * * In order to receive #nua_i_publish events, the application must enable * both the PUBLISH method with NUTAG_ALLOW() tag and the acceptable SIP * events with nua_set_params() tag NUTAG_ALLOW_EVENTS().  * * The nua_response() call responding to a PUBLISH request must have * NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag. Note that * a successful response to PUBLISH @b MUST include @Expires and @SIPETag * headers. * * The PUBLISH request does not create a dialog. Currently the processing * of incoming PUBLISH creates a new handle for each incoming request which * is not assiciated with an existing dialog. If the handle @a nh is not * bound, you should probably destroy it after responding to the PUBLISH * request. * * @param status status code of response sent automatically by stack * @param phrase a short textual description of @a status code * @param nh     operation handle associated with the incoming request * @param hmagic application context associated with the call *               (usually NULL) * @param sip    incoming PUBLISH request * @param tags   empty * * @sa @RFC3903, nua_respond(), * @Expires, @SIPETag, @SIPIfMatch, @Event,  * nua_subscribe(), #nua_i_subscribe,  * nua_notifier(), #nua_i_subscription, * * @since First used in @VERSION_1_12_4 * * @END_NUA_EVENT */int nua_publish_server_init(nua_server_request_t *sr);nua_server_methods_t const nua_publish_server_methods =   {    SIP_METHOD_PUBLISH,    nua_i_publish,		/* Event */    {       0,			/* Do not create dialog */      0,			/* Initial request */      0,			/* Not a target refresh request  */      1,			/* Add Contact */    },    nua_publish_server_init,    nua_base_server_preprocess,    nua_base_server_params,    nua_base_server_respond,    nua_base_server_report,  };int nua_publish_server_init(nua_server_request_t *sr){  sip_allow_events_t *allow_events = NH_PGET(sr->sr_owner, allow_events);  sip_event_t *o = sr->sr_request.sip->sip_event;  char const *event = o ? o->o_type : NULL;    if (!allow_events)    return SR_STATUS1(sr, SIP_501_NOT_IMPLEMENTED);  else if (!event || !msg_header_find_param(allow_events->k_common, event))    return SR_STATUS1(sr, SIP_489_BAD_EVENT);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -