lorawan_status_t LoRaPHYCN470::set_next_channel(channel_selection_params_t *params, uint8_t *channel, lorawan_time_t *time, lorawan_time_t *aggregate_timeoff) { uint8_t channel_count = 0; uint8_t delay_tx = 0; uint8_t enabled_channels[CN470_MAX_NB_CHANNELS] = {0}; lorawan_time_t next_tx_delay = 0; band_t *band_table = (band_t *) phy_params.bands.table; if (num_active_channels(phy_params.channels.mask, 0, phy_params.channels.mask_size) == 0) { // Reactivate default channels copy_channel_mask(phy_params.channels.mask, phy_params.channels.default_mask, phy_params.channels.mask_size); } if (params->aggregate_timeoff <= _lora_time->get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; // Update bands Time OFF next_tx_delay = update_band_timeoff(params->joined, params->dc_enabled, band_table, phy_params.bands.size); // Search how many channels are enabled channel_count = enabled_channel_count(params->current_datarate, phy_params.channels.mask, enabled_channels, &delay_tx); } else { delay_tx++; next_tx_delay = params->aggregate_timeoff - _lora_time->get_elapsed_time(params->last_aggregate_tx_time); } if (channel_count > 0) { // We found a valid channel *channel = enabled_channels[get_random(0, channel_count - 1)]; *time = 0; return LORAWAN_STATUS_OK; } if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } *time = 0; return LORAWAN_STATUS_NO_CHANNEL_FOUND; }
int8_t LoRaPHYUS915::limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, int8_t datarate) { int8_t tx_power_out = tx_power; // Limit tx power to the band max tx_power_out = MAX (tx_power, max_band_tx_power); if (datarate == DR_4) { // Limit tx power to max 26dBm tx_power_out = MAX (tx_power, TX_POWER_2); } else { if (num_active_channels(channel_mask, 0, 4) < 50) { // Limit tx power to max 21dBm tx_power_out = MAX (tx_power, TX_POWER_5); } } return tx_power_out; }
bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, lorawan_time_t* aggregate_timeOff) { uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; uint8_t enabled_channels[US915_MAX_NB_CHANNELS] = {0}; lorawan_time_t next_tx_delay = 0; // Count 125kHz channels if (num_active_channels(current_channel_mask, 0, 4) == 0) { // If none of the 125 kHz Upstream channel found, // Reactivate default channels copy_channel_mask(current_channel_mask, channel_mask, 4); } // Check other channels if (params->current_datarate >= DR_4) { if ((current_channel_mask[4] & 0x00FF ) == 0) { current_channel_mask[4] = channel_mask[4]; } } if (params->aggregate_timeoff <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeOff = 0; // Update bands Time OFF next_tx_delay = update_band_timeoff(params->joined, params->dc_enabled, bands, US915_MAX_NB_BANDS); // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, current_channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; next_tx_delay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { // We found a valid channel *channel = enabled_channels[get_random( 0, nb_enabled_channels - 1 )]; // Disable the channel in the mask disable_channel(current_channel_mask, *channel, US915_MAX_NB_CHANNELS - 8); *time = 0; return true; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; return true; } // Datarate not supported by any channel *time = 0; return false; } }
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; }
lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, lorawan_time_t* aggregate_timeoff) { uint8_t next_channel_idx = 0; uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; uint8_t enabled_channels[KR920_MAX_NB_CHANNELS] = {0}; lorawan_time_t nextTxDelay = 0; if (num_active_channels(channel_mask, 0, 1) == 0) { // Reactivate default channels channel_mask[0] |= LC(1) + LC(2) + LC(3); } if (params->aggregate_timeoff <= _lora_time->get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; // Update bands Time OFF nextTxDelay = update_band_timeoff(params->joined, params->dc_enabled, bands, KR920_MAX_NB_BANDS); // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(params->current_datarate, channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; nextTxDelay = params->aggregate_timeoff - _lora_time->get_elapsed_time(params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); i < KR920_MAX_NB_CHANNELS; i++) { next_channel_idx = enabled_channels[j]; j = ( j + 1 ) % nb_enabled_channels; // Perform carrier sense for KR920_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism _radio->lock(); if (_radio->perform_carrier_sense(MODEM_LORA, channels[next_channel_idx].frequency, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true) { // Free channel found *channel = next_channel_idx; *time = 0; _radio->unlock(); return LORAWAN_STATUS_OK; } _radio->unlock(); } return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = nextTxDelay; return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel, restore defaults channel_mask[0] |= LC(1) + LC(2) + LC(3); *time = 0; return LORAWAN_STATUS_NO_CHANNEL_FOUND; } }
bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams, uint8_t* channel, lorawan_time_t* time, lorawan_time_t* aggregate_timeoff) { uint8_t next_channel_idx = 0; uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; uint8_t enabled_channels[AS923_MAX_NB_CHANNELS] = { 0 }; lorawan_time_t next_tx_delay = 0; if (num_active_channels(channel_mask, 0, 1) == 0) { // Reactivate default channels channel_mask[0] |= LC(1) + LC(2); } if (next_channel_prams->aggregate_timeoff <= _lora_time.get_elapsed_time(next_channel_prams->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; // Update bands Time OFF next_tx_delay = update_band_timeoff(next_channel_prams->joined, next_channel_prams->dc_enabled, bands, AS923_MAX_NB_BANDS); // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(next_channel_prams->joined, next_channel_prams->current_datarate, channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; next_tx_delay = next_channel_prams->aggregate_timeoff - _lora_time.get_elapsed_time(next_channel_prams->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { _radio->lock(); for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); i < AS923_MAX_NB_CHANNELS; i++) { next_channel_idx = enabled_channels[j]; j = ( j + 1 ) % nb_enabled_channels; // Perform carrier sense for AS923_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism if (_radio->perform_carrier_sense(MODEM_LORA, channels[next_channel_idx].frequency, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME) == true) { // Free channel found _radio->unlock(); *channel = next_channel_idx; *time = 0; return true; } } _radio->unlock(); return false; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; return true; } // Datarate not supported by any channel, restore defaults channel_mask[0] |= LC( 1 ) + LC( 2 ); *time = 0; return false; } }