serial.c.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <?xml version='1.0' encoding='iso-8859-1'?>
  2. <!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
  3. <html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
  4. <head>
  5. <title>
  6. serial.c
  7. </title>
  8. <meta http-equiv='content-type' content='text/html;iso-8859-1'/>
  9. <meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
  10. <meta name='author' content='cmaier@cmassoc.net'/>
  11. <meta name='robots' content='noindex,nofollow'/>
  12. <link href='toolkit.css' rel='stylesheet' type='text/css'/>
  13. </head>
  14. <body>
  15. <div class='headerlink'>
  16. [<a href='sendpacket.c.html' title=' sendpacket.c '>PREV</a>]
  17. [<a href='toolkit.html' title=' Index '>HOME</a>]
  18. [<a href='set32bitmap.c.html' title=' set32bitmap.c '>NEXT</a>]
  19. </div>
  20. <pre>
  21. /*====================================================================*
  22. *
  23. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  24. *
  25. * All rights reserved.
  26. *
  27. * Redistribution and use in source and binary forms, with or
  28. * without modification, are permitted (subject to the limitations
  29. * in the disclaimer below) provided that the following conditions
  30. * are met:
  31. *
  32. * * Redistributions of source code must retain the above copyright
  33. * notice, this list of conditions and the following disclaimer.
  34. *
  35. * * Redistributions in binary form must reproduce the above
  36. * copyright notice, this list of conditions and the following
  37. * disclaimer in the documentation and/or other materials
  38. * provided with the distribution.
  39. *
  40. * * Neither the name of Qualcomm Atheros nor the names of
  41. * its contributors may be used to endorse or promote products
  42. * derived from this software without specific prior written
  43. * permission.
  44. *
  45. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
  46. * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
  47. * COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
  48. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  50. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  51. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  52. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  53. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  56. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  57. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. *
  60. *--------------------------------------------------------------------*/
  61. /*====================================================================*
  62. *
  63. * serial.c - Atheros Serial Line Command Buffer Management;
  64. *
  65. * serial.h
  66. *
  67. * this module contains a serial line command buffer and functions
  68. * to encode and decode it in different formats and send or receive
  69. * it over the serial line;
  70. *
  71. * Contributor(s):
  72. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  73. *
  74. *--------------------------------------------------------------------*/
  75. #ifndef SERIAL_SOURCE
  76. #define SERIAL_SOURCE
  77. /*====================================================================*
  78. * system header files;
  79. *--------------------------------------------------------------------*/
  80. #include &lt;unistd.h&gt;
  81. #include &lt;stdlib.h&gt;
  82. #include &lt;stdint.h&gt;
  83. #include &lt;memory.h&gt;
  84. #include &lt;errno.h&gt;
  85. #if defined (WIN32)
  86. #include &lt;Windows.h&gt;
  87. #endif
  88. /*====================================================================*
  89. * custom header files;
  90. *--------------------------------------------------------------------*/
  91. #include &quot;../serial/serial.h&quot;
  92. #include &quot;../tools/number.h&quot;
  93. #include &quot;../tools/types.h&quot;
  94. #include &quot;../tools/flags.h&quot;
  95. #include &quot;../tools/error.h&quot;
  96. /*====================================================================*
  97. * private variables;
  98. *--------------------------------------------------------------------*/
  99. struct command command;
  100. /*====================================================================*
  101. *
  102. * void clearcommand ();
  103. *
  104. * serial.h
  105. *
  106. * erase the current command by writing 0s;
  107. *
  108. *--------------------------------------------------------------------*/
  109. void clearcommand ()
  110. {
  111. extern struct command command;
  112. memset (&amp;command, 0, sizeof (command));
  113. return;
  114. }
  115. /*====================================================================*
  116. *
  117. * void sendcommand (struct _file_ * port, flag_t flags);
  118. *
  119. * serial.h
  120. *
  121. * echo then send the command;
  122. *
  123. *--------------------------------------------------------------------*/
  124. void sendcommand (struct _file_ * port, flag_t flags)
  125. {
  126. extern struct command command;
  127. if (_anyset (flags, UART_VERBOSE))
  128. {
  129. write (STDERR_FILENO, command.buffer, command.length);
  130. write (STDERR_FILENO, &quot;\n&quot;, sizeof (char));
  131. }
  132. if (write (port-&gt;file, command.buffer, command.length) != (signed)(command.length))
  133. {
  134. error (1, errno, &quot;Can't write to %s&quot;, port-&gt;name);
  135. }
  136. clearcommand ();
  137. return;
  138. }
  139. /*====================================================================*
  140. *
  141. * void readcommand (struct _file_ * port, flag_t flags);
  142. *
  143. * serial.h
  144. *
  145. * read response serial line and log the response;
  146. *
  147. *--------------------------------------------------------------------*/
  148. void readcommand (struct _file_ * port, flag_t flags)
  149. {
  150. extern struct command command;
  151. #if defined (WIN32)
  152. PAUSE (250);
  153. memset (&amp;command, 0, sizeof (command));
  154. command.length = read (port-&gt;file, command.buffer, sizeof (command.buffer));
  155. if (command.length &lt; 0)
  156. {
  157. error (1, errno, &quot;Bad response from %s&quot;, port-&gt;name);
  158. }
  159. if (command.length == 0)
  160. {
  161. error (1, errno, &quot;No response from %s&quot;, port-&gt;name);
  162. }
  163. #else
  164. struct timeval tv;
  165. fd_set rfd;
  166. ssize_t tmp;
  167. memset (&amp;command, 0, sizeof (command));
  168. while (!strchr (command.buffer, '\r'))
  169. {
  170. tv.tv_sec = 1;
  171. tv.tv_usec = 0;
  172. FD_ZERO (&amp;rfd);
  173. FD_SET (port-&gt;file, &amp;rfd);
  174. if (select (port-&gt;file + 1, &amp;rfd, NULL, NULL, &amp;tv) != 1)
  175. {
  176. error (1, errno, &quot;Read timeout&quot;);
  177. }
  178. tmp = read (port-&gt;file, command.buffer + command.length, sizeof (command.buffer) - command.length - 1);
  179. if (tmp &lt; 0)
  180. {
  181. error (1, errno, &quot;Could not read %s&quot;, port-&gt;name);
  182. }
  183. command.length += tmp;
  184. command.buffer [command.length] = '\0';
  185. }
  186. #endif
  187. if (_anyset (flags, UART_VERBOSE))
  188. {
  189. write (STDERR_FILENO, command.buffer, command.length);
  190. write (STDERR_FILENO, &quot;\n&quot;, sizeof (char));
  191. }
  192. if (!memcmp (command.buffer, &quot;ERROR&quot;, 5))
  193. {
  194. error (1, ECANCELED, &quot;Device refused request&quot;);
  195. }
  196. return;
  197. }
  198. /*====================================================================*
  199. *
  200. * void insert (char c);
  201. *
  202. * serial.h
  203. *
  204. * insert a character into the command buffer at the current buffer
  205. * position then increment the buffer position pointer;
  206. *
  207. *--------------------------------------------------------------------*/
  208. void insert (char c)
  209. {
  210. extern struct command command;
  211. if (command.length &lt; sizeof (command.buffer))
  212. {
  213. command.buffer [command.length++] = c;
  214. }
  215. return;
  216. }
  217. /*====================================================================*
  218. *
  219. * unsigned readframe (signed fd, void * memory, size_t extent);
  220. *
  221. * serial.h
  222. *
  223. * read a file and convert hexadecimal octets to binary bytes then
  224. * store them in consecutive memory locations up to a given length;
  225. * return the actual number of bytes stored;
  226. *
  227. * digits may be consecutive or separated by white space consisting
  228. * of spaces, tabs, linefeeds, carriage returns, formfeeds or other
  229. * characters such as punctuation; script-style comments are treated
  230. * as white space;
  231. *
  232. *--------------------------------------------------------------------*/
  233. static signed fdgetc (signed fd)
  234. {
  235. char c;
  236. return ((read (fd, &amp;c, sizeof (c)) == sizeof (c))? c: EOF);
  237. }
  238. size_t readframe (signed fd, void * memory, size_t extent)
  239. {
  240. unsigned digits = 0;
  241. uint8_t * origin = (uint8_t *)(memory);
  242. uint8_t * offset = (uint8_t *)(memory);
  243. signed c = EOF;
  244. while ((extent) &amp;&amp; ((c = fdgetc (fd)) != EOF) &amp;&amp; (c != ';'))
  245. {
  246. if (isspace (c))
  247. {
  248. continue;
  249. }
  250. if (c == '#')
  251. {
  252. do
  253. {
  254. c = fdgetc (fd);
  255. }
  256. while ((c != '\n') &amp;&amp; (c != EOF));
  257. continue;
  258. }
  259. if (c == '/')
  260. {
  261. c = fdgetc (fd);
  262. if (c == '/')
  263. {
  264. do
  265. {
  266. c = fdgetc (fd);
  267. }
  268. while ((c != '\n') &amp;&amp; (c != EOF));
  269. continue;
  270. }
  271. if (c == '*')
  272. {
  273. while ((c != '/') &amp;&amp; (c != EOF))
  274. {
  275. while ((c != '*') &amp;&amp; (c != EOF))
  276. {
  277. c = fdgetc (fd);
  278. }
  279. c = fdgetc (fd);
  280. }
  281. continue;
  282. }
  283. continue;
  284. }
  285. if (isxdigit (c))
  286. {
  287. *offset = c;
  288. offset++;
  289. digits++;
  290. extent--;
  291. continue;
  292. }
  293. error (1, ENOTSUP, &quot;Illegal hex digit '%c' (0x%02X) in source&quot;, c, c);
  294. }
  295. if (digits &amp; 1)
  296. {
  297. error (1, ENOTSUP, &quot;Odd number of hex digits (%d) in source&quot;, digits);
  298. }
  299. return (offset - origin);
  300. }
  301. /*====================================================================*
  302. *
  303. * void decode (void const * memory, size_t extent);
  304. *
  305. * serial.h
  306. *
  307. * copy a memory region into command buffer at the current position
  308. * and increment the buffer position pointer; convert bytes to hex
  309. * octets;
  310. *
  311. *--------------------------------------------------------------------*/
  312. void decode (void const * memory, size_t extent)
  313. {
  314. extern struct command command;
  315. register byte * binary = (byte *)(memory);
  316. while ((command.length &lt; sizeof (command.buffer)) &amp;&amp; (extent--))
  317. {
  318. insert (DIGITS_HEX [(*binary &gt;&gt; 4) &amp; 0x0F]);
  319. insert (DIGITS_HEX [(*binary &gt;&gt; 0) &amp; 0x0F]);
  320. binary++;
  321. }
  322. return;
  323. }
  324. /*====================================================================*
  325. *
  326. * void encode (void * memory, size_t extent);
  327. *
  328. * serial.h
  329. *
  330. * encode a memory region from the current command buffer position
  331. * and increment the command buffer position pointer;
  332. *
  333. *--------------------------------------------------------------------*/
  334. void encode (void * memory, size_t extent)
  335. {
  336. extern struct command command;
  337. register byte * binary = (byte *)(memory);
  338. unsigned digit;
  339. while ((command.offset &lt; command.length) &amp;&amp; (extent--))
  340. {
  341. *binary = 0;
  342. if ((digit = todigit (command.buffer [command.offset++])) &gt; 0x0F)
  343. {
  344. command.buffer [command.offset] = (char)(0);
  345. error (1, EINVAL, &quot;[%s]1&quot;, command.buffer);
  346. }
  347. *binary |= digit &lt;&lt; 4;
  348. if ((digit = todigit (command.buffer [command.offset++])) &gt; 0x0F)
  349. {
  350. command.buffer [command.offset] = (char)(0);
  351. error (1, EINVAL, &quot;[%s]2&quot;, command.buffer);
  352. }
  353. *binary |= digit;
  354. binary++;
  355. }
  356. return;
  357. }
  358. /*====================================================================*
  359. *
  360. * void string (char * string);
  361. *
  362. * serial.h
  363. *
  364. * extract the contents of a quoted string string from the command
  365. * buffer; it assumes that the current char is a quote character;
  366. *
  367. * copy command buffer characters to an external string; start a the
  368. * current buffer position and continue until the buffer exhausts or
  369. * a closing quote is encountered; NUL terminate the string;
  370. *
  371. *--------------------------------------------------------------------*/
  372. void string (char * string)
  373. {
  374. extern struct command command;
  375. while ((command.offset &lt; command.length) &amp;&amp; (command.buffer [command.offset] != '\&quot;'))
  376. {
  377. *string++ = command.buffer [command.offset++];
  378. }
  379. *string = (char)(0);
  380. return;
  381. }
  382. /*====================================================================*
  383. *
  384. * uint64_t hextoint (unsigned bytes);
  385. *
  386. * serial.h
  387. *
  388. * this function is used to extract a hexadecimal integer string as
  389. * an integer of specified length; an error occurs of the string is
  390. * to long for the specified integer size in bytes;
  391. *
  392. *--------------------------------------------------------------------*/
  393. uint64_t hextoint (unsigned bytes)
  394. {
  395. extern struct command command;
  396. uint64_t limit = -1;
  397. uint64_t value = 0;
  398. unsigned radix = 16;
  399. unsigned digit = 0;
  400. if (bytes &lt; sizeof (limit))
  401. {
  402. limit &lt;&lt;= (bytes &lt;&lt; 3);
  403. limit = ~limit;
  404. }
  405. while ((digit = todigit (command.buffer [command.offset])) &lt; radix)
  406. {
  407. value *= radix;
  408. value += digit;
  409. command.offset++;
  410. if (value &gt; limit)
  411. {
  412. command.buffer [command.offset] = (char)(0);
  413. error (1, EINVAL, &quot;[%s] exceeds %d bits&quot;, command.buffer, (bytes &lt;&lt; 3));
  414. }
  415. }
  416. return (value);
  417. }
  418. /*====================================================================*
  419. *
  420. * void mustbe (char c);
  421. *
  422. * serial.h
  423. *
  424. * test the character at the current buffer position; advance the
  425. * buffer position pointer and return true on match; terminate the
  426. * program on mismatch or exhausted buffer;
  427. *
  428. *--------------------------------------------------------------------*/
  429. void mustbe (char c)
  430. {
  431. extern struct command command;
  432. if (command.offset &gt;= command.length)
  433. {
  434. command.buffer [command.offset] = (char)(0);
  435. error (1, EINVAL, &quot;[%s]: overflow&quot;, command.buffer);
  436. }
  437. if (command.buffer [command.offset++] != (c))
  438. {
  439. command.buffer [command.offset] = (char)(0);
  440. error (1, EINVAL, &quot;[%s]: expecting 0x%02X&quot;, command.buffer, c);
  441. }
  442. return;
  443. }
  444. /*====================================================================*
  445. *
  446. *--------------------------------------------------------------------*/
  447. #endif
  448. </pre>
  449. <div class='footerlink'>
  450. [<a href='sendpacket.c.html' title=' sendpacket.c '>PREV</a>]
  451. [<a href='toolkit.html' title=' Index '>HOME</a>]
  452. [<a href='set32bitmap.c.html' title=' set32bitmap.c '>NEXT</a>]
  453. </div>
  454. </body>
  455. </html>