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" 12d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "common/defs.h" 13fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include "common/ieee802_11_common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_random - Generate random string for SSID and passphrase 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning the result 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Number of octets to write to the buffer 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function generates a random string using the following character set: 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 'A'-'Z', 'a'-'z', '0'-'9'. 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_random(char *buf, size_t len) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 val; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 letters = 'Z' - 'A' + 1; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 numbers = 10; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random((unsigned char *) buf, len)) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Character set: 'A'-'Z', 'a'-'z', '0'-'9' */ 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = buf[i]; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val %= 2 * letters + numbers; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (val < letters) 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = 'A' + val; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (val < 2 * letters) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = 'a' + (val - letters); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = '0' + (val - 2 * letters); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 514b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt/** 524b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * p2p_channel_to_freq - Convert channel info to frequency 534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @op_class: Operating class 544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @channel: Channel number 554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * Returns: Frequency in MHz or -1 if the specified channel is unknown 564b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt */ 574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtint p2p_channel_to_freq(int op_class, int channel) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 59fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt return ieee80211_chan_to_freq(NULL, op_class, channel); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_freq_to_channel - Convert frequency into channel info 654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * @op_class: Buffer for returning operating class 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Buffer for returning channel number 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 if the specified frequency is unknown 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtint p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 71d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ieee80211_freq_to_channel_ext(freq, 0, 0, op_class, channel) == 72d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt NUM_HOSTAPD_MODES) 73d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 74661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 75d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_reg_class_intersect(const struct p2p_reg_class *a, 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b, 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_reg_class *res) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_class = a->reg_class; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->channels; i++) { 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->channels; j++) { 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->channel[i] != b->channel[j]) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channel[res->channels] = a->channel[i]; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->channels++; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->channels == P2P_MAX_REG_CLASS_CHANNELS) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_intersect - Intersection of supported channel lists 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @a: First set of supported channels 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @b: Second set of supported channels 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Data structure for returning the intersection of support channels 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to find a common set of supported channels. Both 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input channels sets are assumed to use the same country code. If different 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * country codes are used, the regulatory class numbers may not be matched 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * correctly and results are undefined. 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_channels_intersect(const struct p2p_channels *a, 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_channels *b, 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_channels *res) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(res, 0, sizeof(*res)); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < a->reg_classes; i++) { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *a_reg = &a->reg_class[i]; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *b_reg = &b->reg_class[j]; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a_reg->reg_class != b_reg->reg_class) 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_reg_class_intersect( 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a_reg, b_reg, 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &res->reg_class[res->reg_classes]); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_class[res->reg_classes].channels) { 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res->reg_classes++; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic void p2p_op_class_union(struct p2p_reg_class *cl, 13968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl) 14068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 14168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 14268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 14368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < b_cl->channels; i++) { 14468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < cl->channels; j++) { 14568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (b_cl->channel[i] == cl->channel[j]) 14668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 14768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 14868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (j == cl->channels) { 14968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->channels == P2P_MAX_REG_CLASS_CHANNELS) 15068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 15168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt cl->channel[cl->channels++] = b_cl->channel[i]; 15268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 15368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 15468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 15568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 15668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 15768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt/** 158fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * p2p_channels_union_inplace - Inplace union of channel lists 159fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * @res: Input data and place for returning union of the channel sets 16068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * @b: Second set of channels 16168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 162fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtvoid p2p_channels_union_inplace(struct p2p_channels *res, 163fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt const struct p2p_channels *b) 16468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 16568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t i, j; 16668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 16768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 16868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 16968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 17068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 17168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class != b_cl->reg_class) 17268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt continue; 17368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_op_class_union(cl, b_cl); 17468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 17568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 17668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 17768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (j = 0; j < b->reg_classes; j++) { 17868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct p2p_reg_class *b_cl = &b->reg_class[j]; 17968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 18068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < res->reg_classes; i++) { 18168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *cl = &res->reg_class[i]; 18268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (cl->reg_class == b_cl->reg_class) 18368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 18468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 18568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 18668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (i == res->reg_classes) { 18768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (res->reg_classes == P2P_MAX_REG_CLASSES) 18868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 18968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memcpy(&res->reg_class[res->reg_classes++], 19068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt b_cl, sizeof(struct p2p_reg_class)); 19168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 19268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 19368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 19468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 19568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 196fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt/** 197fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * p2p_channels_union - Union of channel lists 198fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * @a: First set of channels 199fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * @b: Second set of channels 200fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * @res: Data structure for returning the union of channels 201fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt */ 202fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtvoid p2p_channels_union(const struct p2p_channels *a, 203fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt const struct p2p_channels *b, 204fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt struct p2p_channels *res) 205fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{ 206fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt os_memcpy(res, a, sizeof(*res)); 207fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt p2p_channels_union_inplace(res, b); 208fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt} 209fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 210fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 21168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtvoid p2p_channels_remove_freqs(struct p2p_channels *chan, 21268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt const struct wpa_freq_range_list *list) 21368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 21468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt size_t o, c; 21568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 21668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (list == NULL) 21768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return; 21868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 21968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o = 0; 22068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (o < chan->reg_classes) { 22168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt struct p2p_reg_class *op = &chan->reg_class[o]; 22268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 22368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c = 0; 22468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (c < op->channels) { 22568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int freq = p2p_channel_to_freq(op->reg_class, 22668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channel[c]); 22768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (freq > 0 && freq_range_list_includes(list, freq)) { 22868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels--; 22968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&op->channel[c], 23068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt &op->channel[c + 1], 23168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op->channels - c); 23268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 23368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt c++; 23468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 23568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 23668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (op->channels == 0) { 23768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt chan->reg_classes--; 23868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1], 23968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt (chan->reg_classes - o) * 24068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt sizeof(struct p2p_reg_class)); 24168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } else 24268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt o++; 24368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 24468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 24568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 24668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_channels_includes - Check whether a channel is included in the list 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channels: List of supported channels 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reg_class: Regulatory class of the channel to search 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @channel: Channel number of the channel to search 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if channel was found or 0 if not 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class, 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 channel) 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, j; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->reg_class != reg_class) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reg->channel[j] == channel) 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2717a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidtint p2p_channels_includes_freq(const struct p2p_channels *channels, 2727a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt unsigned int freq) 2737a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt{ 2747a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt size_t i, j; 2757a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (i = 0; i < channels->reg_classes; i++) { 2767a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt const struct p2p_reg_class *reg = &channels->reg_class[i]; 2777a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt for (j = 0; j < reg->channels; j++) { 2784b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_channel_to_freq(reg->reg_class, 2794b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt reg->channel[j]) == (int) freq) 2807a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 1; 2817a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 2827a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt } 2837a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt return 0; 2847a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt} 2857a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 2867a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_supported_freq(struct p2p_data *p2p, unsigned int freq) 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 op_reg_class, op_channel; 2904b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt op_channel); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 29644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 29768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq) 29868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 29968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 30068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 30168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 30268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 30368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) && 30468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt !freq_range_list_includes(&p2p->no_go_freq, freq); 30568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 30668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 30768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 30868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint p2p_supported_freq_cli(struct p2p_data *p2p, unsigned int freq) 30968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 31068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt u8 op_reg_class, op_channel; 31168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) 31268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return 0; 31368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, 31468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel) || 31568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt p2p_channels_includes(&p2p->cfg->cli_channels, op_reg_class, 31668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt op_channel); 31768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 31868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 31968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 32044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidtunsigned int p2p_get_pref_freq(struct p2p_data *p2p, 32144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt const struct p2p_channels *channels) 32244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt{ 32344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt unsigned int i; 32443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt int freq = 0; 32543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt const struct p2p_channels *tmpc = channels ? 32643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt channels : &p2p->cfg->channels; 32743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt 32843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (tmpc == NULL) 32943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return 0; 33044c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt 33144c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) { 33244c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->pref_chan[i].op_class, 33344c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt p2p->cfg->pref_chan[i].chan); 33443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (p2p_channels_includes_freq(tmpc, freq)) 33544c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return freq; 33644c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt } 33744c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt return 0; 33844c957860ca714a86357591f39aff0bfa904c743Dmitry Shmidt} 3394ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3404ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtvoid p2p_channels_dump(struct p2p_data *p2p, const char *title, 3424ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_channels *chan) 3434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 3444ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char buf[500], *pos, *end; 3454ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t i, j; 3464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int ret; 3474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3484ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 3494ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = pos + sizeof(buf); 3504ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3514ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < chan->reg_classes; i++) { 3524ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const struct p2p_reg_class *c; 3534ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c = &chan->reg_class[i]; 3544ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, " %u:", c->reg_class); 355fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(end - pos, ret)) 3564ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 3574ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 3584ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3594ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (j = 0; j < c->channels; j++) { 3604ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt ret = os_snprintf(pos, end - pos, "%s%u", 3614ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt j == 0 ? "" : ",", 3624ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt c->channel[j]); 363fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(end - pos, ret)) 3644ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt break; 3654ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += ret; 3664ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 3674ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 3684ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt *pos = '\0'; 3694ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 3704ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt p2p_dbg(p2p, "%s:%s", title, buf); 3714ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 372e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 373e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 374d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtstatic u8 p2p_channel_pick_random(const u8 *channels, unsigned int num_channels) 375d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 376d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int r; 377661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random((u8 *) &r, sizeof(r)) < 0) 378661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt r = 0; 379d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt r %= num_channels; 380d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return channels[r]; 381d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 382d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 383d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 384e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint p2p_channel_select(struct p2p_channels *chans, const int *classes, 385e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt u8 *op_class, u8 *op_channel) 386e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 387d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int i, j; 388e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 389d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt for (j = 0; classes == NULL || classes[j]; j++) { 390a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt for (i = 0; i < chans->reg_classes; i++) { 391a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt struct p2p_reg_class *c = &chans->reg_class[i]; 392e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 393a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt if (c->channels == 0) 394a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt continue; 395e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 396d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL || c->reg_class == classes[j]) { 397a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt /* 398a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * Pick one of the available channels in the 399a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt * operating class at random. 400a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt */ 401a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt *op_class = c->reg_class; 402d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random( 403d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt c->channel, c->channels); 404a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt return 0; 405a0d265f81180f341d22511538fa18166e1bbce9fDmitry Shmidt } 406e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 407d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (classes == NULL) 408d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt break; 409e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 410e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 411e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 412e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 413d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 414d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 415d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidtint p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class, 416d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt u8 *op_channel) 417d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt{ 418661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt u8 chan[4]; 419d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt unsigned int num_channels = 0; 420d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 421d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt /* Try to find available social channels from 2.4 GHz */ 422d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 1)) 423d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 1; 424d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 6)) 425d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 6; 426d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (p2p_channels_includes(chans, 81, 11)) 427d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan[num_channels++] = 11; 428d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 429661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Try to find available social channels from 60 GHz */ 430661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (p2p_channels_includes(chans, 180, 2)) 431661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt chan[num_channels++] = 2; 432661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 433d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (num_channels == 0) 434d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return -1; 435d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 436d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt *op_channel = p2p_channel_pick_random(chan, num_channels); 437661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (*op_channel == 2) 438661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *op_class = 180; 439661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt else 440661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt *op_class = 81; 441d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 442d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt return 0; 443d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt} 444fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 445fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 446fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint p2p_channels_to_freqs(const struct p2p_channels *channels, int *freq_list, 447fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt unsigned int max_len) 448fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{ 449fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt unsigned int i, idx; 450fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 451fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (!channels || max_len == 0) 452fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt return 0; 453fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 454fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt for (i = 0, idx = 0; i < channels->reg_classes; i++) { 455fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt const struct p2p_reg_class *c = &channels->reg_class[i]; 456fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt unsigned int j; 457fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 458fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (idx + 1 == max_len) 459fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt break; 460fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt for (j = 0; j < c->channels; j++) { 461fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt int freq; 462d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int k; 463d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 464fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (idx + 1 == max_len) 465fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt break; 466fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt freq = p2p_channel_to_freq(c->reg_class, 467fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt c->channel[j]); 468fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (freq < 0) 469fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt continue; 470d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 471d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (k = 0; k < idx; k++) { 472d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (freq_list[k] == freq) 473d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (k < idx) 477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt continue; 478fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt freq_list[idx++] = freq; 479fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt } 480fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt } 481fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 482fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt freq_list[idx] = 0; 483fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt 484fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt return idx; 485fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt} 486