Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers channel_list.c Source File

channel_list.c

00001 /*
00002  * Copyright (c) 2015-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 
00019 #include "nsconfig.h"
00020 #include "Service_Libs/fhss/channel_list.h"
00021 
00022 #include "common_functions.h"
00023 #include "ns_trace.h"
00024 
00025 #include <stdint.h>
00026 #include <string.h>
00027 
00028 const int CHANNEL_LIST_SIZE_IN_BITS = 8*32;
00029 
00030 static bool channel_list_bit_test32(uint32_t word, int_fast8_t bit_number);
00031 static bool channel_list_bit_test(const uint32_t* list, int bit_number);
00032 
00033 #if 0
00034 static void channel_list_bit_set32(uint32_t* word, int_fast8_t bit_number);
00035 static void channel_list_bit_set(uint32_t* list, int bit_number);
00036 #endif
00037 
00038 // test bit by number
00039 static bool channel_list_bit_test32(uint32_t word, int_fast8_t bit_number)
00040 {
00041     bool bitSet;
00042 
00043     if (word & ((uint32_t) 1 << bit_number)) {
00044         bitSet = true;
00045     } else {
00046         bitSet = false;
00047     }
00048     return bitSet;
00049 }
00050 
00051 static bool channel_list_bit_test(const uint32_t* list, int bit_number)
00052 {
00053     const int_fast8_t word_index = bit_number / 32;
00054     const int_fast8_t bit_index = bit_number % 32;
00055 
00056     return channel_list_bit_test32(list[word_index], bit_index);
00057 }
00058 #if 0
00059 // set bit by number
00060 static void channel_list_bit_set32(uint32_t* word, int_fast8_t bit_number)
00061 {
00062     *word |= ((uint32_t) 1 << bit_number);
00063 }
00064 
00065 static void channel_list_bit_set(uint32_t* list, int bit_number)
00066 {
00067     const int_fast8_t word_index = bit_number / 32;
00068     const int_fast8_t bit_index = bit_number % 32;
00069 
00070     channel_list_bit_set32(&(list[word_index]), bit_index);
00071 }
00072 
00073 
00074 void channel_list_print(uint8_t dlevel, const char *grp, const uint32_t* list)
00075 {
00076 
00077     int temp_channel = 0;
00078 
00079 #define CHANNELS_PER_LINE 32
00080 
00081     uint8_t channels[CHANNELS_PER_LINE];
00082 
00083     for (int line_index = 0; line_index < (CHANNEL_LIST_SIZE_IN_BITS/CHANNELS_PER_LINE); line_index++) {
00084 
00085         int channels_found = 0;
00086 
00087         for (int row_index = 0; row_index < CHANNELS_PER_LINE; row_index++) {
00088 
00089             if (channel_list_bit_test(list, temp_channel)) {
00090 
00091                 channels[channels_found] = temp_channel;
00092                 channels_found++;
00093             }
00094 
00095             temp_channel++;
00096         }
00097 
00098         tr_info("arr[%d]: %s", line_index, trace_array(channels, channels_found));
00099     }
00100 }
00101 
00102 // this just avoids mistakes/copypaste on client side
00103 void channel_list_clear_mask(uint32_t* list)
00104 {
00105     const int mask_size = (sizeof(list));
00106 
00107     memset(list, 0, mask_size);
00108 }
00109 
00110 static int channel_list_search_in_range(const uint32_t* list, int start_index, int end_index)
00111 {
00112     int found_index = -1;
00113     for (int index = start_index; index <= end_index; index++) {
00114 
00115         if (channel_list_bit_test(list, index)) {
00116             found_index = index;
00117             break;
00118         }
00119     }
00120     return found_index;
00121 }
00122 
00123 // utility for getting the first channel
00124 int channel_list_get_first(const uint32_t* list)
00125 {
00126 
00127     return channel_list_get_next(list, 0xff);
00128 }
00129 #endif
00130 static uint8_t channel_list_search(const uint32_t* list, int index)
00131 {
00132     uint8_t channel = 0;
00133     int enabled_channels = 0;
00134     int i, j;
00135 
00136     for(j=0; j<8; j++)
00137     {
00138         for(i=0; i<32; i++)
00139         {
00140             if (list[j] & ((uint32_t)1 << i)) {
00141                 enabled_channels++;
00142                 if (enabled_channels == (index + 1)) {
00143                     goto exit;
00144                 }
00145             }
00146             channel++;
00147         }
00148     }
00149 exit:
00150     return channel;
00151 
00152 }
00153 
00154 uint8_t channel_list_get_channel(const uint32_t* list, int current_index)
00155 {
00156     uint8_t found_index;
00157 
00158     if (current_index >= CHANNEL_LIST_SIZE_IN_BITS) {
00159         current_index = 0;
00160     }
00161 
00162     found_index = channel_list_search(list, current_index);
00163 
00164     return found_index;
00165 }
00166 #if 0
00167 int channel_list_get_next(const uint32_t* list, int current_index)
00168 {
00169     int found_index;
00170 
00171     current_index++;
00172 
00173     if (current_index >= CHANNEL_LIST_SIZE_IN_BITS) {
00174 
00175         current_index = 0;
00176     }
00177 
00178     // One could use a optimization here to avoid looping through masks 1..7
00179     // if page is not 9 or 10. But is it really worth it?
00180     found_index = channel_list_search_in_range(list, current_index, CHANNEL_LIST_SIZE_IN_BITS-1);
00181 
00182     if ((found_index < 0) && (current_index > 0)) {
00183 
00184         found_index = channel_list_search_in_range(list, 0, current_index-1);
00185     }
00186 
00187     return found_index;
00188 }
00189 
00190 int channel_list_get_next_broadcast(const uint32_t* list, int broadcast_channel_count, int current_index)
00191 {
00192 
00193     // XXX: all these could/should be pre-calculated on configuration time.
00194     const int first_broadcast = channel_list_get_first(list);
00195     const int total_channel_count = channel_list_count_channels(list);
00196     int channels_to_loop = total_channel_count / broadcast_channel_count; // crash if broadcast is configured to zero
00197 
00198     int next_broadcast = -1;
00199 
00200     // If there are more than one broadcast channels and we're not yet at the last channel,
00201     // iteratively search for next broadcast channel.
00202     if ((channels_to_loop > 1) && (current_index < (CHANNEL_LIST_SIZE_IN_BITS - 1))) {
00203 
00204         while (channels_to_loop > 0) {
00205 
00206             current_index = channel_list_get_next(list, current_index);
00207             channels_to_loop--;
00208         }
00209         next_broadcast = current_index;
00210     }
00211     else {
00212         next_broadcast = first_broadcast;
00213     }
00214 
00215     return next_broadcast;
00216 }
00217 #endif
00218 // count the amount of channels enabled in a list
00219 int channel_list_count_channels(const uint32_t* list)
00220 {
00221 
00222     int channel_count = 0;
00223 
00224     for (int index=0; index < CHANNEL_LIST_SIZE_IN_BITS; index++) {
00225 
00226         if (channel_list_bit_test(list, index)) {
00227             channel_count++;
00228         }
00229     }
00230 
00231     return channel_count;
00232 }
00233 #if 0
00234 int channel_list_enable_channel(uint32_t* list, int channel_number)
00235 {
00236     int ret_val = -1;
00237 
00238     if ((channel_number >= 0) && (channel_number < CHANNEL_LIST_SIZE_IN_BITS)) {
00239 
00240         channel_list_bit_set(list, channel_number);
00241 
00242         ret_val = 0;
00243     }
00244 
00245     return ret_val;
00246 }
00247 
00248 bool channel_list_is_channel_enabled(const uint32_t* list, int channel_number) {
00249 
00250     int ret_val = false;
00251 
00252     if ((channel_number >= 0) && (channel_number < CHANNEL_LIST_SIZE_IN_BITS)) {
00253 
00254         ret_val = channel_list_bit_test(list, channel_number);
00255     }
00256 
00257     return ret_val;
00258 }
00259 #endif