Sipper 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. data/sipper/README.rb +26 -0
  2. data/sipper/b2bua_controller.rb +163 -0
  3. data/sipper/b2bua_session_mixin.rb +24 -0
  4. data/sipper/base_controller.rb +425 -0
  5. data/sipper/bin/common.rb +42 -0
  6. data/sipper/bin/generate.rb +70 -0
  7. data/sipper/bin/project.rb +44 -0
  8. data/sipper/bin/run.rb +85 -0
  9. data/sipper/bin/run_smoke.rb +8 -0
  10. data/sipper/config/log4r.xml +71 -0
  11. data/sipper/controller_class_loader.rb +29 -0
  12. data/sipper/controller_selector.rb +119 -0
  13. data/sipper/controllers/invite_controller.rb +30 -0
  14. data/sipper/controllers/order.yaml +3 -0
  15. data/sipper/custom_message.rb +4 -0
  16. data/sipper/detached_session.rb +11 -0
  17. data/sipper/docs/manual.txt +1621 -0
  18. data/sipper/generators/README +12 -0
  19. data/sipper/generators/gen_controller.rb +228 -0
  20. data/sipper/generators/gen_project.rb +45 -0
  21. data/sipper/generators/gen_test.rb +72 -0
  22. data/sipper/generators/project_template_dir/Rakefile +56 -0
  23. data/sipper/generators/project_template_dir/config/sipper.cfg +31 -0
  24. data/sipper/generators/project_template_dir/controllers/README.txt +2 -0
  25. data/sipper/generators/project_template_dir/dot_sipper.proj +2 -0
  26. data/sipper/generators/project_template_dir/logs/README.txt +2 -0
  27. data/sipper/generators/project_template_dir/tests/README.txt +2 -0
  28. data/sipper/lib/smc/statemap.rb +194 -0
  29. data/sipper/logs/dialog_info_store +0 -0
  30. data/sipper/logs/r.cmd +6 -0
  31. data/sipper/logs/r.sh +6 -0
  32. data/sipper/media/sipper_media_client.rb +268 -0
  33. data/sipper/media/sipper_media_event.rb +43 -0
  34. data/sipper/media/sipper_media_manager.rb +145 -0
  35. data/sipper/media/sipper_media_proxy.rb +60 -0
  36. data/sipper/media/sipper_offer_answer.rb +285 -0
  37. data/sipper/message.rb +512 -0
  38. data/sipper/modified_pattern_formatter.rb +119 -0
  39. data/sipper/proxy_controller.rb +143 -0
  40. data/sipper/registration.rb +52 -0
  41. data/sipper/request.rb +109 -0
  42. data/sipper/response.rb +123 -0
  43. data/sipper/ruby_ext/module.rb +27 -0
  44. data/sipper/ruby_ext/mutable_class.rb +17 -0
  45. data/sipper/ruby_ext/object.rb +38 -0
  46. data/sipper/ruby_ext/pqueue.rb +190 -0
  47. data/sipper/ruby_ext/snapshot.rb +201 -0
  48. data/sipper/ruby_ext/string.rb +18 -0
  49. data/sipper/ruby_ext/time.rb +9 -0
  50. data/sipper/run/run_sipper1.rb +28 -0
  51. data/sipper/run/run_sipper2.rb +56 -0
  52. data/sipper/sdp/sdp.rb +257 -0
  53. data/sipper/sdp/sdp_generator.rb +131 -0
  54. data/sipper/sdp/sdp_parser.rb +136 -0
  55. data/sipper/session.rb +1952 -0
  56. data/sipper/session_manager.rb +170 -0
  57. data/sipper/session_recorder.rb +190 -0
  58. data/sipper/session_state/DialogState.sm +54 -0
  59. data/sipper/session_state/DialogState_sm.rb +337 -0
  60. data/sipper/session_state/dialog_routes.rb +141 -0
  61. data/sipper/sip_headers/header.rb +632 -0
  62. data/sipper/sip_headers/sipuri.rb +352 -0
  63. data/sipper/sip_logger.rb +65 -0
  64. data/sipper/sip_message_router.rb +231 -0
  65. data/sipper/sip_test_driver_controller.rb +10 -0
  66. data/sipper/sipper.rb +329 -0
  67. data/sipper/sipper_assertions.rb +21 -0
  68. data/sipper/sipper_configurator.rb +376 -0
  69. data/sipper/sipper_http/sipper_http_request_dispatcher.rb +71 -0
  70. data/sipper/sipper_http/sipper_http_response.rb +25 -0
  71. data/sipper/stray_message_manager.rb +40 -0
  72. data/sipper/test_completion_signaling_helper.rb +77 -0
  73. data/sipper/transaction/Ict.sm +59 -0
  74. data/sipper/transaction/Ict_sm.rb +430 -0
  75. data/sipper/transaction/Ist.sm +74 -0
  76. data/sipper/transaction/Ist_sm.rb +460 -0
  77. data/sipper/transaction/Nict.sm +51 -0
  78. data/sipper/transaction/Nict_sm.rb +325 -0
  79. data/sipper/transaction/Nist.sm +59 -0
  80. data/sipper/transaction/Nist_sm.rb +356 -0
  81. data/sipper/transaction/invite_client_transaction.rb +274 -0
  82. data/sipper/transaction/invite_server_transaction.rb +319 -0
  83. data/sipper/transaction/non_invite_client_transaction.rb +230 -0
  84. data/sipper/transaction/non_invite_server_transaction.rb +263 -0
  85. data/sipper/transaction/state_machine_wrapper.rb +58 -0
  86. data/sipper/transaction/transaction.rb +212 -0
  87. data/sipper/transport/base_transport.rb +84 -0
  88. data/sipper/transport/rel_unrel.rb +19 -0
  89. data/sipper/transport/transport_and_route_resolver.rb +67 -0
  90. data/sipper/transport/udp_transport.rb +156 -0
  91. data/sipper/transport_manager.rb +33 -0
  92. data/sipper/udp_session.rb +17 -0
  93. data/sipper/util/command_element.rb +62 -0
  94. data/sipper/util/compact_converter.rb +50 -0
  95. data/sipper/util/counter.rb +26 -0
  96. data/sipper/util/digest/digest_authorizer.rb +204 -0
  97. data/sipper/util/expectation_parser.rb +164 -0
  98. data/sipper/util/locator.rb +31 -0
  99. data/sipper/util/message_fill.rb +58 -0
  100. data/sipper/util/persistence/ps_sipper_map.rb +63 -0
  101. data/sipper/util/persistence/sipper_map.rb +41 -0
  102. data/sipper/util/sipper_util.rb +305 -0
  103. data/sipper/util/timer/sip_timer_helper.rb +26 -0
  104. data/sipper/util/timer/timer_manager.rb +80 -0
  105. data/sipper/util/timer/timer_task.rb +56 -0
  106. data/sipper/util/validations.rb +44 -0
  107. data/sipper/version.rb +10 -0
  108. data/sipper_test/_test_media_uas.rb +79 -0
  109. data/sipper_test/base_test_case.rb +31 -0
  110. data/sipper_test/c_134.txt +7 -0
  111. data/sipper_test/driven_sip_test_case.rb +96 -0
  112. data/sipper_test/gold.txt +10 -0
  113. data/sipper_test/gold_res.txt +8 -0
  114. data/sipper_test/gold_sub.txt +9 -0
  115. data/sipper_test/hello_sipper.au +0 -0
  116. data/sipper_test/in_sipper.au +0 -0
  117. data/sipper_test/nonrr_proxy.rb +17 -0
  118. data/sipper_test/order_tests.yaml +4 -0
  119. data/sipper_test/rake_res.txt +399 -0
  120. data/sipper_test/rr_proxy.rb +17 -0
  121. data/sipper_test/run_test.cmd +94 -0
  122. data/sipper_test/sip_test_case.rb +104 -0
  123. data/sipper_test/test2xx_retransmission.rb +80 -0
  124. data/sipper_test/test2xx_retransmission_with_limit.rb +81 -0
  125. data/sipper_test/test2xx_retransmission_with_nist.rb +91 -0
  126. data/sipper_test/test2xx_retransmission_with_txns.rb +94 -0
  127. data/sipper_test/test_address_header.rb +66 -0
  128. data/sipper_test/test_b2bua1.rb +130 -0
  129. data/sipper_test/test_b2bua2.rb +120 -0
  130. data/sipper_test/test_b2bua3.rb +160 -0
  131. data/sipper_test/test_b2bua4.rb +130 -0
  132. data/sipper_test/test_base_controller.rb +110 -0
  133. data/sipper_test/test_base_transport.rb +37 -0
  134. data/sipper_test/test_cancel.rb +21 -0
  135. data/sipper_test/test_cancel_after2xx.rb +81 -0
  136. data/sipper_test/test_cancel_retransmission.rb +105 -0
  137. data/sipper_test/test_cancel_with481.rb +83 -0
  138. data/sipper_test/test_cancel_with487.rb +70 -0
  139. data/sipper_test/test_cancel_with_ist_without_nist.rb +99 -0
  140. data/sipper_test/test_cancel_with_nist.rb +84 -0
  141. data/sipper_test/test_cancel_without487.rb +77 -0
  142. data/sipper_test/test_command_element.rb +38 -0
  143. data/sipper_test/test_compact_converter.rb +33 -0
  144. data/sipper_test/test_controller_class_loader.rb +37 -0
  145. data/sipper_test/test_controller_selector.rb +53 -0
  146. data/sipper_test/test_controller_using_compact_headers.rb +74 -0
  147. data/sipper_test/test_controller_using_header_order.rb +85 -0
  148. data/sipper_test/test_controller_using_ict.rb +64 -0
  149. data/sipper_test/test_controller_using_ict_with_non_success.rb +72 -0
  150. data/sipper_test/test_controller_using_ict_with_tcbh.rb +24 -0
  151. data/sipper_test/test_controller_using_ict_with_tcbh_no_action.rb +24 -0
  152. data/sipper_test/test_controller_using_ist.rb +70 -0
  153. data/sipper_test/test_controller_using_ist_with_tcbh.rb +24 -0
  154. data/sipper_test/test_controller_using_nict.rb +115 -0
  155. data/sipper_test/test_controller_using_nict_with_tcbh.rb +24 -0
  156. data/sipper_test/test_controller_using_nist.rb +63 -0
  157. data/sipper_test/test_controller_using_pre_existing_rs0.rb +73 -0
  158. data/sipper_test/test_controller_using_pre_existing_rs1.rb +75 -0
  159. data/sipper_test/test_controller_using_pre_existing_rs2.rb +71 -0
  160. data/sipper_test/test_controller_using_route_set.rb +86 -0
  161. data/sipper_test/test_controller_with_sdp.rb +80 -0
  162. data/sipper_test/test_controllers/cancel/order.yaml +2 -0
  163. data/sipper_test/test_controllers/cancel/uac_cancel_controller.rb +35 -0
  164. data/sipper_test/test_controllers/cancel/uas_cancel_controller.rb +25 -0
  165. data/sipper_test/test_controllers/class_loading/ordered/first_ordered_controller.rb +5 -0
  166. data/sipper_test/test_controllers/class_loading/ordered/order.yaml +3 -0
  167. data/sipper_test/test_controllers/class_loading/ordered/recond_ordered_controller.rb +6 -0
  168. data/sipper_test/test_controllers/class_loading/ordered/second_ordered_controller.rb +6 -0
  169. data/sipper_test/test_controllers/class_loading/unordered/first_unordered_controller.rb +7 -0
  170. data/sipper_test/test_controllers/class_loading/unordered/second_unordered_controller.rb +6 -0
  171. data/sipper_test/test_controllers/ctrl_trhandler/lib/transport_filters/my_transport_handler.rb +22 -0
  172. data/sipper_test/test_controllers/ctrl_trhandler/uac_tr_handler_controller.rb +27 -0
  173. data/sipper_test/test_controllers/ctrl_trhandler/uas_tr_handler_controller.rb +21 -0
  174. data/sipper_test/test_controllers/ete/order.yaml +1 -0
  175. data/sipper_test/test_controllers/ete/uac_controller.rb +39 -0
  176. data/sipper_test/test_controllers/ete/uas_controller.rb +34 -0
  177. data/sipper_test/test_controllers/extensions/extension_uac_controller.rb +24 -0
  178. data/sipper_test/test_controllers/extensions/extension_uas_controller.rb +35 -0
  179. data/sipper_test/test_controllers/extensions/lib/sipper_extensions/my_from_extension.rb +16 -0
  180. data/sipper_test/test_controllers/ict_tcbh/lib/transaction_handlers/app_ict_handler.rb +23 -0
  181. data/sipper_test/test_controllers/ict_tcbh/uac_ict_tcbh_controller.rb +27 -0
  182. data/sipper_test/test_controllers/ict_tcbh/uac_ict_tcbh_no_action_controller.rb +28 -0
  183. data/sipper_test/test_controllers/ict_tcbh/uas_ict_tcbh_controller.rb +29 -0
  184. data/sipper_test/test_controllers/ict_tcbh/uas_ict_tcbh_no_action_controller.rb +31 -0
  185. data/sipper_test/test_controllers/ist_tcbh/lib/app_ist_handler.rb +13 -0
  186. data/sipper_test/test_controllers/ist_tcbh/uac_ist_tcbh_controller.rb +22 -0
  187. data/sipper_test/test_controllers/ist_tcbh/uas_ist_tcbh_controller.rb +31 -0
  188. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/in_order.yaml +2 -0
  189. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/my_transport_handler1.rb +21 -0
  190. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/my_transport_handler2.rb +21 -0
  191. data/sipper_test/test_controllers/multi_trhandlers/lib/transport_filters/out_order.yaml +2 -0
  192. data/sipper_test/test_controllers/multi_trhandlers/uac_multi_tr_handler_controller.rb +27 -0
  193. data/sipper_test/test_controllers/multi_trhandlers/uas_multi_tr_handler_controller.rb +29 -0
  194. data/sipper_test/test_controllers/multiple/lib/blank_test.rb +2 -0
  195. data/sipper_test/test_controllers/multiple/uac_info_controller.rb +21 -0
  196. data/sipper_test/test_controllers/multiple/uac_msg_controller.rb +20 -0
  197. data/sipper_test/test_controllers/multiple/uas_info_controller.rb +15 -0
  198. data/sipper_test/test_controllers/multiple/uas_msg_controller.rb +14 -0
  199. data/sipper_test/test_controllers/nict_tcbh/lib/transaction_handlers/app_nict_handler.rb +13 -0
  200. data/sipper_test/test_controllers/nict_tcbh/uac_nict_tcbh_controller.rb +26 -0
  201. data/sipper_test/test_controllers/nict_tcbh/uas_nict_tcbh_controller.rb +20 -0
  202. data/sipper_test/test_controllers/state_machine_based/lib/CreditControl.sm +43 -0
  203. data/sipper_test/test_controllers/state_machine_based/lib/CreditControl_sm.rb +194 -0
  204. data/sipper_test/test_controllers/state_machine_based/order.yaml +1 -0
  205. data/sipper_test/test_controllers/state_machine_based/uac_message_controller.rb +34 -0
  206. data/sipper_test/test_controllers/state_machine_based/uas_message_controller.rb +44 -0
  207. data/sipper_test/test_controllers/stray_message/lib/sipper_extensions/my_stray_handler.rb +9 -0
  208. data/sipper_test/test_controllers/stray_message/stray_uac_controller.rb +24 -0
  209. data/sipper_test/test_controllers/stray_message/stray_uas_controller.rb +31 -0
  210. data/sipper_test/test_controllers/string/order.yaml +1 -0
  211. data/sipper_test/test_controllers/string/uac_controller.rb +29 -0
  212. data/sipper_test/test_controllers/string/uas_controller.rb +22 -0
  213. data/sipper_test/test_controllers/test_controller.rb +24 -0
  214. data/sipper_test/test_detached_session1.rb +78 -0
  215. data/sipper_test/test_dialog_routes.rb +139 -0
  216. data/sipper_test/test_digest_challenge1.rb +89 -0
  217. data/sipper_test/test_digest_challenge2.rb +90 -0
  218. data/sipper_test/test_dynamic_parse.rb +249 -0
  219. data/sipper_test/test_empty_sdp.rb +89 -0
  220. data/sipper_test/test_ete.rb +37 -0
  221. data/sipper_test/test_expectation_parser.rb +76 -0
  222. data/sipper_test/test_extensions.rb +28 -0
  223. data/sipper_test/test_freeze.rb +81 -0
  224. data/sipper_test/test_generated.rb +90 -0
  225. data/sipper_test/test_header_parameters.rb +75 -0
  226. data/sipper_test/test_header_parse.rb +141 -0
  227. data/sipper_test/test_http_client1.rb +84 -0
  228. data/sipper_test/test_http_client2.rb +90 -0
  229. data/sipper_test/test_ict_with_timeout.rb +62 -0
  230. data/sipper_test/test_in_dialog_request.rb +61 -0
  231. data/sipper_test/test_inline_controller.rb +67 -0
  232. data/sipper_test/test_invite_client_transaction.rb +272 -0
  233. data/sipper_test/test_invite_replace.rb +147 -0
  234. data/sipper_test/test_invite_retransmission.rb +90 -0
  235. data/sipper_test/test_invite_server_transaction.rb +208 -0
  236. data/sipper_test/test_lower_cseq.rb +79 -0
  237. data/sipper_test/test_media.rb +52 -0
  238. data/sipper_test/test_message.rb +392 -0
  239. data/sipper_test/test_method_specific_response_handling.rb +81 -0
  240. data/sipper_test/test_multi_homed1.rb +127 -0
  241. data/sipper_test/test_multi_homed2.rb +109 -0
  242. data/sipper_test/test_multi_homed_duplicate.rb +87 -0
  243. data/sipper_test/test_multi_homed_with_detached.rb +88 -0
  244. data/sipper_test/test_multiple.rb +49 -0
  245. data/sipper_test/test_multiple_contacts.rb +89 -0
  246. data/sipper_test/test_non2xx_retransmission_with_ist.rb +87 -0
  247. data/sipper_test/test_non_invite_client_transaction.rb +210 -0
  248. data/sipper_test/test_non_invite_retransmission.rb +91 -0
  249. data/sipper_test/test_non_invite_server_transaction.rb +202 -0
  250. data/sipper_test/test_offer_answer_prack.rb +103 -0
  251. data/sipper_test/test_pickup.rb +258 -0
  252. data/sipper_test/test_prack.rb +105 -0
  253. data/sipper_test/test_prack_store_and_dispatch.rb +101 -0
  254. data/sipper_test/test_prack_timer.rb +105 -0
  255. data/sipper_test/test_ps_sipper_map.rb +56 -0
  256. data/sipper_test/test_re_invite_uas_ongoing_ict.rb +81 -0
  257. data/sipper_test/test_re_invite_uas_ongoing_ist.rb +84 -0
  258. data/sipper_test/test_re_invite_with_ongoing_ict.rb +101 -0
  259. data/sipper_test/test_re_invite_with_ongoing_ist.rb +89 -0
  260. data/sipper_test/test_recorder_swap.rb +157 -0
  261. data/sipper_test/test_refer.rb +121 -0
  262. data/sipper_test/test_registeration_clearing.rb +97 -0
  263. data/sipper_test/test_registrar.rb +109 -0
  264. data/sipper_test/test_registration_controller.rb +73 -0
  265. data/sipper_test/test_registration_timeout.rb +90 -0
  266. data/sipper_test/test_remote_controller.rb +39 -0
  267. data/sipper_test/test_remote_target_update_on2xx.rb +140 -0
  268. data/sipper_test/test_request.rb +106 -0
  269. data/sipper_test/test_response.rb +40 -0
  270. data/sipper_test/test_response_without_to_tag.rb +92 -0
  271. data/sipper_test/test_rport.rb +88 -0
  272. data/sipper_test/test_sdp.rb +91 -0
  273. data/sipper_test/test_sdp_parser.rb +145 -0
  274. data/sipper_test/test_session.rb +276 -0
  275. data/sipper_test/test_session_callback_handler.rb +68 -0
  276. data/sipper_test/test_session_lifetime.rb +66 -0
  277. data/sipper_test/test_session_manager.rb +141 -0
  278. data/sipper_test/test_session_recorder.rb +145 -0
  279. data/sipper_test/test_session_state_user_defined.rb +84 -0
  280. data/sipper_test/test_session_states.rb +91 -0
  281. data/sipper_test/test_simple_dialog_state.rb +86 -0
  282. data/sipper_test/test_simple_re_invite.rb +86 -0
  283. data/sipper_test/test_sip_uri.rb +234 -0
  284. data/sipper_test/test_sipper_util.rb +45 -0
  285. data/sipper_test/test_smc_controller.rb +17 -0
  286. data/sipper_test/test_smoke.rb +80 -0
  287. data/sipper_test/test_stray.rb +28 -0
  288. data/sipper_test/test_stray_inline.rb +89 -0
  289. data/sipper_test/test_stray_res_acked.rb +103 -0
  290. data/sipper_test/test_stray_respond.rb +104 -0
  291. data/sipper_test/test_stray_retry.rb +92 -0
  292. data/sipper_test/test_stray_retry_failure.rb +93 -0
  293. data/sipper_test/test_stray_retry_initial.rb +100 -0
  294. data/sipper_test/test_strict_router_with_angled.rb +84 -0
  295. data/sipper_test/test_string_record.rb +31 -0
  296. data/sipper_test/test_subscribe_notify.rb +141 -0
  297. data/sipper_test/test_subscribe_notify_client_timeout.rb +158 -0
  298. data/sipper_test/test_subscribe_notify_dialog.rb +146 -0
  299. data/sipper_test/test_subscribe_notify_expires.rb +155 -0
  300. data/sipper_test/test_subscribe_notify_multiple_subscription.rb +157 -0
  301. data/sipper_test/test_subscribe_notify_server_timeout.rb +144 -0
  302. data/sipper_test/test_subsequent_unsent.rb +88 -0
  303. data/sipper_test/test_target_refresh_proxy_detached.rb +128 -0
  304. data/sipper_test/test_target_refresh_proxy_udp.rb +130 -0
  305. data/sipper_test/test_target_refresh_rr_proxy_udp.rb +133 -0
  306. data/sipper_test/test_target_refresh_with_new_port.rb +158 -0
  307. data/sipper_test/test_target_refresh_with_proxy1.rb +113 -0
  308. data/sipper_test/test_target_refresh_with_rr_update_proxy.rb +145 -0
  309. data/sipper_test/test_target_refresh_with_update_proxy.rb +144 -0
  310. data/sipper_test/test_target_refresh_with_update_proxy2.rb +139 -0
  311. data/sipper_test/test_timer_manager.rb +71 -0
  312. data/sipper_test/test_timer_task.rb +60 -0
  313. data/sipper_test/test_transport_handler.rb +19 -0
  314. data/sipper_test/test_transport_multi_handler.rb +18 -0
  315. data/sipper_test/test_udp_transport.rb +119 -0
  316. data/sipper_test/test_unparsed.rb +70 -0
  317. data/sipper_test/test_validations.rb +69 -0
  318. data/sipper_test/test_with_rr_proxy.rb +111 -0
  319. data/sipper_test/testmediacontroller.rb +71 -0
  320. data/sipper_test/tracing.rb +23 -0
  321. data/sipper_test/transaction_test_helper.rb +176 -0
  322. data/sipper_test/transport_filters.rb +26 -0
  323. data/sipper_test/ts_sipper.rb +91 -0
  324. data/sipper_test/ts_smoke.rb +3 -0
  325. data/sipper_test/tt.cmd +20 -0
  326. metadata +455 -0
