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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ns_fnet_port.c
00001 /* 00002 * Copyright (c) 2017-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /** 00019 * FNET porting to Nanostack environment 00020 */ 00021 00022 #include "fnet.h" 00023 #include "fnet_netif.h" 00024 #include "fnet_netif_prv.h" 00025 #include "fnet_timer.h" 00026 #include "fnet_serial.h" 00027 #include "fnet_socket.h" 00028 00029 #include "ns_types.h" 00030 #include "ns_list.h" 00031 #include "common_functions.h" // common_write 00032 #include "ns_trace.h" 00033 #include "socket_api.h" 00034 #include "net_interface.h" 00035 #include "nsdynmemLIB.h" 00036 #include "Core/include/ns_address_internal.h" 00037 00038 #include "ns_fnet_events.h" 00039 00040 #define TRACE_GROUP "mDNS" 00041 00042 00043 fnet_time_t fnet_timer_get_ms(void) 00044 { 00045 return ns_fnet_time_in_ms_get(); 00046 } 00047 00048 fnet_scope_id_t fnet_netif_get_scope_id(fnet_netif_desc_t netif_desc) 00049 { 00050 fnet_netif_t *netif = (fnet_netif_t *)netif_desc; 00051 FNET_DEBUG("fnet_netif_get_scope_id() scope_id=%d", (int)netif->scope_id); 00052 return netif->scope_id; 00053 } 00054 00055 fnet_ip4_addr_t fnet_netif_get_ip4_addr(fnet_netif_desc_t netif_desc) 00056 { 00057 (void)netif_desc; 00058 return 0u; 00059 } 00060 00061 fnet_bool_t fnet_netif_get_ip6_addr(fnet_netif_desc_t netif_desc, fnet_index_t n, fnet_netif_ip6_addr_info_t *addr_info) 00062 { 00063 fnet_bool_t result = FNET_FALSE; 00064 fnet_netif_t *netif = (fnet_netif_t *)netif_desc; 00065 uint8_t global_address[16] = {0}; 00066 (void)n; 00067 00068 if (netif && addr_info) { 00069 if (0 == arm_net_address_get((int8_t)netif->scope_id, ADDR_IPV6_GP, global_address)) { 00070 memcpy(&addr_info->address.addr, global_address, 16); /* IPv6 address.*/ 00071 addr_info->state = FNET_NETIF_IP6_ADDR_STATE_PREFERRED; /* Address current state.*/ 00072 addr_info->type = FNET_NETIF_IP_ADDR_TYPE_AUTOCONFIGURABLE; /* How the address was acquired.*/ 00073 result = FNET_TRUE; 00074 } 00075 FNET_DEBUG("fnet_netif_get_ip6_addr(), if=%d: %s", (int8_t)netif->scope_id, trace_ipv6(addr_info->address.addr)); 00076 } 00077 00078 return result; 00079 } 00080 00081 fnet_bool_t fnet_netif_is_my_ip6_addr(fnet_netif_t *netif, const fnet_ip6_addr_t *ip_addr) 00082 { 00083 int i = 0; 00084 uint8_t address_buffer[16]; 00085 int8_t interface_id = (int8_t)netif->scope_id; 00086 int8_t addr_available = 0; 00087 00088 do { 00089 addr_available = arm_net_address_list_get_next(interface_id, &i, address_buffer); 00090 if (addr_available < 0) { 00091 return FNET_FALSE; 00092 } 00093 if (addr_ipv6_equal(address_buffer, ip_addr->addr)) { 00094 return FNET_TRUE; 00095 } 00096 } while (addr_available); 00097 00098 return FNET_FALSE; 00099 } 00100 00101 static void fnet_nanostack_port_ns_socket_recv(void *socket_cb) 00102 { 00103 (void)socket_cb; 00104 // socket event received, run service again to achieve faster response time 00105 ns_fnet_events_fast_poll(); 00106 } 00107 00108 fnet_socket_t fnet_socket(fnet_address_family_t family, fnet_socket_type_t type, fnet_uint32_t protocol) 00109 { 00110 int8_t socket_id = 0; 00111 (void)protocol; 00112 00113 if (type != SOCK_DGRAM || family != AF_INET6) { 00114 return FNET_NULL; 00115 } 00116 00117 socket_id = socket_open(SOCKET_UDP, 0, fnet_nanostack_port_ns_socket_recv); 00118 if (socket_id < 0) { 00119 return FNET_NULL; 00120 } 00121 00122 // Socket contains buffer for the received data, enable the feature using socket options 00123 static const int32_t rcvbuf_size = 1024 * 4; 00124 socket_setsockopt(socket_id, SOCKET_SOL_SOCKET, SOCKET_SO_RCVBUF, &rcvbuf_size, sizeof rcvbuf_size); 00125 00126 FNET_DEBUG("fnet_socket_open, socket:%d", socket_id); 00127 return (fnet_socket_t)(long)socket_id; 00128 } 00129 00130 fnet_return_t fnet_socket_bind(fnet_socket_t s, const struct sockaddr *name, fnet_size_t namelen) 00131 { 00132 (void)namelen; 00133 ns_address_t ns_source_addr; 00134 int8_t socket_id = (int8_t)(long)s; 00135 fnet_return_t fnet_ret_val = FNET_ERR; 00136 const struct sockaddr_in6 *namein6 = (const struct sockaddr_in6 *) name; 00137 memcpy(ns_source_addr.address, &namein6->sin6_addr, 16); 00138 ns_source_addr.identifier = FNET_NTOHS(namein6->sin6_port); 00139 ns_source_addr.type = ADDRESS_IPV6; 00140 00141 FNET_DEBUG("fnet_socket_bind socket:%d to port %d address %s", socket_id, (int)ns_source_addr.identifier, trace_ipv6(ns_source_addr.address)); 00142 00143 int8_t status = socket_bind(socket_id, &ns_source_addr); 00144 if (status == 0) { 00145 fnet_ret_val = FNET_OK; 00146 } 00147 00148 return fnet_ret_val; 00149 } 00150 00151 fnet_return_t fnet_socket_setopt(fnet_socket_t s, fnet_protocol_t level, fnet_socket_options_t optname, const void *optval, fnet_size_t optvallen) 00152 { 00153 (void) level; 00154 (void) optvallen; 00155 int8_t socket_id; 00156 int8_t ret_val = -1; 00157 00158 socket_id = (int8_t)(long)s; 00159 00160 if (optname == IPV6_JOIN_GROUP) { 00161 const struct ipv6_mreq *mreq6 = optval; /* Multicast group information.*/ 00162 00163 int8_t interface_id = (int8_t)mreq6->ipv6imr_interface; // scope_id holds interface_id 00164 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &interface_id, sizeof(interface_id)); 00165 00166 if (ret_val == 0) { 00167 ns_ipv6_mreq_t ns_ipv6_mreq; 00168 ns_ipv6_mreq.ipv6mr_interface = interface_id; 00169 memcpy(ns_ipv6_mreq.ipv6mr_multiaddr, ADDR_LINK_LOCAL_MDNS, 16); 00170 // Join multicast group 00171 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_JOIN_GROUP, &ns_ipv6_mreq, sizeof(ns_ipv6_mreq)); 00172 } 00173 00174 if (ret_val == 0) { 00175 bool loopback = false; 00176 // Ignore loopback from own multicasts 00177 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_LOOP, &loopback, sizeof(loopback)); 00178 } 00179 } else if (optname == IPV6_MULTICAST_HOPS) { 00180 // Both FNET and Nanostack use int16_t, so can pass straight through 00181 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, optval, optvallen); 00182 } 00183 00184 if (ret_val == 0) { 00185 return FNET_OK; 00186 } 00187 00188 return FNET_ERR; 00189 } 00190 00191 fnet_int32_t fnet_socket_sendto(fnet_socket_t s, fnet_uint8_t *buf, fnet_size_t len, fnet_flag_t flags, const struct sockaddr *to, fnet_size_t tolen) 00192 { 00193 (void)tolen; // ipv6 address expected 00194 (void)flags; // 00195 int8_t socket_id = (int8_t)(long)s; 00196 ns_address_t ns_address; 00197 00198 ns_address.type = ADDRESS_IPV6; 00199 memcpy(ns_address.address, &((struct sockaddr_in6 *)to)->sin6_addr.s6_addr, 16); 00200 // Note! Port is already in network byte order, transfer it back as nanostack will convert it again to network byte order 00201 ns_address.identifier = FNET_NTOHS(to->sa_port); 00202 FNET_DEBUG("fnet_socket_sendto, %d bytes, port:%d, socket:%d", (int)len, (int)ns_address.identifier, socket_id); 00203 return (fnet_int32_t)socket_sendto(socket_id, &ns_address, buf, len); 00204 } 00205 00206 fnet_int32_t fnet_socket_recvfrom(fnet_socket_t s, fnet_uint8_t *buf, fnet_size_t len, fnet_flag_t flags, struct sockaddr *from, fnet_size_t *fromlen) 00207 { 00208 (void)flags; // mdns does not use flags 00209 (void)fromlen; // address is ipv6 00210 int8_t socket_id = (int8_t)(long)s; 00211 int16_t data_len; 00212 ns_address_t source_address; 00213 data_len = socket_read(socket_id, &source_address, buf, len); 00214 00215 if (data_len >= 0) { 00216 if (from) { 00217 struct sockaddr_in6 *fromin6 = (struct sockaddr_in6 *) from; 00218 memcpy(&fromin6->sin6_addr.s6_addr, source_address.address, 16); 00219 //addrin6.sin6_scope_id = interface_id; where to get interface_id here? 00220 fromin6->sin6_family = AF_INET6; 00221 // port is in native byte order,, convert to network byte order 00222 fromin6->sin6_port = FNET_HTONS(source_address.identifier); 00223 *fromlen = sizeof(struct sockaddr_in6); 00224 } 00225 } else { 00226 tr_error("Socket recv failed: socket:%d, err:%d", socket_id, data_len); 00227 data_len = (int16_t) FNET_ERR; 00228 } 00229 00230 return data_len; 00231 } 00232 00233 fnet_return_t fnet_socket_close(fnet_socket_t s) 00234 { 00235 int8_t socket_id = (int8_t)(long)s; 00236 00237 FNET_DEBUG("fnet_socket_close, socket:%d", socket_id); 00238 00239 socket_close(socket_id); 00240 00241 return FNET_OK; 00242 }
Generated on Tue Jul 12 2022 13:54:38 by
