app_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. * Russell Bryant <russelb@clemson.edu>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*! \file
  20. *
  21. * \brief Applications to test connection and produce report in text file
  22. *
  23. * \author Mark Spencer <markster@digium.com>
  24. * \author Russell Bryant <russelb@clemson.edu>
  25. *
  26. * \ingroup applications
  27. */
  28. /*** MODULEINFO
  29. <support_level>extended</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  33. #include <sys/stat.h>
  34. #include "asterisk/paths.h" /* use ast_config_AST_LOG_DIR */
  35. #include "asterisk/channel.h"
  36. #include "asterisk/module.h"
  37. #include "asterisk/lock.h"
  38. #include "asterisk/app.h"
  39. #include "asterisk/pbx.h"
  40. #include "asterisk/utils.h"
  41. #include "asterisk/format_cache.h"
  42. /*** DOCUMENTATION
  43. <application name="TestServer" language="en_US">
  44. <synopsis>
  45. Execute Interface Test Server.
  46. </synopsis>
  47. <syntax />
  48. <description>
  49. <para>Perform test server function and write call report. Results stored in
  50. <filename>/var/log/asterisk/testreports/&lt;testid&gt;-server.txt</filename></para>
  51. </description>
  52. <see-also>
  53. <ref type="application">TestClient</ref>
  54. </see-also>
  55. </application>
  56. <application name="TestClient" language="en_US">
  57. <synopsis>
  58. Execute Interface Test Client.
  59. </synopsis>
  60. <syntax>
  61. <parameter name="testid" required="true">
  62. <para>An ID to identify this test.</para>
  63. </parameter>
  64. </syntax>
  65. <description>
  66. <para>Executes test client with given <replaceable>testid</replaceable>. Results stored in
  67. <filename>/var/log/asterisk/testreports/&lt;testid&gt;-client.txt</filename></para>
  68. </description>
  69. <see-also>
  70. <ref type="application">TestServer</ref>
  71. </see-also>
  72. </application>
  73. ***/
  74. static char *tests_app = "TestServer";
  75. static char *testc_app = "TestClient";
  76. static int measurenoise(struct ast_channel *chan, int ms, char *who)
  77. {
  78. int res=0;
  79. int mssofar;
  80. int noise=0;
  81. int samples=0;
  82. int x;
  83. short *foo;
  84. struct timeval start;
  85. struct ast_frame *f;
  86. struct ast_format *rformat;
  87. rformat = ao2_bump(ast_channel_readformat(chan));
  88. if (ast_set_read_format(chan, ast_format_slin)) {
  89. ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
  90. ao2_cleanup(rformat);
  91. return -1;
  92. }
  93. start = ast_tvnow();
  94. for(;;) {
  95. mssofar = ast_tvdiff_ms(ast_tvnow(), start);
  96. if (mssofar > ms)
  97. break;
  98. res = ast_waitfor(chan, ms - mssofar);
  99. if (res < 1)
  100. break;
  101. f = ast_read(chan);
  102. if (!f) {
  103. res = -1;
  104. break;
  105. }
  106. if ((f->frametype == AST_FRAME_VOICE) &&
  107. (ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) {
  108. foo = (short *)f->data.ptr;
  109. for (x=0;x<f->samples;x++) {
  110. noise += abs(foo[x]);
  111. samples++;
  112. }
  113. }
  114. ast_frfree(f);
  115. }
  116. if (rformat) {
  117. if (ast_set_read_format(chan, rformat)) {
  118. ast_log(LOG_NOTICE, "Unable to restore original format!\n");
  119. ao2_ref(rformat, -1);
  120. return -1;
  121. }
  122. ao2_ref(rformat, -1);
  123. }
  124. if (res < 0)
  125. return res;
  126. if (!samples) {
  127. ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
  128. return -1;
  129. }
  130. ast_debug(1, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
  131. return (noise / samples);
  132. }
  133. static int sendnoise(struct ast_channel *chan, int ms)
  134. {
  135. int res;
  136. res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
  137. if (!res) {
  138. res = ast_waitfordigit(chan, ms);
  139. ast_tonepair_stop(chan);
  140. }
  141. return res;
  142. }
  143. static int testclient_exec(struct ast_channel *chan, const char *data)
  144. {
  145. int res = 0;
  146. const char *testid=data;
  147. char fn[80];
  148. char serverver[80];
  149. FILE *f;
  150. /* Check for test id */
  151. if (ast_strlen_zero(testid)) {
  152. ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
  153. return -1;
  154. }
  155. if (ast_channel_state(chan) != AST_STATE_UP)
  156. res = ast_answer(chan);
  157. /* Wait a few just to be sure things get started */
  158. res = ast_safe_sleep(chan, 3000);
  159. /* Transmit client version */
  160. if (!res)
  161. res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
  162. ast_debug(1, "Transmit client version\n");
  163. /* Read server version */
  164. ast_debug(1, "Read server version\n");
  165. if (!res)
  166. res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
  167. if (res > 0)
  168. res = 0;
  169. ast_debug(1, "server version: %s\n", serverver);
  170. if (res > 0)
  171. res = 0;
  172. if (!res)
  173. res = ast_safe_sleep(chan, 1000);
  174. /* Send test id */
  175. if (!res)
  176. res = ast_dtmf_stream(chan, NULL, testid, 0, 0);
  177. if (!res)
  178. res = ast_dtmf_stream(chan, NULL, "#", 0, 0);
  179. ast_debug(1, "send test identifier: %s\n", testid);
  180. if ((res >=0) && (!ast_strlen_zero(testid))) {
  181. /* Make the directory to hold the test results in case it's not there */
  182. snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
  183. ast_mkdir(fn, 0777);
  184. snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
  185. if ((f = fopen(fn, "w+"))) {
  186. setlinebuf(f);
  187. fprintf(f, "CLIENTCHAN: %s\n", ast_channel_name(chan));
  188. fprintf(f, "CLIENTTEST ID: %s\n", testid);
  189. fprintf(f, "ANSWER: PASS\n");
  190. res = 0;
  191. if (!res) {
  192. /* Step 1: Wait for "1" */
  193. ast_debug(1, "TestClient: 2. Wait DTMF 1\n");
  194. res = ast_waitfordigit(chan, 3000);
  195. fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS");
  196. if (res == '1')
  197. res = 0;
  198. else
  199. res = -1;
  200. }
  201. if (!res) {
  202. res = ast_safe_sleep(chan, 1000);
  203. }
  204. if (!res) {
  205. /* Step 2: Send "2" */
  206. ast_debug(1, "TestClient: 2. Send DTMF 2\n");
  207. res = ast_dtmf_stream(chan, NULL, "2", 0, 0);
  208. fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS");
  209. if (res > 0)
  210. res = 0;
  211. }
  212. if (!res) {
  213. /* Step 3: Wait one second */
  214. ast_debug(1, "TestClient: 3. Wait one second\n");
  215. res = ast_safe_sleep(chan, 1000);
  216. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  217. if (res > 0)
  218. res = 0;
  219. }
  220. if (!res) {
  221. /* Step 4: Measure noise */
  222. ast_debug(1, "TestClient: 4. Measure noise\n");
  223. res = measurenoise(chan, 5000, "TestClient");
  224. fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  225. if (res > 0)
  226. res = 0;
  227. }
  228. if (!res) {
  229. /* Step 5: Wait for "4" */
  230. ast_debug(1, "TestClient: 5. Wait DTMF 4\n");
  231. res = ast_waitfordigit(chan, 3000);
  232. fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS");
  233. if (res == '4')
  234. res = 0;
  235. else
  236. res = -1;
  237. }
  238. if (!res) {
  239. /* Step 6: Transmit tone noise */
  240. ast_debug(1, "TestClient: 6. Transmit tone\n");
  241. res = sendnoise(chan, 6000);
  242. fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
  243. }
  244. if (!res || (res == '5')) {
  245. /* Step 7: Wait for "5" */
  246. ast_debug(1, "TestClient: 7. Wait DTMF 5\n");
  247. if (!res)
  248. res = ast_waitfordigit(chan, 3000);
  249. fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS");
  250. if (res == '5')
  251. res = 0;
  252. else
  253. res = -1;
  254. }
  255. if (!res) {
  256. /* Step 8: Wait one second */
  257. ast_debug(1, "TestClient: 8. Wait one second\n");
  258. res = ast_safe_sleep(chan, 1000);
  259. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  260. if (res > 0)
  261. res = 0;
  262. }
  263. if (!res) {
  264. /* Step 9: Measure noise */
  265. ast_debug(1, "TestClient: 9. Measure tone\n");
  266. res = measurenoise(chan, 4000, "TestClient");
  267. fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  268. if (res > 0)
  269. res = 0;
  270. }
  271. if (!res) {
  272. /* Step 10: Send "7" */
  273. ast_debug(1, "TestClient: 10. Send DTMF 7\n");
  274. res = ast_dtmf_stream(chan, NULL, "7", 0, 0);
  275. fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS");
  276. if (res > 0)
  277. res =0;
  278. }
  279. if (!res) {
  280. /* Step 11: Wait for "8" */
  281. ast_debug(1, "TestClient: 11. Wait DTMF 8\n");
  282. res = ast_waitfordigit(chan, 3000);
  283. fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS");
  284. if (res == '8')
  285. res = 0;
  286. else
  287. res = -1;
  288. }
  289. if (!res) {
  290. res = ast_safe_sleep(chan, 1000);
  291. }
  292. if (!res) {
  293. /* Step 12: Hangup! */
  294. ast_debug(1, "TestClient: 12. Hangup\n");
  295. }
  296. ast_debug(1, "-- TEST COMPLETE--\n");
  297. fprintf(f, "-- END TEST--\n");
  298. fclose(f);
  299. res = -1;
  300. } else
  301. res = -1;
  302. } else {
  303. ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", ast_channel_name(chan));
  304. res = -1;
  305. }
  306. return res;
  307. }
  308. static int testserver_exec(struct ast_channel *chan, const char *data)
  309. {
  310. int res = 0;
  311. char testid[80]="";
  312. FILE *f;
  313. if (ast_channel_state(chan) != AST_STATE_UP)
  314. res = ast_answer(chan);
  315. /* Read version */
  316. ast_debug(1, "Read client version\n");
  317. if (!res)
  318. res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
  319. if (res > 0)
  320. res = 0;
  321. ast_debug(1, "client version: %s\n", testid);
  322. ast_debug(1, "Transmit server version\n");
  323. res = ast_safe_sleep(chan, 1000);
  324. if (!res)
  325. res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
  326. if (res > 0)
  327. res = 0;
  328. if (!res)
  329. res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
  330. ast_debug(1, "read test identifier: %s\n", testid);
  331. /* Check for sneakyness */
  332. if (strchr(testid, '/'))
  333. res = -1;
  334. if ((res >=0) && (!ast_strlen_zero(testid))) {
  335. char fn[PATH_MAX];
  336. /* Got a Test ID! Whoo hoo! */
  337. /* Make the directory to hold the test results in case it's not there */
  338. snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
  339. ast_mkdir(fn, 0777);
  340. snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
  341. if ((f = fopen(fn, "w+"))) {
  342. setlinebuf(f);
  343. fprintf(f, "SERVERCHAN: %s\n", ast_channel_name(chan));
  344. fprintf(f, "SERVERTEST ID: %s\n", testid);
  345. fprintf(f, "ANSWER: PASS\n");
  346. ast_debug(1, "Processing Test ID '%s'\n", testid);
  347. res = ast_safe_sleep(chan, 1000);
  348. if (!res) {
  349. /* Step 1: Send "1" */
  350. ast_debug(1, "TestServer: 1. Send DTMF 1\n");
  351. res = ast_dtmf_stream(chan, NULL, "1", 0,0 );
  352. fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS");
  353. if (res > 0)
  354. res = 0;
  355. }
  356. if (!res) {
  357. /* Step 2: Wait for "2" */
  358. ast_debug(1, "TestServer: 2. Wait DTMF 2\n");
  359. res = ast_waitfordigit(chan, 3000);
  360. fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS");
  361. if (res == '2')
  362. res = 0;
  363. else
  364. res = -1;
  365. }
  366. if (!res) {
  367. /* Step 3: Measure noise */
  368. ast_debug(1, "TestServer: 3. Measure noise\n");
  369. res = measurenoise(chan, 6000, "TestServer");
  370. fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  371. if (res > 0)
  372. res = 0;
  373. }
  374. if (!res) {
  375. /* Step 4: Send "4" */
  376. ast_debug(1, "TestServer: 4. Send DTMF 4\n");
  377. res = ast_dtmf_stream(chan, NULL, "4", 0, 0);
  378. fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS");
  379. if (res > 0)
  380. res = 0;
  381. }
  382. if (!res) {
  383. /* Step 5: Wait one second */
  384. ast_debug(1, "TestServer: 5. Wait one second\n");
  385. res = ast_safe_sleep(chan, 1000);
  386. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  387. if (res > 0)
  388. res = 0;
  389. }
  390. if (!res) {
  391. /* Step 6: Measure noise */
  392. ast_debug(1, "TestServer: 6. Measure tone\n");
  393. res = measurenoise(chan, 4000, "TestServer");
  394. fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  395. if (res > 0)
  396. res = 0;
  397. }
  398. if (!res) {
  399. /* Step 7: Send "5" */
  400. ast_debug(1, "TestServer: 7. Send DTMF 5\n");
  401. res = ast_dtmf_stream(chan, NULL, "5", 0, 0);
  402. fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS");
  403. if (res > 0)
  404. res = 0;
  405. }
  406. if (!res) {
  407. /* Step 8: Transmit tone noise */
  408. ast_debug(1, "TestServer: 8. Transmit tone\n");
  409. res = sendnoise(chan, 6000);
  410. fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
  411. }
  412. if (!res || (res == '7')) {
  413. /* Step 9: Wait for "7" */
  414. ast_debug(1, "TestServer: 9. Wait DTMF 7\n");
  415. if (!res)
  416. res = ast_waitfordigit(chan, 3000);
  417. fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS");
  418. if (res == '7')
  419. res = 0;
  420. else
  421. res = -1;
  422. }
  423. if (!res) {
  424. res = ast_safe_sleep(chan, 1000);
  425. }
  426. if (!res) {
  427. /* Step 10: Send "8" */
  428. ast_debug(1, "TestServer: 10. Send DTMF 8\n");
  429. res = ast_dtmf_stream(chan, NULL, "8", 0, 0);
  430. fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS");
  431. if (res > 0)
  432. res = 0;
  433. }
  434. if (!res) {
  435. /* Step 11: Wait for hangup to arrive! */
  436. ast_debug(1, "TestServer: 11. Waiting for hangup\n");
  437. res = ast_safe_sleep(chan, 10000);
  438. fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL");
  439. }
  440. ast_log(LOG_NOTICE, "-- TEST COMPLETE--\n");
  441. fprintf(f, "-- END TEST--\n");
  442. fclose(f);
  443. res = -1;
  444. } else
  445. res = -1;
  446. } else {
  447. ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", ast_channel_name(chan));
  448. res = -1;
  449. }
  450. return res;
  451. }
  452. static int unload_module(void)
  453. {
  454. int res;
  455. res = ast_unregister_application(testc_app);
  456. res |= ast_unregister_application(tests_app);
  457. return res;
  458. }
  459. static int load_module(void)
  460. {
  461. int res;
  462. res = ast_register_application_xml(testc_app, testclient_exec);
  463. res |= ast_register_application_xml(tests_app, testserver_exec);
  464. return res;
  465. }
  466. AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Interface Test Application");