Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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, 00317 ptr, SOCKET_ACCEPT_PARAMS_LEN); 00318 00319 // Since we are in blocking state - wait for event complete 00320 SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); 00321 00322 00323 // need specify return parameters!!! 00324 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); 00325 *addrlen = ASIC_ADDR_LEN; 00326 errno = tAcceptReturnArguments.iStatus; 00327 ret = errno; 00328 00329 // if succeeded, iStatus = new socket descriptor. otherwise - error number 00330 if(M_IS_VALID_SD(ret)) 00331 { 00332 set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); 00333 } 00334 else 00335 { 00336 set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); 00337 } 00338 00339 return(ret); 00340 } 00341 00342 //***************************************************************************** 00343 // 00344 //! bind 00345 //! 00346 //! @param[in] sd socket descriptor (handle) 00347 //! @param[out] addr specifies the destination address. On this version 00348 //! only AF_INET is supported. 00349 //! @param[out] addrlen contains the size of the structure pointed to by addr. 00350 //! 00351 //! @return On success, zero is returned. On error, -1 is returned. 00352 //! 00353 //! @brief assign a name to a socket 00354 //! This function gives the socket the local address addr. 00355 //! addr is addrlen bytes long. Traditionally, this is called when a 00356 //! socket is created with socket, it exists in a name space (address 00357 //! family) but has no name assigned. 00358 //! It is necessary to assign a local address before a SOCK_STREAM 00359 //! socket may receive connections. 00360 //! 00361 //! @sa socket ; accept ; listen 00362 // 00363 //***************************************************************************** 00364 00365 long 00366 bind(long sd, const sockaddr *addr, long addrlen) 00367 { 00368 long ret; 00369 unsigned char *ptr, *args; 00370 00371 ret = EFAIL; 00372 ptr = tSLInformation.pucTxCommandBuffer; 00373 args = (ptr + HEADERS_SIZE_CMD); 00374 00375 addrlen = ASIC_ADDR_LEN; 00376 00377 // Fill in temporary command buffer 00378 args = UINT32_TO_STREAM(args, sd); 00379 args = UINT32_TO_STREAM(args, 0x00000008); 00380 args = UINT32_TO_STREAM(args, addrlen); 00381 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); 00382 00383 // Initiate a HCI command 00384 hci_command_send(HCI_CMND_BIND, 00385 ptr, SOCKET_BIND_PARAMS_LEN); 00386 00387 // Since we are in blocking state - wait for event complete 00388 SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); 00389 00390 errno = ret; 00391 00392 return(ret); 00393 } 00394 00395 //***************************************************************************** 00396 // 00397 //! listen 00398 //! 00399 //! @param[in] sd socket descriptor (handle) 00400 //! @param[in] backlog specifies the listen queue depth. On this version 00401 //! backlog is not supported. 00402 //! @return On success, zero is returned. On error, -1 is returned. 00403 //! 00404 //! @brief listen for connections on a socket 00405 //! The willingness to accept incoming connections and a queue 00406 //! limit for incoming connections are specified with listen(), 00407 //! and then the connections are accepted with accept. 00408 //! The listen() call applies only to sockets of type SOCK_STREAM 00409 //! The backlog parameter defines the maximum length the queue of 00410 //! pending connections may grow to. 00411 //! 00412 //! @sa socket ; accept ; bind 00413 //! 00414 //! @note On this version, backlog is not supported 00415 // 00416 //***************************************************************************** 00417 00418 long 00419 listen(long sd, long backlog) 00420 { 00421 long ret; 00422 unsigned char *ptr, *args; 00423 00424 ret = EFAIL; 00425 ptr = tSLInformation.pucTxCommandBuffer; 00426 args = (ptr + HEADERS_SIZE_CMD); 00427 00428 // Fill in temporary command buffer 00429 args = UINT32_TO_STREAM(args, sd); 00430 args = UINT32_TO_STREAM(args, backlog); 00431 00432 // Initiate a HCI command 00433 hci_command_send(HCI_CMND_LISTEN, 00434 ptr, SOCKET_LISTEN_PARAMS_LEN); 00435 00436 // Since we are in blocking state - wait for event complete 00437 SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); 00438 errno = ret; 00439 00440 return(ret); 00441 } 00442 00443 //***************************************************************************** 00444 // 00445 //! gethostbyname 00446 //! 00447 //! @param[in] hostname host name 00448 //! @param[in] usNameLen name length 00449 //! @param[out] out_ip_addr This parameter is filled in with host IP address. 00450 //! In case that host name is not resolved, 00451 //! out_ip_addr is zero. 00452 //! @return On success, positive is returned. On error, negative is returned 00453 //! 00454 //! @brief Get host IP by name. Obtain the IP Address of machine on network, 00455 //! by its name. 00456 //! 00457 //! @note On this version, only blocking mode is supported. Also note that 00458 //! the function requires DNS server to be configured prior to its usage. 00459 // 00460 //***************************************************************************** 00461 00462 #ifndef CC3000_TINY_DRIVER 00463 int 00464 gethostbyname(char * hostname, unsigned short usNameLen, 00465 unsigned long* out_ip_addr) 00466 { 00467 tBsdGethostbynameParams ret; 00468 unsigned char *ptr, *args; 00469 00470 errno = EFAIL; 00471 00472 if (usNameLen > HOSTNAME_MAX_LENGTH) 00473 { 00474 return errno; 00475 } 00476 00477 ptr = tSLInformation.pucTxCommandBuffer; 00478 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00479 00480 // Fill in HCI packet structure 00481 args = UINT32_TO_STREAM(args, 8); 00482 args = UINT32_TO_STREAM(args, usNameLen); 00483 ARRAY_TO_STREAM(args, hostname, usNameLen); 00484 00485 // Initiate a HCI command 00486 hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN 00487 + usNameLen - 1); 00488 00489 // Since we are in blocking state - wait for event complete 00490 SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); 00491 00492 errno = ret.retVal; 00493 00494 (*((long*)out_ip_addr)) = ret.outputAddress; 00495 00496 return (errno); 00497 00498 } 00499 #endif 00500 00501 //***************************************************************************** 00502 // 00503 //! connect 00504 //! 00505 //! @param[in] sd socket descriptor (handle) 00506 //! @param[in] addr specifies the destination addr. On this version 00507 //! only AF_INET is supported. 00508 //! @param[out] addrlen contains the size of the structure pointed to by addr 00509 //! @return On success, zero is returned. On error, -1 is returned 00510 //! 00511 //! @brief initiate a connection on a socket 00512 //! Function connects the socket referred to by the socket descriptor 00513 //! sd, to the address specified by addr. The addrlen argument 00514 //! specifies the size of addr. The format of the address in addr is 00515 //! determined by the address space of the socket. If it is of type 00516 //! SOCK_DGRAM, this call specifies the peer with which the socket is 00517 //! to be associated; this address is that to which datagrams are to be 00518 //! sent, and the only address from which datagrams are to be received. 00519 //! If the socket is of type SOCK_STREAM, this call attempts to make a 00520 //! connection to another socket. The other socket is specified by 00521 //! address, which is an address in the communications space of the 00522 //! socket. Note that the function implements only blocking behavior 00523 //! thus the caller will be waiting either for the connection 00524 //! establishment or for the connection establishment failure. 00525 //! 00526 //! @sa socket 00527 // 00528 //***************************************************************************** 00529 00530 long 00531 connect(long sd, const sockaddr *addr, long addrlen) 00532 { 00533 long int ret; 00534 unsigned char *ptr, *args; 00535 00536 ret = EFAIL; 00537 ptr = tSLInformation.pucTxCommandBuffer; 00538 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00539 addrlen = 8; 00540 00541 // Fill in temporary command buffer 00542 args = UINT32_TO_STREAM(args, sd); 00543 args = UINT32_TO_STREAM(args, 0x00000008); 00544 args = UINT32_TO_STREAM(args, addrlen); 00545 ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); 00546 00547 // Initiate a HCI command 00548 hci_command_send(HCI_CMND_CONNECT, 00549 ptr, SOCKET_CONNECT_PARAMS_LEN); 00550 00551 // Since we are in blocking state - wait for event complete 00552 SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); 00553 00554 errno = ret; 00555 00556 return((long)ret); 00557 } 00558 00559 00560 //***************************************************************************** 00561 // 00562 //! select 00563 //! 00564 //! @param[in] nfds the highest-numbered file descriptor in any of the 00565 //! three sets, plus 1. 00566 //! @param[out] writesds socket descriptors list for write monitoring 00567 //! @param[out] readsds socket descriptors list for read monitoring 00568 //! @param[out] exceptsds socket descriptors list for exception monitoring 00569 //! @param[in] timeout is an upper bound on the amount of time elapsed 00570 //! before select() returns. Null means infinity 00571 //! timeout. The minimum timeout is 5 milliseconds, 00572 //! less than 5 milliseconds will be set 00573 //! automatically to 5 milliseconds. 00574 //! @return On success, select() returns the number of file descriptors 00575 //! contained in the three returned descriptor sets (that is, the 00576 //! total number of bits that are set in readfds, writefds, 00577 //! exceptfds) which may be zero if the timeout expires before 00578 //! anything interesting happens. 00579 //! On error, -1 is returned. 00580 //! *readsds - return the sockets on which Read request will 00581 //! return without delay with valid data. 00582 //! *writesds - return the sockets on which Write request 00583 //! will return without delay. 00584 //! *exceptsds - return the sockets which closed recently. 00585 //! 00586 //! @brief Monitor socket activity 00587 //! Select allow a program to monitor multiple file descriptors, 00588 //! waiting until one or more of the file descriptors become 00589 //! "ready" for some class of I/O operation 00590 //! 00591 //! @Note If the timeout value set to less than 5ms it will automatically set 00592 //! to 5ms to prevent overload of the system 00593 //! 00594 //! @sa socket 00595 // 00596 //***************************************************************************** 00597 00598 int 00599 select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, 00600 struct timeval *timeout) 00601 { 00602 unsigned char *ptr, *args; 00603 tBsdSelectRecvParams tParams; 00604 unsigned long is_blocking; 00605 00606 if( timeout == NULL) 00607 { 00608 is_blocking = 1; /* blocking , infinity timeout */ 00609 } 00610 else 00611 { 00612 is_blocking = 0; /* no blocking, timeout */ 00613 } 00614 00615 // Fill in HCI packet structure 00616 ptr = tSLInformation.pucTxCommandBuffer; 00617 args = (ptr + HEADERS_SIZE_CMD); 00618 00619 // Fill in temporary command buffer 00620 args = UINT32_TO_STREAM(args, nfds); 00621 args = UINT32_TO_STREAM(args, 0x00000014); 00622 args = UINT32_TO_STREAM(args, 0x00000014); 00623 args = UINT32_TO_STREAM(args, 0x00000014); 00624 args = UINT32_TO_STREAM(args, 0x00000014); 00625 args = UINT32_TO_STREAM(args, is_blocking); 00626 args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); 00627 args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); 00628 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); 00629 00630 if (timeout) 00631 { 00632 if ( 0 == timeout->tv_sec && timeout->tv_usec < 00633 SELECT_TIMEOUT_MIN_MICRO_SECONDS) 00634 { 00635 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; 00636 } 00637 args = UINT32_TO_STREAM(args, timeout->tv_sec); 00638 args = UINT32_TO_STREAM(args, timeout->tv_usec); 00639 } 00640 00641 // Initiate a HCI command 00642 hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); 00643 00644 // Since we are in blocking state - wait for event complete 00645 SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); 00646 00647 // Update actually read FD 00648 if (tParams.iStatus >= 0) 00649 { 00650 if (readsds) 00651 { 00652 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); 00653 } 00654 00655 if (writesds) 00656 { 00657 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 00658 } 00659 00660 if (exceptsds) 00661 { 00662 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 00663 } 00664 00665 return(tParams.iStatus); 00666 00667 } 00668 else 00669 { 00670 errno = tParams.iStatus; 00671 return(-1); 00672 } 00673 } 00674 00675 //***************************************************************************** 00676 // 00677 //! setsockopt 00678 //! 00679 //! @param[in] sd socket handle 00680 //! @param[in] level defines the protocol level for this option 00681 //! @param[in] optname defines the option name to Interrogate 00682 //! @param[in] optval specifies a value for the option 00683 //! @param[in] optlen specifies the length of the option value 00684 //! @return On success, zero is returned. On error, -1 is returned 00685 //! 00686 //! @brief set socket options 00687 //! This function manipulate the options associated with a socket. 00688 //! Options may exist at multiple protocol levels; they are always 00689 //! present at the uppermost socket level. 00690 //! When manipulating socket options the level at which the option 00691 //! resides and the name of the option must be specified. 00692 //! To manipulate options at the socket level, level is specified as 00693 //! SOL_SOCKET. To manipulate options at any other level the protocol 00694 //! number of the appropriate protocol controlling the option is 00695 //! supplied. For example, to indicate that an option is to be 00696 //! interpreted by the TCP protocol, level should be set to the 00697 //! protocol number of TCP; 00698 //! The parameters optval and optlen are used to access optval - 00699 //! use for setsockopt(). For getsockopt() they identify a buffer 00700 //! in which the value for the requested option(s) are to 00701 //! be returned. For getsockopt(), optlen is a value-result 00702 //! parameter, initially containing the size of the buffer 00703 //! pointed to by option_value, and modified on return to 00704 //! indicate the actual size of the value returned. If no option 00705 //! value is to be supplied or returned, option_value may be NULL. 00706 //! 00707 //! @Note On this version the following two socket options are enabled: 00708 //! The only protocol level supported in this version 00709 //! is SOL_SOCKET (level). 00710 //! 1. SOCKOPT_RECV_TIMEOUT (optname) 00711 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 00712 //! in milliseconds. 00713 //! In that case optval should be pointer to unsigned long. 00714 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 00715 //! or off. 00716 //! In that case optval should be SOCK_ON or SOCK_OFF (optval). 00717 //! 00718 //! @sa getsockopt 00719 // 00720 //***************************************************************************** 00721 00722 #ifndef CC3000_TINY_DRIVER 00723 int 00724 setsockopt(long sd, long level, long optname, const void *optval, 00725 socklen_t optlen) 00726 { 00727 int ret; 00728 unsigned char *ptr, *args; 00729 00730 ptr = tSLInformation.pucTxCommandBuffer; 00731 args = (ptr + HEADERS_SIZE_CMD); 00732 00733 // Fill in temporary command buffer 00734 args = UINT32_TO_STREAM(args, sd); 00735 args = UINT32_TO_STREAM(args, level); 00736 args = UINT32_TO_STREAM(args, optname); 00737 args = UINT32_TO_STREAM(args, 0x00000008); 00738 args = UINT32_TO_STREAM(args, optlen); 00739 ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen); 00740 00741 // Initiate a HCI command 00742 hci_command_send(HCI_CMND_SETSOCKOPT, 00743 ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); 00744 00745 // Since we are in blocking state - wait for event complete 00746 SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); 00747 00748 if (ret >= 0) 00749 { 00750 return (0); 00751 } 00752 else 00753 { 00754 errno = ret; 00755 return (errno); 00756 } 00757 } 00758 #endif 00759 00760 //***************************************************************************** 00761 // 00762 //! getsockopt 00763 //! 00764 //! @param[in] sd socket handle 00765 //! @param[in] level defines the protocol level for this option 00766 //! @param[in] optname defines the option name to Interrogate 00767 //! @param[out] optval specifies a value for the option 00768 //! @param[out] optlen specifies the length of the option value 00769 //! @return On success, zero is returned. On error, -1 is returned 00770 //! 00771 //! @brief set socket options 00772 //! This function manipulate the options associated with a socket. 00773 //! Options may exist at multiple protocol levels; they are always 00774 //! present at the uppermost socket level. 00775 //! When manipulating socket options the level at which the option 00776 //! resides and the name of the option must be specified. 00777 //! To manipulate options at the socket level, level is specified as 00778 //! SOL_SOCKET. To manipulate options at any other level the protocol 00779 //! number of the appropriate protocol controlling the option is 00780 //! supplied. For example, to indicate that an option is to be 00781 //! interpreted by the TCP protocol, level should be set to the 00782 //! protocol number of TCP; 00783 //! The parameters optval and optlen are used to access optval - 00784 //! use for setsockopt(). For getsockopt() they identify a buffer 00785 //! in which the value for the requested option(s) are to 00786 //! be returned. For getsockopt(), optlen is a value-result 00787 //! parameter, initially containing the size of the buffer 00788 //! pointed to by option_value, and modified on return to 00789 //! indicate the actual size of the value returned. If no option 00790 //! value is to be supplied or returned, option_value may be NULL. 00791 //! 00792 //! @Note On this version the following two socket options are enabled: 00793 //! The only protocol level supported in this version 00794 //! is SOL_SOCKET (level). 00795 //! 1. SOCKOPT_RECV_TIMEOUT (optname) 00796 //! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 00797 //! in milliseconds. 00798 //! In that case optval should be pointer to unsigned long. 00799 //! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 00800 //! or off. 00801 //! In that case optval should be SOCK_ON or SOCK_OFF (optval). 00802 //! 00803 //! @sa setsockopt 00804 // 00805 //***************************************************************************** 00806 00807 int 00808 getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) 00809 { 00810 unsigned char *ptr, *args; 00811 tBsdGetSockOptReturnParams tRetParams; 00812 00813 ptr = tSLInformation.pucTxCommandBuffer; 00814 args = (ptr + HEADERS_SIZE_CMD); 00815 00816 // Fill in temporary command buffer 00817 args = UINT32_TO_STREAM(args, sd); 00818 args = UINT32_TO_STREAM(args, level); 00819 args = UINT32_TO_STREAM(args, optname); 00820 00821 // Initiate a HCI command 00822 hci_command_send(HCI_CMND_GETSOCKOPT, 00823 ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); 00824 00825 // Since we are in blocking state - wait for event complete 00826 SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); 00827 00828 if (((signed char)tRetParams.iStatus) >= 0) 00829 { 00830 *optlen = 4; 00831 memcpy(optval, tRetParams.ucOptValue, 4); 00832 return (0); 00833 } 00834 else 00835 { 00836 errno = tRetParams.iStatus; 00837 return (errno); 00838 } 00839 } 00840 00841 //***************************************************************************** 00842 // 00843 //! simple_link_recv 00844 //! 00845 //! @param sd socket handle 00846 //! @param buf read buffer 00847 //! @param len buffer length 00848 //! @param flags indicates blocking or non-blocking operation 00849 //! @param from pointer to an address structure indicating source address 00850 //! @param fromlen source address structure size 00851 //! 00852 //! @return Return the number of bytes received, or -1 if an error 00853 //! occurred 00854 //! 00855 //! @brief Read data from socket 00856 //! Return the length of the message on successful completion. 00857 //! If a message is too long to fit in the supplied buffer, 00858 //! excess bytes may be discarded depending on the type of 00859 //! socket the message is received from 00860 // 00861 //***************************************************************************** 00862 int 00863 simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, 00864 socklen_t *fromlen, long opcode) 00865 { 00866 unsigned char *ptr, *args; 00867 tBsdReadReturnParams tSocketReadEvent; 00868 00869 ptr = tSLInformation.pucTxCommandBuffer; 00870 args = (ptr + HEADERS_SIZE_CMD); 00871 00872 // Fill in HCI packet structure 00873 args = UINT32_TO_STREAM(args, sd); 00874 args = UINT32_TO_STREAM(args, len); 00875 args = UINT32_TO_STREAM(args, flags); 00876 00877 // Generate the read command, and wait for the 00878 hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); 00879 00880 // Since we are in blocking state - wait for event complete 00881 SimpleLinkWaitEvent(opcode, &tSocketReadEvent); 00882 00883 // In case the number of bytes is more then zero - read data 00884 if (tSocketReadEvent.iNumberOfBytes > 0) 00885 { 00886 // Wait for the data in a synchronous way. Here we assume that the bug is 00887 // big enough to store also parameters of receive from too.... 00888 SimpleLinkWaitData((unsigned char *)buf, (unsigned char *)from, (unsigned char *)fromlen); 00889 } 00890 00891 errno = tSocketReadEvent.iNumberOfBytes; 00892 00893 return(tSocketReadEvent.iNumberOfBytes); 00894 } 00895 00896 //***************************************************************************** 00897 // 00898 //! recv 00899 //! 00900 //! @param[in] sd socket handle 00901 //! @param[out] buf Points to the buffer where the message should be stored 00902 //! @param[in] len Specifies the length in bytes of the buffer pointed to 00903 //! by the buffer argument. 00904 //! @param[in] flags Specifies the type of message reception. 00905 //! On this version, this parameter is not supported. 00906 //! 00907 //! @return Return the number of bytes received, or -1 if an error 00908 //! occurred 00909 //! 00910 //! @brief function receives a message from a connection-mode socket 00911 //! 00912 //! @sa recvfrom 00913 //! 00914 //! @Note On this version, only blocking mode is supported. 00915 // 00916 //***************************************************************************** 00917 00918 int 00919 recv(long sd, void *buf, long len, long flags) 00920 { 00921 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); 00922 } 00923 00924 //***************************************************************************** 00925 // 00926 //! recvfrom 00927 //! 00928 //! @param[in] sd socket handle 00929 //! @param[out] buf Points to the buffer where the message should be stored 00930 //! @param[in] len Specifies the length in bytes of the buffer pointed to 00931 //! by the buffer argument. 00932 //! @param[in] flags Specifies the type of message reception. 00933 //! On this version, this parameter is not supported. 00934 //! @param[in] from pointer to an address structure indicating the source 00935 //! address: sockaddr. On this version only AF_INET is 00936 //! supported. 00937 //! @param[in] fromlen source address tructure size 00938 //! 00939 //! @return Return the number of bytes received, or -1 if an error 00940 //! occurred 00941 //! 00942 //! @brief read data from socket 00943 //! function receives a message from a connection-mode or 00944 //! connectionless-mode socket. Note that raw sockets are not 00945 //! supported. 00946 //! 00947 //! @sa recv 00948 //! 00949 //! @Note On this version, only blocking mode is supported. 00950 // 00951 //***************************************************************************** 00952 int 00953 recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, 00954 socklen_t *fromlen) 00955 { 00956 return(simple_link_recv(sd, buf, len, flags, from, fromlen, 00957 HCI_CMND_RECVFROM)); 00958 } 00959 00960 //***************************************************************************** 00961 // 00962 //! simple_link_send 00963 //! 00964 //! @param sd socket handle 00965 //! @param buf write buffer 00966 //! @param len buffer length 00967 //! @param flags On this version, this parameter is not supported 00968 //! @param to pointer to an address structure indicating destination 00969 //! address 00970 //! @param tolen destination address structure size 00971 //! 00972 //! @return Return the number of bytes transmitted, or -1 if an error 00973 //! occurred, or -2 in case there are no free buffers available 00974 //! (only when SEND_NON_BLOCKING is enabled) 00975 //! 00976 //! @brief This function is used to transmit a message to another 00977 //! socket 00978 // 00979 //***************************************************************************** 00980 int 00981 simple_link_send(long sd, const void *buf, long len, long flags, 00982 const sockaddr *to, long tolen, long opcode) 00983 { 00984 unsigned char uArgSize, addrlen; 00985 unsigned char *ptr, *pDataPtr, *args; 00986 unsigned long addr_offset; 00987 int res; 00988 tBsdReadReturnParams tSocketSendEvent; 00989 00990 // Check the bsd_arguments 00991 if (0 != (res = HostFlowControlConsumeBuff(sd))) 00992 { 00993 return res; 00994 } 00995 00996 //Update the number of sent packets 00997 tSLInformation.NumberOfSentPackets++; 00998 00999 // Allocate a buffer and construct a packet and send it over spi 01000 ptr = tSLInformation.pucTxCommandBuffer; 01001 args = (ptr + HEADERS_SIZE_DATA); 01002 01003 // Update the offset of data and parameters according to the command 01004 switch(opcode) 01005 { 01006 case HCI_CMND_SENDTO: 01007 { 01008 addr_offset = len + sizeof(len) + sizeof(len); 01009 addrlen = 8; 01010 uArgSize = SOCKET_SENDTO_PARAMS_LEN; 01011 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; 01012 break; 01013 } 01014 01015 case HCI_CMND_SEND: 01016 { 01017 tolen = 0; 01018 to = NULL; 01019 uArgSize = HCI_CMND_SEND_ARG_LENGTH; 01020 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; 01021 break; 01022 } 01023 01024 default: 01025 { 01026 break; 01027 } 01028 } 01029 01030 // Fill in temporary command buffer 01031 args = UINT32_TO_STREAM(args, sd); 01032 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); 01033 args = UINT32_TO_STREAM(args, len); 01034 args = UINT32_TO_STREAM(args, flags); 01035 01036 if (opcode == HCI_CMND_SENDTO) 01037 { 01038 args = UINT32_TO_STREAM(args, addr_offset); 01039 args = UINT32_TO_STREAM(args, addrlen); 01040 } 01041 01042 // Copy the data received from user into the TX Buffer 01043 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len); 01044 01045 // In case we are using SendTo, copy the to parameters 01046 if (opcode == HCI_CMND_SENDTO) 01047 { 01048 ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen); 01049 } 01050 01051 // Initiate a HCI command 01052 hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen); 01053 01054 if (opcode == HCI_CMND_SENDTO) 01055 SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); 01056 else 01057 SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); 01058 01059 return (len); 01060 } 01061 01062 01063 //***************************************************************************** 01064 // 01065 //! send 01066 //! 01067 //! @param sd socket handle 01068 //! @param buf Points to a buffer containing the message to be sent 01069 //! @param len message size in bytes 01070 //! @param flags On this version, this parameter is not supported 01071 //! 01072 //! @return Return the number of bytes transmitted, or -1 if an 01073 //! error occurred 01074 //! 01075 //! @brief Write data to TCP socket 01076 //! This function is used to transmit a message to another 01077 //! socket. 01078 //! 01079 //! @Note On this version, only blocking mode is supported. 01080 //! 01081 //! @sa sendto 01082 // 01083 //***************************************************************************** 01084 01085 int 01086 send(long sd, const void *buf, long len, long flags) 01087 { 01088 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); 01089 } 01090 01091 //***************************************************************************** 01092 // 01093 //! sendto 01094 //! 01095 //! @param sd socket handle 01096 //! @param buf Points to a buffer containing the message to be sent 01097 //! @param len message size in bytes 01098 //! @param flags On this version, this parameter is not supported 01099 //! @param to pointer to an address structure indicating the destination 01100 //! address: sockaddr. On this version only AF_INET is 01101 //! supported. 01102 //! @param tolen destination address structure size 01103 //! 01104 //! @return Return the number of bytes transmitted, or -1 if an 01105 //! error occurred 01106 //! 01107 //! @brief Write data to TCP socket 01108 //! This function is used to transmit a message to another 01109 //! socket. 01110 //! 01111 //! @Note On this version, only blocking mode is supported. 01112 //! 01113 //! @sa send 01114 // 01115 //***************************************************************************** 01116 01117 int 01118 sendto(long sd, const void *buf, long len, long flags, const sockaddr *to, 01119 socklen_t tolen) 01120 { 01121 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); 01122 } 01123 01124 //***************************************************************************** 01125 // 01126 //! mdnsAdvertiser 01127 //! 01128 //! @param[in] mdnsEnabled flag to enable/disable the mDNS feature 01129 //! @param[in] deviceServiceName Service name as part of the published 01130 //! canonical domain name 01131 //! @param[in] deviceServiceNameLength Length of the service name 01132 //! 01133 //! 01134 //! @return On success, zero is returned, return SOC_ERROR if socket was not 01135 //! opened successfully, or if an error occurred. 01136 //! 01137 //! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself. 01138 // 01139 //***************************************************************************** 01140 01141 int 01142 mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength) 01143 { 01144 int ret; 01145 unsigned char *pTxBuffer, *pArgs; 01146 01147 if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH) 01148 { 01149 return EFAIL; 01150 } 01151 01152 pTxBuffer = tSLInformation.pucTxCommandBuffer; 01153 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 01154 01155 // Fill in HCI packet structure 01156 pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled); 01157 pArgs = UINT32_TO_STREAM(pArgs, 8); 01158 pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength); 01159 ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength); 01160 01161 // Initiate a HCI command 01162 hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength); 01163 01164 // Since we are in blocking state - wait for event complete 01165 SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret); 01166 01167 return ret; 01168 01169 } 01170
Generated on Wed Jul 13 2022 13:30:51 by
1.7.2