app_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  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. #include "asterisk.h"
  29. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  30. #include <sys/stat.h>
  31. #include "asterisk/paths.h" /* use ast_config_AST_LOG_DIR */
  32. #include "asterisk/channel.h"
  33. #include "asterisk/module.h"
  34. #include "asterisk/lock.h"
  35. #include "asterisk/app.h"
  36. #include "asterisk/pbx.h"
  37. #include "asterisk/utils.h"
  38. static char *tests_descrip =
  39. " TestServer(): Perform test server function and write call report.\n"
  40. "Results stored in /var/log/asterisk/testreports/<testid>-server.txt";
  41. static char *tests_app = "TestServer";
  42. static char *tests_synopsis = "Execute Interface Test Server";
  43. static char *testc_descrip =
  44. " TestClient(testid): Executes test client with given testid.\n"
  45. "Results stored in /var/log/asterisk/testreports/<testid>-client.txt";
  46. static char *testc_app = "TestClient";
  47. static char *testc_synopsis = "Execute Interface Test Client";
  48. static int measurenoise(struct ast_channel *chan, int ms, char *who)
  49. {
  50. int res=0;
  51. int mssofar;
  52. int noise=0;
  53. int samples=0;
  54. int x;
  55. short *foo;
  56. struct timeval start;
  57. struct ast_frame *f;
  58. int rformat;
  59. rformat = chan->readformat;
  60. if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
  61. ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
  62. return -1;
  63. }
  64. start = ast_tvnow();
  65. for(;;) {
  66. mssofar = ast_tvdiff_ms(ast_tvnow(), start);
  67. if (mssofar > ms)
  68. break;
  69. res = ast_waitfor(chan, ms - mssofar);
  70. if (res < 1)
  71. break;
  72. f = ast_read(chan);
  73. if (!f) {
  74. res = -1;
  75. break;
  76. }
  77. if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
  78. foo = (short *)f->data.ptr;
  79. for (x=0;x<f->samples;x++) {
  80. noise += abs(foo[x]);
  81. samples++;
  82. }
  83. }
  84. ast_frfree(f);
  85. }
  86. if (rformat) {
  87. if (ast_set_read_format(chan, rformat)) {
  88. ast_log(LOG_NOTICE, "Unable to restore original format!\n");
  89. return -1;
  90. }
  91. }
  92. if (res < 0)
  93. return res;
  94. if (!samples) {
  95. ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
  96. return -1;
  97. }
  98. ast_debug(1, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
  99. return (noise / samples);
  100. }
  101. static int sendnoise(struct ast_channel *chan, int ms)
  102. {
  103. int res;
  104. res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
  105. if (!res) {
  106. res = ast_waitfordigit(chan, ms);
  107. ast_tonepair_stop(chan);
  108. }
  109. return res;
  110. }
  111. static int testclient_exec(struct ast_channel *chan, void *data)
  112. {
  113. int res = 0;
  114. char *testid=data;
  115. char fn[80];
  116. char serverver[80];
  117. FILE *f;
  118. /* Check for test id */
  119. if (ast_strlen_zero(testid)) {
  120. ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
  121. return -1;
  122. }
  123. if (chan->_state != AST_STATE_UP)
  124. res = ast_answer(chan);
  125. /* Wait a few just to be sure things get started */
  126. res = ast_safe_sleep(chan, 3000);
  127. /* Transmit client version */
  128. if (!res)
  129. res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
  130. ast_debug(1, "Transmit client version\n");
  131. /* Read server version */
  132. ast_debug(1, "Read server version\n");
  133. if (!res)
  134. res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
  135. if (res > 0)
  136. res = 0;
  137. ast_debug(1, "server version: %s\n", serverver);
  138. if (res > 0)
  139. res = 0;
  140. if (!res)
  141. res = ast_safe_sleep(chan, 1000);
  142. /* Send test id */
  143. if (!res)
  144. res = ast_dtmf_stream(chan, NULL, testid, 0, 0);
  145. if (!res)
  146. res = ast_dtmf_stream(chan, NULL, "#", 0, 0);
  147. ast_debug(1, "send test identifier: %s\n", testid);
  148. if ((res >=0) && (!ast_strlen_zero(testid))) {
  149. /* Make the directory to hold the test results in case it's not there */
  150. snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
  151. ast_mkdir(fn, 0777);
  152. snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
  153. if ((f = fopen(fn, "w+"))) {
  154. setlinebuf(f);
  155. fprintf(f, "CLIENTCHAN: %s\n", chan->name);
  156. fprintf(f, "CLIENTTEST ID: %s\n", testid);
  157. fprintf(f, "ANSWER: PASS\n");
  158. res = 0;
  159. if (!res) {
  160. /* Step 1: Wait for "1" */
  161. ast_debug(1, "TestClient: 2. Wait DTMF 1\n");
  162. res = ast_waitfordigit(chan, 3000);
  163. fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS");
  164. if (res == '1')
  165. res = 0;
  166. else
  167. res = -1;
  168. }
  169. if (!res) {
  170. res = ast_safe_sleep(chan, 1000);
  171. }
  172. if (!res) {
  173. /* Step 2: Send "2" */
  174. ast_debug(1, "TestClient: 2. Send DTMF 2\n");
  175. res = ast_dtmf_stream(chan, NULL, "2", 0, 0);
  176. fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS");
  177. if (res > 0)
  178. res = 0;
  179. }
  180. if (!res) {
  181. /* Step 3: Wait one second */
  182. ast_debug(1, "TestClient: 3. Wait one second\n");
  183. res = ast_safe_sleep(chan, 1000);
  184. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  185. if (res > 0)
  186. res = 0;
  187. }
  188. if (!res) {
  189. /* Step 4: Measure noise */
  190. ast_debug(1, "TestClient: 4. Measure noise\n");
  191. res = measurenoise(chan, 5000, "TestClient");
  192. fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  193. if (res > 0)
  194. res = 0;
  195. }
  196. if (!res) {
  197. /* Step 5: Wait for "4" */
  198. ast_debug(1, "TestClient: 5. Wait DTMF 4\n");
  199. res = ast_waitfordigit(chan, 3000);
  200. fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS");
  201. if (res == '4')
  202. res = 0;
  203. else
  204. res = -1;
  205. }
  206. if (!res) {
  207. /* Step 6: Transmit tone noise */
  208. ast_debug(1, "TestClient: 6. Transmit tone\n");
  209. res = sendnoise(chan, 6000);
  210. fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
  211. }
  212. if (!res || (res == '5')) {
  213. /* Step 7: Wait for "5" */
  214. ast_debug(1, "TestClient: 7. Wait DTMF 5\n");
  215. if (!res)
  216. res = ast_waitfordigit(chan, 3000);
  217. fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS");
  218. if (res == '5')
  219. res = 0;
  220. else
  221. res = -1;
  222. }
  223. if (!res) {
  224. /* Step 8: Wait one second */
  225. ast_debug(1, "TestClient: 8. Wait one second\n");
  226. res = ast_safe_sleep(chan, 1000);
  227. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  228. if (res > 0)
  229. res = 0;
  230. }
  231. if (!res) {
  232. /* Step 9: Measure noise */
  233. ast_debug(1, "TestClient: 9. Measure tone\n");
  234. res = measurenoise(chan, 4000, "TestClient");
  235. fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  236. if (res > 0)
  237. res = 0;
  238. }
  239. if (!res) {
  240. /* Step 10: Send "7" */
  241. ast_debug(1, "TestClient: 10. Send DTMF 7\n");
  242. res = ast_dtmf_stream(chan, NULL, "7", 0, 0);
  243. fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS");
  244. if (res > 0)
  245. res =0;
  246. }
  247. if (!res) {
  248. /* Step 11: Wait for "8" */
  249. ast_debug(1, "TestClient: 11. Wait DTMF 8\n");
  250. res = ast_waitfordigit(chan, 3000);
  251. fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS");
  252. if (res == '8')
  253. res = 0;
  254. else
  255. res = -1;
  256. }
  257. if (!res) {
  258. res = ast_safe_sleep(chan, 1000);
  259. }
  260. if (!res) {
  261. /* Step 12: Hangup! */
  262. ast_debug(1, "TestClient: 12. Hangup\n");
  263. }
  264. ast_debug(1, "-- TEST COMPLETE--\n");
  265. fprintf(f, "-- END TEST--\n");
  266. fclose(f);
  267. res = -1;
  268. } else
  269. res = -1;
  270. } else {
  271. ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
  272. res = -1;
  273. }
  274. return res;
  275. }
  276. static int testserver_exec(struct ast_channel *chan, void *data)
  277. {
  278. int res = 0;
  279. char testid[80]="";
  280. char fn[80];
  281. FILE *f;
  282. if (chan->_state != AST_STATE_UP)
  283. res = ast_answer(chan);
  284. /* Read version */
  285. ast_debug(1, "Read client version\n");
  286. if (!res)
  287. res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
  288. if (res > 0)
  289. res = 0;
  290. ast_debug(1, "client version: %s\n", testid);
  291. ast_debug(1, "Transmit server version\n");
  292. res = ast_safe_sleep(chan, 1000);
  293. if (!res)
  294. res = ast_dtmf_stream(chan, NULL, "8378*1#", 0, 0);
  295. if (res > 0)
  296. res = 0;
  297. if (!res)
  298. res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
  299. ast_debug(1, "read test identifier: %s\n", testid);
  300. /* Check for sneakyness */
  301. if (strchr(testid, '/'))
  302. res = -1;
  303. if ((res >=0) && (!ast_strlen_zero(testid))) {
  304. /* Got a Test ID! Whoo hoo! */
  305. /* Make the directory to hold the test results in case it's not there */
  306. snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
  307. ast_mkdir(fn, 0777);
  308. snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
  309. if ((f = fopen(fn, "w+"))) {
  310. setlinebuf(f);
  311. fprintf(f, "SERVERCHAN: %s\n", chan->name);
  312. fprintf(f, "SERVERTEST ID: %s\n", testid);
  313. fprintf(f, "ANSWER: PASS\n");
  314. ast_debug(1, "Processing Test ID '%s'\n", testid);
  315. res = ast_safe_sleep(chan, 1000);
  316. if (!res) {
  317. /* Step 1: Send "1" */
  318. ast_debug(1, "TestServer: 1. Send DTMF 1\n");
  319. res = ast_dtmf_stream(chan, NULL, "1", 0,0 );
  320. fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS");
  321. if (res > 0)
  322. res = 0;
  323. }
  324. if (!res) {
  325. /* Step 2: Wait for "2" */
  326. ast_debug(1, "TestServer: 2. Wait DTMF 2\n");
  327. res = ast_waitfordigit(chan, 3000);
  328. fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS");
  329. if (res == '2')
  330. res = 0;
  331. else
  332. res = -1;
  333. }
  334. if (!res) {
  335. /* Step 3: Measure noise */
  336. ast_debug(1, "TestServer: 3. Measure noise\n");
  337. res = measurenoise(chan, 6000, "TestServer");
  338. fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  339. if (res > 0)
  340. res = 0;
  341. }
  342. if (!res) {
  343. /* Step 4: Send "4" */
  344. ast_debug(1, "TestServer: 4. Send DTMF 4\n");
  345. res = ast_dtmf_stream(chan, NULL, "4", 0, 0);
  346. fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS");
  347. if (res > 0)
  348. res = 0;
  349. }
  350. if (!res) {
  351. /* Step 5: Wait one second */
  352. ast_debug(1, "TestServer: 5. Wait one second\n");
  353. res = ast_safe_sleep(chan, 1000);
  354. fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
  355. if (res > 0)
  356. res = 0;
  357. }
  358. if (!res) {
  359. /* Step 6: Measure noise */
  360. ast_debug(1, "TestServer: 6. Measure tone\n");
  361. res = measurenoise(chan, 4000, "TestServer");
  362. fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
  363. if (res > 0)
  364. res = 0;
  365. }
  366. if (!res) {
  367. /* Step 7: Send "5" */
  368. ast_debug(1, "TestServer: 7. Send DTMF 5\n");
  369. res = ast_dtmf_stream(chan, NULL, "5", 0, 0);
  370. fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS");
  371. if (res > 0)
  372. res = 0;
  373. }
  374. if (!res) {
  375. /* Step 8: Transmit tone noise */
  376. ast_debug(1, "TestServer: 8. Transmit tone\n");
  377. res = sendnoise(chan, 6000);
  378. fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
  379. }
  380. if (!res || (res == '7')) {
  381. /* Step 9: Wait for "7" */
  382. ast_debug(1, "TestServer: 9. Wait DTMF 7\n");
  383. if (!res)
  384. res = ast_waitfordigit(chan, 3000);
  385. fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS");
  386. if (res == '7')
  387. res = 0;
  388. else
  389. res = -1;
  390. }
  391. if (!res) {
  392. res = ast_safe_sleep(chan, 1000);
  393. }
  394. if (!res) {
  395. /* Step 10: Send "8" */
  396. ast_debug(1, "TestServer: 10. Send DTMF 8\n");
  397. res = ast_dtmf_stream(chan, NULL, "8", 0, 0);
  398. fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS");
  399. if (res > 0)
  400. res = 0;
  401. }
  402. if (!res) {
  403. /* Step 11: Wait for hangup to arrive! */
  404. ast_debug(1, "TestServer: 11. Waiting for hangup\n");
  405. res = ast_safe_sleep(chan, 10000);
  406. fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL");
  407. }
  408. ast_log(LOG_NOTICE, "-- TEST COMPLETE--\n");
  409. fprintf(f, "-- END TEST--\n");
  410. fclose(f);
  411. res = -1;
  412. } else
  413. res = -1;
  414. } else {
  415. ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
  416. res = -1;
  417. }
  418. return res;
  419. }
  420. static int unload_module(void)
  421. {
  422. int res;
  423. res = ast_unregister_application(testc_app);
  424. res |= ast_unregister_application(tests_app);
  425. return res;
  426. }
  427. static int load_module(void)
  428. {
  429. int res;
  430. res = ast_register_application(testc_app, testclient_exec, testc_synopsis, testc_descrip);
  431. res |= ast_register_application(tests_app, testserver_exec, tests_synopsis, tests_descrip);
  432. return res;
  433. }
  434. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Interface Test Application");