int thread_management_get_current_keysequence(int8_t interface_id, uint32_t *sequencePtr)
{

    link_configuration_s *linkConfiguration;
    linkConfiguration = thread_joiner_application_get_config(interface_id);
    if (!linkConfiguration) {
        return -1;
    }
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (!cur->thread_info->masterSecretMaterial.valid_Info) {
        return -1;
    }

    *sequencePtr = linkConfiguration->key_sequence;

    return 0;
}
Example #2
0
int8_t net_nvm_wpan_params_storage_enable(int8_t interface_id, wpan_params_updated *nvm_update_cb, wpan_params_get *nvm_get_cb)
{

    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !nvm_update_cb || !nvm_get_cb) {
        return -1;
    }

    if (cur->nwk_wpan_nvm_api) {
        return 0;
    }
    cur->nwk_wpan_nvm_api = ns_dyn_mem_alloc(sizeof(nwk_wpan_nvm_api_t));
    if (!cur->nwk_wpan_nvm_api) {
        return -2;
    }

    cur->nwk_wpan_nvm_api->interface = cur;
    cur->nwk_wpan_nvm_api->params.pan_id = 0xffff;
    cur->nwk_wpan_nvm_api->NVM_GET = nvm_get_cb;
    cur->nwk_wpan_nvm_api->NVM_PUSH = nvm_update_cb;
    cur->nwk_wpan_nvm_api->nvm_params_get_cb = nwk_nvm_params_get_cb;
    cur->nwk_wpan_nvm_api->nvm_params_update_cb = nwk_nvm_params_update_cb;

    return 0;
}
int thread_management_max_child_count(
    int8_t interface_id,
    uint8_t maxChildCount)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur;

    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        tr_warn("Invalid interface id");
        return -1;
    }

    if (!cur->thread_info) {
        tr_warn("Not Thread specific interface");
        return -1;
    }

    mac_description_storage_size_t buffer;
    if (!cur->mac_api || !cur->mac_api->mac_storage_sizes_get || cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) {
        return -1;
    }

    if (maxChildCount > buffer.device_decription_table_size) {
        tr_error("Accept values are between 0-%d for max Child count", buffer.device_decription_table_size);
        return -1;
    }
    cur->thread_info->maxChildCount = maxChildCount;
    return 0;
#else
    (void) interface_id;
    (void) maxChildCount;
    return -1;
#endif
}
int thread_management_device_type_set(int8_t interface_id, thread_device_type_e device_type)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);

    if (!cur || !cur->thread_info) {
        tr_warn("Not Thread specific interface");
        return -1;
    }
    if (device_type == THREAD_DEVICE_REED) {
        // Change mode to router
        cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER;
    } else if (device_type == THREAD_DEVICE_FED) {
        //FED devices makes links and makes address resolutions
        cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST;
        cur->thread_info->end_device_link_synch = true;
    } else if (device_type == THREAD_DEVICE_MED) {
        cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST;
        cur->thread_info->end_device_link_synch = false;
    } else if (device_type == THREAD_DEVICE_SED) {
        cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST;
        cur->thread_info->end_device_link_synch = false;
    }
    if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
        // bootstrap active need to restart
        thread_bootstrap_reset_restart(interface_id);
    }

    return 0;
#else
    (void) interface_id;
    (void) device_type;
    return -1;
#endif
}
/**
 * Thread key sequence & key synch
 *
 */
