plcwait.c.html 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  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. plcwait.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='PLCTopologyPrint.c.html' title=' PLCTopologyPrint.c '>PREV</a>]
  17. [<a href='toolkit.html' title=' Index '>HOME</a>]
  18. [<a href='PrintRule.c.html' title=' PrintRule.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. /*====================================================================*&quot;
  62. *
  63. * plcwait.c -
  64. *
  65. *
  66. * Contributor(s):
  67. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  68. *
  69. *--------------------------------------------------------------------*/
  70. /*====================================================================*&quot;
  71. * system header files;
  72. *--------------------------------------------------------------------*/
  73. #include &lt;unistd.h&gt;
  74. #include &lt;stdlib.h&gt;
  75. #include &lt;stdint.h&gt;
  76. #include &lt;limits.h&gt;
  77. #include &lt;sys/time.h&gt;
  78. /*====================================================================*
  79. * custom header files;
  80. *--------------------------------------------------------------------*/
  81. #include &quot;../tools/getoptv.h&quot;
  82. #include &quot;../tools/putoptv.h&quot;
  83. #include &quot;../tools/memory.h&quot;
  84. #include &quot;../tools/number.h&quot;
  85. #include &quot;../tools/symbol.h&quot;
  86. #include &quot;../tools/types.h&quot;
  87. #include &quot;../tools/flags.h&quot;
  88. #include &quot;../tools/files.h&quot;
  89. #include &quot;../tools/timer.h&quot;
  90. #include &quot;../tools/error.h&quot;
  91. #include &quot;../plc/plc.h&quot;
  92. /*====================================================================*
  93. * custom source files;
  94. *--------------------------------------------------------------------*/
  95. #ifndef MAKEFILE
  96. #include &quot;../tools/getoptv.c&quot;
  97. #include &quot;../tools/putoptv.c&quot;
  98. #include &quot;../tools/version.c&quot;
  99. #include &quot;../tools/uintspec.c&quot;
  100. #include &quot;../tools/hexdump.c&quot;
  101. #include &quot;../tools/hexencode.c&quot;
  102. #include &quot;../tools/hexdecode.c&quot;
  103. #include &quot;../tools/todigit.c&quot;
  104. #include &quot;../tools/checkfilename.c&quot;
  105. #include &quot;../tools/synonym.c&quot;
  106. #include &quot;../tools/error.c&quot;
  107. #endif
  108. #ifndef MAKEFILE
  109. #include &quot;../plc/Confirm.c&quot;
  110. #include &quot;../plc/Display.c&quot;
  111. #include &quot;../plc/Failure.c&quot;
  112. #include &quot;../plc/ReadMME.c&quot;
  113. #include &quot;../plc/Request.c&quot;
  114. #include &quot;../plc/SendMME.c&quot;
  115. #include &quot;../plc/Devices.c&quot;
  116. #endif
  117. #ifndef MAKEFILE
  118. #include &quot;../ether/openchannel.c&quot;
  119. #include &quot;../ether/closechannel.c&quot;
  120. #include &quot;../ether/readpacket.c&quot;
  121. #include &quot;../ether/sendpacket.c&quot;
  122. #include &quot;../ether/channel.c&quot;
  123. #endif
  124. #ifndef MAKEFILE
  125. #include &quot;../mme/MMECode.c&quot;
  126. #include &quot;../mme/EthernetHeader.c&quot;
  127. #include &quot;../mme/QualcommHeader.c&quot;
  128. #include &quot;../mme/QualcommHeader1.c&quot;
  129. #include &quot;../mme/UnwantedMessage.c&quot;
  130. #endif
  131. /*====================================================================*
  132. *
  133. * signed ResetAndWait (struct plc * plc);
  134. *
  135. * plc.h
  136. *
  137. * send VS_RS_DEV.REQ messages every channel-&gt;timeout milliseconds
  138. * until the device responds to indicate that it is ready to reset;
  139. * return 0 if the device eventually responds within plc-&gt;timer
  140. * seconds or -1 if not;
  141. *
  142. *--------------------------------------------------------------------*/
  143. signed ResetAndWait (struct plc * plc)
  144. {
  145. struct channel * channel = (struct channel *)(plc-&gt;channel);
  146. struct message * message = (struct message *)(plc-&gt;message);
  147. struct timeval ts;
  148. struct timeval tc;
  149. unsigned timer = 0;
  150. #ifndef __GNUC__
  151. #pragma pack (push,1)
  152. #endif
  153. struct __packed vs_rs_dev_request
  154. {
  155. struct ethernet_hdr ethernet;
  156. struct qualcomm_hdr qualcomm;
  157. }
  158. * request = (struct vs_rs_dev_request *) (message);
  159. struct __packed vs_rs_dev_confirm
  160. {
  161. struct ethernet_hdr ethernet;
  162. struct qualcomm_hdr qualcomm;
  163. uint8_t MSTATUS;
  164. }
  165. * confirm = (struct vs_rs_dev_confirm *) (message);
  166. #ifndef __GNUC__
  167. #pragma pack (pop)
  168. #endif
  169. Request (plc, &quot;Reset when Ready&quot;);
  170. if (gettimeofday (&amp;ts, NULL) == -1)
  171. {
  172. error (1, errno, CANT_START_TIMER);
  173. }
  174. for (timer = 0; timer &lt; plc-&gt;timer; timer = SECONDS (ts, tc))
  175. {
  176. memset (message, 0, sizeof (* message));
  177. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  178. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_RS_DEV | MMTYPE_REQ));
  179. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  180. if (SendMME (plc) &lt;= 0)
  181. {
  182. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  183. return (-1);
  184. }
  185. if (ReadMME (plc, 0, (VS_RS_DEV | MMTYPE_CNF)) &lt; 0)
  186. {
  187. error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
  188. return (-1);
  189. }
  190. if (gettimeofday (&amp;tc, NULL) == -1)
  191. {
  192. error (1, errno, CANT_RESET_TIMER);
  193. }
  194. if (plc-&gt;packetsize)
  195. {
  196. if (!confirm-&gt;MSTATUS)
  197. {
  198. Confirm (plc, &quot;Resetting ...&quot;);
  199. return (0);
  200. }
  201. }
  202. }
  203. return (-1);
  204. }
  205. /*====================================================================*
  206. *
  207. * signed WaitForReset (struct plc * plc, char string [], size_t length);
  208. *
  209. * plc.h
  210. *
  211. * send VS_SW_VER.REQ messages every channel-&gt;timeout milliseconds
  212. * until the device stops responding to indicate that it is inactive;
  213. * return 0 if the device eventually stops responding within
  214. * plc-&gt;timer seconds or -1 if not;
  215. *
  216. * this function cannot distinguish between a software reset and
  217. * hardware reset;
  218. *
  219. *--------------------------------------------------------------------*/
  220. signed WaitForReset (struct plc * plc, char string [], size_t length)
  221. {
  222. struct channel * channel = (struct channel *)(plc-&gt;channel);
  223. struct message * message = (struct message *)(plc-&gt;message);
  224. struct timeval ts;
  225. struct timeval tc;
  226. unsigned timer = 0;
  227. #ifndef __GNUC__
  228. #pragma pack (push,1)
  229. #endif
  230. struct __packed vs_sw_ver_request
  231. {
  232. struct ethernet_hdr ethernet;
  233. struct qualcomm_hdr qualcomm;
  234. uint8_t MSTATUS;
  235. uint8_t MDEVICEID;
  236. uint8_t MVERLENGTH;
  237. char MVERSION [PLC_VERSION_STRING];
  238. }
  239. * request = (struct vs_sw_ver_request *) (message);
  240. struct __packed vs_sw_ver_confirm
  241. {
  242. struct ethernet_hdr ethernet;
  243. struct qualcomm_hdr qualcomm;
  244. uint8_t MSTATUS;
  245. uint8_t MDEVICEID;
  246. uint8_t MVERLENGTH;
  247. char MVERSION [PLC_VERSION_STRING];
  248. }
  249. * confirm = (struct vs_sw_ver_confirm *) (message);
  250. #ifndef __GNUC__
  251. #pragma pack (pop)
  252. #endif
  253. memset (string, 0, length);
  254. Request (plc, &quot;Allow %d seconds for Reset&quot;, plc-&gt;timer);
  255. if (gettimeofday (&amp;ts, NULL) == -1)
  256. {
  257. error (1, errno, CANT_START_TIMER);
  258. }
  259. for (timer = 0; timer &lt; plc-&gt;timer; timer = SECONDS (ts, tc))
  260. {
  261. memset (message, 0, sizeof (* message));
  262. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  263. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
  264. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  265. if (SendMME (plc) &lt;= 0)
  266. {
  267. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  268. return (-1);
  269. }
  270. if (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) &lt; 0)
  271. {
  272. error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
  273. return (-1);
  274. }
  275. if (gettimeofday (&amp;tc, NULL) == -1)
  276. {
  277. error (1, errno, CANT_RESET_TIMER);
  278. }
  279. if (!plc-&gt;packetsize)
  280. {
  281. if (_allset (plc-&gt;flags, (PLC_WAITFORRESET | PLC_ANALYSE)))
  282. {
  283. Confirm (plc, &quot;Waited %d seconds for Reset&quot;, timer);
  284. }
  285. memcpy (string, confirm-&gt;MVERSION, confirm-&gt;MVERLENGTH);
  286. return (0);
  287. }
  288. }
  289. if (_allset (plc-&gt;flags, (PLC_WAITFORRESET | PLC_ANALYSE)))
  290. {
  291. Confirm (plc, &quot;Waited %d seconds for Reset&quot;, timer);
  292. }
  293. return (-1);
  294. }
  295. /*====================================================================*
  296. *
  297. * signed WaitForStart (struct plc * plc, char string [], size_t length);
  298. *
  299. * plc.h
  300. *
  301. * send VS_SW_VER.REQ messages every channel-&gt;timeout milliseconds
  302. * until the device responds to indicate that it is active; return
  303. * 0 if the device eventually responds within plc-&gt;timer seconds
  304. * or -1 if not;
  305. *
  306. *--------------------------------------------------------------------*/
  307. signed WaitForStart (struct plc * plc, char string [], size_t length)
  308. {
  309. struct channel * channel = (struct channel *)(plc-&gt;channel);
  310. struct message * message = (struct message *)(plc-&gt;message);
  311. struct timeval ts;
  312. struct timeval tc;
  313. unsigned timer = 0;
  314. #ifndef __GNUC__
  315. #pragma pack (push,1)
  316. #endif
  317. struct __packed vs_sw_ver_request
  318. {
  319. struct ethernet_hdr ethernet;
  320. struct qualcomm_hdr qualcomm;
  321. uint8_t MSTATUS;
  322. uint8_t MDEVICEID;
  323. uint8_t MVERLENGTH;
  324. char MVERSION [PLC_VERSION_STRING];
  325. }
  326. * request = (struct vs_sw_ver_request *) (message);
  327. struct __packed vs_sw_ver_confirm
  328. {
  329. struct ethernet_hdr ethernet;
  330. struct qualcomm_hdr qualcomm;
  331. uint8_t MSTATUS;
  332. uint8_t MDEVICEID;
  333. uint8_t MVERLENGTH;
  334. char MVERSION [PLC_VERSION_STRING];
  335. }
  336. * confirm = (struct vs_sw_ver_confirm *) (message);
  337. #ifndef __GNUC__
  338. #pragma pack (pop)
  339. #endif
  340. Request (plc, &quot;Allow %d seconds for Start&quot;, plc-&gt;timer);
  341. if (gettimeofday (&amp;ts, NULL) == -1)
  342. {
  343. error (1, errno, CANT_START_TIMER);
  344. }
  345. for (timer = 0; timer &lt; plc-&gt;timer; timer = SECONDS (ts, tc))
  346. {
  347. memset (message, 0, sizeof (* message));
  348. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  349. QualcommHeader (&amp;request-&gt;qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
  350. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  351. if (SendMME (plc) &lt;= 0)
  352. {
  353. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  354. return (-1);
  355. }
  356. if (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) &lt; 0)
  357. {
  358. error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
  359. return (-1);
  360. }
  361. if (gettimeofday (&amp;tc, NULL) == -1)
  362. {
  363. error (1, errno, CANT_RESET_TIMER);
  364. }
  365. if (plc-&gt;packetsize)
  366. {
  367. if (confirm-&gt;MSTATUS)
  368. {
  369. Failure (plc, PLC_WONTDOIT);
  370. return (-1);
  371. }
  372. if (_allset (plc-&gt;flags, (PLC_WAITFORSTART | PLC_ANALYSE)))
  373. {
  374. Confirm (plc, &quot;Waited %d seconds for Start&quot;, timer);
  375. }
  376. strncpy (string, confirm-&gt;MVERSION, length);
  377. return (0);
  378. }
  379. }
  380. if (_allset (plc-&gt;flags, (PLC_WAITFORSTART | PLC_ANALYSE)))
  381. {
  382. Confirm (plc, &quot;Waited %d seconds for Start&quot;, timer);
  383. }
  384. return (-1);
  385. }
  386. /*====================================================================*
  387. *
  388. * signed WaitForAssoc (struct plc * plc);
  389. *
  390. * plc.h
  391. *
  392. * send VS_NW_INFO.REQ messages every channel-&gt;timeout milliseconds
  393. * until the device reports that a network has formed; return 0 if a
  394. * network forms within plc-&gt;timer seconds or -1 if not;
  395. *
  396. *--------------------------------------------------------------------*/
  397. signed WaitForAssoc (struct plc * plc)
  398. {
  399. extern const uint8_t broadcast [ETHER_ADDR_LEN];
  400. struct channel * channel = (struct channel *)(plc-&gt;channel);
  401. struct message * message = (struct message *)(plc-&gt;message);
  402. struct timeval ts;
  403. struct timeval tc;
  404. unsigned timer = 0;
  405. #ifndef __GNUC__
  406. #pragma pack (push,1)
  407. #endif
  408. struct __packed vs_nw_info_request
  409. {
  410. struct ethernet_hdr ethernet;
  411. struct qualcomm_fmi qualcomm;
  412. }
  413. * request = (struct vs_nw_info_request *)(message);
  414. struct __packed vs_nw_info_confirm
  415. {
  416. struct ethernet_hdr ethernet;
  417. struct qualcomm_fmi qualcomm;
  418. uint8_t SUB_VERSION;
  419. uint8_t Reserved;
  420. uint16_t DATA_LEN;
  421. uint8_t DATA [1];
  422. }
  423. * confirm = (struct vs_nw_info_confirm *)(message);
  424. struct __packed station
  425. {
  426. uint8_t MAC [ETHER_ADDR_LEN];
  427. uint8_t TEI;
  428. uint8_t Reserved [3];
  429. uint8_t BDA [ETHER_ADDR_LEN];
  430. uint16_t AVGTX;
  431. uint8_t COUPLING;
  432. uint8_t Reserved3;
  433. uint16_t AVGRX;
  434. uint16_t Reserved4;
  435. }
  436. * station;
  437. struct __packed network
  438. {
  439. uint8_t NID [7];
  440. uint8_t Reserved1 [2];
  441. uint8_t SNID;
  442. uint8_t TEI;
  443. uint8_t Reserved2 [4];
  444. uint8_t ROLE;
  445. uint8_t CCO_MAC [ETHER_ADDR_LEN];
  446. uint8_t CCO_TEI;
  447. uint8_t Reserved3 [3];
  448. uint8_t NUMSTAS;
  449. uint8_t Reserved4 [5];
  450. struct station stations [1];
  451. }
  452. * network;
  453. struct __packed networks
  454. {
  455. uint8_t Reserved;
  456. uint8_t NUMAVLNS;
  457. struct network networks [1];
  458. }
  459. * networks = (struct networks *) (confirm-&gt;DATA);
  460. #ifndef __GNUC__
  461. #pragma pack (pop)
  462. #endif
  463. Request (plc, &quot;Allow %d seconds for Assoc&quot;, plc-&gt;timer);
  464. if (gettimeofday (&amp;ts, NULL) == -1)
  465. {
  466. error (1, errno, CANT_START_TIMER);
  467. }
  468. for (timer = 0; timer &lt; plc-&gt;timer; timer = SECONDS (ts, tc))
  469. {
  470. memset (message, 0, sizeof (* message));
  471. EthernetHeader (&amp;request-&gt;ethernet, channel-&gt;peer, channel-&gt;host, channel-&gt;type);
  472. QualcommHeader1 (&amp;request-&gt;qualcomm, 1, (VS_NW_INFO | MMTYPE_REQ));
  473. plc-&gt;packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  474. if (SendMME (plc) &lt;= 0)
  475. {
  476. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  477. return (-1);
  478. }
  479. if (ReadMME (plc, 1, (VS_NW_INFO | MMTYPE_CNF)) &lt; 0)
  480. {
  481. error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
  482. return (-1);
  483. }
  484. if (gettimeofday (&amp;tc, NULL) == -1)
  485. {
  486. error (1, errno, CANT_RESET_TIMER);
  487. }
  488. if (plc-&gt;packetsize)
  489. {
  490. network = (struct network *)(&amp;networks-&gt;networks);
  491. while (networks-&gt;NUMAVLNS--)
  492. {
  493. station = (struct station *)(&amp;network-&gt;stations);
  494. while (network-&gt;NUMSTAS--)
  495. {
  496. if (memcmp (station-&gt;MAC, broadcast, sizeof (broadcast)))
  497. {
  498. if (_allset (plc-&gt;flags, (PLC_WAITFORASSOC | PLC_ANALYSE)))
  499. {
  500. Confirm (plc, &quot;Waited %d seconds for Assoc&quot;, timer);
  501. }
  502. return (0);
  503. }
  504. station++;
  505. }
  506. network = (struct network *)(station);
  507. }
  508. }
  509. }
  510. if (_allset (plc-&gt;flags, (PLC_WAITFORASSOC | PLC_ANALYSE)))
  511. {
  512. Confirm (plc, &quot;Waited %d seconds for Assoc&quot;, timer);
  513. }
  514. return (-1);
  515. }
  516. #define COMPARE_TYPE_NONE 0
  517. #define COMPARE_TYPE_EXACT 1
  518. #define COMPARE_TYPE_CONTAINS 2
  519. /*====================================================================*
  520. *
  521. * void function (struct plc * plc, char const * firmware, int compare_type);
  522. *
  523. * perform operations in a logical order;
  524. *
  525. *
  526. *--------------------------------------------------------------------*/
  527. static void function (struct plc * plc, char const * firmware, int compare_type)
  528. {
  529. char string [PLC_VERSION_STRING];
  530. if (_anyset (plc-&gt;flags, PLC_RESET_DEVICE))
  531. {
  532. if (ResetAndWait (plc))
  533. {
  534. Failure (plc, &quot;Device did not Reset.&quot;);
  535. }
  536. }
  537. if (_anyset (plc-&gt;flags, PLC_WAITFORRESET))
  538. {
  539. if (WaitForReset (plc, string, sizeof (string)))
  540. {
  541. Failure (plc, &quot;Device did not Reset.&quot;);
  542. }
  543. }
  544. if (_anyset (plc-&gt;flags, PLC_WAITFORSTART))
  545. {
  546. if (WaitForStart (plc, string, sizeof (string)))
  547. {
  548. Failure (plc, &quot;Device did not Start.&quot;);
  549. }
  550. if ((firmware) &amp;&amp; (*firmware))
  551. {
  552. switch (compare_type)
  553. {
  554. case COMPARE_TYPE_EXACT:
  555. if (strcmp (firmware, string))
  556. {
  557. Failure (plc, &quot;Started wrong firmware&quot;);
  558. }
  559. break;
  560. case COMPARE_TYPE_CONTAINS:
  561. if (strstr (string, firmware) == NULL)
  562. {
  563. Failure (plc, &quot;Started wrong firmware&quot;);
  564. }
  565. break;
  566. }
  567. }
  568. }
  569. if (_anyset (plc-&gt;flags, PLC_WAITFORASSOC))
  570. {
  571. if (WaitForAssoc (plc))
  572. {
  573. Failure (plc, &quot;Device did not Assoc.&quot;);
  574. }
  575. }
  576. if (plc-&gt;sleep)
  577. {
  578. Request (plc, &quot;Pause %d seconds&quot;, plc-&gt;sleep);
  579. sleep (plc-&gt;sleep);
  580. }
  581. return;
  582. }
  583. /*====================================================================*
  584. *
  585. * int main (int argc, char const * argv[]);
  586. *
  587. * parse command line, populate plc structure and perform selected
  588. * operations; show help summary if asked; see getoptv and putoptv
  589. * to understand command line parsing and help summary display; see
  590. * plc.h for the definition of struct plc;
  591. *
  592. * the command line accepts multiple MAC addresses and the program
  593. * performs the specified operations on each address, in turn; the
  594. * address order is significant but the option order is not; the
  595. * default address is a local broadcast that causes all devices on
  596. * the local H1 interface to respond but not those at the remote
  597. * end of the powerline;
  598. *
  599. * the default address is 00:B0:52:00:00:01; omitting the address
  600. * will automatically address the local device; some options will
  601. * cancel themselves if this makes no sense;
  602. *
  603. * the default interface is eth1 because most people use eth0 as
  604. * their principle network connection; you can specify another
  605. * interface with -i or define environment string PLC to make
  606. * that the default interface and save typing;
  607. *
  608. *
  609. *--------------------------------------------------------------------*/
  610. int main (int argc, char const * argv [])
  611. {
  612. extern struct channel channel;
  613. static char const * optv [] =
  614. {
  615. &quot;aef:F:i:p:qrRst:vw:xy&quot;,
  616. &quot;device [device] [...] [&gt; stdout]&quot;,
  617. &quot;Qualcomm Atheros Powerline Procrastinator&quot;,
  618. &quot;a\twait for device assoc&quot;,
  619. &quot;e\tredirect stderr to stdout&quot;,
  620. &quot;f s\tconfirm firmware is revision s&quot;,
  621. &quot;F s\tconfirm firmware revision contains substring s&quot;,
  622. #if defined (WINPCAP) || defined (LIBPCAP)
  623. &quot;i n\thost interface is (n) [&quot; LITERAL (CHANNEL_ETHNUMBER) &quot;]&quot;,
  624. #else
  625. &quot;i s\thost interface is (s) [&quot; LITERAL (CHANNEL_ETHDEVICE) &quot;]&quot;,
  626. #endif
  627. &quot;p n\tpause (n) seconds&quot;,
  628. &quot;q\tquiet mode&quot;,
  629. &quot;r\twait for device reset&quot;,
  630. &quot;R\treset device and wait&quot;,
  631. &quot;s\twait for device start&quot;,
  632. &quot;t n\tchannel timeout is (n) milliseconds [&quot; LITERAL (CHANNEL_TIMEOUT) &quot;]&quot;,
  633. &quot;v\tverbose mode&quot;,
  634. &quot;w n\twait up to (n) seconds for action [&quot; LITERAL (PLC_TIMER) &quot;]&quot;,
  635. &quot;x\texit on error&quot;,
  636. &quot;y\treport failure times&quot;,
  637. (char const *) (0)
  638. };
  639. #include &quot;../plc/plc.c&quot;
  640. char const * firmware = &quot;&quot;;
  641. signed c;
  642. int compare_type = COMPARE_TYPE_NONE;
  643. if (getenv (PLCDEVICE))
  644. {
  645. #if defined (WINPCAP) || defined (LIBPCAP)
  646. channel.ifindex = atoi (getenv (PLCDEVICE));
  647. #else
  648. channel.ifname = strdup (getenv (PLCDEVICE));
  649. #endif
  650. }
  651. optind = 1;
  652. while ((c = getoptv (argc, argv, optv)) != -1)
  653. {
  654. switch (c)
  655. {
  656. case 'a':
  657. _setbits (plc.flags, PLC_WAITFORASSOC);
  658. break;
  659. case 'e':
  660. dup2 (STDOUT_FILENO, STDERR_FILENO);
  661. break;
  662. case 'f':
  663. firmware = optarg;
  664. compare_type = COMPARE_TYPE_EXACT;
  665. break;
  666. case 'F':
  667. firmware = optarg;
  668. compare_type = COMPARE_TYPE_CONTAINS;
  669. break;
  670. case 'i':
  671. #if defined (WINPCAP) || defined (LIBPCAP)
  672. channel.ifindex = atoi (optarg);
  673. #else
  674. channel.ifname = optarg;
  675. #endif
  676. break;
  677. case 'p':
  678. plc.sleep = (unsigned)(uintspec (optarg, 0, 3600));
  679. break;
  680. case 'q':
  681. _setbits (channel.flags, CHANNEL_SILENCE);
  682. _setbits (plc.flags, PLC_SILENCE);
  683. break;
  684. case 'r':
  685. _setbits (plc.flags, PLC_WAITFORRESET);
  686. break;
  687. case 'R':
  688. _setbits (plc.flags, PLC_RESET_DEVICE);
  689. break;
  690. case 's':
  691. _setbits (plc.flags, PLC_WAITFORSTART);
  692. break;
  693. case 't':
  694. channel.timeout = (signed)(uintspec (optarg, 0, UINT_MAX));
  695. break;
  696. case 'v':
  697. _setbits (channel.flags, CHANNEL_VERBOSE);
  698. _setbits (plc.flags, PLC_VERBOSE);
  699. break;
  700. case 'w':
  701. plc.timer = (unsigned)(uintspec (optarg, 0, 86400));
  702. break;
  703. case 'x':
  704. _setbits (plc.flags, PLC_BAILOUT);
  705. break;
  706. case 'y':
  707. _setbits (plc.flags, PLC_ANALYSE);
  708. break;
  709. default:
  710. break;
  711. }
  712. }
  713. argc -= optind;
  714. argv += optind;
  715. openchannel (&amp;channel);
  716. if (!(plc.message = malloc (sizeof (* plc.message))))
  717. {
  718. error (1, errno, PLC_NOMEMORY);
  719. }
  720. if (!argc)
  721. {
  722. function (&amp;plc, firmware, compare_type);
  723. }
  724. while ((argc) &amp;&amp; (* argv))
  725. {
  726. if (!hexencode (channel.peer, sizeof (channel.peer), synonym (* argv, devices, SIZEOF (devices))))
  727. {
  728. error (1, errno, PLC_BAD_MAC, * argv);
  729. }
  730. function (&amp;plc, firmware, compare_type);
  731. argv++;
  732. argc--;
  733. }
  734. free (plc.message);
  735. closechannel (&amp;channel);
  736. exit (0);
  737. }
  738. </pre>
  739. <div class='footerlink'>
  740. [<a href='PLCTopologyPrint.c.html' title=' PLCTopologyPrint.c '>PREV</a>]
  741. [<a href='toolkit.html' title=' Index '>HOME</a>]
  742. [<a href='PrintRule.c.html' title=' PrintRule.c '>NEXT</a>]
  743. </div>
  744. </body>
  745. </html>