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.
ns_fnet_port.c
00001 /* 00002 * Copyright (c) 2017, 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/address.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 } 00076 00077 FNET_DEBUG("fnet_netif_get_ip6_addr(), if=%d: %s", (int8_t)netif->scope_id, trace_ipv6(addr_info->address.addr)); 00078 00079 return result; 00080 } 00081 00082 fnet_bool_t fnet_netif_is_my_ip6_addr(fnet_netif_t *netif, const fnet_ip6_addr_t *ip_addr) 00083 { 00084 int i = 0; 00085 uint8_t address_buffer[16]; 00086 int8_t interface_id = (int8_t)netif->scope_id; 00087 int8_t addr_available = 0; 00088 00089 do { 00090 addr_available = arm_net_address_list_get_next(interface_id, &i, address_buffer); 00091 if (addr_available < 0) { 00092 return FNET_FALSE; 00093 } 00094 if (addr_ipv6_equal(address_buffer, ip_addr->addr)) { 00095 return FNET_TRUE; 00096 } 00097 } while (addr_available); 00098 00099 return FNET_FALSE; 00100 } 00101 00102 static void fnet_nanostack_port_ns_socket_recv(void *socket_cb) 00103 { 00104 (void)socket_cb; 00105 // socket event received, run service again to achieve faster response time 00106 ns_fnet_events_fast_poll(); 00107 } 00108 00109 fnet_socket_t fnet_socket(fnet_address_family_t family, fnet_socket_type_t type, fnet_uint32_t protocol) 00110 { 00111 int8_t socket_id = 0; 00112 (void)protocol; 00113 00114 if (type != SOCK_DGRAM || family != AF_INET6) { 00115 return FNET_NULL; 00116 } 00117 00118 socket_id = socket_open(SOCKET_UDP, 0, fnet_nanostack_port_ns_socket_recv); 00119 if (socket_id < 0) { 00120 return FNET_NULL; 00121 } 00122 00123 // Socket contains buffer for the received data, enable the feature using socket options 00124 static const int32_t rcvbuf_size = 1024*4; 00125 socket_setsockopt(socket_id, SOCKET_SOL_SOCKET, SOCKET_SO_RCVBUF, &rcvbuf_size, sizeof rcvbuf_size); 00126 00127 FNET_DEBUG("fnet_socket_open, socket:%d", socket_id); 00128 return (fnet_socket_t)(long)socket_id; 00129 } 00130 00131 fnet_return_t fnet_socket_bind( fnet_socket_t s, const struct sockaddr *name, fnet_size_t namelen ) 00132 { 00133 (void)namelen; 00134 ns_address_t ns_source_addr = {0}; 00135 int8_t socket_id = (int8_t)(long)s; 00136 fnet_return_t fnet_ret_val = FNET_ERR; 00137 const struct sockaddr_in6 *namein6 = (const struct sockaddr_in6 *) name; 00138 memcpy(ns_source_addr.address, &namein6->sin6_addr, 16); 00139 ns_source_addr.identifier = FNET_NTOHS(namein6->sin6_port); 00140 ns_source_addr.type = ADDRESS_IPV6; 00141 00142 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)); 00143 00144 int8_t status = socket_bind(socket_id, &ns_source_addr); 00145 if (status == 0) { 00146 fnet_ret_val = FNET_OK; 00147 } 00148 00149 return fnet_ret_val; 00150 } 00151 00152 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 ) 00153 { 00154 (void) level; 00155 (void) optvallen; 00156 int8_t socket_id; 00157 int8_t ret_val = -1; 00158 00159 socket_id = (int8_t)(long)s; 00160 00161 if (optname == IPV6_JOIN_GROUP) { 00162 const struct ipv6_mreq *mreq6 = optval; /* Multicast group information.*/ 00163 00164 int8_t interface_id = (int8_t)mreq6->ipv6imr_interface; // scope_id holds interface_id 00165 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &interface_id, sizeof(interface_id)); 00166 00167 if (ret_val == 0) { 00168 ns_ipv6_mreq_t ns_ipv6_mreq; 00169 ns_ipv6_mreq.ipv6mr_interface = interface_id; 00170 memcpy(ns_ipv6_mreq.ipv6mr_multiaddr, ADDR_LINK_LOCAL_MDNS, 16); 00171 // Join multicast group 00172 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_JOIN_GROUP, &ns_ipv6_mreq, sizeof(ns_ipv6_mreq)); 00173 } 00174 00175 if (ret_val == 0) { 00176 bool loopback = false; 00177 // Ignore loopback from own multicasts 00178 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_LOOP, &loopback, sizeof(loopback)); 00179 } 00180 } 00181 else if (optname == IPV6_MULTICAST_HOPS) { 00182 // Both FNET and Nanostack use int16_t, so can pass straight through 00183 ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, optval, optvallen); 00184 } 00185 00186 if (ret_val == 0) { 00187 return FNET_OK; 00188 } 00189 00190 return FNET_ERR; 00191 } 00192 00193 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 ) 00194 { 00195 (void)tolen; // ipv6 address expected 00196 (void)flags; // 00197 int8_t socket_id = (int8_t)(long)s; 00198 ns_address_t ns_address; 00199 00200 ns_address.type = ADDRESS_IPV6; 00201 memcpy(ns_address.address, &((struct sockaddr_in6 *)to)->sin6_addr.s6_addr, 16); 00202 // Note! Port is already in network byte order, transfer it back as nanostack will convert it again to network byte order 00203 ns_address.identifier = FNET_NTOHS(to->sa_port); 00204 FNET_DEBUG("fnet_socket_sendto, %d bytes, port:%d, socket:%d", (int)len, (int)ns_address.identifier, socket_id); 00205 return (fnet_int32_t)socket_sendto(socket_id, &ns_address, buf, len); 00206 } 00207 00208 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 ) 00209 { 00210 (void)flags; // mdns does not use flags 00211 (void)fromlen; // address is ipv6 00212 int8_t socket_id = (int8_t)(long)s; 00213 int16_t data_len; 00214 ns_address_t source_address; 00215 data_len = socket_read(socket_id, &source_address, buf, len); 00216 00217 if (data_len >= 0) { 00218 if (from) { 00219 struct sockaddr_in6 *fromin6 = (struct sockaddr_in6 *) from; 00220 memcpy(&fromin6->sin6_addr.s6_addr, source_address.address, 16); 00221 //addrin6.sin6_scope_id = interface_id; where to get interface_id here? 00222 fromin6->sin6_family = AF_INET6; 00223 // port is in native byte order,, convert to network byte order 00224 fromin6->sin6_port = FNET_HTONS(source_address.identifier); 00225 *fromlen = sizeof(struct sockaddr_in6); 00226 } 00227 } else { 00228 tr_error("Socket recv failed: socket:%d, err:%d", socket_id, data_len); 00229 data_len = (int16_t) FNET_ERR; 00230 } 00231 00232 return data_len; 00233 } 00234 00235 fnet_return_t fnet_socket_close( fnet_socket_t s ) 00236 { 00237 int8_t socket_id = (int8_t)(long)s; 00238 00239 FNET_DEBUG("fnet_socket_close, socket:%d", socket_id); 00240 00241 socket_close(socket_id); 00242 00243 return FNET_OK; 00244 }
Generated on Tue Jul 12 2022 18:18:45 by
