SipMessage.cxx 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*
  2. * Copyright (C) 2010-2011 Mamadou Diop.
  3. *
  4. * Contact: Mamadou Diop <diopmamadou(at)doubango.org>
  5. *
  6. * This file is part of Open Source Doubango Framework.
  7. *
  8. * DOUBANGO is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * DOUBANGO is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with DOUBANGO.
  20. *
  21. */
  22. #include "SipMessage.h"
  23. SdpMessage::SdpMessage()
  24. :m_pSdpMessage(tsk_null)
  25. {
  26. }
  27. SdpMessage::SdpMessage(tsdp_message_t *_sdpmessage)
  28. {
  29. m_pSdpMessage = (tsdp_message_t *)tsk_object_ref(_sdpmessage);
  30. }
  31. SdpMessage::~SdpMessage()
  32. {
  33. TSK_OBJECT_SAFE_FREE(m_pSdpMessage);
  34. }
  35. char* SdpMessage::getSdpHeaderValue(const char* media, char name, unsigned index /*= 0*/)
  36. {
  37. const tsdp_header_M_t* M;
  38. if((M = (const tsdp_header_M_t*)tsdp_message_get_header(m_pSdpMessage, tsdp_htype_M))) {
  39. tsdp_header_type_t type = tsdp_htype_Dummy;
  40. const tsdp_header_t* header;
  41. switch(name) {
  42. case 'a':
  43. type = tsdp_htype_A;
  44. break;
  45. case 'b':
  46. type = tsdp_htype_B;
  47. break;
  48. case 'c':
  49. type = tsdp_htype_C;
  50. break;
  51. case 'e':
  52. type = tsdp_htype_E;
  53. break;
  54. case 'i':
  55. type = tsdp_htype_I;
  56. break;
  57. case 'k':
  58. type = tsdp_htype_K;
  59. break;
  60. case 'm':
  61. type = tsdp_htype_M;
  62. break;
  63. case 'o':
  64. type = tsdp_htype_O;
  65. break;
  66. case 'p':
  67. type = tsdp_htype_P;
  68. break;
  69. case 'r':
  70. type = tsdp_htype_R;
  71. break;
  72. case 's':
  73. type = tsdp_htype_S;
  74. break;
  75. case 't':
  76. type = tsdp_htype_T;
  77. break;
  78. case 'u':
  79. type = tsdp_htype_U;
  80. break;
  81. case 'v':
  82. type = tsdp_htype_V;
  83. break;
  84. case 'z':
  85. type = tsdp_htype_Z;
  86. break;
  87. }
  88. if((header = tsdp_message_get_headerAt(m_pSdpMessage, type, index))) {
  89. return tsdp_header_tostring(header);
  90. }
  91. }
  92. return tsk_null;
  93. }
  94. char* SdpMessage::getSdpHeaderAValue(const char* media, const char* attributeName)
  95. {
  96. const tsdp_header_M_t* M;
  97. tsk_size_t i;
  98. for(i = 0; (M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(m_pSdpMessage, tsdp_htype_M, i)); i++) {
  99. if(tsk_striequals(M->media, media)) {
  100. const tsdp_header_A_t* A;
  101. if((A = tsdp_header_M_findA(M, attributeName))) {
  102. return tsk_strdup(A->value);
  103. }
  104. }
  105. }
  106. return tsk_null;
  107. }
  108. SipMessage::SipMessage()
  109. :m_pSipMessage(tsk_null), m_pSdpMessage(tsk_null)
  110. {
  111. }
  112. SipMessage::SipMessage(tsip_message_t *_sipmessage)
  113. : m_pSdpMessage(tsk_null)
  114. {
  115. m_pSipMessage = (tsip_message_t *)tsk_object_ref(_sipmessage);
  116. }
  117. SipMessage::~SipMessage()
  118. {
  119. TSK_OBJECT_SAFE_FREE(m_pSipMessage);
  120. if(m_pSdpMessage) {
  121. delete m_pSdpMessage;
  122. }
  123. }
  124. bool SipMessage::isResponse()
  125. {
  126. return TSIP_MESSAGE_IS_RESPONSE(m_pSipMessage);
  127. }
  128. tsip_request_type_t SipMessage::getRequestType()
  129. {
  130. if(TSIP_MESSAGE_IS_REQUEST(m_pSipMessage)) {
  131. return (m_pSipMessage)->line.request.request_type;
  132. }
  133. return tsip_NONE;
  134. }
  135. short SipMessage::getResponseCode()
  136. {
  137. return TSIP_RESPONSE_CODE(m_pSipMessage);
  138. }
  139. const char* SipMessage::getResponsePhrase()
  140. {
  141. return TSIP_RESPONSE_PHRASE(m_pSipMessage);
  142. }
  143. const tsip_header_t* SipMessage::getSipHeader(const char* name, unsigned index /* =0 */)
  144. {
  145. /* Do not worry about calling tsk_striequals() several times because the function
  146. * is fully optimized.
  147. */
  148. /* Code below comes from tsip_message_get_headerAt() */
  149. tsk_size_t pos = 0;
  150. const tsk_list_item_t *item;
  151. const tsip_header_t* hdr = tsk_null;
  152. if(!m_pSipMessage || !name) {
  153. return tsk_null;
  154. }
  155. if(tsk_striequals(name, "v") || tsk_striequals(name, "via")) {
  156. if(index == 0) {
  157. hdr = (const tsip_header_t*)m_pSipMessage->firstVia;
  158. goto bail;
  159. }
  160. else {
  161. pos++;
  162. }
  163. }
  164. if(tsk_striequals(name, "f") || tsk_striequals(name, "from")) {
  165. if(index == 0) {
  166. hdr = (const tsip_header_t*)m_pSipMessage->From;
  167. goto bail;
  168. }
  169. else {
  170. pos++;
  171. }
  172. }
  173. if(tsk_striequals(name, "t") || tsk_striequals(name, "to")) {
  174. if(index == 0) {
  175. hdr = (const tsip_header_t*)m_pSipMessage->To;
  176. goto bail;
  177. }
  178. else {
  179. pos++;
  180. }
  181. }
  182. if(tsk_striequals(name, "m") || tsk_striequals(name, "contact")) {
  183. if(index == 0) {
  184. hdr = (const tsip_header_t*)m_pSipMessage->Contact;
  185. goto bail;
  186. }
  187. else {
  188. pos++;
  189. }
  190. }
  191. if(tsk_striequals(name, "i") || tsk_striequals(name, "call-id")) {
  192. if(index == 0) {
  193. hdr = (const tsip_header_t*)m_pSipMessage->Call_ID;
  194. goto bail;
  195. }
  196. else {
  197. pos++;
  198. }
  199. }
  200. if(tsk_striequals(name, "cseq")) {
  201. if(index == 0) {
  202. hdr = (const tsip_header_t*)m_pSipMessage->CSeq;
  203. goto bail;
  204. }
  205. else {
  206. pos++;
  207. }
  208. }
  209. if(tsk_striequals(name, "expires")) {
  210. if(index == 0) {
  211. hdr = (const tsip_header_t*)m_pSipMessage->Expires;
  212. goto bail;
  213. }
  214. else {
  215. pos++;
  216. }
  217. }
  218. if(tsk_striequals(name, "c") || tsk_striequals(name, "content-type")) {
  219. if(index == 0) {
  220. hdr = (const tsip_header_t*)m_pSipMessage->Content_Type;
  221. goto bail;
  222. }
  223. else {
  224. pos++;
  225. }
  226. }
  227. if(tsk_striequals(name, "l") || tsk_striequals(name, "content-length")) {
  228. if(index == 0) {
  229. hdr = (const tsip_header_t*)m_pSipMessage->Content_Length;
  230. goto bail;
  231. }
  232. else {
  233. pos++;
  234. }
  235. }
  236. tsk_list_foreach(item, m_pSipMessage->headers) {
  237. if(tsk_striequals(tsip_header_get_name_2(TSIP_HEADER(item->data)), name)) {
  238. if(pos++ >= index) {
  239. hdr = (const tsip_header_t*)item->data;
  240. break;
  241. }
  242. }
  243. }
  244. bail:
  245. return hdr;
  246. }
  247. // e.g. getHeaderParamValue("content-type");
  248. char* SipMessage::getSipHeaderValue(const char* name, unsigned index /* = 0*/)
  249. {
  250. const tsip_header_t* header;
  251. if((header = this->getSipHeader(name, index))) {
  252. switch(header->type) {
  253. case tsip_htype_From:
  254. return tsip_uri_tostring(((const tsip_header_From_t*)header)->uri, tsk_false, tsk_false);
  255. case tsip_htype_To:
  256. return tsip_uri_tostring(((const tsip_header_To_t*)header)->uri, tsk_false, tsk_false);
  257. break;
  258. case tsip_htype_P_Asserted_Identity:
  259. return tsip_uri_tostring(((const tsip_header_P_Asserted_Identity_t*)header)->uri, tsk_false, tsk_false);
  260. break;
  261. default:
  262. return tsip_header_value_tostring(header);
  263. }
  264. }
  265. // SWIG: %newobject getHeaderValueAt;
  266. return tsk_null;
  267. }
  268. // e.g. getHeaderParamValue("content-type", "charset");
  269. char* SipMessage::getSipHeaderParamValue(const char* name, const char* param, unsigned index /*=0*/)
  270. {
  271. const tsip_header_t* header;
  272. if((header = this->getSipHeader(name, index))) {
  273. return tsip_header_get_param_value(header, param);
  274. }
  275. // SWIG: %newobject getSipHeaderParamValue;
  276. return tsk_null;
  277. }
  278. /** Returns the content length.
  279. */
  280. unsigned SipMessage::getSipContentLength()
  281. {
  282. return TSIP_MESSAGE_CONTENT_DATA_LENGTH(m_pSipMessage);
  283. }
  284. /** Gets the message content
  285. * @param output A pointer to the output buffer where to copy the data. MUST
  286. * be allocated by the caller.
  287. * @param maxsize The maximum number of octets to copy. Should be less than the size of the
  288. * @a output buffer. You can use @a getSipContentLength() to get the right value to use.
  289. * @retval The number of octet copied in the @a output buffer.
  290. */
  291. unsigned SipMessage::getSipContent(void* output, unsigned maxsize)
  292. {
  293. unsigned retsize = 0;
  294. if(output && maxsize && TSIP_MESSAGE_HAS_CONTENT(m_pSipMessage)) {
  295. retsize = (m_pSipMessage->Content->size > maxsize) ? maxsize : m_pSipMessage->Content->size;
  296. memcpy(output, m_pSipMessage->Content->data, retsize);
  297. }
  298. return retsize;
  299. }
  300. const void* SipMessage::getSipContentPtr()
  301. {
  302. if(m_pSipMessage && m_pSipMessage->Content) {
  303. return m_pSipMessage->Content->data;
  304. }
  305. return tsk_null;
  306. }
  307. const SdpMessage* SipMessage::getSdpMessage()
  308. {
  309. if(!m_pSdpMessage && TSIP_MESSAGE_HAS_CONTENT(m_pSipMessage)) {
  310. tsdp_message_t* sdp = tsdp_message_parse(m_pSipMessage->Content->data, m_pSipMessage->Content->size);
  311. if(sdp) {
  312. m_pSdpMessage = new SdpMessage(sdp);
  313. TSK_OBJECT_SAFE_FREE(sdp);
  314. }
  315. }
  316. return m_pSdpMessage;
  317. }