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.h@47:cc9a2501e29f, 2014-10-16 (annotated)
- Committer:
- vpcola
- Date:
- Thu Oct 16 13:39:08 2014 +0000
- Revision:
- 47:cc9a2501e29f
- Parent:
- 37:3332f57b7f1e
Added mutex if used in rtos
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Kojto | 20:30b6ed7bf8fd | 1 | /***************************************************************************** |
Kojto | 20:30b6ed7bf8fd | 2 | * |
Kojto | 20:30b6ed7bf8fd | 3 | * C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to |
Kojto | 20:30b6ed7bf8fd | 4 | * Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and |
Kojto | 20:30b6ed7bf8fd | 5 | * provided help. |
Kojto | 20:30b6ed7bf8fd | 6 | * |
Kojto | 20:30b6ed7bf8fd | 7 | * This version of "host driver" uses CC3000 Host Driver Implementation. Thus |
Kojto | 20:30b6ed7bf8fd | 8 | * read the following copyright: |
Kojto | 20:30b6ed7bf8fd | 9 | * |
Kojto | 20:30b6ed7bf8fd | 10 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ |
Kojto | 20:30b6ed7bf8fd | 11 | * |
Kojto | 20:30b6ed7bf8fd | 12 | * Redistribution and use in source and binary forms, with or without |
Kojto | 20:30b6ed7bf8fd | 13 | * modification, are permitted provided that the following conditions |
Kojto | 20:30b6ed7bf8fd | 14 | * are met: |
Kojto | 20:30b6ed7bf8fd | 15 | * |
Kojto | 20:30b6ed7bf8fd | 16 | * Redistributions of source code must retain the above copyright |
Kojto | 20:30b6ed7bf8fd | 17 | * notice, this list of conditions and the following disclaimer. |
Kojto | 20:30b6ed7bf8fd | 18 | * |
Kojto | 20:30b6ed7bf8fd | 19 | * Redistributions in binary form must reproduce the above copyright |
Kojto | 20:30b6ed7bf8fd | 20 | * notice, this list of conditions and the following disclaimer in the |
Kojto | 20:30b6ed7bf8fd | 21 | * documentation and/or other materials provided with the |
Kojto | 20:30b6ed7bf8fd | 22 | * distribution. |
Kojto | 20:30b6ed7bf8fd | 23 | * |
Kojto | 20:30b6ed7bf8fd | 24 | * Neither the name of Texas Instruments Incorporated nor the names of |
Kojto | 20:30b6ed7bf8fd | 25 | * its contributors may be used to endorse or promote products derived |
Kojto | 20:30b6ed7bf8fd | 26 | * from this software without specific prior written permission. |
Kojto | 20:30b6ed7bf8fd | 27 | * |
Kojto | 20:30b6ed7bf8fd | 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
Kojto | 20:30b6ed7bf8fd | 29 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
Kojto | 20:30b6ed7bf8fd | 30 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
Kojto | 20:30b6ed7bf8fd | 31 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
Kojto | 20:30b6ed7bf8fd | 32 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
Kojto | 20:30b6ed7bf8fd | 33 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
Kojto | 20:30b6ed7bf8fd | 34 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
Kojto | 20:30b6ed7bf8fd | 35 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
Kojto | 20:30b6ed7bf8fd | 36 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
Kojto | 20:30b6ed7bf8fd | 37 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
Kojto | 20:30b6ed7bf8fd | 38 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Kojto | 20:30b6ed7bf8fd | 39 | * |
Kojto | 20:30b6ed7bf8fd | 40 | *****************************************************************************/ |
Kojto | 20:30b6ed7bf8fd | 41 | #ifndef CC3000_SOCKET_H |
Kojto | 20:30b6ed7bf8fd | 42 | #define CC3000_SOCKET_H |
Kojto | 20:30b6ed7bf8fd | 43 | |
Kojto | 20:30b6ed7bf8fd | 44 | #define SOCKET_MAX_FREE_BUFFERS 6 |
Kojto | 20:30b6ed7bf8fd | 45 | |
Kojto | 20:30b6ed7bf8fd | 46 | #define SOCKET_STATUS_ACTIVE 0 |
Kojto | 20:30b6ed7bf8fd | 47 | #define SOCKET_STATUS_INACTIVE 1 |
Kojto | 20:30b6ed7bf8fd | 48 | |
Kojto | 20:30b6ed7bf8fd | 49 | #define SOCKET_STATUS_INIT_VAL 0xFFFF |
Kojto | 20:30b6ed7bf8fd | 50 | #define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) |
Kojto | 20:30b6ed7bf8fd | 51 | #define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) |
Kojto | 20:30b6ed7bf8fd | 52 | |
Kojto | 20:30b6ed7bf8fd | 53 | #ifdef _API_USE_BSD_CLOSE |
Kojto | 20:30b6ed7bf8fd | 54 | #define close(sd) closesocket(sd) |
Kojto | 20:30b6ed7bf8fd | 55 | #endif |
Kojto | 20:30b6ed7bf8fd | 56 | |
Kojto | 20:30b6ed7bf8fd | 57 | //Enable this flag if and only if you must comply with BSD socket read() and |
Kojto | 20:30b6ed7bf8fd | 58 | //write() functions |
Kojto | 20:30b6ed7bf8fd | 59 | #ifdef _API_USE_BSD_READ_WRITE |
Kojto | 20:30b6ed7bf8fd | 60 | #define read(sd, buf, len, flags) recv(sd, buf, len, flags) |
Kojto | 20:30b6ed7bf8fd | 61 | #define write(sd, buf, len, flags) send(sd, buf, len, flags) |
Kojto | 20:30b6ed7bf8fd | 62 | #endif |
Kojto | 20:30b6ed7bf8fd | 63 | |
Kojto | 20:30b6ed7bf8fd | 64 | #define SOCKET_OPEN_PARAMS_LEN (12) |
Kojto | 20:30b6ed7bf8fd | 65 | #define SOCKET_CLOSE_PARAMS_LEN (4) |
Kojto | 20:30b6ed7bf8fd | 66 | #define SOCKET_ACCEPT_PARAMS_LEN (4) |
Kojto | 20:30b6ed7bf8fd | 67 | #define SOCKET_BIND_PARAMS_LEN (20) |
Kojto | 20:30b6ed7bf8fd | 68 | #define SOCKET_LISTEN_PARAMS_LEN (8) |
Kojto | 20:30b6ed7bf8fd | 69 | #define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) |
Kojto | 20:30b6ed7bf8fd | 70 | #define SOCKET_CONNECT_PARAMS_LEN (20) |
Kojto | 20:30b6ed7bf8fd | 71 | #define SOCKET_SELECT_PARAMS_LEN (44) |
Kojto | 20:30b6ed7bf8fd | 72 | #define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) |
Kojto | 20:30b6ed7bf8fd | 73 | #define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) |
Kojto | 20:30b6ed7bf8fd | 74 | #define SOCKET_RECV_FROM_PARAMS_LEN (12) |
Kojto | 20:30b6ed7bf8fd | 75 | #define SOCKET_SENDTO_PARAMS_LEN (24) |
Kojto | 20:30b6ed7bf8fd | 76 | #define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) |
Kojto | 20:30b6ed7bf8fd | 77 | |
Kojto | 20:30b6ed7bf8fd | 78 | //#define NULL 0 |
Kojto | 20:30b6ed7bf8fd | 79 | |
Kojto | 20:30b6ed7bf8fd | 80 | // The legnth of arguments for the SEND command: sd + buff_offset + len + flags, |
Kojto | 20:30b6ed7bf8fd | 81 | // while size of each parameter is 32 bit - so the total length is 16 bytes; |
Kojto | 20:30b6ed7bf8fd | 82 | |
Kojto | 20:30b6ed7bf8fd | 83 | #define HCI_CMND_SEND_ARG_LENGTH (16) |
Kojto | 20:30b6ed7bf8fd | 84 | #define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 |
Kojto | 20:30b6ed7bf8fd | 85 | #define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) |
Kojto | 20:30b6ed7bf8fd | 86 | #define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) |
Kojto | 20:30b6ed7bf8fd | 87 | #define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) |
Kojto | 20:30b6ed7bf8fd | 88 | |
Kojto | 20:30b6ed7bf8fd | 89 | |
Kojto | 20:30b6ed7bf8fd | 90 | #define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value |
Kojto | 20:30b6ed7bf8fd | 91 | |
Kojto | 20:30b6ed7bf8fd | 92 | //--------- Address Families -------- |
Kojto | 20:30b6ed7bf8fd | 93 | |
Kojto | 20:30b6ed7bf8fd | 94 | #define AF_INET 2 |
Kojto | 20:30b6ed7bf8fd | 95 | #define AF_INET6 23 |
Kojto | 20:30b6ed7bf8fd | 96 | |
Kojto | 20:30b6ed7bf8fd | 97 | //------------ Socket Types ------------ |
Kojto | 20:30b6ed7bf8fd | 98 | |
Kojto | 20:30b6ed7bf8fd | 99 | #define SOCK_STREAM 1 |
Kojto | 20:30b6ed7bf8fd | 100 | #define SOCK_DGRAM 2 |
Kojto | 20:30b6ed7bf8fd | 101 | #define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers |
Kojto | 20:30b6ed7bf8fd | 102 | #define SOCK_RDM 4 |
Kojto | 20:30b6ed7bf8fd | 103 | #define SOCK_SEQPACKET 5 |
Kojto | 20:30b6ed7bf8fd | 104 | |
Kojto | 20:30b6ed7bf8fd | 105 | //----------- Socket Protocol ---------- |
Kojto | 20:30b6ed7bf8fd | 106 | |
Kojto | 20:30b6ed7bf8fd | 107 | #define IPPROTO_IP 0 // dummy for IP |
Kojto | 20:30b6ed7bf8fd | 108 | #define IPPROTO_ICMP 1 // control message protocol |
Kojto | 20:30b6ed7bf8fd | 109 | #define IPPROTO_IPV4 IPPROTO_IP // IP inside IP |
Kojto | 20:30b6ed7bf8fd | 110 | #define IPPROTO_TCP 6 // tcp |
Kojto | 20:30b6ed7bf8fd | 111 | #define IPPROTO_UDP 17 // user datagram protocol |
Kojto | 20:30b6ed7bf8fd | 112 | #define IPPROTO_IPV6 41 // IPv6 in IPv6 |
Kojto | 20:30b6ed7bf8fd | 113 | #define IPPROTO_NONE 59 // No next header |
Kojto | 20:30b6ed7bf8fd | 114 | #define IPPROTO_RAW 255 // raw IP packet |
Kojto | 20:30b6ed7bf8fd | 115 | #define IPPROTO_MAX 256 |
Kojto | 20:30b6ed7bf8fd | 116 | |
Kojto | 20:30b6ed7bf8fd | 117 | //----------- Socket retunr codes ----------- |
Kojto | 20:30b6ed7bf8fd | 118 | |
Kojto | 20:30b6ed7bf8fd | 119 | #define SOC_ERROR (-1) // error |
Kojto | 20:30b6ed7bf8fd | 120 | #define SOC_IN_PROGRESS (-2) // socket in progress |
Kojto | 20:30b6ed7bf8fd | 121 | |
Kojto | 20:30b6ed7bf8fd | 122 | //----------- Socket Options ----------- |
Kojto | 20:30b6ed7bf8fd | 123 | #define SOL_SOCKET 0xffff // socket level |
Kojto | 20:30b6ed7bf8fd | 124 | #define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout |
Kojto | 20:30b6ed7bf8fd | 125 | #define SOCKOPT_NONBLOCK 2 // accept non block mode set SOCK_ON or SOCK_OFF (default block mode ) |
Kojto | 20:30b6ed7bf8fd | 126 | #define SOCK_ON 0 // socket non-blocking mode is enabled |
Kojto | 20:30b6ed7bf8fd | 127 | #define SOCK_OFF 1 // socket blocking mode is enabled |
Kojto | 20:30b6ed7bf8fd | 128 | |
Kojto | 20:30b6ed7bf8fd | 129 | #define TCP_NODELAY 0x0001 |
Kojto | 20:30b6ed7bf8fd | 130 | #define TCP_BSDURGENT 0x7000 |
Kojto | 20:30b6ed7bf8fd | 131 | |
Kojto | 20:30b6ed7bf8fd | 132 | #define MAX_PACKET_SIZE 1500 |
Kojto | 20:30b6ed7bf8fd | 133 | #define MAX_LISTEN_QUEUE 4 |
Kojto | 20:30b6ed7bf8fd | 134 | |
Kojto | 20:30b6ed7bf8fd | 135 | #define IOCTL_SOCKET_EVENTMASK |
Kojto | 20:30b6ed7bf8fd | 136 | |
Kojto | 20:30b6ed7bf8fd | 137 | #define __FD_SETSIZE 32 |
Kojto | 20:30b6ed7bf8fd | 138 | |
Kojto | 20:30b6ed7bf8fd | 139 | #define ASIC_ADDR_LEN 8 |
Kojto | 20:30b6ed7bf8fd | 140 | |
Kojto | 20:30b6ed7bf8fd | 141 | #define NO_QUERY_RECIVED -3 |
Kojto | 20:30b6ed7bf8fd | 142 | |
Kojto | 20:30b6ed7bf8fd | 143 | |
Kojto | 20:30b6ed7bf8fd | 144 | typedef struct _in_addr_t |
Kojto | 20:30b6ed7bf8fd | 145 | { |
Kojto | 20:30b6ed7bf8fd | 146 | uint32_t s_addr; // load with inet_aton() |
Kojto | 20:30b6ed7bf8fd | 147 | } in_addr; |
Kojto | 20:30b6ed7bf8fd | 148 | |
Kojto | 20:30b6ed7bf8fd | 149 | /*typedef struct _sockaddr_t |
Kojto | 20:30b6ed7bf8fd | 150 | { |
Kojto | 20:30b6ed7bf8fd | 151 | unsigned short int sa_family; |
Kojto | 20:30b6ed7bf8fd | 152 | unsigned char sa_data[14]; |
Kojto | 20:30b6ed7bf8fd | 153 | } sockaddr;*/ |
Kojto | 20:30b6ed7bf8fd | 154 | |
Kojto | 20:30b6ed7bf8fd | 155 | typedef struct _sockaddr_in_t |
Kojto | 20:30b6ed7bf8fd | 156 | { |
Kojto | 20:30b6ed7bf8fd | 157 | int16_t sin_family; // e.g. AF_INET |
Kojto | 20:30b6ed7bf8fd | 158 | uint16_t sin_port; // e.g. htons(3490) |
Kojto | 20:30b6ed7bf8fd | 159 | in_addr sin_addr; // see struct in_addr, below |
Kojto | 20:30b6ed7bf8fd | 160 | uint8_t sin_zero[8]; // zero this if you want to |
Kojto | 20:30b6ed7bf8fd | 161 | } sockaddr_in; |
Kojto | 20:30b6ed7bf8fd | 162 | |
Kojto | 20:30b6ed7bf8fd | 163 | typedef uint32_t socklen_t; |
Kojto | 20:30b6ed7bf8fd | 164 | |
Kojto | 20:30b6ed7bf8fd | 165 | // The fd_set member is required to be an array of longs. |
Kojto | 20:30b6ed7bf8fd | 166 | typedef int32_t __fd_mask; |
Kojto | 20:30b6ed7bf8fd | 167 | |
Kojto | 20:30b6ed7bf8fd | 168 | // It's easier to assume 8-bit bytes than to get CHAR_BIT. |
Kojto | 20:30b6ed7bf8fd | 169 | #define __NFDBITS (8 * sizeof (__fd_mask)) |
Kojto | 20:30b6ed7bf8fd | 170 | #define __FDELT(d) ((d) / __NFDBITS) |
Kojto | 20:30b6ed7bf8fd | 171 | #define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) |
Kojto | 20:30b6ed7bf8fd | 172 | |
Kojto | 37:3332f57b7f1e | 173 | #ifndef FD_SET |
Kojto | 37:3332f57b7f1e | 174 | //not used in the current code |
Kojto | 37:3332f57b7f1e | 175 | #define ENOBUFS 55 // No buffer space available |
Kojto | 37:3332f57b7f1e | 176 | |
Kojto | 37:3332f57b7f1e | 177 | // Access macros for 'fd_set'. |
Kojto | 37:3332f57b7f1e | 178 | #define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) |
Kojto | 37:3332f57b7f1e | 179 | #define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) |
Kojto | 37:3332f57b7f1e | 180 | #define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) |
Kojto | 37:3332f57b7f1e | 181 | #define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) |
Kojto | 37:3332f57b7f1e | 182 | |
Kojto | 20:30b6ed7bf8fd | 183 | // fd_set for select and pselect. |
Kojto | 20:30b6ed7bf8fd | 184 | typedef struct |
Kojto | 20:30b6ed7bf8fd | 185 | { |
Kojto | 20:30b6ed7bf8fd | 186 | __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; |
Kojto | 20:30b6ed7bf8fd | 187 | #define __FDS_BITS(set) ((set)->fds_bits) |
Kojto | 20:30b6ed7bf8fd | 188 | } fd_set; |
Kojto | 20:30b6ed7bf8fd | 189 | |
Kojto | 37:3332f57b7f1e | 190 | #endif /* FD_SET */ |
Kojto | 37:3332f57b7f1e | 191 | |
Kojto | 20:30b6ed7bf8fd | 192 | // We don't use `memset' because this would require a prototype and |
Kojto | 20:30b6ed7bf8fd | 193 | // the array isn't too big. |
Kojto | 20:30b6ed7bf8fd | 194 | #define __FD_ZERO(set) \ |
Kojto | 20:30b6ed7bf8fd | 195 | do { \ |
Kojto | 20:30b6ed7bf8fd | 196 | uint32_t __i; \ |
Kojto | 20:30b6ed7bf8fd | 197 | fd_set *__arr = (set); \ |
Kojto | 20:30b6ed7bf8fd | 198 | for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ |
Kojto | 20:30b6ed7bf8fd | 199 | __FDS_BITS (__arr)[__i] = 0; \ |
Kojto | 20:30b6ed7bf8fd | 200 | } while (0) |
Kojto | 20:30b6ed7bf8fd | 201 | #define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) |
Kojto | 20:30b6ed7bf8fd | 202 | #define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d)) |
Kojto | 20:30b6ed7bf8fd | 203 | #define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d)) |
Kojto | 20:30b6ed7bf8fd | 204 | |
Kojto | 20:30b6ed7bf8fd | 205 | //Use in case of Big Endian only |
Kojto | 20:30b6ed7bf8fd | 206 | |
Kojto | 20:30b6ed7bf8fd | 207 | #define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ |
Kojto | 20:30b6ed7bf8fd | 208 | (((uint32_t)(A) & 0x00ff0000) >> 8) | \ |
Kojto | 20:30b6ed7bf8fd | 209 | (((uint32_t)(A) & 0x0000ff00) << 8) | \ |
Kojto | 20:30b6ed7bf8fd | 210 | (((uint32_t)(A) & 0x000000ff) << 24)) |
Kojto | 20:30b6ed7bf8fd | 211 | |
Kojto | 20:30b6ed7bf8fd | 212 | #define ntohl htonl |
Kojto | 20:30b6ed7bf8fd | 213 | |
Kojto | 20:30b6ed7bf8fd | 214 | //Use in case of Big Endian only |
Kojto | 20:30b6ed7bf8fd | 215 | #define htons(A) ((((uint32_t)(A) & 0xff00) >> 8) | \ |
Kojto | 20:30b6ed7bf8fd | 216 | (((uint32_t)(A) & 0x00ff) << 8)) |
Kojto | 20:30b6ed7bf8fd | 217 | |
Kojto | 20:30b6ed7bf8fd | 218 | |
Kojto | 20:30b6ed7bf8fd | 219 | #define ntohs htons |
Kojto | 20:30b6ed7bf8fd | 220 | |
Kojto | 20:30b6ed7bf8fd | 221 | // mDNS port - 5353 mDNS multicast address - 224.0.0.251 |
Kojto | 20:30b6ed7bf8fd | 222 | #define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ |
Kojto | 20:30b6ed7bf8fd | 223 | sockaddr.sa_data[1] = 0xe9; \ |
Kojto | 20:30b6ed7bf8fd | 224 | sockaddr.sa_data[2] = 0xe0; \ |
Kojto | 20:30b6ed7bf8fd | 225 | sockaddr.sa_data[3] = 0x0; \ |
Kojto | 20:30b6ed7bf8fd | 226 | sockaddr.sa_data[4] = 0x0; \ |
Kojto | 20:30b6ed7bf8fd | 227 | sockaddr.sa_data[5] = 0xfb; |
Kojto | 20:30b6ed7bf8fd | 228 | |
Kojto | 20:30b6ed7bf8fd | 229 | #endif |