app_test.c 14 KB

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