Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;
}