Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
SocketAddress.cpp
00001 /* Socket 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "SocketAddress.h" 00018 #include "NetworkInterface.h" 00019 #include "NetworkStack.h" 00020 #include <string.h> 00021 #include "mbed.h" 00022 00023 00024 static bool ipv4_is_valid(const char *addr) 00025 { 00026 int i = 0; 00027 00028 // Check each digit for [0-9.] 00029 for (; addr[i]; i++) { 00030 if (!(addr[i] >= '0' && addr[i] <= '9') && addr[i] != '.') { 00031 return false; 00032 } 00033 } 00034 00035 // Ending with '.' garuntees host 00036 if (i > 0 && addr[i-1] == '.') { 00037 return false; 00038 } 00039 00040 return true; 00041 } 00042 00043 static bool ipv6_is_valid(const char *addr) 00044 { 00045 // Check each digit for [0-9a-fA-F:] 00046 // Must also have at least 2 colons 00047 int colons = 0; 00048 for (int i = 0; addr[i]; i++) { 00049 if (!(addr[i] >= '0' && addr[i] <= '9') && 00050 !(addr[i] >= 'a' && addr[i] <= 'f') && 00051 !(addr[i] >= 'A' && addr[i] <= 'F') && 00052 addr[i] != ':') { 00053 return false; 00054 } 00055 if (addr[i] == ':') { 00056 colons++; 00057 } 00058 } 00059 00060 return colons >= 2; 00061 } 00062 00063 static void ipv4_from_address(uint8_t *bytes, const char *addr) 00064 { 00065 int count = 0; 00066 int i = 0; 00067 00068 for (; count < NSAPI_IPv4_BYTES; count++) { 00069 unsigned char b; 00070 int scanned = sscanf(&addr[i], "%hhu", &b); 00071 if (scanned < 1) { 00072 return; 00073 } 00074 00075 bytes[count] = b; 00076 00077 for (; addr[i] != '.'; i++) { 00078 if (!addr[i]) { 00079 return; 00080 } 00081 } 00082 00083 i++; 00084 } 00085 } 00086 00087 static int ipv6_scan_chunk(uint16_t *shorts, const char *chunk) { 00088 int count = 0; 00089 int i = 0; 00090 00091 for (; count < NSAPI_IPv6_BYTES/2; count++) { 00092 unsigned short s; 00093 int scanned = sscanf(&chunk[i], "%hx", &s); 00094 if (scanned < 1) { 00095 return count; 00096 } 00097 00098 shorts[count] = s; 00099 00100 for (; chunk[i] != ':'; i++) { 00101 if (!chunk[i]) { 00102 return count+1; 00103 } 00104 } 00105 00106 i++; 00107 } 00108 00109 return count; 00110 } 00111 00112 static void ipv6_from_address(uint8_t *bytes, const char *addr) 00113 { 00114 // Start with zeroed address 00115 uint16_t shorts[NSAPI_IPv6_BYTES/2]; 00116 int suffix = 0; 00117 00118 // Find double colons and scan suffix 00119 for (int i = 0; addr[i]; i++) { 00120 if (addr[i] == ':' && addr[i+1] == ':') { 00121 suffix = ipv6_scan_chunk(shorts, &addr[i+2]); 00122 break; 00123 } 00124 } 00125 00126 // Move suffix to end 00127 memmove(&shorts[NSAPI_IPv6_BYTES/2-suffix], &shorts[0], 00128 suffix*sizeof(uint16_t)); 00129 memset(&shorts[0], 0, 00130 (NSAPI_IPv6_BYTES/2-suffix)*sizeof(uint16_t)); 00131 00132 // Scan prefix 00133 ipv6_scan_chunk(shorts, &addr[0]); 00134 00135 // Flip bytes 00136 for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) { 00137 bytes[2*i+0] = (uint8_t)(shorts[i] >> 8); 00138 bytes[2*i+1] = (uint8_t)(shorts[i] >> 0); 00139 } 00140 } 00141 00142 static void ipv4_to_address(char *addr, const uint8_t *bytes) 00143 { 00144 sprintf(addr, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); 00145 } 00146 00147 static void ipv6_to_address(char *addr, const uint8_t *bytes) 00148 { 00149 for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) { 00150 sprintf(&addr[5*i], "%02x%02x", bytes[2*i], bytes[2*i+1]); 00151 addr[5*i+4] = ':'; 00152 } 00153 addr[NSAPI_IPv6_SIZE-1] = '\0'; 00154 } 00155 00156 00157 SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port) 00158 { 00159 _ip_address[0] = '\0'; 00160 set_addr(addr); 00161 set_port(port); 00162 } 00163 00164 SocketAddress::SocketAddress(const char *addr, uint16_t port) 00165 { 00166 _ip_address[0] = '\0'; 00167 set_ip_address(addr); 00168 set_port(port); 00169 } 00170 00171 SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port) 00172 { 00173 _ip_address[0] = '\0'; 00174 set_ip_bytes(bytes, version); 00175 set_port(port); 00176 } 00177 00178 SocketAddress::SocketAddress(const SocketAddress &addr) 00179 { 00180 _ip_address[0] = '\0'; 00181 set_addr(addr.get_addr()); 00182 set_port(addr.get_port()); 00183 } 00184 00185 bool SocketAddress::set_ip_address(const char *addr) 00186 { 00187 _ip_address[0] = '\0'; 00188 00189 if (addr && ipv4_is_valid(addr)) { 00190 _addr.version = NSAPI_IPv4 ; 00191 ipv4_from_address(_addr.bytes, addr); 00192 return true; 00193 } else if (addr && ipv6_is_valid(addr)) { 00194 _addr.version = NSAPI_IPv6 ; 00195 ipv6_from_address(_addr.bytes, addr); 00196 return true; 00197 } else { 00198 _addr = nsapi_addr_t(); 00199 return false; 00200 } 00201 } 00202 00203 void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version) 00204 { 00205 nsapi_addr_t addr; 00206 00207 addr = nsapi_addr_t(); 00208 addr.version = version; 00209 if (version == NSAPI_IPv6 ) { 00210 memcpy(addr.bytes, bytes, NSAPI_IPv6_BYTES); 00211 } else if (version == NSAPI_IPv4 ) { 00212 memcpy(addr.bytes, bytes, NSAPI_IPv4_BYTES); 00213 } 00214 set_addr(addr); 00215 } 00216 00217 void SocketAddress::set_addr(nsapi_addr_t addr) 00218 { 00219 _ip_address[0] = '\0'; 00220 _addr = addr; 00221 } 00222 00223 void SocketAddress::set_port(uint16_t port) 00224 { 00225 _port = port; 00226 } 00227 00228 const char *SocketAddress::get_ip_address() const 00229 { 00230 if (_addr.version == NSAPI_UNSPEC ) { 00231 return NULL; 00232 } 00233 00234 if (!_ip_address[0]) { 00235 if (_addr.version == NSAPI_IPv4 ) { 00236 ipv4_to_address(_ip_address, _addr.bytes); 00237 } else if (_addr.version == NSAPI_IPv6 ) { 00238 ipv6_to_address(_ip_address, _addr.bytes); 00239 } 00240 } 00241 00242 return _ip_address; 00243 } 00244 00245 const void *SocketAddress::get_ip_bytes() const 00246 { 00247 return _addr.bytes; 00248 } 00249 00250 nsapi_version_t SocketAddress::get_ip_version() const 00251 { 00252 return _addr.version; 00253 } 00254 00255 nsapi_addr_t SocketAddress::get_addr() const 00256 { 00257 return _addr; 00258 } 00259 00260 uint16_t SocketAddress::get_port() const 00261 { 00262 return _port; 00263 } 00264 00265 SocketAddress::operator bool() const 00266 { 00267 if (_addr.version == NSAPI_IPv4 ) { 00268 for (int i = 0; i < NSAPI_IPv4_BYTES; i++) { 00269 if (_addr.bytes[i]) { 00270 return true; 00271 } 00272 } 00273 00274 return false; 00275 } else if (_addr.version == NSAPI_IPv6 ) { 00276 for (int i = 0; i < NSAPI_IPv6_BYTES; i++) { 00277 if (_addr.bytes[i]) { 00278 return true; 00279 } 00280 } 00281 00282 return false; 00283 } else { 00284 return false; 00285 } 00286 } 00287 00288 bool operator==(const SocketAddress &a, const SocketAddress &b) 00289 { 00290 if (!a && !b) { 00291 return true; 00292 } else if (a._addr.version != b._addr.version) { 00293 return false; 00294 } else if (a._addr.version == NSAPI_IPv4 ) { 00295 return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv4_BYTES) == 0; 00296 } else if (a._addr.version == NSAPI_IPv6 ) { 00297 return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv6_BYTES) == 0; 00298 } 00299 00300 MBED_UNREACHABLE; 00301 } 00302 00303 bool operator!=(const SocketAddress &a, const SocketAddress &b) 00304 { 00305 return !(a == b); 00306 } 00307 00308 void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port) 00309 { 00310 _ip_address[0] = '\0'; 00311 00312 // gethostbyname must check for literals, so can call it directly 00313 int err = iface->gethostbyname(host, this); 00314 _port = port; 00315 if (err) { 00316 _addr = nsapi_addr_t(); 00317 _port = 0; 00318 } 00319 }
Generated on Sun Jul 17 2022 08:25:30 by 1.7.2