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