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