/* Note: ht40plus is only used for HT40 channel width, to distinguish between * HT40+ and HT40- */ bool channel_change(int idx, enum chan_width width, bool ht40plus) { unsigned int center1 = 0; if (width == CHAN_WIDTH_UNSPEC) width = channel_get_band_from_idx(idx).max_chan_width; switch (width) { case CHAN_WIDTH_20_NOHT: case CHAN_WIDTH_20: break; case CHAN_WIDTH_40: center1 = get_center_freq_ht40(channels.chan[idx].freq, ht40plus); break; case CHAN_WIDTH_80: case CHAN_WIDTH_160: center1 = get_center_freq_vht(channels.chan[idx].freq, width); break; default: printlog("%s not implemented", channel_width_string(width, -1)); break; } /* only 20 MHz channels don't need additional center freq, otherwise we fail here * quietly because the scanning code sometimes tries invalid HT40+/- channels */ if (center1 == 0 && !(width == CHAN_WIDTH_20_NOHT || width == CHAN_WIDTH_20)) return false; if (!ifctrl_iwset_freq(conf.ifname, channels.chan[idx].freq, width, center1)) { printlog("ERROR: Failed to set CH %d (%d MHz) %s center %d", channels.chan[idx].chan, channels.chan[idx].freq, channel_width_string(width, ht40plus), center1); return false; } printlog("Set CH %d (%d MHz) %s center %d", channels.chan[idx].chan, channels.chan[idx].freq, channel_width_string(width, ht40plus), center1); conf.channel_idx = idx; conf.channel_width = width; conf.channel_ht40plus = ht40plus; last_channelchange = the_time; return true; }
bool channel_init(void) { /* get available channels */ ifctrl_iwget_freqlist(conf.if_phy, &channels); conf.channel_initialized = 1; printf("Got %d Bands, %d Channels:\n", channels.num_bands, channels.num_channels); for (int i = 0; i < channels.num_channels && i < MAX_CHANNELS; i++) printf("%s\n", channel_get_string(i)); if (conf.channel_set_num > 0) { /* configured values */ int ini_idx = channel_find_index_from_chan(conf.channel_set_num); if (!channel_change(ini_idx, conf.channel_set_width, conf.channel_set_ht40plus)) return false; } else { conf.channel_idx = channel_find_index_from_freq(conf.if_freq); conf.channel_set_num = channel_get_chan(conf.channel_idx); if (conf.channel_idx < 0) return true; // not failure /* try to set max width */ struct band_info b = channel_get_band_from_idx(conf.channel_idx); if (conf.channel_width != b.max_chan_width) { printlog("Try to set max channel width %s", channel_width_string(b.max_chan_width, -1)); // try both HT40+ and HT40- if necessary if (!channel_change(conf.channel_idx, b.max_chan_width, true) && !channel_change(conf.channel_idx, b.max_chan_width, false)) return false; } } return true; }
static int net_receive_conf_chan(unsigned char *buffer, size_t len) { struct net_conf_chan *nc; if (len < sizeof(struct net_conf_chan)) return 0; nc = (struct net_conf_chan *)buffer; conf.do_change_channel = nc->do_change; conf.channel_max = nc->upper; conf.channel_time = le32toh(nc->dwell_time); enum chan_width width = nc->width_ht40p & ~NET_WIDTH_HT40PLUS; bool ht40p = !!(nc->width_ht40p & NET_WIDTH_HT40PLUS); if (nc->channel != conf.channel_idx || width != conf.channel_width || ht40p != conf.channel_ht40plus) { /* something changed */ if (cli_fd > -1) { /* server */ if (!channel_change(nc->channel, width, ht40p)) { printlog("Net Channel %d %s is not available/allowed", channel_get_chan(nc->channel), channel_width_string(width, ht40p)); net_send_channel_config(); } else { /* success: update UI */ conf.channel_set_num = channel_get_chan(nc->channel); conf.channel_set_width = width; conf.channel_set_ht40plus = ht40p; update_display(NULL); } } else { /* client */ conf.channel_idx = nc->channel; conf.channel_width = conf.channel_set_width = width; conf.channel_ht40plus = conf.channel_set_ht40plus = ht40p; conf.channel_set_num = channel_get_chan(nc->channel); update_spectrum_durations(); update_display(NULL); } } return sizeof(struct net_conf_chan); }
static int get_center_freq_vht(unsigned int freq, enum chan_width width) { unsigned int center1 = 0; switch(width) { case CHAN_WIDTH_80: /* * VHT80 channels are non-overlapping and the primary * channel can be on any HT20/40 channel in the range */ if (freq >= 5180 && freq <= 5240) center1 = 5210; else if (freq >= 5260 && freq <= 5320) center1 = 5290; else if (freq >= 5500 && freq <= 5560) center1 = 5530; else if (freq >= 5580 && freq <= 5640) center1 = 5610; else if (freq >= 5660 && freq <= 5720) center1 = 5690; else if (freq >= 5745 && freq <= 5805) center1 = 5775; break; case CHAN_WIDTH_160: /* * There are only two possible VHT160 channels */ if (freq >= 5180 && freq <= 5320) center1 = 5250; else if (freq >= 5180 && freq <= 5320) center1 = 5570; break; case CHAN_WIDTH_8080: printlog("VHT80+80 not supported"); break; default: printlog("%s is not VHT", channel_width_string(width, -1)); } return center1; }
bool channel_input(WINDOW *win, int c) { char buf[6]; int x; switch (c) { case 's': case 'S': conf.do_change_channel = conf.do_change_channel ? 0 : 1; break; case 'd': case 'D': echo(); curs_set(1); mvwgetnstr(win, 18, 12, buf, 6); curs_set(0); noecho(); sscanf(buf, "%d", &x); conf.channel_time = x*1000; break; case 'u': case 'U': echo(); curs_set(1); mvwgetnstr(win, 19, 18, buf, 6); curs_set(0); noecho(); sscanf(buf, "%d", &x); conf.channel_max = x; break; case 'm': case 'M': echo(); curs_set(1); mvwgetnstr(win, 21, 18, buf, 3); curs_set(0); noecho(); sscanf(buf, "%d", &x); int i = channel_find_index_from_chan(x); if (i >= 0) { if (!conf.serveraddr[0] != '\0') { if (!channel_change(i, conf.channel_set_width, conf.channel_set_ht40plus)) printlog("Channel %d %s is not available/allowed", x, channel_width_string(conf.channel_set_width, conf.channel_set_ht40plus)); } else conf.channel_idx = i; } break; case '1': conf.channel_set_width = CHAN_WIDTH_20_NOHT; break; case '2': conf.channel_set_width = CHAN_WIDTH_20; break; case '4': conf.channel_set_width = CHAN_WIDTH_40; conf.channel_set_ht40plus = false; break; case '5': conf.channel_set_width = CHAN_WIDTH_40; conf.channel_set_ht40plus = true; break; case '8': conf.channel_set_width = CHAN_WIDTH_80; break; case '6': conf.channel_set_width = CHAN_WIDTH_160; break; default: return false; /* didn't handle input */ } // TODO: net client has not set channel_width and ht40p yet: net_send_channel_config(); update_channel_win(win); return true; }
void update_channel_win(WINDOW *win) { int l = 2; box(win, 0 , 0); print_centered(win, 0, 39, " Channel Settings "); wattron(win, WHITE); for (int b = 0; b < channel_get_num_bands(); b++) { const struct band_info* bp = channel_get_band(b); int c = channel_get_idx_from_band_idx(b, 0); int col = channel_get_chan(c) > 14 ? COL_BAND2 : 2; wattron(win, A_BOLD); mvwprintw(win, 2, col, "%s: %s", col == 2 ? "2.4GHz" : "5GHz", channel_width_string(bp->max_chan_width, -1)); if (bp->streams_rx || bp->streams_tx) wprintw(win, " %dx%d", bp->streams_rx, bp->streams_tx); wattroff(win, A_BOLD); l = 3; for (int i = 0; (c = channel_get_idx_from_band_idx(b, i)) != -1; i++) { if (c == conf.channel_idx) wattron(win, CYAN); else wattron(win, WHITE); mvwprintw(win, l++, col, "%s", channel_get_string(c)); } } wattroff(win, WHITE); l = 17; wattron(win, A_BOLD); mvwprintw(win, l++, 2, "s: [%c] Scan", CHECKED(conf.do_change_channel)); wattroff(win, A_BOLD); mvwprintw(win, l++, 2, "d: Dwell: %d ms ", conf.channel_time/1000); mvwprintw(win, l++, 2, "u: Upper limit: %d ", conf.channel_max); l++; wattron(win, A_BOLD); mvwprintw(win, l++, 2, "m: Set channel: %d ", channel_get_chan(conf.channel_idx)); wattroff(win, A_BOLD); mvwprintw(win, l++, 2, "1: [%c] 20 (no HT)", CHECKED(conf.channel_set_width == CHAN_WIDTH_20_NOHT)); mvwprintw(win, l++, 2, "2: [%c] HT20", CHECKED(conf.channel_set_width == CHAN_WIDTH_20)); mvwprintw(win, l++, 2, "4: [%c] HT40-", CHECKED(conf.channel_set_width == CHAN_WIDTH_40 && !conf.channel_set_ht40plus)); mvwprintw(win, l++, 2, "5: [%c] HT40+", CHECKED(conf.channel_set_width == CHAN_WIDTH_40 && conf.channel_set_ht40plus)); mvwprintw(win, l++, 2, "8: [%c] VHT80", CHECKED(conf.channel_set_width == CHAN_WIDTH_80)); mvwprintw(win, l++, 2, "6: [%c] VHT160", CHECKED(conf.channel_set_width == CHAN_WIDTH_160)); print_centered(win, CHANNEL_WIN_HEIGHT-1, CHANNEL_WIN_WIDTH, "[ Press key or ENTER ]"); wrefresh(win); }