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 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_reg_class_intersect(const struct p2p_reg_class *a, 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b, 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *res) 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_class = a->reg_class; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->channels; i++) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->channels; j++) { 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->channel[i] != b->channel[j]) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channel[res->channels] = a->channel[i]; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channels++; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->channels == P2P_MAX_REG_CLASS_CHANNELS) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_intersect - Intersection of supported channel lists 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @a: First set of supported channels 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @b: Second set of supported channels 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Data structure for returning the intersection of support channels 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to find a common set of supported channels. Both 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input channels sets are assumed to use the same country code. If different 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * country codes are used, the regulatory class numbers may not be matched 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correctly and results are undefined. 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_channels_intersect(const struct p2p_channels *a, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_channels *b, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *res) 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(res, 0, sizeof(*res)); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->reg_classes; i++) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *a_reg = &a->reg_class[i]; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b_reg = &b->reg_class[j]; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a_reg->reg_class != b_reg->reg_class) 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_reg_class_intersect( 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a_reg, b_reg, 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &res->reg_class[res->reg_classes]); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_class[res->reg_classes].channels) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_classes++; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic void p2p_op_class_union(struct p2p_reg_class *cl, 21668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl) 21768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 21868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 21968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 22068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < b_cl->channels; i++) { 22168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < cl->channels; j++) { 22268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (b_cl->channel[i] == cl->channel[j]) 22368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 22468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 22568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (j == cl->channels) { 22668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->channels == P2P_MAX_REG_CLASS_CHANNELS) 22768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 22868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cl->channel[cl->channels++] = b_cl->channel[i]; 22968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 23068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 23168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 23268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 23368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 23468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt/** 23568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * p2p_channels_union - Union of channel lists 23668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @a: First set of channels 23768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @b: Second set of channels 23868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @res: Data structure for returning the union of channels 23968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 24068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_union(const struct p2p_channels *a, 24168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *b, 24268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *res) 24368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 24468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 24568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (a != res) 24768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(res, a, sizeof(*res)); 24868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 25068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 25168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 25268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 25368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class != b_cl->reg_class) 25468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt continue; 25568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_op_class_union(cl, b_cl); 25668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 25768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 25868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 25968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 26068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 26168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 26268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 26368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 26468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class == b_cl->reg_class) 26568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 26668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 26768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 26868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == res->reg_classes) { 26968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 27068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 27168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&res->reg_class[res->reg_classes++], 27268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt b_cl, sizeof(struct p2p_reg_class)); 27368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 27468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 27568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 27668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_remove_freqs(struct p2p_channels *chan, 27968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 28068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 28168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t o, c; 28268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL) 28468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 28568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o = 0; 28768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (o < chan->reg_classes) { 28868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *op = &chan->reg_class[o]; 28968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c = 0; 29168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (c < op->channels) { 29268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq = p2p_channel_to_freq(op->reg_class, 29368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channel[c]); 29468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (freq > 0 && freq_range_list_includes(list, freq)) { 29568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels--; 29668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&op->channel[c], 29768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &op->channel[c + 1], 29868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels - c); 29968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 30068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c++; 30168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 30268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 30368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (op->channels == 0) { 30468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt chan->reg_classes--; 30568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1], 30668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (chan->reg_classes - o) * 30768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_reg_class)); 30868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 30968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o++; 31068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 31168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 31268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 31368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_includes - Check whether a channel is included in the list 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channels: List of supported channels 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reg_class: Regulatory class of the channel to search 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Channel number of the channel to search 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if channel was found or 0 if not 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class, 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel) 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->reg_class != reg_class) 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->channel[j] == channel) 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_channels_includes_freq(const struct p2p_channels *channels, 3397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int freq) 3407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 3417a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt size_t i, j; 3427a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3437a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3454b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg->reg_class, 3464b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt reg->channel[j]) == (int) freq) 3477a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 1; 3487a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3497a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3507a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 0; 3517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 3527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_supported_freq(struct p2p_data *p2p, unsigned int freq) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 3574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 36244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 36344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 36468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq) 36568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 36668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 36768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 36868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 36968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 37068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) && 37168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt !freq_range_list_includes(&p2p->no_go_freq, freq); 37268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 37368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 37468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 37568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_cli(struct p2p_data *p2p, unsigned int freq) 37668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 37768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 37868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 37968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 38068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 38168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) || 38268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_includes(&p2p->cfg->cli_channels, op_reg_class, 38368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel); 38468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 38568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidtunsigned int p2p_get_pref_freq(struct p2p_data *p2p, 38844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt const struct p2p_channels *channels) 38944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt{ 39044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt unsigned int i; 39143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int freq = 0; 39243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const struct p2p_channels *tmpc = channels ? 39343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channels : &p2p->cfg->channels; 39443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 39543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (tmpc == NULL) 39643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 39744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 39844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) { 39944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->pref_chan[i].op_class, 40044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[i].chan); 40143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p_channels_includes_freq(tmpc, freq)) 40244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return freq; 40344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 40444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return 0; 40544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt} 4064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4074ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4084ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtvoid p2p_channels_dump(struct p2p_data *p2p, const char *title, 4094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_channels *chan) 4104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 4114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char buf[500], *pos, *end; 4124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t i, j; 4134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int ret; 4144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 4164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = pos + sizeof(buf); 4174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < chan->reg_classes; i++) { 4194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_reg_class *c; 4204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c = &chan->reg_class[i]; 4214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, " %u:", c->reg_class); 4224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (j = 0; j < c->channels; j++) { 4274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, "%s%u", 4284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt j == 0 ? "" : ",", 4294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c->channel[j]); 4304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt *pos = '\0'; 4364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt p2p_dbg(p2p, "%s:%s", title, buf); 4384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 439e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 440e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 441d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtstatic u8 p2p_channel_pick_random(const u8 *channels, unsigned int num_channels) 442d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 443d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int r; 444d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 445d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt r %= num_channels; 446d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return channels[r]; 447d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 448d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 449d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 450e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint p2p_channel_select(struct p2p_channels *chans, const int *classes, 451e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt u8 *op_class, u8 *op_channel) 452e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 453d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int i, j; 454e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 455d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt for (j = 0; classes == NULL || classes[j]; j++) { 456a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt for (i = 0; i < chans->reg_classes; i++) { 457a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt struct p2p_reg_class *c = &chans->reg_class[i]; 458e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 459a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (c->channels == 0) 460a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt continue; 461e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 462d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL || c->reg_class == classes[j]) { 463a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt /* 464a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * Pick one of the available channels in the 465a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * operating class at random. 466a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt */ 467a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt *op_class = c->reg_class; 468d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random( 469d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt c->channel, c->channels); 470a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt return 0; 471a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 472e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 473d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL) 474d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt break; 475e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 476e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 477e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 478e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 479d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 480d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 481d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtint p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class, 482d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt u8 *op_channel) 483d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 484d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt u8 chan[3]; 485d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int num_channels = 0; 486d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 487d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Try to find available social channels from 2.4 GHz */ 488d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 1)) 489d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 1; 490d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 6)) 491d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 6; 492d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 11)) 493d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 11; 494d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 495d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (num_channels == 0) 496d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return -1; 497d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 498d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_class = 81; 499d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random(chan, num_channels); 500d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 501d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return 0; 502d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 503