diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..3755d7582 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,19 @@ +# YAML -*- mode: yaml; tab-width: 2; indent-tabs-mode: nil; coding: utf-8 -*- +# SPDX-License-Identifier: LicenseRef-MSLA +# SPDX-Copyright-Text: (c) 2024 Silicon Laboratories Inc. (www.silabs.com) +--- +name: Docker Image CI + +on: # yamllint disable-line rule:truthy + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + - name: Build Docker image from sources + run: docker build . diff --git a/6lbr/6lowpan/lowpan_adaptation_interface.c b/6lbr/6lowpan/lowpan_adaptation_interface.c index 8be00e123..2fb17b755 100644 --- a/6lbr/6lowpan/lowpan_adaptation_interface.c +++ b/6lbr/6lowpan/lowpan_adaptation_interface.c @@ -774,9 +774,8 @@ int8_t lowpan_adaptation_interface_tx(struct net_if *cur, buffer_t *buf) if (fragmented_needed) { //Fragmentation init if (lowpan_message_fragmentation_init(buf, tx_ptr, cur, interface_ptr)) { - tr_error("Fragment init fail"); - tx_ptr->buf = NULL; - goto tx_error_handler; + lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr); + return -1; } tx_ptr->tag = interface_ptr->local_frag_tag++; diff --git a/6lbr/6lowpan/lowpan_mtu.h b/6lbr/6lowpan/lowpan_mtu.h index 15081f13c..87510e57e 100644 --- a/6lbr/6lowpan/lowpan_mtu.h +++ b/6lbr/6lowpan/lowpan_mtu.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/commandline.c b/6lbr/app/commandline.c index 96aba8073..a43fb2600 100644 --- a/6lbr/app/commandline.c +++ b/6lbr/app/commandline.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -145,6 +146,7 @@ static const int valid_ws_chan_plan_ids[] = { 0x70, 0x71, // WW 0x80, // CN 0x90, // CN + 0xa0, // CN INT_MIN }; @@ -444,6 +446,13 @@ static void conf_set_key(struct wsbrd_conf *config, const struct storage_parse_i dest->key_len = ret; } +static void conf_set_eui64(struct wsbrd_conf *config, const struct storage_parse_info *info, void *raw_dest, const void *raw_param) +{ + BUG_ON(raw_param); + if (parse_byte_array(raw_dest, 8, info->value)) + FATAL(1, "%s:%d: invalid key: %s", info->filename, info->linenr, info->value); +} + static void conf_set_allowed_macaddr(struct wsbrd_conf *config, const struct storage_parse_info *info, void *raw_dest, const void *raw_param) { BUG_ON(raw_param); @@ -545,6 +554,7 @@ static void parse_config_line(struct wsbrd_conf *config, struct storage_parse_in { "lgtk_new_activation_time", &config->ws_lgtk_new_activation_time, conf_set_number, &valid_positive }, { "lgtk_new_install_required", &config->ws_lgtk_new_install_required, conf_set_number, &valid_gtk_new_install_required }, { "lfn_revocation_lifetime_reduction", &config->ws_lfn_revocation_lifetime_reduction, conf_set_number, &valid_unsigned }, + { "mac_address", config->ws_mac_address, conf_set_eui64, NULL }, { "allowed_mac64", config->ws_allowed_mac_addresses, conf_set_allowed_macaddr, NULL }, { "denied_mac64", config->ws_denied_mac_addresses, conf_set_denied_macaddr, NULL }, { "async_frag_duration", &config->ws_async_frag_duration, conf_set_number, &valid_async_frag_duration }, @@ -653,6 +663,7 @@ void parse_commandline(struct wsbrd_conf *config, int argc, char *argv[], config->rpl_compat = true; config->rpl_rpi_ignorable = false; strcpy(config->storage_prefix, "/var/lib/wsbrd/"); + memset(config->ws_mac_address, 0xff, sizeof(config->ws_mac_address)); memset(config->ws_allowed_channels, 0xFF, sizeof(config->ws_allowed_channels)); while ((opt = getopt_long(argc, argv, opts_short, opts_long, NULL)) != -1) { switch (opt) { diff --git a/6lbr/app/commandline.h b/6lbr/app/commandline.h index d3cc56218..2e940fbcb 100644 --- a/6lbr/app/commandline.h +++ b/6lbr/app/commandline.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -98,6 +99,7 @@ struct wsbrd_conf { bool rpl_rpi_ignorable; unsigned int ws_join_metrics; + uint8_t ws_mac_address[8]; uint8_t ws_allowed_mac_addresses[10][8]; uint8_t ws_allowed_mac_address_count; uint8_t ws_denied_mac_addresses[10][8]; diff --git a/6lbr/app/commandline_values.c b/6lbr/app/commandline_values.c index 226433523..2d75bb817 100644 --- a/6lbr/app/commandline_values.c +++ b/6lbr/app/commandline_values.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/commandline_values.h b/6lbr/app/commandline_values.h index 2549b9439..a69a235c6 100644 --- a/6lbr/app/commandline_values.h +++ b/6lbr/app/commandline_values.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/dbus.c b/6lbr/app/dbus.c index 7670353fa..a2657d2bd 100644 --- a/6lbr/app/dbus.c +++ b/6lbr/app/dbus.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -358,6 +359,7 @@ static int dbus_ie_custom_insert(sd_bus_message *m, void *userdata, sd_bus_error case WS_FT_PA: case WS_FT_PC: case WS_FT_EAPOL: + case WS_FT_DATA: case WS_FT_LPA: case WS_FT_LPC: break; @@ -648,6 +650,7 @@ int dbus_get_routing_graph(sd_bus *bus, const char *path, const char *interface, struct wsbr_ctxt *ctxt = userdata; struct rpl_target target_br = { }; struct rpl_target *target; + struct ws_neigh *ws_neigh; sd_bus_message_open_container(reply, 'a', "(aybaay)"); @@ -665,6 +668,10 @@ int dbus_get_routing_graph(sd_bus *bus, const char *path, const char *interface, continue; if (rpl_target_get(&ctxt->net_if.rpl_root, ipv6_neigh->ip_address)) continue; + ws_neigh = ws_neigh_get(&ctxt->net_if.ws_info.neighbor_storage, + ipv6_neighbour_eui64(&ctxt->net_if.ipv6_neighbour_cache, ipv6_neigh)); + if (!ws_neigh || ws_neigh->node_role != WS_NR_ROLE_LFN) + continue; dbus_message_append_ipv6_neigh(reply, ipv6_neigh, &ctxt->net_if.rpl_root); } diff --git a/6lbr/app/dbus.h b/6lbr/app/dbus.h index 0c2b11ba4..c69464196 100644 --- a/6lbr/app/dbus.h +++ b/6lbr/app/dbus.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/drop_privileges.c b/6lbr/app/drop_privileges.c index 49245032d..1c7c093be 100644 --- a/6lbr/app/drop_privileges.c +++ b/6lbr/app/drop_privileges.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/drop_privileges.h b/6lbr/app/drop_privileges.h index 10204ed86..8a658cd04 100644 --- a/6lbr/app/drop_privileges.h +++ b/6lbr/app/drop_privileges.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/frame_helpers.c b/6lbr/app/frame_helpers.c index 848f12a41..1aa86ef15 100644 --- a/6lbr/app/frame_helpers.c +++ b/6lbr/app/frame_helpers.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -45,10 +46,6 @@ #define IEEE802154_SECURITY_FRAME_COUNT_SUPPR 0b00100000 #define IEEE802154_SECURITY_ASN_IN_NONCE 0b01000000 -// IEEE 802.15.4-2020 Table 7-1 Values of the Frame Type field -#define IEEE802154_FRAME_TYPE_DATA 0b001 -#define IEEE802154_FRAME_TYPE_ACK 0b010 - // IEEE 802.15.4-2020 Figure 7-21 Format of Header IEs #define IEEE802154_HEADER_IE_LEN_MASK 0b0000000001111111 #define IEEE802154_HEADER_IE_ID_MASK 0b0111111110000000 @@ -111,64 +108,6 @@ static const struct { { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_16_BIT, true, false, 1 }, }; -int wsbr_data_ind_rebuild(uint8_t frame[], - const struct mcps_data_ind *ind, - const struct mcps_data_rx_ie_list *ie) -{ - uint8_t *start = frame; - uint16_t fcf; - int i; - - BUG_ON(ind->msduLength); - fcf = FIELD_PREP(IEEE802154_FCF_FRAME_TYPE, IEEE802154_FRAME_TYPE_DATA) - | FIELD_PREP(IEEE802154_FCF_SECURITY_ENABLED, false) - | FIELD_PREP(IEEE802154_FCF_FRAME_PENDING, ind->PendingBit) - | FIELD_PREP(IEEE802154_FCF_ACK_REQ, ind->TxAckReq) - | FIELD_PREP(IEEE802154_FCF_PAN_ID_COMPRESSION, ind->PanIdSuppressed) - | FIELD_PREP(IEEE802154_FCF_SEQ_NUM_SUPPR, ind->DSN_suppressed) - | FIELD_PREP(IEEE802154_FCF_IE_PRESENT, ie->headerIeListLength || ie->payloadIeListLength) - | FIELD_PREP(IEEE802154_FCF_DST_ADDR_MODE, ind->DstAddrMode) - | FIELD_PREP(IEEE802154_FCF_FRAME_VERSION, MAC_FRAME_VERSION_2015) - | FIELD_PREP(IEEE802154_FCF_SRC_ADDR_MODE, ind->SrcAddrMode); - frame = write_le16(frame, fcf); - if (!ind->DSN_suppressed) - *frame++ = ind->DSN; - - for (i = 0; i < ARRAY_SIZE(ieee802154_table_pan_id_comp); i++) - if (ieee802154_table_pan_id_comp[i].dst_addr_mode == ind->DstAddrMode && - ieee802154_table_pan_id_comp[i].src_addr_mode == ind->SrcAddrMode && - ieee802154_table_pan_id_comp[i].pan_id_compression == ind->PanIdSuppressed) - break; - BUG_ON(i == ARRAY_SIZE(ieee802154_table_pan_id_comp), "invalid address mode"); - if (ieee802154_table_pan_id_comp[i].dst_pan_id) - frame = write_le16(frame, ind->DstPANId); - if (ind->DstAddrMode == MAC_ADDR_MODE_64_BIT) { - memrcpy(frame, ind->DstAddr, 8); - frame += 8; - } else if (ind->DstAddrMode == MAC_ADDR_MODE_16_BIT) { - memrcpy(frame, ind->DstAddr, 2); - frame += 2; - } - if (ieee802154_table_pan_id_comp[i].src_pan_id) - frame = write_le16(frame, ind->SrcPANId); - if (ind->SrcAddrMode == MAC_ADDR_MODE_64_BIT) { - memrcpy(frame, ind->SrcAddr, 8); - frame += 8; - } else if (ind->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { - memrcpy(frame, ind->SrcAddr, 2); - frame += 2; - } - - memcpy(frame, ie->headerIeList, ie->headerIeListLength); - frame += ie->headerIeListLength; - if (ie->payloadIeListLength) - frame = write_le16(frame, IEEE802154_IE_HT1); - memcpy(frame, ie->payloadIeList, ie->payloadIeListLength); - frame += ie->payloadIeListLength; - - return frame - start; -} - static int wsbr_data_sec_parse(struct iobuf_read *iobuf, struct mlme_security *sec) { uint8_t scf; diff --git a/6lbr/app/frame_helpers.h b/6lbr/app/frame_helpers.h index 64834c362..3e7c31b40 100644 --- a/6lbr/app/frame_helpers.h +++ b/6lbr/app/frame_helpers.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -20,16 +21,10 @@ struct iobuf_write; struct rcp; struct arm_15_4_mac_parameters; struct mcps_data_cnf; -struct mcps_data_ind; struct mcps_data_rx_ie_list; struct mcps_data_req; struct mcps_data_req_ie_list; -// FIXME: Unify prototypes of wsbr_data_ind_rebuild() and wsbr_data_req_rebuild() -int wsbr_data_ind_rebuild(uint8_t frame[], - const struct mcps_data_ind *ind, - const struct mcps_data_rx_ie_list *ie); - void wsbr_data_req_rebuild(struct iobuf_write *frame, const struct rcp *rcp, const struct mcps_data_req *req, diff --git a/6lbr/app/libwsbrd.h b/6lbr/app/libwsbrd.h index 86a3ba55d..203d3bb66 100644 --- a/6lbr/app/libwsbrd.h +++ b/6lbr/app/libwsbrd.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/mbedtls_config_check.c b/6lbr/app/mbedtls_config_check.c index 03596811b..6f4a6222e 100644 --- a/6lbr/app/mbedtls_config_check.c +++ b/6lbr/app/mbedtls_config_check.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/mbedtls_config_check.h b/6lbr/app/mbedtls_config_check.h index 141d4ca8a..75006226f 100644 --- a/6lbr/app/mbedtls_config_check.h +++ b/6lbr/app/mbedtls_config_check.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/rail_config.c b/6lbr/app/rail_config.c index e17a3ce7a..480d77bd2 100644 --- a/6lbr/app/rail_config.c +++ b/6lbr/app/rail_config.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -83,15 +84,17 @@ static void rail_fill_pom_auto(struct wsbr_ctxt *ctxt) rail_fill_pom_disabled(ctxt); return; } - i = 1; + i = 0; phy_config->rcp_rail_config_index = base_rail_params->index; - phy_config->phy_op_modes[0] = ctxt->config.ws_phy_mode_id; for (rail_params = ctxt->rcp.rail_config_list; rail_params->chan0_freq; rail_params++) { for (chan_params = chan_params_table; chan_params->chan0_freq; chan_params++) { for (phy_mode = chan_params->valid_phy_modes; *phy_mode; phy_mode++) { phy_params = ws_regdb_phy_params(*phy_mode, 0); if (i >= ARRAY_SIZE(phy_config->phy_op_modes) - 1) continue; + // Ignore base mode + if (phy_params->phy_mode_id == ctxt->config.ws_phy_mode_id) + continue; // Ignore FAN1.0 if (!chan_params->chan_plan_id) continue; @@ -132,11 +135,12 @@ static void rail_fill_pom_manual(struct wsbr_ctxt *ctxt) // any group if (!base_rail_params->phy_mode_group) continue; - i = 1; + i = 0; phy_config->rcp_rail_config_index = base_rail_params->index; - phy_config->phy_op_modes[0] = ctxt->config.ws_phy_mode_id; for (phy_mode = ctxt->config.ws_phy_op_modes; *phy_mode; phy_mode++) { phy_params = ws_regdb_phy_params(*phy_mode, 0); + if (phy_params->phy_mode_id == ctxt->config.ws_phy_mode_id) + WARN("base \"phy_mode_id\" should not be present in \"phy_operating_modes\""); found = 0; if (base_phy_params->modulation == MODULATION_OFDM && base_phy_params->rail_phy_mode_id != phy_params->rail_phy_mode_id) diff --git a/6lbr/app/rail_config.h b/6lbr/app/rail_config.h index 5ecfa9b99..ab44ba041 100644 --- a/6lbr/app/rail_config.h +++ b/6lbr/app/rail_config.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/rcp_api.c b/6lbr/app/rcp_api.c index 22fb0b143..d6f520fbc 100644 --- a/6lbr/app/rcp_api.c +++ b/6lbr/app/rcp_api.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -85,6 +86,11 @@ static void rcp_ind_fatal(struct rcp *rcp, struct iobuf_read *buf) msg = hif_pop_str(buf); BUG_ON(buf->err); + // CRC errors can happen during init if a previous frame transmission was + // interrupted. + if (err == HIF_ECRC && !rcp->has_reset) + return; + if (msg) FATAL(3, "rcp error %s: %s", hif_fatal_str(err), msg); else @@ -497,6 +503,18 @@ void rcp_set_filter_src64(struct rcp *rcp, const uint8_t eui64[][8], uint8_t cou iobuf_free(&buf); } +void rcp_set_filter_dst64(struct rcp *rcp, const uint8_t eui64[8]) +{ + struct iobuf_write buf = { }; + + memcpy(&rcp->eui64, eui64, 8); + + hif_push_u8(&buf, HIF_CMD_SET_FILTER_DST64); + hif_push_fixed_u8_array(&buf, eui64, 8); + rcp_tx(rcp, &buf); + iobuf_free(&buf); +} + struct rcp_cmd rcp_cmd_table[] = { { HIF_CMD_IND_NOP, rcp_ind_nop }, { HIF_CMD_IND_RESET, rcp_ind_reset }, diff --git a/6lbr/app/rcp_api.h b/6lbr/app/rcp_api.h index 53c228b9c..4d6380e66 100644 --- a/6lbr/app/rcp_api.h +++ b/6lbr/app/rcp_api.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -90,6 +91,7 @@ void rcp_set_filter_src64(struct rcp *rcp, const uint8_t eui64[][8], uint8_t count, bool allow); +void rcp_set_filter_dst64(struct rcp *rcp, const uint8_t eui64[8]); // Exported for wsbrd-fuzz struct rcp_cmd { diff --git a/6lbr/app/rcp_api_legacy.h b/6lbr/app/rcp_api_legacy.h index 4f2cd11c4..ce4dc2a43 100644 --- a/6lbr/app/rcp_api_legacy.h +++ b/6lbr/app/rcp_api_legacy.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/timers.c b/6lbr/app/timers.c index 44b94ebbf..005160f51 100644 --- a/6lbr/app/timers.c +++ b/6lbr/app/timers.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/timers.h b/6lbr/app/timers.h index cfefd387c..cf6bb6cd7 100644 --- a/6lbr/app/timers.h +++ b/6lbr/app/timers.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/tun.c b/6lbr/app/tun.c index 81928b0ad..57e4ea66b 100644 --- a/6lbr/app/tun.c +++ b/6lbr/app/tun.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -138,8 +139,9 @@ void tun_add_node_to_proxy_neightbl(struct net_if *if_entry, const uint8_t addre src_ipv6_nl_addr = nl_addr_build(AF_INET6, address, 16); FATAL_ON(!src_ipv6_nl_addr, 2, "nl_addr_build: %s", strerror(ENOMEM)); nl_neigh = rtnl_neigh_get(cache, ifindex, src_ipv6_nl_addr); + nl_cache_put(cache); if (nl_neigh) - goto ret_free_addr; + goto cleanup; nl_neigh = rtnl_neigh_alloc(); BUG_ON(!nl_neigh); @@ -150,8 +152,8 @@ void tun_add_node_to_proxy_neightbl(struct net_if *if_entry, const uint8_t addre err = rtnl_neigh_add(sock, nl_neigh, NLM_F_CREATE); FATAL_ON(err < 0, 2, "rtnl_neigh_add: %s", nl_geterror(err)); +cleanup: rtnl_neigh_put(nl_neigh); -ret_free_addr: nl_addr_put(src_ipv6_nl_addr); nl_socket_free(sock); } @@ -405,8 +407,6 @@ void wsbr_tun_read(struct wsbr_ctxt *ctxt) buffer_t *buf_6lowpan; uint8_t type; - if (lowpan_adaptation_queue_size(ctxt->net_if.id) > 2) - return; iobuf.data_size = xread(ctxt->tun_fd, buf, sizeof(buf)); if (iobuf.data_size < 0) { WARN("%s: read: %m", __func__); diff --git a/6lbr/app/tun.h b/6lbr/app/tun.h index dab32ef51..d6e45e4e7 100644 --- a/6lbr/app/tun.h +++ b/6lbr/app/tun.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/version.h b/6lbr/app/version.h index dd5e50b07..a71ec1527 100644 --- a/6lbr/app/version.h +++ b/6lbr/app/version.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/wsbr.c b/6lbr/app/wsbr.c index 194c5f97f..1d1d5f5e1 100644 --- a/6lbr/app/wsbr.c +++ b/6lbr/app/wsbr.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -10,8 +11,11 @@ * * [1]: https://www.silabs.com/about-us/legal/master-software-license-agreement */ +#define _GNU_SOURCE +#include #include #include +#include #include "common/bus_uart.h" #include "common/bus_cpc.h" #include "common/capture.h" @@ -24,12 +28,14 @@ #include "common/mathutils.h" #include "common/version.h" #include "common/ws_regdb.h" +#include "common/ieee802154_frame.h" #include "common/key_value_storage.h" #include "common/string_extra.h" #include "common/specs/ws.h" #include "common/rand.h" #include "6lowpan/bootstraps/protocol_6lowpan.h" +#include "6lowpan/lowpan_adaptation_interface.h" #include "6lowpan/mac/mac_helper.h" #include "ws/ws_pan_info_storage.h" #include "ws/ws_bootstrap.h" @@ -67,6 +73,9 @@ #include "tun.h" static void wsbr_handle_reset(struct rcp *rcp); +static void wsbr_rpl_target_add(struct rpl_root *root, struct rpl_target *target); +static void wsbr_rpl_target_del(struct rpl_root *root, struct rpl_target *target); +static void wsbr_rpl_target_update(struct rpl_root *root, struct rpl_target *target, bool updated_transit); // See warning in wsbr.h struct wsbr_ctxt g_ctxt = { @@ -90,14 +99,15 @@ struct wsbr_ctxt g_ctxt = { .net_if.rpl_root.dio_redundancy = 0, .net_if.rpl_root.lifetime_unit_s = 1200, .net_if.rpl_root.lifetime_s = 1200 * 6, - .net_if.rpl_root.min_rank_hop_inc = 128, + .net_if.rpl_root.min_hop_rank_inc = 128, // Defined by Wi-SUN FAN 1.1v06 - 6.2.3.1.6.3 Upward Route Formation .net_if.rpl_root.pcs = 7, .net_if.rpl_root.dodag_version_number = RPL_LOLLIPOP_INIT, .net_if.rpl_root.instance_id = 0, - .net_if.rpl_root.route_add = rpl_glue_route_add, - .net_if.rpl_root.route_del = rpl_glue_route_del, + .net_if.rpl_root.on_target_add = wsbr_rpl_target_add, + .net_if.rpl_root.on_target_del = wsbr_rpl_target_del, + .net_if.rpl_root.on_target_update = wsbr_rpl_target_update, .net_if.llc_random_early_detection.weight = RED_AVERAGE_WEIGHT_EIGHTH, .net_if.llc_random_early_detection.threshold_min = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MIN, @@ -119,6 +129,68 @@ struct wsbr_ctxt g_ctxt = { .net_if.ws_info.fhss_config.bsi = -1, }; +static void wsbr_rpl_target_add(struct rpl_root *root, struct rpl_target *target) +{ + struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); + + ipv6_route_add_with_info(target->prefix, // prefix + 128, // prefix length + ctxt->net_if.id, // interface id + in6addr_any.s6_addr, // next hop + ROUTE_RPL_DAO_SR, // source + (void *)root, // info + 0, // source id + 0xffffffff, // lifetime + 0); // pref + tun_add_node_to_proxy_neightbl(&ctxt->net_if, target->prefix); + tun_add_ipv6_direct_route(&ctxt->net_if, target->prefix); +} + +static void wsbr_rpl_target_del(struct rpl_root *root, struct rpl_target *target) +{ + struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); + + ipv6_route_delete_with_info(target->prefix, // prefix + 128, // prefix length + ctxt->net_if.id, // interface id + in6addr_any.s6_addr, // next hop + ROUTE_RPL_DAO_SR, // source + (void *)root, // info + 0); // source id + rpl_storage_del_target(root, target); + dbus_emit_nodes_change(ctxt); + dbus_emit_routing_graph_change(ctxt); +} + +static void wsbr_rpl_target_update(struct rpl_root *root, struct rpl_target *target, bool updated_transit) +{ + struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); + struct ipv6_neighbour *neigh; + bool is_neigh = false; + + rpl_storage_store_target(root, target); + + if (!updated_transit) + return; + + dbus_emit_nodes_change(ctxt); + dbus_emit_routing_graph_change(ctxt); + + /* + * HACK: Delete the neighbor cache entry in case the node did not + * remove itself. Otherwise routing will choose an "ARO route" instead + * of a "DAO route", which will fail until ARO expiration. + */ + for (uint8_t i = 0; i < root->pcs + 1; i++) + if (IN6_ARE_ADDR_EQUAL(target->transits[i].parent, root->dodag_id)) + is_neigh = true; + if (!is_neigh) { + neigh = ipv6_neighbour_lookup(&ctxt->net_if.ipv6_neighbour_cache, target->prefix); + if (neigh) + ipv6_neighbour_entry_remove(&ctxt->net_if.ipv6_neighbour_cache, neigh); + } +} + static void ws_enable_mac_filtering(struct wsbr_ctxt *ctxt) { BUG_ON(ctxt->config.ws_allowed_mac_address_count && ctxt->config.ws_denied_mac_address_count); @@ -164,8 +236,8 @@ static void wsbr_pae_controller_configure(struct wsbr_ctxt *ctxt) .revocat_lifetime_reduct = ctxt->config.ws_ffn_revocation_lifetime_reduction, }; struct sec_timing timing_lfn = { - .pmk_lifetime_s = ctxt->config.ws_pmk_lifetime_s, - .ptk_lifetime_s = ctxt->config.ws_ptk_lifetime_s, + .pmk_lifetime_s = ctxt->config.ws_lpmk_lifetime_s, + .ptk_lifetime_s = ctxt->config.ws_lptk_lifetime_s, .expire_offset = ctxt->config.ws_lgtk_expire_offset_s, .new_act_time = ctxt->config.ws_lgtk_new_activation_time, .new_install_req = ctxt->config.ws_lgtk_new_install_required, @@ -378,6 +450,7 @@ static void wsbr_network_init(struct wsbr_ctxt *ctxt) } rpl_glue_init(&ctxt->net_if); rpl_start(&ctxt->net_if.rpl_root, ctxt->config.tun_dev); + rpl_storage_store_config(&ctxt->net_if.rpl_root); } static void wsbr_handle_reset(struct rcp *rcp) @@ -399,9 +472,20 @@ static void wsbr_handle_reset(struct rcp *rcp) void kill_handler(int signal) { + struct wsbr_ctxt *ctxt = &g_ctxt; + + if (ctxt->config.uart_dev[0]) + uart_tx_flush(&ctxt->rcp.bus); exit(0); } +void sig_error_handler(int signal) +{ + __PRINT(91, "bug: %s", strsignal(signal)); + backtrace_show(); + raise(signal); +} + static void wsbr_rcp_init(struct wsbr_ctxt *ctxt) { rcp_set_host_api(&ctxt->rcp, version_daemon_api); @@ -413,6 +497,11 @@ static void wsbr_rcp_init(struct wsbr_ctxt *ctxt) rail_print_config_list(ctxt); exit(0); } + + // NOTE: destination address filtering is enabled by default with the + // native EUI-64. + if (memcmp(ctxt->config.ws_mac_address, &ieee802154_addr_bc, 8)) + rcp_set_filter_dst64(&ctxt->rcp, ctxt->config.ws_mac_address); } static void wsbr_rcp_reset(struct wsbr_ctxt *ctxt) @@ -457,7 +546,7 @@ static void wsbr_fds_init(struct wsbr_ctxt *ctxt) ctxt->fds[POLLFD_RCP].fd = ctxt->rcp.bus.fd; ctxt->fds[POLLFD_RCP].events = POLLIN; ctxt->fds[POLLFD_TUN].fd = ctxt->tun_fd; - ctxt->fds[POLLFD_TUN].events = POLLIN; + ctxt->fds[POLLFD_TUN].events = 0; ctxt->fds[POLLFD_EVENT].fd = ctxt->scheduler.event_fd[0]; ctxt->fds[POLLFD_EVENT].events = POLLIN; ctxt->fds[POLLFD_TIMER].fd = ctxt->timerfd; @@ -481,6 +570,11 @@ static void wsbr_poll(struct wsbr_ctxt *ctxt) uint64_t val; int ret; + if (lowpan_adaptation_queue_size(ctxt->net_if.id) > 2) + ctxt->fds[POLLFD_TUN].events = 0; + else + ctxt->fds[POLLFD_TUN].events = POLLIN; + if (ctxt->rcp.bus.uart.data_ready) ret = poll(ctxt->fds, POLLFD_COUNT, 0); else @@ -520,6 +614,7 @@ static void wsbr_poll(struct wsbr_ctxt *ctxt) int wsbr_main(int argc, char *argv[]) { + struct sigaction sigact = { }; static const char *files[] = { "neighbor-*:*:*:*:*:*:*:*", "keys-*:*:*:*:*:*:*:*", @@ -531,10 +626,19 @@ int wsbr_main(int argc, char *argv[]) struct wsbr_ctxt *ctxt = &g_ctxt; INFO("Silicon Labs Wi-SUN border router %s", version_daemon_str); - signal(SIGINT, kill_handler); - signal(SIGHUP, kill_handler); - signal(SIGTERM, kill_handler); - signal(SIGPIPE, SIG_IGN); // Handle writing to unread FIFO for pcapng capture + sigact.sa_flags = SA_RESETHAND; + sigact.sa_handler = kill_handler; + sigaction(SIGINT, &sigact, NULL); + sigaction(SIGHUP, &sigact, NULL); + sigaction(SIGTERM, &sigact, NULL); + sigact.sa_handler = sig_error_handler; + sigaction(SIGILL, &sigact, NULL); + sigaction(SIGSEGV, &sigact, NULL); + sigaction(SIGBUS, &sigact, NULL); + sigaction(SIGFPE, &sigact, NULL); + sigaction(SIGQUIT, &sigact, NULL); + sigact.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sigact, NULL); // Handle writing to unread FIFO for pcapng capture parse_commandline(&ctxt->config, argc, argv, print_help_br); if (ctxt->config.color_output != -1) g_enable_color_traces = ctxt->config.color_output; diff --git a/6lbr/app/wsbr.h b/6lbr/app/wsbr.h index 2c3cba848..2ad5da6ae 100644 --- a/6lbr/app/wsbr.h +++ b/6lbr/app/wsbr.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -68,6 +69,7 @@ struct wsbr_ctxt { int pcapng_fd; mode_t pcapng_type; + uint64_t pcapng_t0_us; }; // This global variable is necessary for various API of nanostack. Beside this diff --git a/6lbr/app/wsbr_cfg.c b/6lbr/app/wsbr_cfg.c index 40daeedf0..51398b36f 100644 --- a/6lbr/app/wsbr_cfg.c +++ b/6lbr/app/wsbr_cfg.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/wsbr_cfg.h b/6lbr/app/wsbr_cfg.h index 270336b6d..9319bb947 100644 --- a/6lbr/app/wsbr_cfg.h +++ b/6lbr/app/wsbr_cfg.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/wsbr_mac.c b/6lbr/app/wsbr_mac.c index 9d8930f75..adc60efa2 100644 --- a/6lbr/app/wsbr_mac.c +++ b/6lbr/app/wsbr_mac.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -100,6 +101,8 @@ void wsbr_tx_cnf(struct rcp *rcp, const struct hif_tx_cnf *cnf) if (cnf->frame_len) { ret = wsbr_data_cnf_parse(cnf->frame, cnf->frame_len, &mcps_cnf, &mcps_ie); WARN_ON(ret < 0, "invalid ack frame"); + if (!ret && ctxt->config.pcap_file[0]) + wsbr_pcapng_write_frame(ctxt, cnf->timestamp_us, cnf->frame, cnf->frame_len); } ws_llc_mac_confirm_cb(&ctxt->net_if, &mcps_cnf, &mcps_ie); } @@ -117,6 +120,6 @@ void wsbr_rx_ind(struct rcp *rcp, const struct hif_rx_ind *ind) if (ret < 0) return; if (ctxt->config.pcap_file[0]) - wsbr_pcapng_write_frame(ctxt, &mcps_ind, &mcps_ie); + wsbr_pcapng_write_frame(ctxt, ind->timestamp_us, ind->frame, ind->frame_len); ws_llc_mac_indication_cb(&ctxt->net_if, &mcps_ind, &mcps_ie); } diff --git a/6lbr/app/wsbr_mac.h b/6lbr/app/wsbr_mac.h index 8ad1ee2ae..00b4cfb88 100644 --- a/6lbr/app/wsbr_mac.h +++ b/6lbr/app/wsbr_mac.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/app/wsbr_pcapng.c b/6lbr/app/wsbr_pcapng.c index 9a4182fcf..9059a3e06 100644 --- a/6lbr/app/wsbr_pcapng.c +++ b/6lbr/app/wsbr_pcapng.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -20,6 +21,8 @@ #include "common/endian.h" #include "common/log.h" #include "common/memutils.h" +#include "common/ieee802154_frame.h" +#include "common/ieee802154_ie.h" #include "common/iobuf.h" #include "common/pcapng.h" #include "common/string_extra.h" @@ -67,19 +70,10 @@ static void wsbr_pcapng_write(struct wsbr_ctxt *ctxt, const struct iobuf_write * static void wsbr_pcapng_write_start(struct wsbr_ctxt *ctxt) { - static const struct pcapng_shb shb = { - .version_maj = 1, - .version_min = 0, - .section_len = -1, // unknown section length - }; - static const struct pcapng_idb idb = { - .link_type = LINKTYPE_IEEE802_15_4_NOFCS, - .snap_len = 0, // no packet size restriction - }; struct iobuf_write buf = { }; - pcapng_write_shb(&buf, &shb); - pcapng_write_idb(&buf, &idb); + pcapng_write_shb(&buf); + pcapng_write_idb(&buf, LINKTYPE_IEEE802_15_4_NOFCS); wsbr_pcapng_write(ctxt, &buf); iobuf_free(&buf); } @@ -115,20 +109,40 @@ void wsbr_pcapng_init(struct wsbr_ctxt *ctxt) wsbr_pcapng_write_start(ctxt); } -void wsbr_pcapng_write_frame(struct wsbr_ctxt *ctxt, mcps_data_ind_t *ind, - struct mcps_data_rx_ie_list *ie) +void wsbr_pcapng_write_frame(struct wsbr_ctxt *ctxt, uint64_t timestamp_us, + const void *frame, size_t frame_len) { - uint8_t frame[MAC_IEEE_802_15_4G_MAX_PHY_PACKET_SIZE]; - struct iobuf_write buf = { }; - struct pcapng_epb epb = { - .if_id = 0, // only one interface is used - .timestamp = ind->hif.timestamp_us, - }; - - epb.pkt_len = wsbr_data_ind_rebuild(frame, ind, ie); - epb.pkt_len_og = epb.pkt_len; - epb.pkt = frame; - pcapng_write_epb(&buf, &epb); - wsbr_pcapng_write(ctxt, &buf); - iobuf_free(&buf); + struct iobuf_write iobuf_pcapng = { }; + struct iobuf_write iobuf_frame = { }; + struct iobuf_read ie_payload; + struct iobuf_read ie_header; + struct ieee802154_hdr hdr; + struct timespec tp; + int ret; + + ret = ieee802154_frame_parse(frame, frame_len, &hdr, &ie_header, &ie_payload); + if (ret < 0) + return; + hdr.key_index = 0; // Strip the Auxiliary Security Header + + ieee802154_frame_write_hdr(&iobuf_frame, &hdr); + iobuf_push_data(&iobuf_frame, ie_header.data, ie_header.data_size); + if (ie_payload.data_size) { + ieee802154_ie_push_header(&iobuf_frame, IEEE802154_IE_ID_HT1); + iobuf_push_data(&iobuf_frame, ie_payload.data, ie_payload.data_size); + } + + if (!ctxt->pcapng_t0_us) { + // NOTE: Since time is measured only once, details like clock drift and + // leap seconds are ignored. + clock_gettime(CLOCK_REALTIME, &tp); + ctxt->pcapng_t0_us = (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000 - timestamp_us; + } + + pcapng_write_epb(&iobuf_pcapng, timestamp_us + ctxt->pcapng_t0_us, + iobuf_frame.data, iobuf_frame.len); + wsbr_pcapng_write(ctxt, &iobuf_pcapng); + + iobuf_free(&iobuf_pcapng); + iobuf_free(&iobuf_frame); } diff --git a/6lbr/app/wsbr_pcapng.h b/6lbr/app/wsbr_pcapng.h index a935d4897..c5955b6e9 100644 --- a/6lbr/app/wsbr_pcapng.h +++ b/6lbr/app/wsbr_pcapng.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -13,12 +14,16 @@ #ifndef WSBR_PCAPNG_H #define WSBR_PCAPNG_H +#include +#include + struct wsbr_ctxt; struct mcps_data_ind; struct mcps_data_rx_ie_list; void wsbr_pcapng_init(struct wsbr_ctxt *ctxt); void wsbr_pcapng_closed(struct wsbr_ctxt *ctxt); -void wsbr_pcapng_write_frame(struct wsbr_ctxt *ctxt, struct mcps_data_ind *ind, struct mcps_data_rx_ie_list *ie); +void wsbr_pcapng_write_frame(struct wsbr_ctxt *ctxt, uint64_t timestamp_us, + const void *frame, size_t frame_len); #endif diff --git a/6lbr/app/wsbrd.c b/6lbr/app/wsbrd.c index b19a96a0c..c422f7a32 100644 --- a/6lbr/app/wsbrd.c +++ b/6lbr/app/wsbrd.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ipv6/ipv6.c b/6lbr/ipv6/ipv6.c index 4b4ba21ea..2fc1e81d8 100644 --- a/6lbr/ipv6/ipv6.c +++ b/6lbr/ipv6/ipv6.c @@ -598,6 +598,7 @@ buffer_t *ipv6_forwarding_down(buffer_t *buf) buf->options.flow_label = ipv6_flow_label_tunnel(iphdr + IPV6_HDROFF_SRC_ADDR, iphdr + IPV6_HDROFF_DST_ADDR, flow); + buf->options.hop_limit = buf->interface->cur_hop_limit; buf->info = (buffer_info_t)(B_DIR_DOWN | B_FROM_IPV6_FWD | B_TO_IPV6); return buf; } diff --git a/6lbr/ipv6/ipv6_neigh_storage.c b/6lbr/ipv6/ipv6_neigh_storage.c index 1ce580259..d2b2478ed 100644 --- a/6lbr/ipv6/ipv6_neigh_storage.c +++ b/6lbr/ipv6/ipv6_neigh_storage.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ipv6/ipv6_neigh_storage.h b/6lbr/ipv6/ipv6_neigh_storage.h index a4584fde9..295d94611 100644 --- a/6lbr/ipv6/ipv6_neigh_storage.h +++ b/6lbr/ipv6/ipv6_neigh_storage.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/mpl/mpl.c b/6lbr/mpl/mpl.c index 32434c4c0..e22e078d1 100644 --- a/6lbr/mpl/mpl.c +++ b/6lbr/mpl/mpl.c @@ -305,8 +305,7 @@ static void mpl_free_space(void) return; } - oldest_seed->min_sequence = mpl_buffer_sequence(oldest_message) + 1; - mpl_buffer_delete(oldest_seed, oldest_message); + mpl_seed_advance_min_sequence(oldest_seed, mpl_buffer_sequence(oldest_message) + 1); } @@ -601,8 +600,17 @@ void mpl_timer(int seconds) ns_list_foreach_safe(mpl_buffered_message_t, message, &seed->messages) { if (!trickle_running(&message->trickle, &domain->data_trickle_params) && g_monotonic_time_100ms - message->timestamp >= message_age_limit) { - seed->min_sequence = mpl_buffer_sequence(message) + 1; - mpl_buffer_delete(seed, message); + /* + * RFC 7731 7.4. Buffered Message Set + * All MPL Data Messages within a Buffered Message Set MUST have a + * sequence number greater than or equal to MinSequence for the + * corresponding SeedID. When increasing MinSequence for an MPL Seed, + * the MPL Forwarder MUST delete any MPL Data Messages from the + * corresponding Buffered Message Set that have sequence numbers less + * than MinSequence. + */ + mpl_seed_advance_min_sequence(seed, mpl_buffer_sequence(message) + 1); + continue; } if (trickle_timer(&message->trickle, &domain->data_trickle_params, seconds)) mpl_buffer_transmit(domain, message, ns_list_get_next(&seed->messages, message) == NULL); diff --git a/6lbr/net/timers.c b/6lbr/net/timers.c index 066976002..f2d5b135b 100644 --- a/6lbr/net/timers.c +++ b/6lbr/net/timers.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/net/timers.h b/6lbr/net/timers.h index ab275ac4f..10534a52b 100644 --- a/6lbr/net/timers.h +++ b/6lbr/net/timers.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/rpl/rpl.c b/6lbr/rpl/rpl.c index 267956327..dddf2ef64 100644 --- a/6lbr/rpl/rpl.c +++ b/6lbr/rpl/rpl.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -17,7 +18,6 @@ #include "net/timers.h" #include "app/wsbr.h" // FIXME -#include "app/dbus.h" #include "common/bits.h" #include "common/capture.h" #include "common/iobuf.h" @@ -31,7 +31,6 @@ #include "common/specs/icmpv6.h" #include "common/specs/rpl.h" #include "rpl_lollipop.h" -#include "rpl_storage.h" #include "rpl.h" struct rpl_opt_target { @@ -76,26 +75,22 @@ struct rpl_target *rpl_target_get(struct rpl_root *root, const uint8_t prefix[16 struct rpl_target *rpl_target_new(struct rpl_root *root, const uint8_t prefix[16]) { - struct rpl_target *target = calloc(1, sizeof(struct rpl_target)); + struct rpl_target *target = zalloc(sizeof(struct rpl_target)); - FATAL_ON(!target, 2, "malloc: %m"); memcpy(target->prefix, prefix, 16); SLIST_INSERT_HEAD(&root->targets, target, link); - root->route_add(root, target->prefix, 128); + if (root->on_target_add) + root->on_target_add(root, target); return target; } void rpl_target_del(struct rpl_root *root, struct rpl_target *target) { - struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); - TRACE(TR_RPL, "rpl: target remove prefix=%s", tr_ipv6_prefix(target->prefix, 128)); SLIST_REMOVE(&root->targets, target, rpl_target, link); - root->route_del(root, target->prefix, 128); - rpl_storage_del_target(root, target); + if (root->on_target_del) + root->on_target_del(root, target); free(target); - dbus_emit_nodes_change(ctxt); - dbus_emit_routing_graph_change(ctxt); } uint16_t rpl_target_count(struct rpl_root *root) @@ -188,7 +183,7 @@ static void rpl_opt_push_config(struct iobuf_write *buf, struct rpl_root *root) // Wi-SUN FAN 1.1v06 - 6.2.3.1.6.3 Upward Route Formation // The MaxRankIncrease field MUST be set to 0. iobuf_push_be16(buf, 0); - iobuf_push_be16(buf, root->min_rank_hop_inc); + iobuf_push_be16(buf, root->min_hop_rank_inc); // Wi-SUN FAN 1.1v06 - 6.2.3.1.6.3 Upward Route Formation // The OCP field MUST be set to 1 to indicate usage of the MRHOF objective // function. @@ -385,11 +380,11 @@ static void rpl_transit_update(struct rpl_root *root, struct rpl_opt_target *opt_target, struct rpl_opt_transit *opt_transit) { - struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); bool path_ctl_desync, path_ctl_old; + bool updated_lifetime = false; + bool updated_transit = false; struct rpl_transit transit; struct rpl_target *target; - bool nvm_store = false; BUG_ON(opt_target->prefix_len != 128); memcpy(transit.parent, opt_transit->parent, 16); @@ -402,7 +397,7 @@ static void rpl_transit_update(struct rpl_root *root, target->external = opt_transit->external; target->path_seq = opt_transit->path_seq; target->path_seq_tstamp_s = time_current(CLOCK_MONOTONIC); - nvm_store = true; + updated_lifetime = true; TRACE(TR_RPL, "rpl: target new prefix=%s path-seq=%u external=%u", tr_ipv6_prefix(target->prefix, 128), target->path_seq, target->external); } @@ -410,7 +405,7 @@ static void rpl_transit_update(struct rpl_root *root, if (root->compat) { target->path_seq = opt_transit->path_seq; target->path_seq_tstamp_s = time_current(CLOCK_MONOTONIC); - nvm_store = true; + updated_lifetime = true; TRACE(TR_RPL, "rpl: target update prefix=%s path-seq=%u", tr_ipv6_prefix(target->prefix, 128), target->path_seq); } else { @@ -424,9 +419,10 @@ static void rpl_transit_update(struct rpl_root *root, } if (rpl_lollipop_cmp(opt_transit->path_seq, target->path_seq) > 0) { memset(target->transits, 0, sizeof(target->transits)); + updated_lifetime = true; target->path_seq = opt_transit->path_seq; target->path_seq_tstamp_s = time_current(CLOCK_MONOTONIC); - nvm_store = true; + updated_transit = true; TRACE(TR_RPL, "rpl: target update prefix=%s path-seq=%u", tr_ipv6_prefix(target->prefix, 128), target->path_seq); } @@ -438,19 +434,50 @@ static void rpl_transit_update(struct rpl_root *root, for (uint8_t i = 0; i < root->pcs + 1; i++) { if (!(opt_transit->path_ctl & (1 << (7 - i)))) continue; + if (!memcmp(target->transits + i, &transit, sizeof(struct rpl_transit))) + continue; if (memzcmp(target->transits + i, sizeof(struct rpl_transit)) && memcmp(target->transits + i, &transit, sizeof(struct rpl_transit)) && !root->compat) WARN("%s: overwrite", __func__); target->transits[i] = transit; - nvm_store = true; + updated_transit = true; TRACE(TR_RPL, "rpl: transit new target=%s parent=%s path-ctl-bit=%u", tr_ipv6_prefix(target->prefix, 128), tr_ipv6(target->transits[i].parent), i); } - if (nvm_store) { - rpl_storage_store_target(root, target); - dbus_emit_nodes_change(ctxt); - dbus_emit_routing_graph_change(ctxt); + if ((updated_lifetime || updated_transit) && root->on_target_update) + root->on_target_update(root, target, updated_transit); +} + +static bool rpl_apply_transits(struct rpl_root *root, struct rpl_opt_target *opt_target, const uint8_t *opts, + size_t opts_len) +{ + struct rpl_opt_transit opt_transit; + struct iobuf_read opt_buf; + struct iobuf_read buf = { + .data_size = opts_len, + .data = opts, + }; + uint8_t opt_type; + + while (iobuf_remaining_size(&buf)) { + opt_type = iobuf_pop_u8(&buf); + if (opt_type == RPL_OPT_PAD1) + continue; + opt_buf.data_size = iobuf_pop_u8(&buf); + opt_buf.data = iobuf_pop_data_ptr(&buf, opt_buf.data_size); + opt_buf.err = buf.err; + opt_buf.cnt = 0; + if (opt_type == RPL_OPT_PADN) + continue; + if (opt_type == RPL_OPT_TARGET) + continue; // Skip grouped target options + if (opt_type != RPL_OPT_TRANSIT) + break; // No more transits for the current target + if (!rpl_opt_transit_parse(&opt_buf, &opt_transit)) + break; + rpl_transit_update(root, opt_target, &opt_transit); } + return !opt_buf.err; } static void rpl_recv_dao(struct rpl_root *root, const uint8_t *pkt, size_t size, @@ -462,9 +489,7 @@ static void rpl_recv_dao(struct rpl_root *root, const uint8_t *pkt, size_t size, .data = pkt, }; const uint8_t *dodag_id = NULL; - struct rpl_opt_transit opt_transit; struct rpl_opt_target opt_target; - bool has_transit = false; bool has_target = false; uint8_t instance_id; uint8_t bitfield; @@ -499,28 +524,22 @@ static void rpl_recv_dao(struct rpl_root *root, const uint8_t *pkt, size_t size, case RPL_OPT_PADN: break; case RPL_OPT_TARGET: - if (has_target && !has_transit) - TRACE(TR_IGNORE, "ignore: rpl-dao consecutive target options"); - has_transit = false; if (!rpl_opt_target_parse(&opt_buf, &opt_target)) break; if (opt_target.prefix_len != 128) { TRACE(TR_IGNORE, "ignore: rpl-dao target prefix length != 128"); break; } + opt_buf.err = !rpl_apply_transits(root, &opt_target, iobuf_ptr(&buf), iobuf_remaining_size(&buf)); has_target = true; break; case RPL_OPT_TRANSIT: - if (!has_target) { + // Transits are handled in rpl_apply_transit() + if (!has_target) TRACE(TR_IGNORE, "ignore: rpl-dao transit without target"); - break; - } - if (!rpl_opt_transit_parse(&opt_buf, &opt_transit)) - break; - has_transit = true; - rpl_transit_update(root, &opt_target, &opt_transit); break; default: + has_target = false; TRACE(TR_IGNORE, "ignore: rpl-dao unsupported option %u", opt_type); break; } @@ -538,13 +557,12 @@ void rpl_recv_srh_err(struct rpl_root *root, const uint8_t *pkt, size_t size, const uint8_t src[16]) { - struct wsbr_ctxt *ctxt = container_of(root, struct wsbr_ctxt, net_if.rpl_root); struct iobuf_read iobuf = { .data_size = size, .data = pkt, }; struct rpl_target *target; - bool nvm_store = false; + bool updated = false; const uint8_t *dst; // RFC 6550 - 11.2.2.3. DAO Inconsistency Detection and Recovery @@ -575,16 +593,13 @@ void rpl_recv_srh_err(struct rpl_root *root, for (uint8_t i = 0; i < root->pcs + 1; i++) { if (!memcmp(target->transits[i].parent, src, 16)) { memset(target->transits + i, 0, sizeof(struct rpl_transit)); - nvm_store = true; + updated = true; TRACE(TR_RPL, "rpl: transit remove target=%s parent=%s path-ctl-bit=%u", tr_ipv6_prefix(dst, 128), tr_ipv6(src), i); } } - if (nvm_store) { - rpl_storage_store_target(root, target); - dbus_emit_nodes_change(ctxt); - dbus_emit_routing_graph_change(ctxt); - } + if (updated && root->on_target_update) + root->on_target_update(root, target, true); } static void rpl_recv_dispatch(struct rpl_root *root, const uint8_t *pkt, size_t size, @@ -670,7 +685,7 @@ void rpl_start(struct rpl_root *root, const char ifname[IF_NAMESIZE]) struct icmp6_filter filter; int err; - BUG_ON(!root->min_rank_hop_inc); + BUG_ON(!root->min_hop_rank_inc); BUG_ON(!memzcmp(root->dodag_id, 16)); BUG_ON(root->pcs > 7); BUG_ON(!root->lifetime_s); @@ -679,7 +694,6 @@ void rpl_start(struct rpl_root *root, const char ifname[IF_NAMESIZE]) // Wi-SUN FAN 1.1v06 - 6.2.3.1.6.3 Upward Route Formation // The RPLInstanceID MUST be of the global form. BUG_ON(FIELD_GET(RPL_MASK_INSTANCE_ID_TYPE, root->instance_id) != RPL_INSTANCE_ID_TYPE_GLOBAL); - BUG_ON(!root->route_add || !root->route_del); root->sockfd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); FATAL_ON(root->sockfd < 0, 2, "%s: socket: %m", __func__); @@ -699,8 +713,6 @@ void rpl_start(struct rpl_root *root, const char ifname[IF_NAMESIZE]) rpl_dio_trickle_params(root, &dio_trickle_params); trickle_start(&root->dio_trickle, "RPL DIO", &dio_trickle_params); ws_timer_start(WS_TIMER_RPL); - - rpl_storage_store_config(root); } void rpl_timer(int ticks) @@ -709,27 +721,28 @@ void rpl_timer(int ticks) struct rpl_root *root = &g_ctxt.net_if.rpl_root; struct rpl_target *target, *tmp; time_t elapsed; - bool del; + bool updated; rpl_dio_trickle_params(root, &dio_trickle_params); if (trickle_timer(&root->dio_trickle, &dio_trickle_params, ticks)) rpl_send_dio(root, rpl_all_nodes); SLIST_FOREACH_SAFE(target, &root->targets, link, tmp) { - del = true; + updated = false; elapsed = time_get_elapsed(CLOCK_MONOTONIC, target->path_seq_tstamp_s); for (uint8_t i = 0; i < root->pcs + 1; i++) { if (!memzcmp(target->transits + i, sizeof(struct rpl_transit))) continue; - if (elapsed > target->transits[i].path_lifetime_s) { - TRACE(TR_RPL, "rpl: transit expire target=%s parent=%s path-ctl-bit=%u", - tr_ipv6_prefix(target->prefix, 128), tr_ipv6(target->transits[i].parent), i); - memset(target->transits + i, 0, sizeof(struct rpl_transit)); - } else { - del = false; - } + if (elapsed < target->transits[i].path_lifetime_s) + continue; + TRACE(TR_RPL, "rpl: transit expire target=%s parent=%s path-ctl-bit=%u", + tr_ipv6_prefix(target->prefix, 128), tr_ipv6(target->transits[i].parent), i); + memset(target->transits + i, 0, sizeof(struct rpl_transit)); + updated = false; } - if (del) + if (!memzcmp(target->transits, sizeof(target->transits))) rpl_target_del(root, target); + else if (updated && root->on_target_update) + root->on_target_update(root, target, true); } } diff --git a/6lbr/rpl/rpl.h b/6lbr/rpl/rpl.h index 47ea2b8e2..63f171076 100644 --- a/6lbr/rpl/rpl.h +++ b/6lbr/rpl/rpl.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -102,15 +103,16 @@ struct rpl_root { uint8_t dodag_id[16]; uint8_t dodag_version_number; uint8_t dodag_pref; - uint8_t min_rank_hop_inc; + uint16_t min_hop_rank_inc; uint32_t lifetime_s; uint16_t lifetime_unit_s; uint8_t dtsn; // DAO Trigger Sequence Number uint8_t pcs; // Path Control Size bool rpi_ignorable; - void (*route_add)(struct rpl_root *root, const uint8_t prefix[16], size_t prefix_len); - void (*route_del)(struct rpl_root *root, const uint8_t prefix[16], size_t prefix_len); + void (*on_target_add)(struct rpl_root *root, struct rpl_target *target); + void (*on_target_del)(struct rpl_root *root, struct rpl_target *target); + void (*on_target_update)(struct rpl_root *root, struct rpl_target *target, bool updated_transit); // When enabled, some parts of the specification are ignored in order to // hopefully improve interoperability with faulty devices. @@ -145,7 +147,7 @@ static inline uint16_t rpl_dag_rank(const struct rpl_root *root, uint16_t rank) // follows, where floor(x) is the function that evaluates to the greatest // integer less than or equal to x: // DAGRank(rank) = floor(rank/MinHopRankIncrease) - return rank / root->min_rank_hop_inc; + return rank / root->min_hop_rank_inc; } static inline uint16_t rpl_root_rank(struct rpl_root *root) @@ -154,7 +156,7 @@ static inline uint16_t rpl_root_rank(struct rpl_root *root) // A DODAG root MUST advertise a Rank of ROOT_RANK. // RFC 6550 - 17. RPL Constants and Variables // [...] ROOT_RANK has a value of MinHopRankIncrease [...]. - return root->min_rank_hop_inc; + return root->min_hop_rank_inc; } #endif diff --git a/6lbr/rpl/rpl_glue.c b/6lbr/rpl/rpl_glue.c index 9bbd78b20..4afa9984a 100644 --- a/6lbr/rpl/rpl_glue.c +++ b/6lbr/rpl/rpl_glue.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -30,46 +31,6 @@ // The IPv6 extension system from the nanostack is not clear. Design choices // for this file mostly come from mimicking the legacy RPL implementation. -void rpl_glue_route_add(struct rpl_root *root, const uint8_t *prefix, size_t prefix_len) -{ - struct net_if *net_if = container_of(root, struct net_if, rpl_root); - struct ipv6_neighbour *ipv6_neigh = ipv6_neighbour_lookup(&net_if->ipv6_neighbour_cache, prefix); - struct ws_neigh *neigh; - - ipv6_route_add_with_info(prefix, prefix_len, // prefix - net_if->id, // interface id - in6addr_any.s6_addr, // next hop - ROUTE_RPL_DAO_SR, // source - (void *)root, // info - 0, // source id - 0xffffffff, // lifetime - 0); // pref - - // FIXME: This hack allows to handle an LFN changing parent without - // informing us. Removing its ARO routes allows to ensure the RPL DAO SR - // route is used and not the outdated ARO route that would actually prevent - // the host from communicating with the LFN. - // It is expected that the IPv6 neighbor entries linked to this neighbor - // expire and get deleted by the garbage collector later. - if (ipv6_neigh) { - neigh = ws_neigh_get(&net_if->ws_info.neighbor_storage, ipv6_neighbour_eui64(&net_if->ipv6_neighbour_cache, ipv6_neigh)); - if (neigh && neigh->node_role == WS_NR_ROLE_LFN) - nd_remove_aro_routes_by_eui64(net_if, ipv6_neighbour_eui64(&net_if->ipv6_neighbour_cache, ipv6_neigh)); - } -} - -void rpl_glue_route_del(struct rpl_root *root, const uint8_t *prefix, size_t prefix_len) -{ - struct net_if *net_if = container_of(root, struct net_if, rpl_root); - - ipv6_route_delete_with_info(prefix, prefix_len, // prefix - net_if->id, // interface id - in6addr_any.s6_addr, // next hop - ROUTE_RPL_DAO_SR, // source - (void *)root, // info - 0); // source id -} - // RFC 6553 - 3. Format of the RPL Option bool rpl_glue_process_rpi(struct rpl_root *root, struct buffer *buf, const uint8_t *opt, uint8_t opt_len) diff --git a/6lbr/rpl/rpl_glue.h b/6lbr/rpl/rpl_glue.h index 8b8025021..600eae1c7 100644 --- a/6lbr/rpl/rpl_glue.h +++ b/6lbr/rpl/rpl_glue.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -29,7 +30,4 @@ void rpl_glue_init(struct net_if *net_if); bool rpl_glue_process_rpi(struct rpl_root *root, struct buffer *buf, const uint8_t *opt, uint8_t opt_len); -void rpl_glue_route_add(struct rpl_root *root, const uint8_t *prefix, size_t prefix_len); -void rpl_glue_route_del(struct rpl_root *root, const uint8_t *prefix, size_t prefix_len); - #endif diff --git a/6lbr/rpl/rpl_lollipop.h b/6lbr/rpl/rpl_lollipop.h index ad4bd3fe1..95a485f4b 100644 --- a/6lbr/rpl/rpl_lollipop.h +++ b/6lbr/rpl/rpl_lollipop.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/rpl/rpl_srh.c b/6lbr/rpl/rpl_srh.c index dbb72a427..7a2695ad9 100644 --- a/6lbr/rpl/rpl_srh.c +++ b/6lbr/rpl/rpl_srh.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/rpl/rpl_srh.h b/6lbr/rpl/rpl_srh.h index 026c3719f..36a7e46cd 100644 --- a/6lbr/rpl/rpl_srh.h +++ b/6lbr/rpl/rpl_srh.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/rpl/rpl_storage.c b/6lbr/rpl/rpl_storage.c index 76947c016..21fe24734 100644 --- a/6lbr/rpl/rpl_storage.c +++ b/6lbr/rpl/rpl_storage.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/rpl/rpl_storage.h b/6lbr/rpl/rpl_storage.h index de4fbd20b..93e6541e7 100644 --- a/6lbr/rpl/rpl_storage.h +++ b/6lbr/rpl/rpl_storage.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/security/protocols/eap_tls_sec_prot/radius_eap_tls_sec_prot.c b/6lbr/security/protocols/eap_tls_sec_prot/radius_eap_tls_sec_prot.c index 414bc30f9..97e08fb69 100644 --- a/6lbr/security/protocols/eap_tls_sec_prot/radius_eap_tls_sec_prot.c +++ b/6lbr/security/protocols/eap_tls_sec_prot/radius_eap_tls_sec_prot.c @@ -273,9 +273,14 @@ static int8_t radius_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap static int8_t radius_eap_tls_sec_prot_radius_eap_message_forward(sec_prot_t *prot, uint8_t *eap_code) { radius_eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot); + uint16_t eap_pdu_len; + uint8_t *eap_pdu; - uint16_t eap_pdu_len = data->recv_eap_msg_len - prot->receive_peer_hdr_size; - uint8_t *eap_pdu = data->recv_eap_msg + prot->receive_peer_hdr_size; + if (data->recv_eap_msg_len < prot->receive_peer_hdr_size) + return -1; + + eap_pdu_len = data->recv_eap_msg_len - prot->receive_peer_hdr_size; + eap_pdu = data->recv_eap_msg + prot->receive_peer_hdr_size; if (eap_pdu_len < 4) { return -1; diff --git a/6lbr/ws/ws_common.c b/6lbr/ws/ws_common.c index fe5f407a8..9e98519fa 100644 --- a/6lbr/ws/ws_common.c +++ b/6lbr/ws/ws_common.c @@ -85,6 +85,16 @@ void ws_common_calc_chan_excl(ws_excluded_channel_data_t *chan_excl, const uint8 bool in_range = false; int range_cnt = 0; + /* + * Wi-SUN FAN 1.1v08 6.3.2.3.2.1.3 Field Definitions + * The Excluded Channel Control field MUST be set to 0 when the Channel + * Function field is set to zero. + */ + if (ws_common_get_fixed_channel(chan_mask_custom) >= 0) { + chan_excl->excluded_channel_ctrl = WS_EXC_CHAN_CTRL_NONE; + return; + } + memset(chan_excl, 0, sizeof(ws_excluded_channel_data_t)); for (uint16_t i = 0; i < chan_count; i++) { if (!bittest(chan_mask_reg, i) || bittest(chan_mask_custom, i)) { diff --git a/6lbr/ws/ws_common.h b/6lbr/ws/ws_common.h index 5163eb0ae..7c7fa7d38 100644 --- a/6lbr/ws/ws_common.h +++ b/6lbr/ws/ws_common.h @@ -109,6 +109,7 @@ typedef struct ws_info { struct ws_neigh_table neighbor_storage; struct ws_fhss_config fhss_config; int tx_power_dbm; + uint8_t edfe_src[8]; } ws_info_t; int8_t ws_common_generate_channel_list(uint8_t chan_mask[32], diff --git a/6lbr/ws/ws_ie_custom.c b/6lbr/ws/ws_ie_custom.c index f8e062c5e..229328e18 100644 --- a/6lbr/ws/ws_ie_custom.c +++ b/6lbr/ws/ws_ie_custom.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ws/ws_ie_custom.h b/6lbr/ws/ws_ie_custom.h index 1e3d91041..67d307c24 100644 --- a/6lbr/ws/ws_ie_custom.h +++ b/6lbr/ws/ws_ie_custom.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ws/ws_ie_lib.c b/6lbr/ws/ws_ie_lib.c index f9afe8d10..999a41dae 100644 --- a/6lbr/ws/ws_ie_lib.c +++ b/6lbr/ws/ws_ie_lib.c @@ -470,7 +470,7 @@ void ws_wp_nested_netname_write(struct iobuf_write *buf, int offset; offset = ieee802154_ie_push_nested(buf, WS_WPIE_NETNAME, false); - iobuf_push_data(buf, (const uint8_t *)netname, strlen(netname)); + iobuf_push_data(buf, netname, strlen(netname)); ieee802154_ie_fill_len_nested(buf, offset, false); } diff --git a/6lbr/ws/ws_ie_validation.c b/6lbr/ws/ws_ie_validation.c index 731cebd80..a7cf56081 100644 --- a/6lbr/ws/ws_ie_validation.c +++ b/6lbr/ws/ws_ie_validation.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ws/ws_ie_validation.h b/6lbr/ws/ws_ie_validation.h index a182cbd5e..2f35e1277 100644 --- a/6lbr/ws/ws_ie_validation.h +++ b/6lbr/ws/ws_ie_validation.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ws/ws_llc.c b/6lbr/ws/ws_llc.c index 4e9a29b81..357f3b4c7 100644 --- a/6lbr/ws/ws_llc.c +++ b/6lbr/ws/ws_llc.c @@ -1012,12 +1012,13 @@ static inline bool ws_is_frame_mngt(uint8_t frame_type) } /** WS LLC MAC data extension indication */ -void ws_llc_mac_indication_cb(struct net_if *net_if, const mcps_data_ind_t *data, +void ws_llc_mac_indication_cb(struct net_if *net_if, struct mcps_data_ind *data, const struct mcps_data_rx_ie_list *ie_ext) { struct ws_neigh *neigh; struct ws_lutt_ie ie_lutt; struct ws_utt_ie ie_utt; + struct ws_fc_ie ie_fc; bool has_utt, has_lutt; uint8_t frame_type; @@ -1052,6 +1053,16 @@ void ws_llc_mac_indication_cb(struct net_if *net_if, const mcps_data_ind_t *data neigh->frame_counter_min[data->Key.KeyIndex - 1] = add32sat(data->Key.frame_counter, 1); } + // HACK: In FAN 1.0 the source address is elided in EDFE response frames + if (ws_wh_fc_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ie_fc)) { + if (data->SrcAddrMode == MAC_ADDR_MODE_64_BIT) { + memcpy(net_if->ws_info.edfe_src, data->SrcAddr, 8); + } else { + memcpy(data->SrcAddr, net_if->ws_info.edfe_src, 8); + data->SrcAddrMode = MAC_ADDR_MODE_64_BIT; + } + } + if (ws_is_frame_mngt(frame_type)) { ws_llc_mngt_ind(net_if, data, ie_ext, frame_type); } else if (frame_type == WS_FT_DATA) { @@ -1320,8 +1331,7 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us struct wp_ie_list wp_ies = { .us = true, .bs = !data->TxAckReq, - .pom = ws_info->phy_config.phy_op_modes[0] && - ws_info->phy_config.phy_op_modes[1], + .pom = ws_info->phy_config.phy_op_modes[0], // Include JM-IE in broadcast ULAD frames if PA transmissions are suppressed. .jm = ws_info->pan_information.jm.mask && data->DstAddrMode == MAC_ADDR_MODE_NONE && diff --git a/6lbr/ws/ws_llc.h b/6lbr/ws/ws_llc.h index 33a4b3a7a..902205fef 100644 --- a/6lbr/ws/ws_llc.h +++ b/6lbr/ws/ws_llc.h @@ -136,7 +136,7 @@ void ws_llc_mac_confirm_cb(struct net_if *net_if, const mcps_data_cnf_t *data, const struct mcps_data_rx_ie_list *conf_data); typedef struct mcps_data_ind mcps_data_ind_t; -void ws_llc_mac_indication_cb(struct net_if *net_if, const mcps_data_ind_t *data, +void ws_llc_mac_indication_cb(struct net_if *net_if, struct mcps_data_ind *data, const struct mcps_data_rx_ie_list *ie_ext); #endif diff --git a/6lbr/ws/ws_mngt.c b/6lbr/ws/ws_mngt.c index 4ef1daeba..a74b641d8 100644 --- a/6lbr/ws/ws_mngt.c +++ b/6lbr/ws/ws_mngt.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/6lbr/ws/ws_mngt.h b/6lbr/ws/ws_mngt.h index 1599df5b8..ff1abf2a6 100644 --- a/6lbr/ws/ws_mngt.h +++ b/6lbr/ws/ws_mngt.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/CHANGES.md b/CHANGES.md index 36c70086a..5b90f9119 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,75 @@ +v2.1.6 +------ + - Introduce `mac_address` parameter to manually configure the RCP's EUI-64. + - Accept `chan_plan_id = 160` for Chinese PHY. + - Fix Segmentation Fault on 6LoWPAN fragmentation failure. + - Fix memory leak when using `neighbor_proxy`. + - Fix multicast forwarding under heavy load: MPL buffers used to be kept in + the network for an unnecessarily long time, causing confusion with packet + chronology. + +v2.1.5 +------ + - Improve D-Bus `RoutingGraph`: + * FFNs neighbors that are not registered through RPL are no longer exposed. + They would be previously misinterpreted as LFNs during initial connection + or after expiration. + * Update signals are no longer emitted for renewed parent registrations + that do not include any parent change. + - Support LFN aggregation in RPL DAO packets (consecutive target options for + one common transit option). + - Fix use-after-free for multicast packets using MPL. + - Prevent segfault when using an external RADIUS server. + - Fix PMK/PTK configuration for LFNs, the FFN value would be used previously. + - Print backtrace on Segmentation Fault and other crash signals. + - Fix CPC error code logs. + +v2.1.4 +------ + - Fix interoperability issue with mode switch: do not include the base + PhyModeId in advertised POM-IEs. + - Terminate with a fatal error when a CRC error is detected on the bus: + missing HIF frames causes complex errors which are usually not recoverable. + - Use UTC timestamps in `pcap_file` instead of local timebase. + +v2.1.3 +------ + - Fix `neighbor_proxy`: routing has been broken for nodes more than 1 hop + away since `v1.7` when using that feature. + - Improve recovery when a previous neighbor is detected to have moved futher + away from the border router. Previously, `wsbrd` would keep trying to + communicate directly with the node until expiration of its address + registration. Now the neighbor entry is removed when a DAO indicates that + the border router is no longer a parent. + - Fix interoperability issue when operating in fixed channel: do not + advertise any excluded channels. + +v2.1.2 +------ + - Set the IPv6 hop limit to a fixed value when creating a tunnel, instead of + copying the received hop limit. Intermediate Wi-SUN hops are now invisible + to tools like `traceroute`, as it should be for any kind of IP tunnel. + - Include received acknowledgement frames in `pcap_file`. + - Change behavior of TBU endpoints `/config/borderRouter/joinMetrics` and + `/config/borderRouter/informationElements`: previous IEs/metrics are now + always removed when a new request is received. + +v2.1.1 +------ + - Fix high CPU usage during intense traffic: packet queues being full caused + a busy wait in the main loop. + - Fix `wshwping`: + * Fix incorrect frame format for parsing RCPv2 ping confirmations. + * Flush transmission queues on process interruption (`^C` no longer causes + a freeze at the next program start). + * Fix invalid and/or missing HIF traces for RCPv2. + - Fix JM-IE inclusion for TBU: + * Correctly update the content version number. + * Include the JM-IE in data frames for when PA transmissions are disabled + by the trickle algorithm. + * Insert JM-IE with no metrics instead of it being absent, otherwise + neighbors do not observe a new content version. + v2.1 ------ - Support separate PTK/PMK lifetimes between FFN and LFN. diff --git a/CMakeLists.txt b/CMakeLists.txt index 72ab02ee5..aee244c67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -154,6 +155,7 @@ add_library(libwsbrd STATIC common/trickle.c common/ws_regdb.c common/key_value_storage.c + common/ieee802154_frame.c common/ieee802154_ie.c common/ieee80211_prf.c common/time_extra.c @@ -405,7 +407,7 @@ if(COMPILE_DEVTOOLS) -Wl,--wrap=wsbr_common_timer_init -Wl,--wrap=wsbr_common_timer_process -Wl,--wrap=clock_gettime - -Wl,--wrap=signal + -Wl,--wrap=sigaction -Wl,--wrap=exit -Wl,--wrap=__tr_printf ) diff --git a/DBUS.md b/DBUS.md index d7bc39e03..ed185df8f 100644 --- a/DBUS.md +++ b/DBUS.md @@ -231,6 +231,14 @@ refreshed. Each entry is a structure: in the node's preferred order. The border router should be the only entry with no parents. +Implementation limitations: +- LFN directly connected to wsbrd will not be exposed after reboot until + their MAC timing information have been acquired. +- FFN directly connected to wsbrd and that do not have an entry in both RPL + and IPv6 neighbor discovery cache will not be exposed. This choice was made + considering an FFN without both entries cannot be considered operational. + Note potential children of such FFN may still be exposed through this API. + ### `Gtks` and `Gaks` (`aay`) Returns a list of the four Group Transient (or Temporal) Keys (GTKs) or Group diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..6eb00d59c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +#!/bin/echo run with: docker build . -f +# SPDX-License-Identifier: LicenseRef-MSLA +# SPDX-Copyright-Text: (c) 2024 Silicon Laboratories Inc. (www.silabs.com) + +FROM debian:12 + +RUN echo "# log: Setup system" \ + && set -x \ + && apt-get update -y \ + && apt-get install -y sudo make \ + && date -u + +ENV project wisun-br-linux +ENV workdir /usr/local/src/${project} +WORKDIR ${workdir} +COPY helper.mk ${workdir} +RUN echo "# log: Setup ${project}" \ + && set -x \ + && ./helper.mk setup \ + && date -u + +COPY . ${workdir} +WORKDIR ${workdir} +RUN echo "# log: Build ${project}" \ + && set -x \ + && ./helper.mk prepare build \ + && date -u diff --git a/LICENSES/LicenseRef-MSLA.txt b/LICENSES/LicenseRef-MSLA.txt new file mode 100644 index 000000000..356bfd629 --- /dev/null +++ b/LICENSES/LicenseRef-MSLA.txt @@ -0,0 +1,842 @@ +MASTER SOFTWARE LICENSE AGREEMENT + +Version 20221107 + +THIS MASTER SOFTWARE LICENSE AGREEMENT (“AGREEMENT”) GOVERNS YOUR USE OF THE +LICENSED MATERIALS. INSTALLING, COPYING OR OTHERWISE USING THE SOFTWARE, +INDICATES YOUR ACCEPTANCE OF THE TERMS OF THIS AGREEMENT REGARDLESS OF +WHETHER YOU CLICK THE “ACCEPT” BUTTON. IF YOU DO NOT AGREE WITH THESE TERMS +AND CONDITIONS OR IF YOU ARE NOT AUTHORIZED TO ACCEPT THE TERMS OF THIS +LICENSE ON BEHALF OF YOUR EMPLOYER, DECLINE THE LICENSE TERMS AND DO NOT USE +THE SOFTWARE OR DOCUMENTATION. THESE TERMS GOVERN YOUR CONTINUED USE OF THE +LICENSED MATERIALS THAT YOU DOWNLOAD NOW OR IN THE FUTURE, INCLUDING SUCH +ADDITIONAL SOFTWARE MADE AVAILABLE TO YOU THROUGH THE LICENSED MATERIALS YOU +HAVE SELECTED, AND ALL UPDATES AND VERSIONS OF SUCH SOFTWARE. + +1. Definitions. + + “Application” means a product developed by Licensee, or for Licensee by + a third party, that contains Licensed Programs. + + “Authorized Application” means an Application that contains, + integrates, is packaged with, or functions with a Silicon Labs Device + in Licensee’s Application. This includes a Licensed Program embedded in + a network co-processor or host processor that operates in conjunction + with a Silicon Labs Device. + + “Authorized Subcontractor” means a third-party subcontractor that you + engage to design or manufacture Authorized Applications and has + executed an agreement that is consistent with the terms of this + Agreement, including its confidentiality provisions. At all times, you + shall remain responsible for the actions or non-actions of you + Authorized Subcontractors the same as if the action on non-action was + committed by you. + + “Beta Software” means Software, including Software included within an + SDK, that is undergoing testing or further development, and has not + reached the generally available (GA) stage of development. + + “Commercial License” means an executed, in effect, software license + agreement between Licensee and Silicon Labs that governs Licensee’s + rights and obligations with respect to Licensee’s use of Micrium + Software. + + "Commercial Purpose” means embedding Micrium Software in any + Application that you sell or license to End Users or plan to do so. + + “Derivative Works” means a work based upon the Source Code version of + the Software, such as a revision, modification, translation, + abridgment, condensation, expansion or any other form in which such + Software may be recast, transformed or adapted, and that, if prepared + without authorization from Silicon Labs, would constitute copyright + infringement. + + “Development Tool” means a software provided by Silicon Labs to enable + development of Authorized Applications, configuration of Silicon Labs + Devices and Software. + + “Documentation” means Silicon Labs technical documentation related to + the Software, excluding advertising or marketing materials. + + “Embedded Stacks” means Software (other than Micrium Software) that is + stack libraries, application layers, and example code. + + “End User” means a purchaser, sublicensee, recipient and/or user of an + Application obtained directly or indirectly from Licensee. + + “External Manufacturers” means a third-party manufacturer, including + such manufacturer's subcontractors and agents, which is authorized by + Licensee to design and/or manufacture the Applications and to use, + install, and test the Applications and the Licensed Programs. + + “Firmware” means executable or binary code that is embedded in the + Silicon Labs Device in ROM or flash memory and cannot be modified by + Licensee. + + “Licensee” or “you” means the acquirer of the license rights granted by + this Agreement. If you are an individual working solely on your own + behalf, then you are the Licensee. If you are an employee working on + behalf of your employer, then your employer is the Licensee and you + confirm that you are authorized to accept the terms of this Agreement + on behalf of your Employer. + + “Licensed Programs” means Software in Object Code form that was either + originally in Object Code form or was compiled from the Software or + Derivative Works and is designed to operate in Applications in + Authorized Applications. + + “Licensed Materials” means Software and the related Documentation + including all updates and upgrades of the foregoing. + + “Micrium Software” means the Micrium real time kernel within the + Micrium real time operating system (Micrium OS). + + “Modified Open Source Software” means Silicon Labs' modifications to + Open Source Software that was created by a third party. + + “Object Code” means computer programming code in binary form suitable + for machine execution by a processor without the intervening steps of + interpretation or compilation. + + “Open Source Software” means the Source Code version of software that + may be freely used, modified or distributed without payment of a + license fee or royalties subject to the terms of a publicly available + software license, excluding Modified Open Source Software, the use of + which is subject to the terms of this Agreement. + + “Personal Information” means data concerning an individual user, + including but not limited to a user’s activity on a Silicon Labs + website, location, IP address, mobile device ID, name, or biometric + data collected, stored or transmitted by a Silicon Lab Device or + Software. + + “SDK” means software development kit (other than Micrium Software). + + “Silicon Labs” means Silicon Laboratories Inc., a Delaware corporation + located at 400 W. Cesar Chavez, Austin, TX 78701 if you are physically + located within the United States. If you are physically located outside + of the United States, Silicon Labs means Silicon Laboratories + International Pte Ltd., a Singapore corporation located at No. 18 Tai + Seng Street, #05-01, 18 Tai Seng, Singapore 539775. + + "Silicon Labs Devices” means Silicon Labs branded integrated circuit + chips purchased from Silicon Labs or one of its authorized + distributors. + + “Silicon Labs Open Source Code” means Software created by Silicon Labs + and which is (a) delivered to Licensee in Source Code format, (b) is + identified as open source code and (c) states that use of the software + is subject to the terms of this Agreement. + + “Software” means the computer programing code that was downloaded or + otherwise distributed to Licensee and which is the subject of this + Agreement. Software may be in Object Code or Source Code form or may be + embedded as Firmware in a Silicon Labs Device. Software includes + Embedded Stacks, SDKs and Development Tools. Your rights are different + depending on whether the Software is delivered to you in Object Code, + Source Code or Firmware. Software that is Micrium Software is subject + to specific terms and conditions defined in Section 2. + + “Source Code” means the computer programming code in an uncompiled form + readable by humans which cannot be executed by a processor unless it is + compiled into binary form. + + “Third Party Software” means any software that Silicon Labs has + licensed from a third party. + + “Warranty Period” means the period of time ending thirty (30) days + after the first delivery of the Software to the Licensee, whether such + delivery is in the form of a download or actual physical delivery. + + “Unauthorized Use” means use or inclusion of the Licensed Materials in + (a) aeronautical, aerospace, military or nuclear applications; (b) FDA + Class III or other devices for which FDA premarket approval is + required; (c) implantable devices; (d) life support or life endangering + applications where failure or inaccuracy might cause death or personal + injury; and (e) automotive or transportation applications or + environments unless the specific Silicon Labs Device has been + designated by Silicon Labs as compliant with ISO/TS 16949 requirements. + +2. Micrium Software. + + The terms and conditions in this Section 2 apply only to Micrium + Software and take precedence over any other conflicting terms of this + Agreement. + + 2.1. Grant of Micrium Software License. Upon accepting this Agreement + and downloading the Micrium Software, subject to your compliance with + the terms of this Agreement, Silicon Labs hereby grants you a limited, + non-exclusive, nontransferable license for the Term (as described in + Section 23), as follows: + + 2.1.1. You and your Authorized Subcontractors may modify the Source + Code version of Micrium Software for the sole purpose of adapting the + Micrium Software to your application. + + 2.1.2. You may embed the Micrium Software exclusively in products + developed by you or by your Authorized Subcontractors on your behalf + during the Term that embed the Micrium Software into Silicon Labs + Devices (the “End Products”). + + 2.1.3. You may distribute copies of the Object Code version of the + Micrium Software solely to the extent that such copies are embedded in + End Products. + + 2.2. Micrium Software License Restrictions. Your use of the Micrium + Software is subject to the following restrictions: + + 2.2.1. You may allow Authorized Subcontractors to access and use the + Micrium Software solely to the extent necessary to adapt the Micrium + Software to your application. + + 2.2.2. Except as provided in this Agreement, neither you, your + Authorized Subcontractors, nor any of your downstream customers may + sell, transfer, sublicense, distribute, or disseminate in any way the + Object Code or executable code of the Micrium Software in any written + or electronic manner. + + 2.2.3. Neither you, your Authorized Subcontractors, nor any of your + downstream customers may distribute the Source Code version of Micrium + Software to any third party under any circumstances. You shall ensure + that each of your employees and Authorized Subcontractors that work + with Micrium Software are aware of this restriction. + + 2.2.4. Except as permitted in this Agreement, neither you, your + Authorized Subcontractors, nor any of your downstream customer may + embed the Micrium Software in any integrated circuit device that is not + a Silicon Labs Device. + + 2.3. End User Support. You agree to be fully responsible for all End + User support services and warranty costs for all End Products. + + 2.4. Commercial Purpose. You are permitted to use the Micrium Software + for a Commercial Purpose only if you embed the Micrium Software into a + Silicon Labs Device. You may not embed the Micrium Software in a + non-Silicon Labs Device unless you and Silicon Labs execute a separate + Commercial License Agreement expressly permitting such use. + + 2.5. Ownership. Silicon Labs is and shall remain the sole and exclusive + owner of the Micrium Software and all Documentation, media, manuals, + specifications, instructions and printed materials, and any copies or + portions thereof, furnished by Silicon Labs for use with the Micrium + Software. You own any improvements or modifications to the Micrium + Software made by you or your Authorized Subcontractor on your behalf to + adapt Micrium Software for use in your End Products. + + 2.6. Maintenence and Support. Standard maintenance and technical + support, such as bug fixes, correction of failures, updates and + maintenance patches is provided to you at no cost for one year from + date that you download the Micrium Software. Silicon Labs may use a + variety of methods, including but not limited to telephone, Internet + and/or e-mail, to provide such maintenance and support. + +3. 8051 SDK. + + The terms and condition in this Section 3 apply only to the 8051 SDK + and take precedence over any other conflicting terms of this Agreement. + + 3.1. 8051 SDK. The 8051 SDK consists of the following items: + + 3.1.1. Drivers; + + 3.1.2. Peripheral libraries (excluding CSLIB); and + + 3.1.3. Example application code. + + 3.2. Installation and Use Rights. + + 3.2.1. You may download and install the 8051 SDK on one or more + computers and make any number of copies. + + 3.2.2. You may internally evaluate the 8051 SDK. If you elect to use + the 8051 SDK for any other purpose, including modification and + distribution, then the following additional terms apply to you. + + 3.2.3. You may modify any files for your own use. + + 3.2.4. You may redistribute to your customers applications that you + develop using the 8051 SDK. Your redistribution may be in any form, + including executable binary code, source code, physical media and + Internet downloads. + + 3.3. Restrictions. + + 3.3.1. You may not use the 8051 SDK with any integrated circuit + products other than those designed and manufactured by Silicon Labs. + + 3.3.2. Except as provided above, you may not redistribute, sublicense, + assign, rent or lease any portion of the 8051 SDK to any third party. + + 3.3.3. You may not modify or distribute the 8051 SDK so that all or any + part of it becomes Open Source Software. + + 3.3.4. You may not obscure or remove any product identification, + copyright or other notices that appear on or in the 8051 SDK, including + any notices from third parties. + + 3.3.5. You may not redistribute any modified or unmodified version of + the 8051 SDK to any third party as a standalone product. + + 3.4. Ownership. Silicon Labs is and shall remain the owner of the 8051 + SDK at all times. Applications that you develop using the 8051 SDK + shall belong to you. + +4. License Grant. + + Silicon Labs hereby grants Licensee a limited, non-transferable, + non-exclusive, perpetual license to use the Licensed Materials solely + under the following terms and condition: + + 4.1. Object Code. With respect to Software (other than Micrium + Software) that is delivered to Licensee by Silicon Labs in Object Code + format, Licensee may: + + 4.1.1. (a) if the Software is an Embedded Stack, you may install one + copy of the Software and its components all together on a single + computer, and if the Software is copied onto another computer, the + original copy must be deleted or otherwise made irreversibly + inoperable; (b) if the Software is an SDK or a Development Tool, you + may make multiple copies of the Software for your own internal use; + + 4.1.2. store one copy of the Software for archival (non-operational) + purposes only, so long as access to such copy is restricted; + + 4.1.3. use the Licensed Materials to develop applications to be used to + program Silicon Labs Devices; + + 4.1.4. incorporate the Licensed Materials into Authorized Applications; + + 4.1.5. facilitate the integration of the Licensed Materials and Silicon + Labs Devices into Authorized Applications; and + + 4.1.6. distribute copies of the Licensed Materials to Licensee’s + end-user customers, to the extent such copies are in Object Code form + only and are incorporated into Authorized Applications. + + 4.2. Source Code. With respect to Software (other than Micrium Software + and Silicon Labs Open Source Software) that is delivered to Licensee by + Silicon Labs in Source Code format, Licensee may: + + 4.2.1. use the sample application software in Source Code format to + develop and compile applications for use in Authorized Applications; + + 4.2.2. copy, prepare Derivative Works of, compile and modify Source + Code of the Silicon Labs Software, solely to enable Licensee to design, + develop, modify, test, support and/or debug Derivative Works and/or + Licensed Programs that are intended to operate in Authorized + Applications; + + 4.2.3. reproduce and distribute Derivative Works to Authorized + Subcontractors under agreements consistent with Licensee’s rights and + obligations under this Agreement solely (a) to modify for Licensee’s + use in developing and maintaining the Licensed Programs; and (b) to + enable Licensee to distribute Licensed Programs externally to End Users + in accordance with Section 4.2.5 below; + + 4.2.4. reproduce and distribute Licensed Programs internally and to + Licensee’s External Manufacturers under agreements consistent with + Licensee’s rights and obligations under this Agreement, solely (a) for + Licensee’s use in developing and maintaining the Licensed Programs; and + (b) to enable Licensee to distribute Licensed Programs externally to + End Users in accordance with Section 4.2.5 below; and + + 4.2.5. distribute Licensed Programs externally to Licensee’s End Users, + either directly or through Licensee’s distribution channels and + methods, but only for use with Authorized Applications and not on a + standalone basis. + +5. License Restrictions. + + The Licensed Materials shall only be used as permitted by this + Agreement. Any use of the Licensed Materials not specifically + authorized by this Agreement is prohibited. + + 5.1. Without limiting the foregoing restriction, and except as + authorized by this Agreement, Licensee shall not: + + 5.1.1. assign, sublicense, or otherwise transfer the Licensed Materials + to any third party; + + 5.1.2. reverse compile, disassemble, alter, add to, delete from, or + otherwise modify Software delivered to Licensee in Object Code form or + in libraries in the Licensed Materials; + + 5.1.3. publish the Licensed Materials in any manner that would cause it + to become part of the public domain or otherwise become subject to the + terms of an Open Source Software license; + + 5.1.4. use the Licensed Materials except in conjunction with Silicon + Labs Devices; + + 5.1.5. distribute the Source Code form of Software to any third party, + in whole or in part; or + + 5.1.6. remove any copyright, trademark, patent or other proprietary + notices from the Licensed Materials or any portion thereof. + + 5.2. Licensee shall not use the Licensed Materials in any way to + further the development or improvement of any product that does or + would compete with any Silicon Labs Device. + + 5.3. If the Software is provided to demonstrate the capability of + Silicon Labs Devices, it shall be used only for this purpose. + Incorporation of the demonstration version of Silicon Labs Software + into Applications is solely at Licensee’s risk and liability. + + 5.4. Any subsequent distribution or transfer of the Licensed Programs + to End Users shall remain subject to the terms and conditions of this + Agreement. Whether by execution of an end-user license agreement or + other commercially reasonable means, Licensee shall ensure that its End + Users’ use of the Licensed Programs shall only be permitted if they are + incorporated into Authorized Applications. Licensee shall prohibit any + further sublicensing, distribution, sale, marketing, reproduction, + modification, reverse engineering or decompiling of the Licensed + Programs. + + 5.5. Licensor may include features in the Software to restrict use of + the Software that does not comply with the terms of this Agreement. + +6. Unauthorized Use. + + The Licensed Materials are not licensed, designed, intended, + authorized, or warranted for Unauthorized Use. Licensee shall be solely + and exclusively responsible for any Unauthorized Uses by Licensee, + Licensee’s Authorized Subcontractors, Licensee’s End Users or other + sublicensees, and any Unauthorized Use by such Authorized + Subcontractors, End Users or sublicensees, with or without the + knowledge of Licensee, shall be attributed to Licensee. Licensee agrees + to defend and indemnify Silicon Labs for all third-party claims and for + all damages, costs and fees, including Silicon Labs’ attorneys’ fees, + arising from any such Unauthorized Use of the Licensed Materials. + +7. Open Source Software. + + 7.1. If the Software includes any Open Source Software, such Software + and the relevant Open Source Software license under which such Software + is licensed are disclosed at www.silabs.com. All use of such Open + Source Software by Licensee is subject to the terms of the relevant + open source software license and Licensee’s use of such Software is + expressly conditioned upon Licensee’s compliance with the term of such + license. + + 7.2. If the Software is Silicon Labs Open Source Code, then the + following provisions apply: + + 7.2.1. Silicon Labs hereby grants to Licensee a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable copyright license + to reproduce, prepare Derivative Works of, publicly display, publicly + perform, sublicense, and distribute Silicon Labs Open Source Code and + such Derivative Works in Source Code or Object Code form. + + 7.2.2. Silicon Labs hereby grants to Licensee a perpetual, worldwide, + non-exclusive, no-charge, royalty-free, irrevocable (except as stated + in this section) patent license to make, have made, use, offer to sell, + sell, import, and otherwise transfer the Silicon Labs Open Source Code, + where such license applies only to those patent claims licensable by + Silicon Labs that are necessarily infringed by Licensee’s use of the + Silicon Labs Open Source Code or by combination with any other device + or software. + + 7.2.3. Licensee may add Licensee’s own copyright statement to + Licensee’s modifications of Silicon Labs Open Source Software and may + provide additional or different license terms and conditions for use, + reproduction, or distribution of such modifications, or for any such + Derivative Works as a whole, provided Licensee’s use, reproduction, and + distribution of the Silicon Labs Open Source Software otherwise + complies with the conditions stated in this License. + + 7.2.4. Licensee may reproduce and distribute copies of the Silicon Labs + Open Source Code or Derivative Works thereof in any medium, with or + without modifications, and in Source Code or Object Code form, provided + that Licensee meets the following conditions: (a) Licensee must give + any other recipients of the Silicon Labs Open Source Code or Derivative + Works a copy of this License; and (b) Licensee must cause any modified + files to carry prominent notices stating that Licensee changed the + files; and (c) Licensee must retain, in the Source Code form of any + Derivative Works that Licensee distributes, all copyright, patent, + trademark, and attribution notices from the Source Code form of the + Silicon Labs Open Source Code, excluding those notices that do not + pertain to any part of the Derivative Works; and (d) If the Silicon + Labs Open Source Code includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that Licensee distributes must + include a readable copy of the attribution notices contained within + such NOTICE file, excluding those notices that do not pertain to any + part of the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source Code form or documentation, if provided along with + the Derivative Works; or, within a display generated by the Derivative + Works, if and wherever such third-party notices normally appear. The + contents of the NOTICE file are for informational purposes only and do + not modify the License. Licensee may add Licensee’s own attribution + notices within Derivative Works that Licensee distributes, alongside or + as an addendum to the NOTICE text from the Silicon Labs Open Source + Code, provided that such additional attribution notices cannot be + construed as modifying the License. + + 7.3. With respect to Software that is not Open Source Software, + Licensee shall not: + + 7.3.1. cause the Software to become subject to any Open Source Software + license, including but limited to the general public license (GPL) or + the lesser general public license (LGPL); + + 7.3.2. cause the Software to be disclosed into the public domain or to + any third party except for those third parties to whom License is + authorized to distribute Licensed Programs under Sections 4.1.6 or + 4.2.5; or + + 7.3.3. cause any part of the Software to become a derivative of any + Open Source Software. + + 7.4. Licensee shall not enable or permit any of its End Users to breach + the provisions of this Section 7, and shall include similar restrictive + provisions in its end user license agreement with such End Users. If + Licensee breaches this Section 7, Licensee shall indemnify and hold + Silicon Labs harmless from all costs, claims, settlements and judgments + incurred by Silicon Labs, including attorneys’ fees, in the process of + defending, challenging and/or settling any demand, claim or order that + the Software is subject to an Open Source Software license or must be + disclosed into the public domain or to any third party. + +8. Modified Open Source Software. + + Notwithstanding the terms of the Open Source Software license under + which the Open Source Software is licensed, the following terms apply + to modifications to such Open Source Software that constitute Modified + Open Source Software, as defined in this Agreement. The following terms + apply regardless of how the Modified Open Source Software was delivered + to you. + + 8.1.1. You may not use Modified Open Source Software except for use + with Licensed Programs that are intended to operate in Authorized + Applications. + + 8.1.2. You may not obscure, modify or remove copyright notices, files + or statements concerning ownership by Silicon Labs or reference to the + terms of this Agreement. + + 8.1.3. Subject to Sections 8.1.1 and 8.1.2: + + 8.1.3.1. You may copy and compile the Source Code of the Modified Open + Source Software. + + 8.1.3.2. You may reproduce the Object Code and Source Code versions of + Modified Open Source Software and distribute the same through multiple + levels of distributions, including to your External Manufacturers. + + 8.1.3.3. You may modify Modified Open Source Software and create + Derivative Works of Modified Open Source Software. + +9. Third Party Software. + + 9.1. If the Software contains any Third Party Software, all use of such + Third Party Software shall be subject to the terms of the license from + such third party to Silicon Labs or a separate end user license + agreement, if available, which may be set forth in the header files of + the Third Party Software. You agree to comply with all terms and + conditions for use of Third Party Software. + + 9.2. Silicon Labs has licensed the BLE Homekit from Apple. You may not + download or use the BLE Homekit software unless you have executed a MFi + License with Apple. + + 9.3. Silicon Labs has licensed emWin software, including libraries and + executables and related documentation (collectively “emWin Library”) + from Segger Microcontroller GmbH. You are entitled to use the emWin + Library free of charge, subject to the following conditions, which you + accept by virtue of accepting the terms of this Agreement: (a) you may + use the emWin library exclusively with EFM 32-bit microcontrollers and + EFR radios; (b) you may not use the emWin Library to create or develop + software that is similar to or competitive with the emWin Library; and + (c) you may not modify the documentation that accompanies the emWin + Library. + + 9.4. Silicon Labs does not make any endorsements or representations + concerning Third Party Software and disclaims all implied warranties + concerning Third Party Software. Third Party Software is offered “AS + IS.” + +10. Inspection Rights. + + Silicon Labs shall have the right, upon reasonable advance notice, to + inspect Licensee's records and facilities with respect to the + manufacture of Applications and to receive sample units of Applications + in order to verify that such manufacturing is within the scope of this + Agreement, that there are appropriate security procedures to protect + Silicon Labs’ Confidential Information, and that Licensee is in + compliance with its other obligations under this Agreement. + +11. No Other Licenses. + + The licenses granted under this Agreement are specifically set forth + herein, and no licenses are granted by Silicon Labs to Licensee by + implication or estoppel, and no licenses shall be granted by the + parties’ course of doing business. + +12. Beta Software. + + Beta Software, whether Object Code or Source Code (a) can only be used + for internal development, demonstration or testing purposes; (b) cannot + be included within Licensee’s or End-Users’ products that are intended + for general release or high-volume production; and (c) cannot be used + to support Z-Wave certification of Silicon Labs Devices. Silicon Labs + does not offer any warranties on Beta Software and disclaims all + implied warranties including, but not limited to merchantability, + fitness for use and noninfringement. Beta Software is offered “AS IS.” + Under no circumstances will Silicon Labs incur any liability or + obligation to you related to your use of Beta Software. Any use of Beta + Software by you in violation of the terms of this Agreement shall + automatically terminate your right to use Beta Software for any purpose + whatsoever. + +13. Upgrades, Updates, New Versions. + + Although it has no obligation to do so, Silicon Labs may introduce + updates, upgrades or new versions of the Software from time to time. + Licensee is under no obligation to download or use the updates, upgrade + or new version of Software; however, if Licensee elects to do so, the + licenses granted to Licensee pursuant to this Agreement shall be deemed + to include such updates, upgrades and new versions. In the case of any + bug fix, improvement, work-around, or correction made to the Software + by Licensee, Licensee agrees to provide to Silicon Labs, at no cost, + the source code and any documentation reasonably required for Silicon + Labs to be able to incorporate such changes into the Silicon Labs + Software. + +14. Regulatory Compliance. + + Silicon Labs does not warrant that Software or any Application will + comply with the regulatory requirements of the United States or any + other country. Licensee is solely responsible for complying with such + requirements and for obtaining necessary government certifications, if + any. + +15. License Fee and Royalties. + + Unless Licensee has executed a Commercial License with Silicon Labs, + Licensee is not obligated to pay any license fees or royalties to + Silicon Labs so long as Licensee complies with the terms of the + licenses set forth herein. If Licensee has executed a Commercial + License, Licensee agree to pay all license fees, maintenance fees and + subscription fees described in such Commercial License. + +16. No Resale Fees. + + Licensee may not directly or indirectly charge any fee or otherwise + require or accept any type of monetary compensation solely for + redistributing the Licensed Materials which is in excess of any amount + paid to Silicon Labs for the same Licensed Materials. This does not + apply to the sale of hardware products having the Licensed Materials in + object code form embedded within. + +17. Proprietary Rights. + + All rights and title in and to the Licensed Materials, including + without limitation, patents, copyrights, moral rights, trademarks and + trade secret rights, belong to Silicon Labs or its licensors. Except + for the rights expressly granted herein, no other rights are granted to + Licensee with respect to the Licensed Materials. + +18. Confidential Information. + + You agree that the Licensed Materials contain confidential information, + including trade secrets, know-how and other information, that comprise + the exclusive property of Silicon Labs or its licensors. During the + period this Agreement is in effect and at all times after its + termination, you shall maintain the confidentiality of this information + and shall not sell, license, sublicense, publish, display, distribute, + disclose or otherwise make available this information to any third + party nor use such information except as authorized by this Agreement. + +19. Limited Warranty and Remedies. + + Silicon Labs warrants that, during the Warranty Period, the Software + will function substantially in accordance with the Documentation when + used with Silicon Labs Devices and that the media on which the Software + is furnished will be free from defects in material and workmanship, + under normal use and service, when correctly installed and maintained. + Silicon Labs does not warrant that the functions in the Licensed + Materials will meet Licensee’s specific requirements or that the + operation of the Software will be uninterrupted or error free. Silicon + Labs does not warrant that the Software does not contain any viruses or + bugs. If Licensee notifies Silicon Labs, during the Warranty Period, of + a failure of the Software to conform to the limited warranty stated in + this section, Silicon Labs’ sole obligation, and Licensee’s sole + remedy, will be, at Silicon Labs’ sole discretion: (i) replacement of + the Software, or part thereof, with a functionally equivalent software + product or part, or (ii) repair of the Software. Without limiting any + term or condition stated in this Agreement, this warranty does not + apply to any nonconformance caused by (A) improper or inadequate + maintenance or calibration, or (B) software or interfacing equipment, + parts or supplies not supplied by Silicon Labs or its authorized + distributor, (C) modifications to the Software or (D) Unauthorized Use + of the Software. + +20. WARRANTY DISCLAIMER. + + EXCEPT AS PROVIDED ABOVE IN SECTION 19, THE LICENSED MATERIALS ARE + PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT + AND THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LICENSED + MATERIALS IS WITH LICENSEE. SILICON LABS DOES NOT WARRANT THAT THE + LICENSED MATERIALS ARE FREE FROM DEFECTS THAT COULD CAUSE VULNERABILITY + TO CYBER-ATTACK, DATA BREACH OR PRIVACY VIOLATIONS. SILICON LABS + DISCLAIMS ALL LIABILITY RELATED TO LICENSEE’S DATA THAT MAY BE + RECEIVED, STORED OR USED BY SILICON LABS DEVICES OR SOFTWARE OR + INTERCEPTED BY THIRD PARTIES. SILICON LABS DISCLAIMS ALL LIABILITY FOR + DAMAGES CAUSED BY THIRD PARTIES, INCLUDING MACILICOUS USE OF, OR + INTEFERENCE WITH TRANSMISSION OF, LICENSEE’S DATA. + +21. LIMITATION OF LIABILITY. + + SILICON LABS’ SOLE OBLIGATION OR LIABILITY UNDER THIS AGREEMENT IS THE + REPAIR OR REPLACEMENT OF THE LICENSED MATERIALS ACCORDING TO THE + LIMITED WARRANTY ABOVE. IN NO EVENT SHALL SILICON LABS OR ANY OF ITS + AFFILIATES OR SUPPLIERS BE LIABLE FOR CONSEQUENTIAL, SPECIAL, + INCIDENTAL OR SIMILAR DAMAGES, SUCH AS (BUT NOT LIMITED TO) LOSS OF + BUSINESS REVENUES, PROFITS OR SAVINGS OR LOSS OF DATA RESULTING FROM + THE USE OR INABILITY TO USE THE LICENSED MATERIALS, EVEN IF SILICON + LABS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY + CLAIM BY ANY THIRD PARTY. THIS INCLUDES, BUT IS NOT LIMITED TO, DAMAGES + ARISING FROM THE FAILURE OF THE SILICON LABS DEVICE TO TRANSMIT DATA + ARISING FROM A FAILURE OF THE SOFTWARE TO PERFORM IN SUBSTANTIAL + ACCORDANCE WITH THE DOCUMENTATION. IN NO EVENT SHALL THE TOTAL + CUMULATIVE LIABILITY OF SILICON LABS TO LICENSEE FOR ALL MATTERS + RELATED TO THE LICENSED MATERIALS EXCEED THE AMOUNT PAID BY LICENSEE TO + SILICON LABS FOR SUCH LICENSED MATERIALS OR ONE UNITED STATES DOLLAR + ($1.00 USD). YOU ACKNOWLEDGE THAT THE AMOUNT PAID BY YOU FOR THE + LICENSED MATERIALS REFLECTS THIS ALLOCATION OF RISK. + +22. Data Collection. + + To the extent that Silicon Labs Devices collect, store or transfer + Personal Information, Silicon Labs may use such Personal Information + for its own internal purposes, including marketing Silicon Labs Devices + to the user. Silicon Labs will not sell Personal Information to third + parties. Silicon Labs Devices will not transfer Personal Information to + other devices in a network or to third parties except to the extent + necessary to perform the intended function of the Silicon Labs Device. + Silicon Labs will not be liable to Licensee or Licensee’s customers for + (a) any intended transfer of Personal Information described in the + Documentation for the Silicon Labs Device; (b) any unintended transfer + of Personal Information or loss of data caused by any third parties or + third party devices or software, including hacking, malware, + eavesdropping, man-in-the-middle attacks or other intentional acts; or + (c) unauthorized access to or misuse of Personal Information by third + parties. + +23. Term and Termination. + + This Agreement will take effect on the date the Licensed Materials are + acquired by or delivered to Licensee, and will remain in effect unless + terminated as provided below. If you breach any of your obligations + under this Agreement, this Agreement will immediately and automatically + terminate. You may terminate this Agreement at any time by destroying + all copies of the Licensed Materials. Upon termination of this + Agreement, you shall immediately discontinue the use of the Licensed + Materials and shall return or provide certification to Silicon Labs of + the destruction of all copies of the Licensed Materials. You many keep + one copy of the Licensed Materials for archival (non-operational) + purposes only, so long as access to such copies is restricted. If the + Agreement is terminated by Silicon Labs, you may continue to distribute + copies of the Software already installed in finished inventory, but you + may not make any additional copies or install the Software in + additional products. All provisions of this Agreement relating to + disclaimers of warranties, limitation of liability, remedies or + damages, and Silicon Labs’ proprietary rights, shall survive any + termination of this Agreement for any reason. + +24. Termination of License. + + If you institute patent litigation against Silicon Labs or any of its + Affiliates (including a cross-claim or counterclaim in a lawsuit) + alleging that the Licensed Programs directly or indirectly infringe a + patent of Licensee, then any patent licenses granted to you under this + Agreement for that Licensed Program shall terminate as of the date such + litigation is filed. + +25. Export Restrictions. + + You may not export or re-export the Software or any Licensed Programs, + or any copy thereof, in violation of any applicable laws or + regulations. + +26. Amendments. + + This Agreement may be amended unilaterally by Silicon Labs at any time. + The most recent version of this Agreement supersedes and replaces all + prior versions. In the event of any conflicting terms, the terms of the + most recent version of this Agreement shall control. + +27. Miscellaneous. + + This Agreement sets forth the entire agreement and understanding + between the parties and neither party shall be bound by any conditions, + definitions, warranties, understandings or representations with respect + to the subject matter hereof other than as provided herein or as duly + set forth on or after the date hereof in writing and signed by a proper + and duly authorized representative of the party to be bound thereby. + The failure of any party at any time to require performance of any + provision of this Agreement shall in not affect the right of such party + to enforce the terms of this Agreement at a later time. No waiver by + any party of any condition or of any breach of any term contained in + this Agreement, in any one or more instances, shall be construed as a + further or continuing waiver of any such condition or of any breach of + any such term or any other term set forth in this Agreement. If any + provision of this Agreement is unenforceable for any reason, the + remaining terms of the Agreement shall not be deemed invalid, + inoperative, or unenforceable and, if possible, the unenforceable + provision shall be modified or interpreted in a manner to make it + enforceable. + +28. Governing Law. + + This Agreement shall be governed by the laws of the State of Texas, + United States of America, without regard to that state’s conflicts of + laws rules. The 1980 United Nations Convention on Contracts for the + International Sale of Goods shall not apply. In any dispute arising out + of this Agreement, the parties each consent to the exclusive personal + jurisdiction and venue in the State and Federal courts located within + Travis County, Texas, United States of America. All disputes concerning + this Agreement shall be resolved by binding arbitration in Travis + County, Texas before a single arbitrator. The arbitration shall be + administered by JAMS pursuant to JAMS’ Streamlined Arbitration Rules + and Procedures. The arbitration award shall include an award of + attorneys’ fees to the prevailing party. Judgment on the award may be + entered in any court having jurisdiction. This clause shall not + preclude parties from seeking provisional remedies in aid of + arbitration from a court of appropriate jurisdiction. + +29. Injunctive Relief. + + The copying, disclosure, or use of the Software in a manner + inconsistent with any provision of this Agreement or the improper use + of the Silicon Labs trademarks may cause irreparable injury to Silicon + Labs for which Silicon Labs may not have an adequate remedy at law. + Silicon Labs may be entitled to equitable relief in court, including + but not limited to temporary restraining orders, preliminary + injunctions and permanent injunctions. + +30. Silicon Labs Trademarks. + + Silicon Labs and the Silicon Labs logo are trademarks of Silicon + Laboratories Inc. in the United States and other countries. No use of + the Silicon Labs trademarks by Licensee is implied or consented to by + Silicon Labs by entering into this Agreement. + +31. Commercial Computer Software. + + If Licensee is an agency of the U.S. Government, the following will + apply: The Software has been developed entirely at private expense, is + regularly used for nongovernmental purposes and has been licensed to + the public. The Software is a “commercial item” as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer + software” and “commercial computer software documentation” as those + terms are used in 48 C.F.R. 12.212 (Sept. 1995) or as “commercial + computer software” as that term is defined in 48 C.F.R. 252.227-7014 + (June 1995) or any equivalent agency regulation or contract clause, + whichever is applicable. Consistent with 48 C.F.R. 12.212 and 48 C.F.R. + 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government agencies + acquire only those rights to the Software as are expressly set forth + herein. diff --git a/README.md b/README.md index 5c154ba46..d57bcc7e3 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,8 @@ currently supported are EFR32FG12, EFR32MG12, EFR32FG25, EFR32FG28, and EFR32ZG28. The RCP needs to be flashed with a specific firmware to communicate with the -daemon. This firmware is provided in binary format. To help users deploy and -evaluate the solution, a [wisun-br-linux-docker][docker] repository is -provided. It contains a bundle of all the necessary software components -(including a compiled RCP firmware image) to run the Linux Wi-SUN border -router. - -Alternatively, [Application Note 1332][an1332] explains how to build RCP -firmware and flash it. +daemon. This firmware is provided in binary format. [Application Note 1332][an1332] +explains how to build RCP firmware and flash it. The communication between the Linux host and the RCP is supported through a serial link (UART). On Silicon Labs mainboards, this serial link is provided @@ -113,8 +107,9 @@ example is available in `/usr/local/share/doc/wsbrd/examples/wsbrd.conf`. You can copy and edit it. You will notice that you need certificates and keys to authenticate your network's Wi-SUN nodes. The generation of these files is -described in [[Generate Wi-SUN PKI]]. For now, you can use the certificate -examples installed in `/usr/local/share/doc/wsbrd/examples/`. +described in [[Generating the Wi-SUN Public Key Infrastructure]]. For now, you +can use the certificate examples installed in +`/usr/local/share/doc/wsbrd/examples/`. You also must provide the path of the UART representing your RCP device. @@ -140,7 +135,7 @@ Some of these are not compiled by default and require setting | `wshwping` | A tool for testing the serial link | | `wstbu` | An implementation of the [Wi-SUN Test Bed Unit REST API][tbu] | -[tbu]: https://app.swaggerhub.com/apis/Wi-SUN/TestBedUnitAPI/1.0.18 +[tbu]: https://bitbucket.org/wisunalliance/test-bed-unit-api # Using `wsbrd_cli` and the D-Bus Interface diff --git a/cmake/FindCargo.cmake b/cmake/FindCargo.cmake index ba6fae4ef..19e1a9e22 100644 --- a/cmake/FindCargo.cmake +++ b/cmake/FindCargo.cmake @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/cmake/FindRust.cmake b/cmake/FindRust.cmake index 18b060aab..3673bf785 100644 --- a/cmake/FindRust.cmake +++ b/cmake/FindRust.cmake @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/backtrace_show.c b/common/backtrace_show.c index ed5bc949e..c1884f7da 100644 --- a/common/backtrace_show.c +++ b/common/backtrace_show.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/backtrace_show.h b/common/backtrace_show.h index b67a24229..8c2456a5e 100644 --- a/common/backtrace_show.h +++ b/common/backtrace_show.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/bits.c b/common/bits.c index b689849c0..b3f3f1d0a 100644 --- a/common/bits.c +++ b/common/bits.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/bits.h b/common/bits.h index 7ed586d09..346b0724d 100644 --- a/common/bits.h +++ b/common/bits.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/bus.h b/common/bus.h index 06d8121d4..52c7d01f7 100644 --- a/common/bus.h +++ b/common/bus.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/bus_cpc.c b/common/bus_cpc.c index 93c6616dc..42d0f81ca 100644 --- a/common/bus_cpc.c +++ b/common/bus_cpc.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -29,9 +30,9 @@ int cpc_open(struct bus *bus, const char *cpc_instance, bool verbose) int ret, fd; ret = cpc_init(&bus->cpc.handle, cpc_instance, verbose, cpc_reset_callback); - FATAL_ON(ret, 2, "cpc_init: %m"); + FATAL_ON(ret, 2, "cpc_init: %s", strerror(-ret)); fd = cpc_open_endpoint(bus->cpc.handle, &bus->cpc.endpoint, SL_CPC_ENDPOINT_WISUN, 1); - FATAL_ON(fd < 0, 2, "cpc_open_endpoint: %m"); + FATAL_ON(fd < 0, 2, "cpc_open_endpoint: %s", strerror(-fd)); // ret = cpc_set_endpoint_option(bus->cpc_ep, CPC_OPTION_BLOCKING, (void *)true, sizeof(bool)); // FATAL_ON(ret, 2, "cpc_set_endpoint_option: %m"); return fd; @@ -42,7 +43,7 @@ int cpc_tx(struct bus *bus, const void *buf, unsigned int buf_len) int ret; ret = cpc_write_endpoint(bus->cpc.endpoint, buf, buf_len, 0); - FATAL_ON(ret < 0, 2, "cpc_write_endpoint: %m"); + FATAL_ON(ret < 0, 2, "cpc_write_endpoint: %s", strerror(-ret)); TRACE(TR_HDLC, "hdlc tx: %s (%d bytes)", tr_bytes(buf, ret, NULL, 128, DELIM_SPACE | ELLIPSIS_STAR), ret); return ret; @@ -53,7 +54,7 @@ int cpc_rx(struct bus *bus, void *buf, unsigned int buf_len) int ret; ret = cpc_read_endpoint(bus->cpc.endpoint, buf, buf_len, 0); - FATAL_ON(ret < 0, 2, "cpc_read_endpoint: %m"); + FATAL_ON(ret < 0, 2, "cpc_read_endpoint: %s", strerror(-ret)); TRACE(TR_HDLC, "hdlc rx: %s (%d bytes)", tr_bytes(buf, ret, NULL, 128, DELIM_SPACE | ELLIPSIS_STAR), ret); return ret; diff --git a/common/bus_cpc.h b/common/bus_cpc.h index 72be9633a..7abd870de 100644 --- a/common/bus_cpc.h +++ b/common/bus_cpc.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/bus_uart.c b/common/bus_uart.c index 5921ec04c..1d8176d7b 100644 --- a/common/bus_uart.c +++ b/common/bus_uart.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -15,6 +16,7 @@ #include #include #include +#include #include #include "common/bits.h" @@ -147,6 +149,10 @@ int uart_rx(struct bus *bus, void *buf, unsigned int buf_len) memmove(bus->uart.rx_buf, bus->uart.rx_buf + 1, bus->uart.rx_buf_len - 1); bus->uart.rx_buf_len -= 1; bus->uart.data_ready = true; + if (bus->uart.init_phase) + TRACE(TR_DROP, "drop %-9s: bad hcs", "uart"); + else + FATAL(3, "%s: bad hcs", __func__); return 0; } len = FIELD_GET(UART_HDR_LEN_MASK, read_le16(hdr)); @@ -159,7 +165,10 @@ int uart_rx(struct bus *bus, void *buf, unsigned int buf_len) if (!crc_check(CRC_INIT_FCS, buf, len, fcs)) { memmove(bus->uart.rx_buf, bus->uart.rx_buf + 1, bus->uart.rx_buf_len - 1); bus->uart.rx_buf_len -= 1; - TRACE(TR_DROP, "drop %-9s: bad fcs", "uart"); + if (bus->uart.init_phase) + TRACE(TR_DROP, "drop %-9s: bad fcs", "uart"); + else + FATAL(3, "%s: bad fcs", __func__); return 0; } memmove(bus->uart.rx_buf, iobuf_ptr(&iobuf), iobuf_remaining_size(&iobuf)); @@ -329,3 +338,18 @@ bool uart_detect_v2(struct bus *bus) return true; } } + +static inline int uart_txqlen(struct bus *bus) +{ + int ret, cnt; + + ret = ioctl(bus->fd, TIOCOUTQ, &cnt); + FATAL_ON(ret < 0, 2, "ioctl TIOCOUTQ: %m"); + return cnt; +} + +void uart_tx_flush(struct bus *bus) +{ + while (uart_txqlen(bus)) + usleep(1000); +} diff --git a/common/bus_uart.h b/common/bus_uart.h index acc431162..040bd94b6 100644 --- a/common/bus_uart.h +++ b/common/bus_uart.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -38,5 +39,8 @@ int uart_legacy_rx(struct bus *bus, void *buf, unsigned int len); // Try to find a valid APIv2 header within the first bytes received. bool uart_detect_v2(struct bus *bus); +// Wait for the kernel transmission queue to send all of its content. +void uart_tx_flush(struct bus *bus); + #endif diff --git a/common/capture.c b/common/capture.c index 33a2aee43..979d39e4f 100644 --- a/common/capture.c +++ b/common/capture.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/capture.h b/common/capture.h index 53896e0f3..82feb74aa 100644 --- a/common/capture.h +++ b/common/capture.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/crc.c b/common/crc.c index ee7fbcf8d..3afeefbfd 100644 --- a/common/crc.c +++ b/common/crc.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/crc.h b/common/crc.h index f9af35b6f..f0e59ecfb 100644 --- a/common/crc.h +++ b/common/crc.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/dhcp_server.c b/common/dhcp_server.c index dce0282b3..6ced5e341 100644 --- a/common/dhcp_server.c +++ b/common/dhcp_server.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/dhcp_server.h b/common/dhcp_server.h index 6c2627758..177842219 100644 --- a/common/dhcp_server.h +++ b/common/dhcp_server.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/endian.c b/common/endian.c index f8408001b..553221eb6 100644 --- a/common/endian.c +++ b/common/endian.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/endian.h b/common/endian.h index bdfb620e3..4a130205f 100644 --- a/common/endian.h +++ b/common/endian.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/events_scheduler.c b/common/events_scheduler.c index 3faca87d3..74e55bbfd 100644 --- a/common/events_scheduler.c +++ b/common/events_scheduler.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/events_scheduler.h b/common/events_scheduler.h index c1b1009f2..d6d543698 100644 --- a/common/events_scheduler.h +++ b/common/events_scheduler.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/hif.c b/common/hif.c index dc3578262..d83521b8f 100644 --- a/common/hif.c +++ b/common/hif.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -189,7 +190,7 @@ void hif_push_u64(struct iobuf_write *buf, uint64_t val) void hif_push_str(struct iobuf_write *buf, const char *val) { - iobuf_push_data(buf, (const uint8_t *)val, strlen(val) + 1); + iobuf_push_data(buf, val, strlen(val) + 1); TRACE(TR_HIF_EXTRA, "hif tx: string: %s", val); } @@ -350,7 +351,7 @@ const char *hif_pop_str(struct iobuf_read *buf) const char *val = (char *)iobuf_ptr(buf); int len = strnlen(val, iobuf_remaining_size(buf)); - if (len == iobuf_remaining_size(buf) && val[len - 1]) { + if (len == iobuf_remaining_size(buf)) { buf->err = true; return NULL; } diff --git a/common/hif.h b/common/hif.h index d433c4923..dc94d3f8b 100644 --- a/common/hif.h +++ b/common/hif.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/ieee802154_frame.c b/common/ieee802154_frame.c new file mode 100644 index 000000000..83432caf8 --- /dev/null +++ b/common/ieee802154_frame.c @@ -0,0 +1,273 @@ +#include + +#include "common/bits.h" +#include "common/endian.h" +#include "common/log.h" +#include "common/ieee802154_ie.h" +#include "common/iobuf.h" +#include "common/memutils.h" +#include "common/specs/ieee802154.h" +#include "ieee802154_frame.h" + +// IEEE 802.15.4-2020 Figure 7-2 Format of the Frame Control field +#define IEEE802154_MASK_FCF_FRAME_TYPE 0b0000000000000111 +#define IEEE802154_MASK_FCF_SECURED 0b0000000000001000 +#define IEEE802154_MASK_FCF_FRAME_PENDING 0b0000000000010000 +#define IEEE802154_MASK_FCF_ACK_REQ 0b0000000000100000 +#define IEEE802154_MASK_FCF_PAN_ID_CMPR 0b0000000001000000 +#define IEEE802154_MASK_FCF_DEL_SEQNO 0b0000000100000000 +#define IEEE802154_MASK_FCF_HAS_IE 0b0000001000000000 +#define IEEE802154_MASK_FCF_DST_ADDR_MODE 0b0000110000000000 +#define IEEE802154_MASK_FCF_FRAME_VERSION 0b0011000000000000 +#define IEEE802154_MASK_FCF_SRC_ADDR_MODE 0b1100000000000000 + +#define IEEE802154_MASK_SECHDR_LEVEL 0b00000111 +#define IEEE802154_MASK_SECHDR_KEY_ID_MODE 0b00011000 +#define IEEE802154_MASK_SECHDR_DEL_FRAMECTR 0b00100000 +#define IEEE802154_MASK_SECHDR_ASN_IN_NONCE 0b01000000 + +uint8_t ieee802154_addr_bc[8] = { [0 ... 7] = 0xff }; + +// IEEE 802.15.4-2020 Table 7-2 PAN ID Compression field value for frame version 0b10 +static const struct { + uint8_t dst_addr_mode; + uint8_t src_addr_mode; + bool has_dst_pan_id; + bool has_src_pan_id; + bool pan_id_cmpr; +} ieee802154_table_pan_id_cmpr[] = { +// { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_NONE, false, false, 0 }, // Unsupported +// { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_NONE, true, false, 1 }, // Unsupported +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_NONE, true, false, 0 }, // Unsupported +// { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_NONE, true, false, 0 }, // Unsupported +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_NONE, false, false, 1 }, // Unsupported + { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_NONE, false, false, 1 }, +// { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_16_BIT, false, true, 0 }, // Unsupported + { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_64_BIT, false, true, 0 }, +// { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_16_BIT, false, false, 1 }, // Unsupported + { MAC_ADDR_MODE_NONE, MAC_ADDR_MODE_64_BIT, false, false, 1 }, +// { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_64_BIT, true, false, 0 }, // Unsupported + { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_64_BIT, false, false, 1 }, +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_16_BIT, true, true, 0 }, // Unsupported +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_64_BIT, true, true, 0 }, // Unsupported +// { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_16_BIT, true, true, 0 }, // Unsupported +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_64_BIT, true, false, 1 }, // Unsupported +// { MAC_ADDR_MODE_64_BIT, MAC_ADDR_MODE_16_BIT, true, false, 1 }, // Unsupported +// { MAC_ADDR_MODE_16_BIT, MAC_ADDR_MODE_16_BIT, true, false, 1 }, // Unsupported +}; + +static int ieee802154_frame_parse_sec(struct iobuf_read *iobuf, struct ieee802154_hdr *hdr) +{ + uint8_t scf; + + scf = iobuf_pop_u8(iobuf); + if (FIELD_GET(IEEE802154_MASK_SECHDR_LEVEL, scf) != SEC_ENC_MIC64) { + TRACE(TR_DROP, "drop %-9s: unsupported security level", "15.4"); + return -ENOTSUP; + } + if (FIELD_GET(IEEE802154_MASK_SECHDR_KEY_ID_MODE, scf) != MAC_KEY_ID_MODE_IDX) { + TRACE(TR_DROP, "drop %-9s: unsupported security level", "15.4"); + return -ENOTSUP; + } + if (FIELD_GET(IEEE802154_MASK_SECHDR_DEL_FRAMECTR, scf)) { + TRACE(TR_DROP, "drop %-9s: unsupported frame counter suppression", "15.4"); + return -ENOTSUP; + } + if (FIELD_GET(IEEE802154_MASK_SECHDR_ASN_IN_NONCE, scf)) + TRACE(TR_IGNORE, "ignore %-9s: ASN in nonce", "15.4"); + + hdr->frame_counter = iobuf_pop_le32(iobuf); + hdr->key_index = iobuf_pop_u8(iobuf); + + if (iobuf_remaining_size(iobuf) < 8) { + TRACE(TR_DROP, "drop %-9s: missing MIC-64", "15.4"); + return -EINVAL; + } + iobuf->data_size -= 8; + + return 0; +} + +static int ieee802154_frame_parse_ie(struct iobuf_read *iobuf, + struct iobuf_read *ie_header, + struct iobuf_read *ie_payload) +{ + struct iobuf_read iobuf_ie; + int ret; + + memset(ie_header, 0, sizeof(*ie_header)); + memset(ie_payload, 0, sizeof(*ie_payload)); + + ret = ieee802154_ie_find_header(iobuf_ptr(iobuf), iobuf_remaining_size(iobuf), + IEEE802154_IE_ID_HT1, &iobuf_ie); + if (ret < 0 && ret != -ENOENT) { + TRACE(TR_DROP, "drop %-9s: malformed IEs", "15.4"); + return ret; + } + + if (!ret || !ieee802154_ie_find_header(iobuf_ptr(iobuf), iobuf_remaining_size(iobuf), + IEEE802154_IE_ID_HT2, &iobuf_ie)) { + ie_header->data_size = iobuf_ptr(&iobuf_ie) - 2 - iobuf_ptr(iobuf); + ie_header->data = (void *)iobuf_pop_data_ptr(iobuf, ie_header->data_size); + iobuf_pop_le16(iobuf); // Header Termination IE + } else { + ie_header->data_size = iobuf_remaining_size(iobuf); + ie_header->data = (void *)iobuf_pop_data_ptr(iobuf, ie_header->data_size); + } + + if (ret == -ENOENT) + return 0; + + ret = ieee802154_ie_find_payload(iobuf_ptr(iobuf), iobuf_remaining_size(iobuf), + IEEE802154_IE_ID_PT, &iobuf_ie); + if (ret < 0 && ret != -ENOENT) { + TRACE(TR_DROP, "drop %-9s: malformed IEs", "15.4"); + return ret; + } + + if (!ret) { + ie_payload->data_size = iobuf_ptr(&iobuf_ie) - 2 - iobuf_ptr(iobuf); + ie_payload->data = (void *)iobuf_pop_data_ptr(iobuf, ie_payload->data_size); + iobuf_pop_le16(iobuf); // Payload Termination IE + } else { + ie_payload->data_size = iobuf_remaining_size(iobuf); + ie_payload->data = (void *)iobuf_pop_data_ptr(iobuf, ie_payload->data_size); + } + + return 0; +} + +int ieee802154_frame_parse(const uint8_t *frame, size_t frame_len, + struct ieee802154_hdr *hdr, + struct iobuf_read *ie_header, + struct iobuf_read *ie_payload) +{ + struct iobuf_read iobuf = { + .data_size = frame_len, + .data = frame, + }; + uint8_t dst_addr_mode; + uint8_t src_addr_mode; + bool pan_id_cmpr; + uint16_t fcf; + int ret, i; + + fcf = iobuf_pop_le16(&iobuf); + hdr->frame_type = FIELD_GET(IEEE802154_MASK_FCF_FRAME_TYPE, fcf); + if (hdr->frame_type != IEEE802154_FRAME_TYPE_DATA && + hdr->frame_type != IEEE802154_FRAME_TYPE_ACK) { + TRACE(TR_DROP, "drop %-9s: unsupported frame type", "15.4"); + return -ENOTSUP; + } + if (FIELD_GET(IEEE802154_MASK_FCF_FRAME_VERSION, fcf) != MAC_FRAME_VERSION_2015) { + TRACE(TR_DROP, "drop %-9s: unsupported frame version", "15.4"); + return -ENOTSUP; + } + if (FIELD_GET(IEEE802154_MASK_FCF_FRAME_PENDING, fcf)) + TRACE(TR_IGNORE, "ignore %-9s: frame pending bit", "15.4"); + + hdr->ack_req = FIELD_GET(IEEE802154_MASK_FCF_ACK_REQ, fcf); + + hdr->seqno = -1; + if (!FIELD_GET(IEEE802154_MASK_FCF_DEL_SEQNO, fcf)) + hdr->seqno = iobuf_pop_u8(&iobuf); + + pan_id_cmpr = FIELD_GET(IEEE802154_MASK_FCF_PAN_ID_CMPR, fcf); + dst_addr_mode = FIELD_GET(IEEE802154_MASK_FCF_DST_ADDR_MODE, fcf); + src_addr_mode = FIELD_GET(IEEE802154_MASK_FCF_SRC_ADDR_MODE, fcf); + for (i = 0; i < ARRAY_SIZE(ieee802154_table_pan_id_cmpr); i++) + if (ieee802154_table_pan_id_cmpr[i].dst_addr_mode == dst_addr_mode && + ieee802154_table_pan_id_cmpr[i].src_addr_mode == src_addr_mode && + ieee802154_table_pan_id_cmpr[i].pan_id_cmpr == pan_id_cmpr) + break; + if (i == ARRAY_SIZE(ieee802154_table_pan_id_cmpr)) { + TRACE(TR_DROP, "drop %-9s: unsupported address mode", "15.4"); + return -ENOTSUP; + } + + BUG_ON(ieee802154_table_pan_id_cmpr[i].has_dst_pan_id); + + if (ieee802154_table_pan_id_cmpr[i].dst_addr_mode == MAC_ADDR_MODE_64_BIT) + write_be64(hdr->dst, iobuf_pop_le64(&iobuf)); + else + memcpy(hdr->dst, ieee802154_addr_bc, 8); + + hdr->pan_id = 0xffff; + if (ieee802154_table_pan_id_cmpr[i].has_src_pan_id) + hdr->pan_id = iobuf_pop_le16(&iobuf); + + + if (ieee802154_table_pan_id_cmpr[i].src_addr_mode == MAC_ADDR_MODE_64_BIT) + write_be64(hdr->src, iobuf_pop_le64(&iobuf)); + else + memcpy(hdr->src, ieee802154_addr_bc, 8); + + hdr->key_index = 0; + if (FIELD_GET(IEEE802154_MASK_FCF_SECURED, fcf)) { + ret = ieee802154_frame_parse_sec(&iobuf, hdr); + if (ret < 0) + return ret; + } + + if (FIELD_GET(IEEE802154_MASK_FCF_HAS_IE, fcf)) { + ret = ieee802154_frame_parse_ie(&iobuf, ie_header, ie_payload); + if (ret < 0) + return ret; + } + + if (iobuf_remaining_size(&iobuf)) + TRACE(TR_IGNORE, "ignore %-9s: unsupported frame payload", "15.4"); + + if (iobuf.err) { + TRACE(TR_DROP, "drop %-9s: malformed packet", "15.4"); + return -EINVAL; + } + + return 0; +} + +void ieee802154_frame_write_hdr(struct iobuf_write *iobuf, + const struct ieee802154_hdr *hdr) +{ + uint8_t dst_addr_mode = !memcmp(ieee802154_addr_bc, hdr->dst, 8) ? + MAC_ADDR_MODE_NONE : + MAC_ADDR_MODE_64_BIT; + uint8_t src_addr_mode = !memcmp(ieee802154_addr_bc, hdr->src, 8) ? + MAC_ADDR_MODE_NONE : + MAC_ADDR_MODE_64_BIT; + int i; + + for (i = 0; i < ARRAY_SIZE(ieee802154_table_pan_id_cmpr); i++) + if (ieee802154_table_pan_id_cmpr[i].dst_addr_mode == dst_addr_mode && + ieee802154_table_pan_id_cmpr[i].has_src_pan_id == (hdr->pan_id != 0xffff)) + break; + BUG_ON(i == ARRAY_SIZE(ieee802154_table_pan_id_cmpr)); + + iobuf_push_le16(iobuf, FIELD_PREP(IEEE802154_MASK_FCF_FRAME_TYPE, hdr->frame_type) + | FIELD_PREP(IEEE802154_MASK_FCF_SECURED, hdr->key_index != 0) + | FIELD_PREP(IEEE802154_MASK_FCF_ACK_REQ, hdr->ack_req) + | FIELD_PREP(IEEE802154_MASK_FCF_PAN_ID_CMPR, ieee802154_table_pan_id_cmpr[i].pan_id_cmpr) + | FIELD_PREP(IEEE802154_MASK_FCF_DEL_SEQNO, hdr->seqno < 0) + | FIELD_PREP(IEEE802154_MASK_FCF_HAS_IE, true) + | FIELD_PREP(IEEE802154_MASK_FCF_DST_ADDR_MODE, dst_addr_mode) + | FIELD_PREP(IEEE802154_MASK_FCF_FRAME_VERSION, MAC_FRAME_VERSION_2015) + | FIELD_PREP(IEEE802154_MASK_FCF_SRC_ADDR_MODE, src_addr_mode)); + + if (hdr->seqno >= 0) + iobuf_push_u8(iobuf, hdr->seqno); + + BUG_ON(ieee802154_table_pan_id_cmpr[i].has_dst_pan_id); + if (dst_addr_mode == MAC_ADDR_MODE_64_BIT) + iobuf_push_le64(iobuf, read_be64(hdr->dst)); + if (hdr->pan_id != 0xffff) + iobuf_push_le16(iobuf, hdr->pan_id); + if (src_addr_mode == MAC_ADDR_MODE_64_BIT) + iobuf_push_le64(iobuf, read_be64(hdr->src)); + + if (hdr->key_index) { + iobuf_push_u8(iobuf, FIELD_PREP(IEEE802154_MASK_SECHDR_LEVEL, SEC_ENC_MIC64) + | FIELD_PREP(IEEE802154_MASK_SECHDR_KEY_ID_MODE, MAC_KEY_ID_MODE_IDX)); + iobuf_push_data_reserved(iobuf, 4); // Frame Counter + iobuf_push_u8(iobuf, hdr->key_index); + } +} diff --git a/common/ieee802154_frame.h b/common/ieee802154_frame.h new file mode 100644 index 000000000..8f175e5b6 --- /dev/null +++ b/common/ieee802154_frame.h @@ -0,0 +1,32 @@ +#ifndef IEEE802154_FRAME_H +#define IEEE802154_FRAME_H + +#include +#include +#include + +struct iobuf_read; +struct iobuf_write; + +extern uint8_t ieee802154_addr_bc[8]; // ff:ff:ff:ff:ff:ff:ff:ff + +struct ieee802154_hdr { + uint8_t frame_type; + bool ack_req; + int seqno; // < 0 if elided + uint16_t pan_id; // 0xffff if elided + uint8_t dst[8]; // ff:ff:ff:ff:ff:ff:ff:ff if elided + uint8_t src[8]; // ff:ff:ff:ff:ff:ff:ff:ff if elided + uint8_t key_index; // 0 if unsecured + uint32_t frame_counter; // ignored if unsecured +}; + +int ieee802154_frame_parse(const uint8_t *frame, size_t frame_len, + struct ieee802154_hdr *hdr, + struct iobuf_read *ie_header, + struct iobuf_read *ie_payload); + +void ieee802154_frame_write_hdr(struct iobuf_write *iobuf, + const struct ieee802154_hdr *hdr); + +#endif diff --git a/common/ieee802154_ie.c b/common/ieee802154_ie.c index f83bc9937..1495b9a91 100644 --- a/common/ieee802154_ie.c +++ b/common/ieee802154_ie.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/ieee802154_ie.h b/common/ieee802154_ie.h index 864395c9a..308c77e85 100644 --- a/common/ieee802154_ie.h +++ b/common/ieee802154_ie.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/int24.h b/common/int24.h index 9877d22e7..7b1a855ac 100644 --- a/common/int24.h +++ b/common/int24.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/iobuf.c b/common/iobuf.c index 09ff621ff..5699c82f6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -80,7 +81,7 @@ void iobuf_push_le64(struct iobuf_write *buf, uint64_t val) { buf->len += 8; } -void iobuf_push_data(struct iobuf_write *buf, const uint8_t *val, int num) +void iobuf_push_data(struct iobuf_write *buf, const void *val, int num) { iobuf_enlarge_buffer(buf, num); memcpy(buf->data + buf->len, val, num); diff --git a/common/iobuf.h b/common/iobuf.h index ca29916c6..01bf00a1a 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -62,7 +63,7 @@ void iobuf_push_be32(struct iobuf_write *buf, uint32_t val); void iobuf_push_le32(struct iobuf_write *buf, uint32_t val); void iobuf_push_be64(struct iobuf_write *buf, uint64_t val); void iobuf_push_le64(struct iobuf_write *buf, uint64_t val); -void iobuf_push_data(struct iobuf_write *buf, const uint8_t *val, int num); +void iobuf_push_data(struct iobuf_write *buf, const void *val, int num); void iobuf_push_data_reserved(struct iobuf_write *buf, const int num); void iobuf_free(struct iobuf_write *buf); diff --git a/common/key_value_storage.c b/common/key_value_storage.c index d8f1afbb4..0cdda61d0 100644 --- a/common/key_value_storage.c +++ b/common/key_value_storage.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/key_value_storage.h b/common/key_value_storage.h index 184d1f9bb..b18bf7692 100644 --- a/common/key_value_storage.h +++ b/common/key_value_storage.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/log.c b/common/log.c index 74455134f..c889d339b 100644 --- a/common/log.c +++ b/common/log.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -109,7 +110,7 @@ char *str_key(const uint8_t *in, int in_len, char *out, int out_len) char *str_eui48(const uint8_t in[6], char out[STR_MAX_LEN_EUI48]) { - return str_bytes(in, 6, NULL, out, STR_MAX_LEN_EUI64, DELIM_COLON); + return str_bytes(in, 6, NULL, out, STR_MAX_LEN_EUI48, DELIM_COLON); } char *str_eui64(const uint8_t in[8], char out[STR_MAX_LEN_EUI64]) diff --git a/common/log.h b/common/log.h index 207127563..396a7f02a 100644 --- a/common/log.h +++ b/common/log.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/log_legacy.h b/common/log_legacy.h index 07fcd5204..5b9c0d290 100644 --- a/common/log_legacy.h +++ b/common/log_legacy.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/mathutils.h b/common/mathutils.h index ef633aad9..19b325ef5 100644 --- a/common/mathutils.h +++ b/common/mathutils.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/memutils.h b/common/memutils.h index ce652e4c7..2d19248dd 100644 --- a/common/memutils.h +++ b/common/memutils.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/named_values.c b/common/named_values.c index c3a0555f4..37f83643d 100644 --- a/common/named_values.c +++ b/common/named_values.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/named_values.h b/common/named_values.h index b268c2e38..66a651ad7 100644 --- a/common/named_values.h +++ b/common/named_values.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/netinet_in_extra.h b/common/netinet_in_extra.h index 1f6643cdc..6a4ce5db1 100644 --- a/common/netinet_in_extra.h +++ b/common/netinet_in_extra.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/parsers.c b/common/parsers.c index e10f4843c..1f728574d 100644 --- a/common/parsers.c +++ b/common/parsers.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/parsers.h b/common/parsers.h index 4b85d1fbf..0eb005df6 100644 --- a/common/parsers.h +++ b/common/parsers.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/pcapng.c b/common/pcapng.c index 316658298..25b544cb9 100644 --- a/common/pcapng.c +++ b/common/pcapng.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -24,48 +25,92 @@ #define PCAPNG_BYTE_ORDER_MAGIC 0x1A2B3C4D -void pcapng_write_shb(struct iobuf_write *buf, const struct pcapng_shb *shb) +// Section Header Block +struct pcapng_shb { + uint32_t byteorder_magic; + uint16_t version_maj; + uint16_t version_min; + int64_t section_len; +} __attribute__((packed)); + +// Interface Description Block +struct pcapng_idb { + uint16_t link_type; + uint16_t reserved; + uint32_t snap_len; +} __attribute__((packed)); + +// Enhanced Packet Block +struct pcapng_epb { + uint32_t ifindex; + uint32_t timestamp_high; + uint32_t timestamp_low; + uint32_t pkt_len; + uint32_t pkt_len_og; +} __attribute__((packed)); + +static int pcapng_block_start(struct iobuf_write *buf, uint32_t type) +{ + int offset = buf->len; + + iobuf_push_data(buf, &type, sizeof(type)); + iobuf_push_data_reserved(buf, sizeof(uint32_t)); // Block Total Length + return offset; +} + +static void pcapng_block_end(struct iobuf_write *buf, int offset) { - const uint32_t len = PCAPNG_SHB_SIZE_MIN; - - iobuf_push_le32(buf, PCAPNG_BLOCK_TYPE_SHB); - iobuf_push_le32(buf, len); - iobuf_push_le32(buf, PCAPNG_BYTE_ORDER_MAGIC); - iobuf_push_le16(buf, shb->version_maj); - iobuf_push_le16(buf, shb->version_min); - iobuf_push_le64(buf, shb->section_len); - // options not supported - iobuf_push_le32(buf, len); + uint32_t len = buf->len + sizeof(uint32_t) - offset; + + memcpy(buf->data + offset + sizeof(uint32_t), &len, sizeof(len)); + iobuf_push_data(buf, &len, sizeof(len)); // Block Total Length } -void pcapng_write_idb(struct iobuf_write *buf, const struct pcapng_idb *idb) +void pcapng_write_shb(struct iobuf_write *buf) { - const uint32_t len = PCAPNG_IDB_SIZE_MIN; - - iobuf_push_le32(buf, PCAPNG_BLOCK_TYPE_IDB); - iobuf_push_le32(buf, len); - iobuf_push_le16(buf, idb->link_type); - iobuf_push_le16(buf, 0); - iobuf_push_le32(buf, idb->snap_len); - // options not supported - iobuf_push_le32(buf, len); + struct pcapng_shb shb = { + .byteorder_magic = PCAPNG_BYTE_ORDER_MAGIC, + .version_maj = 1, + .version_min = 0, + .section_len = -1, // Unknown + }; + int offset; + + offset = pcapng_block_start(buf, PCAPNG_BLOCK_TYPE_SHB); + iobuf_push_data(buf, &shb, sizeof(shb)); + pcapng_block_end(buf, offset); } -void pcapng_write_epb(struct iobuf_write *buf, const struct pcapng_epb *epb) +void pcapng_write_idb(struct iobuf_write *buf, uint16_t link_type) { - const uint8_t pkt_len_pad = (4 - (epb->pkt_len & 0b11)) & 0b11; // pad to 32 bits - const uint32_t len = PCAPNG_EPB_SIZE_MIN + epb->pkt_len + pkt_len_pad; - - iobuf_push_le32(buf, PCAPNG_BLOCK_TYPE_EPB); - iobuf_push_le32(buf, len); - iobuf_push_le32(buf, epb->if_id); - iobuf_push_le32(buf, epb->timestamp >> 32); - iobuf_push_le32(buf, epb->timestamp & 0xffffffff); - iobuf_push_le32(buf, epb->pkt_len); - iobuf_push_le32(buf, epb->pkt_len_og); - iobuf_push_data(buf, epb->pkt, epb->pkt_len); - for (int i = 0; i < pkt_len_pad; i++) + struct pcapng_idb idb = { + .link_type = link_type, + .snap_len = 0, // No packet size restriction + }; + int offset; + + offset = pcapng_block_start(buf, PCAPNG_BLOCK_TYPE_IDB); + iobuf_push_data(buf, &idb, sizeof(idb)); + pcapng_block_end(buf, offset); +} + +void pcapng_write_epb(struct iobuf_write *buf, + uint64_t timestamp_us, + const void *pkt, size_t pkt_len) +{ + struct pcapng_epb epb = { + .ifindex = 0, + .timestamp_high = timestamp_us >> 32, + .timestamp_low = timestamp_us, + .pkt_len = pkt_len, + .pkt_len_og = pkt_len, + }; + int offset; + + offset = pcapng_block_start(buf, PCAPNG_BLOCK_TYPE_EPB); + iobuf_push_data(buf, &epb, sizeof(epb)); + iobuf_push_data(buf, pkt, pkt_len); + while (buf->len % sizeof(uint32_t)) iobuf_push_u8(buf, 0); // pad to 32 bits - // options not supported - iobuf_push_le32(buf, len); + pcapng_block_end(buf, offset); } diff --git a/common/pcapng.h b/common/pcapng.h index 3ae80f456..ee4d156ff 100644 --- a/common/pcapng.h +++ b/common/pcapng.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -13,8 +14,6 @@ #ifndef PCAPNG_H #define PCAPNG_H #include -#include -#include /* * The pcapng format is specified in draft-tuexen-opsawg-pcapng @@ -26,64 +25,12 @@ // https://datatracker.ietf.org/doc/html/draft-richardson-opsawg-pcaplinktype-00 #define LINKTYPE_IEEE802_15_4_NOFCS 230 -#define PCAPNG_SHB_SIZE_MIN ( \ - 4 + /* Block Type */ \ - 4 + /* Block Total Length */ \ - 4 + /* Byte-Order Magic */ \ - 2 + /* Major Version */ \ - 2 + /* Minor Version */ \ - 8 + /* Section Length */ \ - 0 + /* Options */ \ - 4 /* Block Total Length */ \ -) -#define PCAPNG_IDB_SIZE_MIN ( \ - 4 + /* Block Type */ \ - 4 + /* Block Total Length */ \ - 2 + /* LinkType */ \ - 2 + /* Reserved */ \ - 4 + /* SnapLen */ \ - 0 + /* Options */ \ - 4 /* Block Total Length */ \ -) -#define PCAPNG_EPB_SIZE_MIN ( \ - 4 + /* Block Type */ \ - 4 + /* Block Total Length */ \ - 4 + /* Interface ID */ \ - 4 + /* Timestamp (High) */ \ - 4 + /* Timestamp (Low) */ \ - 4 + /* Captured Packet Length */ \ - 4 + /* Original Packet Length */ \ - 0 + /* Packet Data */ \ - 0 + /* Options */ \ - 4 /* Block Total Length */ \ -) - struct iobuf_write; -struct pcapng_shb { - uint16_t version_maj; - uint16_t version_min; - int64_t section_len; - // options not supported -}; - -struct pcapng_idb { - uint16_t link_type; - uint32_t snap_len; - // options not supported -}; - -struct pcapng_epb { - uint32_t if_id; - uint64_t timestamp; // only us resolution supported (default) - uint32_t pkt_len; - uint32_t pkt_len_og; - const uint8_t *pkt; - // options not supported -}; - -void pcapng_write_shb(struct iobuf_write *buf, const struct pcapng_shb *shb); -void pcapng_write_idb(struct iobuf_write *buf, const struct pcapng_idb *idb); -void pcapng_write_epb(struct iobuf_write *buf, const struct pcapng_epb *epb); +void pcapng_write_shb(struct iobuf_write *buf); +void pcapng_write_idb(struct iobuf_write *buf, uint16_t link_type); +void pcapng_write_epb(struct iobuf_write *buf, + uint64_t timestamp_us, + const void *pkt, size_t pkt_len); #endif diff --git a/common/rand.h b/common/rand.h index 19abac8d7..8a8364941 100644 --- a/common/rand.h +++ b/common/rand.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/seqno.h b/common/seqno.h index 84871f314..a23380d8e 100644 --- a/common/seqno.h +++ b/common/seqno.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/specs/icmpv6.h b/common/specs/icmpv6.h index 7efa91416..0fd8ef0cd 100644 --- a/common/specs/icmpv6.h +++ b/common/specs/icmpv6.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/specs/ieee802154.h b/common/specs/ieee802154.h index 9e464d88e..d3d6fcc42 100644 --- a/common/specs/ieee802154.h +++ b/common/specs/ieee802154.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -13,6 +14,17 @@ #ifndef SPECS_IEEE802154_H #define SPECS_IEEE802154_H +// IEEE 802.15.4-2020 Table 7-1 Values of the Frame Type field +enum { + IEEE802154_FRAME_TYPE_BEACON = 0b000, // Unused + IEEE802154_FRAME_TYPE_DATA = 0b001, + IEEE802154_FRAME_TYPE_ACK = 0b010, + IEEE802154_FRAME_TYPE_CMD = 0b011, + IEEE802154_FRAME_TYPE_MPX = 0b101, // Unused + IEEE802154_FRAME_TYPE_FRAG = 0b110, // Unused + IEEE802154_FRAME_TYPE_EXT = 0b111, // Unused +}; + // 802.15.4 ANA database - IE Header // https://mentor.ieee.org/802.15/documents?is_dcn=257&is_group=0000 enum { diff --git a/common/specs/rpl.h b/common/specs/rpl.h index cae140648..1b9a9fecf 100644 --- a/common/specs/rpl.h +++ b/common/specs/rpl.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/spinel.c b/common/spinel.c index 5dddb51c0..214fa56a2 100644 --- a/common/spinel.c +++ b/common/spinel.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/string_extra.h b/common/string_extra.h index 42b5ac0b7..c9dadeb25 100644 --- a/common/string_extra.h +++ b/common/string_extra.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/sys_queue_extra.h b/common/sys_queue_extra.h index f90baf0e4..2ae86c85c 100644 --- a/common/sys_queue_extra.h +++ b/common/sys_queue_extra.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/time_extra.c b/common/time_extra.c index 10353d884..821decb84 100644 --- a/common/time_extra.c +++ b/common/time_extra.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/time_extra.h b/common/time_extra.h index 1825efc5c..22985a886 100644 --- a/common/time_extra.h +++ b/common/time_extra.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/version.h b/common/version.h index 68ebba7a0..0de9e413c 100644 --- a/common/version.h +++ b/common/version.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/ws_regdb.c b/common/ws_regdb.c index 9224d68c5..0eee4a23e 100644 --- a/common/ws_regdb.c +++ b/common/ws_regdb.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/common/ws_regdb.h b/common/ws_regdb.h index 89181926b..a55b366a1 100644 --- a/common/ws_regdb.h +++ b/common/ws_regdb.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/examples/mbedtls-config.h b/examples/mbedtls-config.h index 6f27d8c13..99656cd51 100644 --- a/examples/mbedtls-config.h +++ b/examples/mbedtls-config.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/examples/wsbrd.conf b/examples/wsbrd.conf index 9d64fa367..b0b1e5a8e 100644 --- a/examples/wsbrd.conf +++ b/examples/wsbrd.conf @@ -135,8 +135,8 @@ phy_mode_id = 0x02 # A comma separated list of Wi-SUN PHY Mode IDs, which is advertised to other # nodes for mode switch. All PHY mode IDs MUST be part of the same PHY group # (check column "phy grp" in output of --list-rf-config). The base PHY mode ID -# is automatically added, so 14 other modes can be specified. -# If value is "auto", the first 14 PHYs available will be included. +# should not be specified here, up to 15 other modes can be used. +# If value is "auto", the first 15 PHYs available will be included. # If not set, mode switch is disabled. phy_operating_modes = auto @@ -365,6 +365,10 @@ authority = examples/ca_cert.pem # in PAN-IE to simulate a busy network in testing environments. #pan_size = 1000 +# Overwrite the RCP MAC address. By default, the RCP uses a unique identifier +# hardcoded in the chip. +#mac_address = ff:ff:ff:ff:ff:ff:ff:ff + # List of filtered MAC addresses (EUI-64). # Border router will prevent communication with any device whose MAC address # does not match any item in the 'allowed' list, OR will prevent communication diff --git a/helper.mk b/helper.mk new file mode 100755 index 000000000..c690d3849 --- /dev/null +++ b/helper.mk @@ -0,0 +1,39 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# ex: set tabstop=4 noexpandtab: +# -*- coding: utf-8 -* +# +# SPDX-License-Identifier: LicenseRef-MSLA +# SPDX-Copyright-Text: (c) 2024 Silicon Laboratories Inc. (www.silabs.com) + +tmpdir?=${CURDIR}/tmp + +sudo?=sudo + +export CMAKE_PREFIX_PATH=${tmpdir}/usr/local/cmake + +debian_packages?=build-essential \ + git cmake sudo rustc pkg-config \ + libnl-route-3-dev libdbus-1-dev + +mbedtls_url?=https://github.com/ARMmbed/mbedtls +mbedtls_rev?=v3.0.0 + + +build: + cmake . + cmake --build . + make install DESTDIR="${tmpdir}" + +mbedtls: + git clone --branch=${mbedtls_rev} --recursive --depth=1 ${mbedtls_url} + +prepare: mbedtls + cd $< \ + && cmake . \ + && cmake --build . \ + && make install DESTDIR="${tmpdir}" + +setup: + ${sudo} apt-get install -y ${debian_packages} + diff --git a/tools/fuzz/commandline.c b/tools/fuzz/commandline.c index a857c8aa9..0517c919a 100644 --- a/tools/fuzz/commandline.c +++ b/tools/fuzz/commandline.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/commandline.h b/tools/fuzz/commandline.h index a1bf61a89..a4abdb3f3 100644 --- a/tools/fuzz/commandline.h +++ b/tools/fuzz/commandline.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/interfaces.c b/tools/fuzz/interfaces.c index 886251549..b62cb9872 100644 --- a/tools/fuzz/interfaces.c +++ b/tools/fuzz/interfaces.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/interfaces.h b/tools/fuzz/interfaces.h index 813322b80..bc36f9d7a 100644 --- a/tools/fuzz/interfaces.h +++ b/tools/fuzz/interfaces.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/main.c b/tools/fuzz/main.c index ef1f7adf5..3e67767f6 100644 --- a/tools/fuzz/main.c +++ b/tools/fuzz/main.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/rand.c b/tools/fuzz/rand.c index f7bcfc9a4..6820541dc 100644 --- a/tools/fuzz/rand.c +++ b/tools/fuzz/rand.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/rand.h b/tools/fuzz/rand.h index 6dc73a65f..6782ca3af 100644 --- a/tools/fuzz/rand.h +++ b/tools/fuzz/rand.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/replay.c b/tools/fuzz/replay.c index cb3b9d93f..1ab8fa336 100644 --- a/tools/fuzz/replay.c +++ b/tools/fuzz/replay.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/replay.h b/tools/fuzz/replay.h index 63d41663a..52294537d 100644 --- a/tools/fuzz/replay.h +++ b/tools/fuzz/replay.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/split-capture b/tools/fuzz/split-capture index 4ff01fb7a..cb4ab2497 100755 --- a/tools/fuzz/split-capture +++ b/tools/fuzz/split-capture @@ -1,5 +1,6 @@ #!/bin/env python3 # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/wsbrd_fuzz.c b/tools/fuzz/wsbrd_fuzz.c index 8c13fced7..e860a96a2 100644 --- a/tools/fuzz/wsbrd_fuzz.c +++ b/tools/fuzz/wsbrd_fuzz.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fuzz/wsbrd_fuzz.h b/tools/fuzz/wsbrd_fuzz.h index 039176cd0..19df9fd88 100644 --- a/tools/fuzz/wsbrd_fuzz.h +++ b/tools/fuzz/wsbrd_fuzz.h @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/fwup/wsbrd_fwup.c b/tools/fwup/wsbrd_fwup.c index 2370548ff..40f403b86 100644 --- a/tools/fwup/wsbrd_fwup.c +++ b/tools/fwup/wsbrd_fwup.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/hwping/wshwping.c b/tools/hwping/wshwping.c index 56ece280b..c6311bb7b 100644 --- a/tools/hwping/wshwping.c +++ b/tools/hwping/wshwping.c @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -10,6 +11,7 @@ * * [1]: https://www.silabs.com/about-us/legal/master-software-license-agreement */ +#include #include #include #include @@ -192,6 +194,25 @@ static uint8_t get_spinel_hdr(struct bus *bus) return hdr; } +static void send_data(struct bus *bus, struct commandline_args *cmdline, + const uint8_t *buf, size_t buf_len, bool is_v2) +{ + BUG_ON(!buf_len); + if (cmdline->cpc_instance[0]) + cpc_tx(bus, buf, buf_len); + else if (!is_v2) + uart_legacy_tx(bus, buf, buf_len); + else + uart_tx(bus, buf, buf_len); + + if (!is_v2) + spinel_trace(buf, buf_len, "hif tx: "); + else + TRACE(TR_HIF, "hif tx: %s %s", + hif_cmd_str(buf[0]), + tr_bytes(buf + 1, buf_len - 1, NULL, 128, DELIM_SPACE | ELLIPSIS_STAR)); +} + static void send(struct bus *bus, struct commandline_args *cmdline, uint16_t counter, bool is_v2) { struct iobuf_write tx_buf = { }; @@ -206,22 +227,13 @@ static void send(struct bus *bus, struct commandline_args *cmdline, uint16_t cou hif_push_u8(&tx_buf, HIF_CMD_REQ_PING); } hif_push_u16(&tx_buf, counter); - if (cmdline->mode & MODE_TX) - hif_push_u16(&tx_buf, cmdline->payload_size); - else - hif_push_u16(&tx_buf, 0); - if (cmdline->mode & MODE_RX) - hif_push_raw(&tx_buf, payload_buf, cmdline->payload_size); + hif_push_u16(&tx_buf, (cmdline->mode & MODE_TX) ? cmdline->payload_size : 0); + if (!is_v2) + hif_push_raw(&tx_buf, payload_buf, (cmdline->mode & MODE_RX) ? cmdline->payload_size : 0); else - hif_push_raw(&tx_buf, payload_buf, 0); + hif_push_data(&tx_buf, payload_buf, (cmdline->mode & MODE_RX) ? cmdline->payload_size : 0); - if (cmdline->cpc_instance[0]) - cpc_tx(bus, tx_buf.data, tx_buf.len); - else if (!is_v2) - uart_legacy_tx(bus, tx_buf.data, tx_buf.len); - else - uart_tx(bus, tx_buf.data, tx_buf.len); - spinel_trace(tx_buf.data, tx_buf.data_size, "hif tx: "); + send_data(bus, cmdline, tx_buf.data, tx_buf.len, is_v2); iobuf_free(&tx_buf); } @@ -251,9 +263,35 @@ static size_t read_data(struct bus *bus, struct commandline_args *cmdline, uint8 len = uart_rx(bus, buf, buf_len); } } while (!len); + if (len) { + if (!is_v2) + spinel_trace(buf, len, "hif rx: "); + else + TRACE(TR_HIF, "hif rx: %s %s", hif_cmd_str(buf[0]), + tr_bytes(buf + 1, len - 1, + NULL, 128, DELIM_SPACE | ELLIPSIS_STAR)); + } return len; } +static void rcp_ind_fatal(struct iobuf_read *buf, bool ignore_crc) +{ + const char *err_msg; + uint16_t err_code; + + err_code = hif_pop_u16(buf); + err_msg = hif_pop_str(buf); + BUG_ON(buf->err); + // If a frame was canceled previously before restarting wshwping, the RCP + // will emit a CRC error once its buffers are filled with by NOP request. + if (ignore_crc && err_code == HIF_ECRC) + return; + if (err_msg) + FATAL(3, "rcp error %s: %s", hif_fatal_str(err_code), err_msg); + else + FATAL(3, "rcp error %s", hif_fatal_str(err_code)); +} + static int receive(struct bus *bus, struct commandline_args *cmdline, uint16_t counter, bool is_v2) { const uint8_t *payload; @@ -267,14 +305,7 @@ static int receive(struct bus *bus, struct commandline_args *cmdline, uint16_t c WARN("poll: no answer from RCP on ping %d", counter); return counter + 1; } - if (!is_v2) - spinel_trace(rx_buf.data, rx_buf.data_size, "hif rx: "); val = hif_pop_u8(&rx_buf); // Either RCPv2 command or SPINEL header - if (is_v2) - TRACE(TR_HIF, "hif rx: %s %s", hif_cmd_str(val), - tr_bytes(iobuf_ptr(&rx_buf), iobuf_remaining_size(&rx_buf), - NULL, 128, DELIM_SPACE | ELLIPSIS_STAR)); - if (!is_v2) { val = hif_pop_uint(&rx_buf); if (val != SPINEL_CMD_RCP_PING) { @@ -286,9 +317,13 @@ static int receive(struct bus *bus, struct commandline_args *cmdline, uint16_t c return counter; } } - } else if (val != HIF_CMD_CNF_PING) { - WARN("received %02x instead of %02x", val, HIF_CMD_CNF_PING); - return counter; + } else { + if (val == HIF_CMD_IND_FATAL) + rcp_ind_fatal(&rx_buf, false); + if (val != HIF_CMD_CNF_PING) { + WARN("received %02x instead of %02x", val, HIF_CMD_CNF_PING); + return counter; + } } val = hif_pop_u16(&rx_buf); @@ -363,12 +398,45 @@ static void print_throughput(struct timespec *ts, struct commandline_args *cmdli INFO("equivalent baudrate: %.0lf bits/sec", 10 * real_payload * real_exchanges_count / real_time); } +static void wait_reset(struct bus *bus, struct commandline_args *cmdline, bool is_v2) +{ + uint8_t buf[FIELD_MAX(UART_HDR_LEN_MASK)]; + struct iobuf_read iobuf = { .data = buf }; + + while (1) { + iobuf.cnt = 0; + iobuf.data_size = read_data(bus, cmdline, buf, sizeof(buf), is_v2); + if (!is_v2) { + hif_pop_u8(&iobuf); + switch (hif_pop_uint(&iobuf)) { + case SPINEL_CMD_NOOP: + continue; + case SPINEL_CMD_RESET: + return; + default: + FATAL(3, "unexpected command"); + } + } else { + switch (hif_pop_u8(&iobuf)) { + case HIF_CMD_IND_NOP: + continue; + case HIF_CMD_IND_RESET: + return; + case HIF_CMD_IND_FATAL: + rcp_ind_fatal(&iobuf, true); + break; + default: + FATAL(3, "unexpected command"); + } + } + } +} + static bool detect_v2(struct bus *bus, struct commandline_args *cmdline) { struct iobuf_write buf = { }; uint32_t version_api; bool is_v2; - int ret; if (cmdline->cpc_instance[0]) { version_api = cpc_secondary_app_version(bus); @@ -376,42 +444,53 @@ static bool detect_v2(struct bus *bus, struct commandline_args *cmdline) } else { hif_push_u8(&buf, get_spinel_hdr(bus)); hif_push_uint(&buf, SPINEL_CMD_NOOP); - uart_legacy_tx(bus, buf.data, buf.len); + send_data(bus, cmdline, buf.data, buf.len, false); iobuf_free(&buf); hif_push_u8(&buf, get_spinel_hdr(bus)); hif_push_uint(&buf, SPINEL_CMD_RESET); - uart_legacy_tx(bus, buf.data, buf.len); + send_data(bus, cmdline, buf.data, buf.len, false); iobuf_free(&buf); hif_push_u8(&buf, HIF_CMD_REQ_RESET); hif_push_bool(&buf,false); - uart_tx(bus, buf.data, buf.len); + send_data(bus, cmdline, buf.data, buf.len, true); iobuf_free(&buf); is_v2 = uart_detect_v2(bus); if (!is_v2) { hif_push_u8(&buf, get_spinel_hdr(bus)); hif_push_uint(&buf, SPINEL_CMD_NOOP); - uart_legacy_tx(bus, buf.data, buf.len); + send_data(bus, cmdline, buf.data, buf.len, false); iobuf_free(&buf); } - bus->uart.data_ready = false; - bus->uart.rx_buf_len = 0; - ret = tcflush(bus->fd, TCIFLUSH); - FATAL_ON(ret < 0, 2, "tcflush: %m"); + bus->uart.init_phase = true; + wait_reset(bus, cmdline, is_v2); + bus->uart.init_phase = false; return is_v2; } } +static void *sighandler_data; + +static void sighandler(int signum) +{ + uart_tx_flush(sighandler_data); + exit(EXIT_SUCCESS); +} + int main(int argc, char **argv) { + const struct sigaction sigact = { .sa_handler = sighandler }; struct timespec ts_start, ts_end, ts_res; struct commandline_args cmdline = { }; struct bus bus = { }; int in_cnt, out_cnt; bool is_v2; + sighandler_data = &bus; + sigaction(SIGINT, &sigact, NULL); + parse_commandline(&cmdline, argc, argv); if (cmdline.cpc_instance[0]) diff --git a/tools/simulation/rand.cpp b/tools/simulation/rand.cpp index 29134c5be..b1c3374c7 100644 --- a/tools/simulation/rand.cpp +++ b/tools/simulation/rand.cpp @@ -1,5 +1,7 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) + * * The licensor of this software is Silicon Laboratories Inc. Your use of this * software is governed by the terms of the Silicon Labs Master Software License diff --git a/tools/simulation/time.cpp b/tools/simulation/time.cpp index 9b2a83c1d..7fd258ee0 100644 --- a/tools/simulation/time.cpp +++ b/tools/simulation/time.cpp @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/simulation/uart.cpp b/tools/simulation/uart.cpp index 8c3e5e3b2..0269d437d 100644 --- a/tools/simulation/uart.cpp +++ b/tools/simulation/uart.cpp @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/simulation/wsbrd_ns3.cpp b/tools/simulation/wsbrd_ns3.cpp index 768318add..69fe8851d 100644 --- a/tools/simulation/wsbrd_ns3.cpp +++ b/tools/simulation/wsbrd_ns3.cpp @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2022 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -103,10 +104,10 @@ extern "C" void __wrap___tr_printf(const char *color, const char *fmt, ...) va_end(ap); } -extern "C" sighandler_t __wrap_signal(int signum, sighandler_t handler) +extern "C" int __wrap_sigaction(int signum, const struct sigaction *sa_in, struct sigaction *sa_out) { errno = ENOSYS; - return SIG_ERR; + return -1; } // exit() is not thread-safe, so aborting is preferred. diff --git a/tools/tbu/README.md b/tools/tbu/README.md index 161a2aecb..52edc8eb3 100644 --- a/tools/tbu/README.md +++ b/tools/tbu/README.md @@ -49,16 +49,10 @@ Finally, the server can be run using: different channel exclusions between its unicast and broadcast schedules, so the last exclusion set using one of the 2 endpoints will be used for both unicast and broadcast. -- EDFE is not supported for transmission in endpoints `/transmitter/udp` and - `/transmitter/icmpv6Echo`. - Broadcast Schedule Identifier (BSI) is ignored in `/config/chanPlan/bcast`, a random BSI is generated instead. - Endpoints `/config/neighborTable` and `subscription/frames/hash` are not implemented. -- Parameters `lfnPtkLifetime` and `lfnPmkLifetime` are ignored in - `/config/borderRouter/keyLifetimes`, pairwise key lifetimes are the same - between FFN and LFN. - Endpoint `/config/borderRouter/revokeKeys` will always revoke both GTKs and LGTKs, inserting a custom (L)GTK based on the `isLgtk` parameter, and a random key for the other key type. -- MAC mode switch (using MDR command frame) is not supported. diff --git a/tools/tbu/configutils.py b/tools/tbu/configutils.py index a464e04e9..513f3f86f 100644 --- a/tools/tbu/configutils.py +++ b/tools/tbu/configutils.py @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/tbu/systemd/wstbu-dhcpv6-relay b/tools/tbu/systemd/wstbu-dhcpv6-relay index b4d14057f..5c7d9828f 100644 --- a/tools/tbu/systemd/wstbu-dhcpv6-relay +++ b/tools/tbu/systemd/wstbu-dhcpv6-relay @@ -36,7 +36,7 @@ def main(): cmd = [ 'dnsmasq', '--port=0', # Disable DNS - '--no-daemon', + '--keep-in-foreground', '--conf-file=/dev/null', f'--dhcp-relay={wsbrd_addr},{dhcpv6_server_addr}', '--log-debug', diff --git a/tools/tbu/utils.py b/tools/tbu/utils.py index d239e95cc..8b1460e23 100644 --- a/tools/tbu/utils.py +++ b/tools/tbu/utils.py @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this diff --git a/tools/tbu/wsbrd.py b/tools/tbu/wsbrd.py index 83328b934..c6f3009e9 100644 --- a/tools/tbu/wsbrd.py +++ b/tools/tbu/wsbrd.py @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -130,6 +131,10 @@ def install_lgtk(self, lgtk: bytes) -> None: def ie_custom_insert(self, ie_type, id, content, frame_types) -> None: raise NotImplementedError + @sdbus.dbus_method() + def ie_custom_clear(self) -> None: + raise NotImplementedError + @sdbus.dbus_method() def increment_rpl_dtsn(self) -> None: raise NotImplementedError diff --git a/tools/tbu/wstbu.py b/tools/tbu/wstbu.py index 0120a5f50..033bf00dc 100644 --- a/tools/tbu/wstbu.py +++ b/tools/tbu/wstbu.py @@ -1,4 +1,5 @@ # +# SPDX-License-Identifier: LicenseRef-MSLA # Copyright (c) 2024 Silicon Laboratories Inc. (www.silabs.com) # # The licensor of this software is Silicon Laboratories Inc. Your use of this @@ -175,32 +176,28 @@ def wrapper(*args, **kwargs): return decorator -# HACK: /config/borderRouter/joinMetrics may be called before /runMode/1 +# Dict from JM-ID to tuple (len, data) +jm_list: dict[int, tuple[int, bytes]] = dict() +jm_version = 0 + + def wsbrd_set_join_metrics(jm_list, jm_version): - if jm_list: - jm_content = bytearray() - jm_version = (jm_version + 1) % 256 - jm_content.append(jm_version) - for jm_id in jm_list: - jm_len, jm_data = jm_list[jm_id] - jm_content.append( - utils.field_prep(WS_MASK_JM_ID, jm_id) | - utils.field_prep(WS_MASK_JM_LEN, jm_len) - ) - jm_content.extend(jm_data) - wsbrd.dbus().ie_custom_insert( - WSTBU_IE_FORMAT_WP_SHORT, - WS_WPIE_JM, - bytes(jm_content), - bytes([WS_FRAME_TYPE_PA, WS_FRAME_TYPE_LPA]) - ) - else: - wsbrd.dbus().ie_custom_insert( - WSTBU_IE_FORMAT_WP_SHORT, - WS_WPIE_JM, - bytes(), - bytes() + jm_content = bytearray() + jm_content.append(jm_version) + # NOTE: JM-IE can be inserted with no metric included + for jm_id in jm_list: + jm_len, jm_data = jm_list[jm_id] + jm_content.append( + utils.field_prep(WS_MASK_JM_ID, jm_id) | + utils.field_prep(WS_MASK_JM_LEN, jm_len) ) + jm_content.extend(jm_data) + wsbrd.dbus().ie_custom_insert( + WSTBU_IE_FORMAT_WP_SHORT, + WS_WPIE_JM, + bytes(jm_content), + bytes([WS_FRAME_TYPE_PA, WS_FRAME_TYPE_LPA, WS_FRAME_TYPE_DATA]) + ) @dbus_errcheck @@ -572,7 +569,12 @@ def config_border_router_revoke_keys(): @dbus_errcheck @json_errcheck('/config/borderRouter/informationElements') def config_border_router_information_elements(): + global jm_list, jm_version + json = flask.request.get_json(force=True, silent=True) + wsbrd.dbus().ie_custom_clear() + # HACK: JM-IE are also inserted using D-Bus IeCustomInsert + wsbrd_set_join_metrics(jm_list, jm_version) for json_ie in json: format = json_ie['format'] sub_id = json_ie['subID'] @@ -582,22 +584,17 @@ def config_border_router_information_elements(): return error(400, WSTBU_ERR_UNKNOWN, 'invalid content') wsbrd.dbus().ie_custom_insert(format, sub_id, content, bytes([WS_FRAME_TYPE_PC])) elif flask.request.method == 'DELETE': - wsbrd.dbus().ie_custom_insert(format, sub_id, bytes(), bytes()) + pass return success() -# Dict from JM-ID to tuple (len, data) -jm_list: dict[int, tuple[int, bytes]] = dict() -jm_version = 0 - - @dbus_errcheck @json_errcheck('/config/borderRouter/joinMetrics') def config_border_router_join_metrics(): global jm_list, jm_version json = flask.request.get_json(force=True, silent=True) - jm_list_cpy = jm_list.copy() # Do not update the JM list before validation + jm_list_new = dict() # Do not update the JM list before validation for json_jm in json: if json_jm['metricId'] > utils.field_max(WS_MASK_JM_ID): return error(500, WSTBU_ERR_UNKNOWN, 'invalid metric ID') @@ -617,10 +614,11 @@ def config_border_router_join_metrics(): return error(500, WSTBU_ERR_UNKNOWN, 'invalid metricData') if 'metricLength' in json_jm and json_jm['metricLength'] != jm_len: return error(500, WSTBU_ERR_UNKNOWN, 'invalid length') - jm_list_cpy[json_jm['metricId']] = (jm_len, jm_data) + jm_list_new[json_jm['metricId']] = (jm_len, jm_data) elif flask.request.method == 'DELETE': - del jm_list_cpy[json_jm['metricId']] - jm_list = jm_list_cpy + pass # Delete all metrics + jm_list = jm_list_new + jm_version = (jm_version + 1) % 256 # HACK: /config/borderRouter/joinMetrics may be called before /runMode/1 if wsbrd.service.active_state == 'active': wsbrd_set_join_metrics(jm_list, jm_version) diff --git a/tools/wsbrd_cli/wsbrd_cli.rs b/tools/wsbrd_cli/wsbrd_cli.rs index 680b9e202..20a35d253 100644 --- a/tools/wsbrd_cli/wsbrd_cli.rs +++ b/tools/wsbrd_cli/wsbrd_cli.rs @@ -1,4 +1,5 @@ /* + * SPDX-License-Identifier: LicenseRef-MSLA * Copyright (c) 2021-2023 Silicon Laboratories Inc. (www.silabs.com) * * The licensor of this software is Silicon Laboratories Inc. Your use of this