18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P - generic helper functions 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_random - Generate random string for SSID and passphrase 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning the result 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Number of octets to write to the buffer 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function generates a random string using the following character set: 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 'A'-'Z', 'a'-'z', '0'-'9'. 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_random(char *buf, size_t len) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 val; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 letters = 'Z' - 'A' + 1; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 numbers = 10; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random((unsigned char *) buf, len)) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Character set: 'A'-'Z', 'a'-'z', '0'-'9' */ 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = buf[i]; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val %= 2 * letters + numbers; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (val < letters) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = 'A' + val; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (val < 2 * letters) 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = 'a' + (val - letters); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = '0' + (val - 2 * letters); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 494b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt/** 504b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * p2p_channel_to_freq - Convert channel info to frequency 514b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @op_class: Operating class 524b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @channel: Channel number 534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * Returns: Frequency in MHz or -1 if the specified channel is unknown 544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt */ 554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtint p2p_channel_to_freq(int op_class, int channel) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */ 584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt /* TODO: more operating classes */ 594b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt switch (op_class) { 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 81: 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* channels 1..13 */ 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 1 || channel > 13) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2407 + 5 * channel; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 82: 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* channel 14 */ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel != 14) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2414 + 5 * channel; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 83: /* channels 1..9; 40 MHz */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 84: /* channels 5..13; 40 MHz */ 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 1 || channel > 13) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2407 + 5 * channel; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 115: /* channels 36,40,44,48; indoor only */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 118: /* channels 52,56,60,64; dfs */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 36 || channel > 64) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 5000 + 5 * channel; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 124: /* channels 149,153,157,161 */ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 125: /* channels 149,153,157,161,165,169 */ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 149 || channel > 161) 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 5000 + 5 * channel; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 116: /* channels 36,44; 40 MHz; indoor only */ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 117: /* channels 40,48; 40 MHz; indoor only */ 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 119: /* channels 52,60; 40 MHz; dfs */ 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 120: /* channels 56,64; 40 MHz; dfs */ 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 36 || channel > 64) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 5000 + 5 * channel; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 126: /* channels 149,157; 40 MHz */ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 127: /* channels 153,161; 40 MHz */ 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (channel < 149 || channel > 161) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 5000 + 5 * channel; 9768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 9868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (channel < 36 || channel > 161) 9968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return -1; 10068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 5000 + 5 * channel; 10176cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt case 180: /* 60 GHz band, channels 1..4 */ 10276cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt if (channel < 1 || channel > 4) 10376cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt return -1; 10476cd2cc44b62e858f1897ce58f4ce7d0174e8839Dmitry Shmidt return 56160 + 2160 * channel; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_freq_to_channel - Convert frequency into channel info 1124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @op_class: Buffer for returning operating class 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Buffer for returning channel number 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 if the specified frequency is unknown 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1164b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtint p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: more operating classes */ 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2472) { 120b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 2407) % 5) 121b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 122b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1234b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 81; /* 2.407 GHz, channels 1..13 */ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 2407) / 5; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2484) { 1294b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 82; /* channel 14 */ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = 14; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 5180 && freq <= 5240) { 135b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 5000) % 5) 136b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 137b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1384b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 115; /* 5 GHz, channels 36..48 */ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 5000) / 5; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 5745 && freq <= 5805) { 144b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 5000) % 5) 145b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 146b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1474b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 124; /* 5 GHz, channels 149..161 */ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 5000) / 5; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 152661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (freq >= 58320 && freq <= 64800) { 153661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if ((freq - 58320) % 2160) 154661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 155661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 156661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *op_class = 180; /* 60 GHz, channels 1..4 */ 157661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *channel = (freq - 56160) / 2160; 158661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return 0; 159661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 160661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_reg_class_intersect(const struct p2p_reg_class *a, 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b, 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *res) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_class = a->reg_class; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->channels; i++) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->channels; j++) { 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->channel[i] != b->channel[j]) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channel[res->channels] = a->channel[i]; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channels++; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->channels == P2P_MAX_REG_CLASS_CHANNELS) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_intersect - Intersection of supported channel lists 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @a: First set of supported channels 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @b: Second set of supported channels 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Data structure for returning the intersection of support channels 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to find a common set of supported channels. Both 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input channels sets are assumed to use the same country code. If different 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * country codes are used, the regulatory class numbers may not be matched 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correctly and results are undefined. 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_channels_intersect(const struct p2p_channels *a, 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_channels *b, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *res) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(res, 0, sizeof(*res)); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->reg_classes; i++) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *a_reg = &a->reg_class[i]; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b_reg = &b->reg_class[j]; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a_reg->reg_class != b_reg->reg_class) 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_reg_class_intersect( 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a_reg, b_reg, 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &res->reg_class[res->reg_classes]); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_class[res->reg_classes].channels) { 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_classes++; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic void p2p_op_class_union(struct p2p_reg_class *cl, 22568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl) 22668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 22768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 22868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 22968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < b_cl->channels; i++) { 23068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < cl->channels; j++) { 23168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (b_cl->channel[i] == cl->channel[j]) 23268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 23368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 23468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (j == cl->channels) { 23568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->channels == P2P_MAX_REG_CLASS_CHANNELS) 23668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 23768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cl->channel[cl->channels++] = b_cl->channel[i]; 23868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 23968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 24068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 24168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt/** 24468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * p2p_channels_union - Union of channel lists 24568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @a: First set of channels 24668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @b: Second set of channels 24768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @res: Data structure for returning the union of channels 24868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 24968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_union(const struct p2p_channels *a, 25068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *b, 25168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *res) 25268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 25368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 25468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 25568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (a != res) 25668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(res, a, sizeof(*res)); 25768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 25868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 25968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 26068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 26168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 26268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class != b_cl->reg_class) 26368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt continue; 26468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_op_class_union(cl, b_cl); 26568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 26668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 26768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 26868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 26968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 27068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 27268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 27368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class == b_cl->reg_class) 27468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 27568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 27668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == res->reg_classes) { 27868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 27968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 28068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&res->reg_class[res->reg_classes++], 28168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt b_cl, sizeof(struct p2p_reg_class)); 28268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 28368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 28468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 28568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_remove_freqs(struct p2p_channels *chan, 28868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 28968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 29068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t o, c; 29168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL) 29368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 29468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o = 0; 29668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (o < chan->reg_classes) { 29768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *op = &chan->reg_class[o]; 29868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c = 0; 30068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (c < op->channels) { 30168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq = p2p_channel_to_freq(op->reg_class, 30268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channel[c]); 30368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (freq > 0 && freq_range_list_includes(list, freq)) { 30468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels--; 30568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&op->channel[c], 30668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &op->channel[c + 1], 30768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels - c); 30868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 30968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c++; 31068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 31168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 31268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (op->channels == 0) { 31368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt chan->reg_classes--; 31468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1], 31568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (chan->reg_classes - o) * 31668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_reg_class)); 31768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 31868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o++; 31968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 32068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 32168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 32268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_includes - Check whether a channel is included in the list 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channels: List of supported channels 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reg_class: Regulatory class of the channel to search 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Channel number of the channel to search 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if channel was found or 0 if not 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class, 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel) 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->reg_class != reg_class) 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->channel[j] == channel) 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3477a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_channels_includes_freq(const struct p2p_channels *channels, 3487a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int freq) 3497a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 3507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt size_t i, j; 3517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg->reg_class, 3554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt reg->channel[j]) == (int) freq) 3567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 1; 3577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3587a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3597a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 0; 3607a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 3617a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3627a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_supported_freq(struct p2p_data *p2p, unsigned int freq) 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 3664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 37144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 37244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 37368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq) 37468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 37568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 37668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 37768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 37868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 37968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) && 38068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt !freq_range_list_includes(&p2p->no_go_freq, freq); 38168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 38268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_cli(struct p2p_data *p2p, unsigned int freq) 38568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 38668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 38768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 38868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 38968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 39068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) || 39168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_includes(&p2p->cfg->cli_channels, op_reg_class, 39268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel); 39368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 39468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 39568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 39644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidtunsigned int p2p_get_pref_freq(struct p2p_data *p2p, 39744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt const struct p2p_channels *channels) 39844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt{ 39944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt unsigned int i; 40043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int freq = 0; 40143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const struct p2p_channels *tmpc = channels ? 40243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channels : &p2p->cfg->channels; 40343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 40443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (tmpc == NULL) 40543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 40644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 40744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) { 40844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->pref_chan[i].op_class, 40944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[i].chan); 41043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p_channels_includes_freq(tmpc, freq)) 41144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return freq; 41244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 41344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return 0; 41444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt} 4154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtvoid p2p_channels_dump(struct p2p_data *p2p, const char *title, 4184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_channels *chan) 4194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 4204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char buf[500], *pos, *end; 4214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t i, j; 4224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int ret; 4234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 4254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = pos + sizeof(buf); 4264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < chan->reg_classes; i++) { 4284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_reg_class *c; 4294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c = &chan->reg_class[i]; 4304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, " %u:", c->reg_class); 4314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (j = 0; j < c->channels; j++) { 4364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, "%s%u", 4374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt j == 0 ? "" : ",", 4384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c->channel[j]); 4394ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4404ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4424ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4444ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt *pos = '\0'; 4454ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt p2p_dbg(p2p, "%s:%s", title, buf); 4474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 448e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 449e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 450d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtstatic u8 p2p_channel_pick_random(const u8 *channels, unsigned int num_channels) 451d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 452d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int r; 453661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 454661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt r = 0; 455d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt r %= num_channels; 456d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return channels[r]; 457d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 458d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 459d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 460e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint p2p_channel_select(struct p2p_channels *chans, const int *classes, 461e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt u8 *op_class, u8 *op_channel) 462e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 463d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int i, j; 464e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 465d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt for (j = 0; classes == NULL || classes[j]; j++) { 466a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt for (i = 0; i < chans->reg_classes; i++) { 467a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt struct p2p_reg_class *c = &chans->reg_class[i]; 468e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 469a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (c->channels == 0) 470a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt continue; 471e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 472d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL || c->reg_class == classes[j]) { 473a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt /* 474a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * Pick one of the available channels in the 475a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * operating class at random. 476a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt */ 477a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt *op_class = c->reg_class; 478d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random( 479d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt c->channel, c->channels); 480a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt return 0; 481a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 482e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 483d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL) 484d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt break; 485e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 486e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 487e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 488e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 489d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 490d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 491d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtint p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class, 492d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt u8 *op_channel) 493d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 494661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt u8 chan[4]; 495d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int num_channels = 0; 496d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 497d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Try to find available social channels from 2.4 GHz */ 498d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 1)) 499d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 1; 500d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 6)) 501d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 6; 502d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 11)) 503d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 11; 504d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 505661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Try to find available social channels from 60 GHz */ 506661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p_channels_includes(chans, 180, 2)) 507661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt chan[num_channels++] = 2; 508661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 509d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (num_channels == 0) 510d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return -1; 511d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 512d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random(chan, num_channels); 513661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (*op_channel == 2) 514661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *op_class = 180; 515661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt else 516661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *op_class = 81; 517d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 518d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return 0; 519d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 520