LCOV - code coverage report
Current view: top level - src/p2p - p2p_utils.c (source / functions) Hit Total Coverage
Test: wpa_supplicant hwsim test run 1388240082 Lines: 150 214 70.1 %
Date: 2013-12-28 Functions: 16 16 100.0 %
Branches: 97 187 51.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * P2P - generic helper functions
       3                 :            :  * Copyright (c) 2009, Atheros Communications
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "includes.h"
      10                 :            : 
      11                 :            : #include "common.h"
      12                 :            : #include "p2p_i.h"
      13                 :            : 
      14                 :            : 
      15                 :            : /**
      16                 :            :  * p2p_random - Generate random string for SSID and passphrase
      17                 :            :  * @buf: Buffer for returning the result
      18                 :            :  * @len: Number of octets to write to the buffer
      19                 :            :  * Returns: 0 on success, -1 on failure
      20                 :            :  *
      21                 :            :  * This function generates a random string using the following character set:
      22                 :            :  * 'A'-'Z', 'a'-'z', '0'-'9'.
      23                 :            :  */
      24                 :         94 : int p2p_random(char *buf, size_t len)
      25                 :            : {
      26                 :            :         u8 val;
      27                 :            :         size_t i;
      28                 :         94 :         u8 letters = 'Z' - 'A' + 1;
      29                 :         94 :         u8 numbers = 10;
      30                 :            : 
      31         [ -  + ]:         94 :         if (os_get_random((unsigned char *) buf, len))
      32                 :          0 :                 return -1;
      33                 :            :         /* Character set: 'A'-'Z', 'a'-'z', '0'-'9' */
      34         [ +  + ]:        564 :         for (i = 0; i < len; i++) {
      35                 :        470 :                 val = buf[i];
      36                 :        470 :                 val %= 2 * letters + numbers;
      37         [ +  + ]:        470 :                 if (val < letters)
      38                 :        195 :                         buf[i] = 'A' + val;
      39         [ +  + ]:        275 :                 else if (val < 2 * letters)
      40                 :        197 :                         buf[i] = 'a' + (val - letters);
      41                 :            :                 else
      42                 :         78 :                         buf[i] = '0' + (val - 2 * letters);
      43                 :            :         }
      44                 :            : 
      45                 :         94 :         return 0;
      46                 :            : }
      47                 :            : 
      48                 :            : 
      49                 :            : /**
      50                 :            :  * p2p_channel_to_freq - Convert channel info to frequency
      51                 :            :  * @op_class: Operating class
      52                 :            :  * @channel: Channel number
      53                 :            :  * Returns: Frequency in MHz or -1 if the specified channel is unknown
      54                 :            :  */
      55                 :       2269 : int p2p_channel_to_freq(int op_class, int channel)
      56                 :            : {
      57                 :            :         /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
      58                 :            :         /* TODO: more operating classes */
      59   [ +  -  -  -  :       2269 :         switch (op_class) {
             -  -  -  -  
                      - ]
      60                 :            :         case 81:
      61                 :            :                 /* channels 1..13 */
      62 [ +  - ][ -  + ]:       2269 :                 if (channel < 1 || channel > 13)
      63                 :          0 :                         return -1;
      64                 :       2269 :                 return 2407 + 5 * channel;
      65                 :            :         case 82:
      66                 :            :                 /* channel 14 */
      67         [ #  # ]:          0 :                 if (channel != 14)
      68                 :          0 :                         return -1;
      69                 :          0 :                 return 2414 + 5 * channel;
      70                 :            :         case 83: /* channels 1..9; 40 MHz */
      71                 :            :         case 84: /* channels 5..13; 40 MHz */
      72 [ #  # ][ #  # ]:          0 :                 if (channel < 1 || channel > 13)
      73                 :          0 :                         return -1;
      74                 :          0 :                 return 2407 + 5 * channel;
      75                 :            :         case 115: /* channels 36,40,44,48; indoor only */
      76                 :            :         case 118: /* channels 52,56,60,64; dfs */
      77 [ #  # ][ #  # ]:          0 :                 if (channel < 36 || channel > 64)
      78                 :          0 :                         return -1;
      79                 :          0 :                 return 5000 + 5 * channel;
      80                 :            :         case 124: /* channels 149,153,157,161 */
      81                 :            :         case 125: /* channels 149,153,157,161,165,169 */
      82 [ #  # ][ #  # ]:          0 :                 if (channel < 149 || channel > 161)
      83                 :          0 :                         return -1;
      84                 :          0 :                 return 5000 + 5 * channel;
      85                 :            :         case 116: /* channels 36,44; 40 MHz; indoor only */
      86                 :            :         case 117: /* channels 40,48; 40 MHz; indoor only */
      87                 :            :         case 119: /* channels 52,60; 40 MHz; dfs */
      88                 :            :         case 120: /* channels 56,64; 40 MHz; dfs */
      89 [ #  # ][ #  # ]:          0 :                 if (channel < 36 || channel > 64)
      90                 :          0 :                         return -1;
      91                 :          0 :                 return 5000 + 5 * channel;
      92                 :            :         case 126: /* channels 149,157; 40 MHz */
      93                 :            :         case 127: /* channels 153,161; 40 MHz */
      94 [ #  # ][ #  # ]:          0 :                 if (channel < 149 || channel > 161)
      95                 :          0 :                         return -1;
      96                 :          0 :                 return 5000 + 5 * channel;
      97                 :            :         case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
      98 [ #  # ][ #  # ]:          0 :                 if (channel < 36 || channel > 161)
      99                 :          0 :                         return -1;
     100                 :          0 :                 return 5000 + 5 * channel;
     101                 :            :         }
     102                 :       2269 :         return -1;
     103                 :            : }
     104                 :            : 
     105                 :            : 
     106                 :            : /**
     107                 :            :  * p2p_freq_to_channel - Convert frequency into channel info
     108                 :            :  * @op_class: Buffer for returning operating class
     109                 :            :  * @channel: Buffer for returning channel number
     110                 :            :  * Returns: 0 on success, -1 if the specified frequency is unknown
     111                 :            :  */
     112                 :         72 : int p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel)
     113                 :            : {
     114                 :            :         /* TODO: more operating classes */
     115 [ +  - ][ +  - ]:         72 :         if (freq >= 2412 && freq <= 2472) {
     116         [ -  + ]:         72 :                 if ((freq - 2407) % 5)
     117                 :          0 :                         return -1;
     118                 :            : 
     119                 :         72 :                 *op_class = 81; /* 2.407 GHz, channels 1..13 */
     120                 :         72 :                 *channel = (freq - 2407) / 5;
     121                 :         72 :                 return 0;
     122                 :            :         }
     123                 :            : 
     124         [ #  # ]:          0 :         if (freq == 2484) {
     125                 :          0 :                 *op_class = 82; /* channel 14 */
     126                 :          0 :                 *channel = 14;
     127                 :          0 :                 return 0;
     128                 :            :         }
     129                 :            : 
     130 [ #  # ][ #  # ]:          0 :         if (freq >= 5180 && freq <= 5240) {
     131         [ #  # ]:          0 :                 if ((freq - 5000) % 5)
     132                 :          0 :                         return -1;
     133                 :            : 
     134                 :          0 :                 *op_class = 115; /* 5 GHz, channels 36..48 */
     135                 :          0 :                 *channel = (freq - 5000) / 5;
     136                 :          0 :                 return 0;
     137                 :            :         }
     138                 :            : 
     139 [ #  # ][ #  # ]:          0 :         if (freq >= 5745 && freq <= 5805) {
     140         [ #  # ]:          0 :                 if ((freq - 5000) % 5)
     141                 :          0 :                         return -1;
     142                 :            : 
     143                 :          0 :                 *op_class = 124; /* 5 GHz, channels 149..161 */
     144                 :          0 :                 *channel = (freq - 5000) / 5;
     145                 :          0 :                 return 0;
     146                 :            :         }
     147                 :            : 
     148                 :         72 :         return -1;
     149                 :            : }
     150                 :            : 
     151                 :            : 
     152                 :        281 : static void p2p_reg_class_intersect(const struct p2p_reg_class *a,
     153                 :            :                                     const struct p2p_reg_class *b,
     154                 :            :                                     struct p2p_reg_class *res)
     155                 :            : {
     156                 :            :         size_t i, j;
     157                 :            : 
     158                 :        281 :         res->reg_class = a->reg_class;
     159                 :            : 
     160         [ +  + ]:       2872 :         for (i = 0; i < a->channels; i++) {
     161         [ +  + ]:      27652 :                 for (j = 0; j < b->channels; j++) {
     162         [ +  + ]:      25061 :                         if (a->channel[i] != b->channel[j])
     163                 :      22791 :                                 continue;
     164                 :       2270 :                         res->channel[res->channels] = a->channel[i];
     165                 :       2270 :                         res->channels++;
     166         [ -  + ]:       2270 :                         if (res->channels == P2P_MAX_REG_CLASS_CHANNELS)
     167                 :        281 :                                 return;
     168                 :            :                 }
     169                 :            :         }
     170                 :            : }
     171                 :            : 
     172                 :            : 
     173                 :            : /**
     174                 :            :  * p2p_channels_intersect - Intersection of supported channel lists
     175                 :            :  * @a: First set of supported channels
     176                 :            :  * @b: Second set of supported channels
     177                 :            :  * @res: Data structure for returning the intersection of support channels
     178                 :            :  *
     179                 :            :  * This function can be used to find a common set of supported channels. Both
     180                 :            :  * input channels sets are assumed to use the same country code. If different
     181                 :            :  * country codes are used, the regulatory class numbers may not be matched
     182                 :            :  * correctly and results are undefined.
     183                 :            :  */
     184                 :        282 : void p2p_channels_intersect(const struct p2p_channels *a,
     185                 :            :                             const struct p2p_channels *b,
     186                 :            :                             struct p2p_channels *res)
     187                 :            : {
     188                 :            :         size_t i, j;
     189                 :            : 
     190                 :        282 :         os_memset(res, 0, sizeof(*res));
     191                 :            : 
     192         [ +  + ]:        623 :         for (i = 0; i < a->reg_classes; i++) {
     193                 :        341 :                 const struct p2p_reg_class *a_reg = &a->reg_class[i];
     194         [ +  + ]:        742 :                 for (j = 0; j < b->reg_classes; j++) {
     195                 :        401 :                         const struct p2p_reg_class *b_reg = &b->reg_class[j];
     196         [ +  + ]:        401 :                         if (a_reg->reg_class != b_reg->reg_class)
     197                 :        120 :                                 continue;
     198                 :        281 :                         p2p_reg_class_intersect(
     199                 :            :                                 a_reg, b_reg,
     200                 :        281 :                                 &res->reg_class[res->reg_classes]);
     201         [ +  + ]:        281 :                         if (res->reg_class[res->reg_classes].channels) {
     202                 :        280 :                                 res->reg_classes++;
     203         [ -  + ]:        280 :                                 if (res->reg_classes == P2P_MAX_REG_CLASSES)
     204                 :        282 :                                         return;
     205                 :            :                         }
     206                 :            :                 }
     207                 :            :         }
     208                 :            : }
     209                 :            : 
     210                 :            : 
     211                 :          5 : static void p2p_op_class_union(struct p2p_reg_class *cl,
     212                 :            :                                const struct p2p_reg_class *b_cl)
     213                 :            : {
     214                 :            :         size_t i, j;
     215                 :            : 
     216         [ +  + ]:         15 :         for (i = 0; i < b_cl->channels; i++) {
     217         [ +  + ]:        125 :                 for (j = 0; j < cl->channels; j++) {
     218         [ -  + ]:        115 :                         if (b_cl->channel[i] == cl->channel[j])
     219                 :          0 :                                 break;
     220                 :            :                 }
     221         [ +  - ]:         10 :                 if (j == cl->channels) {
     222         [ -  + ]:         10 :                         if (cl->channels == P2P_MAX_REG_CLASS_CHANNELS)
     223                 :          5 :                                 return;
     224                 :         10 :                         cl->channel[cl->channels++] = b_cl->channel[i];
     225                 :            :                 }
     226                 :            :         }
     227                 :            : }
     228                 :            : 
     229                 :            : 
     230                 :            : /**
     231                 :            :  * p2p_channels_union - Union of channel lists
     232                 :            :  * @a: First set of channels
     233                 :            :  * @b: Second set of channels
     234                 :            :  * @res: Data structure for returning the union of channels
     235                 :            :  */
     236                 :         35 : void p2p_channels_union(const struct p2p_channels *a,
     237                 :            :                         const struct p2p_channels *b,
     238                 :            :                         struct p2p_channels *res)
     239                 :            : {
     240                 :            :         size_t i, j;
     241                 :            : 
     242         [ -  + ]:         35 :         if (a != res)
     243                 :          0 :                 os_memcpy(res, a, sizeof(*res));
     244                 :            : 
     245         [ +  + ]:         70 :         for (i = 0; i < res->reg_classes; i++) {
     246                 :         35 :                 struct p2p_reg_class *cl = &res->reg_class[i];
     247         [ +  + ]:         70 :                 for (j = 0; j < b->reg_classes; j++) {
     248                 :         35 :                         const struct p2p_reg_class *b_cl = &b->reg_class[j];
     249         [ +  + ]:         35 :                         if (cl->reg_class != b_cl->reg_class)
     250                 :         30 :                                 continue;
     251                 :          5 :                         p2p_op_class_union(cl, b_cl);
     252                 :            :                 }
     253                 :            :         }
     254                 :            : 
     255         [ +  + ]:         70 :         for (j = 0; j < b->reg_classes; j++) {
     256                 :         35 :                 const struct p2p_reg_class *b_cl = &b->reg_class[j];
     257                 :            : 
     258         [ +  + ]:        140 :                 for (i = 0; i < res->reg_classes; i++) {
     259                 :        110 :                         struct p2p_reg_class *cl = &res->reg_class[i];
     260         [ +  + ]:        110 :                         if (cl->reg_class == b_cl->reg_class)
     261                 :          5 :                                 break;
     262                 :            :                 }
     263                 :            : 
     264         [ +  + ]:         35 :                 if (i == res->reg_classes) {
     265         [ -  + ]:         30 :                         if (res->reg_classes == P2P_MAX_REG_CLASSES)
     266                 :         35 :                                 return;
     267                 :         30 :                         os_memcpy(&res->reg_class[res->reg_classes++],
     268                 :            :                                   b_cl, sizeof(struct p2p_reg_class));
     269                 :            :                 }
     270                 :            :         }
     271                 :            : }
     272                 :            : 
     273                 :            : 
     274                 :        105 : void p2p_channels_remove_freqs(struct p2p_channels *chan,
     275                 :            :                                const struct wpa_freq_range_list *list)
     276                 :            : {
     277                 :            :         size_t o, c;
     278                 :            : 
     279         [ -  + ]:        105 :         if (list == NULL)
     280                 :        105 :                 return;
     281                 :            : 
     282                 :        105 :         o = 0;
     283         [ +  + ]:        210 :         while (o < chan->reg_classes) {
     284                 :        105 :                 struct p2p_reg_class *op = &chan->reg_class[o];
     285                 :            : 
     286                 :        105 :                 c = 0;
     287         [ +  + ]:        990 :                 while (c < op->channels) {
     288                 :        885 :                         int freq = p2p_channel_to_freq(op->reg_class,
     289                 :        885 :                                                        op->channel[c]);
     290 [ +  - ][ +  + ]:        885 :                         if (freq > 0 && freq_range_list_includes(list, freq)) {
     291                 :         12 :                                 op->channels--;
     292                 :         12 :                                 os_memmove(&op->channel[c],
     293                 :            :                                            &op->channel[c + 1],
     294                 :            :                                            op->channels - c);
     295                 :            :                         } else
     296                 :        873 :                                 c++;
     297                 :            :                 }
     298                 :            : 
     299         [ +  + ]:        105 :                 if (op->channels == 0) {
     300                 :          2 :                         chan->reg_classes--;
     301                 :          2 :                         os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1],
     302                 :            :                                    (chan->reg_classes - o) *
     303                 :            :                                    sizeof(struct p2p_reg_class));
     304                 :            :                 } else
     305                 :        103 :                         o++;
     306                 :            :         }
     307                 :            : }
     308                 :            : 
     309                 :            : 
     310                 :            : /**
     311                 :            :  * p2p_channels_includes - Check whether a channel is included in the list
     312                 :            :  * @channels: List of supported channels
     313                 :            :  * @reg_class: Regulatory class of the channel to search
     314                 :            :  * @channel: Channel number of the channel to search
     315                 :            :  * Returns: 1 if channel was found or 0 if not
     316                 :            :  */
     317                 :        163 : int p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class,
     318                 :            :                           u8 channel)
     319                 :            : {
     320                 :            :         size_t i, j;
     321         [ +  + ]:        168 :         for (i = 0; i < channels->reg_classes; i++) {
     322                 :        163 :                 const struct p2p_reg_class *reg = &channels->reg_class[i];
     323         [ -  + ]:        163 :                 if (reg->reg_class != reg_class)
     324                 :          0 :                         continue;
     325         [ +  + ]:        529 :                 for (j = 0; j < reg->channels; j++) {
     326         [ +  + ]:        524 :                         if (reg->channel[j] == channel)
     327                 :        158 :                                 return 1;
     328                 :            :                 }
     329                 :            :         }
     330                 :        163 :         return 0;
     331                 :            : }
     332                 :            : 
     333                 :            : 
     334                 :          6 : int p2p_channels_includes_freq(const struct p2p_channels *channels,
     335                 :            :                                unsigned int freq)
     336                 :            : {
     337                 :            :         size_t i, j;
     338         [ +  - ]:          6 :         for (i = 0; i < channels->reg_classes; i++) {
     339                 :          6 :                 const struct p2p_reg_class *reg = &channels->reg_class[i];
     340         [ +  - ]:         26 :                 for (j = 0; j < reg->channels; j++) {
     341         [ +  + ]:         26 :                         if (p2p_channel_to_freq(reg->reg_class,
     342                 :         52 :                                                 reg->channel[j]) == (int) freq)
     343                 :          6 :                                 return 1;
     344                 :            :                 }
     345                 :            :         }
     346                 :          6 :         return 0;
     347                 :            : }
     348                 :            : 
     349                 :            : 
     350                 :         13 : int p2p_supported_freq(struct p2p_data *p2p, unsigned int freq)
     351                 :            : {
     352                 :            :         u8 op_reg_class, op_channel;
     353         [ -  + ]:         13 :         if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0)
     354                 :          0 :                 return 0;
     355                 :         13 :         return p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
     356                 :            :                                      op_channel);
     357                 :            : }
     358                 :            : 
     359                 :            : 
     360                 :         29 : int p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq)
     361                 :            : {
     362                 :            :         u8 op_reg_class, op_channel;
     363         [ -  + ]:         29 :         if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0)
     364                 :          0 :                 return 0;
     365         [ +  - ]:         58 :         return p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
     366         [ +  - ]:         29 :                                      op_channel) &&
     367                 :         29 :                 !freq_range_list_includes(&p2p->no_go_freq, freq);
     368                 :            : }
     369                 :            : 
     370                 :            : 
     371                 :          9 : int p2p_supported_freq_cli(struct p2p_data *p2p, unsigned int freq)
     372                 :            : {
     373                 :            :         u8 op_reg_class, op_channel;
     374         [ -  + ]:          9 :         if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0)
     375                 :          0 :                 return 0;
     376         [ -  + ]:          9 :         return p2p_channels_includes(&p2p->cfg->channels, op_reg_class,
     377         [ #  # ]:          0 :                                      op_channel) ||
     378                 :          0 :                 p2p_channels_includes(&p2p->cfg->cli_channels, op_reg_class,
     379                 :            :                                       op_channel);
     380                 :            : }
     381                 :            : 
     382                 :            : 
     383                 :          9 : unsigned int p2p_get_pref_freq(struct p2p_data *p2p,
     384                 :            :                                const struct p2p_channels *channels)
     385                 :            : {
     386                 :            :         unsigned int i;
     387                 :          9 :         int freq = 0;
     388                 :            : 
     389         [ +  - ]:          9 :         if (channels == NULL) {
     390         [ -  + ]:          9 :                 if (p2p->cfg->num_pref_chan) {
     391                 :          0 :                         freq = p2p_channel_to_freq(
     392                 :          0 :                                 p2p->cfg->pref_chan[0].op_class,
     393                 :          0 :                                 p2p->cfg->pref_chan[0].chan);
     394         [ #  # ]:          0 :                         if (freq < 0)
     395                 :          0 :                                 freq = 0;
     396                 :            :                 }
     397                 :          9 :                 return freq;
     398                 :            :         }
     399                 :            : 
     400 [ #  # ][ #  # ]:          0 :         for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) {
     401                 :          0 :                 freq = p2p_channel_to_freq(p2p->cfg->pref_chan[i].op_class,
     402                 :          0 :                                            p2p->cfg->pref_chan[i].chan);
     403         [ #  # ]:          0 :                 if (p2p_channels_includes_freq(channels, freq))
     404                 :          0 :                         return freq;
     405                 :            :         }
     406                 :            : 
     407                 :          9 :         return 0;
     408                 :            : }
     409                 :            : 
     410                 :            : 
     411                 :       2199 : void p2p_channels_dump(struct p2p_data *p2p, const char *title,
     412                 :            :                        const struct p2p_channels *chan)
     413                 :            : {
     414                 :            :         char buf[500], *pos, *end;
     415                 :            :         size_t i, j;
     416                 :            :         int ret;
     417                 :            : 
     418                 :       2199 :         pos = buf;
     419                 :       2199 :         end = pos + sizeof(buf);
     420                 :            : 
     421         [ +  + ]:       3739 :         for (i = 0; i < chan->reg_classes; i++) {
     422                 :            :                 const struct p2p_reg_class *c;
     423                 :       1540 :                 c = &chan->reg_class[i];
     424                 :       1540 :                 ret = os_snprintf(pos, end - pos, " %u:", c->reg_class);
     425 [ +  - ][ +  - ]:       1540 :                 if (ret < 0 || ret >= end - pos)
     426                 :            :                         break;
     427                 :       1540 :                 pos += ret;
     428                 :            : 
     429         [ +  + ]:      15764 :                 for (j = 0; j < c->channels; j++) {
     430         [ +  + ]:      14224 :                         ret = os_snprintf(pos, end - pos, "%s%u",
     431                 :            :                                           j == 0 ? "" : ",",
     432                 :      14224 :                                           c->channel[j]);
     433 [ +  - ][ +  - ]:      14224 :                         if (ret < 0 || ret >= end - pos)
     434                 :            :                                 break;
     435                 :      14224 :                         pos += ret;
     436                 :            :                 }
     437                 :            :         }
     438                 :       2199 :         *pos = '\0';
     439                 :            : 
     440                 :       2199 :         p2p_dbg(p2p, "%s:%s", title, buf);
     441                 :       2199 : }
     442                 :            : 
     443                 :            : 
     444                 :        291 : int p2p_channel_select(struct p2p_channels *chans, const int *classes,
     445                 :            :                        u8 *op_class, u8 *op_channel)
     446                 :            : {
     447                 :            :         unsigned int i, j, r;
     448                 :            : 
     449         [ +  + ]:        970 :         for (j = 0; classes[j]; j++) {
     450         [ +  + ]:       1358 :                 for (i = 0; i < chans->reg_classes; i++) {
     451                 :        679 :                         struct p2p_reg_class *c = &chans->reg_class[i];
     452                 :            : 
     453         [ -  + ]:        679 :                         if (c->channels == 0)
     454                 :          0 :                                 continue;
     455                 :            : 
     456         [ -  + ]:        679 :                         if (c->reg_class == classes[j]) {
     457                 :            :                                 /*
     458                 :            :                                  * Pick one of the available channels in the
     459                 :            :                                  * operating class at random.
     460                 :            :                                  */
     461                 :          0 :                                 os_get_random((u8 *) &r, sizeof(r));
     462                 :          0 :                                 r %= c->channels;
     463                 :          0 :                                 *op_class = c->reg_class;
     464                 :          0 :                                 *op_channel = c->channel[r];
     465                 :          0 :                                 return 0;
     466                 :            :                         }
     467                 :            :                 }
     468                 :            :         }
     469                 :            : 
     470                 :        291 :         return -1;
     471                 :            : }

Generated by: LCOV version 1.9