/src/Arduino/libraries/CC3000/utility/socket.cpp

https://github.com/InsideTheBlue/signal-fish · C++ · 1205 lines · 465 code · 158 blank · 582 comment · 42 complexity · 7b658ec1b32352cb7f4b2913f69ab340 MD5 · raw file

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