void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce)
{
    protocol_interface_info_entry_t *cur;
    link_configuration_s *linkConfiguration;
    linkConfiguration = thread_joiner_application_get_config(interface_id);
    if (!linkConfiguration) {
        return;
    }
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->thread_info) {
        return;
    }
    if (!cur->thread_info->masterSecretMaterial.valid_Info) {
        return;
    }
    //tr_debug("Sync key material by %"PRIu32, keySequnce);

    if (keySequnce <= linkConfiguration->key_sequence) {
        // Smaller or equal request ignored
        //tr_debug("Sync key material no change");
        return;
    }
    if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) {
        // Guard time prevent the change
        //tr_debug("Sync key material guard blocked");
        return;
    }
    // Calculate new keys
    tr_debug("Sync key material by %"PRIu32, keySequnce);
    thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
    thread_key_guard_timer_calculate(cur, linkConfiguration, false);
}
int thread_management_get_my_iid16(int8_t interface_id, uint8_t *iidPtr)
{
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (thread_attach_ready(cur) != 0) {
        return -1;
    }

    if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) {
        return -1;
    }

    memcpy(iidPtr, ADDR_SHORT_ADR_SUFFIC, 6);
    common_write_16_bit(mac_helper_mac16_address_get(cur), (iidPtr + 6));

    return 0;
}
int8_t thread_management_get_request_full_nwk_data(int8_t interface_id, bool *full_nwk_data)
{
#ifdef HAVE_THREAD
    const protocol_interface_info_entry_t *cur;

    if (!full_nwk_data) {
        tr_warn("Invalid input ptr");
        return -3;
    }
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        tr_warn("Invalid interface id");
        return -1;
    }
    if (!cur->thread_info) {
        tr_warn("Thread not active");
        return -2;
    }
    *full_nwk_data = cur->thread_info->requestFullNetworkData;
    return 0;
#else
    (void) interface_id;
    (void) full_nwk_data;
    return -1;
#endif
}
int thread_management_network_certificate_set(int8_t interface_id, const unsigned char *network_certificate_ptr, uint16_t network_certificate_len, const unsigned char *priv_key_ptr, uint16_t priv_key_len)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur;

    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        tr_debug("invalid interface id");
        return -1;
    }

    if (0 > thread_extension_bootstrap_network_certificate_set(cur, network_certificate_ptr, network_certificate_len)) {
        return -1;
    }

    return thread_extension_bootstrap_network_private_key_set(cur, priv_key_ptr, priv_key_len);
#else
    (void) interface_id;
    (void) network_certificate_ptr;
    (void) network_certificate_len;
    (void) priv_key_ptr;
    (void) priv_key_len;
    return -1;
#endif
}
int8_t thread_management_set_link_timeout(int8_t interface_id, uint32_t link_timeout)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur;

    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        tr_warn("Invalid interface id");
        return -1;
    }
    thread_info_t *thread = cur->thread_info;
    if (!thread) {
        tr_warn("Thread not active");
        return -2;
    }
    tr_info("set new link timeout %"PRIu32" , old value %"PRIu32"", link_timeout, thread->host_link_timeout);
    thread->host_link_timeout = link_timeout;
    thread_bootstrap_child_update_trig(cur);
    return 0;
#else
    (void) interface_id;
    (void) link_timeout;
    return -1;
#endif
}
int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr)
{
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
    uint8_t temp[16];
    protocol_interface_info_entry_t *cur;
    thread_prefix_tlv_t prefixTlv;
    tr_debug("GUA server Delete");
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    memcpy(temp, prefix_ptr, 8);
    memset(temp + 8, 0, 8);

    prefixTlv.domainId = 0;
    prefixTlv.Prefix = prefix_ptr;
    prefixTlv.PrefixLen = 64;
    //Delete dhcp service
    DHCPv6_server_service_delete(interface_id, prefix_ptr, false);
    ipv6_route_delete(temp, 64, cur->id, NULL, ROUTE_THREAD);
    thread_local_server_list_del_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv);

    return 0;
#else
    (void) interface_id;
    (void) prefix_ptr;
    return -1;
#endif
}
int thread_management_get_ml64_address(int8_t interface_id, uint8_t *address_ptr)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!address_ptr) {
        return -1;
    }

    if (0 != thread_management_get_ml_prefix(interface_id, address_ptr)) {
        return -2;
    }

    memcpy(&address_ptr[8], cur->iid_slaac, 8);
    return 0;
#else
    (void) interface_id;
    (void) address_ptr;
    return -1;
