Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kmp_socket_if.c Source File

kmp_socket_if.c

00001 /*
00002  * Copyright (c) 2016-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 #include "nsconfig.h"
00019 #include <string.h>
00020 #include "ns_types.h"
00021 #include "ns_list.h"
00022 #include "ns_trace.h"
00023 #include "ns_address.h"
00024 #include "nsdynmemLIB.h"
00025 #include "eventOS_event.h"
00026 #include "eventOS_scheduler.h"
00027 #include "eventOS_event_timer.h"
00028 #include "NWK_INTERFACE/Include/protocol.h"
00029 #include "Common_Protocols/ipv6_constants.h"
00030 #include "socket_api.h"
00031 #include "6LoWPAN/ws/ws_config.h"
00032 #include "Security/kmp/kmp_addr.h"
00033 #include "Security/kmp/kmp_api.h"
00034 #include "Security/kmp/kmp_socket_if.h"
00035 #include "common_functions.h"
00036 
00037 #ifdef HAVE_WS
00038 
00039 #define TRACE_GROUP "kmsi"
00040 
00041 #define SOCKET_IF_HEADER_SIZE    27
00042 
00043 typedef struct {
00044     kmp_service_t *kmp_service;                       /**< KMP service */
00045     ns_address_t remote_addr;                         /**< Remote address */
00046     int8_t socket_id;                                 /**< Socket ID */
00047     ns_list_link_t link;                              /**< Link */
00048 } kmp_socket_if_t;
00049 
00050 static int8_t kmp_socket_if_send(kmp_service_t *service, kmp_type_e kmp_id, const kmp_addr_t *addr, void *pdu, uint16_t size, uint8_t tx_identifier);
00051 static void kmp_socket_if_socket_cb(void *ptr);
00052 
00053 static NS_LIST_DEFINE(kmp_socket_if_list, kmp_socket_if_t, link);
00054 
00055 int8_t kmp_socket_if_register(kmp_service_t *service, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
00056 {
00057     if (!service || !remote_addr) {
00058         return -1;
00059     }
00060 
00061     ns_list_foreach(kmp_socket_if_t, entry, &kmp_socket_if_list) {
00062         if (entry->kmp_service == service) {
00063             return -1;
00064         }
00065     }
00066 
00067     kmp_socket_if_t *socket_if = ns_dyn_mem_alloc(sizeof(kmp_socket_if_t));
00068     if (!socket_if) {
00069         return -1;
00070     }
00071 
00072     socket_if->kmp_service = service;
00073 
00074     socket_if->remote_addr.type = ADDRESS_IPV6;
00075     memcpy(&socket_if->remote_addr.address, remote_addr, 16);
00076     socket_if->remote_addr.identifier = remote_port;
00077 
00078     socket_if->socket_id = socket_open(IPV6_NH_UDP, local_port, &kmp_socket_if_socket_cb);
00079     if (socket_if->socket_id < 0) {
00080         ns_dyn_mem_free(socket_if);
00081         return -1;
00082     }
00083 
00084     if (kmp_service_msg_if_register(service, kmp_socket_if_send, SOCKET_IF_HEADER_SIZE) < 0) {
00085         ns_dyn_mem_free(socket_if);
00086         return -1;
00087     }
00088 
00089     ns_list_add_to_end(&kmp_socket_if_list, socket_if);
00090 
00091     return 0;
00092 }
00093 
00094 int8_t kmp_socket_if_unregister(kmp_service_t *service)
00095 {
00096     if (!service) {
00097         return -1;
00098     }
00099 
00100     ns_list_foreach_safe(kmp_socket_if_t, entry, &kmp_socket_if_list) {
00101         if (entry->kmp_service == service) {
00102             ns_list_remove(&kmp_socket_if_list, entry);
00103             socket_close(entry->socket_id);
00104             ns_dyn_mem_free(entry);
00105             kmp_service_msg_if_register(service, NULL, 0);
00106         }
00107     }
00108     return 0;
00109 }
00110 
00111 static int8_t kmp_socket_if_send(kmp_service_t *service, kmp_type_e kmp_id, const kmp_addr_t *addr, void *pdu, uint16_t size, uint8_t tx_identifier)
00112 {
00113     (void) tx_identifier;
00114 
00115     if (!service || !pdu || !addr) {
00116         return -1;
00117     }
00118 
00119     kmp_socket_if_t *socket_if = NULL;
00120 
00121     ns_list_foreach(kmp_socket_if_t, entry, &kmp_socket_if_list) {
00122         if (entry->kmp_service == service) {
00123             socket_if = entry;
00124             break;
00125         }
00126     }
00127 
00128     if (!socket_if) {
00129         return -1;
00130     }
00131 
00132     //Build UPD Relay
00133     uint8_t *ptr = pdu;
00134     memcpy(ptr, addr->relay_address, 16);
00135     ptr += 16;
00136     ptr = common_write_16_bit(addr->port, ptr);
00137     memcpy(ptr, kmp_address_eui_64_get(addr), 8);
00138     ptr += 8;
00139     *ptr = kmp_id;
00140 
00141     socket_sendto(socket_if->socket_id, &socket_if->remote_addr, pdu, size);
00142     ns_dyn_mem_free(pdu);
00143 
00144     return 0;
00145 }
00146 
00147 static void kmp_socket_if_socket_cb(void *ptr)
00148 {
00149     socket_callback_t *cb_data = ptr;
00150 
00151     if (cb_data->event_type != SOCKET_DATA) {
00152         return;
00153     }
00154 
00155     kmp_socket_if_t *socket_if = NULL;
00156 
00157     ns_list_foreach(kmp_socket_if_t, entry, &kmp_socket_if_list) {
00158         if (entry->socket_id == cb_data->socket_id) {
00159             socket_if = entry;
00160             break;
00161         }
00162     }
00163 
00164     if (!socket_if) {
00165         return;
00166     }
00167 
00168     uint8_t *pdu = ns_dyn_mem_temporary_alloc(cb_data->d_len);
00169 
00170     if (socket_recvfrom(cb_data->socket_id, pdu, cb_data->d_len, 0, 0) != cb_data->d_len) {
00171         ns_dyn_mem_free(pdu);
00172         return;
00173     }
00174     kmp_addr_t addr;
00175     addr.type = KMP_ADDR_EUI_64_AND_IP;
00176 
00177     uint8_t *data_ptr = pdu;
00178     memcpy(addr.relay_address, data_ptr, 16);
00179     data_ptr += 16;
00180     addr.port = common_read_16_bit(data_ptr);
00181     data_ptr += 2;
00182     memcpy(addr.eui_64, data_ptr, 8);
00183     data_ptr += 8;
00184 
00185     kmp_type_e type = kmp_api_type_from_id_get(*data_ptr++);
00186     if (type == KMP_TYPE_NONE) {
00187         ns_dyn_mem_free(pdu);
00188         return;
00189     }
00190 
00191 
00192     kmp_service_msg_if_receive(socket_if->kmp_service, type, &addr, data_ptr, cb_data->d_len - 27);
00193 
00194     ns_dyn_mem_free(pdu);
00195 }
00196 
00197 #endif /* HAVE_WS */
00198