res_pjsip_mwi.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  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. /*** MODULEINFO
  19. <depend>pjproject</depend>
  20. <depend>res_pjsip</depend>
  21. <depend>res_pjsip_pubsub</depend>
  22. <support_level>core</support_level>
  23. ***/
  24. #include "asterisk.h"
  25. #include <pjsip.h>
  26. #include <pjsip_simple.h>
  27. #include <pjlib.h>
  28. #include "asterisk/res_pjsip.h"
  29. #include "asterisk/res_pjsip_pubsub.h"
  30. #include "asterisk/res_pjsip_body_generator_types.h"
  31. #include "asterisk/module.h"
  32. #include "asterisk/logger.h"
  33. #include "asterisk/astobj2.h"
  34. #include "asterisk/taskprocessor.h"
  35. #include "asterisk/sorcery.h"
  36. #include "asterisk/stasis.h"
  37. #include "asterisk/app.h"
  38. struct mwi_subscription;
  39. static struct ao2_container *unsolicited_mwi;
  40. static char *default_voicemail_extension;
  41. #define STASIS_BUCKETS 13
  42. #define MWI_BUCKETS 53
  43. #define MWI_TYPE "application"
  44. #define MWI_SUBTYPE "simple-message-summary"
  45. #define MWI_DATASTORE "MWI datastore"
  46. /*! Number of serializers in pool if one not supplied. */
  47. #define MWI_SERIALIZER_POOL_SIZE 8
  48. /*! Pool of serializers to use if not supplied. */
  49. static struct ast_taskprocessor *mwi_serializer_pool[MWI_SERIALIZER_POOL_SIZE];
  50. static void mwi_subscription_shutdown(struct ast_sip_subscription *sub);
  51. static void mwi_to_ami(struct ast_sip_subscription *sub, struct ast_str **buf);
  52. static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
  53. const char *resource);
  54. static int mwi_subscription_established(struct ast_sip_subscription *sub);
  55. static void *mwi_get_notify_data(struct ast_sip_subscription *sub);
  56. static struct ast_sip_notifier mwi_notifier = {
  57. .default_accept = MWI_TYPE"/"MWI_SUBTYPE,
  58. .new_subscribe = mwi_new_subscribe,
  59. .subscription_established = mwi_subscription_established,
  60. .get_notify_data = mwi_get_notify_data,
  61. };
  62. static struct ast_sip_subscription_handler mwi_handler = {
  63. .event_name = "message-summary",
  64. .body_type = AST_SIP_MESSAGE_ACCUMULATOR,
  65. .accept = { MWI_TYPE"/"MWI_SUBTYPE, },
  66. .subscription_shutdown = mwi_subscription_shutdown,
  67. .to_ami = mwi_to_ami,
  68. .notifier = &mwi_notifier,
  69. };
  70. /*!
  71. * \brief Wrapper for stasis subscription
  72. *
  73. * An MWI subscription has a container of these. This
  74. * represents a stasis subscription for MWI state.
  75. */
  76. struct mwi_stasis_subscription {
  77. /*! The MWI stasis subscription */
  78. struct stasis_subscription *stasis_sub;
  79. /*! The mailbox corresponding with the MWI subscription. Used as a hash key */
  80. char mailbox[1];
  81. };
  82. /*!
  83. * \brief A subscription for MWI
  84. *
  85. * This subscription is the basis for MWI for an endpoint. Each
  86. * endpoint that uses MWI will have a corresponding mwi_subscription.
  87. *
  88. * This structure acts as the owner for the underlying SIP subscription.
  89. * When the mwi_subscription is destroyed, the SIP subscription dies, too.
  90. * The mwi_subscription's lifetime is governed by its underlying stasis
  91. * subscriptions. When all stasis subscriptions are destroyed, the
  92. * mwi_subscription is destroyed as well.
  93. */
  94. struct mwi_subscription {
  95. /*! Container of \ref mwi_stasis_subscription structures.
  96. * A single MWI subscription may be for multiple mailboxes, thus
  97. * requiring multiple stasis subscriptions
  98. */
  99. struct ao2_container *stasis_subs;
  100. /*! The SIP subscription. Unsolicited MWI does not use this */
  101. struct ast_sip_subscription *sip_sub;
  102. /*! AORs we should react to for unsolicited MWI NOTIFY */
  103. char *aors;
  104. /*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */
  105. unsigned int is_solicited;
  106. /*! Identifier for the subscription.
  107. * The identifier is the same as the corresponding endpoint's stasis ID.
  108. * Used as a hash key
  109. */
  110. char id[1];
  111. };
  112. /*!
  113. * \internal
  114. * \brief Shutdown the serializers in the mwi pool.
  115. * \since 13.12.0
  116. *
  117. * \return Nothing
  118. */
  119. static void mwi_serializer_pool_shutdown(void)
  120. {
  121. int idx;
  122. for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {
  123. ast_taskprocessor_unreference(mwi_serializer_pool[idx]);
  124. mwi_serializer_pool[idx] = NULL;
  125. }
  126. }
  127. /*!
  128. * \internal
  129. * \brief Setup the serializers in the mwi pool.
  130. * \since 13.12.0
  131. *
  132. * \retval 0 on success.
  133. * \retval -1 on error.
  134. */
  135. static int mwi_serializer_pool_setup(void)
  136. {
  137. char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
  138. int idx;
  139. for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {
  140. /* Create name with seq number appended. */
  141. ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/mwi");
  142. mwi_serializer_pool[idx] = ast_sip_create_serializer_named(tps_name);
  143. if (!mwi_serializer_pool[idx]) {
  144. mwi_serializer_pool_shutdown();
  145. return -1;
  146. }
  147. }
  148. return 0;
  149. }
  150. /*!
  151. * \internal
  152. * \brief Pick a mwi serializer from the pool.
  153. * \since 13.12.0
  154. *
  155. * \retval least queue size task processor.
  156. */
  157. static struct ast_taskprocessor *get_mwi_serializer(void)
  158. {
  159. int idx;
  160. int pos;
  161. if (!mwi_serializer_pool[0]) {
  162. return NULL;
  163. }
  164. for (pos = idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {
  165. if (ast_taskprocessor_size(mwi_serializer_pool[idx]) < ast_taskprocessor_size(mwi_serializer_pool[pos])) {
  166. pos = idx;
  167. }
  168. }
  169. return mwi_serializer_pool[pos];
  170. }
  171. /*!
  172. * \internal
  173. * \brief Set taskprocessor alert levels for the serializers in the mwi pool.
  174. * \since 13.12.0
  175. *
  176. * \retval 0 on success.
  177. * \retval -1 on error.
  178. */
  179. static int mwi_serializer_set_alert_levels(void)
  180. {
  181. int idx;
  182. long tps_queue_high;
  183. long tps_queue_low;
  184. if (!mwi_serializer_pool[0]) {
  185. return -1;
  186. }
  187. tps_queue_high = ast_sip_get_mwi_tps_queue_high();
  188. if (tps_queue_high <= 0) {
  189. ast_log(AST_LOG_WARNING, "Invalid taskprocessor high water alert trigger level '%ld'\n",
  190. tps_queue_high);
  191. tps_queue_high = AST_TASKPROCESSOR_HIGH_WATER_LEVEL;
  192. }
  193. tps_queue_low = ast_sip_get_mwi_tps_queue_low();
  194. if (tps_queue_low < -1 || tps_queue_high < tps_queue_low) {
  195. ast_log(AST_LOG_WARNING, "Invalid taskprocessor low water clear alert level '%ld'\n",
  196. tps_queue_low);
  197. tps_queue_low = -1;
  198. }
  199. for (idx = 0; idx < MWI_SERIALIZER_POOL_SIZE; ++idx) {
  200. if (ast_taskprocessor_alert_set_levels(mwi_serializer_pool[idx], tps_queue_low, tps_queue_high)) {
  201. ast_log(AST_LOG_WARNING, "Failed to set alert levels for MWI serializer pool #%d.\n",
  202. idx);
  203. }
  204. }
  205. return 0;
  206. }
  207. static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
  208. struct stasis_message *msg);
  209. static struct mwi_stasis_subscription *mwi_stasis_subscription_alloc(const char *mailbox, struct mwi_subscription *mwi_sub)
  210. {
  211. struct mwi_stasis_subscription *mwi_stasis_sub;
  212. struct stasis_topic *topic;
  213. if (!mwi_sub) {
  214. return NULL;
  215. }
  216. mwi_stasis_sub = ao2_alloc(sizeof(*mwi_stasis_sub) + strlen(mailbox), NULL);
  217. if (!mwi_stasis_sub) {
  218. return NULL;
  219. }
  220. topic = ast_mwi_topic(mailbox);
  221. /* Safe strcpy */
  222. strcpy(mwi_stasis_sub->mailbox, mailbox);
  223. ast_debug(3, "Creating stasis MWI subscription to mailbox %s for endpoint %s\n",
  224. mailbox, mwi_sub->id);
  225. ao2_ref(mwi_sub, +1);
  226. mwi_stasis_sub->stasis_sub = stasis_subscribe_pool(topic, mwi_stasis_cb, mwi_sub);
  227. if (!mwi_stasis_sub->stasis_sub) {
  228. /* Failed to subscribe. */
  229. ao2_ref(mwi_stasis_sub, -1);
  230. ao2_ref(mwi_sub, -1);
  231. mwi_stasis_sub = NULL;
  232. }
  233. stasis_subscription_accept_message_type(mwi_stasis_sub->stasis_sub, ast_mwi_state_type());
  234. stasis_subscription_accept_message_type(mwi_stasis_sub->stasis_sub, stasis_subscription_change_type());
  235. stasis_subscription_set_filter(mwi_stasis_sub->stasis_sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);
  236. return mwi_stasis_sub;
  237. }
  238. static int stasis_sub_hash(const void *obj, const int flags)
  239. {
  240. const struct mwi_stasis_subscription *object;
  241. const char *key;
  242. switch (flags & OBJ_SEARCH_MASK) {
  243. case OBJ_SEARCH_KEY:
  244. key = obj;
  245. break;
  246. case OBJ_SEARCH_OBJECT:
  247. object = obj;
  248. key = object->mailbox;
  249. break;
  250. default:
  251. ast_assert(0);
  252. return 0;
  253. }
  254. return ast_str_hash(key);
  255. }
  256. static int stasis_sub_cmp(void *obj, void *arg, int flags)
  257. {
  258. const struct mwi_stasis_subscription *sub_left = obj;
  259. const struct mwi_stasis_subscription *sub_right = arg;
  260. const char *right_key = arg;
  261. int cmp;
  262. switch (flags & OBJ_SEARCH_MASK) {
  263. case OBJ_SEARCH_OBJECT:
  264. right_key = sub_right->mailbox;
  265. /* Fall through */
  266. case OBJ_SEARCH_KEY:
  267. cmp = strcmp(sub_left->mailbox, right_key);
  268. break;
  269. case OBJ_SEARCH_PARTIAL_KEY:
  270. cmp = strncmp(sub_left->mailbox, right_key, strlen(right_key));
  271. break;
  272. default:
  273. cmp = 0;
  274. break;
  275. }
  276. if (cmp) {
  277. return 0;
  278. }
  279. return CMP_MATCH;
  280. }
  281. static void mwi_subscription_destructor(void *obj)
  282. {
  283. struct mwi_subscription *sub = obj;
  284. ast_debug(3, "Destroying MWI subscription for endpoint %s\n", sub->id);
  285. if (sub->is_solicited) {
  286. ast_sip_subscription_destroy(sub->sip_sub);
  287. }
  288. ao2_cleanup(sub->stasis_subs);
  289. ast_free(sub->aors);
  290. }
  291. static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint,
  292. unsigned int is_solicited, struct ast_sip_subscription *sip_sub)
  293. {
  294. struct mwi_subscription *sub;
  295. const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
  296. sub = ao2_alloc(sizeof(*sub) + strlen(endpoint_id),
  297. mwi_subscription_destructor);
  298. if (!sub) {
  299. return NULL;
  300. }
  301. /* Safe strcpy */
  302. strcpy(sub->id, endpoint_id);
  303. /* Unsolicited MWI doesn't actually result in a SIP subscription being
  304. * created. This is because a SIP subscription associates with a dialog.
  305. * Most devices expect unsolicited MWI NOTIFYs to appear out of dialog. If
  306. * they receive an in-dialog MWI NOTIFY (i.e. with a to-tag), then they
  307. * will reject the NOTIFY with a 481, thus resulting in message-waiting
  308. * state not being updated on the device
  309. */
  310. if (is_solicited) {
  311. sub->sip_sub = sip_sub;
  312. }
  313. sub->stasis_subs = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
  314. STASIS_BUCKETS, stasis_sub_hash, NULL, stasis_sub_cmp);
  315. if (!sub->stasis_subs) {
  316. ao2_cleanup(sub);
  317. return NULL;
  318. }
  319. sub->is_solicited = is_solicited;
  320. if (!is_solicited && !ast_strlen_zero(endpoint->aors)) {
  321. sub->aors = ast_strdup(endpoint->aors);
  322. if (!sub->aors) {
  323. ao2_ref(sub, -1);
  324. return NULL;
  325. }
  326. }
  327. ast_debug(3, "Created %s MWI subscription for endpoint %s\n", is_solicited ? "solicited" : "unsolicited", sub->id);
  328. return sub;
  329. }
  330. static int mwi_sub_hash(const void *obj, const int flags)
  331. {
  332. const struct mwi_subscription *object;
  333. const char *key;
  334. switch (flags & OBJ_SEARCH_MASK) {
  335. case OBJ_SEARCH_KEY:
  336. key = obj;
  337. break;
  338. case OBJ_SEARCH_OBJECT:
  339. object = obj;
  340. key = object->id;
  341. break;
  342. default:
  343. ast_assert(0);
  344. return 0;
  345. }
  346. return ast_str_hash(key);
  347. }
  348. static int mwi_sub_cmp(void *obj, void *arg, int flags)
  349. {
  350. const struct mwi_subscription *sub_left = obj;
  351. const struct mwi_subscription *sub_right = arg;
  352. const char *right_key = arg;
  353. int cmp;
  354. switch (flags & OBJ_SEARCH_MASK) {
  355. case OBJ_SEARCH_OBJECT:
  356. right_key = sub_right->id;
  357. /* Fall through */
  358. case OBJ_SEARCH_KEY:
  359. cmp = strcmp(sub_left->id, right_key);
  360. break;
  361. case OBJ_SEARCH_PARTIAL_KEY:
  362. cmp = strncmp(sub_left->id, right_key, strlen(right_key));
  363. break;
  364. default:
  365. cmp = 0;
  366. break;
  367. }
  368. if (cmp) {
  369. return 0;
  370. }
  371. return CMP_MATCH;
  372. }
  373. static int get_message_count(void *obj, void *arg, int flags)
  374. {
  375. struct stasis_message *msg;
  376. struct mwi_stasis_subscription *mwi_stasis = obj;
  377. struct ast_sip_message_accumulator *counter = arg;
  378. struct ast_mwi_state *mwi_state;
  379. msg = stasis_cache_get(ast_mwi_state_cache(), ast_mwi_state_type(), mwi_stasis->mailbox);
  380. if (!msg) {
  381. return 0;
  382. }
  383. mwi_state = stasis_message_data(msg);
  384. counter->old_msgs += mwi_state->old_msgs;
  385. counter->new_msgs += mwi_state->new_msgs;
  386. ao2_ref(msg, -1);
  387. return 0;
  388. }
  389. static void set_voicemail_extension(pj_pool_t *pool, pjsip_sip_uri *local_uri,
  390. struct ast_sip_message_accumulator *counter, const char *voicemail_extension)
  391. {
  392. pjsip_sip_uri *account_uri;
  393. const char *vm_exten;
  394. if (ast_strlen_zero(voicemail_extension)) {
  395. vm_exten = default_voicemail_extension;
  396. } else {
  397. vm_exten = voicemail_extension;
  398. }
  399. if (!ast_strlen_zero(vm_exten)) {
  400. account_uri = pjsip_uri_clone(pool, local_uri);
  401. pj_strdup2(pool, &account_uri->user, vm_exten);
  402. pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, account_uri, counter->message_account, sizeof(counter->message_account));
  403. }
  404. }
  405. struct unsolicited_mwi_data {
  406. struct mwi_subscription *sub;
  407. struct ast_sip_endpoint *endpoint;
  408. pjsip_evsub_state state;
  409. struct ast_sip_message_accumulator *counter;
  410. };
  411. static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flags)
  412. {
  413. struct unsolicited_mwi_data *mwi_data = arg;
  414. struct mwi_subscription *sub = mwi_data->sub;
  415. struct ast_sip_endpoint *endpoint = mwi_data->endpoint;
  416. pjsip_evsub_state state = mwi_data->state;
  417. struct ast_sip_contact *contact = obj;
  418. const char *state_name;
  419. pjsip_tx_data *tdata;
  420. pjsip_sub_state_hdr *sub_state;
  421. pjsip_event_hdr *event;
  422. pjsip_from_hdr *from;
  423. pjsip_sip_uri *from_uri;
  424. const pjsip_hdr *allow_events = pjsip_evsub_get_allow_events_hdr(NULL);
  425. struct ast_sip_body body;
  426. struct ast_str *body_text;
  427. struct ast_sip_body_data body_data = {
  428. .body_type = AST_SIP_MESSAGE_ACCUMULATOR,
  429. .body_data = mwi_data->counter,
  430. };
  431. if (ast_sip_create_request("NOTIFY", NULL, endpoint, NULL, contact, &tdata)) {
  432. ast_log(LOG_WARNING, "Unable to create unsolicited NOTIFY request to endpoint %s URI %s\n", sub->id, contact->uri);
  433. return 0;
  434. }
  435. body.type = MWI_TYPE;
  436. body.subtype = MWI_SUBTYPE;
  437. body_text = ast_str_create(64);
  438. if (!body_text) {
  439. pjsip_tx_data_dec_ref(tdata);
  440. return 0;
  441. }
  442. from = PJSIP_MSG_FROM_HDR(tdata->msg);
  443. from_uri = pjsip_uri_get_uri(from->uri);
  444. if (!ast_strlen_zero(endpoint->subscription.mwi.fromuser)) {
  445. pj_strdup2(tdata->pool, &from_uri->user, endpoint->subscription.mwi.fromuser);
  446. }
  447. set_voicemail_extension(tdata->pool, from_uri, mwi_data->counter, endpoint->subscription.mwi.voicemail_extension);
  448. if (ast_sip_pubsub_generate_body_content(body.type, body.subtype, &body_data, &body_text)) {
  449. ast_log(LOG_WARNING, "Unable to generate SIP MWI NOTIFY body.\n");
  450. ast_free(body_text);
  451. pjsip_tx_data_dec_ref(tdata);
  452. return 0;
  453. }
  454. body.body_text = ast_str_buffer(body_text);
  455. switch (state) {
  456. case PJSIP_EVSUB_STATE_ACTIVE:
  457. state_name = "active";
  458. break;
  459. case PJSIP_EVSUB_STATE_TERMINATED:
  460. default:
  461. state_name = "terminated";
  462. break;
  463. }
  464. sub_state = pjsip_sub_state_hdr_create(tdata->pool);
  465. pj_cstr(&sub_state->sub_state, state_name);
  466. pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) sub_state);
  467. event = pjsip_event_hdr_create(tdata->pool);
  468. pj_cstr(&event->event_type, "message-summary");
  469. pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);
  470. pjsip_msg_add_hdr(tdata->msg, pjsip_hdr_shallow_clone(tdata->pool, allow_events));
  471. ast_sip_add_body(tdata, &body);
  472. ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL);
  473. ast_free(body_text);
  474. return 0;
  475. }
  476. static struct ast_sip_aor *find_aor_for_resource(struct ast_sip_endpoint *endpoint, const char *resource)
  477. {
  478. struct ast_sip_aor *aor;
  479. char *aor_name;
  480. char *aors_copy;
  481. /* Direct match */
  482. if ((aor = ast_sip_location_retrieve_aor(resource))) {
  483. return aor;
  484. }
  485. if (!endpoint) {
  486. return NULL;
  487. }
  488. /*
  489. * This may be a subscribe to the voicemail_extension. If so,
  490. * look for an aor belonging to this endpoint that has a matching
  491. * voicemail_extension.
  492. */
  493. aors_copy = ast_strdupa(endpoint->aors);
  494. while ((aor_name = ast_strip(strsep(&aors_copy, ",")))) {
  495. struct ast_sip_aor *check_aor = ast_sip_location_retrieve_aor(aor_name);
  496. if (!check_aor) {
  497. continue;
  498. }
  499. if (!ast_strlen_zero(check_aor->voicemail_extension)
  500. && !strcasecmp(check_aor->voicemail_extension, resource)) {
  501. ast_debug(1, "Found an aor (%s) that matches voicemail_extension %s\n", aor_name, resource);
  502. return check_aor;
  503. }
  504. ao2_ref(check_aor, -1);
  505. }
  506. return NULL;
  507. }
  508. static void send_unsolicited_mwi_notify(struct mwi_subscription *sub,
  509. struct ast_sip_message_accumulator *counter)
  510. {
  511. RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
  512. "endpoint", sub->id), ao2_cleanup);
  513. char *endpoint_aors;
  514. char *aor_name;
  515. if (!endpoint) {
  516. ast_log(LOG_WARNING, "Unable to send unsolicited MWI to %s because endpoint does not exist\n",
  517. sub->id);
  518. return;
  519. }
  520. if (ast_strlen_zero(endpoint->aors)) {
  521. ast_log(LOG_WARNING, "Unable to send unsolicited MWI to %s because the endpoint has no"
  522. " configured AORs\n", sub->id);
  523. return;
  524. }
  525. endpoint_aors = ast_strdupa(endpoint->aors);
  526. ast_debug(5, "Sending unsolicited MWI NOTIFY to endpoint %s, new messages: %d, old messages: %d\n",
  527. sub->id, counter->new_msgs, counter->old_msgs);
  528. while ((aor_name = ast_strip(strsep(&endpoint_aors, ",")))) {
  529. RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
  530. RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
  531. struct unsolicited_mwi_data mwi_data = {
  532. .sub = sub,
  533. .endpoint = endpoint,
  534. .counter = counter,
  535. };
  536. if (!aor) {
  537. ast_log(LOG_WARNING, "Unable to locate AOR %s for unsolicited MWI\n", aor_name);
  538. continue;
  539. }
  540. contacts = ast_sip_location_retrieve_aor_contacts(aor);
  541. if (!contacts || (ao2_container_count(contacts) == 0)) {
  542. ast_debug(1, "No contacts bound to AOR %s. Cannot send unsolicited MWI until a contact registers.\n", aor_name);
  543. continue;
  544. }
  545. ao2_callback(contacts, OBJ_NODATA, send_unsolicited_mwi_notify_to_contact, &mwi_data);
  546. }
  547. }
  548. static void send_mwi_notify(struct mwi_subscription *sub)
  549. {
  550. struct ast_sip_message_accumulator counter = {
  551. .old_msgs = 0,
  552. .new_msgs = 0,
  553. .message_account[0] = '\0',
  554. };
  555. struct ast_sip_body_data data = {
  556. .body_type = AST_SIP_MESSAGE_ACCUMULATOR,
  557. .body_data = &counter,
  558. };
  559. ao2_callback(sub->stasis_subs, OBJ_NODATA, get_message_count, &counter);
  560. if (sub->is_solicited) {
  561. const char *resource = ast_sip_subscription_get_resource_name(sub->sip_sub);
  562. struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sub->sip_sub);
  563. struct ast_sip_aor *aor = find_aor_for_resource(endpoint, resource);
  564. pjsip_dialog *dlg = ast_sip_subscription_get_dialog(sub->sip_sub);
  565. pjsip_sip_uri *sip_uri = ast_sip_subscription_get_sip_uri(sub->sip_sub);
  566. if (aor && dlg && sip_uri) {
  567. set_voicemail_extension(dlg->pool, sip_uri, &counter, aor->voicemail_extension);
  568. }
  569. ao2_cleanup(aor);
  570. ao2_cleanup(endpoint);
  571. ast_sip_subscription_notify(sub->sip_sub, &data, 0);
  572. return;
  573. }
  574. send_unsolicited_mwi_notify(sub, &counter);
  575. }
  576. static int unsubscribe_stasis(void *obj, void *arg, int flags)
  577. {
  578. struct mwi_stasis_subscription *mwi_stasis = obj;
  579. if (mwi_stasis->stasis_sub) {
  580. ast_debug(3, "Removing stasis subscription to mailbox %s\n", mwi_stasis->mailbox);
  581. mwi_stasis->stasis_sub = stasis_unsubscribe_and_join(mwi_stasis->stasis_sub);
  582. }
  583. return CMP_MATCH;
  584. }
  585. static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
  586. {
  587. struct mwi_subscription *mwi_sub;
  588. struct ast_datastore *mwi_datastore;
  589. mwi_datastore = ast_sip_subscription_get_datastore(sub, MWI_DATASTORE);
  590. if (!mwi_datastore) {
  591. return;
  592. }
  593. mwi_sub = mwi_datastore->data;
  594. ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
  595. ast_sip_subscription_remove_datastore(sub, MWI_DATASTORE);
  596. ao2_ref(mwi_datastore, -1);
  597. }
  598. static void mwi_ds_destroy(void *data)
  599. {
  600. struct mwi_subscription *sub = data;
  601. ao2_ref(sub, -1);
  602. }
  603. static struct ast_datastore_info mwi_ds_info = {
  604. .destroy = mwi_ds_destroy,
  605. };
  606. static int add_mwi_datastore(struct mwi_subscription *sub)
  607. {
  608. struct ast_datastore *mwi_datastore;
  609. int res;
  610. mwi_datastore = ast_sip_subscription_alloc_datastore(&mwi_ds_info, MWI_DATASTORE);
  611. if (!mwi_datastore) {
  612. return -1;
  613. }
  614. ao2_ref(sub, +1);
  615. mwi_datastore->data = sub;
  616. /*
  617. * NOTE: Adding the datastore to the subscription creates a ref loop
  618. * that must be manually broken.
  619. */
  620. res = ast_sip_subscription_add_datastore(sub->sip_sub, mwi_datastore);
  621. ao2_ref(mwi_datastore, -1);
  622. return res;
  623. }
  624. /*!
  625. * \brief Determines if an endpoint is receiving unsolicited MWI for a particular mailbox.
  626. *
  627. * \param endpoint The endpoint to check
  628. * \param mailbox The candidate mailbox
  629. * \retval 0 The endpoint does not receive unsolicited MWI for this mailbox
  630. * \retval 1 The endpoint receives unsolicited MWI for this mailbox
  631. */
  632. static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint *endpoint,
  633. const char *mailbox)
  634. {
  635. struct ao2_iterator *mwi_subs;
  636. struct mwi_subscription *mwi_sub;
  637. const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
  638. int ret = 0;
  639. mwi_subs = ao2_find(unsolicited_mwi, endpoint_id, OBJ_SEARCH_KEY | OBJ_MULTIPLE);
  640. if (!mwi_subs) {
  641. return 0;
  642. }
  643. for (; (mwi_sub = ao2_iterator_next(mwi_subs)) && !ret; ao2_cleanup(mwi_sub)) {
  644. struct mwi_stasis_subscription *mwi_stasis;
  645. mwi_stasis = ao2_find(mwi_sub->stasis_subs, mailbox, OBJ_SEARCH_KEY);
  646. if (mwi_stasis) {
  647. if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {
  648. unsubscribe_stasis(mwi_stasis, NULL, 0);
  649. ao2_unlink(mwi_sub->stasis_subs, mwi_stasis);
  650. } else {
  651. ret = 1;
  652. }
  653. ao2_cleanup(mwi_stasis);
  654. }
  655. }
  656. ao2_iterator_destroy(mwi_subs);
  657. return ret;
  658. }
  659. /*!
  660. * \brief Determine if an endpoint is a candidate to be able to subscribe for MWI
  661. *
  662. * Currently, this just makes sure that the endpoint is not already receiving unsolicted
  663. * MWI for any of an AOR's configured mailboxes.
  664. *
  665. * \param obj The AOR to which the endpoint is subscribing.
  666. * \param arg The endpoint that is attempting to subscribe.
  667. * \param flags Unused.
  668. * \retval 0 Endpoint is a candidate to subscribe to MWI on the AOR.
  669. * \retval -1 The endpoint cannot subscribe to MWI on the AOR.
  670. */
  671. static int mwi_validate_for_aor(void *obj, void *arg, int flags)
  672. {
  673. struct ast_sip_aor *aor = obj;
  674. struct ast_sip_endpoint *endpoint = arg;
  675. char *mailboxes;
  676. char *mailbox;
  677. if (ast_strlen_zero(aor->mailboxes)) {
  678. return 0;
  679. }
  680. mailboxes = ast_strdupa(aor->mailboxes);
  681. while ((mailbox = ast_strip(strsep(&mailboxes, ",")))) {
  682. if (ast_strlen_zero(mailbox)) {
  683. continue;
  684. }
  685. if (endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox)) {
  686. ast_debug(1, "Endpoint '%s' already configured for unsolicited MWI for mailbox '%s'. "
  687. "Denying MWI subscription to %s\n", ast_sorcery_object_get_id(endpoint), mailbox,
  688. ast_sorcery_object_get_id(aor));
  689. return -1;
  690. }
  691. }
  692. return 0;
  693. }
  694. static int mwi_on_aor(void *obj, void *arg, int flags)
  695. {
  696. struct ast_sip_aor *aor = obj;
  697. struct mwi_subscription *sub = arg;
  698. char *mailboxes;
  699. char *mailbox;
  700. if (ast_strlen_zero(aor->mailboxes)) {
  701. return 0;
  702. }
  703. mailboxes = ast_strdupa(aor->mailboxes);
  704. while ((mailbox = ast_strip(strsep(&mailboxes, ",")))) {
  705. struct mwi_stasis_subscription *mwi_stasis_sub;
  706. if (ast_strlen_zero(mailbox)) {
  707. continue;
  708. }
  709. mwi_stasis_sub = mwi_stasis_subscription_alloc(mailbox, sub);
  710. if (!mwi_stasis_sub) {
  711. continue;
  712. }
  713. ao2_link(sub->stasis_subs, mwi_stasis_sub);
  714. ao2_ref(mwi_stasis_sub, -1);
  715. }
  716. return 0;
  717. }
  718. static struct mwi_subscription *mwi_create_subscription(
  719. struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
  720. {
  721. struct mwi_subscription *sub = mwi_subscription_alloc(endpoint, 1, sip_sub);
  722. if (!sub) {
  723. return NULL;
  724. }
  725. if (add_mwi_datastore(sub)) {
  726. ast_log(LOG_WARNING, "Unable to add datastore for MWI subscription to %s\n",
  727. sub->id);
  728. ao2_ref(sub, -1);
  729. return NULL;
  730. }
  731. return sub;
  732. }
  733. static struct mwi_subscription *mwi_subscribe_single(
  734. struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub, const char *name)
  735. {
  736. struct ast_sip_aor *aor;
  737. struct mwi_subscription *sub;
  738. aor = find_aor_for_resource(endpoint, name);
  739. if (!aor) {
  740. ast_log(LOG_WARNING, "Unable to locate aor %s. MWI subscription failed.\n", name);
  741. return NULL;
  742. }
  743. sub = mwi_create_subscription(endpoint, sip_sub);
  744. if (sub) {
  745. mwi_on_aor(aor, sub, 0);
  746. }
  747. ao2_ref(aor, -1);
  748. return sub;
  749. }
  750. static struct mwi_subscription *mwi_subscribe_all(
  751. struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
  752. {
  753. struct mwi_subscription *sub;
  754. sub = mwi_create_subscription(endpoint, sip_sub);
  755. if (!sub) {
  756. return NULL;
  757. }
  758. ast_sip_for_each_aor(endpoint->aors, mwi_on_aor, sub);
  759. return sub;
  760. }
  761. static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
  762. const char *resource)
  763. {
  764. RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
  765. if (ast_strlen_zero(resource)) {
  766. if (ast_sip_for_each_aor(endpoint->aors, mwi_validate_for_aor, endpoint)) {
  767. return 500;
  768. }
  769. return 200;
  770. }
  771. aor = find_aor_for_resource(endpoint, resource);
  772. if (!aor) {
  773. ast_debug(1, "Unable to locate aor %s. MWI subscription failed.\n", resource);
  774. return 404;
  775. }
  776. if (ast_strlen_zero(aor->mailboxes)) {
  777. ast_debug(1, "AOR %s has no configured mailboxes. MWI subscription failed.\n",
  778. resource);
  779. return 404;
  780. }
  781. if (mwi_validate_for_aor(aor, endpoint, 0)) {
  782. return 500;
  783. }
  784. return 200;
  785. }
  786. static int mwi_subscription_established(struct ast_sip_subscription *sip_sub)
  787. {
  788. const char *resource = ast_sip_subscription_get_resource_name(sip_sub);
  789. struct mwi_subscription *sub;
  790. struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sip_sub);
  791. /* no aor in uri? subscribe to all on endpoint */
  792. if (ast_strlen_zero(resource)) {
  793. sub = mwi_subscribe_all(endpoint, sip_sub);
  794. } else {
  795. sub = mwi_subscribe_single(endpoint, sip_sub, resource);
  796. }
  797. if (!sub) {
  798. ao2_cleanup(endpoint);
  799. return -1;
  800. }
  801. if (!ao2_container_count(sub->stasis_subs)) {
  802. /*
  803. * We setup no MWI subscriptions so remove the MWI datastore
  804. * to break the ref loop.
  805. */
  806. ast_sip_subscription_remove_datastore(sip_sub, MWI_DATASTORE);
  807. }
  808. ao2_cleanup(sub);
  809. ao2_cleanup(endpoint);
  810. return 0;
  811. }
  812. static void *mwi_get_notify_data(struct ast_sip_subscription *sub)
  813. {
  814. struct ast_sip_message_accumulator *counter;
  815. struct mwi_subscription *mwi_sub;
  816. struct ast_datastore *mwi_datastore;
  817. struct ast_sip_aor *aor;
  818. struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sub);
  819. mwi_datastore = ast_sip_subscription_get_datastore(sub, MWI_DATASTORE);
  820. if (!mwi_datastore) {
  821. return NULL;
  822. }
  823. mwi_sub = mwi_datastore->data;
  824. counter = ao2_alloc(sizeof(*counter), NULL);
  825. if (!counter) {
  826. ao2_cleanup(mwi_datastore);
  827. return NULL;
  828. }
  829. if ((aor = find_aor_for_resource(endpoint, ast_sip_subscription_get_resource_name(sub)))) {
  830. pjsip_dialog *dlg = ast_sip_subscription_get_dialog(sub);
  831. pjsip_sip_uri *sip_uri = ast_sip_subscription_get_sip_uri(sub);
  832. if (dlg && sip_uri) {
  833. set_voicemail_extension(dlg->pool, sip_uri, counter, aor->voicemail_extension);
  834. }
  835. ao2_ref(aor, -1);
  836. }
  837. ao2_cleanup(endpoint);
  838. ao2_callback(mwi_sub->stasis_subs, OBJ_NODATA, get_message_count, counter);
  839. ao2_cleanup(mwi_datastore);
  840. return counter;
  841. }
  842. static void mwi_subscription_mailboxes_str(struct ao2_container *stasis_subs,
  843. struct ast_str **str)
  844. {
  845. int is_first = 1;
  846. struct mwi_stasis_subscription *node;
  847. struct ao2_iterator i = ao2_iterator_init(stasis_subs, 0);
  848. while ((node = ao2_iterator_next(&i))) {
  849. if (is_first) {
  850. is_first = 0;
  851. ast_str_append(str, 0, "%s", node->mailbox);
  852. } else {
  853. ast_str_append(str, 0, ",%s", node->mailbox);
  854. }
  855. ao2_ref(node, -1);
  856. }
  857. ao2_iterator_destroy(&i);
  858. }
  859. static void mwi_to_ami(struct ast_sip_subscription *sub,
  860. struct ast_str **buf)
  861. {
  862. struct mwi_subscription *mwi_sub;
  863. struct ast_datastore *mwi_datastore;
  864. mwi_datastore = ast_sip_subscription_get_datastore(sub, MWI_DATASTORE);
  865. if (!mwi_datastore) {
  866. return;
  867. }
  868. mwi_sub = mwi_datastore->data;
  869. ast_str_append(buf, 0, "SubscriptionType: mwi\r\n");
  870. ast_str_append(buf, 0, "Mailboxes: ");
  871. mwi_subscription_mailboxes_str(mwi_sub->stasis_subs, buf);
  872. ast_str_append(buf, 0, "\r\n");
  873. ao2_ref(mwi_datastore, -1);
  874. }
  875. static int serialized_notify(void *userdata)
  876. {
  877. struct mwi_subscription *mwi_sub = userdata;
  878. send_mwi_notify(mwi_sub);
  879. ao2_ref(mwi_sub, -1);
  880. return 0;
  881. }
  882. static int serialized_cleanup(void *userdata)
  883. {
  884. struct mwi_subscription *mwi_sub = userdata;
  885. /* This is getting rid of the reference that was added
  886. * just before this serialized task was pushed.
  887. */
  888. ao2_cleanup(mwi_sub);
  889. /* This is getting rid of the reference held by the
  890. * stasis subscription
  891. */
  892. ao2_cleanup(mwi_sub);
  893. return 0;
  894. }
  895. static int send_notify(void *obj, void *arg, int flags)
  896. {
  897. struct mwi_subscription *mwi_sub = obj;
  898. struct ast_taskprocessor *serializer = mwi_sub->is_solicited
  899. ? ast_sip_subscription_get_serializer(mwi_sub->sip_sub)
  900. : get_mwi_serializer();
  901. if (ast_sip_push_task(serializer, serialized_notify, ao2_bump(mwi_sub))) {
  902. ao2_ref(mwi_sub, -1);
  903. }
  904. return 0;
  905. }
  906. static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
  907. struct stasis_message *msg)
  908. {
  909. struct mwi_subscription *mwi_sub = userdata;
  910. if (stasis_subscription_final_message(sub, msg)) {
  911. if (ast_sip_push_task(NULL, serialized_cleanup, ao2_bump(mwi_sub))) {
  912. ao2_ref(mwi_sub, -1);
  913. }
  914. return;
  915. }
  916. if (ast_mwi_state_type() == stasis_message_type(msg)) {
  917. send_notify(mwi_sub, NULL, 0);
  918. }
  919. }
  920. /*! \note Called with the unsolicited_mwi container lock held. */
  921. static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags)
  922. {
  923. RAII_VAR(struct mwi_subscription *, aggregate_sub, NULL, ao2_cleanup);
  924. struct ast_sip_endpoint *endpoint = obj;
  925. char *mailboxes, *mailbox;
  926. if (ast_strlen_zero(endpoint->subscription.mwi.mailboxes)) {
  927. return 0;
  928. }
  929. if (endpoint->subscription.mwi.aggregate) {
  930. const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
  931. /* Check if subscription exists */
  932. aggregate_sub = ao2_find(unsolicited_mwi, endpoint_id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
  933. if (aggregate_sub) {
  934. return 0;
  935. }
  936. aggregate_sub = mwi_subscription_alloc(endpoint, 0, NULL);
  937. if (!aggregate_sub) {
  938. return 0;
  939. }
  940. }
  941. mailboxes = ast_strdupa(endpoint->subscription.mwi.mailboxes);
  942. while ((mailbox = ast_strip(strsep(&mailboxes, ",")))) {
  943. struct mwi_subscription *sub;
  944. struct mwi_stasis_subscription *mwi_stasis_sub;
  945. /* check if subscription exists */
  946. if (ast_strlen_zero(mailbox) ||
  947. (!aggregate_sub && endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox))) {
  948. continue;
  949. }
  950. sub = aggregate_sub ?: mwi_subscription_alloc(endpoint, 0, NULL);
  951. mwi_stasis_sub = mwi_stasis_subscription_alloc(mailbox, sub);
  952. if (mwi_stasis_sub) {
  953. ao2_link(sub->stasis_subs, mwi_stasis_sub);
  954. ao2_ref(mwi_stasis_sub, -1);
  955. }
  956. if (!aggregate_sub && sub) {
  957. ao2_link_flags(unsolicited_mwi, sub, OBJ_NOLOCK);
  958. ao2_ref(sub, -1);
  959. }
  960. }
  961. if (aggregate_sub) {
  962. ao2_link_flags(unsolicited_mwi, aggregate_sub, OBJ_NOLOCK);
  963. }
  964. return 0;
  965. }
  966. static int unsubscribe(void *obj, void *arg, int flags)
  967. {
  968. struct mwi_subscription *mwi_sub = obj;
  969. ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
  970. return CMP_MATCH;
  971. }
  972. static void create_mwi_subscriptions(void)
  973. {
  974. struct ao2_container *endpoints;
  975. struct ast_variable *var;
  976. var = ast_variable_new("mailboxes !=", "", "");
  977. endpoints = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "endpoint",
  978. AST_RETRIEVE_FLAG_MULTIPLE, var);
  979. ast_variables_destroy(var);
  980. if (!endpoints) {
  981. return;
  982. }
  983. /* We remove all the old stasis subscriptions first before applying the new configuration. This
  984. * prevents a situation where there might be multiple overlapping stasis subscriptions for an
  985. * endpoint for mailboxes. Though there may be mailbox changes during the gap between unsubscribing
  986. * and resubscribing, up-to-date mailbox state will be sent out to the endpoint when the
  987. * new stasis subscription is established
  988. */
  989. ao2_lock(unsolicited_mwi);
  990. ao2_callback(unsolicited_mwi, OBJ_NOLOCK | OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
  991. ao2_callback(endpoints, OBJ_NODATA, create_mwi_subscriptions_for_endpoint, NULL);
  992. ao2_unlock(unsolicited_mwi);
  993. ao2_ref(endpoints, -1);
  994. }
  995. /*! \brief Function called to send MWI NOTIFY on any unsolicited mailboxes relating to this AOR */
  996. static int send_contact_notify(void *obj, void *arg, int flags)
  997. {
  998. struct mwi_subscription *mwi_sub = obj;
  999. const char *aor = arg;
  1000. if (!mwi_sub->aors || !strstr(mwi_sub->aors, aor)) {
  1001. return 0;
  1002. }
  1003. if (ast_sip_push_task(get_mwi_serializer(), serialized_notify, ao2_bump(mwi_sub))) {
  1004. ao2_ref(mwi_sub, -1);
  1005. }
  1006. return 0;
  1007. }
  1008. /*! \brief Create mwi subscriptions and notify */
  1009. static void mwi_contact_changed(const struct ast_sip_contact *contact)
  1010. {
  1011. char *id = ast_strdupa(ast_sorcery_object_get_id(contact));
  1012. char *aor = NULL;
  1013. struct ast_sip_endpoint *endpoint = NULL;
  1014. if (contact->endpoint) {
  1015. endpoint = ao2_bump(contact->endpoint);
  1016. } else {
  1017. if (!ast_strlen_zero(contact->endpoint_name)) {
  1018. endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", contact->endpoint_name);
  1019. }
  1020. }
  1021. if (!endpoint || ast_strlen_zero(endpoint->subscription.mwi.mailboxes)) {
  1022. ao2_cleanup(endpoint);
  1023. return;
  1024. }
  1025. ao2_lock(unsolicited_mwi);
  1026. create_mwi_subscriptions_for_endpoint(endpoint, NULL, 0);
  1027. ao2_unlock(unsolicited_mwi);
  1028. ao2_cleanup(endpoint);
  1029. aor = strsep(&id, ";@");
  1030. ao2_callback(unsolicited_mwi, OBJ_NODATA, send_contact_notify, aor);
  1031. }
  1032. /*! \brief Function called when a contact is updated */
  1033. static void mwi_contact_updated(const void *object)
  1034. {
  1035. mwi_contact_changed(object);
  1036. }
  1037. /*! \brief Function called when a contact is added */
  1038. static void mwi_contact_added(const void *object)
  1039. {
  1040. mwi_contact_changed(object);
  1041. }
  1042. /*! \brief Function called when a contact is deleted */
  1043. static void mwi_contact_deleted(const void *object)
  1044. {
  1045. const struct ast_sip_contact *contact = object;
  1046. struct ao2_iterator *mwi_subs;
  1047. struct mwi_subscription *mwi_sub;
  1048. struct ast_sip_endpoint *endpoint = NULL;
  1049. struct ast_sip_contact *found_contact;
  1050. if (contact->endpoint) {
  1051. endpoint = ao2_bump(contact->endpoint);
  1052. } else {
  1053. if (!ast_strlen_zero(contact->endpoint_name)) {
  1054. endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", contact->endpoint_name);
  1055. }
  1056. }
  1057. if (!endpoint || ast_strlen_zero(endpoint->subscription.mwi.mailboxes)) {
  1058. ao2_cleanup(endpoint);
  1059. return;
  1060. }
  1061. /* Check if there is another contact */
  1062. found_contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
  1063. ao2_cleanup(endpoint);
  1064. if (found_contact) {
  1065. ao2_cleanup(found_contact);
  1066. return;
  1067. }
  1068. ao2_lock(unsolicited_mwi);
  1069. mwi_subs = ao2_find(unsolicited_mwi, contact->endpoint_name,
  1070. OBJ_SEARCH_KEY | OBJ_MULTIPLE | OBJ_NOLOCK | OBJ_UNLINK);
  1071. if (mwi_subs) {
  1072. for (; (mwi_sub = ao2_iterator_next(mwi_subs)); ao2_cleanup(mwi_sub)) {
  1073. unsubscribe(mwi_sub, NULL, 0);
  1074. }
  1075. ao2_iterator_destroy(mwi_subs);
  1076. }
  1077. ao2_unlock(unsolicited_mwi);
  1078. }
  1079. /*! \brief Observer for contacts so unsolicited MWI is sent when a contact changes */
  1080. static const struct ast_sorcery_observer mwi_contact_observer = {
  1081. .created = mwi_contact_added,
  1082. .updated = mwi_contact_updated,
  1083. .deleted = mwi_contact_deleted,
  1084. };
  1085. /*! \brief Task invoked to send initial MWI NOTIFY for unsolicited */
  1086. static int send_initial_notify_all(void *obj)
  1087. {
  1088. ao2_callback(unsolicited_mwi, OBJ_NODATA, send_notify, NULL);
  1089. return 0;
  1090. }
  1091. /*! \brief Event callback which fires initial unsolicited MWI NOTIFY messages when we're fully booted */
  1092. static void mwi_startup_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
  1093. {
  1094. struct ast_json_payload *payload;
  1095. const char *type;
  1096. if (stasis_message_type(message) != ast_manager_get_generic_type()) {
  1097. return;
  1098. }
  1099. payload = stasis_message_data(message);
  1100. type = ast_json_string_get(ast_json_object_get(payload->json, "type"));
  1101. if (strcmp(type, "FullyBooted")) {
  1102. return;
  1103. }
  1104. ast_sip_push_task(NULL, send_initial_notify_all, NULL);
  1105. stasis_unsubscribe(sub);
  1106. }
  1107. static void global_loaded(const char *object_type)
  1108. {
  1109. ast_free(default_voicemail_extension);
  1110. default_voicemail_extension = ast_sip_get_default_voicemail_extension();
  1111. mwi_serializer_set_alert_levels();
  1112. }
  1113. static struct ast_sorcery_observer global_observer = {
  1114. .loaded = global_loaded,
  1115. };
  1116. static int reload(void)
  1117. {
  1118. if (!ast_sip_get_mwi_disable_initial_unsolicited()) {
  1119. create_mwi_subscriptions();
  1120. }
  1121. return 0;
  1122. }
  1123. static int load_module(void)
  1124. {
  1125. CHECK_PJSIP_MODULE_LOADED();
  1126. if (ast_sip_register_subscription_handler(&mwi_handler)) {
  1127. return AST_MODULE_LOAD_DECLINE;
  1128. }
  1129. if (mwi_serializer_pool_setup()) {
  1130. ast_log(AST_LOG_WARNING, "Failed to create MWI serializer pool. The default SIP pool will be used for MWI\n");
  1131. }
  1132. unsolicited_mwi = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MWI_BUCKETS,
  1133. mwi_sub_hash, NULL, mwi_sub_cmp);
  1134. if (!unsolicited_mwi) {
  1135. mwi_serializer_pool_shutdown();
  1136. ast_sip_unregister_subscription_handler(&mwi_handler);
  1137. return AST_MODULE_LOAD_DECLINE;
  1138. }
  1139. ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
  1140. ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &global_observer);
  1141. ast_sorcery_reload_object(ast_sip_get_sorcery(), "global");
  1142. if (!ast_sip_get_mwi_disable_initial_unsolicited()) {
  1143. create_mwi_subscriptions();
  1144. if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
  1145. ast_sip_push_task(NULL, send_initial_notify_all, NULL);
  1146. } else {
  1147. struct stasis_subscription *sub;
  1148. sub = stasis_subscribe_pool(ast_manager_get_topic(), mwi_startup_event_cb, NULL);
  1149. stasis_subscription_accept_message_type(sub, ast_manager_get_generic_type());
  1150. stasis_subscription_set_filter(sub, STASIS_SUBSCRIPTION_FILTER_SELECTIVE);
  1151. }
  1152. }
  1153. return AST_MODULE_LOAD_SUCCESS;
  1154. }
  1155. static int unload_module(void)
  1156. {
  1157. ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
  1158. ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
  1159. ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
  1160. ao2_ref(unsolicited_mwi, -1);
  1161. unsolicited_mwi = NULL;
  1162. mwi_serializer_pool_shutdown();
  1163. ast_sip_unregister_subscription_handler(&mwi_handler);
  1164. ast_free(default_voicemail_extension);
  1165. default_voicemail_extension = NULL;
  1166. return 0;
  1167. }
  1168. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP MWI resource",
  1169. .support_level = AST_MODULE_SUPPORT_CORE,
  1170. .load = load_module,
  1171. .unload = unload_module,
  1172. .reload = reload,
  1173. .load_pri = AST_MODPRI_CHANNEL_DEPEND + 5,
  1174. );