switch_eavesdrop.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #include <switch.h>
  2. #include <test/switch_test.h>
  3. static switch_status_t test_detect_long_tone_in_file(const char *filepath, int rate, int freq, int ptime) {
  4. teletone_multi_tone_t mt;
  5. teletone_tone_map_t map;
  6. int16_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
  7. switch_size_t len = (rate * ptime / 1000) /*packet len in samples */ * 8; /*length of chunk that must contain tone*/
  8. switch_size_t fin = 0;
  9. switch_status_t status;
  10. switch_file_handle_t fh = { 0 };
  11. uint8_t fail = 0, gaps = 0, audio = 0;
  12. status = switch_core_file_open(&fh, filepath, 1, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
  13. if (status != SWITCH_STATUS_SUCCESS) {
  14. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open file [%s]\n", filepath);
  15. return SWITCH_STATUS_FALSE;
  16. }
  17. mt.sample_rate = rate;
  18. map.freqs[0] = (teletone_process_t)freq;
  19. teletone_multi_tone_init(&mt, &map);
  20. len = (rate * 2 / 100) /*packet len in samples */ * 8;
  21. while (switch_core_file_read(&fh, &data, &len) == SWITCH_STATUS_SUCCESS) {
  22. fin += len;
  23. /*skip silence at the beginning of the file, 1 second max. */
  24. if (!teletone_multi_tone_detect(&mt, data, len)) {
  25. if ((fin > rate && !audio) || gaps > 30) {
  26. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many gaps in audio or no tone detected 1st second. [%" SWITCH_SIZE_T_FMT "][%d]\n", fin, gaps);
  27. fail = 1;
  28. break;
  29. }
  30. gaps++;
  31. continue;
  32. } else {
  33. audio++;
  34. }
  35. }
  36. switch_core_file_close(&fh);
  37. if (fail) {
  38. return SWITCH_STATUS_FALSE;
  39. }
  40. return SWITCH_STATUS_SUCCESS;
  41. }
  42. FST_CORE_BEGIN("./conf_eavesdrop")
  43. {
  44. FST_SUITE_BEGIN(switch_eavesdrop)
  45. {
  46. FST_SETUP_BEGIN()
  47. {
  48. fst_requires_module("mod_loopback");
  49. fst_requires_module("mod_sofia");
  50. switch_core_set_variable("link_ip", switch_core_get_variable("local_ip_v4"));
  51. }
  52. FST_SETUP_END()
  53. FST_TEARDOWN_BEGIN()
  54. {
  55. }
  56. FST_TEARDOWN_END()
  57. FST_TEST_BEGIN(test_eavesdrop_bridged_same_ptime_20ms)
  58. {
  59. switch_core_session_t *session1 = NULL;
  60. switch_core_session_t *session2 = NULL;
  61. switch_core_session_t *session3 = NULL;
  62. switch_channel_t *channel1 = NULL;
  63. switch_channel_t *channel2 = NULL;
  64. switch_channel_t *channel3 = NULL;
  65. switch_status_t status;
  66. switch_call_cause_t cause;
  67. switch_stream_handle_t stream = { 0 };
  68. char eavesdrop_command[256] = { 0 };
  69. char rec_path[1024];
  70. char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
  71. char eaves_dialstr[512] = { 0 };
  72. switch_uuid_str(rec_uuid, sizeof(rec_uuid));
  73. /*parked 20 ms ptime */
  74. status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  75. fst_requires(session1);
  76. fst_check(status == SWITCH_STATUS_SUCCESS);
  77. channel1 = switch_core_session_get_channel(session1);
  78. fst_requires(channel1);
  79. snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid);
  80. /*eavesdropper 20 ms ptime*/
  81. status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  82. fst_requires(session2);
  83. fst_check(status == SWITCH_STATUS_SUCCESS);
  84. channel2 = switch_core_session_get_channel(session2);
  85. fst_requires(channel2);
  86. /*milliwatt tone 20 ms ptime*/
  87. status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  88. fst_requires(session3);
  89. fst_check(status == SWITCH_STATUS_SUCCESS);
  90. channel3 = switch_core_session_get_channel(session3);
  91. fst_requires(channel3);
  92. SWITCH_STANDARD_STREAM(stream);
  93. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
  94. switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
  95. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  96. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
  97. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  98. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  99. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
  100. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  101. switch_safe_free(stream.data);
  102. sleep(5); // it will record ~ 5 secs
  103. snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
  104. fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
  105. fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS);
  106. unlink(rec_path);
  107. switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
  108. switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
  109. switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
  110. switch_core_session_rwunlock(session1);
  111. switch_core_session_rwunlock(session2);
  112. switch_core_session_rwunlock(session3);
  113. }
  114. FST_TEST_END()
  115. FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_20ms_30ms)
  116. {
  117. switch_core_session_t *session1 = NULL;
  118. switch_core_session_t *session2 = NULL;
  119. switch_core_session_t *session3 = NULL;
  120. switch_channel_t *channel1 = NULL;
  121. switch_channel_t *channel2 = NULL;
  122. switch_channel_t *channel3 = NULL;
  123. switch_status_t status;
  124. switch_call_cause_t cause;
  125. switch_stream_handle_t stream = { 0 };
  126. char eavesdrop_command[256] = { 0 };
  127. char rec_path[1024];
  128. char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
  129. char eaves_dialstr[512] = { 0 };
  130. switch_uuid_str(rec_uuid, sizeof(rec_uuid));
  131. /*parked 20 ms ptime */
  132. status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  133. fst_requires(session1);
  134. fst_check(status == SWITCH_STATUS_SUCCESS);
  135. channel1 = switch_core_session_get_channel(session1);
  136. fst_requires(channel1);
  137. snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid);
  138. /*eavesdropper 20 ms ptime*/
  139. status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  140. fst_requires(session2);
  141. fst_check(status == SWITCH_STATUS_SUCCESS);
  142. channel2 = switch_core_session_get_channel(session2);
  143. fst_requires(channel2);
  144. /*milliwatt tone 30 ms ptime*/
  145. status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332222", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  146. fst_requires(session3);
  147. fst_check(status == SWITCH_STATUS_SUCCESS);
  148. channel3 = switch_core_session_get_channel(session3);
  149. fst_requires(channel3);
  150. SWITCH_STANDARD_STREAM(stream);
  151. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
  152. switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
  153. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  154. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
  155. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  156. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  157. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
  158. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  159. switch_safe_free(stream.data);
  160. sleep(5); // it will record ~ 5 secs
  161. snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
  162. fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
  163. fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS);
  164. unlink(rec_path);
  165. switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
  166. switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
  167. switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
  168. switch_core_session_rwunlock(session1);
  169. switch_core_session_rwunlock(session2);
  170. switch_core_session_rwunlock(session3);
  171. }
  172. FST_TEST_END()
  173. FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_30ms_20ms)
  174. {
  175. switch_core_session_t *session1 = NULL;
  176. switch_core_session_t *session2 = NULL;
  177. switch_core_session_t *session3 = NULL;
  178. switch_channel_t *channel1 = NULL;
  179. switch_channel_t *channel2 = NULL;
  180. switch_channel_t *channel3 = NULL;
  181. switch_status_t status;
  182. switch_call_cause_t cause;
  183. switch_stream_handle_t stream = { 0 };
  184. char eavesdrop_command[256] = { 0 };
  185. char rec_path[1024];
  186. char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
  187. char eaves_dialstr[512] = { 0 };
  188. switch_uuid_str(rec_uuid, sizeof(rec_uuid));
  189. /*parked 30 ms ptime */
  190. status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  191. fst_requires(session1);
  192. fst_check(status == SWITCH_STATUS_SUCCESS);
  193. channel1 = switch_core_session_get_channel(session1);
  194. fst_requires(channel1);
  195. snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid);
  196. /*eavesdropper 30 ms ptime*/
  197. status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  198. fst_requires(session2);
  199. fst_check(status == SWITCH_STATUS_SUCCESS);
  200. channel2 = switch_core_session_get_channel(session2);
  201. fst_requires(channel2);
  202. /*milliwatt tone 20 ms ptime*/
  203. status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  204. fst_requires(session3);
  205. fst_check(status == SWITCH_STATUS_SUCCESS);
  206. channel3 = switch_core_session_get_channel(session3);
  207. fst_requires(channel3);
  208. SWITCH_STANDARD_STREAM(stream);
  209. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
  210. switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
  211. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  212. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
  213. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  214. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  215. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
  216. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  217. switch_safe_free(stream.data);
  218. sleep(5); // it will record ~ 5 secs
  219. snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
  220. fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
  221. fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS);
  222. unlink(rec_path);
  223. switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
  224. switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
  225. switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
  226. switch_core_session_rwunlock(session1);
  227. switch_core_session_rwunlock(session2);
  228. switch_core_session_rwunlock(session3);
  229. }
  230. FST_TEST_END()
  231. FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_reneg)
  232. {
  233. switch_core_session_t *session1 = NULL;
  234. switch_core_session_t *session2 = NULL;
  235. switch_core_session_t *session3 = NULL;
  236. switch_channel_t *channel1 = NULL;
  237. switch_channel_t *channel2 = NULL;
  238. switch_channel_t *channel3 = NULL;
  239. switch_status_t status;
  240. switch_call_cause_t cause;
  241. switch_stream_handle_t stream = { 0 };
  242. char eavesdrop_command[256] = { 0 };
  243. char rec_path[1024];
  244. char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
  245. char eaves_dialstr[512] = { 0 };
  246. switch_uuid_str(rec_uuid, sizeof(rec_uuid));
  247. /*parked 30 ms ptime */
  248. status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  249. fst_requires(session1);
  250. fst_check(status == SWITCH_STATUS_SUCCESS);
  251. channel1 = switch_core_session_get_channel(session1);
  252. fst_requires(channel1);
  253. snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid);
  254. /*eavesdropper 30 ms ptime*/
  255. status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  256. fst_requires(session2);
  257. fst_check(status == SWITCH_STATUS_SUCCESS);
  258. channel2 = switch_core_session_get_channel(session2);
  259. fst_requires(channel2);
  260. /*milliwatt tone 20 ms ptime*/
  261. status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
  262. fst_requires(session3);
  263. fst_check(status == SWITCH_STATUS_SUCCESS);
  264. channel3 = switch_core_session_get_channel(session3);
  265. fst_requires(channel3);
  266. SWITCH_STANDARD_STREAM(stream);
  267. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
  268. switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
  269. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  270. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
  271. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  272. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  273. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
  274. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  275. sleep(2);
  276. // codec reneg for eavesdropper
  277. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  278. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@20i", switch_core_session_get_uuid(session2));
  279. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  280. sleep(1);
  281. // codec reneg for eavesdroppee
  282. memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
  283. switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@30i", switch_core_session_get_uuid(session3));
  284. switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
  285. switch_safe_free(stream.data);
  286. sleep(2);
  287. snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
  288. fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
  289. fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS);
  290. unlink(rec_path);
  291. switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
  292. switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
  293. switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
  294. switch_core_session_rwunlock(session1);
  295. switch_core_session_rwunlock(session2);
  296. switch_core_session_rwunlock(session3);
  297. }
  298. FST_TEST_END()
  299. }
  300. FST_SUITE_END()
  301. }
  302. FST_CORE_END()