PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/SimplelinkWifi/utility/socket.c

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