#endif
}
int thread_management_get_commissioner_address(int8_t interface_id, uint8_t *address_ptr, uint16_t *port_ptr)
{
#ifdef HAVE_THREAD
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);

    if (!cur || !cur->thread_info || !address_ptr) {
        return -1;
    }

    if (!cur->thread_info->registered_commissioner.commissioner_valid) {
        return -2;
    }
    memcpy(address_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8);
    memcpy(address_ptr + 8, ADDR_SHORT_ADR_SUFFIC, 6);
    common_write_16_bit(0xfc30 + (cur->thread_info->registered_commissioner.session_id % 8), address_ptr + 14);

    if (port_ptr) {
        *port_ptr = THREAD_MANAGEMENT_PORT;// Default commissioner port
    }

    return 0;
#else
    (void) interface_id;
    (void) address_ptr;
    (void) port_ptr;
    return -1;
#endif
}
int thread_management_link_configuration_add(int8_t interface_id, uint8_t *additional_ptr, uint8_t additional_len)
{
#ifdef HAVE_THREAD
    if (interface_id < 0) {
        return -1;
    }

    int ret = thread_joiner_application_update_configuration(interface_id, additional_ptr, additional_len, true);
    if (ret != 0) {
        return ret;
    }

    protocol_interface_info_entry_t *cur =  protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur  || !cur->thread_info) {
        return -2;
    }
    if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) !=  0) {
        // take new settings into use after restart
        thread_bootstrap_reset_restart(interface_id);
    }

    return ret;
#else
    (void) interface_id;
    (void) additional_ptr;
    (void) additional_len;
    return -1;
#endif
}
int thread_management_link_configuration_store(int8_t interface_id, link_configuration_s *link_config)
{
#ifdef HAVE_THREAD
    int ret = thread_joiner_application_link_configuration_store(interface_id, link_config);

    if (interface_id == -1) {
        return ret;
    }

    if (ret >= 0) {
        protocol_interface_info_entry_t *cur =  protocol_stack_interface_info_get_by_id(interface_id);
        if (!link_config || !cur  || !cur->thread_info) {
            return -2;
        }
        if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) !=  0) {
            // take new settings into use after restart
            thread_bootstrap_reset_restart(interface_id);
        }
    }

    return ret;
#else
    (void) interface_id;
    (void) link_config;
    return -1;
#endif
}
Example #15
0
static void thread_nd_coap_notification_callback(int8_t interface_id, const uint8_t ip_addr[16], uint16_t loc_addr, const uint8_t ml_eid[8])
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return;
    }

    /* First check to see if we have an existing entry with different RLOC - we need to unicast error
     * notification to that old entry if so. */
    ipv6_neighbour_t *entry = ipv6_neighbour_lookup(&cur->ipv6_neighbour_cache, ip_addr);
    if (entry && entry->ll_type == ADDR_802_15_4_SHORT) {
        uint16_t old_entry_rloc = common_read_16_bit(entry->ll_address + 2);
        if (old_entry_rloc != loc_addr) {
            uint8_t old_entry_ip[16];
            thread_addr_write_mesh_local_16(old_entry_ip, common_read_16_bit(entry->ll_address + 2), cur->thread_info);
            tr_warn("Proactive address change %s %04x->%04x", trace_ipv6(ip_addr), old_entry_rloc, loc_addr);
            thread_resolution_client_address_error(interface_id, old_entry_ip, ip_addr, ml_eid);
        }
    }

    /* Now treat as an unsolicited update (by address, because entry may be NULL) */
    uint8_t ll_addr[4];
    common_write_16_bit(cur->mac_parameters->pan_id, ll_addr + 0);
    common_write_16_bit(loc_addr, ll_addr + 2);
    ipv6_neighbour_update_unsolicited(&cur->ipv6_neighbour_cache, ip_addr, ADDR_802_15_4_SHORT, ll_addr);

    if (nd_proxy_enabled_for_upstream(cur->id)) {
        ipv6_route_add(ip_addr, 128, cur->id, NULL, ROUTE_THREAD_PROXIED_HOST, 3600, 0);
    }
}
/* Get my mesh local prefix /112 */
int thread_management_get_ml_prefix_112(int8_t interface_id, uint8_t *prefix_ptr)
{
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !prefix_ptr) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (thread_attach_ready(cur) != 0) {
        return -1;
    }

    if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) {
        return -1;
    }

    memcpy(prefix_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8);
    memcpy(prefix_ptr + 8, ADDR_SHORT_ADR_SUFFIC, 6);

    return 0;
}
int8_t thread_management_get_link_timeout(int8_t interface_id, uint32_t *link_timeout)
{
#ifdef HAVE_THREAD
    const protocol_interface_info_entry_t *cur;

    if (!link_timeout) {
        tr_warn("Invalid input ptr");
        return -3;
    }
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        tr_warn("Invalid interface id");
        return -1;
    }
    const thread_info_t *thread = cur->thread_info;
    if (!thread) {
        tr_warn("Thread not active");
        return -2;
    }
    *link_timeout = thread->host_link_timeout;
    return 0;
