adccap3.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2018 Qualcomm Technologies, Inc.
  4. * All Rights Reserved.
  5. * Confidential and Proprietary - Qualcomm Technologies, Inc.
  6. * *****************************************************************               
  7. * 2013 Qualcomm Atheros, Inc.
  8. *--------------------------------------------------------------------*/
  9. /*====================================================================*
  10. *
  11. * adccap3.c - ADC Capture Utility III
  12. *
  13. * Contributor(s):
  14. * Charles Maier <cmaier@qca.qualcomm.com>
  15. * Nathaniel Houghton <nhoughto@qca.qualcomm.com>
  16. *
  17. *--------------------------------------------------------------------*/
  18. /*====================================================================*
  19. * system header files;
  20. *--------------------------------------------------------------------*/
  21. #include <unistd.h>
  22. #include <stdlib.h>
  23. #include <stdint.h>
  24. #include <limits.h>
  25. #include <ctype.h>
  26. #include <errno.h>
  27. #include <math.h>
  28. #include <sys/time.h>
  29. /*====================================================================*
  30. * custom header files;
  31. *--------------------------------------------------------------------*/
  32. #include "../tools/getoptv.h"
  33. #include "../tools/putoptv.h"
  34. #include "../tools/number.h"
  35. #include "../tools/symbol.h"
  36. #include "../tools/error.h"
  37. #include "../tools/flags.h"
  38. #include "../mme/mme.h"
  39. #include "../plc/plc.h"
  40. /*====================================================================*
  41. * custom source files;
  42. *--------------------------------------------------------------------*/
  43. #ifndef MAKEFILE
  44. #include "../plc/Devices.c"
  45. #include "../plc/Failure.c"
  46. #include "../plc/ReadMME.c"
  47. #include "../plc/ReadFMI.c"
  48. #include "../plc/SendMME.c"
  49. #endif
  50. #ifndef MAKEFILE
  51. #include "../tools/error.c"
  52. #include "../tools/getoptv.c"
  53. #include "../tools/putoptv.c"
  54. #include "../tools/version.c"
  55. #include "../tools/uintspec.c"
  56. #include "../tools/hexdump.c"
  57. #include "../tools/hexencode.c"
  58. #include "../tools/hexdecode.c"
  59. #include "../tools/hexstring.c"
  60. #include "../tools/todigit.c"
  61. #include "../tools/synonym.c"
  62. #include "../tools/checkfilename.c"
  63. #endif
  64. #ifndef MAKEFILE
  65. #include "../ether/openchannel.c"
  66. #include "../ether/closechannel.c"
  67. #include "../ether/readpacket.c"
  68. #include "../ether/sendpacket.c"
  69. #include "../ether/channel.c"
  70. #endif
  71. #ifndef MAKEFILE
  72. #include "../mme/MMECode.c"
  73. #include "../mme/EthernetHeader.c"
  74. #include "../mme/QualcommHeader1.c"
  75. #include "../mme/UnwantedMessage.c"
  76. #endif
  77. /*====================================================================*
  78. * program constants;
  79. *--------------------------------------------------------------------*/
  80. #define ADCCAP_GAIN 0
  81. #define ADCCAP_ACTION_GRAB 0
  82. #define ADCCAP_ACTION_SYNC 1
  83. #define ADCCAP_ACTION_READ 2
  84. #define ADCCAP_ACTION_AUTO 3
  85. #define ADCCAP_DATAITEMS_12_BIT 6528
  86. #define ADCCAP_DATAITEMS_10_BIT 3456
  87. #define ADCCAP_WAITTIME 0
  88. /*====================================================================*
  89. *
  90. * void print_data (int16_t list [], unsigned size);
  91. *
  92. * print the specified number of signed 12-bit integers on stdout;
  93. *
  94. * since the 12-bit vales are stored in a 16-bit variable, we must
  95. * shift left to set the 16-bit sign bit and shift right to restore
  96. * the original magnitude;
  97. *
  98. *--------------------------------------------------------------------*/
  99. static void print_data (uint16_t list [], unsigned size)
  100. {
  101. int shift_bits = 4;
  102. if (size == ADCCAP_DATAITEMS_10_BIT)
  103. shift_bits = 6;
  104. while (size--)
  105. {
  106. int16_t number = LE16TOH (* list++);
  107. number <<= shift_bits;
  108. number >>= shift_bits;
  109. printf ("%d\n", number);
  110. }
  111. return;
  112. }
  113. /*====================================================================*
  114. *
  115. * signed collect (struct plc * plc, void * memory, unsigned extent)
  116. *
  117. * collect and print captured ADC data;
  118. *
  119. *--------------------------------------------------------------------*/
  120. static signed collect (struct plc * plc)
  121. {
  122. struct channel * channel = (struct channel *) (plc->channel);
  123. struct message * message = (struct message *) (plc->message);
  124. #ifndef __GNUC__
  125. #pragma pack (push,1)
  126. #endif
  127. struct __packed vs_debug_info_request
  128. {
  129. struct ethernet_hdr ethernet;
  130. struct qualcomm_fmi qualcomm;
  131. uint32_t MME_LEN;
  132. uint16_t REQ_TYPE;
  133. uint32_t RESERVED;
  134. uint8_t COMMAND;
  135. uint8_t RXGAIN;
  136. uint16_t STARTINDEX;
  137. uint16_t VALUECOUNT;
  138. uint8_t COUPLING_TYPE;
  139. uint8_t RESERVED2;
  140. }
  141. * request = (struct vs_debug_info_request *) (message);
  142. struct __packed vs_debug_info_confirm
  143. {
  144. struct ethernet_hdr ethernet;
  145. struct qualcomm_fmi qualcomm;
  146. uint8_t MSTATUS;
  147. uint8_t RSVD1;
  148. uint32_t MME_LEN;
  149. uint16_t REQ_TYPE;
  150. uint8_t RSVD2;
  151. uint8_t COUPLING;
  152. uint8_t COMMAND;
  153. uint8_t GAIN;
  154. uint16_t STARTINDEX;
  155. uint16_t VALUECOUNT;
  156. uint16_t ACTUALCOUNT;
  157. uint16_t DATA [1];
  158. }
  159. * confirm = (struct vs_debug_info_confirm *) (message);
  160. #ifndef __GNUC__
  161. #pragma pack (pop)
  162. #endif
  163. memset (message, 0, sizeof (* message));
  164. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  165. QualcommHeader1 (& request->qualcomm, 1, (VS_DEBUG_INFO | MMTYPE_REQ));
  166. request->REQ_TYPE = HTOLE16 (2);
  167. request->COMMAND = plc->action;
  168. request->RXGAIN = plc->module;
  169. request->COUPLING_TYPE = plc->coupling;
  170. plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  171. if (SendMME (plc) <= 0)
  172. {
  173. error (1, ECANCELED, CHANNEL_CANTSEND);
  174. }
  175. if (ReadFMI (plc, 1, (VS_DEBUG_INFO | MMTYPE_CNF)) <= 0)
  176. {
  177. error (1, ECANCELED, CHANNEL_CANTREAD);
  178. }
  179. confirm = (struct vs_debug_info_confirm *) (plc->content);
  180. if (confirm->MSTATUS)
  181. {
  182. Failure (plc, PLC_WONTDOIT);
  183. }
  184. print_data (confirm->DATA, LE16TOH (confirm->ACTUALCOUNT));
  185. free (plc->content);
  186. plc->content = NULL;
  187. return (0);
  188. }
  189. /*====================================================================*
  190. *
  191. * signed capture (struct plc * plc)
  192. *
  193. * send ADC capture request and return; the capbure request may be
  194. * either 'immediate' or 'after sync';
  195. *
  196. *--------------------------------------------------------------------*/
  197. signed capture (struct plc * plc)
  198. {
  199. struct channel * channel = (struct channel *) (plc->channel);
  200. struct message * message = (struct message *) (plc->message);
  201. #ifndef __GNUC__
  202. #pragma pack (push,1)
  203. #endif
  204. struct __packed vs_debug_info_request
  205. {
  206. struct ethernet_hdr ethernet;
  207. struct qualcomm_fmi qualcomm;
  208. uint32_t MME_LEN;
  209. uint16_t REQ_TYPE;
  210. uint32_t RESERVED1;
  211. uint8_t COMMAND;
  212. uint8_t RXGAIN;
  213. uint16_t STARTINDEX;
  214. uint16_t VALUECOUNT;
  215. uint8_t COUPLING_TYPE;
  216. uint8_t RESERVED2;
  217. }
  218. * request = (struct vs_debug_info_request *) (message);
  219. struct __packed vs_debug_info_confirm
  220. {
  221. struct ethernet_hdr ethernet;
  222. struct qualcomm_fmi qualcomm;
  223. uint8_t MSTATUS;
  224. uint8_t RSVD1;
  225. uint32_t MME_LEN;
  226. uint16_t REQ_TYPE;
  227. uint8_t RSVD2;
  228. uint8_t COUPLING_TYPE;
  229. uint8_t COMMAND;
  230. uint16_t STARTINDEX;
  231. uint16_t VALUECOUNT;
  232. uint16_t ACTUALCOUNT;
  233. uint8_t GAIN;
  234. }
  235. * confirm = (struct vs_debug_info_confirm *) (message);
  236. #ifndef __GNUC__
  237. #pragma pack (pop)
  238. #endif
  239. memset (message, 0, sizeof (* message));
  240. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  241. QualcommHeader1 (& request->qualcomm, 1, (VS_DEBUG_INFO | MMTYPE_REQ));
  242. request->REQ_TYPE = HTOLE16 (2);
  243. request->COMMAND = plc->action;
  244. request->RXGAIN = plc->module;
  245. request->COUPLING_TYPE = plc->coupling;
  246. plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  247. if (SendMME (plc) <= 0)
  248. {
  249. error (1, ECANCELED, CHANNEL_CANTSEND);
  250. }
  251. if (ReadFMI (plc, 1, (VS_DEBUG_INFO | MMTYPE_CNF)) <= 0)
  252. {
  253. error (1, ECANCELED, CHANNEL_CANTREAD);
  254. }
  255. confirm = (struct vs_debug_info_confirm *) (plc->content);
  256. if (confirm->MSTATUS)
  257. {
  258. Failure (plc, PLC_WONTDOIT);
  259. }
  260. free (plc->content);
  261. plc->content = NULL;
  262. return (0);
  263. }
  264. /*====================================================================*
  265. *
  266. * int main (int argc, char const * argv[]);
  267. *
  268. * plc.hostaction holds the ADC capture operation code;
  269. *
  270. * plc.module holds the RX Gain value; a value of 255 means
  271. * "reuse previous RX Gain value";
  272. *
  273. * plc.index holds the ADC data offset;
  274. * plc.count holds the ADC data length;
  275. *
  276. *--------------------------------------------------------------------*/
  277. int main (int argc, char const * argv [])
  278. {
  279. extern struct channel channel;
  280. extern const struct _term_ devices [];
  281. static char const * optv [] =
  282. {
  283. "c:ei:g:np:qrst:vw:",
  284. "device [device] [> stdout]",
  285. "Qualcomm Atheros ADC Capture Utility",
  286. "c n\tcoupling is (n) [" LITERAL (PLCOUPLING) "]",
  287. "e\tredirect stderr messages to stdout",
  288. #if defined (WINPCAP) || defined (LIBPCAP)
  289. "i n\thost interface is (n) [" LITERAL (CHANNEL_ETHNUMBER) "]",
  290. #else
  291. "i s\thost interface is (s) [" LITERAL (CHANNEL_ETHDEVICE) "]",
  292. #endif
  293. "n\tcapture now",
  294. "r\tcollect data (read)",
  295. "s\tcapture after sync",
  296. "g n\tgain is (n) [" LITERAL (ADCCAP_GAIN) "]",
  297. "q\tquiet mode",
  298. "t n\tread timeout is (n) milliseconds [" LITERAL (CHANNEL_TIMEOUT) "]",
  299. "v\tverbose mode",
  300. "w n\twait time is (n) seconds [" LITERAL (ADCCAP_WAITTIME) "]",
  301. (char const *) (0)
  302. };
  303. static const struct _term_ coupling [] =
  304. {
  305. {
  306. "alt",
  307. "1"
  308. },
  309. {
  310. "pri",
  311. "0"
  312. }
  313. };
  314. #include "../plc/plc.c"
  315. signed timer = ADCCAP_WAITTIME;
  316. signed c;
  317. if (getenv (PLCDEVICE))
  318. {
  319. #if defined (WINPCAP) || defined (LIBPCAP)
  320. channel.ifindex = atoi (getenv (PLCDEVICE));
  321. #else
  322. channel.ifname = strdup (getenv (PLCDEVICE));
  323. #endif
  324. }
  325. optind = 1;
  326. plc.module = ADCCAP_GAIN;
  327. while (~ (c = getoptv (argc, argv, optv)))
  328. {
  329. switch (c)
  330. {
  331. case 'c':
  332. plc.coupling = (byte) (uintspec (synonym (optarg, coupling, SIZEOF (coupling)), 0, UCHAR_MAX));
  333. break;
  334. case 'e':
  335. dup2 (STDOUT_FILENO, STDERR_FILENO);
  336. break;
  337. case 'g':
  338. plc.module = (uint8_t) (uintspec (optarg, 0, 31));
  339. break;
  340. case 'i':
  341. #if defined (WINPCAP) || defined (LIBPCAP)
  342. channel.ifindex = atoi (optarg);
  343. #else
  344. channel.ifname = optarg;
  345. #endif
  346. break;
  347. case 'n':
  348. plc.action = ADCCAP_ACTION_GRAB;
  349. break;
  350. case 'q':
  351. _setbits (channel.flags, CHANNEL_SILENCE);
  352. _setbits (plc.flags, PLC_SILENCE);
  353. break;
  354. case 'r':
  355. plc.action = ADCCAP_ACTION_READ;
  356. break;
  357. case 's':
  358. plc.action = ADCCAP_ACTION_SYNC;
  359. break;
  360. case 't':
  361. channel.timeout = (signed) (uintspec (optarg, 0, UINT_MAX));
  362. break;
  363. case 'v':
  364. _setbits (channel.flags, CHANNEL_VERBOSE);
  365. _setbits (plc.flags, PLC_VERBOSE);
  366. break;
  367. case 'w':
  368. timer = (signed) (uintspec (optarg, 0, 30));
  369. break;
  370. default:
  371. break;
  372. }
  373. }
  374. argc -= optind;
  375. argv += optind;
  376. openchannel (& channel);
  377. if (! (plc.message = malloc (sizeof (* plc.message))))
  378. {
  379. error (1, errno, PLC_NOMEMORY);
  380. }
  381. if ((argc) && (* argv))
  382. {
  383. if (! hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices))))
  384. {
  385. error (1, errno, PLC_BAD_MAC, * argv);
  386. }
  387. argc--;
  388. argv++;
  389. }
  390. if ((argc) || (* argv))
  391. {
  392. error (1, ENOTSUP, ERROR_TOOMANY);
  393. }
  394. else if (timer)
  395. {
  396. plc.action = ADCCAP_ACTION_GRAB;
  397. capture (& plc);
  398. error (0, 0, "pause %d seconds ...", timer);
  399. sleep (timer);
  400. plc.action = ADCCAP_ACTION_READ;
  401. collect (& plc);
  402. }
  403. else if (plc.action == ADCCAP_ACTION_READ)
  404. {
  405. collect (& plc);
  406. }
  407. else if (plc.action == ADCCAP_ACTION_GRAB)
  408. {
  409. capture (& plc);
  410. }
  411. else if (plc.action == ADCCAP_ACTION_SYNC)
  412. {
  413. capture (& plc);
  414. }
  415. else
  416. {
  417. error (1, EINVAL, "Bad command");
  418. }
  419. free (plc.content);
  420. free (plc.message);
  421. closechannel (& channel);
  422. exit (0);
  423. }