Exemple #1
0
uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params,
                                       int8_t* dr_out, int8_t* tx_power_out,
                                       uint8_t* nb_rep_out,
                                       uint8_t* nb_bytes_parsed)
{
    uint8_t status = 0x07;
    link_adr_params_t adr_settings;
    uint8_t next_index = 0;
    uint8_t bytes_processed = 0;
    uint16_t temp_channel_masks[CN470_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0, 0};

    verify_adr_params_t verify_params;

    // Initialize local copy of channels mask
    copy_channel_mask(temp_channel_masks, channel_mask, CN470_CHANNEL_MASK_SIZE);

    while(bytes_processed < params->payload_size) {

        // Get ADR request parameters
        next_index = parse_link_ADR_req(&(params->payload[bytes_processed]), &adr_settings);

        if (next_index == 0) {
            break; // break loop, since no more request has been found
        }

        // Update bytes processed
        bytes_processed += next_index;

        // Revert status, as we only check the last ADR request for the channel mask KO
        status = 0x07;

        if (adr_settings.ch_mask_ctrl == 6) {

            // Enable all 125 kHz channels
            for (uint8_t i = 0; i < CN470_CHANNEL_MASK_SIZE; i++) {
                temp_channel_masks[i] = 0xFFFF;
            }

        } else if( adr_settings.ch_mask_ctrl == 7 ) {

            status &= 0xFE; // Channel mask KO

        } else {

            for (uint8_t i = 0; i < 16; i++) {

                if (((adr_settings.channel_mask & (1 << i)) != 0 ) &&
                    (channels[adr_settings.ch_mask_ctrl * 16 + i].frequency == 0)) {
                    // Trying to enable an undefined channel
                    status &= 0xFE; // Channel mask KO
                }
            }

            temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask;
        }
    }

    verify_params.status = status;
    verify_params.adr_enabled = params->adr_enabled;
    verify_params.datarate = adr_settings.datarate;
    verify_params.tx_power = adr_settings.tx_power;
    verify_params.nb_rep = adr_settings.nb_rep;
    verify_params.current_datarate = params->current_datarate;
    verify_params.current_tx_power = params->current_tx_power;
    verify_params.current_nb_rep = params->current_nb_rep;
    verify_params.channel_mask = temp_channel_masks;


    // Verify the parameters and update, if necessary
    status = verify_link_ADR_req(&verify_params, &adr_settings.datarate,
                                 &adr_settings.tx_power, &adr_settings.nb_rep);

    // Update channelsMask if everything is correct
    if (status == 0x07) {
        // Copy Mask
        copy_channel_mask(channel_mask, temp_channel_masks, CN470_CHANNEL_MASK_SIZE);
    }

    // Update status variables
    *dr_out = adr_settings.datarate;
    *tx_power_out = adr_settings.tx_power;
    *nb_rep_out = adr_settings.nb_rep;
    *nb_bytes_parsed = bytes_processed;

    return status;
}
Exemple #2
0
uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params,
                                       int8_t* dr_out, int8_t* tx_power_out,
                                       uint8_t* nb_rep_out, uint8_t* nb_bytes_parsed)
{
    uint8_t status = 0x07;

    link_adr_params_t adr_settings;
    uint8_t next_idx = 0;
    uint8_t bytes_processed = 0;
    uint16_t temp_channel_masks[US915_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0};

    verify_adr_params_t verify_params;

    // Initialize local copy of channels mask
    copy_channel_mask(temp_channel_masks, channel_mask, US915_CHANNEL_MASK_SIZE);

    while (bytes_processed < params->payload_size) {
        next_idx = parse_link_ADR_req(&(params->payload[bytes_processed]),
                                      &adr_settings);

        if (next_idx == 0) {
            break; // break loop, since no more request has been found
        }

        // Update bytes processed
        bytes_processed += next_idx;

        // Revert status, as we only check the last ADR request for the channel mask KO
        status = 0x07;

        if (adr_settings.ch_mask_ctrl == 6) {

            // Enable all 125 kHz channels
            temp_channel_masks[0] = 0xFFFF;
            temp_channel_masks[1] = 0xFFFF;
            temp_channel_masks[2] = 0xFFFF;
            temp_channel_masks[3] = 0xFFFF;
            // Apply chMask to channels 64 to 71
            temp_channel_masks[4] = adr_settings.channel_mask;

        } else if (adr_settings.ch_mask_ctrl == 7) {

            // Disable all 125 kHz channels
            temp_channel_masks[0] = 0x0000;
            temp_channel_masks[1] = 0x0000;
            temp_channel_masks[2] = 0x0000;
            temp_channel_masks[3] = 0x0000;
            // Apply chMask to channels 64 to 71
            temp_channel_masks[4] = adr_settings.channel_mask;

        } else if (adr_settings.ch_mask_ctrl == 5) {
            // RFU
            status &= 0xFE; // Channel mask KO

        } else {
            temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask;
        }
    }

    // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
    if ((adr_settings.datarate < DR_4) &&
        (num_active_channels(temp_channel_masks, 0, 4) < 2)) {

        status &= 0xFE; // Channel mask KO

    }

    verify_params.status = status;
    verify_params.adr_enabled = params->adr_enabled;
    verify_params.datarate = adr_settings.datarate;
    verify_params.tx_power = adr_settings.tx_power;
    verify_params.nb_rep = adr_settings.nb_rep;
    verify_params.current_datarate = params->current_datarate;
    verify_params.current_tx_power = params->current_tx_power;
    verify_params.current_nb_rep = params->current_nb_rep;
    verify_params.channel_mask = temp_channel_masks;

    // Verify the parameters and update, if necessary
    status = verify_link_ADR_req(&verify_params, &adr_settings.datarate,
                                 &adr_settings.tx_power, &adr_settings.nb_rep);

    // Update channelsMask if everything is correct
    if (status == 0x07) {
        // Copy Mask
        copy_channel_mask(channel_mask, temp_channel_masks, US915_CHANNEL_MASK_SIZE);

        current_channel_mask[0] &= channel_mask[0];
        current_channel_mask[1] &= channel_mask[1];
        current_channel_mask[2] &= channel_mask[2];
        current_channel_mask[3] &= channel_mask[3];
        current_channel_mask[4] = channel_mask[4];
    }

    // Update status variables
    *dr_out = adr_settings.datarate;
    *tx_power_out = adr_settings.tx_power;
    *nb_rep_out = adr_settings.nb_rep;
    *nb_bytes_parsed = bytes_processed;

    return status;
}