#else
    (void) interface_id;
    (void) link_timeout;
    return -1;
#endif
}
void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t *status)
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
    if (!cur) {
        return;
    }
    mac_neighbor_table_entry_t *entry;

    switch (status->status) {

        case MLME_SECURITY_FAIL:

            break;

        case MLME_COUNTER_ERROR:

            break;

        case MLME_DATA_POLL_NOTIFICATION:
            entry = neighbor_data_poll_referesh(cur, status->SrcAddr, (addrtype_t)status->SrcAddrMode);
            if (entry) {
                thread_neighbor_communication_update(cur, entry->index);
            }
            break;
        default:
            break;
    }
}
int thread_management_get_ml_prefix(int8_t interface_id, uint8_t *prefix_ptr)
{
    // TODO get from static configuration
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !prefix_ptr) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (thread_attach_ready(cur) != 0) {
        return -1;
    }

    if (!cur->thread_info->threadPrivatePrefixInfo.ulaValid) {
        return -1;
    }

    memcpy(prefix_ptr, cur->thread_info->threadPrivatePrefixInfo.ulaPrefix, 8);

    return 0;
}
Example #20
0
int8_t net_nvm_wpan_params_storage_reset(int8_t interface_id)
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->nwk_wpan_nvm_api) {
        return -1;
    }
    cur->nwk_wpan_nvm_api->params.pan_id = 0xffff;
    return 0;
}
Example #21
0
int8_t arm_nwk_6lowpan_rpl_dodag_start(int8_t interface_id)
{
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->rpl_domain) {
        return -1;
    }
    rpl_control_force_leaf(cur->rpl_domain, false);
    return 0;
}
Example #22
0
int8_t net_nvm_wpan_params_storage_disable(int8_t interface_id)
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->nwk_wpan_nvm_api) {
        return -1;
    }
    ns_dyn_mem_free(cur->nwk_wpan_nvm_api);
    cur->nwk_wpan_nvm_api = NULL;
    return 0;

}
Example #23
0
int8_t arm_nwk_6lowpan_rpl_dodag_poison(int8_t interface_id)
{
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->rpl_domain) {
        return -1;
    }
    rpl_control_poison(cur->rpl_domain, 3 /* arbitrary poison count */);
    /* Make sure we send no more adverts after poison */
    rpl_control_force_leaf(cur->rpl_domain, true);
    return 0;
}
/**
 * Set DHCPV6 server for Thread GP data purpose
 *
 * \param interface_id Network Interface
 * \param prefix_ptr pointer DHCPv6 Server Given Prefix
 *
 * return 0, Set OK
 * return <0 Set Not OK
 */
