wizchip_socket.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. //*****************************************************************************
  2. //
  3. //! \file wizchip_socket.c
  4. //! \brief SOCKET APIs Implements file.
  5. //! \details SOCKET APIs like as Berkeley Socket APIs.
  6. //! \version 1.0.3
  7. //! \date 2013/10/21
  8. //! \par Revision history
  9. //! <2015/02/05> Notice
  10. //! The version history is not updated after this point.
  11. //! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
  12. //! >> https://github.com/Wiznet/ioLibrary_Driver
  13. //! <2014/05/01> V1.0.3. Refer to M20140501
  14. //! 1. Implicit type casting -> Explicit type casting.
  15. //! 2. replace 0x01 with PACK_REMAINED in recvfrom()
  16. //! 3. Validation a destination ip in connect() & sendto():
  17. //! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
  18. //! Copy 4 byte addr value into temporary uint32 variable and then compares it.
  19. //! <2013/12/20> V1.0.2 Refer to M20131220
  20. //! Remove Warning.
  21. //! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
  22. //! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
  23. //! <2013/10/21> 1st Release
  24. //! \author MidnightCow
  25. //! \copyright
  26. //!
  27. //! Copyright (c) 2013, WIZnet Co., LTD.
  28. //! All rights reserved.
  29. //!
  30. //! Redistribution and use in source and binary forms, with or without
  31. //! modification, are permitted provided that the following conditions
  32. //! are met:
  33. //!
  34. //! * Redistributions of source code must retain the above copyright
  35. //! notice, this list of conditions and the following disclaimer.
  36. //! * Redistributions in binary form must reproduce the above copyright
  37. //! notice, this list of conditions and the following disclaimer in the
  38. //! documentation and/or other materials provided with the distribution.
  39. //! * Neither the name of the <ORGANIZATION> nor the names of its
  40. //! contributors may be used to endorse or promote products derived
  41. //! from this software without specific prior written permission.
  42. //!
  43. //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  44. //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  45. //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  46. //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  47. //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  48. //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  49. //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  50. //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  51. //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  52. //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  53. //! THE POSSIBILITY OF SUCH DAMAGE.
  54. //
  55. //*****************************************************************************
  56. #include "wizchip_socket.h"
  57. #include "RyanW5500Store.h"
  58. #define RyanWizchipCheck(EX, count, code) RyanWizchipCheckCode(EX, count, 1, code, { NULL; })
  59. #define RyanWizchipCheckCode(EX, count, ms, code, userCode) \
  60. for (uint16_t i = 0; (EX); i++) \
  61. { \
  62. { \
  63. userCode \
  64. } \
  65. if (i >= count) \
  66. { \
  67. return (code); \
  68. } \
  69. delay(ms); \
  70. }
  71. // M20150401 : Typing Error
  72. // #define SOCK_ANY_PORT_NUM 0xC000;
  73. #define SOCK_ANY_PORT_NUM 0xC000
  74. static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
  75. static uint16_t sock_io_mode = 0;
  76. static uint16_t sock_is_sending = 0;
  77. static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0};
  78. // M20150601 : For extern decleation
  79. // static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
  80. uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0};
  81. //
  82. #if _WIZCHIP_ == 5200
  83. static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = {y0};
  84. #endif
  85. // A20150601 : For integrating with W5300
  86. #if _WIZCHIP_ == 5300
  87. uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0}; // set by wiz_recv_data()
  88. #endif
  89. #define CHECK_SOCKNUM() \
  90. do \
  91. { \
  92. if (sn > _WIZCHIP_SOCK_NUM_) \
  93. return SOCKERR_SOCKNUM; \
  94. } while (0);
  95. #define CHECK_SOCKMODE(mode) \
  96. do \
  97. { \
  98. if ((getSn_MR(sn) & 0x0F) != mode) \
  99. return SOCKERR_SOCKMODE; \
  100. } while (0);
  101. #define CHECK_SOCKINIT() \
  102. do \
  103. { \
  104. if ((getSn_SR(sn) != SOCK_INIT)) \
  105. return SOCKERR_SOCKINIT; \
  106. } while (0);
  107. #define CHECK_SOCKDATA() \
  108. do \
  109. { \
  110. if (len == 0) \
  111. return SOCKERR_DATALEN; \
  112. } while (0);
  113. int8_t wizchip_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
  114. {
  115. CHECK_SOCKNUM();
  116. switch (protocol)
  117. {
  118. case Sn_MR_TCP:
  119. {
  120. uint32_t taddr;
  121. getSIPR((uint8_t *)&taddr); // 源iP寄存器
  122. if (taddr == 0)
  123. return SOCKERR_SOCKINIT;
  124. break;
  125. }
  126. case Sn_MR_UDP:
  127. case Sn_MR_MACRAW:
  128. case Sn_MR_IPRAW:
  129. break;
  130. #if (_WIZCHIP_ < 5200)
  131. case Sn_MR_PPPoE:
  132. break;
  133. #endif
  134. default:
  135. return SOCKERR_SOCKMODE;
  136. }
  137. // M20150601 : For SF_TCP_ALIGN & W5300
  138. // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
  139. if ((flag & 0x04) != 0)
  140. return SOCKERR_SOCKFLAG;
  141. #if _WIZCHIP_ == 5200
  142. if (flag & 0x10)
  143. return SOCKERR_SOCKFLAG;
  144. #endif
  145. if (flag != 0)
  146. {
  147. switch (protocol)
  148. {
  149. case Sn_MR_TCP:
  150. // M20150601 : For SF_TCP_ALIGN & W5300
  151. #if _WIZCHIP_ == 5300
  152. if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0)
  153. return SOCKERR_SOCKFLAG;
  154. #else
  155. if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0)
  156. return SOCKERR_SOCKFLAG;
  157. #endif
  158. break;
  159. case Sn_MR_UDP:
  160. if (flag & SF_IGMP_VER2)
  161. {
  162. if ((flag & SF_MULTI_ENABLE) == 0)
  163. return SOCKERR_SOCKFLAG;
  164. }
  165. #if _WIZCHIP_ == 5500
  166. if (flag & SF_UNI_BLOCK)
  167. {
  168. if ((flag & SF_MULTI_ENABLE) == 0)
  169. return SOCKERR_SOCKFLAG;
  170. }
  171. #endif
  172. break;
  173. default:
  174. break;
  175. }
  176. }
  177. wizchip_close(sn);
  178. // M20150601
  179. #if _WIZCHIP_ == 5300
  180. setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7));
  181. #else
  182. setSn_MR(sn, (protocol | (flag & 0xF0)));
  183. #endif
  184. if (!port)
  185. {
  186. port = sock_any_port++;
  187. if (sock_any_port == 0xFFF0)
  188. sock_any_port = SOCK_ANY_PORT_NUM;
  189. }
  190. setSn_PORT(sn, port);
  191. setSn_CR(sn, Sn_CR_OPEN);
  192. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  193. // A20150401 : For release the previous sock_io_mode
  194. sock_io_mode &= ~(1 << sn);
  195. //
  196. sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
  197. sock_is_sending &= ~(1 << sn);
  198. sock_remained_size[sn] = 0;
  199. // M20150601 : repalce 0 with PACK_COMPLETED
  200. // sock_pack_info[sn] = 0;
  201. sock_pack_info[sn] = PACK_COMPLETED;
  202. //
  203. RyanWizchipCheck(getSn_SR(sn) == SOCK_CLOSED, 10, SOCKERR_SOCKCLOSED);
  204. return (int8_t)sn;
  205. }
  206. int8_t wizchip_close(uint8_t sn)
  207. {
  208. CHECK_SOCKNUM();
  209. // A20160426 : Applied the erratum 1 of W5300
  210. #if (_WIZCHIP_ == 5300)
  211. // M20160503 : Wrong socket parameter. s -> sn
  212. // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
  213. if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)))
  214. {
  215. uint8_t destip[4] = {0, 0, 0, 1};
  216. // TODO
  217. // You can wait for completing to sending data;
  218. // wait about 1 second;
  219. // if you have completed to send data, skip the code of erratum 1
  220. // ex> wait_1s();
  221. // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
  222. //
  223. // M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
  224. // socket(s,Sn_MR_UDP,0x3000,0);
  225. // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
  226. setSn_MR(sn, Sn_MR_UDP);
  227. setSn_PORTR(sn, 0x3000);
  228. setSn_CR(sn, Sn_CR_OPEN);
  229. RyanWizchipCheck(getSn_CR(sn) != 0, 10, SOCKERR_SOCKCLOSED);
  230. RyanWizchipCheck(getSn_SR(sn) != SOCK_UDP, 10, SOCKERR_SOCKCLOSED);
  231. sendto(sn, destip, 1, destip, 0x3000); // send the dummy data to an unknown destination(0.0.0.1).
  232. };
  233. #endif
  234. setSn_CR(sn, Sn_CR_CLOSE);
  235. /* wait to process the command... */
  236. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  237. /* clear all interrupt of the socket. */
  238. setSn_IR(sn, 0xFF);
  239. // A20150401 : Release the sock_io_mode of socket n.
  240. sock_io_mode &= ~(1 << sn);
  241. //
  242. sock_is_sending &= ~(1 << sn);
  243. sock_remained_size[sn] = 0;
  244. sock_pack_info[sn] = 0;
  245. RyanWizchipCheck(getSn_SR(sn) != SOCK_CLOSED, 10, SOCKERR_SOCKCLOSED);
  246. return SOCK_OK;
  247. }
  248. int8_t wizchip_listen(uint8_t sn)
  249. {
  250. CHECK_SOCKNUM();
  251. CHECK_SOCKMODE(Sn_MR_TCP);
  252. CHECK_SOCKINIT();
  253. setSn_CR(sn, Sn_CR_LISTEN);
  254. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  255. for (uint8_t i = 0; getSn_SR(sn) != SOCK_LISTEN; i++)
  256. {
  257. if (i >= 10)
  258. {
  259. wizchip_close(sn);
  260. return SOCKERR_SOCKCLOSED;
  261. }
  262. delay(2);
  263. }
  264. return SOCK_OK;
  265. }
  266. int8_t wizchip_connect(uint8_t sn, uint8_t *addr, uint16_t port)
  267. {
  268. CHECK_SOCKNUM();
  269. CHECK_SOCKMODE(Sn_MR_TCP);
  270. CHECK_SOCKINIT();
  271. // M20140501 : For avoiding fatal error on memory align mismatched
  272. // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
  273. {
  274. uint32_t taddr;
  275. taddr = ((uint32_t)addr[0] & 0x000000FF);
  276. taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
  277. taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
  278. taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
  279. if (taddr == 0xFFFFFFFF || taddr == 0)
  280. return SOCKERR_IPINVALID;
  281. }
  282. //
  283. if (port == 0)
  284. return SOCKERR_PORTZERO;
  285. setSn_DIPR(sn, addr);
  286. setSn_DPORT(sn, port);
  287. setSn_CR(sn, Sn_CR_CONNECT);
  288. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  289. if (sock_io_mode & (1 << sn))
  290. return SOCK_BUSY;
  291. RyanWizchipCheckCode(getSn_SR(sn) != SOCK_ESTABLISHED, 1000, 2, SOCKERR_SOCKCLOSED, {
  292. if (getSn_IR(sn) & Sn_IR_TIMEOUT)
  293. {
  294. setSn_IR(sn, Sn_IR_TIMEOUT);
  295. return SOCKERR_TIMEOUT;
  296. }
  297. if (getSn_SR(sn) == SOCK_CLOSED)
  298. {
  299. return SOCKERR_SOCKCLOSED;
  300. }
  301. });
  302. return SOCK_OK;
  303. }
  304. int8_t wizchip_disconnect(uint8_t sn)
  305. {
  306. CHECK_SOCKNUM();
  307. CHECK_SOCKMODE(Sn_MR_TCP);
  308. setSn_CR(sn, Sn_CR_DISCON);
  309. /* wait to process the command... */
  310. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  311. sock_is_sending &= ~(1 << sn);
  312. if (sock_io_mode & (1 << sn))
  313. return SOCK_BUSY;
  314. RyanWizchipCheckCode(getSn_SR(sn) != SOCK_CLOSED, 1000, 2, SOCKERR_SOCKCLOSED, {
  315. if (getSn_IR(sn) & Sn_IR_TIMEOUT)
  316. {
  317. wizchip_close(sn);
  318. return SOCKERR_TIMEOUT;
  319. }
  320. });
  321. return SOCK_OK;
  322. }
  323. int32_t wizchip_send(uint8_t sn, uint8_t *buf, uint16_t len)
  324. {
  325. uint8_t tmp = 0;
  326. uint16_t freesize = 0;
  327. CHECK_SOCKNUM();
  328. CHECK_SOCKMODE(Sn_MR_TCP);
  329. CHECK_SOCKDATA();
  330. tmp = getSn_SR(sn);
  331. if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT)
  332. return SOCKERR_SOCKSTATUS;
  333. if (sock_is_sending & (1 << sn))
  334. {
  335. tmp = getSn_IR(sn);
  336. if (tmp & Sn_IR_SENDOK)
  337. {
  338. setSn_IR(sn, Sn_IR_SENDOK);
  339. // M20150401 : Typing Error
  340. // #if _WZICHIP_ == 5200
  341. #if _WIZCHIP_ == 5200
  342. if (getSn_TX_RD(sn) != sock_next_rd[sn])
  343. {
  344. setSn_CR(sn, Sn_CR_SEND);
  345. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  346. return SOCK_BUSY;
  347. }
  348. #endif
  349. sock_is_sending &= ~(1 << sn);
  350. }
  351. else if (tmp & Sn_IR_TIMEOUT)
  352. {
  353. wizchip_close(sn);
  354. return SOCKERR_TIMEOUT;
  355. }
  356. else
  357. return SOCK_BUSY;
  358. }
  359. freesize = getSn_TxMAX(sn);
  360. if (len > freesize)
  361. len = freesize; // check size not to exceed MAX size.
  362. RyanWizchipCheckCode(getSn_SR(sn) != SOCK_CLOSED, 1000, 2, SOCKERR_SOCKCLOSED, {
  363. freesize = getSn_TX_FSR(sn);
  364. tmp = getSn_SR(sn);
  365. if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
  366. {
  367. wizchip_close(sn);
  368. return SOCKERR_SOCKSTATUS;
  369. }
  370. if ((sock_io_mode & (1 << sn)) && (len > freesize))
  371. return SOCK_BUSY;
  372. if (len <= freesize)
  373. break;
  374. });
  375. wiz_send_data(sn, buf, len);
  376. #if _WIZCHIP_ == 5200
  377. sock_next_rd[sn] = getSn_TX_RD(sn) + len;
  378. #endif
  379. #if _WIZCHIP_ == 5300
  380. setSn_TX_WRSR(sn, len);
  381. #endif
  382. setSn_CR(sn, Sn_CR_SEND);
  383. /* wait to process the command... */
  384. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  385. sock_is_sending |= (1 << sn);
  386. // M20150409 : Explicit Type Casting
  387. // return len;
  388. return (int32_t)len;
  389. }
  390. int32_t wizchip_recv(uint8_t sn, uint8_t *buf, uint16_t len)
  391. {
  392. uint8_t tmp = 0;
  393. uint16_t recvsize = 0;
  394. // A20150601 : For integarating with W5300
  395. #if _WIZCHIP_ == 5300
  396. uint8_t head[2];
  397. uint16_t mr;
  398. #endif
  399. //
  400. CHECK_SOCKNUM();
  401. CHECK_SOCKMODE(Sn_MR_TCP);
  402. CHECK_SOCKDATA();
  403. recvsize = getSn_RxMAX(sn);
  404. if (recvsize < len)
  405. len = recvsize;
  406. // A20150601 : For Integrating with W5300
  407. #if _WIZCHIP_ == 5300
  408. // sock_pack_info[sn] = PACK_COMPLETED; // for clear
  409. if (sock_remained_size[sn] == 0)
  410. {
  411. #endif
  412. //
  413. RyanWizchipCheckCode(getSn_SR(sn) != SOCK_CLOSED, 1000, 2, SOCKERR_SOCKCLOSED, {
  414. recvsize = getSn_RX_RSR(sn);
  415. tmp = getSn_SR(sn);
  416. if (tmp != SOCK_ESTABLISHED)
  417. {
  418. if (tmp == SOCK_CLOSE_WAIT)
  419. {
  420. if (recvsize != 0)
  421. break;
  422. else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn))
  423. {
  424. wizchip_close(sn);
  425. return SOCKERR_SOCKSTATUS;
  426. }
  427. }
  428. else
  429. {
  430. wizchip_close(sn);
  431. return SOCKERR_SOCKSTATUS;
  432. }
  433. }
  434. if ((sock_io_mode & (1 << sn)) && (recvsize == 0))
  435. return SOCK_BUSY;
  436. if (recvsize != 0)
  437. break;
  438. });
  439. #if _WIZCHIP_ == 5300
  440. }
  441. #endif
  442. // A20150601 : For integrating with W5300
  443. #if _WIZCHIP_ == 5300
  444. if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN))
  445. {
  446. mr = getMR();
  447. if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0)
  448. {
  449. wiz_recv_data(sn, head, 2);
  450. if (mr & MR_FS)
  451. recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]);
  452. else
  453. recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]);
  454. sock_pack_info[sn] = PACK_FIRST;
  455. }
  456. sock_remained_size[sn] = recvsize;
  457. }
  458. if (len > sock_remained_size[sn])
  459. len = sock_remained_size[sn];
  460. recvsize = len;
  461. if (sock_pack_info[sn] & PACK_FIFOBYTE)
  462. {
  463. *buf = sock_remained_byte[sn];
  464. buf++;
  465. sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
  466. recvsize -= 1;
  467. sock_remained_size[sn] -= 1;
  468. }
  469. if (recvsize != 0)
  470. {
  471. wiz_recv_data(sn, buf, recvsize);
  472. setSn_CR(sn, Sn_CR_RECV);
  473. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  474. }
  475. sock_remained_size[sn] -= recvsize;
  476. if (sock_remained_size[sn] != 0)
  477. {
  478. sock_pack_info[sn] |= PACK_REMAINED;
  479. if (recvsize & 0x1)
  480. sock_pack_info[sn] |= PACK_FIFOBYTE;
  481. }
  482. else
  483. sock_pack_info[sn] = PACK_COMPLETED;
  484. if (getSn_MR(sn) & Sn_MR_ALIGN)
  485. sock_remained_size[sn] = 0;
  486. // len = recvsize;
  487. #else
  488. if (recvsize < len)
  489. len = recvsize;
  490. wiz_recv_data(sn, buf, len);
  491. setSn_CR(sn, Sn_CR_RECV);
  492. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  493. #endif
  494. // M20150409 : Explicit Type Casting
  495. // return len;
  496. return (int32_t)len;
  497. }
  498. int32_t wizchip_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
  499. {
  500. uint8_t tmp = 0;
  501. uint16_t freesize = 0;
  502. uint32_t taddr;
  503. CHECK_SOCKNUM();
  504. switch (getSn_MR(sn) & 0x0F)
  505. {
  506. case Sn_MR_UDP:
  507. case Sn_MR_MACRAW:
  508. // break;
  509. // #if ( _WIZCHIP_ < 5200 )
  510. case Sn_MR_IPRAW:
  511. break;
  512. // #endif
  513. default:
  514. return SOCKERR_SOCKMODE;
  515. }
  516. CHECK_SOCKDATA();
  517. // M20140501 : For avoiding fatal error on memory align mismatched
  518. // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
  519. //{
  520. // uint32_t taddr;
  521. taddr = ((uint32_t)addr[0]) & 0x000000FF;
  522. taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
  523. taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
  524. taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
  525. //}
  526. //
  527. // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
  528. if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW))
  529. return SOCKERR_IPINVALID;
  530. if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW))
  531. return SOCKERR_PORTZERO;
  532. tmp = getSn_SR(sn);
  533. // #if ( _WIZCHIP_ < 5200 )
  534. if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW))
  535. return SOCKERR_SOCKSTATUS;
  536. // #else
  537. // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
  538. // #endif
  539. setSn_DIPR(sn, addr);
  540. setSn_DPORT(sn, port);
  541. freesize = getSn_TxMAX(sn);
  542. if (len > freesize)
  543. len = freesize; // check size not to exceed MAX size.
  544. RyanWizchipCheckCode(1, 1000, 2, SOCKERR_SOCKCLOSED, {
  545. freesize = getSn_TX_FSR(sn);
  546. if (getSn_SR(sn) == SOCK_CLOSED)
  547. return SOCKERR_SOCKCLOSED;
  548. if ((sock_io_mode & (1 << sn)) && (len > freesize))
  549. return SOCK_BUSY;
  550. if (len <= freesize)
  551. break;
  552. });
  553. wiz_send_data(sn, buf, len);
  554. #if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
  555. getSIPR((uint8_t *)&taddr);
  556. if (taddr == 0)
  557. {
  558. getSUBR((uint8_t *)&taddr);
  559. setSUBR((uint8_t *)"\x00\x00\x00\x00");
  560. }
  561. else
  562. taddr = 0;
  563. #endif
  564. // A20150601 : For W5300
  565. #if _WIZCHIP_ == 5300
  566. setSn_TX_WRSR(sn, len);
  567. #endif
  568. //
  569. setSn_CR(sn, Sn_CR_SEND);
  570. /* wait to process the command... */
  571. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  572. RyanWizchipCheckCode(1, 1000, 2, SOCKERR_SOCKCLOSED, {
  573. tmp = getSn_IR(sn);
  574. if (tmp & Sn_IR_SENDOK)
  575. {
  576. setSn_IR(sn, Sn_IR_SENDOK);
  577. break;
  578. }
  579. // M:20131104
  580. // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
  581. else if (tmp & Sn_IR_TIMEOUT)
  582. {
  583. setSn_IR(sn, Sn_IR_TIMEOUT);
  584. // M20150409 : Fixed the lost of sign bits by type casting.
  585. // len = (uint16_t)SOCKERR_TIMEOUT;
  586. // break;
  587. #if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
  588. if (taddr)
  589. setSUBR((uint8_t *)&taddr);
  590. #endif
  591. return SOCKERR_TIMEOUT;
  592. }
  593. });
  594. #if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
  595. if (taddr)
  596. setSUBR((uint8_t *)&taddr);
  597. #endif
  598. // M20150409 : Explicit Type Casting
  599. // return len;
  600. return (int32_t)len;
  601. }
  602. int32_t wizchip_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
  603. {
  604. // M20150601 : For W5300
  605. #if _WIZCHIP_ == 5300
  606. uint16_t mr;
  607. uint16_t mr1;
  608. #else
  609. uint8_t mr;
  610. #endif
  611. //
  612. uint8_t head[8];
  613. uint16_t pack_len = 0;
  614. CHECK_SOCKNUM();
  615. // CHECK_SOCKMODE(Sn_MR_UDP);
  616. // A20150601
  617. #if _WIZCHIP_ == 5300
  618. mr1 = getMR();
  619. #endif
  620. switch ((mr = getSn_MR(sn)) & 0x0F)
  621. {
  622. case Sn_MR_UDP:
  623. case Sn_MR_IPRAW:
  624. case Sn_MR_MACRAW:
  625. break;
  626. #if (_WIZCHIP_ < 5200)
  627. case Sn_MR_PPPoE:
  628. break;
  629. #endif
  630. default:
  631. return SOCKERR_SOCKMODE;
  632. }
  633. CHECK_SOCKDATA();
  634. if (sock_remained_size[sn] == 0)
  635. {
  636. RyanWizchipCheckCode(1, 1000, 1, SOCKERR_SOCKCLOSED, {
  637. pack_len = getSn_RX_RSR(sn);
  638. if (getSn_SR(sn) == SOCK_CLOSED)
  639. return SOCKERR_SOCKCLOSED;
  640. if ((sock_io_mode & (1 << sn)) && (pack_len == 0))
  641. return SOCK_BUSY;
  642. if (pack_len != 0)
  643. break;
  644. });
  645. }
  646. // D20150601 : Move it to bottom
  647. // sock_pack_info[sn] = PACK_COMPLETED;
  648. switch (mr & 0x07)
  649. {
  650. case Sn_MR_UDP:
  651. if (sock_remained_size[sn] == 0)
  652. {
  653. wiz_recv_data(sn, head, 8);
  654. setSn_CR(sn, Sn_CR_RECV);
  655. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  656. // read peer's IP address, port number & packet length
  657. // A20150601 : For W5300
  658. #if _WIZCHIP_ == 5300
  659. if (mr1 & MR_FS)
  660. {
  661. addr[0] = head[1];
  662. addr[1] = head[0];
  663. addr[2] = head[3];
  664. addr[3] = head[2];
  665. *port = head[5];
  666. *port = (*port << 8) + head[4];
  667. sock_remained_size[sn] = head[7];
  668. sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6];
  669. }
  670. else
  671. {
  672. #endif
  673. addr[0] = head[0];
  674. addr[1] = head[1];
  675. addr[2] = head[2];
  676. addr[3] = head[3];
  677. *port = head[4];
  678. *port = (*port << 8) + head[5];
  679. sock_remained_size[sn] = head[6];
  680. sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
  681. #if _WIZCHIP_ == 5300
  682. }
  683. #endif
  684. sock_pack_info[sn] = PACK_FIRST;
  685. }
  686. if (len < sock_remained_size[sn])
  687. pack_len = len;
  688. else
  689. pack_len = sock_remained_size[sn];
  690. // A20150601 : For W5300
  691. len = pack_len;
  692. #if _WIZCHIP_ == 5300
  693. if (sock_pack_info[sn] & PACK_FIFOBYTE)
  694. {
  695. *buf++ = sock_remained_byte[sn];
  696. pack_len -= 1;
  697. sock_remained_size[sn] -= 1;
  698. sock_pack_info[sn] &= ~PACK_FIFOBYTE;
  699. }
  700. #endif
  701. //
  702. // Need to packet length check (default 1472)
  703. //
  704. wiz_recv_data(sn, buf, pack_len); // data copy.
  705. break;
  706. case Sn_MR_MACRAW:
  707. if (sock_remained_size[sn] == 0)
  708. {
  709. wiz_recv_data(sn, head, 2);
  710. setSn_CR(sn, Sn_CR_RECV);
  711. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  712. // read peer's IP address, port number & packet length
  713. sock_remained_size[sn] = head[0];
  714. sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2;
  715. #if _WIZCHIP_ == W5300
  716. if (sock_remained_size[sn] & 0x01)
  717. sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4;
  718. else
  719. sock_remained_size[sn] -= 4;
  720. #endif
  721. if (sock_remained_size[sn] > 1514)
  722. {
  723. wizchip_close(sn);
  724. return SOCKFATAL_PACKLEN;
  725. }
  726. sock_pack_info[sn] = PACK_FIRST;
  727. }
  728. if (len < sock_remained_size[sn])
  729. pack_len = len;
  730. else
  731. pack_len = sock_remained_size[sn];
  732. wiz_recv_data(sn, buf, pack_len);
  733. break;
  734. // #if ( _WIZCHIP_ < 5200 )
  735. case Sn_MR_IPRAW:
  736. if (sock_remained_size[sn] == 0)
  737. {
  738. wiz_recv_data(sn, head, 6);
  739. setSn_CR(sn, Sn_CR_RECV);
  740. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  741. addr[0] = head[0];
  742. addr[1] = head[1];
  743. addr[2] = head[2];
  744. addr[3] = head[3];
  745. sock_remained_size[sn] = head[4];
  746. // M20150401 : For Typing Error
  747. // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
  748. sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
  749. sock_pack_info[sn] = PACK_FIRST;
  750. }
  751. //
  752. // Need to packet length check
  753. //
  754. if (len < sock_remained_size[sn])
  755. pack_len = len;
  756. else
  757. pack_len = sock_remained_size[sn];
  758. wiz_recv_data(sn, buf, pack_len); // data copy.
  759. break;
  760. // #endif
  761. default:
  762. wiz_recv_ignore(sn, pack_len); // data copy.
  763. sock_remained_size[sn] = pack_len;
  764. break;
  765. }
  766. setSn_CR(sn, Sn_CR_RECV);
  767. /* wait to process the command... */
  768. RyanWizchipCheck(getSn_CR(sn), 10, SOCKERR_SOCKCLOSED);
  769. sock_remained_size[sn] -= pack_len;
  770. // M20150601 :
  771. // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
  772. if (sock_remained_size[sn] != 0)
  773. {
  774. sock_pack_info[sn] |= PACK_REMAINED;
  775. #if _WIZCHIP_ == 5300
  776. if (pack_len & 0x01)
  777. sock_pack_info[sn] |= PACK_FIFOBYTE;
  778. #endif
  779. }
  780. else
  781. sock_pack_info[sn] = PACK_COMPLETED;
  782. #if _WIZCHIP_ == 5300
  783. pack_len = len;
  784. #endif
  785. //
  786. // M20150409 : Explicit Type Casting
  787. // return pack_len;
  788. return (int32_t)pack_len;
  789. }
  790. int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg)
  791. {
  792. uint8_t tmp = 0;
  793. CHECK_SOCKNUM();
  794. switch (cstype)
  795. {
  796. case CS_SET_IOMODE:
  797. tmp = *((uint8_t *)arg);
  798. if (tmp == SOCK_IO_NONBLOCK)
  799. sock_io_mode |= (1 << sn);
  800. else if (tmp == SOCK_IO_BLOCK)
  801. sock_io_mode &= ~(1 << sn);
  802. else
  803. return SOCKERR_ARG;
  804. break;
  805. case CS_GET_IOMODE:
  806. // M20140501 : implict type casting -> explict type casting
  807. //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
  808. *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
  809. //
  810. break;
  811. case CS_GET_MAXTXBUF:
  812. *((uint16_t *)arg) = getSn_TxMAX(sn);
  813. break;
  814. case CS_GET_MAXRXBUF:
  815. *((uint16_t *)arg) = getSn_RxMAX(sn);
  816. break;
  817. case CS_CLR_INTERRUPT:
  818. if ((*(uint8_t *)arg) > SIK_ALL)
  819. return SOCKERR_ARG;
  820. setSn_IR(sn, *(uint8_t *)arg);
  821. break;
  822. case CS_GET_INTERRUPT:
  823. *((uint8_t *)arg) = getSn_IR(sn);
  824. break;
  825. #if _WIZCHIP_ != 5100
  826. case CS_SET_INTMASK:
  827. if ((*(uint8_t *)arg) > SIK_ALL)
  828. return SOCKERR_ARG;
  829. setSn_IMR(sn, *(uint8_t *)arg);
  830. break;
  831. case CS_GET_INTMASK:
  832. *((uint8_t *)arg) = getSn_IMR(sn);
  833. break;
  834. #endif
  835. default:
  836. return SOCKERR_ARG;
  837. }
  838. return SOCK_OK;
  839. }
  840. int8_t wizchip_setsockopt(uint8_t sn, sockopt_type sotype, void *arg)
  841. {
  842. // M20131220 : Remove warning
  843. // uint8_t tmp;
  844. CHECK_SOCKNUM();
  845. switch (sotype)
  846. {
  847. case SO_TTL:
  848. setSn_TTL(sn, *(uint8_t *)arg);
  849. break;
  850. case SO_TOS:
  851. setSn_TOS(sn, *(uint8_t *)arg);
  852. break;
  853. case SO_MSS:
  854. setSn_MSSR(sn, *(uint16_t *)arg);
  855. break;
  856. case SO_DESTIP:
  857. setSn_DIPR(sn, (uint8_t *)arg);
  858. break;
  859. case SO_DESTPORT:
  860. setSn_DPORT(sn, *(uint16_t *)arg);
  861. break;
  862. #if _WIZCHIP_ != 5100
  863. case SO_KEEPALIVESEND:
  864. CHECK_SOCKMODE(Sn_MR_TCP);
  865. #if _WIZCHIP_ > 5200
  866. if (getSn_KPALVTR(sn) != 0)
  867. return SOCKERR_SOCKOPT;
  868. #endif
  869. setSn_CR(sn, Sn_CR_SEND_KEEP);
  870. RyanWizchipCheckCode(getSn_CR(sn) != 0, 1000, 2, SOCKERR_SOCKCLOSED, {
  871. // M20131220
  872. // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
  873. if (getSn_IR(sn) & Sn_IR_TIMEOUT)
  874. {
  875. setSn_IR(sn, Sn_IR_TIMEOUT);
  876. return SOCKERR_TIMEOUT;
  877. }
  878. });
  879. break;
  880. #if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200))
  881. case SO_KEEPALIVEAUTO:
  882. CHECK_SOCKMODE(Sn_MR_TCP);
  883. setSn_KPALVTR(sn, *(uint8_t *)arg);
  884. break;
  885. #endif
  886. #endif
  887. default:
  888. return SOCKERR_ARG;
  889. }
  890. return SOCK_OK;
  891. }
  892. int8_t wizchip_getsockopt(uint8_t sn, sockopt_type sotype, void *arg)
  893. {
  894. CHECK_SOCKNUM();
  895. switch (sotype)
  896. {
  897. case SO_FLAG:
  898. *(uint8_t *)arg = getSn_MR(sn) & 0xF0;
  899. break;
  900. case SO_TTL:
  901. *(uint8_t *)arg = getSn_TTL(sn);
  902. break;
  903. case SO_TOS:
  904. *(uint8_t *)arg = getSn_TOS(sn);
  905. break;
  906. case SO_MSS:
  907. *(uint16_t *)arg = getSn_MSSR(sn);
  908. break;
  909. case SO_DESTIP:
  910. getSn_DIPR(sn, (uint8_t *)arg);
  911. break;
  912. case SO_DESTPORT:
  913. *(uint16_t *)arg = getSn_DPORT(sn);
  914. break;
  915. #if _WIZCHIP_ > 5200
  916. case SO_KEEPALIVEAUTO:
  917. CHECK_SOCKMODE(Sn_MR_TCP);
  918. *(uint16_t *)arg = getSn_KPALVTR(sn);
  919. break;
  920. #endif
  921. case SO_SENDBUF:
  922. *(uint16_t *)arg = getSn_TX_FSR(sn);
  923. break;
  924. case SO_RECVBUF:
  925. *(uint16_t *)arg = getSn_RX_RSR(sn);
  926. break;
  927. case SO_STATUS:
  928. *(uint8_t *)arg = getSn_SR(sn);
  929. break;
  930. case SO_REMAINSIZE:
  931. if (getSn_MR(sn) & Sn_MR_TCP)
  932. *(uint16_t *)arg = getSn_RX_RSR(sn);
  933. else
  934. *(uint16_t *)arg = sock_remained_size[sn];
  935. break;
  936. case SO_PACKINFO:
  937. // CHECK_SOCKMODE(Sn_MR_TCP);
  938. #if _WIZCHIP_ != 5300
  939. if ((getSn_MR(sn) == Sn_MR_TCP))
  940. return SOCKERR_SOCKMODE;
  941. #endif
  942. *(uint8_t *)arg = sock_pack_info[sn];
  943. break;
  944. default:
  945. return SOCKERR_SOCKOPT;
  946. }
  947. return SOCK_OK;
  948. }