diff --git a/include/asterisk/res_pjsip_pubsub.h b/include/asterisk/res_pjsip_pubsub.h index f6c6e4109c..d985b9019c 100644 --- a/include/asterisk/res_pjsip_pubsub.h +++ b/include/asterisk/res_pjsip_pubsub.h @@ -228,7 +228,21 @@ struct ast_sip_subscription_handler { const char *event_name; /*! The types of body this handler accepts */ const char *accept[AST_SIP_MAX_ACCEPT]; - + /*! + * \brief Indicates if this handler can be used as a default handler for an event type. + * + * Typically, a SUBSCRIBE request will contain one or more Accept headers that tell + * what format they expect the body of NOTIFY requests to use. However, every event + * package is required to define a default body format type to be used if a SUBSCRIBE + * request for the event contains no Accept header. + * + * If this value is non-zero, then this handler provides the default body format for + * the event package and can handle SUBSCRIBES with no Accept headers present. + * If this value is zero, then this handler provides an alternative body format + * from the default for the event package and cannot handle SUBSCRIBEs with no + * Accept header. + */ + unsigned int handles_default_accept; /*! * \brief Called when a subscription is to be destroyed * diff --git a/res/res_pjsip_exten_state.c b/res/res_pjsip_exten_state.c index 483d78b4b5..0144e1cbbb 100644 --- a/res/res_pjsip_exten_state.c +++ b/res/res_pjsip_exten_state.c @@ -515,6 +515,8 @@ static void subscription_terminated(struct ast_sip_subscription *sub, send_notify(exten_state_sub, NULL, PJSIP_EVSUB_STATE_TERMINATED); } +#define DEFAULT_PRESENCE_BODY "application/pidf+xml" + /*! * \internal * \brief Create and register a subscription handler. @@ -534,6 +536,9 @@ static struct ast_sip_subscription_handler *create_and_register_handler( handler->event_name = event_name; handler->accept[0] = accept; + if (!strcmp(accept, DEFAULT_PRESENCE_BODY)) { + handler->handles_default_accept = 1; + } handler->subscription_shutdown = subscription_shutdown; handler->new_subscribe = new_subscribe; diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c index faf0a07b68..e2b9b630dd 100644 --- a/res/res_pjsip_mwi.c +++ b/res/res_pjsip_mwi.c @@ -64,6 +64,7 @@ static int mwi_refresh_subscription(struct ast_sip_subscription *sub); static struct ast_sip_subscription_handler mwi_handler = { .event_name = "message-summary", .accept = { "application/simple-message-summary", }, + .handles_default_accept = 1, .subscription_shutdown = mwi_subscription_shutdown, .new_subscribe = mwi_new_subscribe, .resubscribe = mwi_resubscribe, diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index 1ccfc1972a..ae31f5c95c 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -585,6 +585,12 @@ static struct ast_sip_subscription_handler *find_sub_handler(const char *event, continue; } ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name); + if (!num_accept && iter->handles_default_accept) { + /* The SUBSCRIBE contained no Accept headers, and this subscription handler + * provides the default body type, so it's a match! + */ + break; + } for (i = 0; i < num_accept; ++i) { for (j = 0; j < num_accept; ++j) { if (ast_strlen_zero(iter->accept[i])) { @@ -620,7 +626,7 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata) struct ast_sip_subscription_handler *handler; RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup); struct ast_sip_subscription *sub; - int i; + size_t num_accept_headers; endpoint = ast_pjsip_rdata_get_endpoint(rdata); ast_assert(endpoint != NULL); @@ -646,20 +652,21 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata) pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL); return PJ_TRUE; } + ast_copy_pj_str(event, &event_header->event_type, sizeof(event)); accept_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, rdata->msg_info.msg->hdr.next); - if (!accept_header) { - ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Accept header\n"); - pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL); - return PJ_TRUE; + if (accept_header) { + int i; + + for (i = 0; i < accept_header->count; ++i) { + ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i])); + } + num_accept_headers = accept_header->count; + } else { + num_accept_headers = 0; } - ast_copy_pj_str(event, &event_header->event_type, sizeof(event)); - for (i = 0; i < accept_header->count; ++i) { - ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i])); - } - - handler = find_sub_handler(event, accept, accept_header->count); + handler = find_sub_handler(event, accept, num_accept_headers); if (!handler) { ast_log(LOG_WARNING, "No registered subscribe handler for event %s\n", event); pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);