res_pjsip_t38: Don't pass T.38 control frames through to other hooks.
[asterisk/asterisk.git] / res / res_pjsip_pubsub.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 /*!
19  * \brief Opaque structure representing an RFC 3265 SIP subscription
20  */
21
22 /*** MODULEINFO
23         <depend>pjproject</depend>
24         <depend>res_pjsip</depend>
25         <support_level>core</support_level>
26  ***/
27
28 #include "asterisk.h"
29
30 #include <pjsip.h>
31 #include <pjsip_simple.h>
32 #include <pjlib.h>
33
34 #include "asterisk/res_pjsip_pubsub.h"
35 #include "asterisk/module.h"
36 #include "asterisk/linkedlists.h"
37 #include "asterisk/astobj2.h"
38 #include "asterisk/datastore.h"
39 #include "asterisk/uuid.h"
40 #include "asterisk/taskprocessor.h"
41 #include "asterisk/sched.h"
42 #include "asterisk/res_pjsip.h"
43 #include "asterisk/callerid.h"
44 #include "asterisk/manager.h"
45 #include "res_pjsip/include/res_pjsip_private.h"
46
47 /*** DOCUMENTATION
48         <manager name="PJSIPShowSubscriptionsInbound" language="en_US">
49                 <synopsis>
50                         Lists subscriptions.
51                 </synopsis>
52                 <syntax />
53                 <description>
54                         <para>
55                         Provides a listing of all inbound subscriptions.  An event <literal>InboundSubscriptionDetail</literal>
56                         is issued for each subscription object.  Once all detail events are completed an
57                         <literal>InboundSubscriptionDetailComplete</literal> event is issued.
58                         </para>
59                 </description>
60         </manager>
61         <manager name="PJSIPShowSubscriptionsOutbound" language="en_US">
62                 <synopsis>
63                         Lists subscriptions.
64                 </synopsis>
65                 <syntax />
66                 <description>
67                         <para>
68                         Provides a listing of all outbound subscriptions.  An event <literal>OutboundSubscriptionDetail</literal>
69                         is issued for each subscription object.  Once all detail events are completed an
70                         <literal>OutboundSubscriptionDetailComplete</literal> event is issued.
71                         </para>
72                 </description>
73         </manager>
74  ***/
75
76 static pj_bool_t pubsub_on_rx_request(pjsip_rx_data *rdata);
77
78 static struct pjsip_module pubsub_module = {
79         .name = { "PubSub Module", 13 },
80         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
81         .on_rx_request = pubsub_on_rx_request,
82 };
83
84 static const pj_str_t str_event_name = { "Event", 5 };
85
86 /*! \brief Scheduler used for automatically expiring publications */
87 static struct ast_sched_context *sched;
88
89 /*! \brief Number of buckets for publications (on a per handler) */
90 #define PUBLICATIONS_BUCKETS 37
91
92 /*! \brief Default expiration time for PUBLISH if one is not specified */
93 #define DEFAULT_PUBLISH_EXPIRES 3600
94
95 /*! \brief Defined method for PUBLISH */
96 const pjsip_method pjsip_publish_method =
97 {
98         PJSIP_OTHER_METHOD,
99         { "PUBLISH", 7 }
100 };
101
102 /*!
103  * \brief The types of PUBLISH messages defined in RFC 3903
104  */
105 enum sip_publish_type {
106         /*!
107          * \brief Unknown
108          *
109          * \details
110          * This actually is not defined in RFC 3903. We use this as a constant
111          * to indicate that an incoming PUBLISH does not fit into any of the
112          * other categories and is thus invalid.
113          */
114         SIP_PUBLISH_UNKNOWN,
115
116         /*!
117          * \brief Initial
118          *
119          * \details
120          * The first PUBLISH sent. This will contain a non-zero Expires header
121          * as well as a body that indicates the current state of the endpoint
122          * that has sent the message. The initial PUBLISH is the only type
123          * of PUBLISH to not contain a Sip-If-Match header in it.
124          */
125         SIP_PUBLISH_INITIAL,
126
127         /*!
128          * \brief Refresh
129          *
130          * \details
131          * Used to keep a published state from expiring. This will contain a
132          * non-zero Expires header but no body since its purpose is not to
133          * update state.
134          */
135         SIP_PUBLISH_REFRESH,
136
137         /*!
138          * \brief Modify
139          *
140          * \details
141          * Used to change state from its previous value. This will contain
142          * a body updating the published state. May or may not contain an
143          * Expires header.
144          */
145         SIP_PUBLISH_MODIFY,
146
147         /*!
148          * \brief Remove
149          *
150          * \details
151          * Used to remove published state from an ESC. This will contain
152          * an Expires header set to 0 and likely no body.
153          */
154         SIP_PUBLISH_REMOVE,
155 };
156
157 /*!
158  * Used to create new entity IDs by ESCs.
159  */
160 static int esc_etag_counter;
161
162 /*!
163  * \brief Structure representing a SIP publication
164  */
165 struct ast_sip_publication {
166         /*! Publication datastores set up by handlers */
167         struct ao2_container *datastores;
168         /*! \brief Entity tag for the publication */
169         int entity_tag;
170         /*! \brief Handler for this publication */
171         struct ast_sip_publish_handler *handler;
172         /*! \brief The endpoint with which the subscription is communicating */
173         struct ast_sip_endpoint *endpoint;
174         /*! \brief Expiration time of the publication */
175         int expires;
176         /*! \brief Scheduled item for expiration of publication */
177         int sched_id;
178 };
179
180 /*!
181  * \brief Structure representing a SIP subscription
182  */
183 struct ast_sip_subscription {
184         /*! Subscription datastores set up by handlers */
185         struct ao2_container *datastores;
186         /*! The endpoint with which the subscription is communicating */
187         struct ast_sip_endpoint *endpoint;
188         /*! Serializer on which to place operations for this subscription */
189         struct ast_taskprocessor *serializer;
190         /*! The handler for this subscription */
191         const struct ast_sip_subscription_handler *handler;
192         /*! The role for this subscription */
193         enum ast_sip_subscription_role role;
194         /*! The underlying PJSIP event subscription structure */
195         pjsip_evsub *evsub;
196         /*! The underlying PJSIP dialog */
197         pjsip_dialog *dlg;
198         /*! Next item in the list */
199         AST_LIST_ENTRY(ast_sip_subscription) next;
200 };
201
202 static const char *sip_subscription_roles_map[] = {
203         [AST_SIP_SUBSCRIBER] = "Subscriber",
204         [AST_SIP_NOTIFIER] = "Notifier"
205 };
206
207 AST_RWLIST_HEAD_STATIC(subscriptions, ast_sip_subscription);
208
209 static void add_subscription(struct ast_sip_subscription *obj)
210 {
211         SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
212         AST_RWLIST_INSERT_TAIL(&subscriptions, obj, next);
213         ast_module_ref(ast_module_info->self);
214 }
215
216 static void remove_subscription(struct ast_sip_subscription *obj)
217 {
218         struct ast_sip_subscription *i;
219         SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
220         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&subscriptions, i, next) {
221                 if (i == obj) {
222                         AST_RWLIST_REMOVE_CURRENT(next);
223                         ast_module_unref(ast_module_info->self);
224                         break;
225                 }
226         }
227         AST_RWLIST_TRAVERSE_SAFE_END;
228 }
229
230 typedef int (*on_subscription_t)(struct ast_sip_subscription *sub, void *arg);
231
232 static int for_each_subscription(on_subscription_t on_subscription, void *arg)
233 {
234         int num = 0;
235         struct ast_sip_subscription *i;
236         SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
237
238         if (!on_subscription) {
239                 return num;
240         }
241
242         AST_RWLIST_TRAVERSE(&subscriptions, i, next) {
243                 if (on_subscription(i, arg)) {
244                         break;
245                 }
246                 ++num;
247         }
248         return num;
249 }
250
251 static void sip_subscription_to_ami(struct ast_sip_subscription *sub,
252                                     struct ast_str **buf)
253 {
254         char str[256];
255         struct ast_sip_endpoint_id_configuration *id = &sub->endpoint->id;
256
257         ast_str_append(buf, 0, "Role: %s\r\n",
258                        sip_subscription_roles_map[sub->role]);
259         ast_str_append(buf, 0, "Endpoint: %s\r\n",
260                        ast_sorcery_object_get_id(sub->endpoint));
261
262         ast_copy_pj_str(str, &sub->dlg->call_id->id, sizeof(str));
263         ast_str_append(buf, 0, "Callid: %s\r\n", str);
264
265         ast_str_append(buf, 0, "State: %s\r\n", pjsip_evsub_get_state_name(
266                                ast_sip_subscription_get_evsub(sub)));
267
268         ast_callerid_merge(str, sizeof(str),
269                            S_COR(id->self.name.valid, id->self.name.str, NULL),
270                            S_COR(id->self.number.valid, id->self.number.str, NULL),
271                            "Unknown");
272
273         ast_str_append(buf, 0, "Callerid: %s\r\n", str);
274
275         if (sub->handler->to_ami) {
276                 sub->handler->to_ami(sub, buf);
277         }
278 }
279
280 #define DATASTORE_BUCKETS 53
281
282 #define DEFAULT_EXPIRES 3600
283
284 static int datastore_hash(const void *obj, int flags)
285 {
286         const struct ast_datastore *datastore = obj;
287         const char *uid = flags & OBJ_KEY ? obj : datastore->uid;
288
289         ast_assert(uid != NULL);
290
291         return ast_str_hash(uid);
292 }
293
294 static int datastore_cmp(void *obj, void *arg, int flags)
295 {
296         const struct ast_datastore *datastore1 = obj;
297         const struct ast_datastore *datastore2 = arg;
298         const char *uid2 = flags & OBJ_KEY ? arg : datastore2->uid;
299
300         ast_assert(datastore1->uid != NULL);
301         ast_assert(uid2 != NULL);
302
303         return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
304 }
305
306 static void subscription_destructor(void *obj)
307 {
308         struct ast_sip_subscription *sub = obj;
309
310         ast_debug(3, "Destroying SIP subscription\n");
311         remove_subscription(sub);
312
313         ao2_cleanup(sub->datastores);
314         ao2_cleanup(sub->endpoint);
315
316         if (sub->dlg) {
317                 /* This is why we keep the dialog on the subscription. When the subscription
318                  * is destroyed, there is no guarantee that the underlying dialog is ready
319                  * to be destroyed. Furthermore, there's no guarantee in the opposite direction
320                  * either. The dialog could be destroyed before our subscription is. We fix
321                  * this problem by keeping a reference to the dialog until it is time to
322                  * destroy the subscription. We need to have the dialog available when the
323                  * subscription is destroyed so that we can guarantee that our attempt to
324                  * remove the serializer will be successful.
325                  */
326                 ast_sip_dialog_set_serializer(sub->dlg, NULL);
327                 pjsip_dlg_dec_session(sub->dlg, &pubsub_module);
328         }
329         ast_taskprocessor_unreference(sub->serializer);
330 }
331
332 static void pubsub_on_evsub_state(pjsip_evsub *sub, pjsip_event *event);
333 static void pubsub_on_tsx_state(pjsip_evsub *sub, pjsip_transaction *tsx, pjsip_event *event);
334 static void pubsub_on_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,
335                 int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
336 static void pubsub_on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,
337                 pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
338 static void pubsub_on_client_refresh(pjsip_evsub *sub);
339 static void pubsub_on_server_timeout(pjsip_evsub *sub);
340
341
342 static pjsip_evsub_user pubsub_cb = {
343         .on_evsub_state = pubsub_on_evsub_state,
344         .on_tsx_state = pubsub_on_tsx_state,
345         .on_rx_refresh = pubsub_on_rx_refresh,
346         .on_rx_notify = pubsub_on_rx_notify,
347         .on_client_refresh = pubsub_on_client_refresh,
348         .on_server_timeout = pubsub_on_server_timeout,
349 };
350
351 static pjsip_evsub *allocate_evsub(const char *event, enum ast_sip_subscription_role role,
352                 struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_dialog *dlg)
353 {
354         pjsip_evsub *evsub;
355         /* PJSIP is kind enough to have some built-in support for certain
356          * events. We need to use the correct initialization function for the
357          * built-in events
358          */
359         if (role == AST_SIP_NOTIFIER) {
360                 if (!strcmp(event, "message-summary")) {
361                         pjsip_mwi_create_uas(dlg, &pubsub_cb, rdata, &evsub);
362                 } else {
363                         pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &evsub);
364                 }
365         } else {
366                 if (!strcmp(event, "message-summary")) {
367                         pjsip_mwi_create_uac(dlg, &pubsub_cb, 0, &evsub);
368                 } else {
369                         pj_str_t pj_event;
370                         pj_cstr(&pj_event, event);
371                         pjsip_evsub_create_uac(dlg, &pubsub_cb, &pj_event, 0, &evsub);
372                 }
373         }
374         return evsub;
375 }
376
377 struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
378                 enum ast_sip_subscription_role role, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
379 {
380         struct ast_sip_subscription *sub = ao2_alloc(sizeof(*sub), subscription_destructor);
381         pjsip_dialog *dlg;
382
383         if (!sub) {
384                 return NULL;
385         }
386         sub->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp);
387         if (!sub->datastores) {
388                 ao2_ref(sub, -1);
389                 return NULL;
390         }
391         sub->serializer = ast_sip_create_serializer();
392         if (!sub->serializer) {
393                 ao2_ref(sub, -1);
394                 return NULL;
395         }
396         sub->role = role;
397         if (role == AST_SIP_NOTIFIER) {
398                 dlg = ast_sip_create_dialog_uas(endpoint, rdata);
399         } else {
400                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
401
402                 contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
403                 if (!contact || ast_strlen_zero(contact->uri)) {
404                         ast_log(LOG_WARNING, "No contacts configured for endpoint %s. Unable to create SIP subsription\n",
405                                         ast_sorcery_object_get_id(endpoint));
406                         ao2_ref(sub, -1);
407                         return NULL;
408                 }
409                 dlg = ast_sip_create_dialog_uac(endpoint, contact->uri, NULL);
410         }
411         if (!dlg) {
412                 ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
413                 ao2_ref(sub, -1);
414                 return NULL;
415         }
416         sub->evsub = allocate_evsub(handler->event_name, role, endpoint, rdata, dlg);
417         /* We keep a reference to the dialog until our subscription is destroyed. See
418          * the subscription_destructor for more details
419          */
420         pjsip_dlg_inc_session(dlg, &pubsub_module);
421         sub->dlg = dlg;
422         ast_sip_dialog_set_serializer(dlg, sub->serializer);
423         pjsip_evsub_set_mod_data(sub->evsub, pubsub_module.id, sub);
424         ao2_ref(endpoint, +1);
425         sub->endpoint = endpoint;
426         sub->handler = handler;
427
428         add_subscription(sub);
429         return sub;
430 }
431
432 struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub)
433 {
434         ast_assert(sub->endpoint != NULL);
435         ao2_ref(sub->endpoint, +1);
436         return sub->endpoint;
437 }
438
439 struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub)
440 {
441         ast_assert(sub->serializer != NULL);
442         return sub->serializer;
443 }
444
445 pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub)
446 {
447         return sub->evsub;
448 }
449
450 pjsip_dialog *ast_sip_subscription_get_dlg(struct ast_sip_subscription *sub)
451 {
452         return sub->dlg;
453 }
454
455 int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata)
456 {
457         return pjsip_evsub_send_request(ast_sip_subscription_get_evsub(sub),
458                         tdata) == PJ_SUCCESS ? 0 : -1;
459 }
460
461 static void subscription_datastore_destroy(void *obj)
462 {
463         struct ast_datastore *datastore = obj;
464
465         /* Using the destroy function (if present) destroy the data */
466         if (datastore->info->destroy != NULL && datastore->data != NULL) {
467                 datastore->info->destroy(datastore->data);
468                 datastore->data = NULL;
469         }
470
471         ast_free((void *) datastore->uid);
472         datastore->uid = NULL;
473 }
474
475 struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
476 {
477         RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
478         const char *uid_ptr = uid;
479
480         if (!info) {
481                 return NULL;
482         }
483
484         datastore = ao2_alloc(sizeof(*datastore), subscription_datastore_destroy);
485         if (!datastore) {
486                 return NULL;
487         }
488
489         datastore->info = info;
490         if (ast_strlen_zero(uid)) {
491                 /* They didn't provide an ID so we'll provide one ourself */
492                 struct ast_uuid *uuid = ast_uuid_generate();
493                 char uuid_buf[AST_UUID_STR_LEN];
494                 if (!uuid) {
495                         return NULL;
496                 }
497                 uid_ptr = ast_uuid_to_str(uuid, uuid_buf, sizeof(uuid_buf));
498                 ast_free(uuid);
499         }
500
501         datastore->uid = ast_strdup(uid_ptr);
502         if (!datastore->uid) {
503                 return NULL;
504         }
505
506         ao2_ref(datastore, +1);
507         return datastore;
508 }
509
510 int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore)
511 {
512         ast_assert(datastore != NULL);
513         ast_assert(datastore->info != NULL);
514         ast_assert(!ast_strlen_zero(datastore->uid));
515
516         if (!ao2_link(subscription->datastores, datastore)) {
517                 return -1;
518         }
519         return 0;
520 }
521
522 struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name)
523 {
524         return ao2_find(subscription->datastores, name, OBJ_KEY);
525 }
526
527 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name)
528 {
529         ao2_callback(subscription->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
530 }
531
532 int ast_sip_publication_add_datastore(struct ast_sip_publication *publication, struct ast_datastore *datastore)
533 {
534         ast_assert(datastore != NULL);
535         ast_assert(datastore->info != NULL);
536         ast_assert(!ast_strlen_zero(datastore->uid));
537
538         if (!ao2_link(publication->datastores, datastore)) {
539                 return -1;
540         }
541         return 0;
542 }
543
544 struct ast_datastore *ast_sip_publication_get_datastore(struct ast_sip_publication *publication, const char *name)
545 {
546         return ao2_find(publication->datastores, name, OBJ_KEY);
547 }
548
549 void ast_sip_publication_remove_datastore(struct ast_sip_publication *publication, const char *name)
550 {
551         ao2_callback(publication->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
552 }
553
554 AST_RWLIST_HEAD_STATIC(publish_handlers, ast_sip_publish_handler);
555
556 static int publication_hash_fn(const void *obj, const int flags)
557 {
558         const struct ast_sip_publication *publication = obj;
559         const int *entity_tag = obj;
560
561         return flags & OBJ_KEY ? *entity_tag : publication->entity_tag;
562 }
563
564 static int publication_cmp_fn(void *obj, void *arg, int flags)
565 {
566         const struct ast_sip_publication *publication1 = obj;
567         const struct ast_sip_publication *publication2 = arg;
568         const int *entity_tag = arg;
569
570         return (publication1->entity_tag == (flags & OBJ_KEY ? *entity_tag : publication2->entity_tag) ?
571                 CMP_MATCH | CMP_STOP : 0);
572 }
573
574 static void publish_add_handler(struct ast_sip_publish_handler *handler)
575 {
576         SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
577         AST_RWLIST_INSERT_TAIL(&publish_handlers, handler, next);
578 }
579
580 int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler)
581 {
582         if (ast_strlen_zero(handler->event_name)) {
583                 ast_log(LOG_ERROR, "No event package specified for publish handler. Cannot register\n");
584                 return -1;
585         }
586
587         if (!(handler->publications = ao2_container_alloc(PUBLICATIONS_BUCKETS,
588                 publication_hash_fn, publication_cmp_fn))) {
589                 ast_log(LOG_ERROR, "Could not allocate publications container for event '%s'\n",
590                         handler->event_name);
591                 return -1;
592         }
593
594         publish_add_handler(handler);
595
596         ast_module_ref(ast_module_info->self);
597
598         return 0;
599 }
600
601 void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler)
602 {
603         struct ast_sip_publish_handler *iter;
604         SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
605         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&publish_handlers, iter, next) {
606                 if (handler == iter) {
607                         AST_RWLIST_REMOVE_CURRENT(next);
608                         ao2_cleanup(handler->publications);
609                         ast_module_unref(ast_module_info->self);
610                         break;
611                 }
612         }
613         AST_RWLIST_TRAVERSE_SAFE_END;
614 }
615
616 AST_RWLIST_HEAD_STATIC(subscription_handlers, ast_sip_subscription_handler);
617
618 static void sub_add_handler(struct ast_sip_subscription_handler *handler)
619 {
620         SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
621         AST_RWLIST_INSERT_TAIL(&subscription_handlers, handler, next);
622         ast_module_ref(ast_module_info->self);
623 }
624
625 static int sub_handler_exists_for_event_name(const char *event_name)
626 {
627         struct ast_sip_subscription_handler *iter;
628         SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
629
630         AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
631                 if (!strcmp(iter->event_name, event_name)) {
632                         return 1;
633                 }
634         }
635         return 0;
636 }
637
638 int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler)
639 {
640         pj_str_t accept[AST_SIP_MAX_ACCEPT];
641         int i;
642
643         if (ast_strlen_zero(handler->event_name)) {
644                 ast_log(LOG_ERROR, "No event package specifief for subscription handler. Cannot register\n");
645                 return -1;
646         }
647
648         if (ast_strlen_zero(handler->accept[0])) {
649                 ast_log(LOG_ERROR, "Subscription handler must supply at least one 'Accept' format\n");
650                 return -1;
651         }
652
653         for (i = 0; i < AST_SIP_MAX_ACCEPT && !ast_strlen_zero(handler->accept[i]); ++i) {
654                 pj_cstr(&accept[i], handler->accept[i]);
655         }
656
657         if (!sub_handler_exists_for_event_name(handler->event_name)) {
658                 pj_str_t event;
659
660                 pj_cstr(&event, handler->event_name);
661
662                 if (!strcmp(handler->event_name, "message-summary")) {
663                         pjsip_mwi_init_module(ast_sip_get_pjsip_endpoint(), pjsip_evsub_instance());
664                 } else {
665                         pjsip_evsub_register_pkg(&pubsub_module, &event, DEFAULT_EXPIRES, i, accept);
666                 }
667         } else {
668                 pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), &pubsub_module, PJSIP_H_ACCEPT, NULL,
669                         i, accept);
670         }
671
672         sub_add_handler(handler);
673         return 0;
674 }
675
676 void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler)
677 {
678         struct ast_sip_subscription_handler *iter;
679         SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
680         AST_RWLIST_TRAVERSE_SAFE_BEGIN(&subscription_handlers, iter, next) {
681                 if (handler == iter) {
682                         AST_RWLIST_REMOVE_CURRENT(next);
683                         ast_module_unref(ast_module_info->self);
684                         break;
685                 }
686         }
687         AST_RWLIST_TRAVERSE_SAFE_END;
688 }
689
690 static struct ast_sip_subscription_handler *find_sub_handler(const char *event, char accept[AST_SIP_MAX_ACCEPT][64], size_t num_accept)
691 {
692         struct ast_sip_subscription_handler *iter;
693         int match = 0;
694         SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
695         AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
696                 int i;
697                 int j;
698                 if (strcmp(event, iter->event_name)) {
699                         ast_debug(3, "Event %s does not match %s\n", event, iter->event_name);
700                         continue;
701                 }
702                 ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name);
703                 if (!num_accept && iter->handles_default_accept) {
704                         /* The SUBSCRIBE contained no Accept headers, and this subscription handler
705                          * provides the default body type, so it's a match!
706                          */
707                         break;
708                 }
709                 for (i = 0; i < num_accept; ++i) {
710                         for (j = 0; j < num_accept; ++j) {
711                                 if (ast_strlen_zero(iter->accept[i])) {
712                                         ast_debug(3, "Breaking because subscription handler has run out of 'accept' types\n");
713                                         break;
714                                 }
715                                 if (!strcmp(accept[j], iter->accept[i])) {
716                                         ast_debug(3, "Accept headers match: %s = %s\n", accept[j], iter->accept[i]);
717                                         match = 1;
718                                         break;
719                                 }
720                                 ast_debug(3, "Accept %s does not match %s\n", accept[j], iter->accept[i]);
721                         }
722                         if (match) {
723                                 break;
724                         }
725                 }
726                 if (match) {
727                         break;
728                 }
729         }
730
731         return iter;
732 }
733
734 static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
735 {
736         char event[32];
737         char accept[AST_SIP_MAX_ACCEPT][64];
738         pjsip_accept_hdr *accept_header;
739         pjsip_event_hdr *event_header;
740         pjsip_expires_hdr *expires_header;
741         struct ast_sip_subscription_handler *handler;
742         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
743         struct ast_sip_subscription *sub;
744         size_t num_accept_headers;
745
746         endpoint = ast_pjsip_rdata_get_endpoint(rdata);
747         ast_assert(endpoint != NULL);
748
749         if (!endpoint->subscription.allow) {
750                 ast_log(LOG_WARNING, "Subscriptions not permitted for endpoint %s.\n", ast_sorcery_object_get_id(endpoint));
751                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 603, NULL, NULL, NULL);
752                 return PJ_TRUE;
753         }
754
755         expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
756
757         if (expires_header && expires_header->ivalue < endpoint->subscription.minexpiry) {
758                 ast_log(LOG_WARNING, "Subscription expiration %d is too brief for endpoint %s. Minimum is %d\n",
759                                 expires_header->ivalue, ast_sorcery_object_get_id(endpoint), endpoint->subscription.minexpiry);
760                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 423, NULL, NULL, NULL);
761                 return PJ_TRUE;
762         }
763
764         event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_event_name, rdata->msg_info.msg->hdr.next);
765         if (!event_header) {
766                 ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Event header\n");
767                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
768                 return PJ_TRUE;
769         }
770         ast_copy_pj_str(event, &event_header->event_type, sizeof(event));
771
772         accept_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, rdata->msg_info.msg->hdr.next);
773         if (accept_header) {
774                 int i;
775
776                 for (i = 0; i < accept_header->count; ++i) {
777                         ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i]));
778                 }
779                 num_accept_headers = accept_header->count;
780         } else {
781                 num_accept_headers = 0;
782         }
783
784         handler = find_sub_handler(event, accept, num_accept_headers);
785         if (!handler) {
786                 ast_log(LOG_WARNING, "No registered subscribe handler for event %s\n", event);
787                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
788                 return PJ_TRUE;
789         }
790         sub = handler->new_subscribe(endpoint, rdata);
791         if (!sub) {
792                 pjsip_transaction *trans = pjsip_rdata_get_tsx(rdata);
793
794                 if (trans) {
795                         pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
796                         pjsip_tx_data *tdata;
797
798                         if (pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, &tdata) != PJ_SUCCESS) {
799                                 return PJ_TRUE;
800                         }
801                         pjsip_dlg_send_response(dlg, trans, tdata);
802                 } else {
803                         pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
804                 }
805         }
806         return PJ_TRUE;
807 }
808
809 static struct ast_sip_publish_handler *find_pub_handler(const char *event)
810 {
811         struct ast_sip_publish_handler *iter = NULL;
812         SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
813
814         AST_RWLIST_TRAVERSE(&publish_handlers, iter, next) {
815                 if (strcmp(event, iter->event_name)) {
816                         ast_debug(3, "Event %s does not match %s\n", event, iter->event_name);
817                         continue;
818                 }
819                 ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name);
820                 break;
821         }
822
823         return iter;
824 }
825
826 static enum sip_publish_type determine_sip_publish_type(pjsip_rx_data *rdata,
827         pjsip_generic_string_hdr *etag_hdr, int *expires, int *entity_id)
828 {
829         pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
830
831         if (etag_hdr) {
832                 char etag[pj_strlen(&etag_hdr->hvalue) + 1];
833
834                 ast_copy_pj_str(etag, &etag_hdr->hvalue, sizeof(etag));
835
836                 if (sscanf(etag, "%30d", entity_id) != 1) {
837                         return SIP_PUBLISH_UNKNOWN;
838                 }
839         }
840
841         *expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
842
843         if (!(*expires)) {
844                 return SIP_PUBLISH_REMOVE;
845         } else if (!etag_hdr && rdata->msg_info.msg->body) {
846                 return SIP_PUBLISH_INITIAL;
847         } else if (etag_hdr && !rdata->msg_info.msg->body) {
848                 return SIP_PUBLISH_REFRESH;
849         } else if (etag_hdr && rdata->msg_info.msg->body) {
850                 return SIP_PUBLISH_MODIFY;
851         }
852
853         return SIP_PUBLISH_UNKNOWN;
854 }
855
856 static struct ast_sip_publication *publish_request_initial(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata,
857         struct ast_sip_publish_handler *handler)
858 {
859         struct ast_sip_publication *publication = handler->new_publication(endpoint, rdata);
860
861         if (!publication) {
862                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 503, NULL, NULL, NULL);
863                 return NULL;
864         }
865
866         publication->handler = handler;
867
868         return publication;
869 }
870
871 static int publish_expire_callback(void *data)
872 {
873         RAII_VAR(struct ast_sip_publication *, publication, data, ao2_cleanup);
874
875         publication->handler->publish_expire(publication);
876
877         return 0;
878 }
879
880 static int publish_expire(const void *data)
881 {
882         struct ast_sip_publication *publication = (struct ast_sip_publication*)data;
883
884         ao2_unlink(publication->handler->publications, publication);
885         publication->sched_id = -1;
886
887         if (ast_sip_push_task(NULL, publish_expire_callback, publication)) {
888                 ao2_cleanup(publication);
889         }
890
891         return 0;
892 }
893
894 static pj_bool_t pubsub_on_rx_publish_request(pjsip_rx_data *rdata)
895 {
896         pjsip_event_hdr *event_header;
897         struct ast_sip_publish_handler *handler;
898         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
899         char event[32];
900         static const pj_str_t str_sip_if_match = { "SIP-If-Match", 12 };
901         pjsip_generic_string_hdr *etag_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_sip_if_match, NULL);
902         enum sip_publish_type publish_type;
903         RAII_VAR(struct ast_sip_publication *, publication, NULL, ao2_cleanup);
904         int expires = 0, entity_id;
905
906         endpoint = ast_pjsip_rdata_get_endpoint(rdata);
907         ast_assert(endpoint != NULL);
908
909         event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_event_name, rdata->msg_info.msg->hdr.next);
910         if (!event_header) {
911                 ast_log(LOG_WARNING, "Incoming PUBLISH request with no Event header\n");
912                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
913                 return PJ_TRUE;
914         }
915         ast_copy_pj_str(event, &event_header->event_type, sizeof(event));
916
917         handler = find_pub_handler(event);
918         if (!handler) {
919                 ast_log(LOG_WARNING, "No registered publish handler for event %s\n", event);
920                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
921                 return PJ_TRUE;
922         }
923
924         publish_type = determine_sip_publish_type(rdata, etag_hdr, &expires, &entity_id);
925
926         /* If this is not an initial publish ensure that a publication is present */
927         if ((publish_type != SIP_PUBLISH_INITIAL) && (publish_type != SIP_PUBLISH_UNKNOWN)) {
928                 if (!(publication = ao2_find(handler->publications, &entity_id, OBJ_KEY | OBJ_UNLINK))) {
929                         static const pj_str_t str_conditional_request_failed = { "Conditional Request Failed", 26 };
930
931                         pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 412, &str_conditional_request_failed,
932                                 NULL, NULL);
933                         return PJ_TRUE;
934                 }
935
936                 /* Per the RFC every response has to have a new entity tag */
937                 publication->entity_tag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
938
939                 /* Update the expires here so that the created responses will contain the correct value */
940                 publication->expires = expires;
941         }
942
943         switch (publish_type) {
944                 case SIP_PUBLISH_INITIAL:
945                         publication = publish_request_initial(endpoint, rdata, handler);
946                         break;
947                 case SIP_PUBLISH_REFRESH:
948                 case SIP_PUBLISH_MODIFY:
949                         if (handler->publish_refresh(publication, rdata)) {
950                                 /* If an error occurs we want to terminate the publication */
951                                 expires = 0;
952                         }
953                         break;
954                 case SIP_PUBLISH_REMOVE:
955                         handler->publish_termination(publication, rdata);
956                         break;
957                 case SIP_PUBLISH_UNKNOWN:
958                 default:
959                         pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL);
960                         break;
961         }
962
963         if (publication) {
964                 if (expires) {
965                         ao2_link(handler->publications, publication);
966
967                         AST_SCHED_REPLACE_UNREF(publication->sched_id, sched, expires * 1000, publish_expire, publication,
968                                                 ao2_ref(publication, -1), ao2_ref(publication, -1), ao2_ref(publication, +1));
969                 } else {
970                         AST_SCHED_DEL_UNREF(sched, publication->sched_id, ao2_ref(publication, -1));
971                 }
972         }
973
974         return PJ_TRUE;
975 }
976
977 /*! \brief Internal destructor for publications */
978 static void publication_destroy_fn(void *obj)
979 {
980         struct ast_sip_publication *publication = obj;
981
982         ast_debug(3, "Destroying SIP publication\n");
983
984         ao2_cleanup(publication->datastores);
985         ao2_cleanup(publication->endpoint);
986 }
987
988 struct ast_sip_publication *ast_sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
989 {
990         struct ast_sip_publication *publication;
991         pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
992
993         ast_assert(endpoint != NULL);
994
995         if (!(publication = ao2_alloc(sizeof(*publication), publication_destroy_fn))) {
996                 return NULL;
997         }
998
999         if (!(publication->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp))) {
1000                 ao2_ref(publication, -1);
1001                 return NULL;
1002         }
1003
1004         publication->entity_tag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
1005         ao2_ref(endpoint, +1);
1006         publication->endpoint = endpoint;
1007         publication->expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
1008         publication->sched_id = -1;
1009
1010         return publication;
1011 }
1012
1013 struct ast_sip_endpoint *ast_sip_publication_get_endpoint(struct ast_sip_publication *pub)
1014 {
1015         return pub->endpoint;
1016 }
1017
1018 int ast_sip_publication_create_response(struct ast_sip_publication *pub, int status_code, pjsip_rx_data *rdata,
1019         pjsip_tx_data **tdata)
1020 {
1021         if (pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, status_code, NULL, tdata) != PJ_SUCCESS) {
1022                 return -1;
1023         }
1024
1025         if (PJSIP_IS_STATUS_IN_CLASS(status_code, 200)) {
1026                 RAII_VAR(char *, entity_tag, NULL, ast_free_ptr);
1027                 RAII_VAR(char *, expires, NULL, ast_free_ptr);
1028
1029                 if ((ast_asprintf(&entity_tag, "%d", pub->entity_tag) < 0) ||
1030                         (ast_asprintf(&expires, "%d", pub->expires) < 0)) {
1031                         pjsip_tx_data_dec_ref(*tdata);
1032                         return -1;
1033                 }
1034
1035                 ast_sip_add_header(*tdata, "SIP-ETag", entity_tag);
1036                 ast_sip_add_header(*tdata, "Expires", expires);
1037         }
1038
1039         return 0;
1040 }
1041
1042 pj_status_t ast_sip_publication_send_response(struct ast_sip_publication *pub, pjsip_rx_data *rdata,
1043         pjsip_tx_data *tdata)
1044 {
1045         pj_status_t status;
1046         pjsip_transaction *tsx;
1047
1048         if ((status = pjsip_tsx_create_uas(&pubsub_module, rdata, &tsx)) != PJ_SUCCESS) {
1049                 return status;
1050         }
1051
1052         pjsip_tsx_recv_msg(tsx, rdata);
1053
1054         return pjsip_tsx_send_msg(tsx, tdata);
1055 }
1056
1057 static pj_bool_t pubsub_on_rx_request(pjsip_rx_data *rdata)
1058 {
1059         if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method())) {
1060                 return pubsub_on_rx_subscribe_request(rdata);
1061         } else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_publish_method)) {
1062                 return pubsub_on_rx_publish_request(rdata);
1063         }
1064
1065         return PJ_FALSE;
1066 }
1067
1068 static void pubsub_on_evsub_state(pjsip_evsub *evsub, pjsip_event *event)
1069 {
1070         struct ast_sip_subscription *sub;
1071         if (pjsip_evsub_get_state(evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
1072                 return;
1073         }
1074
1075         sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1076         if (!sub) {
1077                 return;
1078         }
1079
1080         if (sub->handler->subscription_shutdown) {
1081                 sub->handler->subscription_shutdown(sub);
1082         }
1083         pjsip_evsub_set_mod_data(evsub, pubsub_module.id, NULL);
1084 }
1085
1086 static void pubsub_on_tsx_state(pjsip_evsub *evsub, pjsip_transaction *tsx, pjsip_event *event)
1087 {
1088         struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1089
1090         if (!sub) {
1091                 return;
1092         }
1093
1094         if (sub->handler->notify_response && tsx->role == PJSIP_ROLE_UAC &&
1095             event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {
1096                 sub->handler->notify_response(sub, event->body.tsx_state.src.rdata);
1097         }
1098 }
1099
1100 static void set_parameters_from_response_data(pj_pool_t *pool, int *p_st_code,
1101                 pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body,
1102                 struct ast_sip_subscription_response_data *response_data)
1103 {
1104         ast_assert(response_data->status_code >= 200 && response_data->status_code <= 699);
1105         *p_st_code = response_data->status_code;
1106
1107         if (!ast_strlen_zero(response_data->status_text)) {
1108                 pj_strdup2(pool, *p_st_text, response_data->status_text);
1109         }
1110
1111         if (response_data->headers) {
1112                 struct ast_variable *iter;
1113                 for (iter = response_data->headers; iter; iter = iter->next) {
1114                         pj_str_t header_name;
1115                         pj_str_t header_value;
1116                         pjsip_generic_string_hdr *hdr;
1117
1118                         pj_cstr(&header_name, iter->name);
1119                         pj_cstr(&header_value, iter->value);
1120                         hdr = pjsip_generic_string_hdr_create(pool, &header_name, &header_value);
1121                         pj_list_insert_before(res_hdr, hdr);
1122                 }
1123         }
1124
1125         if (response_data->body) {
1126                 pj_str_t type;
1127                 pj_str_t subtype;
1128                 pj_str_t body_text;
1129
1130                 pj_cstr(&type, response_data->body->type);
1131                 pj_cstr(&subtype, response_data->body->subtype);
1132                 pj_cstr(&body_text, response_data->body->body_text);
1133
1134                 *p_body = pjsip_msg_body_create(pool, &type, &subtype, &body_text);
1135         }
1136 }
1137
1138 static int response_data_changed(struct ast_sip_subscription_response_data *response_data)
1139 {
1140         if (response_data->status_code != 200 ||
1141                         !ast_strlen_zero(response_data->status_text) ||
1142                         response_data->headers ||
1143                         response_data->body) {
1144                 return 1;
1145         }
1146         return 0;
1147 }
1148
1149 static void pubsub_on_rx_refresh(pjsip_evsub *evsub, pjsip_rx_data *rdata,
1150                 int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
1151 {
1152         struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1153         struct ast_sip_subscription_response_data response_data = {
1154                 .status_code = 200,
1155         };
1156
1157         if (!sub) {
1158                 return;
1159         }
1160
1161         if (pjsip_evsub_get_state(sub->evsub) == PJSIP_EVSUB_STATE_TERMINATED) {
1162                 sub->handler->subscription_terminated(sub, rdata);
1163                 return;
1164         }
1165
1166         sub->handler->resubscribe(sub, rdata, &response_data);
1167
1168         if (!response_data_changed(&response_data)) {
1169                 return;
1170         }
1171
1172         set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
1173                         res_hdr, p_body, &response_data);
1174 }
1175
1176 static void pubsub_on_rx_notify(pjsip_evsub *evsub, pjsip_rx_data *rdata, int *p_st_code,
1177                 pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
1178 {
1179         struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1180         struct ast_sip_subscription_response_data response_data = {
1181                 .status_code = 200,
1182         };
1183
1184         if (!sub || !sub->handler->notify_request) {
1185                 return;
1186         }
1187
1188         sub->handler->notify_request(sub, rdata, &response_data);
1189
1190         if (!response_data_changed(&response_data)) {
1191                 return;
1192         }
1193
1194         set_parameters_from_response_data(rdata->tp_info.pool, p_st_code, p_st_text,
1195                         res_hdr, p_body, &response_data);
1196 }
1197
1198 static int serialized_pubsub_on_client_refresh(void *userdata)
1199 {
1200         struct ast_sip_subscription *sub = userdata;
1201
1202         sub->handler->refresh_subscription(sub);
1203         ao2_cleanup(sub);
1204         return 0;
1205 }
1206
1207 static void pubsub_on_client_refresh(pjsip_evsub *evsub)
1208 {
1209         struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1210
1211         ao2_ref(sub, +1);
1212         ast_sip_push_task(sub->serializer, serialized_pubsub_on_client_refresh, sub);
1213 }
1214
1215 static int serialized_pubsub_on_server_timeout(void *userdata)
1216 {
1217         struct ast_sip_subscription *sub = userdata;
1218
1219         sub->handler->subscription_timeout(sub);
1220         ao2_cleanup(sub);
1221         return 0;
1222 }
1223
1224 static void pubsub_on_server_timeout(pjsip_evsub *evsub)
1225 {
1226         struct ast_sip_subscription *sub = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);
1227
1228         ao2_ref(sub, +1);
1229         ast_sip_push_task(sub->serializer, serialized_pubsub_on_server_timeout, sub);
1230 }
1231
1232 static int ami_subscription_detail(struct ast_sip_subscription *sub,
1233                                    struct ast_sip_ami *ami,
1234                                    const char *event)
1235 {
1236         RAII_VAR(struct ast_str *, buf,
1237                  ast_sip_create_ami_event(event, ami), ast_free);
1238
1239         if (!buf) {
1240                 return -1;
1241         }
1242
1243         sip_subscription_to_ami(sub, &buf);
1244         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1245         return 0;
1246 }
1247
1248 static int ami_subscription_detail_inbound(struct ast_sip_subscription *sub, void *arg)
1249 {
1250         return sub->role == AST_SIP_NOTIFIER ? ami_subscription_detail(
1251                 sub, arg, "InboundSubscriptionDetail") : 0;
1252 }
1253
1254 static int ami_subscription_detail_outbound(struct ast_sip_subscription *sub, void *arg)
1255 {
1256         return sub->role == AST_SIP_SUBSCRIBER ? ami_subscription_detail(
1257                 sub, arg, "OutboundSubscriptionDetail") : 0;
1258 }
1259
1260 static int ami_show_subscriptions_inbound(struct mansession *s, const struct message *m)
1261 {
1262         struct ast_sip_ami ami = { .s = s, .m = m };
1263         int num;
1264
1265         astman_send_listack(s, m, "Following are Events for "
1266                             "each inbound Subscription", "start");
1267
1268         num = for_each_subscription(ami_subscription_detail_inbound, &ami);
1269
1270         astman_append(s,
1271                       "Event: InboundSubscriptionDetailComplete\r\n"
1272                       "EventList: Complete\r\n"
1273                       "ListItems: %d\r\n\r\n", num);
1274         return 0;
1275 }
1276
1277 static int ami_show_subscriptions_outbound(struct mansession *s, const struct message *m)
1278 {
1279         struct ast_sip_ami ami = { .s = s, .m = m };
1280         int num;
1281
1282         astman_send_listack(s, m, "Following are Events for "
1283                             "each outbound Subscription", "start");
1284
1285         num = for_each_subscription(ami_subscription_detail_outbound, &ami);
1286
1287         astman_append(s,
1288                       "Event: OutboundSubscriptionDetailComplete\r\n"
1289                       "EventList: Complete\r\n"
1290                       "ListItems: %d\r\n\r\n", num);
1291         return 0;
1292 }
1293
1294 #define AMI_SHOW_SUBSCRIPTIONS_INBOUND "PJSIPShowSubscriptionsInbound"
1295 #define AMI_SHOW_SUBSCRIPTIONS_OUTBOUND "PJSIPShowSubscriptionsOutbound"
1296
1297 static int load_module(void)
1298 {
1299         static const pj_str_t str_PUBLISH = { "PUBLISH", 7 };
1300
1301         pjsip_evsub_init_module(ast_sip_get_pjsip_endpoint());
1302
1303         if (!(sched = ast_sched_context_create())) {
1304                 ast_log(LOG_ERROR, "Could not create scheduler for publication expiration\n");
1305                 return AST_MODULE_LOAD_FAILURE;
1306         }
1307
1308         if (ast_sched_start_thread(sched)) {
1309                 ast_log(LOG_ERROR, "Could not start scheduler thread for publication expiration\n");
1310                 ast_sched_context_destroy(sched);
1311                 return AST_MODULE_LOAD_FAILURE;
1312         }
1313
1314         pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &str_PUBLISH);
1315
1316         if (ast_sip_register_service(&pubsub_module)) {
1317                 ast_log(LOG_ERROR, "Could not register pubsub service\n");
1318                 ast_sched_context_destroy(sched);
1319                 return AST_MODULE_LOAD_FAILURE;
1320         }
1321
1322         ast_manager_register_xml(AMI_SHOW_SUBSCRIPTIONS_INBOUND, EVENT_FLAG_SYSTEM,
1323                                  ami_show_subscriptions_inbound);
1324         ast_manager_register_xml(AMI_SHOW_SUBSCRIPTIONS_OUTBOUND, EVENT_FLAG_SYSTEM,
1325                                  ami_show_subscriptions_outbound);
1326
1327         return AST_MODULE_LOAD_SUCCESS;
1328 }
1329
1330 static int unload_module(void)
1331 {
1332         ast_manager_unregister(AMI_SHOW_SUBSCRIPTIONS_OUTBOUND);
1333         ast_manager_unregister(AMI_SHOW_SUBSCRIPTIONS_INBOUND);
1334
1335         if (sched) {
1336                 ast_sched_context_destroy(sched);
1337         }
1338
1339         return 0;
1340 }
1341
1342 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJSIP event resource",
1343                 .load = load_module,
1344                 .unload = unload_module,
1345                 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
1346 );