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_mdns_api.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 #include "fnet.h" 00019 #include "fnet_netif_prv.h" 00020 00021 #include "ns_types.h" 00022 #include "ns_list.h" 00023 #include "nsdynmemLIB.h" 00024 #include "ns_mdns_api.h" 00025 #include "ns_fnet_events.h" 00026 #include "common_functions.h" // common_write 00027 #include "ns_trace.h" 00028 00029 #define TRACE_GROUP "mDNS" 00030 00031 /* Structure for list of services */ 00032 typedef struct { 00033 fnet_mdns_service_t service_opt; // service options holding service parameters 00034 fnet_mdns_service_desc_t service_desc; // service descriptor received from fnet 00035 ns_list_link_t link; 00036 } ns_mdns_service_entry_t; 00037 00038 typedef NS_LIST_HEAD (ns_mdns_service_entry_t, link) ns_mdns_service_entry_list; 00039 00040 /* Structure for list of servers */ 00041 typedef struct { 00042 fnet_netif_t *ns_netif; // network interface 00043 fnet_mdns_desc_t mdns_desc; // server descriptor from fnet 00044 ns_mdns_service_entry_list service_list; // list of services added to this server 00045 ns_list_link_t link; 00046 } ns_mdns_server_entry_t; 00047 00048 static NS_LIST_DEFINE(server_list, ns_mdns_server_entry_t, link); 00049 00050 /* 00051 * Find service_entry from a server list based on service_descriptor 00052 */ 00053 static ns_mdns_service_entry_t* ns_mdns_service_entry_find(fnet_mdns_service_desc_t service_desc) 00054 { 00055 ns_list_foreach(ns_mdns_server_entry_t, cur_server_entry_ptr, &server_list) { 00056 ns_list_foreach(ns_mdns_service_entry_t, cur_service__entry_ptr, &cur_server_entry_ptr->service_list) { 00057 if (cur_service__entry_ptr->service_desc == service_desc ) { 00058 return cur_service__entry_ptr; 00059 } 00060 } 00061 } 00062 return NULL; 00063 } 00064 00065 /* 00066 * Find server_entry based on service_entry 00067 */ 00068 static ns_mdns_server_entry_t* ns_mdns_server_entry_find_by_service(ns_mdns_service_entry_t *service_entry) 00069 { 00070 ns_list_foreach(ns_mdns_server_entry_t, cur_server_entry_ptr, &server_list) { 00071 ns_list_foreach(ns_mdns_service_entry_t, cur_service_entry_ptr, &cur_server_entry_ptr->service_list) { 00072 if (cur_service_entry_ptr == service_entry ) { 00073 return cur_server_entry_ptr; 00074 } 00075 } 00076 } 00077 return NULL; 00078 } 00079 00080 /* 00081 * Find server entry based on server_descriptor 00082 */ 00083 static ns_mdns_server_entry_t* ns_mdns_server_entry_find(fnet_mdns_desc_t mdns_desc) 00084 { 00085 ns_list_foreach(ns_mdns_server_entry_t, cur_server__entry_ptr, &server_list) { 00086 if (cur_server__entry_ptr->mdns_desc == mdns_desc ) { 00087 return cur_server__entry_ptr; 00088 } 00089 } 00090 return NULL; 00091 } 00092 00093 static ns_mdns_service_entry_t* ns_mdns_service_entry_create(ns_mdns_server_entry_t *server_entry, ns_mdns_service_param_t *service) 00094 { 00095 if (!service || !service->service_type || !service->service_get_txt || !server_entry) { 00096 return NULL; 00097 } 00098 00099 ns_mdns_service_entry_t *mdns_service = ns_dyn_mem_alloc(sizeof(ns_mdns_service_entry_t)); 00100 if (!mdns_service) { 00101 return NULL; 00102 } 00103 mdns_service->service_opt.service_type = ns_dyn_mem_alloc(strlen(service->service_type) + 1); 00104 if (!mdns_service->service_opt.service_type) { 00105 ns_dyn_mem_free(mdns_service); 00106 return NULL; 00107 } 00108 strcpy((char*)mdns_service->service_opt.service_type, service->service_type); 00109 // change port to be in network byte order 00110 mdns_service->service_opt.service_port = FNET_HTONS(service->service_port); 00111 mdns_service->service_opt.service_get_txt = service->service_get_txt; 00112 00113 ns_list_add_to_end(&server_entry->service_list, mdns_service); 00114 return mdns_service; 00115 } 00116 00117 /* 00118 * Free service entry and remove it from the list 00119 */ 00120 static void ns_mdns_service_entry_free(ns_mdns_server_entry_t *server_entry, ns_mdns_service_entry_t *service_entry) 00121 { 00122 if (service_entry) { 00123 ns_list_remove(&server_entry->service_list, service_entry); 00124 ns_dyn_mem_free((void*)service_entry->service_opt.service_type); 00125 ns_dyn_mem_free(service_entry); 00126 } 00127 } 00128 00129 ns_mdns_t ns_mdns_server_start(const char *server_name, uint32_t ttl, uint32_t ttl_ip, int8_t interface_id) 00130 { 00131 FNET_DEBUG("ns_mdns_server_start(), interface=%d", interface_id); 00132 struct fnet_mdns_params params; 00133 fnet_netif_t *ns_netif; 00134 ns_mdns_server_entry_t *server_entry; 00135 fnet_mdns_desc_t mdns_desc; 00136 00137 if (interface_id < 0) { 00138 return NULL; 00139 } 00140 00141 server_entry = ns_dyn_mem_alloc(sizeof(ns_mdns_server_entry_t)); 00142 if (!server_entry) { 00143 return NULL; 00144 } 00145 00146 ns_netif = ns_dyn_mem_alloc(sizeof(fnet_netif_t)); 00147 if (!ns_netif) { 00148 ns_dyn_mem_free(server_entry); 00149 return NULL; 00150 } 00151 ns_netif->scope_id = interface_id; 00152 server_entry->ns_netif = ns_netif; 00153 00154 params.netif_desc = (fnet_mdns_desc_t)ns_netif; 00155 params.name = server_name; 00156 params.rr_ttl = ttl; 00157 params.rr_ttl_ip = ttl_ip; 00158 params.addr_family = AF_INET6; 00159 00160 ns_fnet_events_start(); 00161 00162 /* Start mDNS server */ 00163 mdns_desc = fnet_mdns_init(¶ms); 00164 if (!mdns_desc) { 00165 ns_dyn_mem_free(ns_netif); 00166 ns_dyn_mem_free(server_entry); 00167 tr_error("mdns init failure"); 00168 return NULL; 00169 } 00170 00171 server_entry->mdns_desc = mdns_desc; 00172 00173 ns_list_init(&server_entry->service_list); 00174 ns_list_add_to_end(&server_list, server_entry); 00175 return mdns_desc; 00176 } 00177 00178 void ns_mdns_server_stop(ns_mdns_t ns_mdns) 00179 { 00180 FNET_DEBUG("ns_mdns_server_stop()"); 00181 ns_mdns_server_entry_t *server_entry; 00182 00183 server_entry = ns_mdns_server_entry_find(ns_mdns); 00184 if (server_entry) { 00185 fnet_mdns_release((fnet_mdns_desc_t)ns_mdns); 00186 ns_list_remove(&server_list, server_entry); 00187 00188 ns_list_foreach_safe(ns_mdns_service_entry_t, cur_service_entry_ptr, &server_entry->service_list) { 00189 // free all services from the current server 00190 ns_mdns_service_entry_free(server_entry, cur_service_entry_ptr); 00191 } 00192 00193 ns_dyn_mem_free(server_entry->ns_netif); 00194 ns_dyn_mem_free(server_entry); 00195 } 00196 00197 if (ns_list_is_empty(&server_list)) { 00198 // No more servers in the system, stop events 00199 ns_fnet_events_stop(); 00200 } 00201 } 00202 00203 ns_mdns_service_t ns_mdns_service_register(ns_mdns_t ns_mdns, ns_mdns_service_param_t *service) 00204 { 00205 ns_mdns_server_entry_t *server_entry = ns_mdns_server_entry_find(ns_mdns); 00206 ns_mdns_service_entry_t *mdns_service_entry = ns_mdns_service_entry_create(server_entry, service); 00207 00208 if (!mdns_service_entry) { 00209 tr_error("Failed to create service entry"); 00210 return NULL; 00211 } 00212 00213 mdns_service_entry->service_desc = fnet_mdns_service_register((fnet_mdns_desc_t)ns_mdns, &mdns_service_entry->service_opt); 00214 return mdns_service_entry->service_desc; 00215 } 00216 00217 void ns_mdns_service_unregister(ns_mdns_service_t service_desc) 00218 { 00219 ns_mdns_service_entry_t *service_entry; 00220 ns_mdns_server_entry_t *server_entry; 00221 00222 // find service from a server 00223 service_entry = ns_mdns_service_entry_find(service_desc); 00224 // find server that holds current server 00225 server_entry = ns_mdns_server_entry_find_by_service(service_entry); 00226 if (service_entry && server_entry) { 00227 fnet_mdns_service_unregister(service_desc); 00228 ns_mdns_service_entry_free(server_entry, service_entry); 00229 } 00230 } 00231 00232 void ns_mdns_announcement_send(ns_mdns_t ns_mdns) 00233 { 00234 FNET_DEBUG("ns_mdns_announcement_send()"); 00235 if (ns_mdns_server_entry_find(ns_mdns)) { 00236 fnet_mdns_announce((fnet_mdns_desc_t)ns_mdns); 00237 } 00238 }
Generated on Tue Jul 12 2022 12:45:37 by
