/core-common-lib/CC3000_Host_Driver/socket.c

https://github.com/vk2tds/Spark_Ethernet · C · 1212 lines · 459 code · 163 blank · 590 comment · 41 complexity · f7eaa0671a5d692c4123b52a01fcf07c MD5 · raw file

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