presence_xml.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Kevin Harwell <kharwell@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. #include "asterisk.h"
  19. #include <pjsip.h>
  20. #include <pjsip_simple.h>
  21. #include <pjlib.h>
  22. #include "asterisk/module.h"
  23. #include "asterisk/pbx.h"
  24. #include "asterisk/res_pjsip_presence_xml.h"
  25. void ast_sip_sanitize_xml(const char *input, char *output, size_t len)
  26. {
  27. char *copy = ast_strdupa(input);
  28. char *break_point;
  29. size_t remaining = len - 1;
  30. output[0] = '\0';
  31. while ((break_point = strpbrk(copy, "<>\"&'\n\r")) && remaining) {
  32. char to_escape = *break_point;
  33. *break_point = '\0';
  34. strncat(output, copy, remaining);
  35. /* The strncat function will write remaining+1 if the string length is
  36. * equal to or greater than the size provided to it. We take this into
  37. * account by subtracting 1, which ensures that the NULL byte is written
  38. * inside of the provided buffer.
  39. */
  40. remaining = len - strlen(output) - 1;
  41. switch (to_escape) {
  42. case '<':
  43. strncat(output, "&lt;", remaining);
  44. break;
  45. case '>':
  46. strncat(output, "&gt;", remaining);
  47. break;
  48. case '"':
  49. strncat(output, "&quot;", remaining);
  50. break;
  51. case '&':
  52. strncat(output, "&amp;", remaining);
  53. break;
  54. case '\'':
  55. strncat(output, "&apos;", remaining);
  56. break;
  57. case '\r':
  58. strncat(output, "&#13;", remaining);
  59. break;
  60. case '\n':
  61. strncat(output, "&#10;", remaining);
  62. break;
  63. };
  64. copy = break_point + 1;
  65. remaining = len - strlen(output) - 1;
  66. }
  67. /* Be sure to copy everything after the final bracket */
  68. if (*copy && remaining) {
  69. strncat(output, copy, remaining);
  70. }
  71. }
  72. void ast_sip_presence_exten_state_to_str(int state, char **statestring, char **pidfstate,
  73. char **pidfnote, enum ast_sip_pidf_state *local_state,
  74. unsigned int notify_early_inuse_ringing)
  75. {
  76. switch (state) {
  77. case AST_EXTENSION_RINGING:
  78. *statestring = "early";
  79. *local_state = NOTIFY_INUSE;
  80. *pidfstate = "on-the-phone";
  81. *pidfnote = "Ringing";
  82. break;
  83. case (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING):
  84. if (notify_early_inuse_ringing) {
  85. *statestring = "early";
  86. } else {
  87. *statestring = "confirmed";
  88. }
  89. *local_state = NOTIFY_INUSE;
  90. *pidfstate = "on-the-phone";
  91. *pidfnote = "Ringing";
  92. break;
  93. case AST_EXTENSION_INUSE:
  94. *statestring = "confirmed";
  95. *local_state = NOTIFY_INUSE;
  96. *pidfstate = "on-the-phone";
  97. *pidfnote = "On the phone";
  98. break;
  99. case AST_EXTENSION_BUSY:
  100. *statestring = "confirmed";
  101. *local_state = NOTIFY_INUSE;
  102. *pidfstate = "on-the-phone";
  103. *pidfnote = "On the phone";
  104. break;
  105. case AST_EXTENSION_UNAVAILABLE:
  106. *statestring = "terminated";
  107. *local_state = NOTIFY_CLOSED;
  108. *pidfstate = "--";
  109. *pidfnote = "Unavailable";
  110. break;
  111. case AST_EXTENSION_ONHOLD:
  112. *statestring = "confirmed";
  113. *local_state = NOTIFY_INUSE;
  114. *pidfstate = "on-the-phone";
  115. *pidfnote = "On hold";
  116. break;
  117. case AST_EXTENSION_NOT_INUSE:
  118. default:
  119. /* Default setting */
  120. *statestring = "terminated";
  121. *local_state = NOTIFY_OPEN;
  122. *pidfstate = "--";
  123. *pidfnote = "Ready";
  124. break;
  125. }
  126. }
  127. pj_xml_attr *ast_sip_presence_xml_create_attr(pj_pool_t *pool,
  128. pj_xml_node *node, const char *name, const char *value)
  129. {
  130. pj_xml_attr *attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);
  131. pj_strdup2(pool, &attr->name, name);
  132. pj_strdup2(pool, &attr->value, value);
  133. pj_xml_add_attr(node, attr);
  134. return attr;
  135. }
  136. pj_xml_node *ast_sip_presence_xml_create_node(pj_pool_t *pool,
  137. pj_xml_node *parent, const char* name)
  138. {
  139. pj_xml_node *node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
  140. pj_list_init(&node->attr_head);
  141. pj_list_init(&node->node_head);
  142. pj_strdup2(pool, &node->name, name);
  143. node->content.ptr = NULL;
  144. node->content.slen = 0;
  145. if (parent) {
  146. pj_xml_add_node(parent, node);
  147. }
  148. return node;
  149. }
  150. void ast_sip_presence_xml_find_node_attr(pj_pool_t* pool,
  151. pj_xml_node *parent, const char *node_name, const char *attr_name,
  152. pj_xml_node **node, pj_xml_attr **attr)
  153. {
  154. pj_str_t name;
  155. if (!(*node = pj_xml_find_node(parent, pj_cstr(&name, node_name)))) {
  156. *node = ast_sip_presence_xml_create_node(pool, parent, node_name);
  157. }
  158. if (!(*attr = pj_xml_find_attr(*node, pj_cstr(&name, attr_name), NULL))) {
  159. *attr = ast_sip_presence_xml_create_attr(pool, *node, attr_name, "");
  160. }
  161. }