@@ -0,0 +1,58 @@
1
+ require 'delegate'
2
+ require 'monitor'
3
+
4
+ module SIP
5
+ module Transaction
6
+ SM_PROCEED = 9000
7
+ SM_PROCEED_NO_ACTION = 9001
8
+ SM_DO_NOT_PROCEED = 9002
9
+
10
+ class StateMachineWrapper < SimpleDelegator
11
+ include MonitorMixin # all state transitions are synchronized
12
+
13
+ @@machines_covered = {} # names of machines handled.
14
+
15
+ def initialize(ctxt, txn_callback, sm_name) # the context is the object that is driving the state machine
16
+ super(sm_name.new(ctxt))
17
+ @txn_callback = txn_callback
18
+ @ctxt = ctxt
19
+ end #initialize
20
+
21
+ def self.bootstrap_machine(ctxt, sm_name)
22
+ unless @@machines_covered[sm_name]
23
+ ctxt.state_machine_transitions.each do |m|
24
+ before = ("before_"+m).to_sym
25
+ after = ("after_"+m).to_sym
26
+ self.class_eval do
27
+ define_method(before) do
28
+ if @txn_callback && @txn_callback.respond_to?(before)
29
+ return @txn_callback.send(before, @ctxt)
30
+ else
31
+ SIP::Transaction::SM_PROCEED
32
+ end
33
+ end
34
+ define_method(after) do
35
+ if @txn_callback && @txn_callback.respond_to?(after)
36
+ @txn_callback.send(after, @ctxt)
37
+ end
38
+ end
39
+ define_method(m.to_sym) do
40
+ ret = self.send(before)
41
+ return if ret == SIP::Transaction::SM_DO_NOT_PROCEED
42
+ @ctxt.mask_actions if ret == SIP::Transaction::SM_PROCEED_NO_ACTION
43
+ self.synchronize do # all transitions are lock protected
44
+ super
45
+ end
46
+ @ctxt.unmask_actions if ret == SIP::Transaction::SM_PROCEED_NO_ACTION
47
+ self.send(after)
48
+ end
49
+ end
50
+ end # transition methods
51
+ @@machines_covered[sm_name] = sm_name
52
+ end
53
+
54
+ end #bootstrap
55
+
56
+ end #class
57
+ end
58
+ end
@@ -0,0 +1,212 @@
1
+ require 'sipper_configurator'
2
+ require 'statemap'
3
+
4
+ module SIP
5
+ module Transaction
6
+
7
+ T1 = 500
8
+ T2 = 4000
9
+ T4 = 5000
10
+ Td = 32000 # 17.1.1.2
11
+
12
+ Transactions = [:Ict, :Nict, :Ist, :Nist]
13
+
14
+
15
+ class BaseTransaction
16
+ attr_accessor :branch_id, :transport, :t1, :t2, :t4, :ta, :tb, :td,
17
+ :tg, :th, :ti, :tz, :te, :tf, :tk, :tj, :ty,
18
+ :transaction_name, :txn_handler,
19
+ :message # the message is the message being sent or received by this transactions
20
+
21
+
22
+ def initialize(&block)
23
+ instance_eval(&block) if block_given?
24
+ end
25
+
26
+
27
+ #------------------
28
+ # The two methods txn_send and txn_received are two general purpose methods
29
+ # that will be called by the TU as against the transcation type specific
30
+ # methods defined on each type of transaction.
31
+ def txn_send(msg)
32
+ raise "Unimplemented method txn_send by #{self}"
33
+ end
34
+
35
+ def txn_received(msg)
36
+ raise "Unimplemented method txn_received by #{self}"
37
+ end
38
+
39
+ # called when the session is being invalidated
40
+ def invalidate
41
+ @invalidated = true
42
+ end
43
+ #------------------
44
+
45
+ # rewrite SM callbacks for masking
46
+ # each callback has to start with a "__"
47
+ def self.mask_callbacks
48
+ self.instance_methods(false).grep(/^__/).each do |m|
49
+ mask = ("mask_"+m)
50
+ alias_method mask, m
51
+ define_method(m.to_sym) do |*args|
52
+ self.send(mask.to_sym, *args) unless @mask_actions
53
+ end
54
+ end
55
+ end
56
+
57
+ #---------SM Wrapper calls------
58
+ def mask_actions
59
+ @mask_actions = true
60
+ end
61
+
62
+ def unmask_actions
63
+ @mask_actions = false
64
+ end
65
+ #------------------------------
66
+
67
+
68
+ def state
69
+ if @sm
70
+ @sm.getState.getName
71
+ else
72
+ nil
73
+ end
74
+ end
75
+
76
+ # Returns the current value and resets the value to false (default).
77
+ def consume?
78
+ c = @consume
79
+ @consume = false
80
+ return c
81
+ end
82
+
83
+
84
+ # Returns the transition methods of the state machine.
85
+ def state_machine_transitions
86
+ @transitions if @transitions
87
+ @transitions =
88
+ Kernel.const_get(@transaction_name.to_s + "State").instance_methods(false) -
89
+ ["Default", "Entry", "Exit"]
90
+ end
91
+
92
+ # Timer callback
93
+ def on_timer_expiration(timer_task)
94
+ if @invalidated
95
+ logi("This txn #{self} is invalidated, not firing timer #{timer_task}")
96
+ return
97
+ end
98
+ end
99
+
100
+ def t1
101
+ return @t1 if @t1
102
+ @t1 = @t1 || SipperConfigurator[:TransactionTimers][:t1] || SIP::Transaction::T1
103
+ end
104
+
105
+ def t2
106
+ return @t2 if @t2
107
+ @t2 = @t2 || SipperConfigurator[:TransactionTimers][:t2] || SIP::Transaction::T2
108
+ end
109
+
110
+ def t4
111
+ return @t4 if @t4
112
+ @t4 = @t4 || SipperConfigurator[:TransactionTimers][:t4] || SIP::Transaction::T4
113
+ end
114
+
115
+ # the starting value of timerA. <ICT>
116
+ def ta
117
+ return @ta if @ta
118
+ @ta = self.t1 || SipperConfigurator[:TransactionTimers][:ta]
119
+ end
120
+
121
+ # the value of timerB <ICT>
122
+ def tb
123
+ return @tb if @tb
124
+ @tb = self.t1*64 || SipperConfigurator[:TransactionTimers][:tb]
125
+ end
126
+
127
+ # <ICT>
128
+ def td
129
+ return @td if @td
130
+ @td = @td || SipperConfigurator[:TransactionTimers][:td] || SIP::Transaction::Td
131
+ end
132
+
133
+ # the value if timerY <IST>
134
+ # After having sent CANCEL the INVITE transaction also times out -
135
+ # However, a UAC canceling a request cannot rely on receiving a 487
136
+ # (Request Terminated) response for the original request, as an
137
+ # RFC 2543-compliant UAS will not generate such a response.
138
+ # If there is no final response for the original request in
139
+ # 64*T1 seconds (T1 is defined in Section 17.1.1.1), the client
140
+ # SHOULD then consider the original transaction cancelled and
141
+ # SHOULD destroy the client transaction handling the original request.
142
+ def ty
143
+ return @ty if @ty
144
+ @ty = self.t1*64 || SipperConfigurator[:TransactionTimers][:ty]
145
+ end
146
+
147
+ # the starting value of timerG <IST>
148
+ def tg
149
+ return @tg if @tg
150
+ @tg = self.t1 || SipperConfigurator[:TransactionTimers][:tg]
151
+ end
152
+
153
+ # the value of timerH <IST>
154
+ def th
155
+ return @th if @th
156
+ @th = self.t1*64 || SipperConfigurator[:TransactionTimers][:th]
157
+ end
158
+
159
+ # the value if timerI <IST>
160
+ def ti
161
+ return @ti if @ti
162
+ @ti = self.t4 || SipperConfigurator[:TransactionTimers][:ti]
163
+ end
164
+
165
+ # the value if timerZ <IST>
166
+ # have a look at sipit bug http://bugs.sipit.net/show_bug.cgi?id=769
167
+ def tz
168
+ return @tz if @tz
169
+ @tz = self.t4 || SipperConfigurator[:TransactionTimers][:tz]
170
+ end
171
+
172
+ #--- <NICT>-------
173
+ def te
174
+ return @te if @te
175
+ @te = self.t1 || SipperConfigurator[:TransactionTimers][:te]
176
+ end
177
+
178
+ def tf
179
+ return @tf if @tf
180
+ @tf = self.t1*64 || SipperConfigurator[:TransactionTimers][:tf]
181
+ end
182
+
183
+ def tk
184
+ return @tk if @tk
185
+ @tk = self.t4 || SipperConfigurator[:TransactionTimers][:tk]
186
+ end
187
+ #--------
188
+
189
+ # the value if timerJ <NIST>
190
+ def tj
191
+ return @tj if @tj
192
+ @tj = self.t1*64 || SipperConfigurator[:TransactionTimers][:tj]
193
+ end
194
+
195
+ def _send_to_transport(msg)
196
+ if msg.is_request?
197
+ rd = @tu.get_request_destination()
198
+ else
199
+ rd = @tu.get_response_destination(msg)
200
+ end
201
+ @transport = rd[0] if rd[0]
202
+ @msg_sent = @transport.send(msg, @tp_flags, rd[1], rd[2])
203
+ logd("Now record the outgoing message from #{self.transaction_name}")
204
+ @tu.transaction_record("out", msg)
205
+ rescue
206
+ @transport_err = true
207
+ end
208
+
209
+ protected :_send_to_transport
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,84 @@
1
+ require 'sipper_configurator'
2
+
3
+ module Transport
4
+
5
+ # Pre filter : for incoming messages
6
+ class TransportIngressFilter
7
+
8
+ # Filter on anonymous Module because if the transport handler is defined inline then
9
+ # we load the string twice, once in an anonymous module and once in top
10
+ # level object. We do not want to register the transport handler twice.
11
+ def self.inherited(child)
12
+ TransportIngressFilter.registered_filters << child.new unless child.to_s =~ /^#<Module/
13
+ end
14
+
15
+ # default handler
16
+ def do_filter(msg)
17
+ msg
18
+ end
19
+
20
+ @registered_filters = []
21
+ class << self; attr_reader :registered_filters end
22
+ end
23
+
24
+ # Post filter : for outgoing messages
25
+ class TransportOutgressFilter
26
+
27
+ def self.inherited(child)
28
+ TransportOutgressFilter.registered_filters << child.new unless child.to_s =~ /^#<Module/
29
+ end
30
+
31
+ # default handler
32
+ def do_filter(msg)
33
+ msg
34
+ end
35
+
36
+ @registered_filters = []
37
+ class << self; attr_reader :registered_filters end
38
+ end
39
+
40
+
41
+ class BaseTransport
42
+
43
+ attr_reader :running, :ip, :port, :tid
44
+
45
+ @@out_oa = nil
46
+ @@in_oa = nil
47
+
48
+ def self.in_order=(order_arr)
49
+ @@in_oa = order_arr
50
+ end
51
+
52
+ def self.out_order=(order_arr)
53
+ @@out_oa = order_arr
54
+ end
55
+
56
+ def self.in_filters
57
+ if @@in_oa
58
+ return TransportIngressFilter.registered_filters.sort do |x,y|
59
+ (@@in_oa.index(x.class.name)?@@in_oa.index(x.class.name):@@in_oa.length) <=> (@@in_oa.index(y.class.name)?@@in_oa.index(y.class.name):@@in_oa.length)
60
+ end
61
+ else
62
+ TransportIngressFilter.registered_filters
63
+ end
64
+ end
65
+
66
+ def self.out_filters
67
+ if @@out_oa
68
+ return TransportOutgressFilter.registered_filters.sort do |x,y|
69
+ (@@out_oa.index(x.class.name)?@@out_oa.index(x.class.name):@@out_oa.length) <=> (@@out_oa.index(y.class.name)?@@out_oa.index(y.class.name):@@out_oa.length)
70
+ end
71
+ else
72
+ TransportOutgressFilter.registered_filters
73
+ end
74
+ end
75
+
76
+ def self.clear_all_filters
77
+ TransportIngressFilter.registered_filters.clear
78
+ TransportOutgressFilter.registered_filters.clear
79
+ end
80
+
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,19 @@
1
+ module SIP
2
+ module Transport
3
+
4
+ module ReliableTransport
5
+ def reliable?
6
+ true
7
+ end
8
+ end
9
+
10
+ module UnreliableTransport
11
+ def reliable?
12
+ false
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+
19
+
@@ -0,0 +1,67 @@
1
+ require 'ipaddr'
2
+
3
+ module Transport
4
+
5
+ # This class resolves the address for the next hop destination, looking up the DNS
6
+ # eventually and returning a tuple of addresses and transport to try. For now we just
7
+ # do a simple name resolve of one address.
8
+ #
9
+ # RFC
10
+ # The destination for the request is then computed. Unless there is local policy specifying
11
+ # otherwise, the destination MUST be determined by applying the DNS procedures described in [4]
12
+ # as follows. If the first element in the route set indicated a strict router (resulting in
13
+ # forming the request as described in Section 12.2.1.1), the procedures MUST be applied to the
14
+ # Request-URI of the request .
15
+ # Otherwise, the procedures are applied to the first Route header field value in the request
16
+ # (if one exists), or to the request's Request-URI if there is no Route header field present.
17
+ # These procedures yield an ordered set of address, port, and transports to attempt.
18
+ class TransportAndRouteResolver
19
+
20
+ IP = /^(\d{1,3}\.){3}\d{1,3}$/.freeze
21
+
22
+ def self.ascertain_transport_and_destination(msg)
23
+
24
+ # if controller preference set then we chose the transport directly
25
+ if stp = msg.attributes[:_sipper_controller_specified_transport]
26
+ tp = SIP::Locator[:Tm].get_udp_transport_with(stp[0], stp[1])
27
+ end
28
+
29
+ dest_uri = nil
30
+ if msg.is_request?
31
+ if msg.attributes[:_sipper_use_ruri_to_send]
32
+ dest_uri = msg.uri
33
+ elsif msg[:route] && msg[:route].length > 0
34
+ dest_uri = msg.route.uri
35
+ else
36
+ dest_uri = msg.uri
37
+ end
38
+ end
39
+ # now find out rip, rp and transport from destination uri.
40
+ # check out http uri resolution. Ruby URI library can be used here.
41
+ # Use the 3263 mechanism to look at the right destination and transport to use.
42
+ # For now fail if domain name is given.
43
+ # Assumptions-
44
+ # Assume 5060 if no port is given.
45
+ # Assume sip:ip:port or sip:user@ip:port or sip:user@ip
46
+ # Assume UDP transport
47
+
48
+ ip = dest_uri.host if dest_uri && dest_uri.respond_to?(:host)
49
+
50
+ return [tp, nil, nil] unless IP =~ ip
51
+
52
+ # simple valiadtion, todo must remove when you have 3263 lookup.
53
+ port = Integer((x=dest_uri.port) ? x : 5060)
54
+
55
+
56
+ # todo look for right transport, for now use udp
57
+
58
+ # here we check if tp is already set as a result of controller specification
59
+ unless tp
60
+ tp = SIP::Locator[:Tm].get_udp_transport_for(ip, port) if ip && port
61
+ end
62
+ [tp, ip, port]
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,156 @@
1
+ require 'socket'
2
+ require 'thread'
3
+ require 'monitor'
4
+ require 'util/message_fill'
5
+ require 'sip_logger'
6
+ require 'ruby_ext/object'
7
+ require 'transport/rel_unrel'
8
+ require 'transport/base_transport'
9
+ require 'message'
10
+
11
+ # todo have a base transport class and also have module Transport
12
+ module Transport
13
+ class UdpTransport < BaseTransport
14
+
15
+ include SipLogger
16
+ include SIP::Transport::UnreliableTransport # returns false for reliable? check.
17
+
18
+ private_class_method :new
19
+
20
+ MAX_RECV_BUFFER = 65500
21
+
22
+ @@instance = {}
23
+ @@class_lock = Monitor.new
24
+
25
+ # comment : need to synchronize on queue and running paramaters
26
+
27
+
28
+ def initialize(ip, port, external_q)
29
+ @tid = "UDP"
30
+ if external_q
31
+ @queue = external_q
32
+ else
33
+ @queue = Queue.new
34
+ end
35
+ @ip = ip
36
+ @port = port
37
+ @running = false
38
+ @running_lock = Monitor.new
39
+ logi("Created a new udptransport with #{@ip} and #{@port}")
40
+ end
41
+
42
+
43
+ def to_s
44
+ @str = "udptransport ip=#{@ip}, port=#{@port}" unless @str
45
+ @str
46
+ end
47
+
48
+ def UdpTransport.instance(i, p, q=nil)
49
+ @@class_lock.synchronize do
50
+ k = i.to_s + ":" + p.to_s
51
+ @@instance[k] = new(i, p, q) unless @@instance[k]
52
+ @@instance[k]
53
+ end
54
+ end
55
+
56
+
57
+ def start_transport
58
+ logi("Starting the transport #{self}")
59
+ #@running_lock.synchronize do
60
+ fail "Already running" if @running
61
+ @running = true
62
+ #end
63
+ t = Thread.new do
64
+ Thread.current[:name] = "UDPThread-"+@ip.to_s+"-"+@port.to_s
65
+ @sock = UDPSocket.new
66
+ @sock.bind(@ip, @port)
67
+ logd "binded ..#{@port}"
68
+ begin
69
+ loop do
70
+ #puts "starting the select loop.."
71
+ IO.select([@sock])
72
+ mesg = @sock.recvfrom_nonblock(MAX_RECV_BUFFER)
73
+ BaseTransport.in_filters.each do |in_filter|
74
+ logd("Ingress filter applied is #{in_filter.class.name}")
75
+ mesg[0] = in_filter.do_filter(mesg[0])
76
+ break unless mesg[0]
77
+ end
78
+ #["msg", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]]
79
+ if logger.debug?
80
+ logd("Message received is - ")
81
+ mesg.each_with_index {|x,i| logd(" > mesg[#{i}]=#{x}")}
82
+ end
83
+ if mesg[0]
84
+ mesg << [@ip, @port]
85
+ @queue << mesg
86
+ #logi("Message recvd on transport and enqueued on #{@queue}")
87
+ else
88
+ logi("Message recvd on transport does not have the payload or is consumed by a filter, not enquing")
89
+ end
90
+ break if mesg[0] =~ /poison dart/
91
+ end # loop
92
+ rescue => detail
93
+ logd detail.backtrace.join("\n")
94
+ loge("Exception #{detail} occured for #{self}")
95
+ @sock.close
96
+ break
97
+ end # exception
98
+ end
99
+ @t_thread = t
100
+ return t
101
+ end
102
+
103
+ def stop_transport
104
+ logi("Stopping transport #{self}")
105
+ #@running_lock.synchronize do
106
+ fail "Already stopped" unless @running
107
+ @running = false
108
+ #end
109
+ @sock.close
110
+ @t_thread.kill
111
+ k = @ip.to_s + ":" + @port.to_s
112
+ @@instance[k] = nil
113
+ end
114
+
115
+
116
+ def send(mesg, flags, *ipport)
117
+ if mesg.class <= ::Message
118
+ smesg = mesg.to_s
119
+ else
120
+ smesg = mesg
121
+ end
122
+ logi("Sending message #{smesg} using #{self} to ip=#{ipport[0]} and port=#{ipport[1]}")
123
+ if smesg =~ /_PH_/
124
+ logd("Now filling in message of class #{smesg.class}")
125
+ SipperUtil::MessageFill.sub(smesg, :trans=>@tid, :lip=>@ip, :lp=>@port.to_s)
126
+ else
127
+ logd("Nothing to fill in message of class #{smesg.class}")
128
+ end
129
+
130
+ BaseTransport.out_filters.each do |out_filter|
131
+ logd("Outgress filter applied is #{out_filter.class.name}")
132
+ smesg = out_filter.do_filter(smesg)
133
+ break unless smesg
134
+ end
135
+ logsip("O", ipport[0], ipport[1], @ip, @port, smesg)
136
+ if smesg
137
+ @sock.send(smesg, flags, *ipport)
138
+ else
139
+ logi("Not sending the message as it has probably been nilled out by a filter")
140
+ end
141
+ smesg # returns for recorder etc.
142
+ end
143
+
144
+ def get_next_message
145
+ @queue.pop
146
+ end
147
+
148
+
149
+ def running
150
+ @running_lock.synchronize do
151
+ return @running
152
+ end
153
+ end
154
+
155
+ end
156
+ end