PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/network/cc3000/socket.c

https://github.com/shehperd/Espruino
C | 1183 lines | 456 code | 153 blank | 574 comment | 36 complexity | 0710f4547215da597520ca5c626dfc51 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*****************************************************************************
  2. *
  3. * socket.c - CC3000 Host Driver Implementation.
  4. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. *
  13. * Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the
  16. * distribution.
  17. *
  18. * Neither the name of Texas Instruments Incorporated nor the names of
  19. * its contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  26. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  28. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  30. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  32. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. *****************************************************************************/
  35. //*****************************************************************************
  36. //
  37. //! \addtogroup socket_api
  38. //! @{
  39. //
  40. //*****************************************************************************
  41. #include "jsinteractive.h"
  42. #include "hci.h"
  43. #include "socket.h"
  44. #include "evnt_handler.h"
  45. #include "netapp.h"
  46. //Enable this flag if and only if you must comply with BSD socket
  47. //close() function
  48. #ifdef _API_USE_BSD_CLOSE
  49. #define close(sd) closesocket(sd)
  50. #endif
  51. //Enable this flag if and only if you must comply with BSD socket read() and
  52. //write() functions
  53. #ifdef _API_USE_BSD_READ_WRITE
  54. #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
  55. #define write(sd, buf, len, flags) send(sd, buf, len, flags)
  56. #endif
  57. #define SOCKET_OPEN_PARAMS_LEN (12)
  58. #define SOCKET_CLOSE_PARAMS_LEN (4)
  59. #define SOCKET_ACCEPT_PARAMS_LEN (4)
  60. #define SOCKET_BIND_PARAMS_LEN (20)
  61. #define SOCKET_LISTEN_PARAMS_LEN (8)
  62. #define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
  63. #define SOCKET_CONNECT_PARAMS_LEN (20)
  64. #define SOCKET_SELECT_PARAMS_LEN (44)
  65. #define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
  66. #define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
  67. #define SOCKET_RECV_FROM_PARAMS_LEN (12)
  68. #define SOCKET_SENDTO_PARAMS_LEN (24)
  69. #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
  70. // The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
  71. // while size of each parameter is 32 bit - so the total length is 16 bytes;
  72. #define HCI_CMND_SEND_ARG_LENGTH (16)
  73. #define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
  74. #define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
  75. #define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
  76. #define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
  77. //*****************************************************************************
  78. //
  79. //! HostFlowControlConsumeBuff
  80. //!
  81. //! @param sd socket descriptor
  82. //!
  83. //! @return 0 in case there are buffers available,
  84. //! -1 in case of bad socket
  85. //! -2 if there are no free buffers present (only when
  86. //! SEND_NON_BLOCKING is enabled)
  87. //!
  88. //! @brief if SEND_NON_BLOCKING not define - block until have free buffer
  89. //! becomes available, else return immediately with correct status
  90. //! regarding the buffers available.
  91. //
  92. //*****************************************************************************
  93. int
  94. HostFlowControlConsumeBuff(int sd)
  95. {
  96. #ifndef SEND_NON_BLOCKING
  97. /* wait in busy loop */
  98. do
  99. {
  100. // In case last transmission failed then we will return the last failure
  101. // reason here.
  102. // Note that the buffer will not be allocated in this case
  103. if (tSLInformation.slTransmitDataError != 0)
  104. {
  105. errno = tSLInformation.slTransmitDataError;
  106. tSLInformation.slTransmitDataError = 0;
  107. return errno;
  108. }
  109. if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
  110. return -1;
  111. } while(0 == tSLInformation.usNumberOfFreeBuffers);
  112. tSLInformation.usNumberOfFreeBuffers--;
  113. return 0;
  114. #else
  115. // In case last transmission failed then we will return the last failure
  116. // reason here.
  117. // Note that the buffer will not be allocated in this case
  118. if (tSLInformation.slTransmitDataError != 0)
  119. {
  120. errno = tSLInformation.slTransmitDataError;
  121. tSLInformation.slTransmitDataError = 0;
  122. return errno;
  123. }
  124. if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
  125. return -1;
  126. //If there are no available buffers, return -2. It is recommended to use
  127. // select or receive to see if there is any buffer occupied with received data
  128. // If so, call receive() to release the buffer.
  129. if(0 == tSLInformation.usNumberOfFreeBuffers)
  130. {
  131. return -2;
  132. }
  133. else
  134. {
  135. tSLInformation.usNumberOfFreeBuffers--;
  136. return 0;
  137. }
  138. #endif
  139. }
  140. //*****************************************************************************
  141. //
  142. //! socket
  143. //!
  144. //! @param domain selects the protocol family which will be used for
  145. //! communication. On this version only AF_INET is supported
  146. //! @param type specifies the communication semantics. On this version
  147. //! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
  148. //! @param protocol specifies a particular protocol to be used with the
  149. //! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
  150. //! supported.
  151. //!
  152. //! @return On success, socket handle that is used for consequent socket
  153. //! operations. On error, -1 is returned.
  154. //!
  155. //! @brief create an endpoint for communication
  156. //! The socket function creates a socket that is bound to a specific
  157. //! transport service provider. This function is called by the
  158. //! application layer to obtain a socket handle.
  159. //
  160. //*****************************************************************************
  161. int
  162. socket(long domain, long type, long protocol)
  163. {
  164. cc3000_check_irq_pin();
  165. long ret;
  166. unsigned char *ptr, *args;
  167. ret = EFAIL;
  168. ptr = tSLInformation.pucTxCommandBuffer;
  169. args = (ptr + HEADERS_SIZE_CMD);
  170. // Fill in HCI packet structure
  171. args = UINT32_TO_STREAM(args, domain);
  172. args = UINT32_TO_STREAM(args, type);
  173. args = UINT32_TO_STREAM(args, protocol);
  174. // Initiate a HCI command
  175. hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
  176. // Since we are in blocking state - wait for event complete
  177. SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
  178. // Process the event
  179. errno = ret;
  180. set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
  181. return(ret);
  182. }
  183. //*****************************************************************************
  184. //
  185. //! closesocket
  186. //!
  187. //! @param sd socket handle.
  188. //!
  189. //! @return On success, zero is returned. On error, -1 is returned.
  190. //!
  191. //! @brief The socket function closes a created socket.
  192. //
  193. //*****************************************************************************
  194. long
  195. closesocket(long sd)
  196. {
  197. cc3000_check_irq_pin();
  198. long ret;
  199. unsigned char *ptr, *args;
  200. ret = EFAIL;
  201. ptr = tSLInformation.pucTxCommandBuffer;
  202. args = (ptr + HEADERS_SIZE_CMD);
  203. // Fill in HCI packet structure
  204. args = UINT32_TO_STREAM(args, sd);
  205. // Initiate a HCI command
  206. hci_command_send(HCI_CMND_CLOSE_SOCKET,
  207. ptr, SOCKET_CLOSE_PARAMS_LEN);
  208. // Since we are in blocking state - wait for event complete
  209. SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
  210. errno = ret;
  211. // since 'close' call may result in either OK (and then it closed) or error
  212. // mark this socket as invalid
  213. set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
  214. return(ret);
  215. }
  216. //*****************************************************************************
  217. //
  218. //! accept
  219. //!
  220. //! @param[in] sd socket descriptor (handle)
  221. //! @param[out] addr the argument addr is a pointer to a sockaddr structure
  222. //! This structure is filled in with the address of the
  223. //! peer socket, as known to the communications layer.
  224. //! determined. The exact format of the address returned
  225. //! addr is by the socket's address sockaddr.
  226. //! On this version only AF_INET is supported.
  227. //! This argument returns in network order.
  228. //! @param[out] addrlen the addrlen argument is a value-result argument:
  229. //! it should initially contain the size of the structure
  230. //! pointed to by addr.
  231. //!
  232. //! @return For socket in blocking mode:
  233. //! On success, socket handle. on failure negative
  234. //! For socket in non-blocking mode:
  235. //! - On connection establishment, socket handle
  236. //! - On connection pending, SOC_IN_PROGRESS (-2)
  237. //! - On failure, SOC_ERROR (-1)
  238. //!
  239. //! @brief accept a connection on a socket:
  240. //! This function is used with connection-based socket types
  241. //! (SOCK_STREAM). It extracts the first connection request on the
  242. //! queue of pending connections, creates a new connected socket, and
  243. //! returns a new file descriptor referring to that socket.
  244. //! The newly created socket is not in the listening state.
  245. //! The original socket sd is unaffected by this call.
  246. //! The argument sd is a socket that has been created with socket(),
  247. //! bound to a local address with bind(), and is listening for
  248. //! connections after a listen(). The argument addr is a pointer
  249. //! to a sockaddr structure. This structure is filled in with the
  250. //! address of the peer socket, as known to the communications layer.
  251. //! The exact format of the address returned addr is determined by the
  252. //! socket's address family. The addrlen argument is a value-result
  253. //! argument: it should initially contain the size of the structure
  254. //! pointed to by addr, on return it will contain the actual
  255. //! length (in bytes) of the address returned.
  256. //!
  257. //! @sa socket ; bind ; listen
  258. //
  259. //*****************************************************************************
  260. long
  261. accept(long sd, sockaddr *addr, socklen_t *addrlen)
  262. {
  263. cc3000_check_irq_pin();
  264. long ret;
  265. unsigned char *ptr, *args;
  266. tBsdReturnParams tAcceptReturnArguments;
  267. ret = EFAIL;
  268. tAcceptReturnArguments.iStatus = EFAIL; // in case of timeout
  269. ptr = tSLInformation.pucTxCommandBuffer;
  270. args = (ptr + HEADERS_SIZE_CMD);
  271. // Fill in temporary command buffer
  272. args = UINT32_TO_STREAM(args, sd);
  273. // Initiate a HCI command
  274. hci_command_send(HCI_CMND_ACCEPT,
  275. ptr, SOCKET_ACCEPT_PARAMS_LEN);
  276. // Since we are in blocking state - wait for event complete
  277. SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
  278. // if we had a problem while waiting, just exit...
  279. if (jspIsInterrupted()) return -1;
  280. // need specify return parameters!!!
  281. memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
  282. *addrlen = ASIC_ADDR_LEN;
  283. errno = tAcceptReturnArguments.iStatus;
  284. ret = errno;
  285. // if succeeded, iStatus = new socket descriptor. otherwise - error number
  286. if(M_IS_VALID_SD(ret))
  287. {
  288. set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
  289. }
  290. else
  291. {
  292. set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
  293. }
  294. return(ret);
  295. }
  296. //*****************************************************************************
  297. //
  298. //! bind
  299. //!
  300. //! @param[in] sd socket descriptor (handle)
  301. //! @param[out] addr specifies the destination address. On this version
  302. //! only AF_INET is supported.
  303. //! @param[out] addrlen contains the size of the structure pointed to by addr.
  304. //!
  305. //! @return On success, zero is returned. On error, -1 is returned.
  306. //!
  307. //! @brief assign a name to a socket
  308. //! This function gives the socket the local address addr.
  309. //! addr is addrlen bytes long. Traditionally, this is called when a
  310. //! socket is created with socket, it exists in a name space (address
  311. //! family) but has no name assigned.
  312. //! It is necessary to assign a local address before a SOCK_STREAM
  313. //! socket may receive connections.
  314. //!
  315. //! @sa socket ; accept ; listen
  316. //
  317. //*****************************************************************************
  318. long
  319. bind(long sd, const sockaddr *addr, long addrlen)
  320. {
  321. cc3000_check_irq_pin();
  322. long ret;
  323. unsigned char *ptr, *args;
  324. ret = EFAIL;
  325. ptr = tSLInformation.pucTxCommandBuffer;
  326. args = (ptr + HEADERS_SIZE_CMD);
  327. addrlen = ASIC_ADDR_LEN;
  328. // Fill in temporary command buffer
  329. args = UINT32_TO_STREAM(args, sd);
  330. args = UINT32_TO_STREAM(args, 0x00000008);
  331. args = UINT32_TO_STREAM(args, addrlen);
  332. ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
  333. // Initiate a HCI command
  334. hci_command_send(HCI_CMND_BIND,
  335. ptr, SOCKET_BIND_PARAMS_LEN);
  336. // Since we are in blocking state - wait for event complete
  337. SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
  338. errno = ret;
  339. return(ret);
  340. }
  341. //*****************************************************************************
  342. //
  343. //! listen
  344. //!
  345. //! @param[in] sd socket descriptor (handle)
  346. //! @param[in] backlog specifies the listen queue depth. On this version
  347. //! backlog is not supported.
  348. //! @return On success, zero is returned. On error, -1 is returned.
  349. //!
  350. //! @brief listen for connections on a socket
  351. //! The willingness to accept incoming connections and a queue
  352. //! limit for incoming connections are specified with listen(),
  353. //! and then the connections are accepted with accept.
  354. //! The listen() call applies only to sockets of type SOCK_STREAM
  355. //! The backlog parameter defines the maximum length the queue of
  356. //! pending connections may grow to.
  357. //!
  358. //! @sa socket ; accept ; bind
  359. //!
  360. //! @note On this version, backlog is not supported
  361. //
  362. //*****************************************************************************
  363. long
  364. listen(long sd, long backlog)
  365. {
  366. cc3000_check_irq_pin();
  367. long ret;
  368. unsigned char *ptr, *args;
  369. ret = EFAIL;
  370. ptr = tSLInformation.pucTxCommandBuffer;
  371. args = (ptr + HEADERS_SIZE_CMD);
  372. // Fill in temporary command buffer
  373. args = UINT32_TO_STREAM(args, sd);
  374. args = UINT32_TO_STREAM(args, backlog);
  375. // Initiate a HCI command
  376. hci_command_send(HCI_CMND_LISTEN,
  377. ptr, SOCKET_LISTEN_PARAMS_LEN);
  378. // Since we are in blocking state - wait for event complete
  379. SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
  380. errno = ret;
  381. return(ret);
  382. }
  383. //*****************************************************************************
  384. //
  385. //! gethostbyname
  386. //!
  387. //! @param[in] hostname host name
  388. //! @param[in] usNameLen name length
  389. //! @param[out] out_ip_addr This parameter is filled in with host IP address.
  390. //! In case that host name is not resolved,
  391. //! out_ip_addr is zero.
  392. //! @return On success, positive is returned. On error, negative is returned
  393. //!
  394. //! @brief Get host IP by name. Obtain the IP Address of machine on network,
  395. //! by its name.
  396. //!
  397. //! @note On this version, only blocking mode is supported. Also note that
  398. //! the function requires DNS server to be configured prior to its usage.
  399. //
  400. //*****************************************************************************
  401. #ifndef CC3000_TINY_DRIVER
  402. int
  403. gethostbyname(char * hostname, unsigned short usNameLen,
  404. unsigned long* out_ip_addr)
  405. {
  406. cc3000_check_irq_pin();
  407. tBsdGethostbynameParams ret;
  408. unsigned char *ptr, *args;
  409. errno = EFAIL;
  410. if (usNameLen > HOSTNAME_MAX_LENGTH)
  411. {
  412. return errno;
  413. }
  414. ptr = tSLInformation.pucTxCommandBuffer;
  415. args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
  416. // Fill in HCI packet structure
  417. args = UINT32_TO_STREAM(args, 8);
  418. args = UINT32_TO_STREAM(args, usNameLen);
  419. ARRAY_TO_STREAM(args, hostname, usNameLen);
  420. // Initiate a HCI command
  421. hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN
  422. + usNameLen - 1);
  423. // Since we are in blocking state - wait for event complete
  424. SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
  425. errno = ret.retVal;
  426. (*((long*)out_ip_addr)) = ret.outputAddress;
  427. return (errno);
  428. }
  429. #endif
  430. //*****************************************************************************
  431. //
  432. //! connect
  433. //!
  434. //! @param[in] sd socket descriptor (handle)
  435. //! @param[in] addr specifies the destination addr. On this version
  436. //! only AF_INET is supported.
  437. //! @param[out] addrlen contains the size of the structure pointed to by addr
  438. //! @return On success, zero is returned. On error, -1 is returned
  439. //!
  440. //! @brief initiate a connection on a socket
  441. //! Function connects the socket referred to by the socket descriptor
  442. //! sd, to the address specified by addr. The addrlen argument
  443. //! specifies the size of addr. The format of the address in addr is
  444. //! determined by the address space of the socket. If it is of type
  445. //! SOCK_DGRAM, this call specifies the peer with which the socket is
  446. //! to be associated; this address is that to which datagrams are to be
  447. //! sent, and the only address from which datagrams are to be received.
  448. //! If the socket is of type SOCK_STREAM, this call attempts to make a
  449. //! connection to another socket. The other socket is specified by
  450. //! address, which is an address in the communications space of the
  451. //! socket. Note that the function implements only blocking behavior
  452. //! thus the caller will be waiting either for the connection
  453. //! establishment or for the connection establishment failure.
  454. //!
  455. //! @sa socket
  456. //
  457. //*****************************************************************************
  458. long
  459. connect(long sd, const sockaddr *addr, long addrlen)
  460. {
  461. cc3000_check_irq_pin();
  462. long int ret;
  463. unsigned char *ptr, *args;
  464. ret = EFAIL;
  465. ptr = tSLInformation.pucTxCommandBuffer;
  466. args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
  467. addrlen = 8;
  468. // Fill in temporary command buffer
  469. args = UINT32_TO_STREAM(args, sd);
  470. args = UINT32_TO_STREAM(args, 0x00000008);
  471. args = UINT32_TO_STREAM(args, addrlen);
  472. ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
  473. // Initiate a HCI command
  474. hci_command_send(HCI_CMND_CONNECT,
  475. ptr, SOCKET_CONNECT_PARAMS_LEN);
  476. // Since we are in blocking state - wait for event complete
  477. SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
  478. errno = ret;
  479. return((long)ret);
  480. }
  481. //*****************************************************************************
  482. //
  483. //! select
  484. //!
  485. //! @param[in] nfds the highest-numbered file descriptor in any of the
  486. //! three sets, plus 1.
  487. //! @param[out] writesds socket descriptors list for write monitoring
  488. //! @param[out] readsds socket descriptors list for read monitoring
  489. //! @param[out] exceptsds socket descriptors list for exception monitoring
  490. //! @param[in] timeout is an upper bound on the amount of time elapsed
  491. //! before select() returns. Null means infinity
  492. //! timeout. The minimum timeout is 5 milliseconds,
  493. //! less than 5 milliseconds will be set
  494. //! automatically to 5 milliseconds.
  495. //! @return On success, select() returns the number of file descriptors
  496. //! contained in the three returned descriptor sets (that is, the
  497. //! total number of bits that are set in readfds, writefds,
  498. //! exceptfds) which may be zero if the timeout expires before
  499. //! anything interesting happens.
  500. //! On error, -1 is returned.
  501. //! *readsds - return the sockets on which Read request will
  502. //! return without delay with valid data.
  503. //! *writesds - return the sockets on which Write request
  504. //! will return without delay.
  505. //! *exceptsds - return the sockets which closed recently.
  506. //!
  507. //! @brief Monitor socket activity
  508. //! Select allow a program to monitor multiple file descriptors,
  509. //! waiting until one or more of the file descriptors become
  510. //! "ready" for some class of I/O operation
  511. //!
  512. //! @Note If the timeout value set to less than 5ms it will automatically set
  513. //! to 5ms to prevent overload of the system
  514. //!
  515. //! @sa socket
  516. //
  517. //*****************************************************************************
  518. int
  519. select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds,
  520. struct timeval *timeout)
  521. {
  522. cc3000_check_irq_pin();
  523. unsigned char *ptr, *args;
  524. tBsdSelectRecvParams tParams;
  525. unsigned long is_blocking;
  526. if( timeout == NULL)
  527. {
  528. is_blocking = 1; /* blocking , infinity timeout */
  529. }
  530. else
  531. {
  532. is_blocking = 0; /* no blocking, timeout */
  533. }
  534. // Fill in HCI packet structure
  535. ptr = tSLInformation.pucTxCommandBuffer;
  536. args = (ptr + HEADERS_SIZE_CMD);
  537. // Fill in temporary command buffer
  538. args = UINT32_TO_STREAM(args, nfds);
  539. args = UINT32_TO_STREAM(args, 0x00000014);
  540. args = UINT32_TO_STREAM(args, 0x00000014);
  541. args = UINT32_TO_STREAM(args, 0x00000014);
  542. args = UINT32_TO_STREAM(args, 0x00000014);
  543. args = UINT32_TO_STREAM(args, is_blocking);
  544. args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
  545. args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
  546. args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
  547. if (timeout)
  548. {
  549. if ( 0 == timeout->tv_sec && timeout->tv_usec <
  550. SELECT_TIMEOUT_MIN_MICRO_SECONDS)
  551. {
  552. timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
  553. }
  554. args = UINT32_TO_STREAM(args, timeout->tv_sec);
  555. args = UINT32_TO_STREAM(args, timeout->tv_usec);
  556. }
  557. // Initiate a HCI command
  558. hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
  559. // Since we are in blocking state - wait for event complete
  560. SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
  561. // Update actually read FD
  562. if (tParams.iStatus >= 0)
  563. {
  564. if (readsds)
  565. {
  566. memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
  567. }
  568. if (writesds)
  569. {
  570. memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
  571. }
  572. if (exceptsds)
  573. {
  574. memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
  575. }
  576. return(tParams.iStatus);
  577. }
  578. else
  579. {
  580. errno = tParams.iStatus;
  581. return(-1);
  582. }
  583. }
  584. //*****************************************************************************
  585. //
  586. //! setsockopt
  587. //!
  588. //! @param[in] sd socket handle
  589. //! @param[in] level defines the protocol level for this option
  590. //! @param[in] optname defines the option name to Interrogate
  591. //! @param[in] optval specifies a value for the option
  592. //! @param[in] optlen specifies the length of the option value
  593. //! @return On success, zero is returned. On error, -1 is returned
  594. //!
  595. //! @brief set socket options
  596. //! This function manipulate the options associated with a socket.
  597. //! Options may exist at multiple protocol levels; they are always
  598. //! present at the uppermost socket level.
  599. //! When manipulating socket options the level at which the option
  600. //! resides and the name of the option must be specified.
  601. //! To manipulate options at the socket level, level is specified as
  602. //! SOL_SOCKET. To manipulate options at any other level the protocol
  603. //! number of the appropriate protocol controlling the option is
  604. //! supplied. For example, to indicate that an option is to be
  605. //! interpreted by the TCP protocol, level should be set to the
  606. //! protocol number of TCP;
  607. //! The parameters optval and optlen are used to access optval -
  608. //! use for setsockopt(). For getsockopt() they identify a buffer
  609. //! in which the value for the requested option(s) are to
  610. //! be returned. For getsockopt(), optlen is a value-result
  611. //! parameter, initially containing the size of the buffer
  612. //! pointed to by option_value, and modified on return to
  613. //! indicate the actual size of the value returned. If no option
  614. //! value is to be supplied or returned, option_value may be NULL.
  615. //!
  616. //! @Note On this version the following two socket options are enabled:
  617. //! The only protocol level supported in this version
  618. //! is SOL_SOCKET (level).
  619. //! 1. SOCKOPT_RECV_TIMEOUT (optname)
  620. //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
  621. //! in milliseconds.
  622. //! In that case optval should be pointer to unsigned long.
  623. //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
  624. //! or off.
  625. //! In that case optval should be SOCK_ON or SOCK_OFF (optval).
  626. //!
  627. //! @sa getsockopt
  628. //
  629. //*****************************************************************************
  630. #ifndef CC3000_TINY_DRIVER
  631. int
  632. setsockopt(long sd, long level, long optname, const void *optval,
  633. socklen_t optlen)
  634. {
  635. cc3000_check_irq_pin();
  636. int ret;
  637. unsigned char *ptr, *args;
  638. ptr = tSLInformation.pucTxCommandBuffer;
  639. args = (ptr + HEADERS_SIZE_CMD);
  640. // Fill in temporary command buffer
  641. args = UINT32_TO_STREAM(args, sd);
  642. args = UINT32_TO_STREAM(args, level);
  643. args = UINT32_TO_STREAM(args, optname);
  644. args = UINT32_TO_STREAM(args, 0x00000008);
  645. args = UINT32_TO_STREAM(args, optlen);
  646. ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
  647. // Initiate a HCI command
  648. hci_command_send(HCI_CMND_SETSOCKOPT,
  649. ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
  650. // Since we are in blocking state - wait for event complete
  651. SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
  652. if (ret >= 0)
  653. {
  654. return (0);
  655. }
  656. else
  657. {
  658. errno = ret;
  659. return ret;
  660. }
  661. }
  662. #endif
  663. //*****************************************************************************
  664. //
  665. //! getsockopt
  666. //!
  667. //! @param[in] sd socket handle
  668. //! @param[in] level defines the protocol level for this option
  669. //! @param[in] optname defines the option name to Interrogate
  670. //! @param[out] optval specifies a value for the option
  671. //! @param[out] optlen specifies the length of the option value
  672. //! @return On success, zero is returned. On error, -1 is returned
  673. //!
  674. //! @brief set socket options
  675. //! This function manipulate the options associated with a socket.
  676. //! Options may exist at multiple protocol levels; they are always
  677. //! present at the uppermost socket level.
  678. //! When manipulating socket options the level at which the option
  679. //! resides and the name of the option must be specified.
  680. //! To manipulate options at the socket level, level is specified as
  681. //! SOL_SOCKET. To manipulate options at any other level the protocol
  682. //! number of the appropriate protocol controlling the option is
  683. //! supplied. For example, to indicate that an option is to be
  684. //! interpreted by the TCP protocol, level should be set to the
  685. //! protocol number of TCP;
  686. //! The parameters optval and optlen are used to access optval -
  687. //! use for setsockopt(). For getsockopt() they identify a buffer
  688. //! in which the value for the requested option(s) are to
  689. //! be returned. For getsockopt(), optlen is a value-result
  690. //! parameter, initially containing the size of the buffer
  691. //! pointed to by option_value, and modified on return to
  692. //! indicate the actual size of the value returned. If no option
  693. //! value is to be supplied or returned, option_value may be NULL.
  694. //!
  695. //! @Note On this version the following two socket options are enabled:
  696. //! The only protocol level supported in this version
  697. //! is SOL_SOCKET (level).
  698. //! 1. SOCKOPT_RECV_TIMEOUT (optname)
  699. //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
  700. //! in milliseconds.
  701. //! In that case optval should be pointer to unsigned long.
  702. //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
  703. //! or off.
  704. //! In that case optval should be SOCK_ON or SOCK_OFF (optval).
  705. //!
  706. //! @sa setsockopt
  707. //
  708. //*****************************************************************************
  709. int
  710. getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
  711. {
  712. cc3000_check_irq_pin();
  713. unsigned char *ptr, *args;
  714. tBsdGetSockOptReturnParams tRetParams;
  715. ptr = tSLInformation.pucTxCommandBuffer;
  716. args = (ptr + HEADERS_SIZE_CMD);
  717. // Fill in temporary command buffer
  718. args = UINT32_TO_STREAM(args, sd);
  719. args = UINT32_TO_STREAM(args, level);
  720. args = UINT32_TO_STREAM(args, optname);
  721. // Initiate a HCI command
  722. hci_command_send(HCI_CMND_GETSOCKOPT,
  723. ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
  724. // Since we are in blocking state - wait for event complete
  725. SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
  726. if (((signed char)tRetParams.iStatus) >= 0)
  727. {
  728. *optlen = 4;
  729. memcpy(optval, tRetParams.ucOptValue, 4);
  730. return (0);
  731. }
  732. else
  733. {
  734. errno = tRetParams.iStatus;
  735. return errno;
  736. }
  737. }
  738. //*****************************************************************************
  739. //
  740. //! simple_link_recv
  741. //!
  742. //! @param sd socket handle
  743. //! @param buf read buffer
  744. //! @param len buffer length
  745. //! @param flags indicates blocking or non-blocking operation
  746. //! @param from pointer to an address structure indicating source address
  747. //! @param fromlen source address structure size
  748. //!
  749. //! @return Return the number of bytes received, or -1 if an error
  750. //! occurred
  751. //!
  752. //! @brief Read data from socket
  753. //! Return the length of the message on successful completion.
  754. //! If a message is too long to fit in the supplied buffer,
  755. //! excess bytes may be discarded depending on the type of
  756. //! socket the message is received from
  757. //
  758. //*****************************************************************************
  759. int
  760. simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
  761. socklen_t *fromlen, long opcode)
  762. {
  763. cc3000_check_irq_pin();
  764. unsigned char *ptr, *args;
  765. tBsdReadReturnParams tSocketReadEvent;
  766. ptr = tSLInformation.pucTxCommandBuffer;
  767. args = (ptr + HEADERS_SIZE_CMD);
  768. // Fill in HCI packet structure
  769. args = UINT32_TO_STREAM(args, sd);
  770. args = UINT32_TO_STREAM(args, len);
  771. args = UINT32_TO_STREAM(args, flags);
  772. // Generate the read command, and wait for the
  773. hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
  774. // Since we are in blocking state - wait for event complete
  775. SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
  776. // In case the number of bytes is more then zero - read data
  777. if (tSocketReadEvent.iNumberOfBytes > 0)
  778. {
  779. // Wait for the data in a synchronous way. Here we assume that the bug is
  780. // big enough to store also parameters of receive from too....
  781. SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen);
  782. }
  783. errno = tSocketReadEvent.iNumberOfBytes;
  784. return(tSocketReadEvent.iNumberOfBytes);
  785. }
  786. //*****************************************************************************
  787. //
  788. //! recv
  789. //!
  790. //! @param[in] sd socket handle
  791. //! @param[out] buf Points to the buffer where the message should be stored
  792. //! @param[in] len Specifies the length in bytes of the buffer pointed to
  793. //! by the buffer argument.
  794. //! @param[in] flags Specifies the type of message reception.
  795. //! On this version, this parameter is not supported.
  796. //!
  797. //! @return Return the number of bytes received, or -1 if an error
  798. //! occurred
  799. //!
  800. //! @brief function receives a message from a connection-mode socket
  801. //!
  802. //! @sa recvfrom
  803. //!
  804. //! @Note On this version, only blocking mode is supported.
  805. //
  806. //*****************************************************************************
  807. int
  808. recv(long sd, void *buf, long len, long flags)
  809. {
  810. return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
  811. }
  812. //*****************************************************************************
  813. //
  814. //! recvfrom
  815. //!
  816. //! @param[in] sd socket handle
  817. //! @param[out] buf Points to the buffer where the message should be stored
  818. //! @param[in] len Specifies the length in bytes of the buffer pointed to
  819. //! by the buffer argument.
  820. //! @param[in] flags Specifies the type of message reception.
  821. //! On this version, this parameter is not supported.
  822. //! @param[in] from pointer to an address structure indicating the source
  823. //! address: sockaddr. On this version only AF_INET is
  824. //! supported.
  825. //! @param[in] fromlen source address tructure size
  826. //!
  827. //! @return Return the number of bytes received, or -1 if an error
  828. //! occurred
  829. //!
  830. //! @brief read data from socket
  831. //! function receives a message from a connection-mode or
  832. //! connectionless-mode socket. Note that raw sockets are not
  833. //! supported.
  834. //!
  835. //! @sa recv
  836. //!
  837. //! @Note On this version, only blocking mode is supported.
  838. //
  839. //*****************************************************************************
  840. int
  841. recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
  842. socklen_t *fromlen)
  843. {
  844. return(simple_link_recv(sd, buf, len, flags, from, fromlen,
  845. HCI_CMND_RECVFROM));
  846. }
  847. //*****************************************************************************
  848. //
  849. //! simple_link_send
  850. //!
  851. //! @param sd socket handle
  852. //! @param buf write buffer
  853. //! @param len buffer length
  854. //! @param flags On this version, this parameter is not supported
  855. //! @param to pointer to an address structure indicating destination
  856. //! address
  857. //! @param tolen destination address structure size
  858. //!
  859. //! @return Return the number of bytes transmitted, or -1 if an error
  860. //! occurred, or -2 in case there are no free buffers available
  861. //! (only when SEND_NON_BLOCKING is enabled)
  862. //!
  863. //! @brief This function is used to transmit a message to another
  864. //! socket
  865. //
  866. //*****************************************************************************
  867. int
  868. simple_link_send(long sd, const void *buf, long len, long flags,
  869. const sockaddr *to, long tolen, long opcode)
  870. {
  871. cc3000_check_irq_pin();
  872. unsigned char uArgSize, addrlen;
  873. unsigned char *ptr, *pDataPtr, *args;
  874. unsigned long addr_offset;
  875. int res;
  876. tBsdReadReturnParams tSocketSendEvent;
  877. // Check the bsd_arguments
  878. if (0 != (res = HostFlowControlConsumeBuff(sd)))
  879. {
  880. return res;
  881. }
  882. //Update the number of sent packets
  883. tSLInformation.NumberOfSentPackets++;
  884. // Allocate a buffer and construct a packet and send it over spi
  885. ptr = tSLInformation.pucTxCommandBuffer;
  886. args = (ptr + HEADERS_SIZE_DATA);
  887. // Update the offset of data and parameters according to the command
  888. switch(opcode)
  889. {
  890. case HCI_CMND_SENDTO:
  891. {
  892. addr_offset = len + sizeof(len) + sizeof(len);
  893. addrlen = 8;
  894. uArgSize = SOCKET_SENDTO_PARAMS_LEN;
  895. pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
  896. break;
  897. }
  898. case HCI_CMND_SEND:
  899. {
  900. tolen = 0;
  901. to = NULL;
  902. uArgSize = HCI_CMND_SEND_ARG_LENGTH;
  903. pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
  904. break;
  905. }
  906. default:
  907. {
  908. break;
  909. }
  910. }
  911. // Fill in temporary command buffer
  912. args = UINT32_TO_STREAM(args, sd);
  913. args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
  914. args = UINT32_TO_STREAM(args, len);
  915. args = UINT32_TO_STREAM(args, flags);
  916. if (opcode == HCI_CMND_SENDTO)
  917. {
  918. args = UINT32_TO_STREAM(args, addr_offset);
  919. args = UINT32_TO_STREAM(args, addrlen);
  920. }
  921. // Copy the data received from user into the TX Buffer
  922. ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
  923. // In case we are using SendTo, copy the to parameters
  924. if (opcode == HCI_CMND_SENDTO)
  925. {
  926. ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
  927. }
  928. // Initiate a HCI command
  929. hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
  930. if (opcode == HCI_CMND_SENDTO)
  931. SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
  932. else
  933. SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
  934. return (len);
  935. }
  936. //*****************************************************************************
  937. //
  938. //! send
  939. //!
  940. //! @param sd socket handle
  941. //! @param buf Points to a buffer containing the message to be sent
  942. //! @param len message size in bytes
  943. //! @param flags On this version, this parameter is not supported
  944. //!
  945. //! @return Return the number of bytes transmitted, or -1 if an
  946. //! error occurred
  947. //!
  948. //! @brief Write data to TCP socket
  949. //! This function is used to transmit a message to another
  950. //! socket.
  951. //!
  952. //! @Note On this version, only blocking mode is supported.
  953. //!
  954. //! @sa sendto
  955. //
  956. //*****************************************************************************
  957. int
  958. send(long sd, const void *buf, long len, long flags)
  959. {
  960. return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
  961. }
  962. //*****************************************************************************
  963. //
  964. //! sendto
  965. //!
  966. //! @param sd socket handle
  967. //! @param buf Points to a buffer containing the message to be sent
  968. //! @param len message size in bytes
  969. //! @param flags On this version, this parameter is not supported
  970. //! @param to pointer to an address structure indicating the destination
  971. //! address: sockaddr. On this version only AF_INET is
  972. //! supported.
  973. //! @param tolen destination address structure size
  974. //!
  975. //! @return Return the number of bytes transmitted, or -1 if an
  976. //! error occurred
  977. //!
  978. //! @brief Write data to TCP socket
  979. //! This function is used to transmit a message to another
  980. //! socket.
  981. //!
  982. //! @Note On this version, only blocking mode is supported.
  983. //!
  984. //! @sa send
  985. //
  986. //*****************************************************************************
  987. int
  988. sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
  989. socklen_t tolen)
  990. {
  991. return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
  992. }
  993. //*****************************************************************************
  994. //
  995. //! mdnsAdvertiser
  996. //!
  997. //! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
  998. //! @param[in] deviceServiceName Service name as part of the published
  999. //! canonical domain name
  1000. //! @param[in] deviceServiceNameLength Length of the service name
  1001. //!
  1002. //!
  1003. //! @return On success, zero is returned, return SOC_ERROR if socket was not
  1004. //! opened successfully, or if an error occurred.
  1005. //!
  1006. //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
  1007. //
  1008. //*****************************************************************************
  1009. int
  1010. mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
  1011. {
  1012. int ret;
  1013. unsigned char *pTxBuffer, *pArgs;
  1014. if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
  1015. {
  1016. return EFAIL;
  1017. }
  1018. pTxBuffer = tSLInformation.pucTxCommandBuffer;
  1019. pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
  1020. // Fill in HCI packet structure
  1021. pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
  1022. pArgs = UINT32_TO_STREAM(pArgs, 8);
  1023. pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
  1024. ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
  1025. // Initiate a HCI command
  1026. hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
  1027. // Since we are in blocking state - wait for event complete
  1028. SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
  1029. return ret;
  1030. }