app_test.c 13 KB

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