1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17#include <stdio.h> 18#include <string.h> 19#include <bcmnvram.h> 20#include <net/if_arp.h> 21#include <shutils.h> 22#include <sys/types.h> 23#include <sys/stat.h> 24#include <dirent.h> 25#include <sys/ioctl.h> 26#include <sys/sysctl.h> 27#include <errno.h> 28#include <etioctl.h> 29#include <rc.h> 30typedef u_int64_t __u64; 31typedef u_int32_t __u32; 32typedef u_int16_t __u16; 33typedef u_int8_t __u8; 34#include <linux/sockios.h> 35#include <linux/ethtool.h> 36#include <ctype.h> 37#include <wlutils.h> 38#include <shared.h> 39#include <wlscan.h> 40 41#ifdef RTCONFIG_BCM_7114 42#include <bcmutils.h> 43#include <bcmendian.h> 44#include <security_ipc.h> 45#endif 46 47//This define only used for switch 53125 48#define SWITCH_PORT_0_UP 0x0001 49#define SWITCH_PORT_1_UP 0x0002 50#define SWITCH_PORT_2_UP 0x0004 51#define SWITCH_PORT_3_UP 0x0008 52#define SWITCH_PORT_4_UP 0x0010 53 54#define SWITCH_PORT_0_GIGA 0x0002 55#define SWITCH_PORT_1_GIGA 0x0008 56#define SWITCH_PORT_2_GIGA 0x0020 57#define SWITCH_PORT_3_GIGA 0x0080 58#define SWITCH_PORT_4_GIGA 0x0200 59//End 60 61//Defined for switch 5325 62//#define SWITCH_ACCESS_CMD SIOCGETCROBORD 63#define SWITCH_ACCESS_PAGE "0x1" 64#define SWITCH_ACCESS_REG_LINKSTATUS "0x0" 65#define SWITCH_ACCESS_REG_LINKSPEED "0x4" 66 67/* hardware-dependent */ 68#define ETH_WAN_PORT "4" 69#define ETH_LAN1_PORT "3" 70#define ETH_LAN2_PORT "2" 71#define ETH_LAN3_PORT "1" 72#define ETH_LAN4_PORT "0" 73 74/* RT-N53 */ 75/* WAN Port=4 */ 76#define MASK_PHYPORT 0x0010 77 78#define ETH_WAN_PORT_UP 0x0010 79#define ETH_LAN1_PORT_UP 0x0001 80#define ETH_LAN2_PORT_UP 0x0002 81#define ETH_LAN3_PORT_UP 0x0004 82#define ETH_LAN4_PORT_UP 0x0008 83 84#define ETH_WAN_PORT_GIGA 0x0200 85#define ETH_LAN1_PORT_GIGA 0x0002 86#define ETH_LAN2_PORT_GIGA 0x0008 87#define ETH_LAN3_PORT_GIGA 0x0020 88#define ETH_LAN4_PORT_GIGA 0x0080 89 90#define ETH_PHY_REG_LAN_ADDR "0x1e" 91#define ETH_PHY_REG_LAN_DISCONN_VALUE "0x80a8" 92#define ETH_PHY_REG_LAN_CONN_VALUE "0x80a0" 93//End 94char cmd[32]; 95 96#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 97extern int ext_rtk_phyState(int v, char* BCMPorts); 98#endif 99 100int 101set40M_Channel_2G(char *channel) 102{ 103#ifdef RTCONFIG_BCMWL6 104 char str[8]; 105#endif 106 107 if (channel==NULL || !isValidChannel(1, channel)) 108 return 0; 109 110#ifdef RTCONFIG_BCMWL6 111 if (atoi(channel) >= 5) sprintf(str, "%su", channel); 112 else sprintf(str, "%sl", channel); 113 nvram_set("wl0_chanspec", str); 114 nvram_set("wl0_bw_cap", "3"); 115#else 116 nvram_set("wl0_channel", channel); 117 nvram_set("wl0_nbw_cap", "1"); 118 nvram_set("wl0_nctrlsb", "lower"); 119#endif 120 nvram_set("wl0_obss_coex", "0"); 121 eval("wlconf", "eth1", "down"); 122 eval("wlconf", "eth1", "up"); 123 eval("wlconf", "eth1", "start"); 124 puts("1"); 125 return 1; 126} 127 128int 129set40M_Channel_5G(char *channel) 130{ 131#ifdef RTCONFIG_BCMWL6 132 char str[8]; 133 int ch = 0; 134#endif 135 136 if (channel==NULL || !isValidChannel(0, channel)) 137 return 0; 138 139#ifdef RTCONFIG_BCMWL6 140 ch = atoi(channel); 141 sprintf(str, "0"); 142 if (ch==40||ch==48||ch==56||ch==64||ch==104||ch==112||ch==120||ch==128||ch==136||ch==153||ch==161) 143 sprintf(str, "%su", channel); 144 else if (ch==36||ch==44||ch==52||ch==60||ch==100||ch==108||ch==116||ch==124||ch==132||ch==149||ch==157) 145 sprintf(str, "%sl", channel); 146 nvram_set("wl1_chanspec", str); 147 nvram_set("wl1_bw_cap", "3"); 148#else 149 nvram_set("wl1_channel", channel); 150 nvram_set("wl1_nbw_cap", "1"); 151 nvram_set("wl1_nctrlsb", "lower"); 152#endif 153 eval("wlconf", "eth2", "down"); 154 eval("wlconf", "eth2", "up"); 155 eval("wlconf", "eth2", "start"); 156 puts("1"); 157 return 1; 158} 159 160int 161set80M_Channel_5G(char *channel) 162{ 163#ifdef RTCONFIG_BCMWL6 164 char str[8]; 165 int ch = 0; 166#endif 167 168 if (channel==NULL || !isValidChannel(0, channel)) 169 return 0; 170 171#ifdef RTCONFIG_BCMWL6 172 ch = atoi(channel); 173 sprintf(str, "0"); 174 if (ch==36||ch==40||ch==44||ch==48||ch==52||ch==56||ch==60||ch==64|| 175 ch==100||ch==104||ch==108||ch==112||ch==149||ch==153||ch==157||ch==161) 176 sprintf(str, "%s/80", channel); 177 nvram_set("wl1_chanspec", str); 178 nvram_set("wl1_bw_cap", "7"); 179#else 180 nvram_set("wl1_channel", channel); 181 nvram_set("wl1_nbw_cap", "1"); 182 nvram_set("wl1_nctrlsb", "lower"); 183#endif 184 eval("wlconf", "eth2", "down"); 185 eval("wlconf", "eth2", "up"); 186 eval("wlconf", "eth2", "start"); 187 puts("1"); 188 return 1; 189} 190 191int 192ResetDefault(void) 193{ 194#ifndef RTCONFIG_BCMARM 195 eval("mtd-erase","-d","nvram"); 196 puts("1"); 197#else 198 int ret=0; 199 if (nvram_contains_word("rc_support", "nandflash")) /* RT-AC56S,U/RT-AC68U/RT-N18U */ 200#ifdef RTAC87U 201 ret = mtd_erase("nvram"); 202#else 203 ret = eval("mtd-erase2", "nvram"); 204#endif 205 else 206#if defined(RTAC1200G) || defined(RTAC1200GP) 207 ret = eval("mtd-erase2", "nvram"); 208#else 209 ret = eval("mtd-erase","-d","nvram"); 210#endif 211#ifdef RTAC87U 212 if (ret == 0) { 213 return 0; 214 } else { 215 return -1; 216 } 217#else 218 if (ret >= 0) { 219 sleep(3); 220 puts("1"); 221 } 222 else 223 puts("0"); 224#endif 225#endif 226 return 0; 227} 228 229int 230GetPhyStatus(int verbose) 231{ 232 int ports[5]; 233#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 234 int ext = 0; 235#endif 236 int i, ret, lret=0, model, mask; 237 char out_buf[30]; 238 239 model = get_model(); 240 switch(model) { 241 case MODEL_RTN14UHP: 242 /* WAN L1 L2 L3 L4 */ 243 ports[0]=4; ports[1]=0; ports[2]=1, ports[3]=2; ports[4]=3; 244 break; 245 case MODEL_RTN53: 246 case MODEL_RTN15U: 247 case MODEL_RTN12: 248 case MODEL_RTN12B1: 249 case MODEL_RTN12C1: 250 case MODEL_RTN12D1: 251 case MODEL_RTN12VP: 252 case MODEL_RTN12HP: 253 case MODEL_RTN12HP_B1: 254 case MODEL_APN12HP: 255 case MODEL_RTN10P: 256 case MODEL_RTN10D1: 257 case MODEL_RTN10PV2: 258 /* WAN L1 L2 L3 L4 */ 259 ports[0]=4; ports[1]=3; ports[2]=2, ports[3]=1; ports[4]=0; 260 break; 261 case MODEL_RTN16: 262 case MODEL_RTN10U: 263 /* WAN L1 L2 L3 L4 */ 264 ports[0]=0; ports[1]=4; ports[2]=3, ports[3]=2; ports[4]=1; 265 break; 266 case MODEL_RTAC88U: 267 case MODEL_RTAC3100: 268 /* WAN L1 L2 L3 L4 */ 269 ports[0]=4; ports[1]=3; ports[2]=2; ports[3]=1; ports[4]=0; 270#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 271 ext = 1; 272#endif 273 break; 274 case MODEL_RTAC56S: 275 case MODEL_RTAC56U: 276 /* WAN L1 L2 L3 L4 */ 277 ports[0]=4; ports[1]=0; ports[2]=1; ports[3]=2; ports[4]=3; 278 break; 279 280 case MODEL_RTAC87U: 281 /* WAN L1 L2 L3 L4 */ 282 ports[0]=0; ports[1]=5; ports[2]=3; ports[3]=2; ports[4]=1; 283 break; 284 285 case MODEL_DSLAC68U: 286 case MODEL_RPAC68U: 287 case MODEL_RTAC68U: 288 case MODEL_RTAC3200: 289 case MODEL_RTN18U: 290 case MODEL_RTAC53U: 291 case MODEL_RTN66U: 292 case MODEL_RTAC66U: 293 case MODEL_RTAC1200G: 294 case MODEL_RTAC1200GP: 295 /* WAN L1 L2 L3 L4 */ 296 ports[0]=0; ports[1]=1; ports[2]=2; ports[3]=3; ports[4]=4; 297 break; 298 case MODEL_RTAC5300: 299 /* WAN L1 L2 L3 L4 */ 300 ports[0]=0; ports[1]=1; ports[2]=2; ports[3]=3; ports[4]=4; 301#ifdef RTCONFIG_EXT_RTL8365MB 302 ext = 1; 303#endif 304 break; 305 case MODEL_RTAC5300R: 306 /* WAN L8 L4 TRUNK2 TRUNK1 */ 307 ports[0]=0; ports[1]=4; ports[2]=3; ports[3]=2; ports[4]=1; 308#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 309 ext = 1; 310#endif 311 break; 312 } 313 314#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 315 char PStatus[5]="XXXXX"; 316#endif 317 318 memset(out_buf, 0, 30); 319 for (i=0; i<5; i++) { 320 mask = 0; 321 mask |= 0x0001<<ports[i]; 322 if (get_phy_status(mask)==0) {/*Disconnect*/ 323 if (i==0) 324 sprintf(out_buf, "W0=X;"); 325 else { 326#ifndef RTAC5300R 327 sprintf(out_buf, "%sL%d=X;", out_buf, i); 328#endif 329 } 330 } 331 else { /*Connect, keep check speed*/ 332 mask = 0; 333 mask |= (0x0003<<(ports[i]*2)); 334 ret=get_phy_speed(mask); 335 ret>>=(ports[i]*2); 336 if (i==0) 337 sprintf(out_buf, "W0=%s;", (ret & 2)? "G":"M"); 338 else { 339#ifndef RTAC5300R 340 lret = 1; 341 sprintf(out_buf, "%sL%d=%s;", out_buf, i, (ret & 2)? "G":"M"); 342#else 343 PStatus[i] = (ret & 2)? 'G':'M'; 344 if (i < 3) lret = 1; 345#endif 346 } 347 } 348 } 349 350#ifdef RTCONFIG_QTN 351 if (model == MODEL_RTAC87U) { 352 ports[1] = GetPhyStatus_qtn(); 353 if (ports[1] == 1000) { 354 out_buf[8] = 'G'; 355 } else if (ports[1] == 100) { 356 out_buf[8] = 'M'; 357 } else if (ports[1] == 10) { 358 out_buf[8] = 'M'; 359 } else { 360 out_buf[8] = 'X'; 361 } 362 } 363#endif 364 if (verbose) 365#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 366 printf("%s", out_buf); 367#else 368 puts(out_buf); 369#endif 370 371#if defined(RTCONFIG_EXT_RTL8365MB) || defined(RTCONFIG_EXT_RTL8370MB) 372 if (ext) 373 lret |= ext_rtk_phyState(verbose, PStatus); 374#endif 375 return lret; 376} 377 378#ifdef RTCONFIG_LAN4WAN_LED 379int LanWanLedCtrl(void) 380{ 381 int ports[5]; 382 int i, ret, model, mask; 383 char out_buf[30]; 384 385 model = get_model(); 386 switch(model) { 387 case MODEL_RTN14UHP: 388 /* WAN L1 L2 L3 L4 */ 389 ports[0]=4; ports[1]=0; ports[2]=1, ports[3]=2; ports[4]=3; 390 break; 391 } 392 393 memset(out_buf, 0, 30); 394 for (i=0; i<5; i++) { 395 mask = 0; 396 mask |= 0x0001<<ports[i]; 397 if (get_phy_status(mask)==0) {/*Disconnect*/ 398 if (i==0) { 399 led_control(LED_WAN, LED_OFF); 400 } else { 401 if (i == 1) led_control(LED_LAN1, LED_OFF); 402 if (i == 2) led_control(LED_LAN2, LED_OFF); 403 if (i == 3) led_control(LED_LAN3, LED_OFF); 404 if (i == 4) led_control(LED_LAN4, LED_OFF); 405 } 406 } 407 else { /*Connect, keep check speed*/ 408 mask = 0; 409 mask |= (0x0003<<(ports[i]*2)); 410 ret=get_phy_speed(mask); 411 ret>>=(ports[i]*2); 412 if (i==0) { 413 led_control(LED_WAN, LED_ON); 414 } else { 415 if (i == 1) led_control(LED_LAN1, LED_ON); 416 if (i == 2) led_control(LED_LAN2, LED_ON); 417 if (i == 3) led_control(LED_LAN3, LED_ON); 418 if (i == 4) led_control(LED_LAN4, LED_ON); 419 } 420 } 421 } 422 return 1; 423} 424#endif /* LAN4WAN_LED*/ 425 426int 427setAllLedOn(void) 428{ 429 int model; 430 431 led_control(LED_POWER, LED_ON); 432 433 // generate nvram nvram according to system setting 434 model = get_model(); 435 switch(model) { 436 case MODEL_RTN16: 437 case MODEL_RTN66U: 438 { 439 /* LAN, WAN Led On */ 440 eval("et", "robowr", "0", "0x18", "0x01ff"); 441 eval("et", "robowr", "0", "0x1a", "0x01e0"); 442 eval("radio", "on"); /* wireless */ 443 led_control(LED_USB, LED_ON); 444 break; 445 } 446 case MODEL_RTN18U: 447 { 448 led_control(LED_USB, LED_ON); 449 led_control(LED_USB3, LED_ON); 450 led_control(LED_POWER, LED_ON); 451 led_control(LED_WAN, LED_ON); 452 led_control(LED_LAN, LED_ON); 453 eval("wl", "-i", "eth1", "ledbh", "10", "7"); 454 break; 455 } 456 case MODEL_DSLAC68U: 457 { 458 led_control(LED_USB3, LED_ON); 459 led_control(LED_WAN, LED_ON); 460 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 461 eval("et", "robowr", "0", "0x1a", "0x01e0"); 462 eval("wl", "ledbh", "10", "1"); // wl 2.4G 463 eval("wl", "-i", "eth2", "ledbh", "10", "1"); // wl 5G 464 /* 4360's fake 5g led */ 465 led_control(LED_5G, LED_ON); 466 eval("adslate", "led", "on"); 467 break; 468 } 469 case MODEL_RTAC87U: 470 { 471 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 472 eval("et", "robowr", "0", "0x1a", "0x01e0"); 473 eval("wl", "ledbh", "10", "1"); // wl 2.4G 474 led_control(LED_WPS, LED_ON); 475 led_control(LED_WAN, LED_ON); 476#ifdef RTCONFIG_QTN 477 setAllLedOn_qtn(); 478#endif 479 break; 480 } 481 case MODEL_RPAC68U: 482 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 483 eval("et", "robowr", "0", "0x1a", "0x01e0"); 484 485 eval("wl", "ledbh", "0", "1"); // wl 2.4G 486 eval("wl", "ledbh", "9", "1"); // wl 2.4G 487 eval("wl", "ledbh", "10", "1"); // wl 2.4G 488 eval("wl", "-i", "eth2", "ledbh", "0", "1"); // wl 5G 489 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 5G 490 eval("wl", "-i", "eth2", "ledbh", "10", "1"); // wl 5G 491 break; 492 case MODEL_RTAC68U: 493 case MODEL_RTAC3200: 494 case MODEL_RTAC5300: 495 case MODEL_RTAC5300R: 496 case MODEL_RTAC88U: 497 case MODEL_RTAC3100: 498 { 499#if defined(RTAC68U) || defined(RTAC88U) || defined(RTAC3100) || defined(RTAC5300) || defined(RTAC5300R) 500 led_control(LED_USB, LED_ON); 501 led_control(LED_USB3, LED_ON); 502#endif 503#ifdef RTCONFIG_TURBO 504 led_control(LED_TURBO, LED_ON); 505#endif 506 eval("et", "-i", "eth0", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 507 eval("et", "-i", "eth0", "robowr", "0", "0x1a", "0x01e0"); 508#if defined(RTAC3200) 509 eval("wl", "ledbh", "10", "1"); // wl 5G low 510 eval("wl", "-i", "eth2", "ledbh", "10", "1"); // wl 2.4G 511 eval("wl", "-i", "eth3", "ledbh", "10", "1"); // wl 5G high 512#elif defined(RTAC5300) || defined(RTAC5300R) 513 eval("wl", "ledbh", "9", "1"); // wl 5G low 514 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 2.4G 515 eval("wl", "-i", "eth3", "ledbh", "9", "1"); // wl 5G high 516#elif defined(RTAC88U) || defined(RTAC3100) 517 eval("wl", "ledbh", "9", "1"); // wl 2.4G 518 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 5G 519#else 520 eval("wl", "ledbh", "10", "1"); // wl 2.4G 521 eval("wl", "-i", "eth2", "ledbh", "10", "1"); // wl 5G 522#endif 523 524#if defined(RTAC3200) 525 led_control(LED_WPS, LED_ON); 526 led_control(LED_WAN, LED_ON); 527#elif defined (RTAC88U) || defined (RTAC3100) || defined (RTAC5300) || defined(RTAC5300R) 528 led_control(LED_WPS, LED_ON); 529 led_control(LED_WAN, LED_ON); 530 led_control(LED_LAN, LED_ON); 531#endif 532#ifdef RTAC68U 533 /* 4360's fake 5g led */ 534 led_control(LED_5G, LED_ON); 535 if (!strcmp(get_productid(), "RT-AC66U V2")) 536 led_control(LED_WAN, LED_ON); 537#endif 538 break; 539 } 540 case MODEL_RTAC56S: 541 case MODEL_RTAC56U: 542 { 543#ifdef RTCONFIG_LED_ALL 544 led_control(LED_ALL, LED_ON); 545#endif 546 led_control(LED_USB, LED_ON); 547 led_control(LED_USB3, LED_ON); 548 led_control(LED_WAN, LED_ON); 549 led_control(LED_LAN, LED_ON); 550 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 551 eval("et", "robowr", "0", "0x1a", "0x01e0"); 552 eval("wl", "ledbh", "3", "1"); // wl 2.4G 553 eval("wl", "-i", "eth2","ledbh", "10", "1"); 554 /* 4352's fake 5g led */ 555 led_control(LED_5G, LED_ON); 556 break; 557 } 558 case MODEL_RTAC66U: 559 { 560 /* LAN, WAN Led On */ 561 eval("et", "robowr", "0", "0x18", "0x01ff"); 562 eval("et", "robowr", "0", "0x1a", "0x01e0"); 563 eval("radio", "on"); /* 2G led */ 564 led_control(LED_5G, LED_ON); 565 led_control(LED_USB, LED_ON); 566 break; 567 } 568 case MODEL_RTN14UHP: 569 { 570 led_control(LED_POWER, LED_ON); 571 /* convert from shared, boardapi.c */ 572 led_control(LED_WPS, LED_ON); 573 led_control(LED_USB, LED_ON); 574 eval("radio", "on"); /* 2G led */ 575 if (nvram_contains_word("rc_support", "lanwan_led2")) { 576 led_control(LED_WAN, LED_ON); 577#ifdef RTCONFIG_LAN4WAN_LED 578 led_control(LED_LAN1, LED_ON); 579 led_control(LED_LAN2, LED_ON); 580 led_control(LED_LAN3, LED_ON); 581 led_control(LED_LAN4, LED_ON); 582#endif 583 } else { 584 eval("et", "robowr", "00", "0x12", "0xfd55"); 585 } 586 break; 587 } 588 case MODEL_APN12HP: 589 { 590 led_control(LED_POWER, LED_ON); 591 /* convert from shared, boardapi.c */ 592 nvram_set_int("led_2g_gpio", 4099); 593 led_control(LED_2G, LED_ON); 594 led_control(LED_WAN, LED_ON); 595 break; 596 } 597 case MODEL_RTN10P: 598 case MODEL_RTN10D1: 599 case MODEL_RTN10PV2: 600 { 601 led_control(LED_WPS, LED_ON); 602 } 603 case MODEL_RTN12B1: 604 case MODEL_RTN12C1: 605 case MODEL_RTN12D1: 606 case MODEL_RTN12VP: 607 case MODEL_RTN12HP: 608 case MODEL_RTN12HP_B1: 609 { 610 eval("et", "robowr", "00", "0x12", "0xfd55"); 611 eval("radio", "on"); /* wireless */ 612 break; 613 } 614 case MODEL_RTN10U: 615 { 616 led_control(LED_WPS, LED_ON); 617 led_control(LED_USB, LED_ON); 618 eval("et", "robowr", "00", "0x12", "0xfd55"); 619 eval("radio", "on"); /* wireless */ 620 break; 621 } 622 case MODEL_RTN15U: 623 { 624 //LAN, WAN Led On 625 led_control(LED_POWER, LED_ON); 626 led_control(LED_LAN, LED_ON); 627 led_control(LED_WAN, LED_ON); 628 led_control(LED_USB, LED_ON); 629 eval("radio", "on"); /* wireless */ 630 break; 631 } 632 case MODEL_RTN53: 633 { 634 //LAN, WAN Led On 635 led_control(LED_LAN, LED_ON); 636 led_control(LED_WAN, LED_ON); 637 led_control(LED_2G, LED_ON); 638 led_control(LED_5G, LED_ON); 639 break; 640 } 641 case MODEL_RTAC53U: 642 { 643 led_control(LED_POWER, LED_ON); 644 led_control(LED_LAN, LED_ON); 645 led_control(LED_WAN, LED_ON); 646 led_control(LED_USB, LED_ON); 647 eval("wl", "-i", "eth1", "ledbh", "3", "1"); // wl 2.4G 648 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 5G 649 break; 650 } 651 case MODEL_RTAC1200G: 652 case MODEL_RTAC1200GP: 653 { 654 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 655 eval("et", "robowr", "0", "0x1a", "0x01e0"); 656 eval("wl", "-i", "eth1", "ledbh", "3", "1"); // wl 2.4G 657 eval("wl", "-i", "eth2", "ledbh", "11", "1"); // wl 5G 658 led_control(LED_WPS, LED_ON); 659 led_control(LED_USB, LED_ON); 660 break; 661 } 662 } 663 664 wan_red_led_control(LED_ON); 665 666 puts("1"); 667 return 0; 668} 669 670int 671setWlOffLed(void) 672{ 673 int model; 674 int wlon_unit = nvram_get_int("wlc_band"); 675#ifdef PXYSTA_DUALBAND 676 int wlon_unit_ex = !nvram_match("dpsta_ifnames", "") ? nvram_get_int("wlc_band_ex") : -1 ; 677#else 678 int wlon_unit_ex = -1; 679#endif 680 681 model = get_model(); 682 switch(model) { 683 case MODEL_RTAC56S: 684 case MODEL_RTAC56U: 685 { 686 if (wlon_unit != 0) { 687 eval("wl", "ledbh", "3", "0"); // wl 2.4G 688 } else { 689 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 5G 690 led_control(LED_5G, LED_OFF); 691 } 692 break; 693 } 694 case MODEL_RPAC68U: 695 case MODEL_RTAC68U: 696 if (wlon_unit != 0) { 697 eval("wl", "ledbh", "10", "0"); // wl 2.4G 698#ifdef RTCONFIG_LEDARRAY 699 eval("wl", "ledbh", "0", "0"); // wl 2.4G 700 eval("wl", "ledbh", "9", "0"); // wl 2.4G 701#endif 702 } else { 703 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 5G 704#ifdef RTCONFIG_LEDARRAY 705 eval("wl", "-i", "eth2", "ledbh", "0", "0"); // wl 5G 706 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 707#endif 708#ifndef RTCONFIG_LEDARRAY 709 led_control(LED_5G, LED_OFF); 710#endif 711 } 712 break; 713 714 case MODEL_RTAC88U: 715 case MODEL_RTAC3100: 716 if (wlon_unit != 0) { 717 eval("wl", "ledbh", "9", "0"); // wl 2.4G 718 } else { 719 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 720 led_control(LED_5G, LED_OFF); 721 } 722 break; 723 724 case MODEL_RTAC5300: 725 case MODEL_RTAC5300R: 726 { 727 if (wlon_unit != 0 && wlon_unit_ex != 0) 728 eval("wl", "-i", "eth1", "ledbh", "9", "0"); // wl 2.4G 729 if (wlon_unit != 1 && wlon_unit_ex != 1) 730 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G low 731 if (wlon_unit != 2 && wlon_unit_ex != 2) 732 eval("wl", "-i", "eth3", "ledbh", "9", "0"); // wl 5G high 733 break; 734 } 735 case MODEL_RTAC3200: 736 { 737 if (wlon_unit != 0 && wlon_unit_ex != 0) 738 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 2.4G 739 if (wlon_unit != 1 && wlon_unit_ex != 1) 740 eval("wl", "ledbh", "10", "0"); // wl 5G low 741 if (wlon_unit != 2 && wlon_unit_ex != 2) 742 eval("wl", "-i", "eth3", "ledbh", "10", "0"); // wl 5G high 743 break; 744 } 745 case MODEL_RTAC53U: 746 { 747 if (wlon_unit != 0) { 748 eval("wl", "-i", "eth1", "ledbh", "3", "0"); // wl 2.4G 749 } else { 750 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 751 } 752 break; 753 } 754 case MODEL_RTAC1200G: 755 case MODEL_RTAC1200GP: 756 { 757 eval("wl", "ledbh", "10", "0"); // wl 2.4G 758 led_control(LED_5G, LED_OFF); 759 break; 760 } 761 } 762 763 return 0; 764} 765 766int 767setAllLedOff(void) 768{ 769 int model; 770 771 led_control(LED_POWER, LED_OFF); 772 773 // generate nvram nvram according to system setting 774 model = get_model(); 775 switch(model) { 776 case MODEL_RTN16: 777 case MODEL_RTN66U: 778 { 779 /* LAN, WAN Led Off */ 780 eval("et", "robowr", "0", "0x18", "0x01e0"); 781 eval("et", "robowr", "0", "0x1a", "0x01e0"); 782 eval("radio", "off"); /* wireless */ 783 led_control(LED_USB, LED_OFF); 784 break; 785 } 786 case MODEL_RTAC56S: 787 case MODEL_RTAC56U: 788 { 789#ifdef RTCONFIG_LED_ALL 790 led_control(LED_ALL, LED_OFF); 791#endif 792 eval("et", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 793 eval("et", "robowr", "0", "0x1a", "0x01e0"); 794 eval("wl", "ledbh", "3", "0"); // wl 2.4G 795 eval("wl", "-i", "eth2", "ledbh", "10", "0"); 796 /* 4352's fake 5g led */ 797 led_control(LED_5G, LED_OFF); 798 break; 799 } 800 case MODEL_RTN18U: 801 { 802 led_control(LED_USB, LED_OFF); 803 led_control(LED_USB3, LED_OFF); 804 led_control(LED_POWER, LED_OFF); 805 led_control(LED_WAN, LED_OFF); 806 led_control(LED_LAN, LED_OFF); 807 led_control(LED_2G, LED_OFF); 808 eval("wl", "-i", "eth1", "ledbh", "10", "0"); 809 break; 810 } 811 case MODEL_DSLAC68U: 812 { 813 char *ledcmd_argv[] = {"adslate", "led", "off", NULL}; 814 led_control(LED_USB3, LED_OFF); 815 led_control(LED_WAN, LED_OFF); 816 eval("et", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 817 eval("et", "robowr", "0", "0x1a", "0x01e0"); 818 eval("wl", "ledbh", "10", "0"); // wl 2.4G 819 eval("wl", "-i", "eth2", "ledbh", "10", "0"); 820 /* 4360's fake 5g led */ 821 led_control(LED_5G, LED_OFF); 822 _eval(ledcmd_argv, NULL, 5, NULL); 823 break; 824 } 825 case MODEL_RTAC87U: 826 { 827 eval("et", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 828 eval("et", "robowr", "0", "0x1a", "0x01e0"); 829 eval("wl", "ledbh", "10", "0"); // wl 2.4G 830 led_control(LED_WPS, LED_OFF); 831 led_control(LED_WAN, LED_OFF); 832#ifdef RTCONFIG_QTN 833 setAllLedOff_qtn(); 834#endif 835 break; 836 } 837 case MODEL_RPAC68U: 838 eval("et", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 839 eval("et", "robowr", "0", "0x1a", "0x01e0"); 840 841 eval("wl", "ledbh", "10", "0"); // wl 2.4G 842 eval("wl", "ledbh", "0", "0"); // wl 2.4G 843 eval("wl", "ledbh", "9", "0"); // wl 2.4G 844 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 5G 845 eval("wl", "-i", "eth2", "ledbh", "0", "0"); // wl 5G 846 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 847 break; 848 case MODEL_RTAC68U: 849 case MODEL_RTAC3200: 850 case MODEL_RTAC5300: 851 case MODEL_RTAC5300R: 852 case MODEL_RTAC88U: 853 case MODEL_RTAC3100: 854 { 855#if defined(RTAC68U) || defined(RTAC88U) || defined(RTAC3100) || defined(RTAC5300) || defined(RTAC5300R) 856 led_control(LED_USB, LED_OFF); 857 led_control(LED_USB3, LED_OFF); 858#endif 859#ifdef RTCONFIG_TURBO 860 led_control(LED_TURBO, LED_OFF); 861#endif 862 eval("et", "-i", "eth0", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 863 eval("et", "-i", "eth0", "robowr", "0", "0x1a", "0x01e0"); 864#if defined(RTAC3200) 865 eval("wl", "ledbh", "10", "0"); // wl 5G low 866 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 2.4G 867 eval("wl", "-i", "eth3", "ledbh", "10", "0"); // wl 5G high 868#elif defined (RTAC5300) || defined(RTAC5300R) 869 eval("wl", "ledbh", "9", "0"); // wl 5G low 870 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 2.4G 871 eval("wl", "-i", "eth3", "ledbh", "9", "0"); // wl 5G high 872#elif defined (RTAC88U) || defined (RTAC3100) 873 eval("wl", "ledbh", "9", "0"); // wl 2.4G 874 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 875#else 876 eval("wl", "ledbh", "10", "0"); // wl 2.4G 877 eval("wl", "-i", "eth2", "ledbh", "10", "0"); // wl 5G 878#endif 879 880#if defined(RTAC3200) 881 led_control(LED_WPS, LED_OFF); 882 led_control(LED_WAN, LED_OFF); 883#elif defined (RTAC88U) || defined (RTAC3100) || defined (RTAC5300) || defined(RTAC5300R) 884 led_control(LED_WPS, LED_OFF); 885 led_control(LED_WAN, LED_OFF); 886 led_control(LED_LAN, LED_OFF); 887#endif 888#ifdef RTAC68U 889 /* 4360's fake 5g led */ 890 led_control(LED_5G, LED_OFF); 891 if (!strcmp(get_productid(), "RT-AC66U V2")) 892 led_control(LED_WAN, LED_OFF); 893#endif 894#ifdef RTCONFIG_FAKE_ETLAN_LED 895 led_control(LED_LAN, LED_OFF); 896#endif 897 break; 898 } 899 case MODEL_RTAC66U: 900 { 901 /* LAN, WAN Led Off */ 902 eval("et", "robowr", "0", "0x18", "0x01e0"); 903 eval("et", "robowr", "0", "0x1a", "0x01e0"); 904 eval("radio", "off"); /* 2G led*/ 905 led_control(LED_5G, LED_OFF); 906 led_control(LED_USB, LED_OFF); 907 break; 908 } 909 case MODEL_RTN14UHP: 910 { 911 led_control(LED_POWER, LED_OFF); 912 /* convert from shared, boardapi.c */ 913 led_control(LED_WPS, LED_OFF); 914 led_control(LED_USB, LED_OFF); 915 eval("radio", "off"); /* 2G led */ 916 if (nvram_contains_word("rc_support", "lanwan_led2")) { 917 led_control(LED_WAN, LED_OFF); 918#ifdef RTCONFIG_LAN4WAN_LED 919 led_control(LED_LAN1, LED_OFF); 920 led_control(LED_LAN2, LED_OFF); 921 led_control(LED_LAN3, LED_OFF); 922 led_control(LED_LAN4, LED_OFF); 923#endif 924 } else { 925 eval("et", "robowr", "00", "0x12", "0xf800"); 926 } 927 break; 928 } 929 case MODEL_APN12HP: 930 { 931 led_control(LED_POWER, LED_OFF); 932 /* convert from shared, boardapi.c */ 933 nvram_set_int("led_2g_gpio", 4099); 934 led_control(LED_2G, LED_OFF); 935 led_control(LED_WAN, LED_OFF); 936 break; 937 } 938 case MODEL_RTN10P: 939 case MODEL_RTN10D1: 940 case MODEL_RTN10PV2: 941 { 942 led_control(LED_WPS, LED_OFF); 943 } 944 case MODEL_RTN12B1: 945 case MODEL_RTN12C1: 946 case MODEL_RTN12D1: 947 case MODEL_RTN12VP: 948 case MODEL_RTN12HP: 949 case MODEL_RTN12HP_B1: 950 { 951 eval("et", "robowr", "00", "0x12", "0xf800"); 952 eval("radio", "off"); /* wireless */ 953 break; 954 } 955 case MODEL_RTN10U: 956 { 957 led_control(LED_WPS, LED_OFF); 958 led_control(LED_USB, LED_OFF); 959 eval("et", "robowr", "00", "0x12", "0xf800"); 960 eval("radio", "off"); /* wireless */ 961 break; 962 } 963 case MODEL_RTN15U: 964 { 965 //LAN, WAN Led Off 966 led_control(LED_POWER, LED_OFF); 967 led_control(LED_LAN, LED_OFF); 968 led_control(LED_WAN, LED_OFF); 969 led_control(LED_USB, LED_OFF); 970 eval("radio", "off"); /* wireless */ 971 break; 972 } 973 case MODEL_RTN53: 974 { 975 //LAN, WAN Led Off 976 led_control(LED_LAN, LED_OFF); 977 led_control(LED_WAN, LED_OFF); 978 led_control(LED_2G, LED_OFF); 979 led_control(LED_5G, LED_OFF); 980 break; 981 } 982 case MODEL_RTAC53U: 983 { 984 led_control(LED_POWER, LED_OFF); 985 led_control(LED_LAN, LED_OFF); 986 led_control(LED_WAN, LED_OFF); 987 led_control(LED_USB, LED_OFF); 988 eval("wl", "-i", "eth1", "ledbh", "3", "0"); // wl 2.4G 989 eval("wl", "-i", "eth2", "ledbh", "9", "0"); // wl 5G 990 break; 991 } 992 case MODEL_RTAC1200G: 993 case MODEL_RTAC1200GP: 994 { 995 eval("et", "robowr", "0", "0x18", "0x01e0"); // lan/wan ethernet/giga led 996 eval("et", "robowr", "0", "0x1a", "0x01e0"); 997 eval("wl", "-i", "eth1", "ledbh", "3", "0"); // wl 2.4G 998 eval("wl", "-i", "eth2", "ledbh", "11", "0"); // wl 5G 999 led_control(LED_WPS, LED_OFF); 1000 led_control(LED_USB, LED_OFF); 1001 break; 1002 } 1003 } 1004 1005 wan_red_led_control(LED_OFF); 1006 1007 puts("1"); 1008 return 0; 1009} 1010 1011int 1012setATEModeLedOn(void) { 1013 int model; 1014 1015 led_control(LED_POWER, LED_ON); 1016 model = get_model(); 1017 1018 switch(model) { 1019 case MODEL_RTN16: 1020 case MODEL_RTN66U: 1021 { 1022 /* LAN, WAN Led On */ 1023 eval("et", "robowr", "0", "0x18", "0x01ff"); 1024 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1025 led_control(LED_USB, LED_ON); 1026 break; 1027 } 1028 case MODEL_RTN18U: 1029 { 1030 led_control(LED_USB, LED_ON); 1031 led_control(LED_POWER, LED_ON); 1032 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1033 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1034 break; 1035 } 1036 case MODEL_DSLAC68U: 1037 { 1038 led_control(LED_USB3, LED_ON); 1039 led_control(LED_WAN, LED_ON); 1040 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1041 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1042 eval("adslate", "led", "on"); 1043 break; 1044 } 1045 case MODEL_RTAC87U: 1046 { 1047 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1048 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1049 led_control(LED_WPS, LED_ON); 1050#ifdef RTCONFIG_QTN 1051 setAllLedOn_qtn(); 1052#endif 1053 break; 1054 } 1055 case MODEL_RTAC68U: 1056 case MODEL_RTAC3200: 1057 { 1058 led_control(LED_WPS, LED_ON); 1059 led_control(LED_USB, LED_ON); 1060 led_control(LED_USB3, LED_ON); 1061#ifdef RTCONFIG_TURBO 1062 led_control(LED_TURBO, LED_ON); 1063#endif 1064 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1065 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1066 break; 1067 } 1068 //case MODEL_RPAC68U: 1069 case MODEL_RTAC88U: 1070 case MODEL_RTAC3100: 1071 case MODEL_RTAC5300: 1072 case MODEL_RTAC5300R: 1073 { 1074 led_control(LED_WPS, LED_ON); 1075 led_control(LED_WAN, LED_ON); 1076 led_control(LED_LAN, LED_ON); 1077 led_control(LED_USB, LED_ON); 1078 led_control(LED_USB3, LED_ON); 1079 1080 eval("et", "-i", "eth0", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1081 eval("et", "-i", "eth0", "robowr", "0", "0x1a", "0x01e0"); 1082#if defined(RTAC5300) || defined(RTAC5300R) 1083 eval("wl", "ledbh", "9", "1"); // wl 5G low 1084 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 2.4G 1085 eval("wl", "-i", "eth3", "ledbh", "9", "1"); // wl 5G high 1086#elif defined(RTAC88U) || defined(RTAC3100) 1087 eval("wl", "ledbh", "9", "1"); // wl 2.4G 1088 eval("wl", "-i", "eth2", "ledbh", "9", "1"); // wl 5G 1089#endif 1090 break; 1091 } 1092 case MODEL_RTAC56S: 1093 case MODEL_RTAC56U: 1094 { 1095#ifdef RTCONFIG_LED_ALL 1096 led_control(LED_ALL, LED_ON); 1097#endif 1098 led_control(LED_USB, LED_ON); 1099 led_control(LED_USB3, LED_ON); 1100 led_control(LED_WAN, LED_ON); 1101 led_control(LED_LAN, LED_ON); 1102 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1103 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1104 break; 1105 } 1106 case MODEL_RTAC66U: 1107 { 1108 /* LAN, WAN Led On */ 1109 eval("et", "robowr", "0", "0x18", "0x01ff"); 1110 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1111 led_control(LED_USB, LED_ON); 1112 break; 1113 } 1114 case MODEL_RTN10P: 1115 case MODEL_RTN10D1: 1116 case MODEL_RTN10PV2: 1117 { 1118 led_control(LED_WPS, LED_ON); 1119 break; 1120 } 1121 case MODEL_APN12HP: 1122 { 1123 led_control(LED_POWER, LED_ON); 1124 /* convert from shared, boardapi.c */ 1125 led_control(LED_WAN, LED_ON); 1126 break; 1127 } 1128 case MODEL_RTN12B1: 1129 case MODEL_RTN12C1: 1130 case MODEL_RTN12D1: 1131 case MODEL_RTN12VP: 1132 case MODEL_RTN12HP: 1133 case MODEL_RTN12HP_B1: 1134 { 1135 eval("et", "robowr", "00", "0x12", "0xfd55"); 1136 break; 1137 } 1138 case MODEL_RTN10U: 1139 { 1140 led_control(LED_WPS, LED_ON); 1141 led_control(LED_USB, LED_ON); 1142 eval("et", "robowr", "00", "0x12", "0xfd55"); 1143 break; 1144 } 1145 case MODEL_RTN53: 1146 { 1147 /* LAN, WAN Led On */ 1148 led_control(LED_LAN, LED_ON); 1149 led_control(LED_WAN, LED_ON); 1150 break; 1151 } 1152 case MODEL_RTAC53U: 1153 { 1154 led_control(LED_POWER, LED_ON); 1155 led_control(LED_LAN, LED_ON); 1156 led_control(LED_WAN, LED_ON); 1157 led_control(LED_USB, LED_ON); 1158 break; 1159 } 1160 case MODEL_RTAC1200G: 1161 case MODEL_RTAC1200GP: 1162 { 1163 eval("et", "robowr", "0", "0x18", "0x01ff"); // lan/wan ethernet/giga led 1164 eval("et", "robowr", "0", "0x1a", "0x01e0"); 1165 led_control(LED_WPS, LED_ON); 1166 led_control(LED_USB, LED_ON); 1167 break; 1168 } 1169 } 1170 1171 return 0; 1172} 1173 1174#ifdef RTCONFIG_FANCTRL 1175int 1176setFanOn(void) 1177{ 1178 led_control(FAN, FAN_ON); 1179 if (button_pressed(BTN_FAN)) 1180 puts("1"); 1181 else 1182 puts("ATE_ERROR"); 1183} 1184 1185int 1186setFanOff(void) 1187{ 1188 led_control(FAN, FAN_OFF); 1189 if (!button_pressed(BTN_FAN)) 1190 puts("1"); 1191 else 1192 puts("ATE_ERROR"); 1193} 1194#endif 1195 1196int 1197setWiFi2G(const char *act) 1198{ 1199 if (!strcmp(act, "on")) 1200 eval("wl", "radio", "on"); 1201 else if (!strcmp(act, "off")) 1202 eval("wl", "radio", "off"); 1203 else 1204 return 0; 1205 1206 puts(act); 1207 return 1; 1208} 1209 1210int 1211setWiFi5G(const char *act) 1212{ 1213 if (!strcmp(act, "on")) 1214 eval("wl", "-i", "eth2", "radio", "on"); 1215 else if (!strcmp(act, "off")) 1216 eval("wl", "-i", "eth2", "radio", "off"); 1217 else 1218 return 0; 1219 puts(act); 1220 return 1; 1221} 1222 1223int 1224getWiFiStatus(const char *ifc) 1225{ 1226 FILE *fp; 1227 char buf[128], *line; 1228 int ret = 1; 1229 1230 if (!strcmp(ifc, "2G")) 1231 sprintf(buf, "wl radio"); 1232 else if (!strcmp(ifc, "5G")) 1233 sprintf(buf, "wl -i eth2 radio"); 1234 else 1235 return 0; 1236 1237 fp = popen(buf, "r"); 1238 if (fp == NULL) { 1239 perror("popen"); 1240 return 0; 1241 } 1242 1243 line = fgets(buf, sizeof(buf), fp); 1244 if (line == NULL) 1245 ret = 0; 1246 else if (strstr(line, "0x0000")) 1247 puts("1"); 1248 else if (strstr(line, "0x0001")) 1249 puts("0"); 1250 else 1251 ret = 0; 1252 1253 return ret; 1254} 1255 1256/* The below macro handle endian mis-matches between wl utility and wl driver. */ 1257static bool g_swap = FALSE; 1258#define htod32(i) (g_swap?bcmswap32(i):(uint32)(i)) 1259#define dtoh32(i) (g_swap?bcmswap32(i):(uint32)(i)) 1260#define IW_MAX_FREQUENCIES 32 1261 1262int Get_channel_list(int unit) 1263{ 1264 int i, retval = 0; 1265 int channels[MAXCHANNEL+1]; 1266 wl_uint32_list_t *list = (wl_uint32_list_t *) channels; 1267 char tmp[256], prefix[] = "wlXXXXXXXXXX_"; 1268 char *name; 1269 uint ch; 1270 1271 snprintf(prefix, sizeof(prefix), "wl%d_", unit); 1272 name = nvram_safe_get(strcat_r(prefix, "ifname", tmp)); 1273 memset(tmp, 0x0, sizeof(tmp)); 1274 1275 memset(channels, 0, sizeof(channels)); 1276 list->count = htod32(MAXCHANNEL); 1277 if (wl_ioctl(name, WLC_GET_VALID_CHANNELS , channels, sizeof(channels)) < 0) 1278 { 1279 dbg("error doing WLC_GET_VALID_CHANNELS\n"); 1280 sprintf(tmp, "%d", 0); 1281 goto ERROR; 1282 } 1283 1284 if (dtoh32(list->count) == 0) 1285 { 1286 sprintf(tmp, "%d", 0); 1287 goto ERROR; 1288 } 1289 1290 retval = 1; 1291 for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { 1292 ch = dtoh32(list->element[i]); 1293 1294 if (i == 0) 1295 sprintf(tmp, "%d", ch); 1296 else 1297 sprintf(tmp, "%s, %d", tmp, ch); 1298 } 1299ERROR: 1300 puts(tmp); 1301 return retval; 1302} 1303 1304int Get_ChannelList_2G(void) 1305{ 1306#ifndef RTAC3200_INTF_ORDER 1307 return Get_channel_list(0); 1308#else 1309 return Get_channel_list(1); 1310#endif 1311} 1312 1313int Get_ChannelList_5G(void) 1314{ 1315#ifndef RTAC3200_INTF_ORDER 1316 return Get_channel_list(1); 1317#else 1318 return Get_channel_list(0); 1319#endif 1320} 1321 1322#if defined(RTAC3200) || defined(RTAC5300) || defined(RTAC5300R) 1323int Get_ChannelList_5G_2(void) 1324{ 1325 return Get_channel_list(2); 1326} 1327#endif 1328 1329static const unsigned char WPA_OUT_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; 1330 1331char *wlc_nvname(char *keyword) 1332{ 1333 return(wl_nvname(keyword, nvram_get_int("wlc_band"), -1)); 1334} 1335 1336int wpa_key_mgmt_to_bitfield(const unsigned char *s) 1337{ 1338 if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0) 1339 return WPA_KEY_MGMT_IEEE8021X_; 1340 if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) == 1341 0) 1342 return WPA_KEY_MGMT_PSK_; 1343 if (memcmp(s, WPA_AUTH_KEY_MGMT_NONE, WPA_SELECTOR_LEN) == 0) 1344 return WPA_KEY_MGMT_WPA_NONE_; 1345 return 0; 1346} 1347 1348int rsn_key_mgmt_to_bitfield(const unsigned char *s) 1349{ 1350 if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0) 1351 return WPA_KEY_MGMT_IEEE8021X2_; 1352 if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) == 1353 0) 1354 return WPA_KEY_MGMT_PSK2_; 1355 return 0; 1356} 1357 1358int wpa_selector_to_bitfield(const unsigned char *s) 1359{ 1360 if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0) 1361 return WPA_CIPHER_NONE_; 1362 if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0) 1363 return WPA_CIPHER_WEP40_; 1364 if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0) 1365 return WPA_CIPHER_TKIP_; 1366 if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0) 1367 return WPA_CIPHER_CCMP_; 1368 if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0) 1369 return WPA_CIPHER_WEP104_; 1370 return 0; 1371} 1372 1373int rsn_selector_to_bitfield(const unsigned char *s) 1374{ 1375 if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0) 1376 return WPA_CIPHER_NONE_; 1377 if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0) 1378 return WPA_CIPHER_WEP40_; 1379 if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0) 1380 return WPA_CIPHER_TKIP_; 1381 if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0) 1382 return WPA_CIPHER_CCMP_; 1383 if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0) 1384 return WPA_CIPHER_WEP104_; 1385 return 0; 1386} 1387 1388int wpa_parse_wpa_ie_wpa(const unsigned char *wpa_ie, size_t wpa_ie_len, struct wpa_ie_data *data) 1389{ 1390 const struct wpa_ie_hdr *hdr; 1391 const unsigned char *pos; 1392 int left; 1393 int i, count; 1394 1395 data->proto = WPA_PROTO_WPA_; 1396 data->pairwise_cipher = WPA_CIPHER_TKIP_; 1397 data->group_cipher = WPA_CIPHER_TKIP_; 1398 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X_; 1399 data->capabilities = 0; 1400 data->pmkid = NULL; 1401 data->num_pmkid = 0; 1402 1403 if (wpa_ie_len == 0) { 1404 /* No WPA IE - fail silently */ 1405 return -1; 1406 } 1407 1408 if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) { 1409// fprintf(stderr, "ie len too short %lu", (unsigned long) wpa_ie_len); 1410 return -1; 1411 } 1412 1413 hdr = (const struct wpa_ie_hdr *) wpa_ie; 1414 1415 if (hdr->elem_id != DOT11_MNG_WPA_ID || 1416 hdr->len != wpa_ie_len - 2 || 1417 memcmp(&hdr->oui, WPA_OUI_TYPE_ARR, WPA_SELECTOR_LEN) != 0 || 1418 WPA_GET_LE16(hdr->version) != WPA_VERSION_) { 1419// fprintf(stderr, "malformed ie or unknown version"); 1420 return -1; 1421 } 1422 1423 pos = (const unsigned char *) (hdr + 1); 1424 left = wpa_ie_len - sizeof(*hdr); 1425 1426 if (left >= WPA_SELECTOR_LEN) { 1427 data->group_cipher = wpa_selector_to_bitfield(pos); 1428 pos += WPA_SELECTOR_LEN; 1429 left -= WPA_SELECTOR_LEN; 1430 } else if (left > 0) { 1431// fprintf(stderr, "ie length mismatch, %u too much", left); 1432 return -1; 1433 } 1434 1435 if (left >= 2) { 1436 data->pairwise_cipher = 0; 1437 count = WPA_GET_LE16(pos); 1438 pos += 2; 1439 left -= 2; 1440 if (count == 0 || left < count * WPA_SELECTOR_LEN) { 1441// fprintf(stderr, "ie count botch (pairwise), " 1442// "count %u left %u", count, left); 1443 return -1; 1444 } 1445 for (i = 0; i < count; i++) { 1446 data->pairwise_cipher |= wpa_selector_to_bitfield(pos); 1447 pos += WPA_SELECTOR_LEN; 1448 left -= WPA_SELECTOR_LEN; 1449 } 1450 } else if (left == 1) { 1451// fprintf(stderr, "ie too short (for key mgmt)"); 1452 return -1; 1453 } 1454 1455 if (left >= 2) { 1456 data->key_mgmt = 0; 1457 count = WPA_GET_LE16(pos); 1458 pos += 2; 1459 left -= 2; 1460 if (count == 0 || left < count * WPA_SELECTOR_LEN) { 1461// fprintf(stderr, "ie count botch (key mgmt), " 1462// "count %u left %u", count, left); 1463 return -1; 1464 } 1465 for (i = 0; i < count; i++) { 1466 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); 1467 pos += WPA_SELECTOR_LEN; 1468 left -= WPA_SELECTOR_LEN; 1469 } 1470 } else if (left == 1) { 1471// fprintf(stderr, "ie too short (for capabilities)"); 1472 return -1; 1473 } 1474 1475 if (left >= 2) { 1476 data->capabilities = WPA_GET_LE16(pos); 1477 pos += 2; 1478 left -= 2; 1479 } 1480 1481 if (left > 0) { 1482// fprintf(stderr, "ie has %u trailing bytes", left); 1483 return -1; 1484 } 1485 1486 return 0; 1487} 1488 1489int wpa_parse_wpa_ie_rsn(const unsigned char *rsn_ie, size_t rsn_ie_len, struct wpa_ie_data *data) 1490{ 1491 const struct rsn_ie_hdr *hdr; 1492 const unsigned char *pos; 1493 int left; 1494 int i, count; 1495 1496 data->proto = WPA_PROTO_RSN_; 1497 data->pairwise_cipher = WPA_CIPHER_CCMP_; 1498 data->group_cipher = WPA_CIPHER_CCMP_; 1499 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X2_; 1500 data->capabilities = 0; 1501 data->pmkid = NULL; 1502 data->num_pmkid = 0; 1503 1504 if (rsn_ie_len == 0) { 1505 /* No RSN IE - fail silently */ 1506 return -1; 1507 } 1508 1509 if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) { 1510// fprintf(stderr, "ie len too short %lu", (unsigned long) rsn_ie_len); 1511 return -1; 1512 } 1513 1514 hdr = (const struct rsn_ie_hdr *) rsn_ie; 1515 1516 if (hdr->elem_id != DOT11_MNG_RSN_ID || 1517 hdr->len != rsn_ie_len - 2 || 1518 WPA_GET_LE16(hdr->version) != RSN_VERSION_) { 1519// fprintf(stderr, "malformed ie or unknown version"); 1520 return -1; 1521 } 1522 1523 pos = (const unsigned char *) (hdr + 1); 1524 left = rsn_ie_len - sizeof(*hdr); 1525 1526 if (left >= RSN_SELECTOR_LEN) { 1527 data->group_cipher = rsn_selector_to_bitfield(pos); 1528 pos += RSN_SELECTOR_LEN; 1529 left -= RSN_SELECTOR_LEN; 1530 } else if (left > 0) { 1531// fprintf(stderr, "ie length mismatch, %u too much", left); 1532 return -1; 1533 } 1534 1535 if (left >= 2) { 1536 data->pairwise_cipher = 0; 1537 count = WPA_GET_LE16(pos); 1538 pos += 2; 1539 left -= 2; 1540 if (count == 0 || left < count * RSN_SELECTOR_LEN) { 1541// fprintf(stderr, "ie count botch (pairwise), " 1542// "count %u left %u", count, left); 1543 return -1; 1544 } 1545 for (i = 0; i < count; i++) { 1546 data->pairwise_cipher |= rsn_selector_to_bitfield(pos); 1547 pos += RSN_SELECTOR_LEN; 1548 left -= RSN_SELECTOR_LEN; 1549 } 1550 } else if (left == 1) { 1551// fprintf(stderr, "ie too short (for key mgmt)"); 1552 return -1; 1553 } 1554 1555 if (left >= 2) { 1556 data->key_mgmt = 0; 1557 count = WPA_GET_LE16(pos); 1558 pos += 2; 1559 left -= 2; 1560 if (count == 0 || left < count * RSN_SELECTOR_LEN) { 1561// fprintf(stderr, "ie count botch (key mgmt), " 1562// "count %u left %u", count, left); 1563 return -1; 1564 } 1565 for (i = 0; i < count; i++) { 1566 data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos); 1567 pos += RSN_SELECTOR_LEN; 1568 left -= RSN_SELECTOR_LEN; 1569 } 1570 } else if (left == 1) { 1571// fprintf(stderr, "ie too short (for capabilities)"); 1572 return -1; 1573 } 1574 1575 if (left >= 2) { 1576 data->capabilities = WPA_GET_LE16(pos); 1577 pos += 2; 1578 left -= 2; 1579 } 1580 1581 if (left >= 2) { 1582 data->num_pmkid = WPA_GET_LE16(pos); 1583 pos += 2; 1584 left -= 2; 1585 if (left < data->num_pmkid * PMKID_LEN) { 1586// fprintf(stderr, "PMKID underflow " 1587// "(num_pmkid=%d left=%d)", data->num_pmkid, left); 1588 data->num_pmkid = 0; 1589 } else { 1590 data->pmkid = pos; 1591 pos += data->num_pmkid * PMKID_LEN; 1592 left -= data->num_pmkid * PMKID_LEN; 1593 } 1594 } 1595 1596 if (left > 0) { 1597// fprintf(stderr, "ie has %u trailing bytes - ignored", left); 1598 } 1599 1600 return 0; 1601} 1602 1603int wpa_parse_wpa_ie(const unsigned char *wpa_ie, size_t wpa_ie_len, 1604 struct wpa_ie_data *data) 1605{ 1606 if (wpa_ie_len >= 1 && wpa_ie[0] == DOT11_MNG_RSN_ID) 1607 return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); 1608 else 1609 return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); 1610} 1611 1612static const char * wpa_key_mgmt_txt(int key_mgmt, int proto) 1613{ 1614 switch (key_mgmt) { 1615 case WPA_KEY_MGMT_IEEE8021X_: 1616/* 1617 return proto == WPA_PROTO_RSN_ ? 1618 "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP"; 1619*/ 1620 return "WPA-Enterprise"; 1621 case WPA_KEY_MGMT_IEEE8021X2_: 1622 return "WPA2-Enterprise"; 1623 case WPA_KEY_MGMT_PSK_: 1624/* 1625 return proto == WPA_PROTO_RSN_ ? 1626 "WPA2-PSK" : "WPA-PSK"; 1627*/ 1628 return "WPA-Personal"; 1629 case WPA_KEY_MGMT_PSK2_: 1630 return "WPA2-Personal"; 1631 case WPA_KEY_MGMT_NONE_: 1632 return "NONE"; 1633 case WPA_KEY_MGMT_IEEE8021X_NO_WPA_: 1634// return "IEEE 802.1X (no WPA)"; 1635 return "IEEE 802.1X"; 1636 default: 1637 return "Unknown"; 1638 } 1639} 1640 1641static const char * wpa_cipher_txt(int cipher) 1642{ 1643 switch (cipher) { 1644 case WPA_CIPHER_NONE_: 1645 return "NONE"; 1646 case WPA_CIPHER_WEP40_: 1647 return "WEP-40"; 1648 case WPA_CIPHER_WEP104_: 1649 return "WEP-104"; 1650 case WPA_CIPHER_TKIP_: 1651 return "TKIP"; 1652 case WPA_CIPHER_CCMP_: 1653// return "CCMP"; 1654 return "AES"; 1655 case (WPA_CIPHER_TKIP_|WPA_CIPHER_CCMP_): 1656 return "TKIP+AES"; 1657 default: 1658 return "Unknown"; 1659 } 1660} 1661 1662static char scan_result[WLC_SCAN_RESULT_BUF_LEN]; 1663 1664int wlcscan_core(char *ofile, char *wif) 1665{ 1666 int ret, i, k, left, ht_extcha; 1667 int retval = 0, ap_count = 0, idx_same = -1, count = 0; 1668 unsigned char *bssidp; 1669 char *info_b; 1670 unsigned char rate; 1671 unsigned char bssid[6]; 1672 char macstr[18]; 1673 char ure_mac[18]; 1674 char ssid_str[256]; 1675 wl_scan_results_t *result; 1676 wl_bss_info_t *info; 1677 wl_bss_info_107_t *old_info; 1678 struct bss_ie_hdr *ie; 1679 NDIS_802_11_NETWORK_TYPE NetWorkType; 1680 struct maclist *authorized; 1681 int maclist_size; 1682 int max_sta_count = 128; 1683 int wl_authorized = 0; 1684 wl_scan_params_t *params; 1685 int params_size = WL_SCAN_PARAMS_FIXED_SIZE + NUMCHANS * sizeof(uint16); 1686 FILE *fp; 1687 int org_scan_time = 20, scan_time = 40; 1688 int wait_time = 3; 1689 1690 params = (wl_scan_params_t*)malloc(params_size); 1691 if (params == NULL) 1692 return retval; 1693 1694 memset(params, 0, params_size); 1695 params->bss_type = DOT11_BSSTYPE_INFRASTRUCTURE; 1696 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); 1697 params->scan_type = -1; 1698 params->nprobes = -1; 1699 params->active_time = -1; 1700 params->passive_time = -1; 1701 params->home_time = -1; 1702#if defined(RTAC88U) || defined(RTAC3100) || defined(RTAC5300) || defined(RTAC5300R) 1703 int band = WLC_BAND_ALL; 1704 wl_ioctl(wif, WLC_GET_BAND, &band, sizeof(band)); 1705 if (band == WLC_BAND_5G) 1706 { 1707 if (wl_subband(wif, nvram_get_int("wlcscan_idx")+1) == 1) 1708 { 1709 params->channel_num = 4; 1710 params->channel_list[0] = 36; 1711 params->channel_list[1] = 40; 1712 params->channel_list[2] = 44; 1713 params->channel_list[3] = 48; 1714 } 1715 else if (wl_subband(wif, nvram_get_int("wlcscan_idx")+1) == 2) 1716 { 1717 params->channel_num = 4; 1718 params->channel_list[0] = 52; 1719 params->channel_list[1] = 56; 1720 params->channel_list[2] = 60; 1721 params->channel_list[3] = 64; 1722 } 1723 else if (wl_subband(wif, nvram_get_int("wlcscan_idx")+1) == 3) 1724 { 1725 if (wl_channel_valid(wif, 120)) 1726 { 1727 params->channel_num = 11; 1728 params->channel_list[0] = 100; 1729 params->channel_list[1] = 104; 1730 params->channel_list[2] = 108; 1731 params->channel_list[3] = 112; 1732 params->channel_list[4] = 116; 1733 params->channel_list[5] = 120; 1734 params->channel_list[6] = 124; 1735 params->channel_list[7] = 128; 1736 params->channel_list[8] = 132; 1737 params->channel_list[9] = 136; 1738 params->channel_list[10] = 140; 1739 } 1740 else 1741 { 1742 params->channel_num = 8; 1743 params->channel_list[0] = 100; 1744 params->channel_list[1] = 104; 1745 params->channel_list[2] = 108; 1746 params->channel_list[3] = 112; 1747 params->channel_list[4] = 116; 1748 params->channel_list[5] = 132; 1749 params->channel_list[6] = 136; 1750 params->channel_list[7] = 140; 1751 } 1752 } 1753 else if (wl_subband(wif, nvram_get_int("wlcscan_idx")+1) == 4) 1754 { 1755 params->channel_num = 5; 1756 params->channel_list[0] = 165; 1757 params->channel_list[1] = 161; 1758 params->channel_list[2] = 157; 1759 params->channel_list[3] = 153; 1760 params->channel_list[4] = 149; 1761 } 1762 else 1763 { 1764 free(params); 1765 return retval; 1766 } 1767 } 1768 else 1769 { 1770 if (nvram_get_int("wlcscan_idx") == 0) 1771 { 1772 params->channel_num = 6; 1773 params->channel_list[0] = 1; 1774 params->channel_list[1] = 2; 1775 params->channel_list[2] = 3; 1776 params->channel_list[3] = 4; 1777 params->channel_list[4] = 5; 1778 params->channel_list[5] = 6; 1779 } 1780 else if (nvram_get_int("wlcscan_idx") == 1) 1781 { 1782 if (wl_channel_valid(wif, 13)) 1783 { 1784 params->channel_num = 7; 1785 params->channel_list[0] = 7; 1786 params->channel_list[1] = 8; 1787 params->channel_list[2] = 9; 1788 params->channel_list[3] = 10; 1789 params->channel_list[4] = 11; 1790 params->channel_list[5] = 12; 1791 params->channel_list[6] = 13; 1792 } 1793 else 1794 { 1795 params->channel_num = 5; 1796 params->channel_list[0] = 7; 1797 params->channel_list[1] = 8; 1798 params->channel_list[2] = 9; 1799 params->channel_list[3] = 10; 1800 params->channel_list[4] = 11; 1801 } 1802 } 1803 else 1804 { 1805 free(params); 1806 return retval; 1807 } 1808 } 1809#else 1810 params->channel_num = 0; 1811#endif 1812 1813 /* extend scan channel time to get more AP probe resp */ 1814 wl_ioctl(wif, WLC_GET_SCAN_CHANNEL_TIME, &org_scan_time, sizeof(org_scan_time)); 1815 if (org_scan_time < scan_time) 1816 wl_ioctl(wif, WLC_SET_SCAN_CHANNEL_TIME, &scan_time, sizeof(scan_time)); 1817 1818 while ((ret = wl_ioctl(wif, WLC_SCAN, params, params_size)) < 0 && 1819 count++ < 2) { 1820 dbg("[rc] set scan command failed, retry %d\n", count); 1821 sleep(1); 1822 } 1823 1824 free(params); 1825 1826 /* restore original scan channel time */ 1827 wl_ioctl(wif, WLC_SET_SCAN_CHANNEL_TIME, &org_scan_time, sizeof(org_scan_time)); 1828 1829#if defined(RTAC88U) || defined(RTAC3100) || defined(RTAC5300) || defined(RTAC5300R) 1830 wait_time = 2; 1831#endif 1832 dbg("[rc] Please wait %d seconds ", wait_time); 1833 do { 1834 sleep(1); 1835 dbg("."); 1836 } while (--wait_time > 0); 1837 dbg("\n\n"); 1838 1839 if (ret == 0) { 1840 result = (wl_scan_results_t *)scan_result; 1841 result->buflen = htod32(WLC_SCAN_RESULT_BUF_LEN); 1842 1843 while ((ret = wl_ioctl(wif, WLC_SCAN_RESULTS, result, WLC_SCAN_RESULT_BUF_LEN)) < 0 && count++ < 2) 1844 { 1845 dbg("[rc] set scan results command failed, retry %d\n", count); 1846 sleep(1); 1847 } 1848 1849 if (ret == 0) 1850 { 1851 info = &(result->bss_info[0]); 1852 1853 /* Convert version 107 to 109 */ 1854 if (dtoh32(info->version) == LEGACY_WL_BSS_INFO_VERSION) { 1855 old_info = (wl_bss_info_107_t *)info; 1856 info->chanspec = CH20MHZ_CHSPEC(old_info->channel); 1857 info->ie_length = old_info->ie_length; 1858 info->ie_offset = sizeof(wl_bss_info_107_t); 1859 } 1860 1861 info_b = (char *) info; 1862 1863 for (i = 0; i < result->count; i++) 1864 { 1865 if (info->SSID_len > 32/* || info->SSID_len == 0*/) 1866 goto next_info; 1867 bssidp = (unsigned char *)&info->BSSID; 1868 sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X", 1869 (unsigned char)bssidp[0], 1870 (unsigned char)bssidp[1], 1871 (unsigned char)bssidp[2], 1872 (unsigned char)bssidp[3], 1873 (unsigned char)bssidp[4], 1874 (unsigned char)bssidp[5]); 1875 1876 idx_same = -1; 1877 for (k = 0; k < ap_count; k++) { 1878 /* deal with old version of Broadcom Multiple SSID 1879 (share the same BSSID) */ 1880 if (strcmp(apinfos[k].BSSID, macstr) == 0 && 1881 strcmp(apinfos[k].SSID, (const char *) info->SSID) == 0) { 1882 idx_same = k; 1883 break; 1884 } 1885 } 1886 1887 if (idx_same != -1) 1888 { 1889 if (info->RSSI >= -50) 1890 apinfos[idx_same].RSSI_Quality = 100; 1891 else if (info->RSSI >= -80) // between -50 ~ -80dbm 1892 apinfos[idx_same].RSSI_Quality = (int)(24 + ((info->RSSI + 80) * 26)/10); 1893 else if (info->RSSI >= -90) // between -80 ~ -90dbm 1894 apinfos[idx_same].RSSI_Quality = (int)(((info->RSSI + 90) * 26)/10); 1895 else // < -84 dbm 1896 apinfos[idx_same].RSSI_Quality = 0; 1897 } 1898 else 1899 { 1900 strcpy(apinfos[ap_count].BSSID, macstr); 1901// strcpy(apinfos[ap_count].SSID, info->SSID); 1902 memset(apinfos[ap_count].SSID, 0x0, 33); 1903 memcpy(apinfos[ap_count].SSID, info->SSID, info->SSID_len); 1904 apinfos[ap_count].channel = (uint8)(info->chanspec & WL_CHANSPEC_CHAN_MASK); 1905 if (info->ctl_ch == 0) 1906 { 1907 apinfos[ap_count].ctl_ch = apinfos[ap_count].channel; 1908 } else 1909 { 1910 apinfos[ap_count].ctl_ch = info->ctl_ch; 1911 } 1912 1913 if (info->RSSI >= -50) 1914 apinfos[ap_count].RSSI_Quality = 100; 1915 else if (info->RSSI >= -80) // between -50 ~ -80dbm 1916 apinfos[ap_count].RSSI_Quality = (int)(24 + ((info->RSSI + 80) * 26)/10); 1917 else if (info->RSSI >= -90) // between -80 ~ -90dbm 1918 apinfos[ap_count].RSSI_Quality = (int)(((info->RSSI + 90) * 26)/10); 1919 else // < -84 dbm 1920 apinfos[ap_count].RSSI_Quality = 0; 1921 1922 if ((info->capability & 0x10) == 0x10) 1923 apinfos[ap_count].wep = 1; 1924 else 1925 apinfos[ap_count].wep = 0; 1926 apinfos[ap_count].wpa = 0; 1927 1928/* 1929 unsigned char *RATESET = &info->rateset; 1930 for (k = 0; k < 18; k++) 1931 dbg("%02x ", (unsigned char)RATESET[k]); 1932 dbg("\n"); 1933*/ 1934 1935 NetWorkType = Ndis802_11DS; 1936 if ((uint8)(info->chanspec & WL_CHANSPEC_CHAN_MASK) <= 14) 1937 { 1938 for (k = 0; k < info->rateset.count; k++) 1939 { 1940 rate = info->rateset.rates[k] & 0x7f; // Mask out basic rate set bit 1941 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) 1942 continue; 1943 else 1944 { 1945 NetWorkType = Ndis802_11OFDM24; 1946 break; 1947 } 1948 } 1949 } 1950 else 1951 NetWorkType = Ndis802_11OFDM5; 1952 1953 if (info->n_cap) 1954 { 1955 if (NetWorkType == Ndis802_11OFDM5) 1956 { 1957#ifdef RTCONFIG_BCMWL6 1958 if (info->vht_cap) 1959 NetWorkType = Ndis802_11OFDM5_VHT; 1960 else 1961#endif 1962 NetWorkType = Ndis802_11OFDM5_N; 1963 } 1964 else 1965 NetWorkType = Ndis802_11OFDM24_N; 1966 } 1967 1968 apinfos[ap_count].NetworkType = NetWorkType; 1969 1970 ap_count++; 1971 1972 if (ap_count >= MAX_NUMBER_OF_APINFO) 1973 break; 1974 } 1975 1976 ie = (struct bss_ie_hdr *) ((unsigned char *) info + sizeof(*info)); 1977 for (left = info->ie_length; left > 0; // look for RSN IE first 1978 left -= (ie->len + 2), ie = (struct bss_ie_hdr *) ((unsigned char *) ie + 2 + ie->len)) 1979 { 1980 if (ie->elem_id != DOT11_MNG_RSN_ID) 1981 continue; 1982 1983 if (wpa_parse_wpa_ie(&ie->elem_id, ie->len + 2, &apinfos[ap_count - 1].wid) == 0) 1984 { 1985 apinfos[ap_count-1].wpa = 1; 1986 goto next_info; 1987 } 1988 } 1989 1990 ie = (struct bss_ie_hdr *) ((unsigned char *) info + sizeof(*info)); 1991 for (left = info->ie_length; left > 0; // then look for WPA IE 1992 left -= (ie->len + 2), ie = (struct bss_ie_hdr *) ((unsigned char *) ie + 2 + ie->len)) 1993 { 1994 if (ie->elem_id != DOT11_MNG_WPA_ID) 1995 continue; 1996 1997 if (wpa_parse_wpa_ie(&ie->elem_id, ie->len + 2, &apinfos[ap_count-1].wid) == 0) 1998 { 1999 apinfos[ap_count-1].wpa = 1; 2000 break; 2001 } 2002 } 2003 2004next_info: 2005 info = (wl_bss_info_t *) ((unsigned char *) info + info->length); 2006 } 2007 } 2008 } 2009 2010 /* Print scanning result to console */ 2011 if (ap_count == 0) { 2012 dbg("[wlc] No AP found!\n"); 2013 } else { 2014 printf("%-4s%4s%-33s%-18s%-9s%-16s%-9s%8s%3s%3s\n", 2015 "idx", "CH ", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", "CC", "EC"); 2016 for (k = 0; k < ap_count; k++) 2017 { 2018 printf("%2d. ", k + 1); 2019 printf("%3d ", apinfos[k].ctl_ch); 2020 printf("%-33s", apinfos[k].SSID); 2021 printf("%-18s", apinfos[k].BSSID); 2022 2023 if (apinfos[k].wpa == 1) 2024 printf("%-9s%-16s", wpa_cipher_txt(apinfos[k].wid.pairwise_cipher), wpa_key_mgmt_txt(apinfos[k].wid.key_mgmt, apinfos[k].wid.proto)); 2025 else if (apinfos[k].wep == 1) 2026 printf("WEP Unknown "); 2027 else 2028 printf("NONE Open System "); 2029 printf("%9d ", apinfos[k].RSSI_Quality); 2030 2031 if (apinfos[k].NetworkType == Ndis802_11FH || apinfos[k].NetworkType == Ndis802_11DS) 2032 printf("%-7s", "11b"); 2033 else if (apinfos[k].NetworkType == Ndis802_11OFDM5) 2034 printf("%-7s", "11a"); 2035 else if (apinfos[k].NetworkType == Ndis802_11OFDM5_VHT) 2036 printf("%-7s", "11ac"); 2037 else if (apinfos[k].NetworkType == Ndis802_11OFDM5_N) 2038 printf("%-7s", "11a/n"); 2039 else if (apinfos[k].NetworkType == Ndis802_11OFDM24) 2040 printf("%-7s", "11b/g"); 2041 else if (apinfos[k].NetworkType == Ndis802_11OFDM24_N) 2042 printf("%-7s", "11b/g/n"); 2043 else 2044 printf("%-7s", "unknown"); 2045 2046 printf("%3d", apinfos[k].ctl_ch); 2047 2048 if ( ((apinfos[k].NetworkType == Ndis802_11OFDM5_VHT) || 2049 (apinfos[k].NetworkType == Ndis802_11OFDM5_N) || 2050 (apinfos[k].NetworkType == Ndis802_11OFDM24_N)) && 2051 (apinfos[k].channel != apinfos[k].ctl_ch)) { 2052 if (apinfos[k].ctl_ch < apinfos[k].channel) 2053 ht_extcha = 1; 2054 else 2055 ht_extcha = 0; 2056 2057 printf("%3d", ht_extcha); 2058 } 2059 2060 printf("\n"); 2061 } 2062 } 2063 2064 ret = wl_ioctl(wif, WLC_GET_BSSID, bssid, sizeof(bssid)); 2065 memset(ure_mac, 0x0, 18); 2066 if (!ret) { 2067 if (!(!bssid[0] && !bssid[1] && !bssid[2] && !bssid[3] && !bssid[4] && !bssid[5])) { 2068 sprintf(ure_mac, "%02X:%02X:%02X:%02X:%02X:%02X", 2069 (unsigned char)bssid[0], 2070 (unsigned char)bssid[1], 2071 (unsigned char)bssid[2], 2072 (unsigned char)bssid[3], 2073 (unsigned char)bssid[4], 2074 (unsigned char)bssid[5]); 2075 } 2076 } 2077 2078 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2079 maclist_size = sizeof(authorized->count) + max_sta_count * sizeof(struct ether_addr); 2080 authorized = malloc(maclist_size); 2081 2082 // query wl for authorized sta list 2083 strcpy((char*)authorized, "autho_sta_list"); 2084 if (!wl_ioctl(wif, WLC_GET_VAR, authorized, maclist_size)) { 2085 if (authorized->count > 0) wl_authorized = 1; 2086 } 2087 2088 if (authorized) free(authorized); 2089 } 2090 2091 /* Print scanning result to web format */ 2092 if (ap_count > 0) { 2093 /* write pid */ 2094 if ((fp = fopen(ofile, "a")) == NULL) { 2095 printf("[wlcscan] Output %s error\n", ofile); 2096 } else { 2097#if defined(RTAC3200) || defined(RTAC5300) || defined(RTAC5300R) 2098 int unit = 0; 2099 char prefix[] = "wlXXXXXXXXXX_", tmp[100]; 2100 wl_ioctl(wif, WLC_GET_INSTANCE, &unit, sizeof(unit)); 2101 snprintf(prefix, sizeof(prefix), "wl%d_", unit); 2102#endif 2103 for (i = 0; i < ap_count; i++) { 2104#if defined(RTAC3200) || defined(RTAC5300) || defined(RTAC5300R) 2105 if (!strcmp(wif, "eth1") && (apinfos[i].ctl_ch > 48)) 2106 continue; 2107 if (!strcmp(wif, "eth3")) { 2108 if (nvram_match(strcat_r(prefix, "country_code", tmp), "E0") || 2109 nvram_match(strcat_r(prefix, "country_code", tmp), "JP")) { 2110 if (apinfos[i].ctl_ch < 100) 2111 continue; 2112 } else { 2113 if (apinfos[i].ctl_ch < 149) 2114 continue; 2115 } 2116 } 2117#endif 2118 /*if (apinfos[i].ctl_ch < 0 ) { 2119 fprintf(fp, "\"ERR_BNAD\","); 2120 } else */if (apinfos[i].ctl_ch > 0 && 2121 apinfos[i].ctl_ch < 14) { 2122 fprintf(fp, "\"2G\","); 2123 } else if (apinfos[i].ctl_ch > 14 && 2124 apinfos[i].ctl_ch < 166) { 2125 fprintf(fp, "\"5G\","); 2126 } else { 2127 fprintf(fp, "\"ERR_BNAD\","); 2128 } 2129 2130 if (strlen(apinfos[i].SSID) == 0) { 2131 fprintf(fp, "\"\","); 2132 } else { 2133 memset(ssid_str, 0, sizeof(ssid_str)); 2134 char_to_ascii(ssid_str, apinfos[i].SSID); 2135 fprintf(fp, "\"%s\",", ssid_str); 2136 } 2137 2138 fprintf(fp, "\"%d\",", apinfos[i].ctl_ch); 2139 2140 if (apinfos[i].wpa == 1) { 2141 if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X_) 2142 fprintf(fp, "\"%s\",", "WPA-Enterprise"); 2143 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X2_) 2144 fprintf(fp, "\"%s\",", "WPA2-Enterprise"); 2145 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_PSK_) 2146 fprintf(fp, "\"%s\",", "WPA-Personal"); 2147 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_PSK2_) 2148 fprintf(fp, "\"%s\",", "WPA2-Personal"); 2149 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_NONE_) 2150 fprintf(fp, "\"%s\",", "NONE"); 2151 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA_) 2152 fprintf(fp, "\"%s\",", "IEEE 802.1X"); 2153 else 2154 fprintf(fp, "\"%s\",", "Unknown"); 2155 } else if (apinfos[i].wep == 1) { 2156 fprintf(fp, "\"%s\",", "Unknown"); 2157 } else { 2158 fprintf(fp, "\"%s\",", "Open System"); 2159 } 2160 2161 if (apinfos[i].wpa == 1) { 2162 if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_NONE_) 2163 fprintf(fp, "\"%s\",", "NONE"); 2164 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_WEP40_) 2165 fprintf(fp, "\"%s\",", "WEP"); 2166 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_WEP104_) 2167 fprintf(fp, "\"%s\",", "WEP"); 2168 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_TKIP_) 2169 fprintf(fp, "\"%s\",", "TKIP"); 2170 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_CCMP_) 2171 fprintf(fp, "\"%s\",", "AES"); 2172 else if (apinfos[i].wid.pairwise_cipher == (WPA_CIPHER_TKIP_|WPA_CIPHER_CCMP_)) 2173 fprintf(fp, "\"%s\",", "TKIP+AES"); 2174 else 2175 fprintf(fp, "\"%s\",", "Unknown"); 2176 } else if (apinfos[i].wep == 1) { 2177 fprintf(fp, "\"%s\",", "WEP"); 2178 } else { 2179 fprintf(fp, "\"%s\",", "NONE"); 2180 } 2181 2182 fprintf(fp, "\"%d\",", apinfos[i].RSSI_Quality); 2183 fprintf(fp, "\"%s\",", apinfos[i].BSSID); 2184 2185 if (apinfos[i].NetworkType == Ndis802_11FH || apinfos[i].NetworkType == Ndis802_11DS) 2186 fprintf(fp, "\"%s\",", "b"); 2187 else if (apinfos[i].NetworkType == Ndis802_11OFDM5) 2188 fprintf(fp, "\"%s\",", "a"); 2189 else if (apinfos[i].NetworkType == Ndis802_11OFDM5_N) 2190 fprintf(fp, "\"%s\",", "an"); 2191 else if (apinfos[i].NetworkType == Ndis802_11OFDM5_VHT) 2192 fprintf(fp, "\"%s\",", "ac"); 2193 else if (apinfos[i].NetworkType == Ndis802_11OFDM24) 2194 fprintf(fp, "\"%s\",", "bg"); 2195 else if (apinfos[i].NetworkType == Ndis802_11OFDM24_N) 2196 fprintf(fp, "\"%s\",", "bgn"); 2197 else 2198 fprintf(fp, "\"%s\",", ""); 2199 2200 if (strcmp(nvram_safe_get(wlc_nvname("ssid")), apinfos[i].SSID)) { 2201 if (strcmp(apinfos[i].SSID, "")) 2202 fprintf(fp, "\"%s\"", "0"); // none 2203 else if (!strcmp(ure_mac, apinfos[i].BSSID)) { 2204 // hidden AP (null SSID) 2205 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2206 if (wl_authorized) { 2207 // in profile, connected 2208 fprintf(fp, "\"%s\"", "4"); 2209 } else { 2210 // in profile, connecting 2211 fprintf(fp, "\"%s\"", "5"); 2212 } 2213 } else { 2214 // in profile, connected 2215 fprintf(fp, "\"%s\"", "4"); 2216 } 2217 } else { 2218 // hidden AP (null SSID) 2219 fprintf(fp, "\"%s\"", "0"); // none 2220 } 2221 } else if (!strcmp(nvram_safe_get(wlc_nvname("ssid")), apinfos[i].SSID)) { 2222 if (!strlen(ure_mac)) { 2223 // in profile, disconnected 2224 fprintf(fp, "\"%s\",", "1"); 2225 } else if (!strcmp(ure_mac, apinfos[i].BSSID)) { 2226 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2227 if (wl_authorized) { 2228 // in profile, connected 2229 fprintf(fp, "\"%s\"", "2"); 2230 } else { 2231 // in profile, connecting 2232 fprintf(fp, "\"%s\"", "3"); 2233 } 2234 } else { 2235 // in profile, connected 2236 fprintf(fp, "\"%s\"", "2"); 2237 } 2238 } else { 2239 fprintf(fp, "\"%s\"", "0"); // impossible... 2240 } 2241 } else { 2242 // wl0_ssid is empty 2243 fprintf(fp, "\"%s\"", "0"); 2244 } 2245 2246 if (i == ap_count - 1) { 2247 fprintf(fp, "\n"); 2248 } else { 2249 fprintf(fp, "\n"); 2250 } 2251 } /* for */ 2252 fclose(fp); 2253 } 2254 } /* if */ 2255 2256 return retval; 2257} 2258 2259#ifdef RTCONFIG_BCM_7114 2260 2261typedef struct escan_wksp_s { 2262 uint8 packet[4096]; 2263 int event_fd; 2264} escan_wksp_t; 2265 2266static escan_wksp_t *d_info; 2267 2268/* open a UDP packet to event dispatcher for receiving/sending data */ 2269static int 2270escan_open_eventfd() 2271{ 2272 int reuse = 1; 2273 struct sockaddr_in sockaddr; 2274 int fd = -1; 2275 2276 d_info->event_fd = -1; 2277 2278 /* open loopback socket to communicate with event dispatcher */ 2279 memset(&sockaddr, 0, sizeof(sockaddr)); 2280 sockaddr.sin_family = AF_INET; 2281 sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 2282 sockaddr.sin_port = htons(EAPD_WKSP_DCS_UDP_SPORT); 2283 2284 if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 2285 dbg("Unable to create loopback socket\n"); 2286 goto exit; 2287 } 2288 2289 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0) { 2290 dbg("Unable to setsockopt to loopback socket %d.\n", fd); 2291 goto exit; 2292 } 2293 2294 if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) { 2295 dbg("Unable to bind to loopback socket %d\n", fd); 2296 goto exit; 2297 } 2298 2299 d_info->event_fd = fd; 2300 2301 return 0; 2302 2303 /* error handling */ 2304exit: 2305 if (fd != -1) { 2306 close(fd); 2307 } 2308 2309 return errno; 2310} 2311 2312static bool escan_swap = FALSE; 2313#define htod16(i) (escan_swap?bcmswap16(i):(uint16)(i)) 2314#define WL_EVENT_TIMEOUT 10 2315 2316struct escan_bss { 2317 struct escan_bss *next; 2318 wl_bss_info_t bss[1]; 2319}; 2320#define ESCAN_BSS_FIXED_SIZE 4 2321 2322/* listen to sockets and receive escan results */ 2323static int 2324get_scan_escan(char *scan_buf, uint buf_len) 2325{ 2326 fd_set fdset; 2327 int fd; 2328 struct timeval tv; 2329 uint8 *pkt; 2330 int len; 2331 int retval; 2332 wl_escan_result_t *escan_data; 2333 struct escan_bss *escan_bss_head = NULL; 2334 struct escan_bss *escan_bss_tail = NULL; 2335 struct escan_bss *result; 2336 2337 d_info = (escan_wksp_t*)malloc(sizeof(escan_wksp_t)); 2338 2339 escan_open_eventfd(); 2340 2341 if (d_info->event_fd == -1) { 2342 return -1; 2343 } 2344 2345 fd = d_info->event_fd; 2346 2347 FD_ZERO(&fdset); 2348 FD_SET(fd, &fdset); 2349 2350 pkt = d_info->packet; 2351 len = sizeof(d_info->packet); 2352 2353 tv.tv_sec = WL_EVENT_TIMEOUT; 2354 tv.tv_usec = 0; 2355 2356 /* listen to data availible on all sockets */ 2357 while ((retval = select(fd+1, &fdset, NULL, NULL, &tv)) > 0) { 2358 bcm_event_t *pvt_data; 2359 uint32 evt_type; 2360 uint32 status; 2361 2362 if (recv(fd, pkt, len, 0) <= 0) 2363 continue; 2364 2365 pvt_data = (bcm_event_t *)(pkt + IFNAMSIZ); 2366 evt_type = ntoh32(pvt_data->event.event_type); 2367 2368 if (evt_type == WLC_E_ESCAN_RESULT) { 2369 escan_data = (wl_escan_result_t*)(pvt_data + 1); 2370 status = ntoh32(pvt_data->event.status); 2371 2372 if (status == WLC_E_STATUS_PARTIAL) { 2373 wl_bss_info_t *bi = &escan_data->bss_info[0]; 2374 wl_bss_info_t *bss = NULL; 2375 2376 /* check if we've received info of same BSSID */ 2377 for (result = escan_bss_head; result; result = result->next) { 2378 bss = result->bss; 2379 2380 if (!memcmp(bi->BSSID.octet, bss->BSSID.octet, 2381 ETHER_ADDR_LEN) && 2382 CHSPEC_BAND(bi->chanspec) == 2383 CHSPEC_BAND(bss->chanspec) && 2384 bi->SSID_len == bss->SSID_len && 2385 !memcmp(bi->SSID, bss->SSID, bi->SSID_len)) 2386 break; 2387 } 2388 2389 if (!result) { 2390 /* New BSS. Allocate memory and save it */ 2391 struct escan_bss *ebss = (struct escan_bss *)malloc( 2392 OFFSETOF(struct escan_bss, bss) + bi->length); 2393 2394 if (!ebss) { 2395 dbg("can't allocate memory for bss"); 2396 goto exit; 2397 } 2398 2399 ebss->next = NULL; 2400 memcpy(&ebss->bss, bi, bi->length); 2401 if (escan_bss_tail) { 2402 escan_bss_tail->next = ebss; 2403 } 2404 else { 2405 escan_bss_head = ebss; 2406 } 2407 escan_bss_tail = ebss; 2408 } 2409 else if (bi->RSSI != WLC_RSSI_INVALID) { 2410 /* We've got this BSS. Update rssi if necessary */ 2411 if (((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == 2412 (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL)) && 2413 ((bss->RSSI == WLC_RSSI_INVALID) || 2414 (bss->RSSI < bi->RSSI))) { 2415 /* preserve max RSSI if the measurements are 2416 * both on-channel or both off-channel 2417 */ 2418 bss->RSSI = bi->RSSI; 2419 bss->SNR = bi->SNR; 2420 bss->phy_noise = bi->phy_noise; 2421 } else if ((bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) && 2422 (bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == 0) { 2423 /* preserve the on-channel rssi measurement 2424 * if the new measurement is off channel 2425 */ 2426 bss->RSSI = bi->RSSI; 2427 bss->SNR = bi->SNR; 2428 bss->phy_noise = bi->phy_noise; 2429 bss->flags |= WL_BSS_FLAGS_RSSI_ONCHANNEL; 2430 } 2431 } 2432 } 2433 else if (status == WLC_E_STATUS_SUCCESS) { 2434 /* Escan finished. Let's go dump the results. */ 2435 break; 2436 } 2437 else { 2438 dbg("sync_id: %d, status:%d, misc. error/abort\n", 2439 escan_data->sync_id, status); 2440 goto exit; 2441 } 2442 } 2443 } 2444 2445 if (retval > 0) { 2446 wl_scan_results_t* s_result = (wl_scan_results_t*)scan_buf; 2447 wl_bss_info_t *bi = s_result->bss_info; 2448 wl_bss_info_t *bss; 2449 2450 s_result->count = 0; 2451 len = buf_len - WL_SCAN_RESULTS_FIXED_SIZE; 2452 2453 for (result = escan_bss_head; result; result = result->next) { 2454 bss = result->bss; 2455 if (buf_len < bss->length) { 2456 dbg("Memory not enough for scan results\n"); 2457 break; 2458 } 2459 memcpy(bi, bss, bss->length); 2460 bi = (wl_bss_info_t*)((int8*)bi + bss->length); 2461 len -= bss->length; 2462 s_result->count++; 2463 } 2464 } else if (retval == 0) { 2465 dbg("Scan timeout!\n"); 2466 } else { 2467 dbg("Receive scan results failed!\n"); 2468 } 2469 2470exit: 2471 if (d_info) { 2472 if (d_info->event_fd != -1) { 2473 close(d_info->event_fd); 2474 d_info->event_fd = -1; 2475 } 2476 2477 free(d_info); 2478 } 2479 2480 /* free scan results */ 2481 result = escan_bss_head; 2482 while (result) { 2483 struct escan_bss *tmp = result->next; 2484 free(result); 2485 result = tmp; 2486 } 2487 2488 return (retval > 0) ? BCME_OK : BCME_ERROR; 2489} 2490 2491int wlcscan_core_escan(char *ofile, char *wif) 2492{ 2493 int ret, i, k, left, ht_extcha; 2494 int retval = 0, ap_count = 0, idx_same = -1, count = 0; 2495 unsigned char *bssidp; 2496 char *info_b; 2497 unsigned char rate; 2498 unsigned char bssid[6]; 2499 char macstr[18]; 2500 char ure_mac[18]; 2501 char ssid_str[256]; 2502 wl_scan_results_t *result; 2503 wl_bss_info_t *info; 2504 wl_bss_info_107_t *old_info; 2505 struct bss_ie_hdr *ie; 2506 NDIS_802_11_NETWORK_TYPE NetWorkType; 2507 struct maclist *authorized; 2508 int maclist_size; 2509 int max_sta_count = 128; 2510 int wl_authorized = 0; 2511 wl_escan_params_t *params = NULL; 2512 int params_size = WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params) + NUMCHANS * sizeof(uint16); 2513 FILE *fp; 2514 int org_scan_time = 20, scan_time = 40; 2515 2516 params = (wl_escan_params_t*)malloc(params_size); 2517 if (params == NULL) 2518 return retval; 2519 2520 memset(params, 0, params_size); 2521 params->params.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE; 2522 memcpy(¶ms->params.bssid, ðer_bcast, ETHER_ADDR_LEN); 2523 params->params.scan_type = -1; 2524 params->params.nprobes = -1; 2525 params->params.active_time = -1; 2526 params->params.passive_time = -1; 2527 params->params.home_time = -1; 2528 params->params.channel_num = 0; 2529 2530 params->version = htod32(ESCAN_REQ_VERSION); 2531 params->action = htod16(WL_SCAN_ACTION_START); 2532 2533 srand((unsigned int)uptime()); 2534 params->sync_id = htod16(rand() & 0xffff); 2535 2536 params_size += OFFSETOF(wl_escan_params_t, params); 2537 2538 /* extend scan channel time to get more AP probe resp */ 2539 wl_ioctl(wif, WLC_GET_SCAN_CHANNEL_TIME, &org_scan_time, sizeof(org_scan_time)); 2540 if (org_scan_time < scan_time) 2541 wl_ioctl(wif, WLC_SET_SCAN_CHANNEL_TIME, &scan_time, sizeof(scan_time)); 2542 2543 while ((ret = wl_iovar_set(wif, "escan", params, params_size)) < 0 && 2544 count++ < 2) { 2545 dbg("[rc] set escan command failed, retry %d\n", count); 2546 sleep(1); 2547 } 2548 2549 free(params); 2550 2551 /* restore original scan channel time */ 2552 wl_ioctl(wif, WLC_SET_SCAN_CHANNEL_TIME, &org_scan_time, sizeof(org_scan_time)); 2553 2554 if (ret == 0) { 2555 ret = get_scan_escan(scan_result, WLC_SCAN_RESULT_BUF_LEN); 2556 2557 if (ret == 0) 2558 { 2559 result = (wl_scan_results_t *)scan_result; 2560 2561 info = &(result->bss_info[0]); 2562 2563 /* Convert version 107 to 109 */ 2564 if (dtoh32(info->version) == LEGACY_WL_BSS_INFO_VERSION) { 2565 old_info = (wl_bss_info_107_t *)info; 2566 info->chanspec = CH20MHZ_CHSPEC(old_info->channel); 2567 info->ie_length = old_info->ie_length; 2568 info->ie_offset = sizeof(wl_bss_info_107_t); 2569 } 2570 2571 info_b = (char *) info; 2572 2573 for (i = 0; i < result->count; i++) 2574 { 2575 if (info->SSID_len > 32/* || info->SSID_len == 0*/) 2576 goto next_info; 2577 bssidp = (unsigned char *)&info->BSSID; 2578 sprintf(macstr, "%02X:%02X:%02X:%02X:%02X:%02X", 2579 (unsigned char)bssidp[0], 2580 (unsigned char)bssidp[1], 2581 (unsigned char)bssidp[2], 2582 (unsigned char)bssidp[3], 2583 (unsigned char)bssidp[4], 2584 (unsigned char)bssidp[5]); 2585 2586 idx_same = -1; 2587 for (k = 0; k < ap_count; k++) { 2588 /* deal with old version of Broadcom Multiple SSID 2589 (share the same BSSID) */ 2590 if (strcmp(apinfos[k].BSSID, macstr) == 0 && 2591 strcmp(apinfos[k].SSID, (const char *) info->SSID) == 0) { 2592 idx_same = k; 2593 break; 2594 } 2595 } 2596 2597 if (idx_same != -1) 2598 { 2599 if (info->RSSI >= -50) 2600 apinfos[idx_same].RSSI_Quality = 100; 2601 else if (info->RSSI >= -80) // between -50 ~ -80dbm 2602 apinfos[idx_same].RSSI_Quality = (int)(24 + ((info->RSSI + 80) * 26)/10); 2603 else if (info->RSSI >= -90) // between -80 ~ -90dbm 2604 apinfos[idx_same].RSSI_Quality = (int)(((info->RSSI + 90) * 26)/10); 2605 else // < -84 dbm 2606 apinfos[idx_same].RSSI_Quality = 0; 2607 } 2608 else 2609 { 2610 strcpy(apinfos[ap_count].BSSID, macstr); 2611// strcpy(apinfos[ap_count].SSID, info->SSID); 2612 memset(apinfos[ap_count].SSID, 0x0, 33); 2613 memcpy(apinfos[ap_count].SSID, info->SSID, info->SSID_len); 2614 apinfos[ap_count].channel = (uint8)(info->chanspec & WL_CHANSPEC_CHAN_MASK); 2615 if (info->ctl_ch == 0) 2616 { 2617 apinfos[ap_count].ctl_ch = apinfos[ap_count].channel; 2618 } else 2619 { 2620 apinfos[ap_count].ctl_ch = info->ctl_ch; 2621 } 2622 2623 if (info->RSSI >= -50) 2624 apinfos[ap_count].RSSI_Quality = 100; 2625 else if (info->RSSI >= -80) // between -50 ~ -80dbm 2626 apinfos[ap_count].RSSI_Quality = (int)(24 + ((info->RSSI + 80) * 26)/10); 2627 else if (info->RSSI >= -90) // between -80 ~ -90dbm 2628 apinfos[ap_count].RSSI_Quality = (int)(((info->RSSI + 90) * 26)/10); 2629 else // < -84 dbm 2630 apinfos[ap_count].RSSI_Quality = 0; 2631 2632 if ((info->capability & 0x10) == 0x10) 2633 apinfos[ap_count].wep = 1; 2634 else 2635 apinfos[ap_count].wep = 0; 2636 apinfos[ap_count].wpa = 0; 2637 2638/* 2639 unsigned char *RATESET = &info->rateset; 2640 for (k = 0; k < 18; k++) 2641 dbg("%02x ", (unsigned char)RATESET[k]); 2642 dbg("\n"); 2643*/ 2644 2645 NetWorkType = Ndis802_11DS; 2646 if ((uint8)(info->chanspec & WL_CHANSPEC_CHAN_MASK) <= 14) 2647 { 2648 for (k = 0; k < info->rateset.count; k++) 2649 { 2650 rate = info->rateset.rates[k] & 0x7f; // Mask out basic rate set bit 2651 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) 2652 continue; 2653 else 2654 { 2655 NetWorkType = Ndis802_11OFDM24; 2656 break; 2657 } 2658 } 2659 } 2660 else 2661 NetWorkType = Ndis802_11OFDM5; 2662 2663 if (info->n_cap) 2664 { 2665 if (NetWorkType == Ndis802_11OFDM5) 2666 { 2667#ifdef RTCONFIG_BCMWL6 2668 if (info->vht_cap) 2669 NetWorkType = Ndis802_11OFDM5_VHT; 2670 else 2671#endif 2672 NetWorkType = Ndis802_11OFDM5_N; 2673 } 2674 else 2675 NetWorkType = Ndis802_11OFDM24_N; 2676 } 2677 2678 apinfos[ap_count].NetworkType = NetWorkType; 2679 2680 ap_count++; 2681 2682 if (ap_count >= MAX_NUMBER_OF_APINFO) 2683 break; 2684 } 2685 2686 ie = (struct bss_ie_hdr *) ((unsigned char *) info + sizeof(*info)); 2687 for (left = info->ie_length; left > 0; // look for RSN IE first 2688 left -= (ie->len + 2), ie = (struct bss_ie_hdr *) ((unsigned char *) ie + 2 + ie->len)) 2689 { 2690 if (ie->elem_id != DOT11_MNG_RSN_ID) 2691 continue; 2692 2693 if (wpa_parse_wpa_ie(&ie->elem_id, ie->len + 2, &apinfos[ap_count - 1].wid) == 0) 2694 { 2695 apinfos[ap_count-1].wpa = 1; 2696 goto next_info; 2697 } 2698 } 2699 2700 ie = (struct bss_ie_hdr *) ((unsigned char *) info + sizeof(*info)); 2701 for (left = info->ie_length; left > 0; // then look for WPA IE 2702 left -= (ie->len + 2), ie = (struct bss_ie_hdr *) ((unsigned char *) ie + 2 + ie->len)) 2703 { 2704 if (ie->elem_id != DOT11_MNG_WPA_ID) 2705 continue; 2706 2707 if (wpa_parse_wpa_ie(&ie->elem_id, ie->len + 2, &apinfos[ap_count-1].wid) == 0) 2708 { 2709 apinfos[ap_count-1].wpa = 1; 2710 break; 2711 } 2712 } 2713 2714next_info: 2715 info = (wl_bss_info_t *) ((unsigned char *) info + info->length); 2716 } 2717 } 2718 } 2719 2720 /* Print scanning result to console */ 2721 if (ap_count == 0) { 2722 dbg("[wlc] No AP found!\n"); 2723 } else { 2724 printf("%-4s%4s%-33s%-18s%-9s%-16s%-9s%8s%3s%3s\n", 2725 "idx", "CH ", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", "CC", "EC"); 2726 for (k = 0; k < ap_count; k++) 2727 { 2728 printf("%2d. ", k + 1); 2729 printf("%3d ", apinfos[k].ctl_ch); 2730 printf("%-33s", apinfos[k].SSID); 2731 printf("%-18s", apinfos[k].BSSID); 2732 2733 if (apinfos[k].wpa == 1) 2734 printf("%-9s%-16s", wpa_cipher_txt(apinfos[k].wid.pairwise_cipher), wpa_key_mgmt_txt(apinfos[k].wid.key_mgmt, apinfos[k].wid.proto)); 2735 else if (apinfos[k].wep == 1) 2736 printf("WEP Unknown "); 2737 else 2738 printf("NONE Open System "); 2739 printf("%9d ", apinfos[k].RSSI_Quality); 2740 2741 if (apinfos[k].NetworkType == Ndis802_11FH || apinfos[k].NetworkType == Ndis802_11DS) 2742 printf("%-7s", "11b"); 2743 else if (apinfos[k].NetworkType == Ndis802_11OFDM5) 2744 printf("%-7s", "11a"); 2745 else if (apinfos[k].NetworkType == Ndis802_11OFDM5_VHT) 2746 printf("%-7s", "11ac"); 2747 else if (apinfos[k].NetworkType == Ndis802_11OFDM5_N) 2748 printf("%-7s", "11a/n"); 2749 else if (apinfos[k].NetworkType == Ndis802_11OFDM24) 2750 printf("%-7s", "11b/g"); 2751 else if (apinfos[k].NetworkType == Ndis802_11OFDM24_N) 2752 printf("%-7s", "11b/g/n"); 2753 else 2754 printf("%-7s", "unknown"); 2755 2756 printf("%3d", apinfos[k].ctl_ch); 2757 2758 if ( ((apinfos[k].NetworkType == Ndis802_11OFDM5_VHT) || 2759 (apinfos[k].NetworkType == Ndis802_11OFDM5_N) || 2760 (apinfos[k].NetworkType == Ndis802_11OFDM24_N)) && 2761 (apinfos[k].channel != apinfos[k].ctl_ch)) { 2762 if (apinfos[k].ctl_ch < apinfos[k].channel) 2763 ht_extcha = 1; 2764 else 2765 ht_extcha = 0; 2766 2767 printf("%3d", ht_extcha); 2768 } 2769 2770 printf("\n"); 2771 } 2772 } 2773 2774 ret = wl_ioctl(wif, WLC_GET_BSSID, bssid, sizeof(bssid)); 2775 memset(ure_mac, 0x0, 18); 2776 if (!ret) { 2777 if (!(!bssid[0] && !bssid[1] && !bssid[2] && !bssid[3] && !bssid[4] && !bssid[5])) { 2778 sprintf(ure_mac, "%02X:%02X:%02X:%02X:%02X:%02X", 2779 (unsigned char)bssid[0], 2780 (unsigned char)bssid[1], 2781 (unsigned char)bssid[2], 2782 (unsigned char)bssid[3], 2783 (unsigned char)bssid[4], 2784 (unsigned char)bssid[5]); 2785 } 2786 } 2787 2788 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2789 maclist_size = sizeof(authorized->count) + max_sta_count * sizeof(struct ether_addr); 2790 authorized = malloc(maclist_size); 2791 2792 // query wl for authorized sta list 2793 strcpy((char*)authorized, "autho_sta_list"); 2794 if (!wl_ioctl(wif, WLC_GET_VAR, authorized, maclist_size)) { 2795 if (authorized->count > 0) wl_authorized = 1; 2796 } 2797 2798 if (authorized) free(authorized); 2799 } 2800 2801 /* Print scanning result to web format */ 2802 if (ap_count > 0) { 2803 /* write pid */ 2804 if ((fp = fopen(ofile, "a")) == NULL) { 2805 printf("[wlcscan] Output %s error\n", ofile); 2806 } else { 2807 for (i = 0; i < ap_count; i++) { 2808 /*if (apinfos[i].ctl_ch < 0 ) { 2809 fprintf(fp, "\"ERR_BNAD\","); 2810 } else */if (apinfos[i].ctl_ch > 0 && 2811 apinfos[i].ctl_ch < 14) { 2812 fprintf(fp, "\"2G\","); 2813 } else if (apinfos[i].ctl_ch > 14 && 2814 apinfos[i].ctl_ch < 166) { 2815 fprintf(fp, "\"5G\","); 2816 } else { 2817 fprintf(fp, "\"ERR_BNAD\","); 2818 } 2819 2820 if (strlen(apinfos[i].SSID) == 0) { 2821 fprintf(fp, "\"\","); 2822 } else { 2823 memset(ssid_str, 0, sizeof(ssid_str)); 2824 char_to_ascii(ssid_str, apinfos[i].SSID); 2825 fprintf(fp, "\"%s\",", ssid_str); 2826 } 2827 2828 fprintf(fp, "\"%d\",", apinfos[i].ctl_ch); 2829 2830 if (apinfos[i].wpa == 1) { 2831 if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X_) 2832 fprintf(fp, "\"%s\",", "WPA-Enterprise"); 2833 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X2_) 2834 fprintf(fp, "\"%s\",", "WPA2-Enterprise"); 2835 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_PSK_) 2836 fprintf(fp, "\"%s\",", "WPA-Personal"); 2837 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_PSK2_) 2838 fprintf(fp, "\"%s\",", "WPA2-Personal"); 2839 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_NONE_) 2840 fprintf(fp, "\"%s\",", "NONE"); 2841 else if (apinfos[i].wid.key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA_) 2842 fprintf(fp, "\"%s\",", "IEEE 802.1X"); 2843 else 2844 fprintf(fp, "\"%s\",", "Unknown"); 2845 } else if (apinfos[i].wep == 1) { 2846 fprintf(fp, "\"%s\",", "Unknown"); 2847 } else { 2848 fprintf(fp, "\"%s\",", "Open System"); 2849 } 2850 2851 if (apinfos[i].wpa == 1) { 2852 if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_NONE_) 2853 fprintf(fp, "\"%s\",", "NONE"); 2854 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_WEP40_) 2855 fprintf(fp, "\"%s\",", "WEP"); 2856 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_WEP104_) 2857 fprintf(fp, "\"%s\",", "WEP"); 2858 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_TKIP_) 2859 fprintf(fp, "\"%s\",", "TKIP"); 2860 else if (apinfos[i].wid.pairwise_cipher == WPA_CIPHER_CCMP_) 2861 fprintf(fp, "\"%s\",", "AES"); 2862 else if (apinfos[i].wid.pairwise_cipher == (WPA_CIPHER_TKIP_|WPA_CIPHER_CCMP_)) 2863 fprintf(fp, "\"%s\",", "TKIP+AES"); 2864 else 2865 fprintf(fp, "\"%s\",", "Unknown"); 2866 } else if (apinfos[i].wep == 1) { 2867 fprintf(fp, "\"%s\",", "WEP"); 2868 } else { 2869 fprintf(fp, "\"%s\",", "NONE"); 2870 } 2871 2872 fprintf(fp, "\"%d\",", apinfos[i].RSSI_Quality); 2873 fprintf(fp, "\"%s\",", apinfos[i].BSSID); 2874 2875 if (apinfos[i].NetworkType == Ndis802_11FH || apinfos[i].NetworkType == Ndis802_11DS) 2876 fprintf(fp, "\"%s\",", "b"); 2877 else if (apinfos[i].NetworkType == Ndis802_11OFDM5) 2878 fprintf(fp, "\"%s\",", "a"); 2879 else if (apinfos[i].NetworkType == Ndis802_11OFDM5_N) 2880 fprintf(fp, "\"%s\",", "an"); 2881 else if (apinfos[i].NetworkType == Ndis802_11OFDM5_VHT) 2882 fprintf(fp, "\"%s\",", "ac"); 2883 else if (apinfos[i].NetworkType == Ndis802_11OFDM24) 2884 fprintf(fp, "\"%s\",", "bg"); 2885 else if (apinfos[i].NetworkType == Ndis802_11OFDM24_N) 2886 fprintf(fp, "\"%s\",", "bgn"); 2887 else 2888 fprintf(fp, "\"%s\",", ""); 2889 2890 if (strcmp(nvram_safe_get(wlc_nvname("ssid")), apinfos[i].SSID)) { 2891 if (strcmp(apinfos[i].SSID, "")) 2892 fprintf(fp, "\"%s\"", "0"); // none 2893 else if (!strcmp(ure_mac, apinfos[i].BSSID)) { 2894 // hidden AP (null SSID) 2895 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2896 if (wl_authorized) { 2897 // in profile, connected 2898 fprintf(fp, "\"%s\"", "4"); 2899 } else { 2900 // in profile, connecting 2901 fprintf(fp, "\"%s\"", "5"); 2902 } 2903 } else { 2904 // in profile, connected 2905 fprintf(fp, "\"%s\"", "4"); 2906 } 2907 } else { 2908 // hidden AP (null SSID) 2909 fprintf(fp, "\"%s\"", "0"); // none 2910 } 2911 } else if (!strcmp(nvram_safe_get(wlc_nvname("ssid")), apinfos[i].SSID)) { 2912 if (!strlen(ure_mac)) { 2913 // in profile, disconnected 2914 fprintf(fp, "\"%s\",", "1"); 2915 } else if (!strcmp(ure_mac, apinfos[i].BSSID)) { 2916 if (strstr(nvram_safe_get(wlc_nvname("akm")), "psk")) { 2917 if (wl_authorized) { 2918 // in profile, connected 2919 fprintf(fp, "\"%s\"", "2"); 2920 } else { 2921 // in profile, connecting 2922 fprintf(fp, "\"%s\"", "3"); 2923 } 2924 } else { 2925 // in profile, connected 2926 fprintf(fp, "\"%s\"", "2"); 2927 } 2928 } else { 2929 fprintf(fp, "\"%s\"", "0"); // impossible... 2930 } 2931 } else { 2932 // wl0_ssid is empty 2933 fprintf(fp, "\"%s\"", "0"); 2934 } 2935 2936 if (i == ap_count - 1) { 2937 fprintf(fp, "\n"); 2938 } else { 2939 fprintf(fp, "\n"); 2940 } 2941 } /* for */ 2942 fclose(fp); 2943 } 2944 } /* if */ 2945 2946 return retval; 2947} 2948#endif 2949 2950#ifdef RTCONFIG_WIRELESSREPEATER 2951/* 2952 * Return value: 2953 * 2 = successfully connected to parent AP 2954 */ 2955int get_wlc_status(char *wif) 2956{ 2957 char ure_mac[18]; 2958 unsigned char bssid[6]; 2959 struct maclist *authorized; 2960 int maclist_size; 2961 int max_sta_count = 128; 2962 int wl_authorized = 0; 2963 int wl_associated = 0; 2964 int wl_psk = 0; 2965 wlc_ssid_t wst = {0, ""}; 2966 2967 wl_psk = strstr(nvram_safe_get(wlc_nvname("akm")), "psk") ? 1 : 0; 2968 2969 if (wl_ioctl(wif, WLC_GET_SSID, &wst, sizeof(wst))) { 2970 dbg("[wlc] WLC_GET_SSID error\n"); 2971 goto wl_ioctl_error; 2972 } 2973 2974 memset(ure_mac, 0x0, 18); 2975 if (!wl_ioctl(wif, WLC_GET_BSSID, bssid, sizeof(bssid))) { 2976 if (!(!bssid[0] && !bssid[1] && !bssid[2] && 2977 !bssid[3] && !bssid[4] && !bssid[5])) { 2978 wl_associated = 1; 2979 sprintf(ure_mac, "%02X:%02X:%02X:%02X:%02X:%02X", 2980 (unsigned char)bssid[0], 2981 (unsigned char)bssid[1], 2982 (unsigned char)bssid[2], 2983 (unsigned char)bssid[3], 2984 (unsigned char)bssid[4], 2985 (unsigned char)bssid[5]); 2986 } 2987 } else { 2988 dbg("[wlc] WLC_GET_BSSID error\n"); 2989 goto wl_ioctl_error; 2990 } 2991 2992 if (wl_psk) { 2993 maclist_size = sizeof(authorized->count) + 2994 max_sta_count * sizeof(struct ether_addr); 2995 authorized = malloc(maclist_size); 2996 2997 if (authorized) { 2998 // query wl for authorized sta list 2999 strcpy((char*)authorized, "autho_sta_list"); 3000 3001 if (!wl_ioctl(wif, WLC_GET_VAR, authorized, maclist_size)) { 3002 if (authorized->count > 0) wl_authorized = 1; 3003 free(authorized); 3004 } else { 3005 free(authorized); 3006 dbg("[wlc] Authorized failed\n"); 3007 goto wl_ioctl_error; 3008 } 3009 } 3010 } 3011 3012 if (!wl_associated) { 3013 dbg("[wlc] not wl_associated\n"); 3014 } 3015 3016 dbg("[wlc] wl-associated [%d]\n", wl_associated); 3017 dbg("[wlc] %s\n", wst.SSID); 3018 dbg("[wlc] %s\n", nvram_safe_get(wlc_nvname("ssid"))); 3019 3020 if (wl_associated && 3021 !strncmp((const char *) wst.SSID, nvram_safe_get(wlc_nvname("ssid")), wst.SSID_len)) { 3022 if (wl_psk) { 3023 if (wl_authorized) { 3024 dbg("[wlc] wl_authorized\n"); 3025 return 2; 3026 } else { 3027 dbg("[wlc] not wl_authorized\n"); 3028 return 1; 3029 } 3030 } else { 3031 dbg("[wlc] wl_psk:[%d]\n", wl_psk); 3032 return 2; 3033 } 3034 } else { 3035 dbg("[wlc] Not associated\n"); 3036 return 0; 3037 } 3038 3039wl_ioctl_error: 3040 return 0; 3041} 3042 3043// TODO: wlcconnect_main 3044// wireless ap monitor to connect to ap 3045// when wlc_list, then connect to it according to priority 3046int wlcconnect_core(void) 3047{ 3048 int ret = 0; 3049 char word[256], *next; 3050 unsigned char SEND_NULLDATA[]={ 0x73, 0x65, 0x6e, 0x64, 3051 0x5f, 0x6e, 0x75, 0x6c, 3052 0x6c, 0x64, 0x61, 0x74, 3053 0x61, 0x00, 0xff, 0xff, 3054 0xff, 0xff, 0xff, 0xff}; 3055 unsigned char bssid[6]; 3056 int unit = 0; 3057 3058 /* return WLC connection status */ 3059 foreach (word, nvram_safe_get("wl_ifnames"), next) { 3060 // only one client in a system 3061 if (is_ure(unit)) { 3062 //dbg("[rc] [%s] is URE mode\n", word); 3063 memset(bssid, 0xff, 6); 3064 if (!wl_ioctl(word, WLC_GET_BSSID, bssid, sizeof(bssid))) { 3065 memcpy(SEND_NULLDATA + 14, bssid, 6); 3066 3067 // wl send_nulldata xx:xx:xx:xx:xx:xx 3068 wl_ioctl(word, WLC_SET_VAR, SEND_NULLDATA, 3069 sizeof(SEND_NULLDATA)); 3070 } 3071 3072 ret = get_wlc_status(word); 3073 dbg("[wlc][%s] get_wlc_status:[%d]\n", word, ret); 3074 3075 break; 3076 } 3077 3078 unit++; 3079 } 3080 3081 return ret; 3082} 3083 3084#endif 3085 3086#if 0 3087bool 3088wl_check_assoc_scb(char *ifname) 3089{ 3090 bool connected = TRUE; 3091 int result = 0; 3092 int ret = 0; 3093 3094 ret = wl_iovar_getint(ifname, "scb_assoced", &result); 3095 if (ret) { 3096 dbg("failed to get scb_assoced\n"); 3097 return connected; 3098 } 3099 3100 connected = dtoh32(result) ? TRUE : FALSE; 3101 return connected; 3102} 3103 3104int 3105wl_phy_rssi_ant(char *ifname) 3106{ 3107 char buf[WLC_IOCTL_MAXLEN]; 3108 int ret = 0; 3109 uint i; 3110 wl_rssi_ant_t *rssi_ant_p; 3111 3112 if (!ifname) 3113 return -1; 3114 3115 memset(buf, 0, WLC_IOCTL_MAXLEN); 3116 strcpy(buf, "phy_rssi_ant"); 3117 3118 if ((ret = wl_ioctl(ifname, WLC_GET_VAR, &buf[0], WLC_IOCTL_MAXLEN)) < 0) 3119 return ret; 3120 3121 rssi_ant_p = (wl_rssi_ant_t *)buf; 3122 rssi_ant_p->version = dtoh32(rssi_ant_p->version); 3123 rssi_ant_p->count = dtoh32(rssi_ant_p->count); 3124 3125 if (rssi_ant_p->count == 0) { 3126 dbg("not supported on this chip\n"); 3127 } else { 3128 if ((rssi_ant_p->rssi_ant[0]) && 3129 (rssi_ant_p->rssi_ant[1] < -100) && 3130 ((rssi_ant_p->count > 2)?(rssi_ant_p->rssi_ant[2] < -100) : 1)) 3131 { 3132 for (i = 0; i < rssi_ant_p->count; i++) 3133 dbg("rssi[%d] %d ", i, rssi_ant_p->rssi_ant[i]); 3134 dbg("\n"); 3135 } 3136 } 3137 3138 return ret; 3139} 3140#endif 3141 3142#ifdef RTAC3200 3143extern struct nvram_tuple router_defaults[]; 3144 3145void 3146bsd_defaults(void) 3147{ 3148 char extendno_org[14]; 3149 int ext_num; 3150 char ext_commit_str[8]; 3151 struct nvram_tuple *t; 3152 3153 if (!strlen(nvram_safe_get("extendno_org")) || 3154 nvram_match("extendno_org", nvram_safe_get("extendno"))) 3155 return; 3156 3157 strcpy(extendno_org, nvram_safe_get("extendno_org")); 3158 if (!strlen(extendno_org) || 3159 sscanf(extendno_org, "%d-g%s", &ext_num, ext_commit_str) != 2) 3160 return; 3161 3162// if (strcmp(rt_serialno, "378") || (ext_num >= 4120)) 3163// return; 3164 3165 for (t = router_defaults; t->name; t++) 3166 if (strstr(t->name, "bsd")) 3167 nvram_set(t->name, t->value); 3168} 3169#endif 3170 3171#ifdef RTCONFIG_BCMWL6 3172int 3173wl_check_chanspec() 3174{ 3175 wl_uint32_list_t *list; 3176 chanspec_t c, chansp_40m; 3177 int ret = 0, i, count; 3178 char data_buf[WLC_IOCTL_MAXLEN]; 3179 char chanbuf[CHANSPEC_STR_LEN]; 3180 char word[256], *next; 3181 char tmp[256], tmp2[256], prefix[] = "wlXXXXXXXXXX_"; 3182 int unit = 0; 3183 int match; 3184 int match_ctrl_ch; 3185 int match_40m_ch; 3186 3187 foreach (word, nvram_safe_get("wl_ifnames"), next) { 3188 snprintf(prefix, sizeof(prefix), "wl%d_", unit++); 3189 c = 0; 3190 chansp_40m = 0; 3191 match = 0; 3192 match_ctrl_ch = 0; 3193 match_40m_ch = 0; 3194 3195 if (!nvram_get_int(strcat_r(prefix, "chanspec", tmp))) 3196 continue; 3197 3198 memset(data_buf, 0, WLC_IOCTL_MAXLEN); 3199 ret = wl_iovar_getbuf(word, "chanspecs", &c, sizeof(chanspec_t), 3200 data_buf, WLC_IOCTL_MAXLEN); 3201 if (ret < 0) { 3202 dbg("failed to get valid chanspec list\n"); 3203 continue; 3204 } 3205 3206 list = (wl_uint32_list_t *)data_buf; 3207 count = dtoh32(list->count); 3208 3209 if (!count) { 3210 dbg("number of valid chanspec is 0\n"); 3211 continue; 3212 } else 3213 for (i = 0; i < count; i++) { 3214 c = (chanspec_t)dtoh32(list->element[i]); 3215 3216 if (!match && 3217 (c == wf_chspec_aton(nvram_safe_get(strcat_r(prefix, "chanspec", tmp))))) { 3218 match = 1; 3219 break; 3220 } 3221 3222 if (wf_chspec_ctlchan(c) == wf_chspec_ctlchan(wf_chspec_aton(nvram_safe_get(strcat_r(prefix, "chanspec", tmp))))) { 3223 if (!match_ctrl_ch) 3224 match_ctrl_ch = 1; 3225 3226 if (!match_40m_ch && CHSPEC_IS40(c)) { 3227 match_40m_ch = 1; 3228 chansp_40m = c; 3229 } 3230 } 3231 } 3232 3233 if (!match) { 3234 dbg("chanspec %s is invalid\n", nvram_safe_get(strcat_r(prefix, "chanspec", tmp))); 3235 3236 if (match_40m_ch) { 3237 dbg("downgraded to 40M chanspec\n"); 3238 nvram_set(strcat_r(prefix, "chanspec", tmp), wf_chspec_ntoa(chansp_40m, chanbuf)); 3239 } else if (match_ctrl_ch) { 3240 dbg("downgraded to 20M chanspec\n"); 3241 nvram_set_int(strcat_r(prefix, "chanspec", tmp), wf_chspec_ctlchan(wf_chspec_aton(nvram_safe_get(strcat_r(prefix, "chanspec", tmp2))))); 3242 } else { 3243 dbg("downgraded to auto chanspec\n"); 3244 nvram_set_int(strcat_r(prefix, "chanspec", tmp), 0); 3245 nvram_set_int(strcat_r(prefix, "bw", tmp), 0); 3246 } 3247 } 3248 } 3249 3250 return ret; 3251} 3252 3253#define CHANNEL_5G_BAND_GROUP(c) \ 3254 (((c) < 52) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))) 3255 3256void 3257wl_check_5g_band_group() 3258{ 3259 wl_uint32_list_t *list; 3260 chanspec_t c; 3261 int ret = 0, i, count; 3262 char data_buf[WLC_IOCTL_MAXLEN]; 3263 char word[256], *next; 3264 char tmp[100], tmp2[100], prefix[] = "wlXXXXXXXXXX_"; 3265 int unit = 0; 3266 unsigned int band5grp; 3267 3268 foreach (word, nvram_safe_get("wl_ifnames"), next) { 3269 snprintf(prefix, sizeof(prefix), "wl%d_", unit++); 3270 c = 0; 3271 3272 if (unit == 1) continue; 3273 3274 memset(data_buf, 0, WLC_IOCTL_MAXLEN); 3275 ret = wl_iovar_getbuf(word, "chanspecs", &c, sizeof(chanspec_t), 3276 data_buf, WLC_IOCTL_MAXLEN); 3277 if (ret < 0) { 3278 dbg("failed to get valid chanspec list\n"); 3279 continue; 3280 } 3281 3282 list = (wl_uint32_list_t *)data_buf; 3283 count = dtoh32(list->count); 3284 3285 if (!count) { 3286 dbg("number of valid chanspec is 0\n"); 3287 continue; 3288 } else 3289 for (i = 0, band5grp = 0; i < count; i++) { 3290 c = (chanspec_t)dtoh32(list->element[i]); 3291 band5grp |= 1 << (CHANNEL_5G_BAND_GROUP(wf_chspec_ctlchan(c)) - 1); 3292 } 3293 3294 sprintf(tmp2, "%x", band5grp); 3295 nvram_set(strcat_r(prefix, "band5grp", tmp), tmp2); 3296 } 3297} 3298#endif 3299 3300#if defined(RTAC88U) || defined(RTAC3100) || defined(RTAC5300) || defined(RTAC5300R) 3301int wl_channel_valid(char *wif, int channel) 3302{ 3303 int channels[MAXCHANNEL+1]; 3304 wl_uint32_list_t *list = (wl_uint32_list_t *) channels; 3305 int i; 3306 3307 memset(channels, 0, sizeof(channels)); 3308 list->count = htod32(MAXCHANNEL); 3309 if (wl_ioctl(wif, WLC_GET_VALID_CHANNELS , channels, sizeof(channels)) < 0) 3310 { 3311 dbg("error doing WLC_GET_VALID_CHANNELS\n"); 3312 return 0; 3313 } 3314 3315 if (dtoh32(list->count) == 0) 3316 return 0; 3317 3318 for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) 3319 if (channel == dtoh32(list->element[i])) 3320 return 1; 3321 3322 return 0; 3323} 3324 3325int wl_subband(char *wif, int idx) 3326{ 3327 int count = 0; 3328 int band; 3329 3330 wl_ioctl(wif, WLC_GET_BAND, &band, sizeof(band)); 3331 if (band != WLC_BAND_5G) 3332 return -1; 3333 3334 if (wl_channel_valid(wif, 36)) 3335 { 3336 if (++count == idx) 3337 return 1; 3338 } 3339 3340 if (wl_channel_valid(wif, 52)) 3341 { 3342 if (++count == idx) 3343 return 2; 3344 } 3345 3346 if (wl_channel_valid(wif, 100)) 3347 { 3348 if (++count == idx) 3349 return 3; 3350 } 3351 3352 if (wl_channel_valid(wif, 149)) 3353 { 3354 if (++count == idx) 3355 return 4; 3356 } 3357 3358 return -1; 3359} 3360#endif 3361