Esempio n. 1
0
int fhss_tx_handle_cb(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length)
{
    fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
    if (!fhss_structure) {
        return -2;
    }
    // TODO: needs some more logic to push buffer back to queue
    if (frame_type == FHSS_DATA_FRAME) {
        if (is_broadcast_addr == true) {
            if (fhss_is_current_channel_broadcast(fhss_structure) == false) {
                tr_info("Broadcast on UC channel -> Back to queue");
                return -3;
            }
        }
    }
    if (frame_type == FHSS_SYNCH_FRAME) {
        if (!synch_info) {
            return -4;
        }
        fhss_beacon_build(fhss_structure, synch_info);
    } else if (fhss_check_tx_allowed(fhss_structure, is_broadcast_addr, frame_length, frame_type, phy_header_length, phy_tail_length) == false) {
        return -1;
    }
    // If sending Beacon request on parents Unicast channel
    if (frame_type == FHSS_SYNCH_REQUEST_FRAME && fhss_structure->fhss_state == FHSS_SYNCHRONIZED) {
        fhss_change_to_parent_channel(fhss_structure);
    } else if (frame_type == FHSS_DATA_FRAME) {
        fhss_change_to_tx_channel(fhss_structure, destination_address);
    }
    return 0;
}
Esempio n. 2
0
void fhss_receive_frame_cb(const fhss_api_t *api, uint16_t pan_id, uint8_t *source_address, uint32_t timestamp, uint8_t *synch_info, int frame_type)
{
    fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
    if (!fhss_structure) {
        return;
    }
    if (FHSS_SYNCH_FRAME == frame_type) {
        if ((fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) || fhss_structure->synch_panid != pan_id) {
            fhss_add_beacon_info(fhss_structure, pan_id, source_address, timestamp, synch_info);
        } else {
            if (!fhss_compare_with_synch_parent_address(fhss_structure, source_address)) {
                // Synch parent address needs to be updated in case parent has changed
                fhss_update_synch_parent_address(fhss_structure);
                platform_enter_critical();
                // Calculate time since the Beacon was received
                uint32_t elapsed_time = api->read_timestamp(api) - timestamp;
                // Synchronize to given PAN
                fhss_beacon_received(fhss_structure, synch_info, elapsed_time);
                platform_exit_critical();
            }
        }
    } else if (FHSS_SYNCH_REQUEST_FRAME == frame_type) {
        // If current channel is broadcast, we don't need to send another synch info on next broadcast channel.
        // Only send number of MAX_SYNCH_INFOS_PER_CHANNEL_LIST synch infos per one channel list cycle
        if ((fhss_structure->fhss_state == FHSS_SYNCHRONIZED) && (fhss_is_current_channel_broadcast(fhss_structure) == false)
                && (fhss_structure->synch_infos_sent_counter < MAX_SYNCH_INFOS_PER_CHANNEL_LIST)) {
            fhss_structure->send_synch_info_on_next_broadcast_channel = true;
        }
    }
}
Esempio n. 3
0
/**
 * Update channel
 *
 * This function is called by superframe handler on first(0) superframe
 * of every channel to resolve and change new channel.
 *
 * @param cur network interface to work on
 * @return true if changed to broadcast channel, false otherwise
 */
bool fhss_change_to_next_channel(fhss_structure_t *fhss_structure)
{
    int next_channel;
    bool broadcast_channel = false;

    uint16_t number_of_channels = fhss_structure->number_of_channels;
    uint8_t number_of_broadcast_channels = fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels;
    uint8_t unicast_channel_index = fhss_structure->bs->uc_channel_index;
    uint8_t channel_index_tmp;

    /* Get the channel number using channel index. Latter (number_of_broadcast_channels) indexes in channel table are broadcast channels and
     * first (number_of_channels - number_of_broadcast_channels) are unicast channels.
     * In channel hopping sequence, every (number_of_channels / number_of_broadcast_channels) channel is broadcast channel and
     * channel hopping sequence is e.g. |uc0|uc1|uc2|bc0|uc3|uc4|uc5|bc1|uc6|...
     */
    /* Get broadcast channel */
    if (fhss_is_current_channel_broadcast(fhss_structure) == true) {
        channel_index_tmp = fhss_calc_channel_shuffle((number_of_channels - number_of_broadcast_channels) + fhss_get_bc_index(fhss_structure), fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels);
        fhss_generate_broadcast_start_superframe(fhss_structure);
        broadcast_channel = true;
    } else { /* Get unicast channel */
        channel_index_tmp = fhss_calc_channel_shuffle(unicast_channel_index, fhss_structure->number_of_channels, fhss_structure->bs->synch_configuration.fhss_number_of_bc_channels);
        if (++fhss_structure->bs->uc_channel_index >= number_of_channels - number_of_broadcast_channels) {
            fhss_structure->bs->uc_channel_index = 0;
        }
    }
    // Reset Beacon received flag when channel has changed
    fhss_structure->bs->beacon_received_on_this_bc_channel = false;
    channel_index_tmp = fhss_add_channel_list_counter(channel_index_tmp, fhss_structure->number_of_channels, fhss_structure->bs->channel_list_counter, fhss_structure->bs->fhss_scramble_table);
    next_channel = channel_list_get_channel(fhss_structure->bs->fhss_configuration.channel_mask, channel_index_tmp);

    fhss_structure->rx_channel = next_channel;
#ifdef FHSS_CHANNEL_DEBUG
    if (fhss_is_current_channel_broadcast(fhss_structure) == true) {
        tr_info("%"PRIu32" BC %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel);
    } else {
        tr_info("%"PRIu32" UC %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), next_channel);
    }
#endif /*FHSS_CHANNEL_DEBUG*/
    fhss_structure->callbacks.change_channel(fhss_structure->fhss_api, next_channel);
    return broadcast_channel;
}
Esempio n. 4
0
bool fhss_is_broadcast_channel_cb(const fhss_api_t *api)
{
    fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
    if (!fhss_structure) {
        return false;
    }
    // FHSS is unsynchronized, broadcasts allowed
    if (fhss_structure->fhss_state == FHSS_UNSYNCHRONIZED) {
        return true;
    }
    return fhss_is_current_channel_broadcast(fhss_structure);
}
Esempio n. 5
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;
}