|
| 1 | +/* |
| 2 | + * Copyright (c) 2016-2018, Arm Limited and affiliates. |
| 3 | + * SPDX-License-Identifier: Apache-2.0 |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + */ |
| 17 | + |
| 18 | + |
| 19 | +#include "nsconfig.h" |
| 20 | +#include <string.h> |
| 21 | +#include "ns_types.h" |
| 22 | +#include "ns_list.h" |
| 23 | +#include "ns_trace.h" |
| 24 | +#include "nsdynmemLIB.h" |
| 25 | +#include "fhss_config.h" |
| 26 | +#include "NWK_INTERFACE/Include/protocol.h" |
| 27 | +#include "6LoWPAN/ws/ws_config.h" |
| 28 | +#include "Security/kmp/kmp.h" |
| 29 | + |
| 30 | +#include "mac_api.h" |
| 31 | +#include "mac_mcps.h" |
| 32 | + |
| 33 | +#include "Common_Protocols/ipv6_constants.h" |
| 34 | +#include "socket_api.h" |
| 35 | + |
| 36 | +#include "6LoWPAN/MAC/mac_helper.h" |
| 37 | +#include "6LoWPAN/MAC/mpx_api.h" |
| 38 | + |
| 39 | +#ifdef HAVE_WS |
| 40 | + |
| 41 | +#define TRACE_GROUP "wspsu" |
| 42 | + |
| 43 | +static void ws_eapol_relay_socket_cb(void *ptr); |
| 44 | +static void ws_eapol_relay_mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data); |
| 45 | +static void ws_eapol_relay_mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data); |
| 46 | +static void ws_eapol_relay_data_request_primitiv_set(mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur); |
| 47 | + |
| 48 | +typedef struct { |
| 49 | + protocol_interface_info_entry_t *interface_ptr; /**< List link entry */ |
| 50 | + int8_t relay_socket_id; /**< Socket ID for relay */ |
| 51 | + mpx_api_t *mpx_api; /**< mpx api */ |
| 52 | + uint16_t mpx_user_id; /**< mpx user identifier */ |
| 53 | +} eapol_relay_data_t; |
| 54 | + |
| 55 | +static eapol_relay_data_t *eapol_relay_data; |
| 56 | + |
| 57 | +void ws_eapol_relay_init(protocol_interface_info_entry_t *cur) |
| 58 | +{ |
| 59 | + if (!eapol_relay_data) { |
| 60 | + eapol_relay_data = ns_dyn_mem_alloc(sizeof(eapol_relay_data_t)); |
| 61 | + } |
| 62 | + eapol_relay_data->interface_ptr = cur; |
| 63 | + eapol_relay_data->relay_socket_id = socket_open(IPV6_NH_UDP, 10253, &ws_eapol_relay_socket_cb); |
| 64 | +} |
| 65 | + |
| 66 | +static void ws_eapol_relay_socket_cb(void *cb) |
| 67 | +{ |
| 68 | + if (!eapol_relay_data || !eapol_relay_data->mpx_api) { |
| 69 | + return; |
| 70 | + } |
| 71 | + |
| 72 | + socket_callback_t *cb_data = cb; |
| 73 | + |
| 74 | + mcps_data_req_t data_request; |
| 75 | + |
| 76 | + ws_eapol_relay_data_request_primitiv_set(&data_request, eapol_relay_data->interface_ptr); |
| 77 | + |
| 78 | + kmp_udp_pdu_t *pdu = ns_dyn_mem_temporary_alloc(cb_data->d_len); |
| 79 | + |
| 80 | + if (socket_recvfrom(cb_data->socket_id, pdu, cb_data->d_len, 0, 0) != cb_data->d_len) { |
| 81 | + ns_dyn_mem_free(pdu); |
| 82 | + return; |
| 83 | + } |
| 84 | + |
| 85 | + memcpy(data_request.DstAddr, pdu->eui_64, 8); |
| 86 | + |
| 87 | + data_request.msdu = &(pdu->kmp_id); |
| 88 | + data_request.msduLength = cb_data->d_len - 8; |
| 89 | + |
| 90 | + eapol_relay_data->mpx_api->mpx_data_request(eapol_relay_data->mpx_api, &data_request, eapol_relay_data->mpx_user_id); |
| 91 | + |
| 92 | + ns_dyn_mem_free(pdu); |
| 93 | +} |
| 94 | + |
| 95 | +static void ws_eapol_relay_data_request_primitiv_set(mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur) |
| 96 | +{ |
| 97 | + memset(dataReq, 0, sizeof(mcps_data_req_t)); |
| 98 | + |
| 99 | + dataReq->InDirectTx = false; |
| 100 | + dataReq->TxAckReq = true; |
| 101 | + dataReq->SrcAddrMode = ADDR_802_15_4_LONG; |
| 102 | + dataReq->DstAddrMode = ADDR_802_15_4_LONG; |
| 103 | + dataReq->DstPANId = mac_helper_panid_get(cur); |
| 104 | +} |
| 105 | + |
| 106 | +int8_t ws_eapol_relay_mpx_register(struct mpx_api_s *mpx_api, uint16_t mpx_user_id) |
| 107 | +{ |
| 108 | + eapol_relay_data->mpx_api = mpx_api; |
| 109 | + eapol_relay_data->mpx_user_id = mpx_user_id; |
| 110 | + |
| 111 | + if (eapol_relay_data->mpx_api) { |
| 112 | + eapol_relay_data->mpx_api->mpx_user_registration(eapol_relay_data->mpx_api, ws_eapol_relay_mpx_data_confirm, ws_eapol_relay_mpx_data_indication, eapol_relay_data->mpx_user_id); |
| 113 | + } |
| 114 | + return 0; |
| 115 | +} |
| 116 | + |
| 117 | +static void ws_eapol_relay_mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data) |
| 118 | +{ |
| 119 | + (void) api; |
| 120 | + (void) data; |
| 121 | +} |
| 122 | + |
| 123 | +static void ws_eapol_relay_mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data) |
| 124 | +{ |
| 125 | + (void) api; |
| 126 | + |
| 127 | + if (!data || !data->msduLength || !data->msdu_ptr) { |
| 128 | + return; |
| 129 | + } |
| 130 | + |
| 131 | + ns_address_t dest_addr; |
| 132 | + if (addr_interface_get_ll_address(eapol_relay_data->interface_ptr, &dest_addr.address[0], 1) < 0) { |
| 133 | + return; |
| 134 | + } |
| 135 | + dest_addr.type = ADDRESS_IPV6; |
| 136 | + dest_addr.identifier = 10254; |
| 137 | + |
| 138 | + kmp_udp_pdu_t *pdu = ns_dyn_mem_temporary_alloc(8 + data->msduLength); |
| 139 | + memcpy(&pdu->eui_64[0], &data->SrcAddr[0], 8); |
| 140 | + memcpy(&pdu->kmp_id, data->msdu_ptr, data->msduLength); |
| 141 | + |
| 142 | + socket_sendto(eapol_relay_data->relay_socket_id , &dest_addr, pdu, 8 + data->msduLength); |
| 143 | + |
| 144 | + ns_dyn_mem_free(pdu); |
| 145 | +} |
| 146 | + |
| 147 | +#endif /* HAVE_WS */ |
| 148 | + |
0 commit comments