int fhss_change_to_parent_channel(fhss_structure_t *fhss_structure) { uint8_t uc_index; uint8_t destination_channel; uint8_t destination_offset; if (fhss_structure) { if (fhss_structure->number_of_channels != fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) { uint8_t parent_address[8]; if (fhss_get_parent_address(fhss_structure, parent_address)) { return -1; } destination_offset = fhss_get_offset(fhss_structure, parent_address); uc_index = fhss_calculate_uc_index(fhss_structure->bs->current_channel_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) + destination_offset; if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels)) { uc_index -= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); } uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table); destination_channel = channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, uc_index); fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, destination_channel); #ifdef FHSS_CHANNEL_DEBUG tr_info("Parent channel: %u", destination_channel); #endif /*FHSS_CHANNEL_DEBUG*/ } } return 0; }
void fhss_synch_state_set_cb(const fhss_api_t *api, fhss_states fhss_state, uint16_t pan_id) { fhss_structure_t *fhss_structure = fhss_get_object_with_api(api); if (!fhss_structure) { return; } // State is already set if (fhss_structure->fhss_state == fhss_state) { tr_debug("Synch same state %u", fhss_state); return; } if (fhss_state == FHSS_UNSYNCHRONIZED) { tr_debug("FHSS down"); fhss_down(fhss_structure); } else { // Do not synchronize to current pan if (fhss_structure->synch_panid == pan_id) { tr_debug("Synch same panid %u", pan_id); return; } uint32_t datarate = fhss_structure->callbacks.read_datarate(api); fhss_set_datarate(fhss_structure, datarate); uint8_t mac_address[8]; fhss_structure->callbacks.read_mac_address(fhss_structure->fhss_api, mac_address); fhss_structure->uc_channel_index = fhss_get_offset(fhss_structure, mac_address); // Get Beacon info from storage fhss_beacon_info_t *beacon_info = fhss_get_beacon_info(fhss_structure, pan_id); if (beacon_info) { memcpy(fhss_structure->synch_parent, beacon_info->source_address, 8); platform_enter_critical(); // Calculate time since the Beacon was received uint32_t elapsed_time = api->read_timestamp(api) - beacon_info->timestamp; // Synchronize to given PAN fhss_beacon_received(fhss_structure, beacon_info->synch_info, elapsed_time); platform_exit_critical(); // Delete stored Beacon infos fhss_flush_beacon_info_storage(fhss_structure); fhss_structure->synch_panid = pan_id; } else if (fhss_is_synch_root(fhss_structure) == true) { // Synch root will start new network fhss_start_timer(fhss_structure, fhss_structure->synch_configuration.fhss_superframe_length, fhss_superframe_handler); } else { tr_error("Synch info not find"); } } fhss_structure->fhss_state = fhss_state; }
static uint8_t fhss_get_destination_channel(fhss_structure_t *fhss_structure, uint8_t *destination_address) { uint8_t destination_offset; uint8_t uc_index; if (fhss_structure) { if (fhss_is_current_channel_broadcast(fhss_structure) == false) { destination_offset = fhss_get_offset(fhss_structure, destination_address); uc_index = fhss_calculate_uc_index(fhss_structure->bs->current_channel_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels) + destination_offset; if (uc_index >= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels)) { uc_index -= (fhss_structure->number_of_channels - fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); } uc_index = fhss_calc_channel_shuffle(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels); uc_index = fhss_add_channel_list_counter(uc_index, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table); return channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, uc_index); } return fhss_structure->rx_channel; } return 0; }