tsip_parser_uri.rl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (C) 2010-2011 Mamadou Diop.
  3. *
  4. * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]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. /**@file tsip_parser_uri.c
  23. * @brief SIP/SIPS/TEL URI parser.
  24. *
  25. * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
  26. *
  27. */
  28. #include "tinysip/parsers/tsip_parser_uri.h"
  29. #include "tsk_string.h"
  30. #include "tsk_memory.h"
  31. #include "tsk_debug.h"
  32. /***********************************
  33. * Ragel state machine.
  34. */
  35. %%{
  36. machine tsip_machine_parser_uri;
  37. # Includes
  38. include tsip_machine_utils "./ragel/tsip_machine_utils.rl";
  39. #include tsip_machine_userinfo;
  40. action tag{
  41. tag_start = p;
  42. }
  43. #/* Sets URI type */
  44. action is_sip { uri->scheme = tsk_strdup("sip"), uri->type = uri_sip; }
  45. action is_sips { uri->scheme = tsk_strdup("sips"), uri->type = uri_sips; }
  46. action is_tel { uri->scheme = tsk_strdup("tel"), uri->type = uri_tel; }
  47. #/* Sets HOST type */
  48. action is_ipv4 { uri->host_type = host_ipv4; }
  49. action is_ipv6 { uri->host_type = host_ipv6; }
  50. action is_hostname { uri->host_type = host_hostname; }
  51. action parse_scheme{
  52. TSK_PARSER_SET_STRING(uri->scheme);
  53. }
  54. action parse_user_name{
  55. TSK_PARSER_SET_STRING(uri->user_name);
  56. }
  57. action parse_password{
  58. TSK_PARSER_SET_STRING(uri->password);
  59. }
  60. action parse_host{
  61. TSK_PARSER_SET_STRING(uri->host);
  62. }
  63. action parse_port{
  64. TSK_PARSER_SET_INTEGER(uri->port);
  65. }
  66. action parse_param{
  67. TSK_PARSER_ADD_PARAM(uri->params);
  68. }
  69. action eob{
  70. }
  71. my_uri_parameter = (pname ( "=" pvalue )?) >tag %parse_param;
  72. uri_parameters = ( ";" my_uri_parameter )*;
  73. sip_usrinfo := ( ( user>tag %parse_user_name ) :> ( ':' password>tag %parse_password )? :>> '@' ) @{ fgoto main; };
  74. main := |*
  75. ("sip:"i>tag %is_sip | "sips:"i>tag %is_sips) @100
  76. {
  77. if(tsk_strcontains(te, (pe - te), "@")){
  78. fgoto sip_usrinfo;
  79. }
  80. };
  81. ("tel:"i %is_tel (any+)>tag %parse_user_name :> uri_parameters) @100 { };
  82. ( (IPv6reference >is_ipv6)@89 | (IPv4address >is_ipv4)@88 | (hostname >is_hostname)@87 ) @90
  83. {
  84. TSK_SCANNER_SET_STRING(uri->host);
  85. if(uri->host_type == host_ipv6){
  86. tsk_strunquote_2(&uri->host, '[', ']');
  87. }
  88. };
  89. (":" port)@80
  90. {
  91. ts++;
  92. TSK_SCANNER_SET_INTEGER(uri->port);
  93. };
  94. ( uri_parameters ) @70 { };
  95. (any)+ @0 { };
  96. *|;
  97. #main := ({ fcall SIP_URI; });
  98. }%%
  99. ////////////////////////////////////////////////////////////////////////////////////////////////////
  100. /// @ingroup tsip_uri_group
  101. ///
  102. /// Creates SIP/SIPS/TEL URI from string buffer.
  103. ///
  104. ///
  105. /// @param data Pointer to a string buffer from which to create the URI object.
  106. /// @param size The size of the string buffer.
  107. ///
  108. /// @retval @ref tsip_uri_t* object if succeed and Null otherwise.
  109. ///
  110. /// @code
  111. /// tsip_uri_t* uri;
  112. /// if((uri = tsip_uri_parse("sip:bob@open-ims.test", strlen("sip:bob@open-ims.test")))){
  113. /// printf("success");
  114. /// }
  115. /// else{
  116. /// printf("error");
  117. /// }
  118. /// TSK_OBJECT_SAFE_FREE(uri);
  119. /// @endcode
  120. ///
  121. /// @sa @ref tsip_uri_create()
  122. ////////////////////////////////////////////////////////////////////////////////////////////////////
  123. tsip_uri_t *tsip_uri_parse(const char *data, tsk_size_t size)
  124. {
  125. int cs = 0;
  126. const char *p = data;
  127. const char *pe = p + size;
  128. const char *eof = pe;
  129. const char *ts = tsk_null, *te = tsk_null;
  130. int act = 0;
  131. tsip_uri_t *uri = tsip_uri_create(uri_unknown);
  132. const char *tag_start = tsk_null;
  133. %%write data;
  134. (void)(eof);
  135. (void)(void)(tsip_machine_parser_uri_first_final);
  136. (void)(void)(tsip_machine_parser_uri_error);
  137. (void)(void)(tsip_machine_parser_uri_en_sip_usrinfo);
  138. (void)(void)(tsip_machine_parser_uri_en_main);
  139. %%write init;
  140. %%write exec;
  141. if( cs < %%{ write first_final; }%% ){
  142. TSK_DEBUG_ERROR("Failed to parse SIP/SIPS/TEL URI.");
  143. TSK_OBJECT_SAFE_FREE(uri);
  144. }
  145. return uri;
  146. }