int thread_dhcpv6_server_add(int8_t interface_id, uint8_t *prefix_ptr, uint32_t max_client_cnt, bool stableData)
{
#if defined(HAVE_THREAD) && defined(HAVE_DHCPV6_SERVER)
    protocol_interface_info_entry_t *cur;
    thread_prefix_tlv_t prefixTlv;
    thread_border_router_tlv_entry_t service;
    uint8_t temp[16];
    uint8_t *ptr = temp;

    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur) {
        return -1;
    }

    if (!cur->thread_info) {
        return -1;
    }

    if (thread_dhcp6_server_init(interface_id, prefix_ptr, cur->mac, THREAD_MIN_PREFIX_LIFETIME) != 0) {
        tr_warn("SerVER alloc fail");
        return -1;
    }

    prefixTlv.domainId = 0;
    prefixTlv.Prefix = prefix_ptr;
    prefixTlv.PrefixLen = 64;

    memset(&service, 0, sizeof(thread_border_router_tlv_entry_t));
    service.Prf = 1;
    service.P_dhcp = true;
    service.P_on_mesh = true;
    service.stableData = stableData;

    // SET maximum number of accepted clients
    DHCPv6_server_service_set_max_clients_accepts_count(interface_id, prefix_ptr, max_client_cnt);

    tr_debug("GUA server Generate OK");
    memcpy(ptr, prefix_ptr, 8);
    memset(ptr + 8, 0, 8);
    //Network Data
    if (thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service) != 0) {
        return -1;
    }

    return 0;
#else
    (void) interface_id;
    (void) prefix_ptr;
    (void) max_client_cnt;
    (void) stableData;
    return -1;
#endif
}
Example #25
0
int8_t net_load_balance_set_max_probability(int8_t interface_id , uint8_t max_p)
{
#ifdef HAVE_6LOWPAN_ND
    protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id);
    if (!interface_ptr) {
        return -1;
    }

    return load_balance_set_max_probability(interface_ptr->lb_api, max_p);
#else
    return -1;
#endif
}
Example #26
0
int8_t arm_nwk_6lowpan_rpl_dodag_remove(int8_t interface_id)
{
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->rpl_domain) {
        return -1;
    }
    if (!protocol_6lowpan_rpl_root_dodag) {
        return -1;
    }
    rpl_control_delete_dodag_root(cur->rpl_domain, protocol_6lowpan_rpl_root_dodag);
    return -1;
}
Example #27
0
int8_t arm_nwk_6lowpan_rpl_dodag_version_increment(int8_t interface_id)
{
    /* New code version - specifying interface ID makes no sense - fudge to let it increase main RPL root */
    protocol_interface_info_entry_t *cur;
    cur = protocol_stack_interface_info_get_by_id(interface_id);
    if (!cur || !cur->rpl_domain || cur->rpl_domain != protocol_6lowpan_rpl_domain || !protocol_6lowpan_rpl_root_dodag) {
        return -1;
    }

    rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag);

    return 0;
}
Example #28
0
int8_t net_load_balance_network_switch_cb_set(int8_t interface_id, net_load_balance_network_switch_notify *network_switch_notify)
{
#ifdef HAVE_6LOWPAN_ND
    protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id);
    if (!interface_ptr) {
        return -1;
    }

    return load_balance_network_switch_cb_set(interface_ptr->lb_api, network_switch_notify);
#else
    return -1;
#endif
}
Example #29
0
void nwk_parent_poll_fail_cb(int8_t id)
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(id);
    if (!cur) {
        tr_error("Data Poll Fail Event: No interface");
        return;
    }
    if (thread_info(cur)) {
        //Initialize Bootsrap
        thread_bootstrap_connection_error(cur->id, CON_ERROR_POLL, NULL);
    } else {
        nwk_bootsrap_state_update(ARM_NWK_NWK_PARENT_POLL_FAIL, cur);
    }

}
Example #30
0
int8_t mac_helper_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr)
{
    protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);

    if (!cur || !cur->mac_api || !seq_ptr) {
        return -1;
    }
    mlme_get_t get_req;
    get_req.attr = macFrameCounter;
    get_req.attr_index = 0;
    cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
    *seq_ptr = cur->mac_parameters->security_frame_counter;

    return 0;
}