Advertisement
Guest User

polycom-broadsoft-feature-event.patch

a guest
Jul 14th, 2014
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 7.46 KB | None | 0 0
  1. --- channels/chan_sip.c.keep    2014-07-14 15:28:59.739985497 -0400
  2. +++ channels/chan_sip.c 2014-07-14 22:02:50.186709816 -0400
  3. @@ -267,6 +267,7 @@
  4.  #include "asterisk/data.h"
  5.  #include "asterisk/aoc.h"
  6.  #include "asterisk/message.h"
  7. +#include "asterisk/dial.h"
  8.  #include "sip/include/sip.h"
  9.  #include "sip/include/globals.h"
  10.  #include "sip/include/config_parser.h"
  11. @@ -663,6 +664,7 @@
  12.     { CPIM_PIDF_XML,   "presence", "application/cpim-pidf+xml",   "cpim-pidf+xml" },  /* RFC 3863 */
  13.     { PIDF_XML,        "presence", "application/pidf+xml",        "pidf+xml" },       /* RFC 3863 */
  14.     { XPIDF_XML,       "presence", "application/xpidf+xml",       "xpidf+xml" },       /* Pre-RFC 3863 with MS additions */
  15. +   { FEATURE_XML,  "as-feature-event", "application/x-as-feature-event+xml",   "x-as-feature-event+xml" }, /* Broadsoft feature key synchronization */
  16.     { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
  17.  };
  18.  
  19. @@ -1640,6 +1642,7 @@
  20.  static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req);
  21.  static int handle_request_message(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e);
  22.  static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, const char *e);
  23. +static void do_feature_call(char *channel, ast_string_field username);
  24.  static void handle_request_info(struct sip_pvt *p, struct sip_request *req);
  25.  static int handle_request_options(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e);
  26.  static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, int *nounlock);
  27. @@ -14542,6 +14545,14 @@
  28.         }
  29.         ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n");
  30.         break;
  31. +   case FEATURE_XML:
  32. +       ast_str_append(tmp, 0,
  33. +           "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
  34. +           "<DoNotDisturbEvent xmlns=\"http://www.ecma-international.org/standards/ecma-323/csta/ed3\">\n");
  35. +       ast_str_append(tmp, 0, "<device>%s</device>\n", exten);
  36. +       ast_str_append(tmp, 0, "<doNotDisturbOn>%s</doNotDisturbOn>", (local_state ==  NOTIFY_OPEN) ? "false" : (local_state == NOTIFY_INUSE) ? "false" : "true");
  37. +       ast_str_append(tmp, 0, "</DoNotDisturbEvent>\n");
  38. +       break;
  39.     case NONE:
  40.     default:
  41.         break;
  42. @@ -14655,6 +14666,12 @@
  43.         add_header(&req, "Content-Type", subscriptiontype->mediatype);
  44.         p->dialogver++;
  45.         break;
  46. +   case FEATURE_XML: /* Broadsoft feature key synchronization */
  47. +       add_header(&req, "Event", subscriptiontype->event);
  48. +       state_notify_build_xml(data, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
  49. +       add_header(&req, "Content-Type", subscriptiontype->mediatype);
  50. +       p->dialogver++;
  51. +       break;
  52.     case NONE:
  53.     default:
  54.         break;
  55. @@ -27500,7 +27517,7 @@
  56.         make_our_tag(p);
  57.     }
  58.  
  59. -   if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
  60. +   if (!strcmp(event, "presence") || !strcmp(event, "dialog") || !strcmp(event, "as-feature-event")) { /* Presence, RFC 3842 */
  61.         int gotdest;
  62.         const char *accept;
  63.         int start = 0;
  64. @@ -27538,9 +27555,12 @@
  65.                 subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
  66.             } else if (strstr(accept, "application/xpidf+xml")) {
  67.                 subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
  68. +           } else if (strstr(accept, "application/x-as-feature-event+xml")) {
  69. +               subscribed = FEATURE_XML;
  70.             } else {
  71.                 unknown_accept = accept;
  72.             }
  73. +
  74.             /* check to see if there is another Accept header present */
  75.             accept = __get_header(req, "Accept", &start);
  76.         }
  77. @@ -27719,6 +27739,25 @@
  78.                 sip_unref_peer(peer, "release a peer ref now that MWI is sent");
  79.             }
  80.         } else if (p->subscribed != CALL_COMPLETION) {
  81. +      
  82. +           if(p->subscribed == FEATURE_XML) {
  83. +               char *feature_body;
  84. +
  85. +               if (!(feature_body = get_content(req))) {
  86. +                   ast_log(LOG_WARNING, "Unable to get feature-event body\n");
  87. +                   } else if (!ast_strlen_zero(feature_body)) {
  88. +                   ast_verb(3, "Found feature-event body %s\n", feature_body);
  89. +
  90. +                   if (strstr(feature_body, "<doNotDisturbOn>true</doNotDisturbOn>")) {
  91. +                       ast_verb(3, "Found feature-event DND status true\n");
  92. +                       do_feature_call("Local/*78@from-internal", p->username);
  93. +                   } else if (strstr(feature_body, "<doNotDisturbOn>false</doNotDisturbOn>")) {
  94. +                       ast_verb(3, "Found feature-event DND status false\n");
  95. +                       do_feature_call("Local/*79@from-internal", p->username);
  96. +                   }
  97. +               }
  98. +           }
  99. +      
  100.             struct state_notify_data data = { 0, };
  101.             char *subtype = NULL;
  102.             char *message = NULL;
  103. @@ -27795,6 +27834,95 @@
  104.     return 1;
  105.  }
  106.  
  107. +static int null_chan_write(struct ast_channel *chan, struct ast_frame *frame)
  108. +{
  109. +   return 0;
  110. +}
  111. +
  112. +static const struct ast_channel_tech null_tech = {
  113. +        .type = "NULL",
  114. +        .description = "Null channel (should not see this)",
  115. +       .write = null_chan_write,
  116. +};
  117. +
  118. +static void do_feature_call(char *channel, ast_string_field username)
  119. +{
  120. +   struct ast_dial *dial = NULL;
  121. +   struct ast_str *apptext = NULL, *tmpstr = NULL;
  122. +   enum ast_dial_result res;
  123. +   struct ast_channel *chan = NULL;
  124. +   char *tech, *dest;
  125. +   char buf[8];
  126. +
  127. +   tech = ast_strdupa(channel);
  128. +
  129. +   if ((dest = strchr(tech, '/'))) {
  130. +       *dest = '\0';
  131. +       dest++;
  132. +   } else {
  133. +       ast_log(LOG_WARNING, "Channel should be in form Tech/Dest (was '%s')\n", tech);
  134. +       goto notify_cleanup;
  135. +   }
  136. +
  137. +   if (!(dial = ast_dial_create())) {
  138. +       ast_log(LOG_ERROR, "Could not create dial structure\n");
  139. +       goto notify_cleanup;
  140. +   }
  141. +
  142. +   if (ast_dial_append(dial, tech, dest) < 0) {
  143. +       ast_log(LOG_ERROR, "Could not append channel\n");
  144. +       goto notify_cleanup;
  145. +   }
  146. +
  147. +   ast_dial_set_global_timeout(dial, 5);
  148. +   generate_random_string(buf, sizeof(buf));
  149. +
  150. +   if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "SIP/%s-%s", username, buf))) {
  151. +       ast_log(LOG_ERROR, "Could not allocate notification channel\n");
  152. +       goto notify_cleanup;
  153. +   }
  154. +
  155. +   ast_channel_tech_set(chan, &null_tech);
  156. +   ast_format_set(ast_channel_writeformat(chan), AST_FORMAT_SLINEAR, 0);
  157. +   ast_format_set(ast_channel_readformat(chan), AST_FORMAT_SLINEAR, 0);
  158. +   ast_format_set(ast_channel_rawwriteformat(chan), AST_FORMAT_SLINEAR, 0);
  159. +   ast_format_set(ast_channel_rawreadformat(chan), AST_FORMAT_SLINEAR, 0);
  160. +   /* clear native formats and set to slinear. write format is signlear so just use that to set it */
  161. +   ast_format_cap_set(ast_channel_nativeformats(chan), ast_channel_writeformat(chan));
  162. +
  163. +   ast_set_callerid(chan, username, username, username);
  164. +  
  165. +   ast_verb(3, "Dialing %s for activation of feature key\n", channel);
  166. +   res = ast_dial_run(dial, chan, 0);
  167. +
  168. +   if (res != AST_DIAL_RESULT_ANSWERED) {
  169. +       ast_verb(3, "Dialing %s was not completed\n", channel);
  170. +   } else {
  171. +       struct ast_channel *answered;
  172. +
  173. +       answered = ast_dial_answered_steal(dial);
  174. +
  175. +       ast_channel_context_set(answered, "sip-feature-xml");
  176. +       ast_channel_exten_set(answered, "s");
  177. +       ast_channel_priority_set(answered, 1);
  178. +       ast_pbx_run(answered);
  179. +   }
  180. +
  181. +notify_cleanup:
  182. +   if (apptext) {
  183. +       ast_free(apptext);
  184. +   }
  185. +   if (tmpstr) {
  186. +       ast_free(tmpstr);
  187. +   }
  188. +   if (dial) {
  189. +       ast_dial_destroy(dial);
  190. +   }
  191. +   if (chan) {
  192. +       ast_channel_release(chan);
  193. +   }
  194. +}
  195. +
  196.  /*! \brief Handle incoming REGISTER request */
  197.  static int handle_request_register(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e)
  198.  {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement