Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of cc3000_hostdriver_mbedsocket by
cc3000_socket.cpp
00001 /***************************************************************************** 00002 * 00003 * C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to 00004 * Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and 00005 * provided help. 00006 * 00007 * This version of "host driver" uses CC3000 Host Driver Implementation. Thus 00008 * read the following copyright: 00009 * 00010 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions 00014 * are met: 00015 * 00016 * Redistributions of source code must retain the above copyright 00017 * notice, this list of conditions and the following disclaimer. 00018 * 00019 * Redistributions in binary form must reproduce the above copyright 00020 * notice, this list of conditions and the following disclaimer in the 00021 * documentation and/or other materials provided with the 00022 * distribution. 00023 * 00024 * Neither the name of Texas Instruments Incorporated nor the names of 00025 * its contributors may be used to endorse or promote products derived 00026 * from this software without specific prior written permission. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00029 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00030 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00031 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00032 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00033 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00034 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00035 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00036 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00037 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00038 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00039 * 00040 *****************************************************************************/ 00041 #include "cc3000.h" 00042 #include "cc3000_socket.h" 00043 #include "cc3000_event.h" //TODO - remove this 00044 #include "cc3000_common.h" 00045 00046 namespace mbed_cc3000 { 00047 00048 cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event) 00049 : _simple_link(simplelink), _hci(hci), _event(event) { 00050 00051 } 00052 00053 cc3000_socket::~cc3000_socket() { 00054 00055 } 00056 00057 int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) { 00058 #ifndef SEND_NON_BLOCKING 00059 /* wait in busy loop */ 00060 do { 00061 // When the last transmission failed, return the last failure reason. 00062 // Note that the buffer will not be allocated in this case 00063 if (_simple_link.get_transmit_error() != 0) { 00064 errno = _simple_link.get_transmit_error(); 00065 _simple_link.set_transmit_error(0); 00066 return errno; 00067 } 00068 00069 if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) 00070 return -1; 00071 } while (0 == _simple_link.get_number_free_buffers()); 00072 00073 uint16_t free_buffer = _simple_link.get_number_free_buffers(); 00074 free_buffer--; 00075 _simple_link.set_number_free_buffers(free_buffer); 00076 00077 return 0; 00078 #else 00079 00080 // When the last transmission failed, return the last failure reason. 00081 // Note that the buffer will not be allocated in this case 00082 if (_simple_link.get_transmit_error() != 0) { 00083 errno = _simple_link.get_transmit_error(); 00084 _simple_link.set_transmit_error(0); 00085 return errno; 00086 } 00087 if (SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) 00088 return -1; 00089 00090 // If there are no available buffers, return -2. It is recommended to use 00091 // select or receive to see if there is any buffer occupied with received data 00092 // If so, call receive() to release the buffer. 00093 if (0 == _simple_link.get_number_free_buffers()) { 00094 return -2; 00095 } else { 00096 uint16_t free_buffer = _simple_link.get_number_free_buffers(); 00097 free_buffer--; 00098 _simple_link.set_number_free_buffers(free_buffer); 00099 return 0; 00100 } 00101 #endif 00102 } 00103 00104 int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) { 00105 int32_t ret; 00106 uint8_t *ptr, *args; 00107 00108 ret = EFAIL; 00109 ptr = _simple_link.get_transmit_buffer(); 00110 args = (ptr + HEADERS_SIZE_CMD); 00111 00112 // Fill in HCI packet structure 00113 args = UINT32_TO_STREAM(args, domain); 00114 args = UINT32_TO_STREAM(args, type); 00115 args = UINT32_TO_STREAM(args, protocol); 00116 00117 // Initiate a HCI command 00118 _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); 00119 00120 // Since we are in blocking state - wait for event complete 00121 _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret); 00122 00123 // Process the event 00124 errno = ret; 00125 00126 _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); 00127 00128 return ret; 00129 } 00130 00131 int32_t cc3000_socket::closesocket(int32_t sd) { 00132 int32_t ret; 00133 uint8_t *ptr, *args; 00134 00135 while (_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS); 00136 ret = EFAIL; 00137 ptr = _simple_link.get_transmit_buffer(); 00138 args = (ptr + HEADERS_SIZE_CMD); 00139 00140 // Fill in HCI packet structure 00141 args = UINT32_TO_STREAM(args, sd); 00142 00143 // Initiate a HCI command 00144 _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN); 00145 00146 // Since we are in blocking state - wait for event complete 00147 _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret); 00148 errno = ret; 00149 00150 // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid 00151 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); 00152 00153 return ret; 00154 } 00155 00156 int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) { 00157 int32_t ret; 00158 uint8_t *ptr, *args; 00159 tBsdReturnParams tAcceptReturnArguments; 00160 00161 ret = EFAIL; 00162 ptr = _simple_link.get_transmit_buffer(); 00163 args = (ptr + HEADERS_SIZE_CMD); 00164 00165 // Fill in temporary command buffer 00166 args = UINT32_TO_STREAM(args, sd); 00167 00168 // Initiate a HCI command 00169 _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); 00170 00171 // Since we are in blocking state - wait for event complete 00172 _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments); 00173 00174 00175 // need specify return parameters!!! 00176 memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); 00177 *addrlen = ASIC_ADDR_LEN; 00178 errno = tAcceptReturnArguments.iStatus; 00179 ret = errno; 00180 00181 // if succeeded, iStatus = new socket descriptor. otherwise - error number 00182 if(M_IS_VALID_SD(ret)) { 00183 _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); 00184 } else { 00185 _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); 00186 } 00187 00188 return ret; 00189 } 00190 00191 int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) { 00192 int32_t ret; 00193 uint8_t *ptr, *args; 00194 00195 ret = EFAIL; 00196 ptr = _simple_link.get_transmit_buffer(); 00197 args = (ptr + HEADERS_SIZE_CMD); 00198 00199 addrlen = ASIC_ADDR_LEN; 00200 00201 // Fill in temporary command buffer 00202 args = UINT32_TO_STREAM(args, sd); 00203 args = UINT32_TO_STREAM(args, 0x00000008); 00204 args = UINT32_TO_STREAM(args, addrlen); 00205 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); 00206 00207 // Initiate a HCI command 00208 _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); 00209 00210 // Since we are in blocking state - wait for event complete 00211 _event.simplelink_wait_event(HCI_CMND_BIND, &ret); 00212 00213 errno = ret; 00214 00215 return ret; 00216 } 00217 00218 int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) { 00219 int32_t ret; 00220 uint8_t *ptr, *args; 00221 00222 ret = EFAIL; 00223 ptr = _simple_link.get_transmit_buffer(); 00224 args = (ptr + HEADERS_SIZE_CMD); 00225 00226 // Fill in temporary command buffer 00227 args = UINT32_TO_STREAM(args, sd); 00228 args = UINT32_TO_STREAM(args, backlog); 00229 00230 // Initiate a HCI command 00231 _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); 00232 00233 // Since we are in blocking state - wait for event complete 00234 _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret); 00235 errno = ret; 00236 00237 return(ret); 00238 } 00239 00240 int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) { 00241 int32_t ret; 00242 uint8_t *ptr, *args; 00243 00244 ret = EFAIL; 00245 ptr = _simple_link.get_transmit_buffer(); 00246 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00247 addrlen = 8; 00248 00249 // Fill in temporary command buffer 00250 args = UINT32_TO_STREAM(args, sd); 00251 args = UINT32_TO_STREAM(args, 0x00000008); 00252 args = UINT32_TO_STREAM(args, addrlen); 00253 ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); 00254 00255 // Initiate a HCI command 00256 _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN); 00257 00258 // Since we are in blocking state - wait for event complete 00259 _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret); 00260 00261 errno = ret; 00262 00263 return((int32_t)ret); 00264 } 00265 00266 int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) { 00267 uint8_t *ptr, *args; 00268 tBsdSelectRecvParams tParams; 00269 uint32_t is_blocking; 00270 00271 if (timeout == NULL) { 00272 is_blocking = 1; /* blocking , infinity timeout */ 00273 } else { 00274 is_blocking = 0; /* no blocking, timeout */ 00275 } 00276 00277 // Fill in HCI packet structure 00278 ptr = _simple_link.get_transmit_buffer(); 00279 args = (ptr + HEADERS_SIZE_CMD); 00280 00281 // Fill in temporary command buffer 00282 args = UINT32_TO_STREAM(args, nfds); 00283 args = UINT32_TO_STREAM(args, 0x00000014); 00284 args = UINT32_TO_STREAM(args, 0x00000014); 00285 args = UINT32_TO_STREAM(args, 0x00000014); 00286 args = UINT32_TO_STREAM(args, 0x00000014); 00287 args = UINT32_TO_STREAM(args, is_blocking); 00288 args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0)); 00289 args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0)); 00290 args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0)); 00291 00292 if (timeout) { 00293 if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) { 00294 timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; 00295 } 00296 args = UINT32_TO_STREAM(args, timeout->tv_sec); 00297 args = UINT32_TO_STREAM(args, timeout->tv_usec); 00298 } 00299 00300 // Initiate a HCI command 00301 _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); 00302 00303 // Since we are in blocking state - wait for event complete 00304 _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams); 00305 00306 // Update actually read FD 00307 if (tParams.iStatus >= 0) { 00308 if (readsds) { 00309 memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); 00310 } 00311 00312 if (writesds) { 00313 memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 00314 } 00315 00316 if (exceptsds) { 00317 memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 00318 } 00319 00320 return(tParams.iStatus); 00321 00322 } else { 00323 errno = tParams.iStatus; 00324 return -1; 00325 } 00326 } 00327 00328 int32_t cc3000_socket::getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) { 00329 uint8_t *ptr, *args; 00330 tBsdGetSockOptReturnParams tRetParams; 00331 00332 ptr = _simple_link.get_transmit_buffer(); 00333 args = (ptr + HEADERS_SIZE_CMD); 00334 00335 // Fill in temporary command buffer 00336 args = UINT32_TO_STREAM(args, sd); 00337 args = UINT32_TO_STREAM(args, level); 00338 args = UINT32_TO_STREAM(args, optname); 00339 00340 // Initiate a HCI command 00341 _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); 00342 00343 // Since we are in blocking state - wait for event complete 00344 _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams); 00345 00346 if (((int8_t)tRetParams.iStatus) >= 0) { 00347 *optlen = 4; 00348 memcpy(optval, tRetParams.ucOptValue, 4); 00349 return (0); 00350 } else { 00351 errno = tRetParams.iStatus; 00352 return errno; 00353 } 00354 } 00355 00356 int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) { 00357 uint8_t *ptr, *args; 00358 tBsdReadReturnParams tSocketReadEvent; 00359 00360 ptr = _simple_link.get_transmit_buffer(); 00361 args = (ptr + HEADERS_SIZE_CMD); 00362 00363 // Fill in HCI packet structure 00364 args = UINT32_TO_STREAM(args, sd); 00365 args = UINT32_TO_STREAM(args, len); 00366 args = UINT32_TO_STREAM(args, flags); 00367 00368 // Generate the read command, and wait for the 00369 _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); 00370 00371 // Since we are in blocking state - wait for event complete 00372 _event.simplelink_wait_event(opcode, &tSocketReadEvent); 00373 00374 // In case the number of bytes is more then zero - read data 00375 if (tSocketReadEvent.iNumberOfBytes > 0) { 00376 // Wait for the data in a synchronous way. Here we assume that the bug is 00377 // big enough to store also parameters of receive from too.... 00378 _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen); 00379 } 00380 00381 errno = tSocketReadEvent.iNumberOfBytes; 00382 00383 return(tSocketReadEvent.iNumberOfBytes); 00384 } 00385 00386 int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) { 00387 return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); 00388 } 00389 00390 int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) { 00391 return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM)); 00392 } 00393 00394 int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) { 00395 uint8_t uArgSize = 0x00, addrlen = 0x00; 00396 uint8_t *ptr, *pDataPtr = NULL, *args; 00397 uint32_t addr_offset = 0x00; 00398 int32_t res; 00399 tBsdReadReturnParams tSocketSendEvent; 00400 00401 // Check the bsd_arguments 00402 if (0 != (res = HostFlowControlConsumeBuff(sd))) { 00403 return res; 00404 } 00405 00406 //Update the number of sent packets 00407 uint16_t sent_packets = _simple_link.get_sent_packets(); 00408 sent_packets++; 00409 _simple_link.set_sent_packets(sent_packets); 00410 00411 // Allocate a buffer and construct a packet and send it over spi 00412 ptr = _simple_link.get_transmit_buffer(); 00413 args = (ptr + HEADERS_SIZE_DATA); 00414 00415 // Update the offset of data and parameters according to the command 00416 switch(opcode) 00417 { 00418 case HCI_CMND_SENDTO: 00419 { 00420 addr_offset = len + sizeof(len) + sizeof(len); 00421 addrlen = 8; 00422 uArgSize = SOCKET_SENDTO_PARAMS_LEN; 00423 pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; 00424 break; 00425 } 00426 00427 case HCI_CMND_SEND: 00428 { 00429 tolen = 0; 00430 to = NULL; 00431 uArgSize = HCI_CMND_SEND_ARG_LENGTH; 00432 pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; 00433 break; 00434 } 00435 00436 default: 00437 { 00438 break; 00439 } 00440 } 00441 00442 // Fill in temporary command buffer 00443 args = UINT32_TO_STREAM(args, sd); 00444 args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); 00445 args = UINT32_TO_STREAM(args, len); 00446 args = UINT32_TO_STREAM(args, flags); 00447 00448 if (opcode == HCI_CMND_SENDTO) { 00449 args = UINT32_TO_STREAM(args, addr_offset); 00450 args = UINT32_TO_STREAM(args, addrlen); 00451 } 00452 00453 // Copy the data received from user into the TX Buffer 00454 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); 00455 00456 // In case we are using SendTo, copy the to parameters 00457 if (opcode == HCI_CMND_SENDTO) { 00458 ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); 00459 } 00460 00461 // Initiate a HCI command 00462 _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); 00463 if (opcode == HCI_CMND_SENDTO) 00464 _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent); 00465 else 00466 _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent); 00467 00468 return (len); 00469 } 00470 00471 int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) { 00472 return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); 00473 } 00474 00475 int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) { 00476 return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); 00477 } 00478 00479 int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) { 00480 int32_t ret; 00481 uint8_t *pTxBuffer, *pArgs; 00482 00483 if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH) { 00484 return EFAIL; 00485 } 00486 00487 pTxBuffer = _simple_link.get_transmit_buffer(); 00488 pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00489 00490 // Fill in HCI packet structure 00491 pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled); 00492 pArgs = UINT32_TO_STREAM(pArgs, 8); 00493 pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length); 00494 ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length); 00495 00496 // Initiate a HCI command 00497 _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length); 00498 00499 // Since we are in blocking state - wait for event complete 00500 _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret); 00501 00502 return ret; 00503 } 00504 00505 00506 #ifndef CC3000_TINY_DRIVER 00507 int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) { 00508 tBsdGethostbynameParams ret; 00509 uint8_t *ptr, *args; 00510 00511 errno = EFAIL; 00512 00513 if (name_length > HOSTNAME_MAX_LENGTH) { 00514 return errno; 00515 } 00516 00517 ptr = _simple_link.get_transmit_buffer(); 00518 args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); 00519 00520 // Fill in HCI packet structure 00521 args = UINT32_TO_STREAM(args, 8); 00522 args = UINT32_TO_STREAM(args, name_length); 00523 ARRAY_TO_STREAM(args, hostname, name_length); 00524 00525 // Initiate a HCI command 00526 _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1); 00527 00528 // Since we are in blocking state - wait for event complete 00529 _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); 00530 00531 errno = ret.retVal; 00532 00533 (*((int32_t*)out_ip_addr)) = ret.outputAddress; 00534 00535 return (errno); 00536 } 00537 00538 int32_t cc3000_socket::setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) { 00539 int32_t ret; 00540 uint8_t *ptr, *args; 00541 00542 ptr = _simple_link.get_transmit_buffer(); 00543 args = (ptr + HEADERS_SIZE_CMD); 00544 00545 // Fill in temporary command buffer 00546 args = UINT32_TO_STREAM(args, sd); 00547 args = UINT32_TO_STREAM(args, level); 00548 args = UINT32_TO_STREAM(args, optname); 00549 args = UINT32_TO_STREAM(args, 0x00000008); 00550 args = UINT32_TO_STREAM(args, optlen); 00551 ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen); 00552 00553 // Initiate a HCI command 00554 _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); 00555 00556 // Since we are in blocking state - wait for event complete 00557 _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret); 00558 00559 if (ret >= 0) { 00560 return (0); 00561 } else { 00562 errno = ret; 00563 return ret; 00564 } 00565 } 00566 00567 #endif 00568 00569 char* cc3000_socket::inet_ntoa_r (uint32_t s_addr, char *buf, int buflen) 00570 { 00571 char inv[3]; 00572 char *rp; 00573 uint8_t *ap; 00574 uint8_t rem; 00575 uint8_t n; 00576 uint8_t i; 00577 int len = 0; 00578 00579 rp = buf; 00580 ap = (uint8_t *)&s_addr; 00581 for (n = 0; n < 4; n++) { 00582 i = 0; 00583 do { 00584 rem = *ap % (uint8_t)10; 00585 *ap /= (uint8_t)10; 00586 inv[i++] = '0' + rem; 00587 } while(*ap); 00588 while(i--) { 00589 if (len++ >= buflen) { 00590 return NULL; 00591 } 00592 *rp++ = inv[i]; 00593 } 00594 if (len++ >= buflen) { 00595 return NULL; 00596 } 00597 *rp++ = '.'; 00598 ap++; 00599 } 00600 *--rp = 0; 00601 return buf; 00602 } 00603 00604 } // mbed_cc3000 namespace
Generated on Fri Jul 15 2022 17:19:25 by
1.7.2
