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