[asterisk-commits] mmichelson: branch mmichelson/pub_sub r385117 - in /team/mmichelson/pub_sub: ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 9 13:28:03 CDT 2013
Author: mmichelson
Date: Tue Apr 9 13:27:59 2013
New Revision: 385117
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385117
Log:
Fill in callbacks with non-stub code.
With this, it should be possible to write a subscription handler and actually
have it work properly.
Modified:
team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h
team/mmichelson/pub_sub/res/res_sip_pubsub.c
Modified: team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h?view=diff&rev=385117&r1=385116&r2=385117
==============================================================================
--- team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h (original)
+++ team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h Tue Apr 9 13:27:59 2013
@@ -61,7 +61,7 @@
* during this callback. This callback is useful for performing any
* necessary cleanup
*/
- void (*subscription_shutdown)(struct ast_sip_subscription *subscription);
+ void (*subscription_shutdown)(struct ast_sip_subscription *subscription);
/*!
* \brief Called when a SUBSCRIBE arrives in order to create a new subscription
@@ -89,7 +89,8 @@
* This is a notifier callback.
*
* Because of the way that the PJSIP evsub framework works, it will automatically
- * send a response to the SUBSCRIBE.
+ * send a response to the SUBSCRIBE. However, the subscription handler must send
+ * a NOTIFY with the current subscription state when this callback is called.
*
* \param sub The subscription that is being renewed
* \param rdata The SUBSCRIBE request in question
@@ -112,16 +113,16 @@
void (*subscription_timeout)(struct ast_sip_subscription *sub);
/*!
- * \brief Called when a subscription is terminated via a SUBSCRIBE request
- *
- * This is a notifier callback.
+ * \brief Called when a subscription is terminated via a SUBSCRIBE or NOTIFY request
+ *
+ * This is a notifier and subscriber callback.
*
* The PJSIP subscription framework will automatically send the response to the
- * SUBSCRIBE. The subscription handler is expected to send a final NOTIFY to
- * terminate the subscription.
+ * request. If a notifier receives this callback, then the subscription handler
+ * is expected to send a final NOTIFY to terminate the subscription.
*
* \param sub The subscription being terminated
- * \param rdata The SUBSCRIBE request that terminated the subscription
+ * \param rdata The request that terminated the subscription
*/
void (*subscription_terminated)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
Modified: team/mmichelson/pub_sub/res/res_sip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/res/res_sip_pubsub.c?view=diff&rev=385117&r1=385116&r2=385117
==============================================================================
--- team/mmichelson/pub_sub/res/res_sip_pubsub.c (original)
+++ team/mmichelson/pub_sub/res/res_sip_pubsub.c Tue Apr 9 13:27:59 2013
@@ -155,6 +155,7 @@
return NULL;
}
sub->evsub = allocate_evsub(handler->event_name, role, endpoint, rdata);
+ pjsip_evsub_set_mod_data(sub->evsub, sub_module.id, sub);
ao2_ref(endpoint, +1);
sub->endpoint = endpoint;
sub->handler = handler;
@@ -364,36 +365,137 @@
return PJ_TRUE;
}
-static void pubsub_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
-{
- /* XXX STUB */
-}
-
-static void pubsub_on_tsx_state(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event)
-{
- /* XXX STUB */
-}
-
-static void pubsub_on_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,
+static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
+{
+ struct ast_sip_subscription *sub;
+ if (pjsip_evsub_get_state(evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
+ return;
+ }
+
+ sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+ if (!sub) {
+ return;
+ }
+
+ if (event->type == PJSIP_EVENT_RX_MSG) {
+ sub->handler->subscription_terminated(sub, event->body.rx_msg.rdata);
+ }
+
+ if (event->type == PJSIP_EVENT_TSX_STATE &&
+ event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+ sub->handler->subscription_terminated(sub, event->body.tsx_state.src.rdata);
+ }
+
+ if (sub->handler->subscription_shutdown) {
+ sub->handler->subscription_shutdown(sub);
+ }
+ pjsip_evsub_set_mod_data(evsub, sub_module.id, NULL);
+ ao2_ref(sub, -1);
+}
+
+static void pubsub_on_tsx_state(pjsip_evsub *evsub, pjsip_transaction *tsx, pjsip_event *event)
+{
+ struct ast_sip_subscription *sub= pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+ if (!sub) {
+ return;
+ }
+
+ if (tsx->role == PJSIP_ROLE_UAC && event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
+ sub->handler->notify_response(sub, event->body.tsx_state.src.rdata);
+ }
+}
+
+static void set_parameters_from_response_data(pj_pool_t *pool, int *p_st_code,
+ pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body,
+ struct ast_sip_subscription_response_data *response_data)
+{
+ ast_assert(response_data->status_code >= 200 && response_data->status_code <= 699);
+ *p_st_code = response_data->status_code;
+
+ if (!ast_strlen_zero(response_data->status_text)) {
+ pj_strdup2(pool, *p_st_text, response_data->status_text);
+ }
+
+ if (response_data->headers) {
+ struct ast_variable *iter;
+ for (iter = response_data->headers; iter; iter = iter->next) {
+ pj_str_t header_name;
+ pj_str_t header_value;
+ pjsip_generic_string_hdr *hdr;
+
+ pj_cstr(&header_name, iter->name);
+ pj_cstr(&header_value, iter->value);
+ hdr = pjsip_generic_string_hdr_create(pool, &header_name, &header_value);
+ pj_list_insert_before(res_hdr, hdr);
+ }
+ }
+
+ if (response_data->body) {
+ pj_str_t type;
+ pj_str_t subtype;
+ pj_str_t body_text;
+
+ pj_cstr(&type, response_data->body->type);
+ pj_cstr(&subtype, response_data->body->subtype);
+ pj_cstr(&body_text, response_data->body->body_text);
+
+ *p_body = pjsip_msg_body_create(pool, &type, &subtype, &body_text);
+ }
+}
+
+static void pubsub_on_rx_refresh(pjsip_evsub *evsub, pjsip_rx_data *rdata,
int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
{
- /* XXX STUB */
-}
-
-static void pubsub_on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,
+ struct ast_sip_subscription *sub= pjsip_evsub_get_mod_data(evsub, sub_module.id);
+ struct ast_sip_subscription_response_data *response_data;
+
+ if (!sub) {
+ return;
+ }
+
+ response_data = sub->handler->resubscribe(sub, rdata);
+
+ if (!response_data) {
+ return;
+ }
+
+ set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
+ res_hdr, p_body, response_data);
+}
+
+static void pubsub_on_rx_notify(pjsip_evsub *evsub, pjsip_rx_data *rdata, int *p_st_code,
pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
{
- /* XXX STUB */
-}
-
-static void pubsub_on_client_refresh(pjsip_evsub *sub)
-{
- /* XXX STUB */
-}
-
-static void pubsub_on_server_timeout(pjsip_evsub *sub)
-{
- /* XXX STUB */
+ struct ast_sip_subscription *sub= pjsip_evsub_get_mod_data(evsub, sub_module.id);
+ struct ast_sip_subscription_response_data *response_data;
+
+ if (!sub|| !sub->handler->notify_request) {
+ return;
+ }
+
+ response_data = sub->handler->notify_request(sub, rdata);
+
+ if (!response_data) {
+ return;
+ }
+
+ set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
+ res_hdr, p_body, response_data);
+}
+
+static void pubsub_on_client_refresh(pjsip_evsub *evsub)
+{
+ struct ast_sip_subscription *sub= pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+ sub->handler->refresh_subscription(sub);
+}
+
+static void pubsub_on_server_timeout(pjsip_evsub *evsub)
+{
+ struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, sub_module.id);
+
+ sub->handler->subscription_timeout(sub);
}
static int load_module(void)
More information about the asterisk-commits
mailing list