CC3000HostDriver for device TI CC3000 some changes were made due to mbed compiler and the use of void*
Embed:
(wiki syntax)
Show/hide line numbers
socket.cpp
00001 /***************************************************************************** 00002 * 00003 * socket.c - CC3000 Host Driver Implementation. 00004 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * Neither the name of Texas Instruments Incorporated nor the names of 00019 * its contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00025 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00026 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 *****************************************************************************/ 00035 00036 //***************************************************************************** 00037 // 00038 //! \addtogroup socket_api 00039 //! @{ 00040 // 00041 //***************************************************************************** 00042 00043 #include <stdio.h> 00044 #include <string.h> 00045 #include <stdlib.h> 00046 #include "hci.h" 00047 #include "socket.h" 00048 #include "evnt_handler.h" 00049 #include "netapp.h" 00050 00051 00052 00053 //Enable this flag if and only if you must comply with BSD socket 00054 //close() function 00055 #ifdef _API_USE_BSD_CLOSE 00056 #define close(sd) closesocket(sd) 00057 #endif 00058 00059 //Enable this flag if and only if you must comply with BSD socket read() and 00060 //write() functions 00061 #ifdef _API_USE_BSD_READ_WRITE 00062 #define read(sd, buf, len, flags) recv(sd, buf, len, flags) 00063 #define write(sd, buf, len, flags) send(sd, buf, len, flags) 00064 #endif 00065 00066 #define SOCKET_OPEN_PARAMS_LEN (12) 00067 #define SOCKET_CLOSE_PARAMS_LEN (4) 00068 #define SOCKET_ACCEPT_PARAMS_LEN (4) 00069 #define SOCKET_BIND_PARAMS_LEN (20) 00070 #define SOCKET_LISTEN_PARAMS_LEN (8) 00071 #define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) 00072 #define SOCKET_CONNECT_PARAMS_LEN (20) 00073 #define SOCKET_SELECT_PARAMS_LEN (44) 00074 #define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) 00075 #define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) 00076 #define SOCKET_RECV_FROM_PARAMS_LEN (12) 00077 #define SOCKET_SENDTO_PARAMS_LEN (24) 00078 #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) 00079 00080 00081 // The legnth of arguments for the SEND command: sd + buff_offset + len + flags, 00082 // while size of each parameter is 32 bit - so the total length is 16 bytes; 00083 00084 #define HCI_CMND_SEND_ARG_LENGTH (16) 00085 00086 00087 #define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 00088 00089 #define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) 00090 00091 #define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) 00092 00093 #define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) 00094 00095 00096 //***************************************************************************** 00097 // 00098 //! HostFlowControlConsumeBuff 00099 //! 00100 //! @param sd socket descriptor 00101 //! 00102 //! @return 0 in case there are buffers available, 00103 //! -1 in case of bad socket 00104 //! -2 if there are no free buffers present (only when 00105 //! SEND_NON_BLOCKING is enabled) 00106 //! 00107 //! @brief if SEND_NON_BLOCKING not define - block until have free buffer 00108 //! becomes available, else return immediately with correct status 00109 //! regarding the buffers available. 00110 // 00111 //***************************************************************************** 00112 int 00113 HostFlowControlConsumeBuff(int sd) 00114 { 00115 #ifndef SEND_NON_BLOCKING 00116 /* wait in busy loop */ 00117 do 00118 { 00119 // In case last transmission failed then we will return the last failure 00120 // reason here. 00121 // Note that the buffer will not be allocated in this case 00122 if (tSLInformation.slTransmitDataError != 0) 00123 { 00124 errno = tSLInformation.slTransmitDataError; 00125 tSLInformation.slTransmitDataError = 0; 00126 return errno; 00127 } 00128 00129 if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) 00130 return -1; 00131 } while(0 == tSLInformation.usNumberOfFreeBuffers); 00132 00133 tSLInformation.usNumberOfFreeBuffers--; 00134 00135 return 0; 00136 #else 00137 00138 // In case last transmission failed then we will return the last failure 00139 // reason here. 00140 // Note that the buffer will not be allocated in this case 00141 if (tSLInformation.slTransmitDataError != 0) 00142 { 00143 errno = tSLInformation.slTransmitDataError; 00144 tSLInformation.slTransmitDataError = 0; 00145 return errno; 00146 } 00147 if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd)) 00148 return -1; 00149 00150 //If there are no available buffers, return -2. It is recommended to use 00151 // select or receive to see if there is any buffer occupied with received data 00152 // If so, call receive() to release the buffer. 00153 if(0 == tSLInformation.usNumberOfFreeBuffers) 00154 { 00155 return -2; 00156 } 00157 else 00158 { 00159 tSLInformation.usNumberOfFreeBuffers--; 00160 return 0; 00161 } 00162 #endif 00163 } 00164 00165 //***************************************************************************** 00166 // 00167 //! socket 00168 //! 00169 //! @param domain selects the protocol family which will be used for 00170 //! communication. On this version only AF_INET is supported 00171 //! @param type specifies the communication semantics. On this version 00172 //! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported 00173 //! @param protocol specifies a particular protocol to be used with the 00174 //! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are 00175 //! supported. 00176 //! 00177 //! @return On success, socket handle that is used for consequent socket 00178 //! operations. On error, -1 is returned. 00179 //! 00180 //! @brief create an endpoint for communication 00181 //! The socket function creates a socket that is bound to a specific 00182 //! transport service provider. This function is called by the 00183 //! application layer to obtain a socket handle. 00184 // 00185 //***************************************************************************** 00186 00187 int 00188 socket(long domain, long type, long protocol) 00189 { 00190 long ret; 00191 unsigned char *ptr, *args; 00192 00193 ret = EFAIL; 00194 ptr = tSLInformation.pucTxCommandBuffer; 00195 args = (ptr + HEADERS_SIZE_CMD); 00196 00197 // Fill in HCI packet structure 00198 args = UINT32_TO_STREAM(args, domain); 00199 args = UINT32_TO_STREAM(args, type); 00200 args = UINT32_TO_STREAM(args, protocol); 00201 00202 // Initiate a HCI command 00203 hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); 00204 00205 // Since we are in blocking state - wait for event complete 00206 SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); 00207 00208 // Process the event 00209 errno = ret; 00210 00211 set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); 00212 00213 return(ret); 00214 } 00215 00216 //***************************************************************************** 00217 // 00218 //! closesocket 00219 //! 00220 //! @param sd socket handle. 00221 //! 00222 //! @return On success, zero is returned. On error, -1 is returned. 00223 //! 00224 //! @brief The socket function closes a created socket. 00225 // 00226 //***************************************************************************** 00227 00228 long 00229 closesocket(long sd) 00230 { 00231 long ret; 00232 unsigned char *ptr, *args; 00233 00234 ret = EFAIL; 00235 ptr = tSLInformation.pucTxCommandBuffer; 00236 args = (ptr + HEADERS_SIZE_CMD); 00237 00238 // Fill in HCI packet structure 00239 args = UINT32_TO_STREAM(args, sd); 00240 00241 // Initiate a HCI command 00242 hci_command_send(HCI_CMND_CLOSE_SOCKET, 00243 ptr, SOCKET_CLOSE_PARAMS_LEN); 00244 00245 // Since we are in blocking state - wait for event complete 00246 SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); 00247 errno = ret; 00248 00249 // since 'close' call may result in either OK (and then it closed) or error 00250 // mark this socket as invalid 00251 set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); 00252 00253 return(ret); 00254 } 00255 00256 //***************************************************************************** 00257 // 00258 //! accept 00259 //! 00260 //! @param[in] sd socket descriptor (handle) 00261 //! @param[out] addr the argument addr is a pointer to a sockaddr structure 00262 //! This structure is filled in with the address of the 00263 //! peer socket, as known to the communications layer. 00264 //! determined. The exact format of the address returned 00265 //! addr is by the socket's address sockaddr. 00266 //! On this version only AF_INET is supported. 00267 //! This argument returns in network order. 00268 //! @param[out] addrlen the addrlen argument is a value-result argument: 00269 //! it should initially contain the size of the structure 00270 //! pointed to by addr. 00271 //! 00272 //! @return For socket in blocking mode: 00273 //! On success, socket handle. on failure negative 00274 //! For socket in non-blocking mode: 00275 //! - On connection establishment, socket handle 00276 //! - On connection pending, SOC_IN_PROGRESS (-2) 00277 //! - On failure, SOC_ERROR (-1) 00278 //! 00279 //! @brief accept a connection on a socket: 00280 //! This function is used with connection-based socket types 00281 //! (SOCK_STREAM). It extracts the first connection request on the 00282 //! queue of pending connections, creates a new connected socket, and 00283 //! returns a new file descriptor referring to that socket. 00284 //! The newly created socket is not in the listening state. 00285 //! The original socket sd is unaffected by this call. 00286 //! The argument sd is a socket that has been created with socket(), 00287 //! bound to a local address with bind(), and is listening for 00288 //! connections after a listen(). The argument addr is a pointer 00289 //! to a sockaddr structure. This structure is filled in with the 00290 //! address of the peer socket, as known to the communications layer. 00291 //! The exact format of the address returned addr is determined by the 00292 //! socket's address family. The addrlen argument is a value-result 00293 //! argument: it should initially contain the size of the structure 00294 //! pointed to by addr, on return it will contain the actual 00295 //! length (in bytes) of the address returned. 00296 //! 00297 //! @sa socket ; bind ; listen 00298 // 00299 //***************************************************************************** 00300 00301 long 00302 accept(long sd, sockaddr *addr, socklen_t *addrlen) 00303 { 00304 long ret; 00305 unsigned char *ptr, *args; 00306 tBsdReturnParams tAcceptReturnArguments; 00307 00308 ret = EFAIL; 00309 ptr = tSLInformation.pucTxCommandBuffer; 00310 args = (ptr + HEADERS_SIZE_CMD); 00311 00312 // Fill in temporary command buffer 00313 args = UINT32_TO_STREAM(args, sd); 00314 00315 // Initiate a HCI command 00316 hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); 00317 00318 // Since we are in blocking state - wait for event complete 00319 SimpleLinkWaitEvent(HCI_CMND_ACCEPT, (long*)&tAcceptReturnArguments); 00320 00321 00322 // need specify return parameters!!! 00323 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); 00324 *addrlen = ASIC_ADDR_LEN; 00325 errno = tAcceptReturnArguments.iStatus; 00326 ret = errno; 00327 00328 // if succeeded, iStatus = new socket descriptor. otherwise - error number 00329 if(M_IS_VALID_SD(ret)) 00330 { 00331 set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); 00332 } 00333 else 00334 { 00335 set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); 00336 } 00337 00338 return(ret); 00339 } 00340 00341 //***************************************************************************** 00342 // 00343 //! bind 00344 //! 00345 //! @param[in] sd socket descriptor (handle) 00346 //! @param[out] addr specifies the destination address. On this version 00347 //! only AF_INET is supported. 00348 //! @param[out] addrlen contains the size of the structure pointed to by addr. 00349 //! 00350 //! @return On success, zero is returned. On error, -1 is returned. 00351 //! 00352 //! @brief assign a name to a socket 00353 //! This function gives the socket the local address addr. 00354 //! addr is addrlen bytes long. Traditionally, this is called when a 00355 //! socket is created with socket, it exists in a name space (address 00356 //! family) but has no name assigned. 00357 //! It is necessary to assign a local address before a SOCK_STREAM 00358 //! socket may receive connections. 00359 //! 00360 //! @sa socket ; accept ; listen 00361 // 00362 //***************************************************************************** 00363 00364 long 00365 bind(long sd, const sockaddr *addr, long addrlen) 00366 { 00367 long ret; 00368 unsigned char *ptr, *args; 00369 00370 ret = EFAIL; 00371 ptr = tSLInformation.pucTxCommandBuffer; 00372 args = (ptr + HEADERS_SIZE_CMD); 00373 00374 addrlen = ASIC_ADDR_LEN; 00375 00376 // Fill in temporary command buffer 00377 args = UINT32_TO_STREAM(args, sd); 00378 args = UINT32_TO_STREAM(args, 0x00000008); 00379 args = UINT32_TO_STREAM(args, addrlen); 00380 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); 00381 00382 // Initiate a HCI command 00383 hci_command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); 00384 00385 // Since we are in blocking state - wait for event complete 00386 SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); 00387 00388 errno = ret; 00389 00390 return(ret); 00391 } 00392 00393 //***************************************************************************** 00394 // 00395 //! listen 00396 //! 00397 //! @param[in] sd socket descriptor (handle) 00398 //! @param[in] backlog specifies the listen queue depth. On this version 00399 //! backlog is not supported. 00400 //! @return On success, zero is returned. On error, -1 is returned. 00401 //! 00402 //! @brief listen for connections on a socket 00403 //! The willingness to accept incoming connections and a queue 00404 //! limit for incoming connections are specified with listen(), 00405 //! and then the connections are accepted with accept. 00406 //! The listen() call applies only to sockets of type SOCK_STREAM 00407 //! The backlog parameter defines the maximum length the queue of 00408 //! pending connections may grow to. 00409 //! 00410 //! @sa socket ; accept ; bind 00411 //! 00412 //! @note On this version, backlog is not supported 00413 // 00414 //***************************************************************************** 00415 00416 long 00417 listen(long sd, long backlog) 00418 { 00419 long ret; 00420 unsigned char *ptr, *args; 00421 00422 ret = EFAIL; 00423 ptr = tSLInformation.pucTxCommandBuffer; 00424 args = (ptr + HEADERS_SIZE_CMD); 00425 00426 // Fill in temporary command buffer 00427 args = UINT32_TO_STREAM(args, sd); 00428 args = UINT32_TO_STREAM(args, backlog); 00429 00430 // Initiate a HCI command 00431 hci_command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); 00432 00433 // Since we are in blocking state - wait for event complete 00434 SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); 00435 errno = ret; 00436 00437 return(ret); 00438 } 00439 00440 //***************************************************************************** 00441 // 00442 //! gethostbyname 00443 //! 00444 //! @param[in] hostname host name 00445 //! @param[in] usNameLen name length 00446 //! @param[out] out_ip_addr This parameter is filled in with host IP address. 00447 //! In case that host name is not resolved, 00448 //! out_ip_addr is zero. 00449 //! @return On success, positive is returned. On error, negative is returned 00450 //! 00451 //! @brief Get host IP by name. Obtain the IP Address of machine on network, 00452 //! by its name. 00453 //! 00454 //! @note On this version, only blocking mode is supported. Also note that 00455 //! the function requires DNS server to be configured prior to its usage. 00456 // 00457 //***************************************************************************** 00458 00459 #ifndef CC3000_TINY_DRIVER 00460 int 00461 gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr) 00462 { 00463 tBsdGethostbynameParams ret; 00464 unsigned char *ptr, *args; 00465 00466 errno = EFAIL; 00467 00468 if (usNameLen > HOSTNAME_MAX_LENGTH) 00469 { 00470 return errno; 00471 } 00472 00473 ptr = tSLInformation.pucTxCommandBuffer; 00474 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00475 00476 // Fill in HCI packet structure 00477 args = UINT32_TO_STREAM(args, 8); 00478 args = UINT32_TO_STREAM(args, usNameLen); 00479 ARRAY_TO_STREAM(args, hostname, usNameLen); 00480 00481 // Initiate a HCI command 00482 hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + usNameLen - 1); 00483 00484 // Since we are in blocking state - wait for event complete 00485 SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, (long*)&ret); 00486 00487 errno = ret.retVal; 00488 00489 (*((long*)out_ip_addr)) = ret.outputAddress; 00490 00491 return (errno); 00492 00493 } 00494 #endif 00495 00496 //***************************************************************************** 00497 // 00498 //! connect 00499 //! 00500 //! @param[in] sd socket descriptor (handle) 00501 //! @param[in] addr specifies the destination addr. On this version 00502 //! only AF_INET is supported. 00503 //! @param[out] addrlen contains the size of the structure pointed to by addr 00504 //! @return On success, zero is returned. On error, -1 is returned 00505 //! 00506 //! @brief initiate a connection on a socket 00507 //! Function connects the socket referred to by the socket descriptor 00508 //! sd, to the address specified by addr. The addrlen argument 00509 //! specifies the size of addr. The format of the address in addr is 00510 //! determined by the address space of the socket. If it is of type 00511 //! SOCK_DGRAM, this call specifies the peer with which the socket is 00512 //! to be associated; this address is that to which datagrams are to be 00513 //! sent, and the only address from which datagrams are to be received. 00514 //! If the socket is of type SOCK_STREAM, this call attempts to make a 00515 //! connection to another socket. The other socket is specified by 00516 //! address, which is an address in the communications space of the 00517 //! socket. Note that the function implements only blocking behavior 00518 //! thus the caller will be waiting either for the connection 00519 //! establishment or for the connection establishment failure. 00520 //! 00521 //! @sa socket 00522 // 00523 //***************************************************************************** 00524 00525 long 00526 connect(long sd, const sockaddr *addr, long addrlen) 00527 { 00528 long int ret; 00529 unsigned char *ptr, *args; 00530 00531 ret = EFAIL; 00532 ptr = tSLInformation.pucTxCommandBuffer; 00533 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00534 addrlen = 8; 00535 00536 // Fill in temporary command buffer 00537 args = UINT32_TO_STREAM(args, sd); 00538 args = UINT32_TO_STREAM(args, 0x00000008); 00539 args = UINT32_TO_STREAM(args, addrlen); 00540 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); 00541 00542 // Initiate a HCI command 00543 hci_command_send(HCI_CMND_CONNECT, 00544 ptr, SOCKET_CONNECT_PARAMS_LEN); 00545 00546 // Since we are in blocking state - wait for event complete 00547 SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); 00548 00549 errno = ret; 00550 00551 return((long)ret); 00552 } 00553 00554 00555 //***************************************************************************** 00556 // 00557 //! select 00558 //! 00559 //! @param[in] nfds the highest-numbered file descriptor in any of the 00560 //! three sets, plus 1. 00561 //! @param[out] writesds socket descriptors list for write monitoring 00562 //! @param[out] readsds socket descriptors list for read monitoring 00563 //! @param[out] exceptsds socket descriptors list for exception monitoring 00564 //! @param[in] timeout is an upper bound on the amount of time elapsed 00565 //! before select() returns. Null means infinity 00566 //! timeout. The minimum timeout is 5 milliseconds, 00567 //! less than 5 milliseconds will be set 00568 //! automatically to 5 milliseconds. 00569 //! @return On success, select() returns the number of file descriptors 00570 //! contained in the three returned descriptor sets (that is, the 00571 //! total number of bits that are set in readfds, writefds, 00572 //! exceptfds) which may be zero if the timeout expires before 00573 //! anything interesting happens. 00574 //! On error, -1 is returned. 00575 //! *readsds - return the sockets on which Read request will 00576 //! return without delay with valid data. 00577 //! *writesds - return the sockets on which Write request 00578 //! will return without delay. 00579 //! *exceptsds - return the sockets which closed recently. 00580 //! 00581 //! @brief Monitor socket activity 00582 //! Select allow a program to monitor multiple file descriptors, 00583 //! waiting until one or more of the file descriptors become 00584 //! "ready" for some class of I/O operation 00585 //! 00586 //! @Note If the timeout value set to less than 5ms it will automatically set 00587 //! to 5ms to prevent overload of the system 00588 //! 00589 //! @sa socket 00590 // 00591 //***************************************************************************** 00592 00593 int 00594 select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, 00595 struct timeval *timeout) 00596 { 00597 unsigned char *ptr, *args; 00598 tBsdSelectRecvParams tParams; 00599 unsigned long is_blocking; 00600 00601 if( timeout == NULL) 00602 { 00603 is_blocking = 1; /* blocking , infinity timeout */ 00604 } 00605 else 00606 { 00607 is_blocking = 0; /* no blocking, timeout */ 00608 } 00609 00610 // Fill in HCI packet structure 00611 ptr = tSLInformation.pucTxCommandBuffer; 00612 args = (ptr + HEADERS_SIZE_CMD); 00613 00614 // Fill in temporary command buffer 00615 args = UINT32_TO_STREAM(args, nfds); 00616 args = UINT32_TO_STREAM(args, 0x00000014); 00617 args = UINT32_TO_STREAM(args, 0x00000014); 00618 args = UINT32_TO_STREAM(args, 0x00000014); 00619 args = UINT32_TO_STREAM(args, 0x00000014); 00620 args = UINT32_TO_STREAM(args, is_blocking); 00621 args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); 00622 args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); 00623 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); 00624 00625 if (timeout) 00626 { 00627 if ( 0 == timeout->tv_sec && timeout->tv_usec < 00628 SELECT_TIMEOUT_MIN_MICRO_SECONDS) 00629 { 00630 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; 00631 } 00632 args = UINT32_TO_STREAM(args, timeout->tv_sec); 00633 args = UINT32_TO_STREAM(args, timeout->tv_usec); 00634 } 00635 00636 // Initiate a HCI command 00637 hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); 00638 00639 // Since we are in blocking state - wait for event complete 00640 SimpleLinkWaitEvent(HCI_EVNT_SELECT, (long*)&tParams); 00641 00642 // Update actually read FD 00643 if (tParams.iStatus >= 0) 00644 { 00645 if (readsds) 00646 { 00647 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); 00648 } 00649 00650 if (writesds) 00651 { 00652 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 00653 } 00654 00655 if (exceptsds) 00656 { 00657 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 00658 } 00659 00660 return(tParams.iStatus); 00661 00662 } 00663 else 00664 { 00665 errno = tParams.iStatus; 00666 return(-1); 00667 } 00668 } 00669 00670 //***************************************************************************** 00671 // 00672 //! setsockopt 00673 //! 00674 //! @param[in] sd socket handle 00675 //! @param[in] level defines the protocol level for this option 00676 //! @param[in] optname defines the option name to Interrogate 00677 //! @param[in] optval specifies a value for the option 00678 //! @param[in] optlen specifies the length of the option value 00679 //! @return On success, zero is returned. On error, -1 is returned 00680 //! 00681 //! @brief set socket options 00682 //! This function manipulate the options associated with a socket. 00683 //! Options may exist at multiple protocol levels; they are always 00684 //! present at the uppermost socket level. 00685 //! When manipulating socket options the level at which the option 00686 //! resides and the name of the option must be specified. 00687 //! To manipulate options at the socket level, level is specified as 00688 //! SOL_SOCKET. To manipulate options at any other level the protocol 00689 //! number of the appropriate protocol controlling the option is 00690 //! supplied. For example, to indicate that an option is to be 00691 //! interpreted by the TCP protocol, level should be set to the 00692 //! protocol number of TCP; 00693 //! The parameters optval and optlen are used to access optval - 00694 //! use for setsockopt(). For getsockopt() they identify a buffer 00695 //! in which the value for the requested option(s) are to 00696 //! be returned. For getsockopt(), optlen is a value-result 00697 //! parameter, initially containing the size of the buffer 00698 //! pointed to by option_value, and modified on return to 00699 //! indicate the actual size of the value returned. If no option 00700 //! value is to be supplied or returned, option_value may be NULL. 00701 //! 00702 //! @Note On this version the following two socket options are enabled: 00703 //! The only protocol level supported in this version 00704 //! is SOL_SOCKET (level). 00705 //! 1. SOCKOPT_RECV_TIMEOUT (optname) 00706 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 00707 //! in milliseconds. 00708 //! In that case optval should be pointer to unsigned long. 00709 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 00710 //! or off. 00711 //! In that case optval should be SOCK_ON or SOCK_OFF (optval). 00712 //! 00713 //! @sa getsockopt 00714 // 00715 //***************************************************************************** 00716 00717 #ifndef CC3000_TINY_DRIVER 00718 int 00719 setsockopt(long sd, long level, long optname, const void *optval, 00720 socklen_t optlen) 00721 { 00722 int ret; 00723 unsigned char *ptr, *args; 00724 00725 ptr = tSLInformation.pucTxCommandBuffer; 00726 args = (ptr + HEADERS_SIZE_CMD); 00727 00728 // Fill in temporary command buffer 00729 args = UINT32_TO_STREAM(args, sd); 00730 args = UINT32_TO_STREAM(args, level); 00731 args = UINT32_TO_STREAM(args, optname); 00732 args = UINT32_TO_STREAM(args, 0x00000008); 00733 args = UINT32_TO_STREAM(args, optlen); 00734 ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen); 00735 00736 // Initiate a HCI command 00737 hci_command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); 00738 00739 // Since we are in blocking state - wait for event complete 00740 SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, (long*)&ret); 00741 00742 if (ret >= 0) 00743 { 00744 return (0); 00745 } 00746 else 00747 { 00748 errno = ret; 00749 return (errno); 00750 } 00751 } 00752 #endif 00753 00754 //***************************************************************************** 00755 // 00756 //! getsockopt 00757 //! 00758 //! @param[in] sd socket handle 00759 //! @param[in] level defines the protocol level for this option 00760 //! @param[in] optname defines the option name to Interrogate 00761 //! @param[out] optval specifies a value for the option 00762 //! @param[out] optlen specifies the length of the option value 00763 //! @return On success, zero is returned. On error, -1 is returned 00764 //! 00765 //! @brief set socket options 00766 //! This function manipulate the options associated with a socket. 00767 //! Options may exist at multiple protocol levels; they are always 00768 //! present at the uppermost socket level. 00769 //! When manipulating socket options the level at which the option 00770 //! resides and the name of the option must be specified. 00771 //! To manipulate options at the socket level, level is specified as 00772 //! SOL_SOCKET. To manipulate options at any other level the protocol 00773 //! number of the appropriate protocol controlling the option is 00774 //! supplied. For example, to indicate that an option is to be 00775 //! interpreted by the TCP protocol, level should be set to the 00776 //! protocol number of TCP; 00777 //! The parameters optval and optlen are used to access optval - 00778 //! use for setsockopt(). For getsockopt() they identify a buffer 00779 //! in which the value for the requested option(s) are to 00780 //! be returned. For getsockopt(), optlen is a value-result 00781 //! parameter, initially containing the size of the buffer 00782 //! pointed to by option_value, and modified on return to 00783 //! indicate the actual size of the value returned. If no option 00784 //! value is to be supplied or returned, option_value may be NULL. 00785 //! 00786 //! @Note On this version the following two socket options are enabled: 00787 //! The only protocol level supported in this version 00788 //! is SOL_SOCKET (level). 00789 //! 1. SOCKOPT_RECV_TIMEOUT (optname) 00790 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 00791 //! in milliseconds. 00792 //! In that case optval should be pointer to unsigned long. 00793 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 00794 //! or off. 00795 //! In that case optval should be SOCK_ON or SOCK_OFF (optval). 00796 //! 00797 //! @sa setsockopt 00798 // 00799 //***************************************************************************** 00800 00801 int 00802 getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) 00803 { 00804 unsigned char *ptr, *args; 00805 tBsdGetSockOptReturnParams tRetParams; 00806 00807 ptr = tSLInformation.pucTxCommandBuffer; 00808 args = (ptr + HEADERS_SIZE_CMD); 00809 00810 // Fill in temporary command buffer 00811 args = UINT32_TO_STREAM(args, sd); 00812 args = UINT32_TO_STREAM(args, level); 00813 args = UINT32_TO_STREAM(args, optname); 00814 00815 // Initiate a HCI command 00816 hci_command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); 00817 00818 // Since we are in blocking state - wait for event complete 00819 SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, (long*)&tRetParams); 00820 00821 if (((signed char)tRetParams.iStatus) >= 0) 00822 { 00823 *optlen = 4; 00824 memcpy(optval, tRetParams.ucOptValue, 4); 00825 return (0); 00826 } 00827 else 00828 { 00829 errno = tRetParams.iStatus; 00830 return (errno); 00831 } 00832 } 00833 00834 //***************************************************************************** 00835 // 00836 //! simple_link_recv 00837 //! 00838 //! @param sd socket handle 00839 //! @param buf read buffer 00840 //! @param len buffer length 00841 //! @param flags indicates blocking or non-blocking operation 00842 //! @param from pointer to an address structure indicating source address 00843 //! @param fromlen source address structure size 00844 //! 00845 //! @return Return the number of bytes received, or -1 if an error 00846 //! occurred 00847 //! 00848 //! @brief Read data from socket 00849 //! Return the length of the message on successful completion. 00850 //! If a message is too long to fit in the supplied buffer, 00851 //! excess bytes may be discarded depending on the type of 00852 //! socket the message is received from 00853 // 00854 //***************************************************************************** 00855 int 00856 simple_link_recv(long sd, unsigned char *buf, long len, long flags, sockaddr *from, socklen_t *fromlen, long opcode) 00857 { 00858 unsigned char *ptr, *args; 00859 tBsdReadReturnParams tSocketReadEvent; 00860 00861 ptr = tSLInformation.pucTxCommandBuffer; 00862 args = (ptr + HEADERS_SIZE_CMD); 00863 00864 // Fill in HCI packet structure 00865 args = UINT32_TO_STREAM(args, sd); 00866 args = UINT32_TO_STREAM(args, len); 00867 args = UINT32_TO_STREAM(args, flags); 00868 00869 // Generate the read command, and wait for the 00870 hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); 00871 00872 // Since we are in blocking state - wait for event complete 00873 SimpleLinkWaitEvent(opcode, (long*)&tSocketReadEvent); 00874 00875 // In case the number of bytes is more then zero - read data 00876 if (tSocketReadEvent.iNumberOfBytes > 0) 00877 { 00878 // Wait for the data in a synchronous way. Here we assume that the bug is 00879 // big enough to store also parameters of receive from too.... 00880 SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen); 00881 } 00882 00883 errno = tSocketReadEvent.iNumberOfBytes; 00884 00885 return(tSocketReadEvent.iNumberOfBytes); 00886 } 00887 00888 //***************************************************************************** 00889 // 00890 //! recv 00891 //! 00892 //! @param[in] sd socket handle 00893 //! @param[out] buf Points to the buffer where the message should be stored 00894 //! @param[in] len Specifies the length in bytes of the buffer pointed to 00895 //! by the buffer argument. 00896 //! @param[in] flags Specifies the type of message reception. 00897 //! On this version, this parameter is not supported. 00898 //! 00899 //! @return Return the number of bytes received, or -1 if an error 00900 //! occurred 00901 //! 00902 //! @brief function receives a message from a connection-mode socket 00903 //! 00904 //! @sa recvfrom 00905 //! 00906 //! @Note On this version, only blocking mode is supported. 00907 // 00908 //***************************************************************************** 00909 00910 int 00911 recv(long sd, unsigned char *buf, long len, long flags) 00912 { 00913 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); 00914 } 00915 00916 //***************************************************************************** 00917 // 00918 //! recvfrom 00919 //! 00920 //! @param[in] sd socket handle 00921 //! @param[out] buf Points to the buffer where the message should be stored 00922 //! @param[in] len Specifies the length in bytes of the buffer pointed to 00923 //! by the buffer argument. 00924 //! @param[in] flags Specifies the type of message reception. 00925 //! On this version, this parameter is not supported. 00926 //! @param[in] from pointer to an address structure indicating the source 00927 //! address: sockaddr. On this version only AF_INET is 00928 //! supported. 00929 //! @param[in] fromlen source address tructure size 00930 //! 00931 //! @return Return the number of bytes received, or -1 if an error 00932 //! occurred 00933 //! 00934 //! @brief read data from socket 00935 //! function receives a message from a connection-mode or 00936 //! connectionless-mode socket. Note that raw sockets are not 00937 //! supported. 00938 //! 00939 //! @sa recv 00940 //! 00941 //! @Note On this version, only blocking mode is supported. 00942 // 00943 //***************************************************************************** 00944 int 00945 recvfrom(long sd, unsigned char *buf, long len, long flags, sockaddr *from, socklen_t *fromlen) 00946 { 00947 return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM)); 00948 } 00949 00950 //***************************************************************************** 00951 // 00952 //! simple_link_send 00953 //! 00954 //! @param sd socket handle 00955 //! @param buf write buffer 00956 //! @param len buffer length 00957 //! @param flags On this version, this parameter is not supported 00958 //! @param to pointer to an address structure indicating destination 00959 //! address 00960 //! @param tolen destination address structure size 00961 //! 00962 //! @return Return the number of bytes transmitted, or -1 if an error 00963 //! occurred, or -2 in case there are no free buffers available 00964 //! (only when SEND_NON_BLOCKING is enabled) 00965 //! 00966 //! @brief This function is used to transmit a message to another 00967 //! socket 00968 // 00969 //***************************************************************************** 00970 int 00971 simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode) 00972 { 00973 unsigned char uArgSize, addrlen; 00974 unsigned char *ptr, *pDataPtr, *args; 00975 unsigned long addr_offset; 00976 int res; 00977 tBsdReadReturnParams tSocketSendEvent; 00978 00979 // Check the bsd_arguments 00980 if (0 != (res = HostFlowControlConsumeBuff(sd))) 00981 { 00982 return res; 00983 } 00984 00985 //Update the number of sent packets 00986 tSLInformation.NumberOfSentPackets++; 00987 00988 // Allocate a buffer and construct a packet and send it over spi 00989 ptr = tSLInformation.pucTxCommandBuffer; 00990 args = (ptr + HEADERS_SIZE_DATA); 00991 00992 // Update the offset of data and parameters according to the command 00993 switch(opcode) 00994 { 00995 case HCI_CMND_SENDTO: 00996 { 00997 addr_offset = len + sizeof(len) + sizeof(len); 00998 addrlen = 8; 00999 uArgSize = SOCKET_SENDTO_PARAMS_LEN; 01000 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; 01001 break; 01002 } 01003 01004 case HCI_CMND_SEND: 01005 { 01006 tolen = 0; 01007 to = NULL; 01008 uArgSize = HCI_CMND_SEND_ARG_LENGTH; 01009 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; 01010 break; 01011 } 01012 01013 default: 01014 { 01015 break; 01016 } 01017 } 01018 01019 // Fill in temporary command buffer 01020 args = UINT32_TO_STREAM(args, sd); 01021 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); 01022 args = UINT32_TO_STREAM(args, len); 01023 args = UINT32_TO_STREAM(args, flags); 01024 01025 if (opcode == HCI_CMND_SENDTO) 01026 { 01027 args = UINT32_TO_STREAM(args, addr_offset); 01028 args = UINT32_TO_STREAM(args, addrlen); 01029 } 01030 01031 // Copy the data received from user into the TX Buffer 01032 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len); 01033 01034 // In case we are using SendTo, copy the to parameters 01035 if (opcode == HCI_CMND_SENDTO) 01036 { 01037 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen); 01038 } 01039 01040 // Initiate a HCI command 01041 hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen); 01042 01043 if (opcode == HCI_CMND_SENDTO) 01044 SimpleLinkWaitEvent(HCI_EVNT_SENDTO, (long*)&tSocketSendEvent); 01045 else 01046 SimpleLinkWaitEvent(HCI_EVNT_SEND, (long*)&tSocketSendEvent); 01047 01048 return (len); 01049 } 01050 01051 01052 //***************************************************************************** 01053 // 01054 //! send 01055 //! 01056 //! @param sd socket handle 01057 //! @param buf Points to a buffer containing the message to be sent 01058 //! @param len message size in bytes 01059 //! @param flags On this version, this parameter is not supported 01060 //! 01061 //! @return Return the number of bytes transmitted, or -1 if an 01062 //! error occurred 01063 //! 01064 //! @brief Write data to TCP socket 01065 //! This function is used to transmit a message to another 01066 //! socket. 01067 //! 01068 //! @Note On this version, only blocking mode is supported. 01069 //! 01070 //! @sa sendto 01071 // 01072 //***************************************************************************** 01073 01074 int 01075 send(long sd, const void *buf, long len, long flags) 01076 { 01077 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); 01078 } 01079 01080 //***************************************************************************** 01081 // 01082 //! sendto 01083 //! 01084 //! @param sd socket handle 01085 //! @param buf Points to a buffer containing the message to be sent 01086 //! @param len message size in bytes 01087 //! @param flags On this version, this parameter is not supported 01088 //! @param to pointer to an address structure indicating the destination 01089 //! address: sockaddr. On this version only AF_INET is 01090 //! supported. 01091 //! @param tolen destination address structure size 01092 //! 01093 //! @return Return the number of bytes transmitted, or -1 if an 01094 //! error occurred 01095 //! 01096 //! @brief Write data to TCP socket 01097 //! This function is used to transmit a message to another 01098 //! socket. 01099 //! 01100 //! @Note On this version, only blocking mode is supported. 01101 //! 01102 //! @sa send 01103 // 01104 //***************************************************************************** 01105 01106 int 01107 sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, socklen_t tolen) 01108 { 01109 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); 01110 } 01111 01112 //***************************************************************************** 01113 // 01114 //! mdnsAdvertiser 01115 //! 01116 //! @param[in] mdnsEnabled flag to enable/disable the mDNS feature 01117 //! @param[in] deviceServiceName Service name as part of the published 01118 //! canonical domain name 01119 //! @param[in] deviceServiceNameLength Length of the service name 01120 //! 01121 //! 01122 //! @return On success, zero is returned, return SOC_ERROR if socket was not 01123 //! opened successfully, or if an error occurred. 01124 //! 01125 //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. 01126 // 01127 //***************************************************************************** 01128 01129 int 01130 mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength) 01131 { 01132 int ret; 01133 unsigned char *pTxBuffer, *pArgs; 01134 01135 if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) 01136 { 01137 return EFAIL; 01138 } 01139 01140 pTxBuffer = tSLInformation.pucTxCommandBuffer; 01141 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 01142 01143 // Fill in HCI packet structure 01144 pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); 01145 pArgs = UINT32_TO_STREAM(pArgs, 8); 01146 pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); 01147 ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); 01148 01149 // Initiate a HCI command 01150 hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); 01151 01152 // Since we are in blocking state - wait for event complete 01153 SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, (long*)&ret); 01154 01155 return ret; 01156 01157 } 01158
Generated on Tue Jul 12 2022 19:26:44 by 1.7.2