PageRenderTime 121ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/utility/socket.cpp

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