p2p_utils.c revision a0d265f81180f341d22511538fa18166e1bbce9f
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; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_freq_to_channel - Convert frequency into channel info 1084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @op_class: Buffer for returning operating class 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Buffer for returning channel number 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 if the specified frequency is unknown 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtint p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel) 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: more operating classes */ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 2412 && freq <= 2472) { 116b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 2407) % 5) 117b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 118b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1194b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 81; /* 2.407 GHz, channels 1..13 */ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 2407) / 5; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq == 2484) { 1254b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 82; /* channel 14 */ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = 14; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 5180 && freq <= 5240) { 131b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 5000) % 5) 132b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 133b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1344b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 115; /* 5 GHz, channels 36..48 */ 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 5000) / 5; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq >= 5745 && freq <= 5805) { 140b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if ((freq - 5000) % 5) 141b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return -1; 142b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 1434b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *op_class = 124; /* 5 GHz, channels 149..161 */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *channel = (freq - 5000) / 5; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_reg_class_intersect(const struct p2p_reg_class *a, 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *res) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_class = a->reg_class; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->channels; i++) { 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->channels; j++) { 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->channel[i] != b->channel[j]) 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channel[res->channels] = a->channel[i]; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channels++; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->channels == P2P_MAX_REG_CLASS_CHANNELS) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_intersect - Intersection of supported channel lists 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @a: First set of supported channels 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @b: Second set of supported channels 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Data structure for returning the intersection of support channels 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to find a common set of supported channels. Both 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input channels sets are assumed to use the same country code. If different 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * country codes are used, the regulatory class numbers may not be matched 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correctly and results are undefined. 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_channels_intersect(const struct p2p_channels *a, 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_channels *b, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *res) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(res, 0, sizeof(*res)); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->reg_classes; i++) { 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *a_reg = &a->reg_class[i]; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b_reg = &b->reg_class[j]; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a_reg->reg_class != b_reg->reg_class) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_reg_class_intersect( 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a_reg, b_reg, 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &res->reg_class[res->reg_classes]); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_class[res->reg_classes].channels) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_classes++; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic void p2p_op_class_union(struct p2p_reg_class *cl, 21268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl) 21368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 21468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 21568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 21668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < b_cl->channels; i++) { 21768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < cl->channels; j++) { 21868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (b_cl->channel[i] == cl->channel[j]) 21968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 22068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 22168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (j == cl->channels) { 22268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->channels == P2P_MAX_REG_CLASS_CHANNELS) 22368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 22468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cl->channel[cl->channels++] = b_cl->channel[i]; 22568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 22668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 22768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 22868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 22968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 23068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt/** 23168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * p2p_channels_union - Union of channel lists 23268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @a: First set of channels 23368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @b: Second set of channels 23468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @res: Data structure for returning the union of channels 23568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 23668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_union(const struct p2p_channels *a, 23768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_channels *b, 23868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_channels *res) 23968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 24068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 24168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (a != res) 24368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(res, a, sizeof(*res)); 24468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 24668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 24768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 24868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 24968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class != b_cl->reg_class) 25068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt continue; 25168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_op_class_union(cl, b_cl); 25268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 25368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 25468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 25568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 25668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 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 if (cl->reg_class == b_cl->reg_class) 26168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 26268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 26368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 26468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == res->reg_classes) { 26568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 26668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 26768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&res->reg_class[res->reg_classes++], 26868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt b_cl, sizeof(struct p2p_reg_class)); 26968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 27068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 27168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 27268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_remove_freqs(struct p2p_channels *chan, 27568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 27668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 27768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t o, c; 27868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 27968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL) 28068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 28168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o = 0; 28368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (o < chan->reg_classes) { 28468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *op = &chan->reg_class[o]; 28568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 28668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c = 0; 28768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (c < op->channels) { 28868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq = p2p_channel_to_freq(op->reg_class, 28968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channel[c]); 29068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (freq > 0 && freq_range_list_includes(list, freq)) { 29168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels--; 29268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&op->channel[c], 29368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &op->channel[c + 1], 29468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels - c); 29568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 29668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c++; 29768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 29868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 29968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (op->channels == 0) { 30068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt chan->reg_classes--; 30168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1], 30268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (chan->reg_classes - o) * 30368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_reg_class)); 30468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 30568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o++; 30668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 30768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 30868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 30968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_includes - Check whether a channel is included in the list 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channels: List of supported channels 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reg_class: Regulatory class of the channel to search 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Channel number of the channel to search 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if channel was found or 0 if not 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class, 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel) 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->reg_class != reg_class) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->channel[j] == channel) 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3347a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_channels_includes_freq(const struct p2p_channels *channels, 3357a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int freq) 3367a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 3377a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt size_t i, j; 3387a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 3397a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 3407a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 3414b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg->reg_class, 3424b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt reg->channel[j]) == (int) freq) 3437a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 1; 3447a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3457a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 3467a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 0; 3477a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 3487a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3497a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_supported_freq(struct p2p_data *p2p, unsigned int freq) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 3534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 35844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 35944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 36068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq) 36168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 36268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 36368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 36468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 36568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 36668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) && 36768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt !freq_range_list_includes(&p2p->no_go_freq, freq); 36868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 36968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 37068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 37168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_cli(struct p2p_data *p2p, unsigned int freq) 37268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 37368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 37468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 37568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 37668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 37768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) || 37868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_includes(&p2p->cfg->cli_channels, op_reg_class, 37968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel); 38068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 38168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 38344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidtunsigned int p2p_get_pref_freq(struct p2p_data *p2p, 38444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt const struct p2p_channels *channels) 38544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt{ 38644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt unsigned int i; 38744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt int freq = 0; 38844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 38944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (channels == NULL) { 39044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (p2p->cfg->num_pref_chan) { 39144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = p2p_channel_to_freq( 39244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[0].op_class, 39344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[0].chan); 39444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (freq < 0) 39544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = 0; 39644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 39744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return freq; 39844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 39944c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 40044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) { 40144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->pref_chan[i].op_class, 40244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[i].chan); 40344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt if (p2p_channels_includes_freq(channels, freq)) 40444c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return freq; 40544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 40644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 40744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return 0; 40844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt} 4094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtvoid p2p_channels_dump(struct p2p_data *p2p, const char *title, 4124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_channels *chan) 4134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 4144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char buf[500], *pos, *end; 4154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t i, j; 4164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int ret; 4174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 4194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = pos + sizeof(buf); 4204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < chan->reg_classes; i++) { 4224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_reg_class *c; 4234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c = &chan->reg_class[i]; 4244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, " %u:", c->reg_class); 4254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (j = 0; j < c->channels; j++) { 4304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, "%s%u", 4314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt j == 0 ? "" : ",", 4324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c->channel[j]); 4334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ret < 0 || ret >= end - pos) 4344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 4354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 4364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt *pos = '\0'; 4394ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4404ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt p2p_dbg(p2p, "%s:%s", title, buf); 4414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 442e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 443e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 444e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint p2p_channel_select(struct p2p_channels *chans, const int *classes, 445e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt u8 *op_class, u8 *op_channel) 446e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 447e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt unsigned int i, j, r; 448e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 449a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt for (j = 0; classes[j]; j++) { 450a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt for (i = 0; i < chans->reg_classes; i++) { 451a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt struct p2p_reg_class *c = &chans->reg_class[i]; 452e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 453a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (c->channels == 0) 454a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt continue; 455e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 456a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (c->reg_class == classes[j]) { 457a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt /* 458a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * Pick one of the available channels in the 459a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * operating class at random. 460a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt */ 461a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt os_get_random((u8 *) &r, sizeof(r)); 462a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt r %= c->channels; 463a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt *op_class = c->reg_class; 464a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt *op_channel = c->channel[r]; 465a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt return 0; 466a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 467e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 468e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 469e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 470e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 471e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 472