| #include <unistd.h> |
| #include <assert.h> |
| #include <signal.h> |
| #include <stdio.h> |
| #include <libubox/blobmsg_json.h> |
| #include "libubus.h" |
| #include <uci.h> |
| #include <include/log.h> |
| #include <sys/prctl.h> |
| #include <stdlib.h> |
| #include <fcntl.h> |
| |
| #define WIFI_DEBUG |
| #ifdef WIFI_DEBUG |
| #define WIFI_DBG(format, args...) RDPRINTF("%s: " format,__FUNCTION__, ##args); |
| #else |
| #define WIFI_DBG(...) do {} while (0) |
| #endif |
| #define WIFI_ERR(format, args...) RERRMSG("%s: " format,__FUNCTION__, ##args); |
| |
| #ifndef UNUSESET |
| #define UNUSESET(param) (void)(param) |
| #endif |
| |
| #define WIFI_PACKAGE_NAME "wireless" |
| #define WIFI_SECTION_DEVICE "wifi-device" |
| #define WIFI_SECTION_IFACE "wifi-iface" |
| #define WIFI_SECTION_SETTING "wifi-settings" |
| #define WIFI_SECTION_CHIP "chip" |
| #define MAX_WIFI_DEVICE_SECTION 10 |
| #define MAX_WIFI_IFACE_SECTION 10 |
| #define MAX_DEV_NAME_LEN 32 |
| #define ADD_MULTI_SSID_SEC 0 |
| #define DELETE_MULTI_SSID_SEC 1 |
| #define MAX_MULTI_SSID_NUM 2 |
| #define IMSI_FILE "/tmp/imsi_file" |
| #define WIFI_SECTION_BS "wifi-bandSteering" |
| |
| #define HOSTAPD_EV_WPS_START "WPS-START" |
| #define HOSTAPD_EV_WPS_FAIL "WPS-FAIL" |
| #define HOSTAPD_EV_WPS_SUCCESS "WPS-SUCCESS" |
| #define WPS_STATUS_CLEAR_TIMEOUT 2*60*1000 //ms |
| #define MULTI_VIRTUAL_AP_IFNAME_PREFIX "va" |
| |
| extern struct ubus_context *applet_ubus_ctx; |
| static struct ubus_context *wifi_ubus_ctx = NULL; |
| static struct blob_buf wifi_buf; |
| |
| static struct ubus_subscriber hostapd_event_subscriber; |
| static struct ubus_subscriber charger_event; |
| static struct ubus_subscriber hostapd_wlan1_event_subscriber; |
| static void wps_status_clear_cb(struct uloop_timeout *timeout); |
| |
| static struct uloop_timeout wps_status_clear_timeout = { |
| .cb = wps_status_clear_cb, |
| }; |
| |
| |
| #define MIN_AUTO_OFF_TIMEOUT 600 |
| #define CHARGER_UBUS_ID "aoc" |
| #define CHARGER_UBUS_REQUEST "get_chg_info" |
| |
| enum { |
| WIFI_OFF, |
| WIFI_START, |
| WIFI_READY, |
| NO_WIFI, |
| }; |
| |
| enum { |
| WIFI_AP0, |
| WIFI_AP1, |
| MAX_WIFI_CHIP_NUM |
| }; |
| enum isolate_state{ |
| AP_ISOLATE_NO_CHANGE, |
| AP_ISOLATE_OFF_ON, |
| AP_ISOLATE_ON_OFF |
| }; |
| |
| enum e_wps_status { |
| WPS_STATUS_INIT, |
| WPS_STATUS_START, |
| WPS_STATUS_SUCCESS, |
| WPS_STATUS_FAIL |
| }; |
| |
| enum e_wps_state{ |
| WPS_STATE_INIT, |
| WPS_STATE_5G_PREFER, |
| WPS_STATE_5G_START, |
| WPS_STATE_5G_SUCCESS, |
| WPS_STATE_5G_FAIL, |
| WPS_STATE_24G_START, |
| WPS_STATE_24G_SUCCESS, |
| WPS_STATE_24G_FAIL |
| }; |
| |
| #define MULTI_SSID_NUM 3 |
| struct ap_sec_info { |
| struct uci_section *device; |
| struct uci_section *iface[MULTI_SSID_NUM]; |
| int n_ssid; |
| }; |
| |
| struct sta_sec_info { |
| struct uci_section *device; |
| struct uci_section *iface; |
| }; |
| |
| struct wifi_sec_info { |
| struct ap_sec_info ap_2G; |
| struct ap_sec_info ap_5G; |
| struct sta_sec_info sta; |
| struct uci_section *chip; |
| int auto_off_enable; |
| int auto_off_timeout; |
| }; |
| |
| struct wireless_info { |
| int n_dev; |
| struct wifi_sec_info wifi_info[MAX_WIFI_CHIP_NUM]; |
| struct uci_section *chip; |
| struct uci_section *sec_bs; |
| int chip_type; |
| int wifi6; |
| int band_steering_support; |
| int band_steering_enable; |
| int wifi_5g_index; |
| int wifi_24g_index; |
| }; |
| |
| struct wps_conn_info { |
| enum e_wps_status wps_status; |
| char peer_mac[20]; |
| }; |
| |
| struct wps_conn_ctx { |
| enum e_wps_state state; |
| int method; // 0: pbc, 1: pin |
| int ap_5g_index; |
| int ap_24g_index; |
| int ap_index; |
| char pin[32]; |
| }; |
| |
| static const struct blobmsg_policy wps_event_pol[] = { |
| [0] = { |
| .name = "address", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| struct wps_conn_info g_wps_info[MAX_WIFI_CHIP_NUM]; |
| struct wps_conn_ctx g_wps_conn_ctx; |
| /*================================================================================== |
| * Struct |
| * MCC -- Counrty |
| * |
| *=================================================================================*/ |
| #define MAX_COUNTRY_NAME_LEN 32 /*Can be changed if necessary*/ |
| |
| typedef struct{ |
| char mcc[4]; |
| char country[MAX_COUNTRY_NAME_LEN]; |
| char ccode[3]; |
| }MCC_Country; |
| /*================================================================================== |
| * Static Array |
| * Mobile Country Code |
| * |
| *=================================================================================*/ |
| static MCC_Country MrvlMccCountryTable[] = |
| { |
| {"001", "Test", ""}, |
| {"289", "Abkhazia", "GE"}, |
| {"412", "Afghanistan", "AF"}, |
| {"276", "Albania", "AL"}, |
| {"603", "Algeria", "DZ"}, |
| {"544", "America", "AS"}, |
| {"213", "Andorra", "AD"}, |
| {"631", "Angola", "AO"}, |
| {"365", "Anguilla", "AI"}, |
| {"344", "Antigua", "AG"}, |
| {"722", "Argentina", "AR"}, |
| {"283", "Armenia", "AM"}, |
| {"363", "Aruba", "AW"}, |
| {"505", "Australia", "AU"}, |
| {"232", "Austria", "AT"}, |
| {"400", "Azerbaijan", "AZ"}, |
| {"364", "Bahamas", "BS"}, |
| {"426", "Bahrain", "BH"}, |
| {"470", "Bangladesh", "BD"}, |
| {"342", "Barbados", "BB"}, |
| {"257", "Belarus", "BY"}, |
| {"206", "Belgium", "BE"}, |
| {"702", "Belize", "BZ"}, |
| {"616", "Benin", "BJ"}, |
| {"350", "Bermuda", "BM"}, |
| {"402", "Bhutan", "BT"}, |
| {"736", "Bolivia", "BO"}, |
| {"218", "Bosnia", "BA"}, |
| {"652", "Botswana", "BW"}, |
| {"724", "Brazil", "BR"}, |
| {"348", "British", "VG"}, |
| {"528", "Brunei", "BN"}, |
| {"284", "Bulgaria", "BG"}, |
| {"613", "Burkina", "BF"}, |
| {"642", "Burundi", "BI"}, |
| {"456", "Cambodia", "KH"}, |
| {"624", "Cameroon", "CM"}, |
| {"302", "Canada", "CA"}, |
| {"625", "Cape", "CV"}, |
| {"346", "Cayman", "KY"}, |
| {"623", "Centra African", "CF"}, |
| {"622", "Chad", "TD"}, |
| {"730", "Chile", "CL"}, |
| {"460", "China", "CN"}, |
| {"732", "Colombia", "CO"}, |
| {"654", "Comoros", "KM"}, |
| {"629", "Congo", "CG"}, |
| {"548", "Cook Islands", "CK"}, |
| {"712", "Costa Rica", "CR"}, |
| {"612", "Ivory Coast", "CI"}, |
| {"219", "Croatia", "HR"}, |
| {"368", "Cuba", "CU"}, |
| {"362", "AN", "CW"}, |
| {"280", "Cyprus", "CY"}, |
| {"230", "Czech Repubic", "CZ"}, |
| {"630", "Democratic", "CD"}, |
| {"238", "Denmark", "DK"}, |
| {"638", "Djibouti", "DJ"}, |
| {"366", "Dominica", "DM"}, |
| {"370", "Dominican", "DO"}, |
| {"514", "East Timor", "TL"}, |
| {"740", "Ecuador", "EC"}, |
| {"602", "Egypt", "EG"}, |
| {"706", "EI Salvador", "SV"}, |
| {"627", "Equatorial", "GQ"}, |
| {"657", "Eritrea", "ER"}, |
| {"248", "Estonia", "EE"}, |
| {"636", "Ethiopia", "ET"}, |
| {"288", "Faroe Islands", "FO"}, |
| {"542", "Fiji", "FJ"}, |
| {"244", "Finland", "FI"}, |
| {"208", "France", "FR"}, |
| {"547", "France", "PF"}, |
| {"628", "Gabon", "GA"}, |
| {"607", "Gambia", "GM"}, |
| {"282", "Georgia", "GE"}, |
| {"262", "Germany", "DE"}, |
| {"620", "Ghana", "GH"}, |
| {"266", "Gibraltar", "GI"}, |
| {"202", "Greece", "GR"}, |
| {"290", "Greenland", "GL"}, |
| {"352", "Grenada", "GD"}, |
| {"340", "Guadeloupe", "GP"}, |
| {"704", "Guatemala", "GT"}, |
| {"611", "Guinea", "GN"}, |
| {"632", "Guinea-Bissau", "GW"}, |
| {"738", "Guyana", "GY"}, |
| {"372", "Haiti", "HT"}, |
| {"708", "Honduras", "HN"}, |
| {"454", "HongKong", "HK"}, |
| {"216", "Hungary", "HU"}, |
| {"274", "Iceland", "IS"}, |
| {"404", "India", "IN"}, |
| {"405", "India", "IN"}, |
| {"510", "Indonesia", "ID"}, |
| {"432", "Iran", "IR"}, |
| {"418", "Iraq", "IQ"}, |
| {"272", "Ireland", "IE"}, |
| {"425", "Israle", "IL"}, |
| {"222", "Italy", "IT"}, |
| {"338", "Jamaica", "JM"}, |
| {"440", "Japan", "JP"}, |
| {"416", "Jordan", "JO"}, |
| {"401", "Kazakhstan", "KZ"}, |
| {"639", "Kenya", "KE"}, |
| {"545", "Kiribati", "KI"}, |
| {"467", "DPRK", "KP"}, |
| {"450", "Korea", "KR"}, |
| {"419", "Kuwait", "KW"}, |
| {"437", "Kyrgyzstan", "KG"}, |
| {"457", "Laos", "LA"}, |
| {"247", "Latvia", "LV"}, |
| {"415", "Lebanon", "LB"}, |
| {"651", "Lesotho", "LS"}, |
| {"618", "Liberia", "LR"}, |
| {"606", "Libya", "LY"}, |
| {"295", "Liechtenstein", "LI"}, |
| {"246", "Lithuania", "LT"}, |
| {"270", "Luxembourg", "LU"}, |
| {"455", "Macau", "MO"}, |
| {"294", "Macedonia", "MK"}, |
| {"646", "Madagascar", "MG"}, |
| {"650", "Malawi", "MW"}, |
| {"502", "Malaysia", "MY"}, |
| {"472", "Maldives", "MV"}, |
| {"610", "Mali", "ML"}, |
| {"278", "Malta", "MT"}, |
| {"551", "Marshall Island", "MH"}, |
| {"609", "Mauritania", "MR"}, |
| {"617", "Mauritius", "MU"}, |
| {"334", "Mexico", "MX"}, |
| {"550", "Micronesia", "FM"}, |
| {"259", "Moldva", "MD"}, |
| {"212", "Monaco", "MC"}, |
| {"428", "Mongolia", "MN"}, |
| {"297", "Montenegro", "ME"}, |
| {"354", "Montserrat", "MS"}, |
| {"604", "Morocco", "MA"}, |
| {"643", "Mozambique", "MZ"}, |
| {"414", "Myanmar", "MM"}, |
| {"649", "Namibia", "NA"}, |
| {"536", "Nauru", "NR"}, |
| {"429", "Nepal", "NP"}, |
| {"204", "Netherlands", "NL"}, |
| {"546", "New Caledonia", "NC"}, |
| {"530", "New Zealand", "NZ"}, |
| {"710", "Nicaragua", "NI"}, |
| {"614", "Niger", "NE"}, |
| {"621", "Nigeria", "NG"}, |
| {"555", "Niue", "NU"}, |
| {"242", "Norway", "NO"}, |
| {"422", "Oman", "OM"}, |
| {"410", "Pakistan", "PK"}, |
| {"552", "Palau", "PW"}, |
| {"714", "Pabana", "PA"}, |
| {"537", "Papua", "PG"}, |
| {"744", "Paraguay", "PY"}, |
| {"716", "Peru", "PE"}, |
| {"515", "Philippines", "PH"}, |
| {"260", "Poland", "PL"}, |
| {"268", "Portugal", "PT"}, |
| {"330", "Puerto Rico", "PR"}, |
| {"427", "Qatar", "QA"}, |
| {"647", "RE", "RE"}, |
| {"226", "Romania", "RO"}, |
| {"250", "Russian", "RU"}, |
| {"635", "Rwanda", "RW"}, |
| {"356", "KN", "KN"}, |
| {"358", "Saint Lucia", "LC"}, |
| {"308", "PM", "PM"}, |
| {"360", "VC", "VC"}, |
| {"549", "Samoa", "WS"}, |
| {"292", "San Marino", "SM"}, |
| {"626", "ST", "ST"}, |
| {"420", "Saudi Arabia", "SA"}, |
| {"608", "Senegal", "SN"}, |
| {"220", "Seribia", "RS"}, |
| {"633", "Seychelles", "SC"}, |
| {"619", "Sierra Leone", "SL"}, |
| {"525", "Singapore", "SG"}, |
| {"231", "Slovakia", "SK"}, |
| {"293", "Slovenia", "SI"}, |
| {"540", "Solomon", "SB"}, |
| {"637", "Somalia", "SO"}, |
| {"655", "South Africa", "ZA"}, |
| {"659", "South Sudan", ""}, |
| {"214", "Spain", "ES"}, |
| {"413", "Sri Lanka", "LK"}, |
| {"634", "Sudan", "SD"}, |
| {"746", "Suriname", "SR"}, |
| {"653", "Swaziland", "SZ"}, |
| {"240", "Sweden", "SE"}, |
| {"228", "Switzerland", "CH"}, |
| {"417", "Syria", "SY"}, |
| {"466", "Taiwan", "TW"}, |
| {"436", "Tajikistan", "TJ"}, |
| {"640", "Tanzania", "TZ"}, |
| {"520", "Thailand", "TH"}, |
| {"539", "Tonga", "TO"}, |
| {"374", "Trinidad", "TT"}, |
| {"605", "Tunisia", "TN"}, |
| {"286", "Turkey", "TR"}, |
| {"438", "Turkmenistan", "TM"}, |
| {"376", "Turks(TC)", "TC"}, |
| {"553", "Tuvalu", ""}, |
| {"641", "Uganda", "UG"}, |
| {"255", "UKraine", "UA"}, |
| {"424", "Arab Emirates", "AE"}, |
| {"234", "United Kingdom", "GB"}, |
| {"310", "Guam", "US"}, |
| {"311", "USA", "US"}, |
| {"313", "USA", "US"}, |
| {"316", "USA", "US"}, |
| {"748", "Uruguay", "UY"}, |
| {"434", "Uzbekistan", "UZ"}, |
| {"541", "Vanuatu", "VU"}, |
| {"225", "Vatican", "VA"}, |
| {"734", "Venezuela", "VE"}, |
| {"452", "Vietnam", "VN"}, |
| {"421", "Yemen", "YE"}, |
| {"645", "Zambia", "ZM"}, |
| {"648", "Zimbabwe", "ZW"}, |
| }; |
| |
| /* Domain and country mapping */ |
| static char FCCDomain_Countries[][4] = { |
| "AE", "AM", "AN", "AR", "AU", "AZ", "BH", "BL", "BN", "BR", "CL", "CN", "CR", "CS", "DZ", "EC", |
| "EG", "GE", "GB", "HN", "HK", "ID", "IL", "IN", "IR", "JM", "JO", "KP", "KR", "KW", "KZ", "LB", |
| "LK", "MA", "MO", "MY", "NP", "OM", "PE", "PG", "PH", "PK", "PT", "QA", "SA", "SG", "SV", "SY", |
| "TH", "TT", "TN", "UY", "YE", "ZA", "ZW", "VN" |
| }; |
| |
| static char FCC1Domain_Countries[][4] = { |
| "US", "UZ", "CA", "CO", "DO", "GT", "MX", "PA", "PR", "TW", "NZ", "BO", "BZ", "VE" |
| }; |
| |
| static char MKKDomain_Countries[][4] = { "JP" }; |
| |
| |
| static char ETSIDomain_Countries[][4] = { |
| "AL", "AD", "AT", "BY", "BE", "BA", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", |
| "MK", "DE", "GR", "HU", "IS", "IE", "IT", "LV", "LI", "LT", "LU", "MT", "MD", "MC", |
| "ME", "NL", "NO", "PL", "RO", "RU", "SM", "RS", "SI", "SK", "ES", "SE", "CH", "TR", |
| "UA", "UK" |
| }; |
| |
| /* Domain specific sub-band information */ |
| /* Domain name followed by set of triplets separated by comma */ |
| /* 1st number in triplet is First channel, */ |
| /* 2nd number in triplet is Number of channels followed from the First channel */ |
| /* 3rd number in triplet is Max-TX-power in dbm */ |
| static int FCCDomain_Subband[3] = {1, 13, 20}; |
| static int FCC1Domain_Subband[3] = {1, 11, 30}; |
| static int ETSIDomain_Subband[3] = {1, 13, 20}; |
| static int MKKDomain_Subband[3] = {1, 14, 23}; |
| |
| #define HOSTAPD_SER "hostapd.uap0" |
| #define HOSTAPD_SER_PREFIX "hostapd" |
| static char hostapd_obj_name[32]; |
| static int active_clients[MAX_WIFI_CHIP_NUM] = {0}; |
| static int wifi_status[MAX_WIFI_CHIP_NUM] = {WIFI_OFF, WIFI_OFF}; |
| struct wireless_info g_wireless_info; |
| int g_isolate_status; |
| int g_current_ap; |
| int ssid_change_notify(struct ubus_context *ctx, char *new_ssid); |
| void wifi_server_main(void); |
| |
| extern struct uci_context *uci_applet_ctx_get(void); |
| extern void free_applet_uci_ctx(void); |
| //extern void obj_cm_add_ev(struct ubus_context *ctx, char *obj_path); |
| |
| static struct uci_context *uci_wifi_ctx_get(void) |
| { |
| return uci_applet_ctx_get(); |
| } |
| |
| static void wireless_package_info_uci_sec_reset() |
| { |
| struct wireless_info *info = &g_wireless_info; |
| int i; |
| |
| for (i = 0; i < MAX_WIFI_CHIP_NUM; i++) { |
| memset(&(info->wifi_info[i].ap_2G), 0, sizeof(info->wifi_info[i].ap_2G)); |
| memset(&(info->wifi_info[i].ap_5G), 0, sizeof(info->wifi_info[i].ap_5G)); |
| memset(&(info->wifi_info[i].sta), 0, sizeof(info->wifi_info[i].sta)); |
| info->wifi_info[i].chip = NULL; |
| } |
| |
| info->chip = NULL; |
| info->sec_bs = NULL; |
| } |
| |
| static void free_wifi_uci_ctx(void) |
| { |
| free_applet_uci_ctx(); |
| wireless_package_info_uci_sec_reset(); |
| } |
| |
| static int wireless_load_config_package(struct uci_context *local_ctx, const char *config_file, struct uci_package **package) |
| { |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, config_file) != 0) |
| continue; |
| p = uci_to_package(e); |
| break; |
| } |
| if (!p) { |
| uci_load(local_ctx, config_file, &p); |
| } |
| if (!p) { |
| return -1; |
| } |
| |
| *package = p; |
| return 0; |
| } |
| |
| |
| /*=============================================================================== |
| * API: IMSI_MATCH_COUNTRYCode |
| * Return : if found , Country(In English),Please do not free return pointer |
| * If not found, NULL. |
| *===============================================================================*/ |
| static char * match_country_code_by_imsi(char *imsi) |
| { |
| unsigned int array_size = 0; |
| |
| if (!imsi ||strlen(imsi) < 14 ) { |
| WIFI_ERR("Leave, IMSI ERROR"); |
| return NULL; |
| } |
| |
| WIFI_DBG("IMSI %s", imsi); |
| for (array_size = 0; array_size < ARRAY_SIZE(MrvlMccCountryTable); array_size++) { |
| if (!strncmp(imsi, MrvlMccCountryTable[array_size].mcc, 3)) { |
| WIFI_ERR("Leave, match Country %s", MrvlMccCountryTable[array_size].country); |
| return MrvlMccCountryTable[array_size].ccode; |
| } |
| } |
| return NULL; |
| } |
| |
| /*get IMSI from tmp file*/ |
| static int get_imsi_from_tmp_file(char *imsi_buf, int buf_size) |
| { |
| int fd = 0, size = 0; |
| |
| fd = open(IMSI_FILE, O_RDONLY); |
| |
| if (fd < 0) { |
| /*File not exist or no read access*/ |
| return -1; |
| } |
| |
| size = read(fd, imsi_buf, buf_size - 1); |
| if (size < 0) { |
| /*read fail*/ |
| close(fd); |
| return -1; |
| } |
| |
| close(fd); |
| return 0; |
| } |
| |
| static const char *get_conuntry_code() |
| { |
| char imsi[32] = { '\0' }; |
| |
| if (get_imsi_from_tmp_file(imsi, 32) != 0) { |
| WIFI_ERR("get imsi from file fail"); |
| return NULL; |
| } |
| |
| char *ccode = match_country_code_by_imsi(imsi); |
| if (ccode == NULL) { |
| WIFI_ERR("no match country code with imsi %s", imsi); |
| return NULL; |
| } |
| |
| return ccode; |
| } |
| |
| /*WIFI channel range match from IMSI*/ |
| static void get_wifi_channel_range(int *first, int *last) |
| { |
| int i = 0; |
| int limit; |
| int found = 0; |
| char imsi[32] = { '\0' }; |
| static int sf = 0; |
| static int sl = 0; |
| |
| if (sf != 0 && sl != 0) { |
| *first = sf; |
| *last = sl; |
| return; |
| } |
| |
| if (get_imsi_from_tmp_file(imsi, 32) != 0) { |
| goto cfound; |
| } |
| |
| char *ccode = match_country_code_by_imsi(imsi); |
| if (ccode == NULL) { |
| goto cfound; |
| } |
| |
| WIFI_DBG("country code is %s", ccode); |
| /* Search specific domain name */ |
| limit = sizeof(FCCDomain_Countries)/4; |
| for (i = 0; i < limit; i++) { |
| if (!strcmp(FCCDomain_Countries[i], ccode)) { |
| found = 1; |
| *first = FCCDomain_Subband[0]; |
| *last = FCCDomain_Subband[0] + FCCDomain_Subband[1] -1; |
| goto cfound; |
| } |
| } |
| |
| limit = sizeof(FCC1Domain_Countries)/4; |
| for (i = 0; i < limit; i++) { |
| if (!strcmp(FCC1Domain_Countries[i], ccode)) { |
| found = 1; |
| *first = FCC1Domain_Subband[0]; |
| *last = FCC1Domain_Subband[0] + FCC1Domain_Subband[1] - 1; |
| goto cfound; |
| } |
| } |
| |
| limit = sizeof(MKKDomain_Countries)/4; |
| for (i = 0; i < limit; i++) { |
| if (!strcmp(MKKDomain_Countries[i], ccode)) { |
| found = 1; |
| *first = MKKDomain_Subband[0]; |
| *last = MKKDomain_Subband[0] + MKKDomain_Subband[1] - 1; |
| goto cfound; |
| } |
| } |
| |
| limit = sizeof(ETSIDomain_Countries)/4; |
| for (i = 0; i < limit; i++) { |
| if (!strcmp(ETSIDomain_Countries[i], ccode)) { |
| found = 1; |
| *first = ETSIDomain_Subband[0]; |
| *last = ETSIDomain_Subband[0] + ETSIDomain_Subband[1] - 1; |
| goto cfound; |
| } |
| } |
| |
| cfound: |
| if (found == 0) { |
| *first = 1; |
| *last = 11; |
| } |
| |
| sf = *first; |
| sl = *last; |
| |
| WIFI_DBG("first channel is %d, last channel is %d", *first, *last); |
| return; |
| } |
| |
| static char g_wireless_ifname[MAX_WIFI_CHIP_NUM][MAX_DEV_NAME_LEN]; |
| static const char *get_wireless_ifname(int ap_index) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| const char *option_value = NULL; |
| char ap_name[32] = { 0 }; |
| |
| |
| if (ap_index >= MAX_WIFI_CHIP_NUM) |
| return NULL; |
| |
| if (strlen(g_wireless_ifname[ap_index])) |
| return g_wireless_ifname[ap_index]; |
| |
| /*load /etc/config/wireless */ |
| local_ctx = (struct uci_context *)uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| goto exit; |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) |
| goto exit; |
| |
| uci_foreach_element(&p->sections, e) |
| { |
| uci_sec = uci_to_section(e); |
| if (uci_sec) |
| { |
| if (strcmp(uci_sec->type, WIFI_SECTION_IFACE) == 0) |
| { |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "ifname"); |
| if (option_value) |
| { |
| snprintf(ap_name, sizeof(ap_name), "AP%d", ap_index); |
| WIFI_DBG( "get wireless iface name %s, ap_name %s", option_value, ap_name); |
| if (strstr(uci_sec->e.name, ap_name)) |
| { |
| strncpy(g_wireless_ifname[ap_index], option_value, MAX_DEV_NAME_LEN - 1); |
| return option_value; |
| } |
| } |
| } |
| } |
| } |
| |
| exit: |
| WIFI_DBG( " no value found"); |
| return NULL; |
| } |
| |
| static char *get_hostapd_obj_name(int ap_index) |
| { |
| const char *ifname = get_wireless_ifname(ap_index); |
| if (ifname) |
| { |
| snprintf(hostapd_obj_name, 32, "%s.%s", HOSTAPD_SER_PREFIX, ifname); |
| } |
| else |
| snprintf(hostapd_obj_name, 32, "%s", HOSTAPD_SER); |
| |
| return hostapd_obj_name; |
| } |
| |
| static int wireless_lookup_hostapd_id(unsigned int *id, int ap_index) |
| { |
| char *hostapd_name = get_hostapd_obj_name(ap_index); |
| |
| if (hostapd_name) |
| { |
| if (ubus_lookup_id(applet_ubus_ctx, hostapd_name, id) == 0) { |
| WIFI_ERR("Lookup object %s SUCCESS with id 0x%x", hostapd_name, id); |
| wifi_status[ap_index] = WIFI_READY; |
| return 0; |
| } |
| } |
| |
| return -1; |
| } |
| |
| #define ASRWIFI_VERSION_FILE "/sys/kernel/debug/ieee80211/asrphy0/asr/wifi_version" |
| #define ASRWIFI6_VERSION_FILE "/sys/kernel/debug/ieee80211/asrphy0/asr_80211ax/wifi_version" |
| #define ASRWIFI_TYPE "asr5803" |
| #define ASRWIFI6_TYPE "asr5861" |
| #define ASRWIFI6_SBAND_TYPE "asr5811" |
| |
| static int read_chip_type_from_sys(void) |
| { |
| FILE *fp = NULL; |
| int nread = 0, type = 0; |
| char read_buf[64]; |
| |
| fp = fopen(ASRWIFI_VERSION_FILE, "r"); |
| if (fp) { |
| memset(read_buf, 0, sizeof(read_buf)); |
| nread = fread(read_buf, sizeof(char), sizeof(read_buf) - 1, fp); |
| WIFI_DBG("wifi_version %s", read_buf); |
| if (nread > 0 && strstr(read_buf, ASRWIFI_TYPE)) { |
| type = 1; |
| goto end; |
| } |
| } |
| else |
| { |
| fp = fopen(ASRWIFI6_VERSION_FILE, "r"); |
| if (fp) { |
| memset(read_buf, 0, sizeof(read_buf)); |
| nread = fread(read_buf, sizeof(char), sizeof(read_buf) - 1, fp); |
| WIFI_DBG("wifi6_version %s", read_buf); |
| if (nread > 0 && strstr(read_buf, ASRWIFI6_TYPE)) { |
| type = 2; |
| goto end; |
| } |
| else if (nread > 0 && strstr(read_buf, ASRWIFI6_SBAND_TYPE)) { |
| type = 3; |
| goto end; |
| } |
| |
| } |
| } |
| |
| end: |
| if (fp) |
| fclose(fp); |
| |
| return type; |
| } |
| |
| int chip_type_support_dual_ap() |
| { |
| if (read_chip_type_from_sys() == 2) |
| return true; |
| else |
| return false; |
| } |
| static int parse_wireless_package_info(struct uci_context *uci_ctx, struct uci_package *p, struct wireless_info *w_info) |
| { |
| struct uci_element *e = NULL; |
| struct wireless_info *info = w_info; |
| struct uci_section *uci_sec = NULL; |
| const char *option_value = NULL; |
| int i, n_2G_ssid = 0, n_5G_ssid = 0; |
| |
| if(!uci_ctx || !p || !info) { |
| return -1; |
| } |
| |
| memset(info, 0, sizeof(struct wireless_info)); |
| if (wifi_status[WIFI_AP0] == NO_WIFI) { |
| WIFI_ERR("%s: NO WIFI card", __func__); |
| info->n_dev = 0; |
| return 0; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WIFI_SECTION_DEVICE) == 0) { |
| WIFI_DBG("find one wifi-device, section name is %s", uci_sec->e.name); |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "hwmode"); |
| if (option_value) { |
| WIFI_DBG("hwmode value is %s", option_value); |
| if (strchr(option_value, 'a')) { |
| if (strstr(uci_sec->e.name, "AP0")) { |
| if (strstr(uci_sec->e.name, "5G")) { |
| info->wifi_info[WIFI_AP0].ap_5G.device = uci_sec; |
| info->wifi_5g_index = WIFI_AP0; |
| } |
| else { |
| info->wifi_info[WIFI_AP0].ap_2G.device = uci_sec; |
| info->wifi_24g_index= WIFI_AP0; |
| } |
| |
| //info->n_dev = info->n_dev < 1 ? 1 : info->n_dev; |
| info->n_dev++; |
| } else if (strstr(uci_sec->e.name, "AP1")) { |
| if (strstr(uci_sec->e.name, "5G")) { |
| info->wifi_info[WIFI_AP1].ap_5G.device = uci_sec; |
| info->wifi_5g_index = WIFI_AP1; |
| } |
| else { |
| info->wifi_info[WIFI_AP1].ap_2G.device = uci_sec; |
| info->wifi_24g_index= WIFI_AP1; |
| } |
| //info->n_dev = info->n_dev < 2 ? 2 : info->n_dev; |
| info->n_dev++; |
| } |
| } else { |
| if (strstr(uci_sec->e.name, "AP0")) { |
| info->wifi_info[WIFI_AP0].ap_2G.device = uci_sec; |
| info->wifi_24g_index= WIFI_AP0; |
| //info->n_dev = info->n_dev < 1 ? 1 : info->n_dev; |
| info->n_dev++; |
| } else if(strstr(uci_sec->e.name, "AP1")) { |
| info->wifi_info[WIFI_AP1].ap_2G.device = uci_sec; |
| info->wifi_24g_index= WIFI_AP1; |
| //info->n_dev = info->n_dev < 2 ? 2 : info->n_dev; |
| info->n_dev++; |
| } |
| } |
| } else { |
| if (strstr(uci_sec->e.name, "STA0")) { |
| info->wifi_info[WIFI_AP0].sta.device = uci_sec; |
| } else if (strstr(uci_sec->e.name, "STA1")) { |
| info->wifi_info[WIFI_AP1].sta.device = uci_sec; |
| } |
| } |
| } else if (strcmp(uci_sec->type, WIFI_SECTION_IFACE) == 0) { |
| WIFI_DBG("find one wifi-iface, section name is %s", uci_sec->e.name); |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "device"); |
| if (option_value) { |
| WIFI_DBG("device value is %s", option_value); |
| for ( i = 0; i < MAX_WIFI_CHIP_NUM; i++) { |
| if (info->wifi_info[i].ap_2G.device) { |
| if (strcmp(option_value, info->wifi_info[i].ap_2G.device->e.name) == 0) { |
| WIFI_DBG("find wifi-iface(24G)"); |
| n_2G_ssid = info->wifi_info[i].ap_2G.n_ssid; |
| info->wifi_info[i].ap_2G.iface[n_2G_ssid]= uci_sec; |
| info->wifi_info[i].ap_2G.n_ssid++; |
| break; |
| } |
| } |
| |
| if (info->wifi_info[i].ap_5G.device) { |
| if (strcmp(option_value, info->wifi_info[i].ap_5G.device->e.name) == 0) { |
| WIFI_DBG("find wifi-iface(5G)"); |
| n_5G_ssid = info->wifi_info[i].ap_5G.n_ssid; |
| info->wifi_info[i].ap_5G.iface[n_5G_ssid] = uci_sec; |
| info->wifi_info[i].ap_5G.n_ssid++; |
| break; |
| } |
| } |
| } |
| } |
| }else if (strcmp(uci_sec->type, WIFI_SECTION_SETTING) == 0) { |
| WIFI_DBG("find wifi-settings, section name is %s", uci_sec->e.name); |
| if (uci_sec->e.name && !strcmp(uci_sec->e.name, "AP0")) { |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "auto_off_enable"); |
| if (option_value) { |
| info->wifi_info[WIFI_AP0].auto_off_enable= atoi(option_value); |
| } |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "auto_off_timeout"); |
| if (option_value) { |
| info->wifi_info[WIFI_AP0].auto_off_timeout = atoi(option_value); |
| } else { |
| info->wifi_info[WIFI_AP0].auto_off_timeout = MIN_AUTO_OFF_TIMEOUT; |
| } |
| } else if (uci_sec->e.name && !strcmp(uci_sec->e.name, "AP1")) { |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "auto_off_enable"); |
| if (option_value) { |
| info->wifi_info[WIFI_AP1].auto_off_enable= atoi(option_value); |
| } |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "auto_off_timeout"); |
| if (option_value) { |
| info->wifi_info[WIFI_AP1].auto_off_timeout = atoi(option_value); |
| } else { |
| info->wifi_info[WIFI_AP0].auto_off_timeout = MIN_AUTO_OFF_TIMEOUT; |
| } |
| } |
| } else if (strcmp(uci_sec->type, WIFI_SECTION_CHIP) == 0) { |
| WIFI_DBG("find one wifi-device, section name is %s", uci_sec->e.name); |
| info->chip = uci_sec; |
| } else if (strcmp(uci_sec->type, WIFI_SECTION_BS) == 0) { |
| info->sec_bs = uci_sec; |
| option_value = uci_lookup_option_string(uci_ctx, uci_sec, "bs_enable"); |
| if (option_value) { |
| info->band_steering_enable = atoi(option_value); |
| } else { |
| info->band_steering_enable = 0; |
| } |
| } |
| } |
| |
| info->chip_type = read_chip_type_from_sys(); |
| |
| if (info->chip_type == 2 || info->chip_type == 3) |
| info->wifi6 = 1; |
| |
| if (info->chip_type == 2) |
| info->band_steering_support = 1; |
| |
| return 0; |
| } |
| |
| static int my_system(const char *cmd) |
| { |
| FILE *fp; |
| int res; |
| char buf[1024]; |
| if (cmd == NULL) { |
| return -1; |
| } |
| if ((fp = popen(cmd, "r")) == NULL) { |
| WIFI_ERR("popen error: %s/n", strerror(errno)); |
| return -1; |
| } else { |
| while (fgets(buf, sizeof(buf), fp)) { |
| WIFI_DBG("%s", buf); |
| } |
| if ((res = pclose(fp)) == -1) { |
| return res; |
| } else if (res == 0) { |
| return res; |
| } else { |
| WIFI_DBG("popen res is :%d\n", res); |
| return res; |
| } |
| } |
| } |
| |
| enum { |
| RETURN_CODE, |
| __RETURN_MAX, |
| }; |
| |
| static const struct blobmsg_policy return_policy[__RETURN_MAX] = { |
| [RETURN_CODE] = { .name = "rc", .type = BLOBMSG_TYPE_INT32 }, |
| }; |
| |
| static void alarm_task_cb(struct ubus_request *req,int type, |
| struct blob_attr *msg) |
| { |
| struct blob_attr *tb[__RETURN_MAX]; |
| int rc; |
| |
| (void)(req); |
| (void)(type); |
| |
| blobmsg_parse(return_policy, __RETURN_MAX, tb, |
| blob_data(msg), blob_len(msg)); |
| if (!tb[RETURN_CODE]) { |
| fprintf(stderr, "No return code received from server\n"); |
| return; |
| } |
| rc = blobmsg_get_u32(tb[RETURN_CODE]); |
| *(uint32_t *)req->priv = rc; |
| return; |
| } |
| |
| static int shutdown_wifi_auto_off(void) |
| { |
| unsigned int id; |
| int ret, rc; |
| |
| ret = ubus_lookup_id(wifi_ubus_ctx, CHARGER_UBUS_ID, &id); |
| if (ret != UBUS_STATUS_OK) |
| return ret; |
| |
| blob_buf_init(&wifi_buf, 0); |
| blobmsg_add_string(&wifi_buf,"alarm_name", "wifi_alarm"); |
| ret = ubus_invoke(wifi_ubus_ctx, id, "alarm_cancel", wifi_buf.head, |
| alarm_task_cb, &rc,0); |
| if (ret) { |
| WIFI_ERR("%s failed\n", __FUNCTION__); |
| return ret; |
| } |
| |
| APRINTK("wireless: turn off wifi auto_off\n"); |
| WIFI_DBG("wireless: turn off wifi auto_off\n"); |
| return rc; |
| } |
| |
| static int set_wifi_auto_off_on(void) |
| { |
| struct wireless_info *info = &g_wireless_info; |
| unsigned int id; |
| int ret, rc; |
| |
| ret = ubus_lookup_id(wifi_ubus_ctx, CHARGER_UBUS_ID, &id); |
| if (ret != UBUS_STATUS_OK) |
| return ret; |
| blob_buf_init(&wifi_buf, 0); |
| blobmsg_add_u32(&wifi_buf, "time", |
| info->wifi_info[WIFI_AP0].auto_off_timeout); |
| blobmsg_add_string(&wifi_buf,"alarm_name", "wifi_alarm"); |
| ret = ubus_invoke(wifi_ubus_ctx, id, "alarm_set", wifi_buf.head, |
| alarm_task_cb, &rc,0); |
| if (ret) { |
| WIFI_ERR("%s failed\n", __FUNCTION__); |
| return ret; |
| } |
| |
| if (rc) |
| WIFI_ERR("%s failed rc=%d\n", __FUNCTION__, rc); |
| |
| APRINTK("wireless: enable wifi auto_off, timeout=%dsec ----->\n", |
| info->wifi_info[WIFI_AP0].auto_off_timeout); |
| |
| WIFI_DBG("wireless: enable wifi auto_off, timeout=%dsec ----->\n", |
| info->wifi_info[WIFI_AP0].auto_off_timeout); |
| return rc; |
| } |
| |
| static int init_wifi_settings(void) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct wireless_info *info = &g_wireless_info; |
| |
| /*load /etc/config/wireless */ |
| local_ctx = (struct uci_context *)uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) |
| goto EXIT; |
| |
| |
| info->wifi_5g_index = -1; |
| info->wifi_24g_index = -1; |
| parse_wireless_package_info(local_ctx, p, info); |
| |
| if (info->wifi_info[WIFI_AP0].auto_off_enable == 1 && |
| active_clients[WIFI_AP0] == 0 && |
| wifi_status[WIFI_AP0] == WIFI_READY) |
| set_wifi_auto_off_on(); |
| |
| EXIT: |
| return 0; |
| } |
| |
| /*listen events from charger,start*/ |
| |
| static int charger_status = 0; |
| enum { |
| ACCH_ONLINE_ID, |
| USBCHG_ONLINE_ID, |
| ALARM_NAME, |
| ONKEY_TYPE, |
| }; |
| |
| static const struct blobmsg_policy charger_pol[] = { |
| [ACCH_ONLINE_ID] = { |
| .name = "acchg_online", |
| .type = BLOBMSG_TYPE_INT32, |
| }, |
| [USBCHG_ONLINE_ID] = { |
| .name = "usbchg_online", |
| .type = BLOBMSG_TYPE_INT32, |
| }, |
| [ALARM_NAME] = { |
| .name = "alarm_name", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [ONKEY_TYPE] = { |
| .name = "type", |
| .type = BLOBMSG_TYPE_INT32, |
| }, |
| }; |
| |
| static void get_charger_data_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| struct blob_attr *charger_data[ARRAY_SIZE(charger_pol)]; |
| int acch_online = 0; |
| int usbchg_online = 0; |
| |
| UNUSESET(type); |
| UNUSESET(req); |
| |
| if (blobmsg_parse(charger_pol, ARRAY_SIZE(charger_pol), charger_data, blob_data(msg), blob_len(msg)) != 0) { |
| return; |
| } |
| if (!charger_data[ACCH_ONLINE_ID] || !charger_data[USBCHG_ONLINE_ID]) { |
| return; |
| } |
| if (charger_data[ACCH_ONLINE_ID]) |
| acch_online = blobmsg_get_u32(charger_data[ACCH_ONLINE_ID]); |
| if (charger_data[USBCHG_ONLINE_ID]) |
| usbchg_online = blobmsg_get_u32(charger_data[USBCHG_ONLINE_ID]); |
| |
| if (acch_online || usbchg_online) { |
| charger_status = 1; |
| shutdown_wifi_auto_off(); |
| |
| } |
| return; |
| } |
| |
| static void charger_complete_cb(struct ubus_request *req, int ret) |
| { |
| UNUSESET(ret); |
| free(req); |
| return; |
| } |
| |
| static int invoke_to_get_charger_data(struct ubus_context *ctx) |
| { |
| uint32_t id; |
| struct ubus_request *req = NULL; |
| int ret; |
| |
| /* Look up the target object id by the object path */ |
| ret = ubus_lookup_id(ctx, CHARGER_UBUS_ID, &id); |
| if (ret) |
| return ret; |
| |
| req = malloc(sizeof(*req)); |
| if (!req) { |
| WIFI_ERR("malloc fail"); |
| ret = -1; |
| return ret; |
| } |
| memset(req, 0, sizeof(*req)); |
| |
| ret = ubus_invoke_async(ctx, id, CHARGER_UBUS_REQUEST, NULL, req); |
| if (ret) { |
| WIFI_ERR("ubus_invoke_async error %d", ret); |
| return ret; |
| } |
| |
| /*these cb initializations are after ubus_invoke_async() because ubus_invoke_async() zeros req */ |
| req->data_cb = get_charger_data_cb; |
| req->complete_cb = charger_complete_cb; |
| |
| ubus_complete_request_async(ctx, req); |
| |
| return 0; |
| } |
| |
| static int |
| charger_event_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *charger_data[ARRAY_SIZE(charger_pol)]; |
| struct wireless_info *info = &g_wireless_info; |
| int acch_online = 0; |
| int usbchg_online = 0; |
| |
| UNUSESET(obj); |
| UNUSESET(ctx); |
| UNUSESET(req); |
| UNUSESET(method); |
| |
| if (blobmsg_parse(charger_pol, ARRAY_SIZE(charger_pol), charger_data, |
| blob_data(msg), blob_len(msg)) != 0) { |
| return UBUS_STATUS_INVALID_ARGUMENT; |
| } |
| |
| if (!strcmp(method, "alarm_triggered") && charger_data[ALARM_NAME]) { |
| if (!strcmp(blobmsg_get_string(charger_data[ALARM_NAME]), |
| "wifi_alarm")) { |
| my_system("echo wifi.lock 1000000000 > /sys/power/wake_lock"); |
| my_system("/sbin/wifi down"); |
| } |
| return 0; |
| } |
| |
| if (!strcmp(method, "onkey_pressed") && charger_data[ONKEY_TYPE]) { |
| if (blobmsg_get_u32(charger_data[ONKEY_TYPE]) == 0 && |
| wifi_status[WIFI_AP0] == WIFI_OFF) { |
| wifi_status[WIFI_AP0] = WIFI_START; |
| my_system("echo wifi.lock 20000000000 > /sys/power/wake_lock"); |
| my_system("/sbin/wifi up"); |
| } |
| return 0; |
| } |
| |
| if (!charger_data[ACCH_ONLINE_ID] || !charger_data[USBCHG_ONLINE_ID]) { |
| return UBUS_STATUS_NO_DATA; |
| } |
| |
| if (charger_data[ACCH_ONLINE_ID]) { |
| acch_online = blobmsg_get_u32(charger_data[ACCH_ONLINE_ID]); |
| } |
| if (charger_data[USBCHG_ONLINE_ID]) { |
| usbchg_online = blobmsg_get_u32(charger_data[USBCHG_ONLINE_ID]); |
| } |
| |
| if (acch_online || usbchg_online) { |
| charger_status = 1; |
| if (info->wifi_info[WIFI_AP0].auto_off_enable == 1) { |
| shutdown_wifi_auto_off(); |
| } |
| } else { |
| /*charger status from on to off */ |
| if (charger_status == 1) { |
| if (info->wifi_info[WIFI_AP0].auto_off_enable == 1 && |
| active_clients[WIFI_AP0] == 0 && |
| wifi_status[WIFI_AP0] == WIFI_READY) { |
| set_wifi_auto_off_on(); |
| } |
| } |
| charger_status = 0; |
| } |
| return 0; |
| |
| } |
| |
| /* statistics get_active_clients_num*/ |
| enum { |
| ATTR_CLIENTS_INFO, |
| ATTR_ACTIVE_CLIENTS_NUM, |
| ATTR_USB_STATE, |
| ATTR_WLAN_CLIENTS, |
| ATTR_WLAN1_CLIENTS |
| }; |
| |
| static const struct blobmsg_policy active_clients_num_attr_policy[] = { |
| [ATTR_CLIENTS_INFO] = {.name = "clients_info", .type = BLOBMSG_TYPE_TABLE}, |
| [ATTR_ACTIVE_CLIENTS_NUM] = {.name = "active_clients_num", .type = BLOBMSG_TYPE_STRING}, |
| [ATTR_USB_STATE] = {.name = "usb_state", .type = BLOBMSG_TYPE_STRING}, |
| [ATTR_WLAN_CLIENTS] = {.name = "wlan_clients", .type = BLOBMSG_TYPE_STRING}, |
| [ATTR_WLAN1_CLIENTS] = {.name = "wlan1_clients", .type = BLOBMSG_TYPE_STRING}, |
| }; |
| |
| static void get_client_number_cb(struct ubus_request *req, int type, |
| struct blob_attr *msg) |
| { |
| struct blob_attr *tb[ARRAY_SIZE(active_clients_num_attr_policy)]; |
| struct wireless_info *info = &g_wireless_info; |
| int clients_num = 0, usb_state = 0; |
| int ret; |
| int wlan_clients = 0, wlan1_clients = 0; |
| |
| UNUSESET(type); |
| UNUSESET(req); |
| |
| ret = blobmsg_parse(active_clients_num_attr_policy, |
| ARRAY_SIZE(active_clients_num_attr_policy), |
| tb, blob_data(msg), blob_len(msg)); |
| if (ret){ |
| WIFI_ERR("parsing clients_num blobmsg failed %d\n", ret); |
| return; |
| } |
| if (!tb[ATTR_CLIENTS_INFO]) |
| return; |
| |
| ret = blobmsg_parse(active_clients_num_attr_policy, |
| ARRAY_SIZE(active_clients_num_attr_policy), tb, |
| blobmsg_data(tb[ATTR_CLIENTS_INFO]), |
| blobmsg_data_len(tb[ATTR_CLIENTS_INFO])); |
| if (ret){ |
| WIFI_ERR("parsing clients_num blobmsg failed %d\n", ret); |
| return; |
| } |
| if (!tb[ATTR_ACTIVE_CLIENTS_NUM] || !tb[ATTR_USB_STATE] || !tb[ATTR_WLAN_CLIENTS] || !tb[ATTR_WLAN1_CLIENTS]) { |
| WIFI_ERR("parsing clients_num blobmsg failed %d\n", ret); |
| return; |
| } |
| |
| clients_num = atoi(blobmsg_get_string(tb[ATTR_ACTIVE_CLIENTS_NUM])); |
| usb_state = atoi(blobmsg_get_string(tb[ATTR_USB_STATE])); |
| wlan_clients = atoi(blobmsg_get_string(tb[ATTR_WLAN_CLIENTS])); |
| wlan1_clients = atoi(blobmsg_get_string(tb[ATTR_WLAN1_CLIENTS])); |
| |
| WIFI_ERR("all_clients_num %d, usb_state %d, wlan_clients %d, wlan1_clients %d\n", clients_num, usb_state); |
| if (clients_num > 0 && usb_state == 1) |
| clients_num --; |
| |
| if (info->wifi_info[WIFI_AP0].auto_off_enable) { |
| if ((active_clients[WIFI_AP0] > 0) && |
| (wlan_clients == 0)) { |
| set_wifi_auto_off_on(); |
| } |
| else if ((active_clients[WIFI_AP0] == 0) && |
| (wlan_clients > 0)) { |
| shutdown_wifi_auto_off(); |
| } |
| } |
| active_clients[WIFI_AP0] = wlan_clients; |
| |
| if (info->wifi_info[WIFI_AP1].auto_off_enable) { |
| if ((active_clients[WIFI_AP1] > 0) && |
| (wlan1_clients == 0)) { |
| set_wifi_auto_off_on(); |
| } |
| else if ((active_clients[WIFI_AP1] == 0) && |
| (wlan1_clients > 0)) { |
| shutdown_wifi_auto_off(); |
| } |
| } |
| active_clients[WIFI_AP1] = wlan1_clients; |
| |
| return; |
| } |
| |
| //static void get_client_number_complete_cb(struct ubus_request *req, int ret) |
| //{ |
| // UNUSESET(ret); |
| // free(req); |
| // return; |
| //} |
| |
| #if 1 |
| static int invoke_to_get_client_number(struct ubus_context *ctx) |
| { |
| uint32_t id; |
| //struct ubus_request *req = NULL; |
| int ret; |
| |
| /* Look up the target object id by the object path */ |
| ret = ubus_lookup_id(ctx, "statistics", &id); |
| if (ret) |
| return ret; |
| //req = malloc(sizeof(*req)); |
| //if (!req) { |
| // WIFI_ERR("malloc fail"); |
| // ret = -1; |
| // return ret; |
| //} |
| //memset(req, 0, sizeof(*req)); |
| ret = ubus_invoke(ctx, id, "get_active_clients_num", NULL, |
| get_client_number_cb, NULL, 0); |
| if (ret) { |
| WIFI_ERR("ubus_invoke error %d", ret); |
| return ret; |
| } |
| //ret = ubus_invoke_async(ctx, id, "get_active_clients_num", NULL, req); |
| //if (ret) { |
| // WIFI_ERR("ubus_invoke_async error %d", ret); |
| // return ret; |
| //} |
| //req->data_cb = get_client_number_cb; |
| //req->complete_cb = get_client_number_complete_cb; |
| //req->priv = ctx; |
| //ubus_complete_request(ctx, req, 0); |
| return 0; |
| } |
| |
| /*listen events from charger*/ |
| static int listen_to_charger_ser(struct ubus_context *ctx) |
| { |
| unsigned int id; |
| int ret; |
| |
| if (ubus_lookup_id(ctx, CHARGER_UBUS_ID, &id)) { |
| return -1; |
| } |
| |
| charger_event.cb = charger_event_cb; |
| ret = ubus_subscribe(ctx, &charger_event, id); |
| WIFI_DBG("watching object %08x: %s", id, ubus_strerror(ret)); |
| return ret; |
| } |
| #endif |
| |
| void wps_status_clear_cb(struct uloop_timeout *timeout) |
| { |
| int i; |
| for (i = 0; i < MAX_WIFI_CHIP_NUM; i++ ) |
| memset(&g_wps_info[i], 0, sizeof(struct wps_conn_info)); |
| |
| uloop_timeout_cancel(timeout); |
| return; |
| } |
| |
| static int |
| hostapd_event_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *hostapd_wps_event_attr[ARRAY_SIZE(wps_event_pol)]; |
| char mac_str[20] = { 0 }; |
| char cmd[32] = { 0 }; |
| |
| UNUSESET(obj); |
| UNUSESET(ctx); |
| UNUSESET(req); |
| |
| if (blobmsg_parse(wps_event_pol, ARRAY_SIZE(wps_event_pol), hostapd_wps_event_attr, blob_data(msg), blob_len(msg)) != 0) { |
| return UBUS_STATUS_INVALID_ARGUMENT; |
| } |
| if (!hostapd_wps_event_attr[0] ) { |
| return UBUS_STATUS_NO_DATA; |
| } |
| |
| strncpy(mac_str, blobmsg_get_string(hostapd_wps_event_attr[0]), 18); |
| WIFI_DBG("WPS client mac %s, event %s", mac_str, method); |
| if (!strcmp(method, HOSTAPD_EV_WPS_START)) { |
| g_wps_info[WIFI_AP0].wps_status = WPS_STATUS_START; |
| if (g_wps_conn_ctx.ap_5g_index == WIFI_AP0) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_PREFER) |
| g_wps_conn_ctx.state = WPS_STATE_5G_START; |
| } |
| uloop_timeout_cancel(&wps_status_clear_timeout); |
| uloop_timeout_set(&wps_status_clear_timeout, WPS_STATUS_CLEAR_TIMEOUT); |
| } else if (!strcmp(method, HOSTAPD_EV_WPS_SUCCESS)) { |
| if (g_wps_conn_ctx.ap_5g_index == WIFI_AP0) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_START) |
| g_wps_conn_ctx.state = WPS_STATE_5G_SUCCESS; |
| } |
| g_wps_info[WIFI_AP0].wps_status = WPS_STATUS_SUCCESS; |
| } else if (!strcmp(method, HOSTAPD_EV_WPS_FAIL)) { |
| if (g_wps_conn_ctx.ap_5g_index== WIFI_AP0) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_START) { |
| g_wps_conn_ctx.state = WPS_STATE_5G_FAIL; |
| g_wps_info[WIFI_AP0].wps_status = WPS_STATUS_START; |
| |
| WIFI_DBG("try auto connect to band 24G with method %d for AP %d", g_wps_conn_ctx.method, g_wps_conn_ctx.ap_24g_index); |
| if (g_wps_conn_ctx.method == 0) |
| snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s wps_pbc", get_wireless_ifname(g_wps_conn_ctx.ap_24g_index)); |
| else if (g_wps_conn_ctx.method == 1) |
| snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s wps_pin any %s", get_wireless_ifname(g_wps_conn_ctx.ap_24g_index), g_wps_conn_ctx.pin); |
| |
| if (strlen(cmd) > 0) { |
| if (my_system(cmd) == 0) { |
| g_wps_conn_ctx.state = WPS_STATE_24G_START; |
| } |
| else { |
| g_wps_conn_ctx.state = WPS_STATE_24G_FAIL; |
| g_wps_info[WIFI_AP0].wps_status = WPS_STATUS_FAIL; |
| g_wps_conn_ctx.ap_index = g_wps_conn_ctx.ap_24g_index; |
| } |
| } |
| } |
| } |
| else |
| g_wps_info[WIFI_AP0].wps_status = WPS_STATUS_FAIL; |
| } |
| |
| strcpy(g_wps_info[WIFI_AP0].peer_mac, mac_str); |
| |
| return 0; |
| } |
| |
| static int |
| hostapd_wlan1_event_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *hostapd_wps_event_attr[ARRAY_SIZE(wps_event_pol)]; |
| char mac_str[20] = { 0 }; |
| char cmd[32]; |
| |
| UNUSESET(obj); |
| UNUSESET(ctx); |
| UNUSESET(req); |
| |
| if (blobmsg_parse(wps_event_pol, ARRAY_SIZE(wps_event_pol), hostapd_wps_event_attr, blob_data(msg), blob_len(msg)) != 0) { |
| return UBUS_STATUS_INVALID_ARGUMENT; |
| } |
| if (!hostapd_wps_event_attr[0] ) { |
| return UBUS_STATUS_NO_DATA; |
| } |
| |
| strncpy(mac_str, blobmsg_get_string(hostapd_wps_event_attr[0]), 18); |
| WIFI_DBG("WPS client mac %s, event %s", mac_str, method); |
| if (!strcmp(method, HOSTAPD_EV_WPS_START)) { |
| g_wps_info[WIFI_AP1].wps_status = WPS_STATUS_START; |
| if (g_wps_conn_ctx.ap_5g_index == WIFI_AP1) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_PREFER) |
| g_wps_conn_ctx.state = WPS_STATE_5G_START; |
| } |
| uloop_timeout_cancel(&wps_status_clear_timeout); |
| uloop_timeout_set(&wps_status_clear_timeout, WPS_STATUS_CLEAR_TIMEOUT); |
| } else if (!strcmp(method, HOSTAPD_EV_WPS_SUCCESS)) { |
| if (g_wps_conn_ctx.ap_5g_index == WIFI_AP1) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_START) |
| g_wps_conn_ctx.state = WPS_STATE_5G_SUCCESS; |
| } |
| g_wps_info[WIFI_AP1].wps_status = WPS_STATUS_SUCCESS; |
| } else if (!strcmp(method, HOSTAPD_EV_WPS_FAIL)) { |
| if (g_wps_conn_ctx.ap_5g_index== WIFI_AP1) { |
| if (g_wps_conn_ctx.state == WPS_STATE_5G_START) { |
| g_wps_conn_ctx.state = WPS_STATE_5G_FAIL; |
| g_wps_info[WIFI_AP1].wps_status = WPS_STATUS_START; |
| |
| WIFI_DBG("try auto connect to band 24G with method %d for AP %d", g_wps_conn_ctx.method, g_wps_conn_ctx.ap_24g_index); |
| if (g_wps_conn_ctx.method == 0) |
| snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s wps_pbc", get_wireless_ifname(g_wps_conn_ctx.ap_24g_index)); |
| else if (g_wps_conn_ctx.method == 1) |
| snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s wps_pin any %s", get_wireless_ifname(g_wps_conn_ctx.ap_24g_index), g_wps_conn_ctx.pin); |
| |
| if (strlen(cmd) > 0) { |
| if (my_system(cmd) == 0) { |
| g_wps_conn_ctx.state = WPS_STATE_24G_START; |
| } |
| else { |
| g_wps_conn_ctx.state = WPS_STATE_24G_FAIL; |
| g_wps_info[WIFI_AP1].wps_status = WPS_STATUS_FAIL; |
| g_wps_conn_ctx.ap_index = g_wps_conn_ctx.ap_24g_index; |
| } |
| } |
| } |
| } |
| else |
| g_wps_info[WIFI_AP1].wps_status = WPS_STATUS_FAIL; |
| } |
| |
| strcpy(g_wps_info[WIFI_AP1].peer_mac, mac_str); |
| |
| return 0; |
| } |
| |
| /*listen events from hostapd*/ |
| static int wireless_listen_to_hostapd(struct ubus_context *ctx, int ap_index) |
| { |
| unsigned int id; |
| int ret; |
| char *hostapd_name = get_hostapd_obj_name(ap_index); |
| |
| if (!hostapd_name) { |
| return -1; |
| } |
| |
| if (ubus_lookup_id(ctx, hostapd_name, &id)) { |
| return -1; |
| } |
| |
| if (ap_index == WIFI_AP0) { |
| hostapd_event_subscriber.cb = hostapd_event_cb; |
| ret = ubus_subscribe(ctx, &hostapd_event_subscriber, id); |
| } |
| else if (ap_index == WIFI_AP1) { |
| hostapd_wlan1_event_subscriber.cb = hostapd_wlan1_event_cb; |
| ret = ubus_subscribe(ctx, &hostapd_wlan1_event_subscriber, id); |
| } |
| |
| WIFI_DBG( "watching object 0x%lx: %s", id, ubus_strerror(ret)); |
| return ret; |
| } |
| |
| |
| /*================================================ |
| method: get_wifi_basic_info |
| return : |
| <wireless> |
| <wireless_num/> |
| <AP0> |
| <wifi_if_24G> |
| <switch/> on/off |
| <ssid/> |
| <channel/> |
| </wifi_if_24G> |
| <wifi_if_5G> |
| <switch/> on/off |
| <ssid/> |
| <channel/> |
| </wifi_if_5G> |
| </AP0> |
| </wireless> |
| ================================================*/ |
| static int wifi_get_basic_info_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL; |
| void *tb_24G = NULL, *tb_wireless = NULL, *tb_5G = NULL, *tb_device = NULL, *tb_ssid = NULL; |
| char dev_name[10] = { 0 }, iface_name[10] = { 0 }, s_channel_first[4] = { 0 }, s_channel_last[4] = { 0 }; |
| int i, j, n_2G_ssid = 0, n_5G_ssid = 0, channel_first = 0, channel_last = 0; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| blobmsg_buf_init(&wifi_buf); |
| |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) |
| goto EXIT; |
| |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| |
| for ( i = 0; i < info->n_dev; i++) { |
| if (info->wifi_info[i].ap_2G.device ||info->wifi_info[i].ap_5G.device) { |
| snprintf(dev_name, sizeof(dev_name) - 1, "AP%d", i); |
| } |
| else { |
| continue; |
| } |
| |
| WIFI_DBG("device name %s", dev_name); |
| tb_device = blobmsg_open_table(&wifi_buf, dev_name); |
| dev_sec_24G = info->wifi_info[i].ap_2G.device; |
| dev_sec_5G = info->wifi_info[i].ap_5G.device; |
| |
| if (dev_sec_24G) { |
| tb_24G = blobmsg_open_table(&wifi_buf, "wifi_if_24G"); |
| |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "disabled"); |
| if (option_value) { |
| WIFI_DBG("disabled is %s", option_value); |
| if (strcmp(option_value, "1") == 0) { |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| } else { |
| WIFI_DBG("wifi_status[%d] %d", i, wifi_status[i]); |
| if (wifi_status[i] == WIFI_OFF) |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| else |
| blobmsg_add_string(&wifi_buf, "switch", "on"); |
| } |
| } |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "channel"); |
| if (option_value) { |
| WIFI_DBG("channel is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "channel", option_value); |
| } |
| |
| get_wifi_channel_range(&channel_first, &channel_last); |
| memset(s_channel_first, 0, 4); |
| memset(s_channel_last, 0, 4); |
| snprintf(s_channel_first, 4, "%d", channel_first); |
| snprintf(s_channel_last, 4, "%d", channel_last); |
| blobmsg_add_string(&wifi_buf, "first_channel", s_channel_first); |
| blobmsg_add_string(&wifi_buf, "last_channel", s_channel_last); |
| |
| n_2G_ssid = info->wifi_info[i].ap_2G.n_ssid; |
| for ( j = 0; j < n_2G_ssid; j++) { |
| iface_sec_24G = info->wifi_info[i].ap_2G.iface[j]; |
| snprintf(iface_name, sizeof(iface_name) - 1, "ssid%d", j); |
| |
| tb_ssid = blobmsg_open_table(&wifi_buf, iface_name); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "ssid"); |
| if (option_value) { |
| WIFI_DBG("SSID is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "ssid", option_value); |
| } |
| blobmsg_close_table(&wifi_buf, tb_ssid); |
| } |
| blobmsg_close_table(&wifi_buf, tb_24G); |
| } |
| |
| if (dev_sec_5G) { |
| tb_5G = blobmsg_open_table(&wifi_buf, "wifi_if_24G"); |
| |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "disabled"); |
| if (option_value) { |
| WIFI_DBG("disabled is %s", option_value); |
| if (strcmp(option_value, "1") == 0) { |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| } else { |
| if (wifi_status[i] == WIFI_OFF) |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| else |
| blobmsg_add_string(&wifi_buf, "switch", "on"); |
| } |
| } |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "channel"); |
| if (option_value) { |
| WIFI_DBG("channel is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "channel", option_value); |
| } |
| get_wifi_channel_range(&channel_first, &channel_last); |
| memset(s_channel_first, 0, 4); |
| memset(s_channel_last, 0, 4); |
| snprintf(s_channel_first, 4, "%d", channel_first); |
| snprintf(s_channel_last, 4, "%d", channel_last); |
| blobmsg_add_string(&wifi_buf, "first_channel", s_channel_first); |
| blobmsg_add_string(&wifi_buf, "last_channel", s_channel_last); |
| |
| n_5G_ssid = info->wifi_info[i].ap_5G.n_ssid; |
| for ( j = 0; j < n_5G_ssid; j++) { |
| iface_sec_5G = info->wifi_info[i].ap_5G.iface[j]; |
| snprintf(iface_name, sizeof(iface_name) - 1, "ssid%d", j); |
| |
| tb_ssid = blobmsg_open_table(&wifi_buf, iface_name); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "ssid"); |
| if (option_value) { |
| WIFI_DBG("SSID is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "ssid", option_value); |
| } |
| blobmsg_close_table(&wifi_buf, tb_ssid); |
| } |
| blobmsg_close_table(&wifi_buf, tb_5G); |
| } |
| blobmsg_close_table(&wifi_buf, tb_device); |
| } |
| |
| EXIT: |
| if (tb_wireless) { |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| } |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done"); |
| return 0; |
| }; |
| |
| static void set_current_ap_index(int index) |
| { |
| g_current_ap = index; |
| WIFI_DBG("%s: index %d", __func__, index); |
| } |
| |
| static int get_current_ap_index() |
| { |
| return g_current_ap; |
| } |
| |
| /*================================================ |
| method: get_wifi_detail |
| |
| <wireless> |
| <wireless_num/> |
| <wireless_type/> |
| <AP0> |
| <wifi_if_24G> |
| <switch/> |
| <net_mode/> |
| <channel/> |
| <first_channel/> |
| <last_channel/> |
| <bandwidth/> |
| <hidden/> |
| <isolate/> |
| <ssid/> |
| <encryption> |
| <key> |
| <key1> |
| <key2> |
| <key3> |
| <key4> |
| <wpa_group_rekey/> |
| </wifi_if_24G> |
| <wifi_if_5G> |
| ... |
| </wifi_if_5G> |
| </AP0> |
| </wireless> |
| ================================================*/ |
| static int wifi_get_detail_info_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL, *opt_val = NULL; |
| void *tb_24G = NULL, *tb_wireless = NULL, *tb_5G = NULL, *tb_device = NULL, *tb_ssid = NULL; |
| char dev_name[10] = { 0 }, iface_name[10] = { 0 }, s_channel_first[4] = { 0 }, s_channel_last[4] = { 0 };; |
| int i, j, n_2G_ssid = 0, n_5G_ssid = 0, channel_first = 0, channel_last = 0; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| blobmsg_buf_init(&wifi_buf); |
| |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| goto EXIT; |
| } |
| } |
| |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| |
| blobmsg_add_u32(&wifi_buf, "wireless_num", (unsigned int)info->n_dev); |
| blobmsg_add_u32(&wifi_buf, "wireless_type", (unsigned int)info->chip_type); |
| blobmsg_add_u32(&wifi_buf, "wifi6_support", (unsigned int)info->wifi6); |
| blobmsg_add_u32(&wifi_buf, "current_ap", (unsigned int)g_current_ap); |
| blobmsg_add_u32(&wifi_buf, "bs_support", (unsigned int)info->band_steering_support); |
| blobmsg_add_u32(&wifi_buf, "bs_enable", (unsigned int)info->band_steering_enable); |
| WIFI_DBG("wireless number %d, wireless type %d, wifi6_support %d, currrent_ap %d, bs_support %d, bs_enable %d", |
| info->n_dev, info->chip_type, info->wifi6, g_current_ap, info->band_steering_support, info->band_steering_enable); |
| /*get detail info -- 2.4G begin */ |
| /*form response blobmsg */ |
| for ( i = 0; i < info->n_dev; i++) { |
| |
| if (info->wifi_info[i].sta.device) { |
| sprintf(dev_name, "STA%d", i); |
| /*STA switch */ |
| WIFI_DBG("device name %s", dev_name); |
| tb_device = blobmsg_open_table(&wifi_buf, dev_name); |
| |
| option_value = uci_lookup_option_string(local_ctx, info->wifi_info[i].sta.device, "disabled"); |
| if (option_value) { |
| WIFI_DBG("%s disabled is %s", dev_name, option_value); |
| if (strcmp(option_value, "1") == 0) { |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| } else { |
| blobmsg_add_string(&wifi_buf, "switch", "on"); |
| } |
| } |
| blobmsg_close_table(&wifi_buf, tb_device); |
| } |
| |
| if (info->wifi_info[i].ap_2G.device ||info->wifi_info[i].ap_5G.device) { |
| sprintf(dev_name, "AP%d", i); |
| } |
| else { |
| continue; |
| } |
| |
| WIFI_DBG("device name %s", dev_name); |
| tb_device = blobmsg_open_table(&wifi_buf, dev_name); |
| |
| if (info->wifi_info[i].ap_2G.device && info->wifi_info[i].ap_2G.iface[0]) { |
| tb_24G = blobmsg_open_table(&wifi_buf, "wifi_if_24G"); |
| dev_sec_24G = info->wifi_info[i].ap_2G.device; |
| /*switch */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "disabled"); |
| if (option_value) { |
| WIFI_DBG("disabled is %s", option_value); |
| if (strcmp(option_value, "1") == 0) { |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| } else { |
| WIFI_DBG("wifi_status[%d] %d", i, wifi_status[i]); |
| if (wifi_status[i] == WIFI_OFF) |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| else |
| blobmsg_add_string(&wifi_buf, "switch", "on"); |
| } |
| } |
| /*net_mode 11g/11n/11a/11b */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "hwmode"); |
| if (option_value) { |
| WIFI_DBG("net_mode hwmode is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "net_mode", option_value); |
| } |
| /*bandwidth */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "htmode"); |
| if (option_value) { |
| WIFI_DBG("bandwidth is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "bandwidth", option_value); |
| } |
| /*channel */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "channel"); |
| if (option_value) { |
| WIFI_DBG("channel is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "channel", option_value); |
| } |
| /*channel range*/ |
| get_wifi_channel_range(&channel_first, &channel_last); |
| memset(s_channel_first, 0, 4); |
| memset(s_channel_last, 0, 4); |
| snprintf(s_channel_first, 4, "%d", channel_first); |
| snprintf(s_channel_last, 4, "%d", channel_last); |
| blobmsg_add_string(&wifi_buf, "first_channel", s_channel_first); |
| blobmsg_add_string(&wifi_buf, "last_channel", s_channel_last); |
| |
| n_2G_ssid = info->wifi_info[i].ap_2G.n_ssid; |
| WIFI_DBG("n_2G_ssid number %d", n_2G_ssid); |
| blobmsg_add_u32(&wifi_buf, "n_ssid", n_2G_ssid); |
| |
| /*multi SSID*/ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "unsupport_multi_ssid"); |
| if (option_value) { |
| WIFI_DBG("unsupport multi ssid %s", option_value); |
| blobmsg_add_string(&wifi_buf, "unsupport_multi_ssid", option_value); |
| } |
| |
| for ( j = 0; j < n_2G_ssid; j++ ) { |
| iface_sec_24G = info->wifi_info[i].ap_2G.iface[j]; |
| sprintf(iface_name, "ssid%d", j); |
| |
| tb_ssid = blobmsg_open_table(&wifi_buf, iface_name); |
| |
| /*SSID*/ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "ssid"); |
| if (option_value) { |
| WIFI_DBG("SSID is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "ssid", option_value); |
| } |
| |
| /*hidden */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "hidden"); |
| if (option_value) { |
| WIFI_DBG("hidden is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "hidden", option_value); |
| } |
| /*isolate */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "isolate"); |
| if (option_value) { |
| WIFI_DBG("isolate is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "isolate", option_value); |
| g_isolate_status = atoi(option_value); |
| } |
| /*auth_mode */ |
| opt_val = uci_lookup_option_string(local_ctx, iface_sec_24G, "encryption"); |
| if (opt_val) { |
| WIFI_DBG("encryption is %s", opt_val); |
| blobmsg_add_string(&wifi_buf, "encryption", opt_val); |
| if (strcmp(opt_val, "none")) { |
| |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key", option_value); |
| } |
| /*wep */ |
| if (strstr(opt_val, "wep")) { |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key1"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key1", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key2"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key2", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key3"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key3", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key4"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key4", option_value); |
| } |
| } |
| if (strstr(opt_val, "psk")) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_24G, "wpa_group_rekey"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "wpa_group_rekey", option_value); |
| } |
| } |
| |
| } |
| } |
| blobmsg_close_table(&wifi_buf, tb_ssid); |
| } |
| |
| blobmsg_close_table(&wifi_buf, tb_24G); |
| /*get detail info -- 2.4G end */ |
| } |
| if (info->wifi_info[i].ap_5G.device && info->wifi_info[i].ap_5G.iface[0]) { |
| /*get detail info -- 5G begin */ |
| tb_5G = blobmsg_open_table(&wifi_buf, "wifi_if_5G"); |
| dev_sec_5G = info->wifi_info[i].ap_5G.device; |
| |
| /*switch */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "disabled"); |
| if (option_value) { |
| WIFI_DBG("disabled is %s", option_value); |
| if (strcmp(option_value, "1") == 0) { |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| } else { |
| WIFI_DBG("wifi_status[%d] %d", i, wifi_status[i]); |
| if (wifi_status[i] == WIFI_OFF) |
| blobmsg_add_string(&wifi_buf, "switch", "off"); |
| else |
| blobmsg_add_string(&wifi_buf, "switch", "on"); |
| } |
| } |
| /*net_mode 11g/11n/11a/11b */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "hwmode"); |
| if (option_value) { |
| WIFI_DBG("net_mode hwmode is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "net_mode", option_value); |
| } |
| /*bandwidth */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "htmode"); |
| if (option_value) { |
| WIFI_DBG("bandwidth is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "bandwidth", option_value); |
| } |
| /*channel */ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "channel"); |
| if (option_value) { |
| WIFI_DBG("channel is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "channel", option_value); |
| } |
| |
| /*channel range*/ |
| get_wifi_channel_range(&channel_first, &channel_last); |
| memset(s_channel_first, 0, 4); |
| memset(s_channel_last, 0, 4); |
| snprintf(s_channel_first, 4, "%d", channel_first); |
| snprintf(s_channel_last, 4, "%d", channel_last); |
| blobmsg_add_string(&wifi_buf, "first_channel", s_channel_first); |
| blobmsg_add_string(&wifi_buf, "last_channel", s_channel_last); |
| |
| n_5G_ssid = info->wifi_info[i].ap_5G.n_ssid; |
| WIFI_DBG("n_5G_ssid number %d", n_5G_ssid); |
| blobmsg_add_u32(&wifi_buf, "n_ssid", n_5G_ssid); |
| |
| /*multi SSID*/ |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "unsupport_multi_ssid"); |
| if (option_value) { |
| WIFI_DBG("unsupport multi ssid %s", option_value); |
| blobmsg_add_string(&wifi_buf, "unsupport_multi_ssid", option_value); |
| } |
| |
| for ( j = 0; j < n_5G_ssid; j++ ) { |
| iface_sec_5G = info->wifi_info[i].ap_5G.iface[j]; |
| sprintf(iface_name, "ssid%d", j); |
| |
| tb_ssid = blobmsg_open_table(&wifi_buf, iface_name); |
| /*SSID*/ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "ssid"); |
| if (option_value) { |
| WIFI_DBG("SSID is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "ssid", option_value); |
| } |
| /*hidden */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "hidden"); |
| if (option_value) { |
| WIFI_DBG("hidden is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "hidden", option_value); |
| } |
| /*isolate */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "isolate"); |
| if (option_value) { |
| WIFI_DBG("isolate is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "isolate", option_value); |
| g_isolate_status = atoi(option_value); |
| } |
| /*auth_mode */ |
| opt_val = uci_lookup_option_string(local_ctx, iface_sec_5G, "encryption"); |
| if (opt_val) { |
| WIFI_DBG("encryption is %s", opt_val); |
| blobmsg_add_string(&wifi_buf, "encryption", opt_val); |
| if (strcmp(opt_val, "none")) { |
| /*wep */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "key"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key", option_value); |
| } |
| if (strstr(opt_val, "wep")) { |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "key1"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key1", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "key2"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key2", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "key3"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key3", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "key4"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "key4", option_value); |
| } |
| } |
| if (strstr(opt_val, "psk")) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_5G, "wpa_group_rekey"); |
| if (option_value) { |
| blobmsg_add_string(&wifi_buf, "wpa_group_rekey", option_value); |
| } |
| } |
| |
| } |
| } |
| /*dtim_period */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "dtim_period"); |
| if (option_value) { |
| WIFI_DBG("dtim_period is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "dtim_period", option_value); |
| } |
| |
| blobmsg_close_table(&wifi_buf, tb_ssid); |
| } |
| |
| blobmsg_close_table(&wifi_buf, tb_5G); |
| /*get detail info -- 5G end */ |
| } |
| |
| blobmsg_close_table(&wifi_buf, tb_device); |
| } |
| EXIT: |
| if (tb_wireless) { |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| } |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done"); |
| return 0; |
| } |
| |
| /*================================================ |
| method: set_wifi_basic_info |
| return : |
| <wireless> |
| <AP0> |
| <wifi_if_24G> |
| <switch/> on/off |
| <ssid0/> primary ssid |
| <ssid/> |
| </ssid0> |
| <channel/> |
| </wifi_if_24G> |
| |
| <wifi_if_5G> |
| <switch/> on/off |
| <ssid0> |
| <ssid/> |
| </ssid0> |
| <channel/> |
| </wifi_if_5G> |
| </AP0> |
| </wireless> |
| ================================================*/ |
| enum { |
| WIFI_DEVICE, |
| WIFI_24G, |
| WIFI_5G, |
| WIFI_STA, |
| WIFI_BS, |
| }; |
| enum { |
| SWITCH, |
| WIFI_SSID, |
| CHANNEL, |
| NET_MODE, |
| BAND_WITCH, |
| HIDDEN, |
| ISOLATE, |
| ENCRYPTION, |
| KEY, |
| KEY1, |
| KEY2, |
| KEY3, |
| KEY4, |
| WPA_GROUP_REKEY, |
| DTIM_PERIOD, |
| MULTI_SSID, |
| SSID_INDEX |
| }; |
| static const struct blobmsg_policy wifi_setting_pol[] = { |
| [WIFI_DEVICE] = { |
| .name = "wifi_device", |
| .type = BLOBMSG_TYPE_STRING |
| }, |
| [WIFI_24G] = { |
| .name = "wifi_if_24G", |
| .type = BLOBMSG_TYPE_TABLE, |
| }, |
| [WIFI_5G] = { |
| .name = "wifi_if_5G", |
| .type = BLOBMSG_TYPE_TABLE, |
| }, |
| [WIFI_STA] = { |
| .name = "wifi_sta", |
| .type = BLOBMSG_TYPE_TABLE, |
| }, |
| [WIFI_BS] = { |
| .name = "bs_enable", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| static const struct blobmsg_policy wifi_basic_info_pol[] = { |
| [SWITCH] = { |
| .name = "switch", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WIFI_SSID] = { |
| .name = "ssid", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| |
| [CHANNEL] = { |
| .name = "channel", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| static const struct blobmsg_policy wifi_all_info_pol[] = { |
| [SWITCH] = { |
| .name = "switch", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WIFI_SSID] = { |
| .name = "ssid", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| |
| [CHANNEL] = { |
| .name = "channel", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [NET_MODE] = { |
| .name = "net_mode", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [BAND_WITCH] = { |
| .name = "bandwidth", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [HIDDEN] = { |
| .name = "hidden", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [ISOLATE] = { |
| .name = "isolate", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [ENCRYPTION] = { |
| .name = "encryption", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [KEY] = { |
| .name = "key", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [KEY1] = { |
| .name = "key1", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [KEY2] = { |
| .name = "key2", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [KEY3] = { |
| .name = "key3", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [KEY4] = { |
| .name = "key4", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WPA_GROUP_REKEY] = { |
| .name = "wpa_group_rekey", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [DTIM_PERIOD] = { |
| .name = "dtim_period", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [MULTI_SSID] = { |
| .name = "multi_ssid", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [SSID_INDEX] = { |
| .name = "ssid_index", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| |
| static int wifi_set_basic_info_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *tb_basic_setting[ARRAY_SIZE(wifi_setting_pol)]; |
| struct blob_attr *tb_basic_info_24G[ARRAY_SIZE(wifi_basic_info_pol)]; |
| struct blob_attr *tb_basic_info_5G[ARRAY_SIZE(wifi_basic_info_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL; |
| void *tb_wireless = NULL; |
| int turn_other_off = 0, ret_val = 0, dev_index = 0; |
| int ssid_change = 0, ssid_len = 0; |
| char *new_ssid = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_setting_pol, ARRAY_SIZE(wifi_setting_pol), tb_basic_setting, blob_data(msg), blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_basic_setting[WIFI_24G] && !tb_basic_setting[WIFI_5G]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_basic_setting[WIFI_24G] && !tb_basic_setting[WIFI_5G]) { |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| ret_val = parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| } |
| |
| if (tb_basic_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_basic_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| |
| dev_sec_24G = info->wifi_info[dev_index].ap_2G.device; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.device; |
| iface_sec_24G = info->wifi_info[dev_index].ap_2G.iface[0]; |
| iface_sec_5G = info->wifi_info[dev_index].ap_5G.iface[0]; |
| |
| if (tb_basic_setting[WIFI_24G] && dev_sec_24G && iface_sec_24G) { |
| if (blobmsg_parse(wifi_basic_info_pol, ARRAY_SIZE(wifi_basic_info_pol), tb_basic_info_24G, |
| blobmsg_data(tb_basic_setting[WIFI_24G]), |
| blobmsg_data_len(tb_basic_setting[WIFI_24G])) == 0) { |
| WIFI_DBG("Parse WIFI_24G successfully\n"); |
| if (tb_basic_info_24G[SWITCH]) { |
| turn_other_off = 0; |
| /*set SWITCH */ |
| WIFI_DBG("setting SWITCH is %s", blobmsg_get_string(tb_basic_info_24G[SWITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "disabled"; |
| if (strcmp(blobmsg_get_string(tb_basic_info_24G[SWITCH]), "off") == 0) { |
| ptr.value = "1"; |
| } else { |
| ptr.value = "0"; |
| /*need to set 5G off */ |
| turn_other_off = 1; |
| } |
| |
| #ifndef STANDALONE_DUAP_AP |
| uci_set(local_ctx, &ptr); |
| if ((turn_other_off == 1) && dev_sec_5G) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "disabled"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| } |
| #endif |
| } |
| if (tb_basic_info_24G[WIFI_SSID]) { |
| /*get current ssid */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "ssid"); |
| /*check whether ssid has been changed */ |
| if (option_value && strcmp(option_value, blobmsg_get_string(tb_basic_info_24G[WIFI_SSID]))) { |
| ssid_len = strlen(blobmsg_get_string(tb_basic_info_24G[WIFI_SSID])); |
| if (new_ssid) { |
| free(new_ssid); |
| new_ssid = NULL; |
| } |
| new_ssid = malloc(ssid_len + 1); |
| if (new_ssid) { |
| memset(new_ssid, 0, ssid_len + 1); |
| memcpy(new_ssid, blobmsg_get_string(tb_basic_info_24G[WIFI_SSID]), |
| ssid_len); |
| } |
| ssid_change = 1; |
| } |
| /*set ssid */ |
| WIFI_DBG("setting WIFI SSID is %s", blobmsg_get_string(tb_basic_info_24G[WIFI_SSID])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "ssid"; |
| ptr.value = blobmsg_get_string(tb_basic_info_24G[WIFI_SSID]); |
| uci_set(local_ctx, &ptr); |
| } |
| if (tb_basic_info_24G[CHANNEL]) { |
| /*set channel */ |
| WIFI_DBG("setting CHANNEL is %s", blobmsg_get_string(tb_basic_info_24G[CHANNEL])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "channel"; |
| ptr.value = blobmsg_get_string(tb_basic_info_24G[CHANNEL]); |
| uci_set(local_ctx, &ptr); |
| } |
| |
| } |
| } |
| |
| if (tb_basic_setting[WIFI_5G] && dev_sec_5G && iface_sec_5G) { |
| if (blobmsg_parse(wifi_basic_info_pol, ARRAY_SIZE(wifi_basic_info_pol), tb_basic_info_5G, |
| blobmsg_data(tb_basic_setting[WIFI_5G]), |
| blobmsg_data_len(tb_basic_setting[WIFI_5G])) == 0) { |
| WIFI_DBG("Parse WIFI_5G successfully\n"); |
| if (tb_basic_info_5G[SWITCH]) { |
| turn_other_off = 0; |
| /*set SWITCH */ |
| WIFI_DBG("setting SWITCH is %s", blobmsg_get_string(tb_basic_info_5G[SWITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "disabled"; |
| if (strcmp(blobmsg_get_string(tb_basic_info_5G[SWITCH]), "off") == 0) { |
| ptr.value = "1"; |
| } else { |
| ptr.value = "0"; |
| turn_other_off = 1; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| #ifndef STANDALONE_DUAP_AP |
| if ((turn_other_off == 1) && dev_sec_24G) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "disabled"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| } |
| #endif |
| } |
| if (tb_basic_info_5G[WIFI_SSID]) { |
| /*get current ssid, */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "ssid"); |
| /*check whether ssid has been changed */ |
| if (strcmp(option_value, blobmsg_get_string(tb_basic_info_5G[WIFI_SSID]))) { |
| ssid_len = strlen(blobmsg_get_string(tb_basic_info_5G[WIFI_SSID])); |
| if (new_ssid) { |
| free(new_ssid); |
| new_ssid = NULL; |
| } |
| new_ssid = malloc(ssid_len + 1); |
| if (new_ssid) { |
| memset(new_ssid, 0, ssid_len + 1); |
| memcpy(new_ssid, blobmsg_get_string(tb_basic_info_5G[WIFI_SSID]), |
| ssid_len); |
| } |
| ssid_change = 1; |
| } |
| /*set SWITCH */ |
| WIFI_DBG("setting WIFI SSID is %s", blobmsg_get_string(tb_basic_info_5G[WIFI_SSID])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "ssid"; |
| ptr.value = blobmsg_get_string(tb_basic_info_5G[WIFI_SSID]); |
| uci_set(local_ctx, &ptr); |
| } |
| if (tb_basic_info_24G[CHANNEL]) { |
| /*set SWITCH */ |
| WIFI_DBG("setting CHANNEL is %s", blobmsg_get_string(tb_basic_info_5G[CHANNEL])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "channel"; |
| ptr.value = blobmsg_get_string(tb_basic_info_5G[CHANNEL]); |
| uci_set(local_ctx, &ptr); |
| } |
| |
| } |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| if (p) { |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| |
| if ( info->wifi_info[dev_index].sta.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].sta.device->e.name); |
| else if ( info->wifi_info[dev_index].ap_2G.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].ap_2G.device->e.name); |
| else if ( info->wifi_info[dev_index].ap_5G.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].ap_5G.device->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| |
| if (p->e.name) { |
| WIFI_DBG("package name is %s", p->e.name); |
| } |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| //my_system("/etc/init.d/mwlan reload"); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| my_system(system_buf); |
| WIFI_DBG("wifi restart"); |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| /*notify that the ssid has been changed */ |
| if ((ssid_change == 1) && new_ssid) { |
| ssid_change_notify(ctx, new_ssid); |
| } |
| WIFI_DBG("done"); |
| return ret_val; |
| } |
| |
| static int wifi_set_multi_ssid_uci_chip_section(struct uci_context *uci_ctx, struct uci_package *p, struct wireless_info *info, int add_del) |
| { |
| struct uci_section *uci_sec = info->chip; |
| struct uci_ptr ptr; |
| char ap_num[4] = { 0 }; |
| |
| if (!uci_ctx || !p || !uci_sec) |
| return 0; |
| |
| switch (add_del) { |
| case ADD_MULTI_SSID_SEC: |
| snprintf(ap_num, 4, "%d", (info->n_dev * 2)); |
| WIFI_DBG("ap_num %s", ap_num); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "ap_num"; |
| ptr.value = ap_num; |
| uci_set(uci_ctx, &ptr); |
| break; |
| case DELETE_MULTI_SSID_SEC: |
| snprintf(ap_num, 4, "%d", info->n_dev ); |
| WIFI_DBG("ap_num %s", ap_num); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "ap_num"; |
| ptr.value = ap_num; |
| uci_set(uci_ctx, &ptr); |
| break; |
| } |
| |
| return 1; |
| } |
| |
| static int wifi_set_multi_ssid_uci(struct uci_context *uci_ctx, struct uci_package *p, struct ap_sec_info *ap_info, int add_del, int ap_index) |
| { |
| struct uci_section *iface_sec = NULL, *uci_sec = NULL; |
| struct uci_ptr ptr; |
| const char *value = NULL; |
| int ifname_index = -1, i, need_commit = 0; |
| char dev_name[MAX_DEV_NAME_LEN] = { 0 }; |
| char iface_name[MAX_DEV_NAME_LEN] = { 0 }; |
| char ifname[MAX_DEV_NAME_LEN] = { 0 }; |
| char ssid[MAX_DEV_NAME_LEN] = { 0 }; |
| char ssid_n[MAX_DEV_NAME_LEN] = { 0 }; |
| char wpa_group_rekey[MAX_DEV_NAME_LEN] = { 0 }; |
| const char *muitl_ap_ifname_prefix = get_wireless_ifname(ap_index); |
| char ifname_prefix[MAX_DEV_NAME_LEN] = { 0 }; |
| |
| switch (add_del) { |
| case ADD_MULTI_SSID_SEC: |
| snprintf(ifname_prefix, sizeof(ifname_prefix) -1, "%s-%s", muitl_ap_ifname_prefix, MULTI_VIRTUAL_AP_IFNAME_PREFIX); |
| iface_sec = ap_info->iface[0]; |
| value = uci_lookup_option_string(uci_ctx, iface_sec, "ifname"); |
| if (value) { |
| //sscanf(value, "uap%d", &ifname_index); |
| if (strstr(value, ifname_prefix)) |
| { |
| sscanf(value + strlen(ifname_prefix), "%d", &ifname_index); |
| } |
| } |
| WIFI_DBG("ifname index %d", ifname_index); |
| |
| value = uci_lookup_option_string(uci_ctx, iface_sec, "device"); |
| if (value) { |
| strncpy(dev_name, value, sizeof(dev_name) - 1); |
| WIFI_DBG("device name is %s", dev_name); |
| } |
| |
| value = uci_lookup_option_string(uci_ctx, iface_sec, "ssid"); |
| if (value) { |
| strncpy(ssid, value, sizeof(ssid) - 1); |
| WIFI_DBG("ssid0 is %s", ssid); |
| } |
| |
| value = uci_lookup_option_string(uci_ctx, iface_sec, "wpa_group_rekey"); |
| if (value) { |
| strncpy(wpa_group_rekey, value, sizeof(ssid) - 1); |
| WIFI_DBG("wpa_group_rekey is %s", wpa_group_rekey); |
| } |
| |
| for ( i = 1; i < MAX_MULTI_SSID_NUM; i++) { |
| ifname_index++; |
| if (iface_sec->e.name) { |
| WIFI_DBG("iface_sec name %s", iface_sec->e.name); |
| snprintf(iface_name, sizeof(iface_name) - 1, "%s_%d", iface_sec->e.name, ifname_index); |
| } |
| |
| snprintf(ifname, sizeof(ifname) -1, "%s%d", ifname_prefix, ifname_index); |
| snprintf(ssid_n, sizeof(ssid_n) - 1, "%s_%d", ssid, ifname_index); |
| WIFI_DBG("add iface_name %s, ifname %s, ssid%d %s", iface_name, ifname, ifname_index, ssid_n); |
| uci_add_section(uci_ctx, p, WIFI_SECTION_IFACE, &uci_sec); |
| WIFI_DBG("add section 0x%x", uci_sec); |
| if (uci_sec) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.value = iface_name; |
| uci_rename(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "device"; |
| ptr.value = dev_name; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "network"; |
| ptr.value = "lan"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "mode"; |
| ptr.value = "ap"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "ifname"; |
| ptr.value = ifname; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "ssid"; |
| ptr.value = ssid_n; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "encryption"; |
| ptr.value = "none"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "hidden"; |
| ptr.value = "0"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "isolate"; |
| ptr.value = "0"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "macfilter"; |
| ptr.value = "disable"; |
| uci_set(uci_ctx, &ptr); |
| |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "wpa_group_rekey"; |
| ptr.value = wpa_group_rekey; |
| uci_set(uci_ctx, &ptr); |
| |
| ap_info->iface[i] = uci_sec; |
| ap_info->n_ssid++; |
| } |
| WIFI_DBG("add section 0x%x done", uci_sec); |
| } |
| //uci_commit(uci_ctx, &p, false); |
| need_commit = 1; |
| break; |
| |
| case DELETE_MULTI_SSID_SEC: |
| while (ap_info->n_ssid > 1) { |
| WIFI_DBG("deleting iface %s", ap_info->iface[ap_info->n_ssid - 1]->e.name); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = ap_info->iface[ap_info->n_ssid - 1]; |
| uci_delete(uci_ctx, &ptr); |
| ap_info->iface[ap_info->n_ssid - 1] = NULL; |
| ap_info->n_ssid--; |
| } |
| need_commit = 1; |
| //uci_commit(uci_ctx, &p, false); |
| break; |
| default: |
| break; |
| } |
| WIFI_DBG("leave, need_commit %d", need_commit); |
| return need_commit; |
| } |
| |
| static void wifi_set_encrytion_uci(struct uci_context *uci_ctx, struct uci_package *p, struct uci_section *iface, struct blob_attr *tb_info[]) |
| { |
| struct uci_ptr ptr; |
| |
| if (tb_info[ENCRYPTION]) { |
| WIFI_DBG("setting encrytion is %s", blobmsg_get_string(tb_info[ENCRYPTION])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "encryption"; |
| ptr.value = blobmsg_get_string(tb_info[ENCRYPTION]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set key */ |
| if (tb_info[KEY]) { |
| WIFI_DBG("setting key is %s", blobmsg_get_string(tb_info[KEY])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "key"; |
| ptr.value = blobmsg_get_string(tb_info[KEY]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set key1 */ |
| if (tb_info[KEY1]) { |
| WIFI_DBG("setting key1 is %s", blobmsg_get_string(tb_info[KEY1])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "key1"; |
| ptr.value = blobmsg_get_string(tb_info[KEY1]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set key2 */ |
| if (tb_info[KEY2]) { |
| WIFI_DBG("setting key2 is %s", blobmsg_get_string(tb_info[KEY2])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "key2"; |
| ptr.value = blobmsg_get_string(tb_info[KEY2]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set key3 */ |
| if (tb_info[KEY3]) { |
| WIFI_DBG("setting key3 is %s", blobmsg_get_string(tb_info[KEY3])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "key3"; |
| ptr.value = blobmsg_get_string(tb_info[KEY3]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set key4 */ |
| if (tb_info[KEY4]) { |
| WIFI_DBG("setting key4 is %s", blobmsg_get_string(tb_info[KEY4])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "key4"; |
| ptr.value = blobmsg_get_string(tb_info[KEY4]); |
| uci_set(uci_ctx, &ptr); |
| } |
| /*set wpa_group_rekey */ |
| if (tb_info[WPA_GROUP_REKEY]) { |
| WIFI_DBG("setting WPA_GROUP_REKEY is %s", |
| blobmsg_get_string(tb_info[WPA_GROUP_REKEY])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface; |
| ptr.option = "wpa_group_rekey"; |
| ptr.value = blobmsg_get_string(tb_info[WPA_GROUP_REKEY]); |
| uci_set(uci_ctx, &ptr); |
| } |
| } |
| |
| /*================================================ |
| method: set_wifi_detail_2.4G/set_wifi_detail_5G |
| |
| <wireless> |
| <wifi_device/> |
| <wifi_if_24G> |
| <switch/> |
| <net_mode/> |
| <channel/> |
| <bandwidth/> |
| <hidden/> |
| <isolate/> |
| <multi_ssid/> |
| <ssid_index/> |
| <ssid/> |
| <encryption> |
| <key> |
| <key1> |
| <key2> |
| <key3> |
| <key4> |
| <wpa_group_rekey/> |
| |
| </wifi_if_24G> |
| <wifi_if_5G> |
| ... |
| </wifi_if_5G> |
| </wireless> |
| ================================================*/ |
| static int wifi_set_all_setting_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *tb_basic_setting[ARRAY_SIZE(wifi_setting_pol)]; |
| struct blob_attr *tb_info_24G[ARRAY_SIZE(wifi_all_info_pol)]; |
| struct blob_attr *tb_info_5G[ARRAY_SIZE(wifi_all_info_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| struct ap_sec_info *ap_info = NULL; |
| const char *option_value = NULL, *country_code = NULL; |
| void *tb_wireless = NULL; |
| int turn_other_off = 0; |
| int ret_val = 0; |
| int ssid_len = 0; |
| int ssid_change = 0; |
| char *new_ssid = NULL; |
| int dev_index, multi_ssid = 0, n_ssid = 0, ssid_index = 0, need_commit = 0; |
| enum isolate_state ap_isolate_state = AP_ISOLATE_NO_CHANGE; |
| int current_isolate_status = g_isolate_status; |
| int stop_start_wifi = 0; |
| int bs_enable = -1; |
| int dev_5g_index = 0; |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| char dev_name1[20] = { 0 }; |
| unsigned int obj_id = 0, wait_seconds = 0; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_setting_pol, ARRAY_SIZE(wifi_setting_pol), tb_basic_setting, blob_data(msg), blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_basic_setting[WIFI_24G] && !tb_basic_setting[WIFI_5G]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| ret_val = parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| } |
| if (tb_basic_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_basic_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| dev_5g_index = dev_index; |
| |
| if (tb_basic_setting[WIFI_BS]) { |
| bs_enable = atoi(blobmsg_get_string(tb_basic_setting[WIFI_BS])); |
| if (info->wifi_info[WIFI_AP0].ap_2G.device) { |
| dev_index = WIFI_AP0; |
| if (info->wifi_info[WIFI_AP1].ap_5G.device) |
| dev_5g_index = WIFI_AP1; |
| } |
| else if (info->wifi_info[WIFI_AP1].ap_2G.device) { |
| dev_index = WIFI_AP1; |
| if (info->wifi_info[WIFI_AP0].ap_5G.device) |
| dev_5g_index = WIFI_AP0; |
| } |
| } |
| |
| WIFI_DBG("dev_index %d, dev_5g_index %d", dev_index, dev_5g_index); |
| if (tb_basic_setting[WIFI_24G]) { |
| if (blobmsg_parse(wifi_all_info_pol, ARRAY_SIZE(wifi_all_info_pol), tb_info_24G, |
| blobmsg_data(tb_basic_setting[WIFI_24G]), |
| blobmsg_data_len(tb_basic_setting[WIFI_24G])) == 0) { |
| WIFI_DBG("Parse WIFI_24G successfully\n"); |
| |
| dev_sec_24G = info->wifi_info[dev_index].ap_2G.device; |
| turn_other_off = 0; |
| if (tb_info_24G[SWITCH]) { |
| /*set SWITCH */ |
| WIFI_DBG("setting SWITCH is %s", blobmsg_get_string(tb_info_24G[SWITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "disabled"; |
| if (strcasecmp(blobmsg_get_string(tb_info_24G[SWITCH]), "off") == 0) { |
| ptr.value = "1"; |
| if (stop_start_wifi == 0) |
| stop_start_wifi = 1; |
| } else { |
| turn_other_off = 1; |
| ptr.value = "0"; |
| stop_start_wifi = 2; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| #ifndef STANDALONE_DUAP_AP |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.device; |
| if ((turn_other_off == 1) && dev_sec_5G) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "disabled"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| } |
| #endif |
| need_commit = 1; |
| } |
| if (tb_info_24G[MULTI_SSID]) { |
| multi_ssid = atoi(blobmsg_get_string(tb_info_24G[MULTI_SSID])); |
| } |
| if (tb_info_24G[SSID_INDEX]) { |
| ssid_index = atoi(blobmsg_get_string(tb_info_24G[SSID_INDEX])); |
| } |
| |
| iface_sec_24G = info->wifi_info[dev_index].ap_2G.iface[ssid_index]; |
| n_ssid = info->wifi_info[dev_index].ap_2G.n_ssid; |
| if (multi_ssid) { |
| if (n_ssid > 1) { |
| /*change some parameters*/ |
| /*set encrytion */ |
| wifi_set_encrytion_uci(local_ctx, p, iface_sec_24G, tb_info_24G); |
| } else { |
| /*need add new iface section*/ |
| ap_info = &(info->wifi_info[dev_index].ap_2G); |
| need_commit |= wifi_set_multi_ssid_uci(local_ctx, p, ap_info, ADD_MULTI_SSID_SEC, dev_index); |
| need_commit |= wifi_set_multi_ssid_uci_chip_section(local_ctx, p, info, ADD_MULTI_SSID_SEC); |
| stop_start_wifi = 2; |
| } |
| } else { |
| if (n_ssid > 1) { |
| /*here should delete iface section*/ |
| ap_info = &(info->wifi_info[dev_index].ap_2G); |
| need_commit |= wifi_set_multi_ssid_uci(local_ctx, p, ap_info, DELETE_MULTI_SSID_SEC, dev_index); |
| need_commit |= wifi_set_multi_ssid_uci_chip_section(local_ctx, p, info, DELETE_MULTI_SSID_SEC); |
| stop_start_wifi = 2; |
| } else { |
| /*set encrytion */ |
| wifi_set_encrytion_uci(local_ctx, p, iface_sec_24G, tb_info_24G); |
| |
| } |
| } |
| |
| if (tb_info_24G[WIFI_SSID]) { |
| /*get current ssid */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "ssid"); |
| WIFI_DBG("setting ssid %s, uci ssid %s", blobmsg_get_string(tb_info_24G[WIFI_SSID]), option_value); |
| /*check whether ssid has been changed */ |
| if (option_value && strcmp(option_value, blobmsg_get_string(tb_info_24G[WIFI_SSID]))) { |
| ssid_len = strlen(blobmsg_get_string(tb_info_24G[WIFI_SSID])); |
| if (new_ssid) { |
| free(new_ssid); |
| new_ssid = NULL; |
| } |
| new_ssid = malloc(ssid_len + 1); |
| if (new_ssid) { |
| memset(new_ssid, 0, ssid_len + 1); |
| strncpy(new_ssid, blobmsg_get_string(tb_info_24G[WIFI_SSID]), ssid_len); |
| } |
| ssid_change = 1; |
| } |
| /*set ssid */ |
| if (ssid_change) { |
| WIFI_DBG("setting WIFI SSID is %s", blobmsg_get_string(tb_info_24G[WIFI_SSID])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "ssid"; |
| ptr.value = blobmsg_get_string(tb_info_24G[WIFI_SSID]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_24G, "country"); |
| country_code = get_conuntry_code(); |
| if (option_value) { |
| if (country_code && strcmp(option_value, country_code)) { |
| /*need set new country code*/ |
| WIFI_DBG("setting country code %s", country_code); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "country"; |
| ptr.value = country_code; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| stop_start_wifi = 2; |
| } |
| } else { |
| if (country_code) { |
| /*need set new country code*/ |
| WIFI_DBG("setting country code %s", country_code); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "country"; |
| ptr.value = country_code; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| stop_start_wifi = 2; |
| } |
| } |
| |
| if (tb_info_24G[CHANNEL]) { |
| /*set channel */ |
| WIFI_DBG("setting CHANNEL is %s", blobmsg_get_string(tb_info_24G[CHANNEL])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "channel"; |
| ptr.value = blobmsg_get_string(tb_info_24G[CHANNEL]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| if (tb_info_24G[NET_MODE]) { |
| /*set net node */ |
| WIFI_DBG("setting NET_MODE is %s", blobmsg_get_string(tb_info_24G[NET_MODE])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "hwmode"; |
| ptr.value = blobmsg_get_string(tb_info_24G[NET_MODE]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| /*set bandwidth */ |
| if (tb_info_24G[NET_MODE]) { |
| if (strstr(blobmsg_get_string(tb_info_24G[NET_MODE]), "ax") || strstr(blobmsg_get_string(tb_info_24G[NET_MODE]), "n")) { |
| /*only 11n/11ax have the htmode option*/ |
| if (tb_info_24G[BAND_WITCH]) { |
| WIFI_DBG("setting bandwidth is %s", blobmsg_get_string(tb_info_24G[BAND_WITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "htmode"; |
| ptr.value = blobmsg_get_string(tb_info_24G[BAND_WITCH]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } else { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "htmode"; |
| uci_delete(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| |
| /*set HIDDEN */ |
| if (tb_info_24G[HIDDEN]) { |
| WIFI_DBG("setting HIDDEN is %s", blobmsg_get_string(tb_info_24G[HIDDEN])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "hidden"; |
| ptr.value = blobmsg_get_string(tb_info_24G[HIDDEN]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| /*set ISOLATE */ |
| if (tb_info_24G[ISOLATE]) { |
| WIFI_DBG("setting ISOLATE is %s", blobmsg_get_string(tb_info_24G[ISOLATE])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "isolate"; |
| ptr.value = blobmsg_get_string(tb_info_24G[ISOLATE]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| current_isolate_status = atoi(blobmsg_get_string(tb_info_24G[ISOLATE])); |
| |
| /*set 5G isolate*/ |
| n_ssid = info->wifi_info[dev_index].ap_5G.n_ssid; |
| for (ssid_index = 0; ssid_index < n_ssid; ssid_index++) { |
| iface_sec_5G = info->wifi_info[dev_index].ap_5G.iface[ssid_index]; |
| WIFI_DBG("setting 5G ISOLATE"); |
| if (current_isolate_status) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "isolate"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } else { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "isolate"; |
| ptr.value = "0"; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| |
| } |
| |
| /*set DTIM_PERIOD */ |
| if (tb_info_24G[DTIM_PERIOD]) { |
| WIFI_DBG("setting DTIM_PERIOD is %s", blobmsg_get_string(tb_info_24G[DTIM_PERIOD])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "dtim_period"; |
| ptr.value = blobmsg_get_string(tb_info_24G[DTIM_PERIOD]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| } |
| |
| if (tb_basic_setting[WIFI_5G]) { |
| if (blobmsg_parse(wifi_all_info_pol, ARRAY_SIZE(wifi_all_info_pol), tb_info_5G, |
| blobmsg_data(tb_basic_setting[WIFI_5G]), |
| blobmsg_data_len(tb_basic_setting[WIFI_5G])) == 0) { |
| WIFI_DBG("Parse WIFI_5G successfully\n"); |
| dev_sec_5G = info->wifi_info[dev_5g_index].ap_5G.device; |
| if (tb_info_5G[SWITCH]) { |
| turn_other_off = 0; |
| /*set SWITCH */ |
| WIFI_DBG("setting SWITCH is %s", blobmsg_get_string(tb_info_5G[SWITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "disabled"; |
| if (strcmp(blobmsg_get_string(tb_info_5G[SWITCH]), "off") == 0) { |
| ptr.value = "1"; |
| if (stop_start_wifi == 0) |
| stop_start_wifi = 1; |
| } else { |
| ptr.value = "0"; |
| turn_other_off = 1; |
| stop_start_wifi = 2; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| #ifndef STANDALONE_DUAP_AP |
| dev_sec_24G = info->wifi_info[dev_5g_index].ap_2G.device; |
| if ((turn_other_off == 1) && dev_sec_24G) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_24G; |
| ptr.option = "disabled"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| } |
| #endif |
| need_commit = 1; |
| } |
| |
| if (tb_info_5G[MULTI_SSID]) { |
| multi_ssid = atoi(blobmsg_get_string(tb_info_5G[MULTI_SSID])); |
| } |
| if (tb_info_5G[SSID_INDEX]) { |
| ssid_index = atoi(blobmsg_get_string(tb_info_5G[SSID_INDEX])); |
| } |
| |
| iface_sec_5G = info->wifi_info[dev_5g_index].ap_5G.iface[ssid_index]; |
| n_ssid = info->wifi_info[dev_5g_index].ap_5G.n_ssid; |
| if (multi_ssid) { |
| if (n_ssid > 1) { |
| /*change some parameters*/ |
| /*set encrytion */ |
| wifi_set_encrytion_uci(local_ctx, p, iface_sec_5G, tb_info_5G); |
| } else { |
| /*need add new iface section*/ |
| ap_info = &(info->wifi_info[dev_5g_index].ap_5G); |
| need_commit |= wifi_set_multi_ssid_uci(local_ctx, p, ap_info, ADD_MULTI_SSID_SEC, dev_5g_index); |
| need_commit |= wifi_set_multi_ssid_uci_chip_section(local_ctx, p, info, ADD_MULTI_SSID_SEC); |
| if (stop_start_wifi != 1) |
| stop_start_wifi = 2; |
| } |
| } else { |
| if (n_ssid > 1) { |
| /*here should delete iface section*/ |
| ap_info = &(info->wifi_info[dev_5g_index].ap_5G); |
| need_commit |= wifi_set_multi_ssid_uci(local_ctx, p, ap_info, DELETE_MULTI_SSID_SEC, dev_5g_index); |
| need_commit |= wifi_set_multi_ssid_uci_chip_section(local_ctx, p, info, DELETE_MULTI_SSID_SEC); |
| if (stop_start_wifi != 1) |
| stop_start_wifi = 2; |
| } else { |
| /*set encrytion */ |
| wifi_set_encrytion_uci(local_ctx, p, iface_sec_5G, tb_info_5G); |
| WIFI_DBG("wifi_set_encrytion_uci done"); |
| } |
| } |
| |
| if (tb_info_5G[WIFI_SSID]) { |
| /*get current ssid */ |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "ssid"); |
| WIFI_DBG("old ssid %s", option_value ? option_value : "NULL"); |
| /*check whether ssid has been changed */ |
| if (option_value && strcmp(option_value, blobmsg_get_string(tb_info_5G[WIFI_SSID]))) { |
| ssid_len = strlen(blobmsg_get_string(tb_info_5G[WIFI_SSID])); |
| if (new_ssid) { |
| free(new_ssid); |
| new_ssid = NULL; |
| } |
| new_ssid = malloc(ssid_len + 1); |
| if (new_ssid) { |
| memset(new_ssid, 0, ssid_len + 1); |
| memcpy(new_ssid, blobmsg_get_string(tb_info_5G[WIFI_SSID]), ssid_len); |
| } |
| ssid_change = 1; |
| WIFI_DBG("new_ssid %s", new_ssid); |
| } |
| if (ssid_change) { |
| /*set ssid */ |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| WIFI_DBG("setting WIFI 5G SSID is %s", blobmsg_get_string(tb_info_5G[WIFI_SSID])); |
| ptr.option = "ssid"; |
| ptr.value = blobmsg_get_string(tb_info_5G[WIFI_SSID]); |
| uci_set(local_ctx, &ptr); |
| } |
| need_commit = 1; |
| } |
| |
| option_value = uci_lookup_option_string(local_ctx, dev_sec_5G, "country"); |
| country_code = get_conuntry_code(); |
| if (option_value) { |
| if (country_code && strcmp(option_value, country_code)) { |
| /*need set new country code*/ |
| WIFI_DBG("setting country code %s", country_code); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "country"; |
| ptr.value = country_code; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| if (stop_start_wifi != 1) |
| stop_start_wifi = 2; |
| } |
| } else { |
| if (country_code) { |
| /*need set new country code*/ |
| WIFI_DBG("setting country code %s", country_code); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "country"; |
| ptr.value = country_code; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| if (stop_start_wifi != 1) |
| stop_start_wifi = 2; |
| } |
| } |
| |
| if (tb_info_5G[CHANNEL]) { |
| /*set channel */ |
| WIFI_DBG("setting CHANNEL is %s", blobmsg_get_string(tb_info_5G[CHANNEL])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "channel"; |
| ptr.value = blobmsg_get_string(tb_info_5G[CHANNEL]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| if (tb_info_5G[NET_MODE]) { |
| /*set net node */ |
| WIFI_DBG("setting NET_MODE is %s", blobmsg_get_string(tb_info_5G[NET_MODE])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "hwmode"; |
| ptr.value = blobmsg_get_string(tb_info_5G[NET_MODE]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| /*set bandwidth */ |
| if (tb_info_5G[NET_MODE]) { |
| if (strstr(blobmsg_get_string(tb_info_5G[NET_MODE]), "n") || strstr(blobmsg_get_string(tb_info_5G[NET_MODE]), "ac") || |
| strstr(blobmsg_get_string(tb_info_5G[NET_MODE]), "ax")) { |
| /*11n/11ac/11ax have the htmode option*/ |
| if (tb_info_5G[BAND_WITCH]) { |
| WIFI_DBG("setting bandwidth is %s", blobmsg_get_string(tb_info_5G[BAND_WITCH])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "htmode"; |
| ptr.value = blobmsg_get_string(tb_info_5G[BAND_WITCH]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } else { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = dev_sec_5G; |
| ptr.option = "htmode"; |
| uci_delete(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| |
| /*set HIDDEN */ |
| if (tb_info_5G[HIDDEN]) { |
| WIFI_DBG("setting HIDDEN is %s", blobmsg_get_string(tb_info_5G[HIDDEN])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "hidden"; |
| ptr.value = blobmsg_get_string(tb_info_5G[HIDDEN]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| /*set ISOLATE */ |
| if (tb_info_5G[ISOLATE]) { |
| WIFI_DBG("setting ISOLATE is %s", blobmsg_get_string(tb_info_5G[ISOLATE])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "isolate"; |
| ptr.value = blobmsg_get_string(tb_info_5G[ISOLATE]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| current_isolate_status = atoi(blobmsg_get_string(tb_info_5G[ISOLATE])); |
| |
| /*set 5G isolate*/ |
| n_ssid = info->wifi_info[dev_5g_index].ap_5G.n_ssid; |
| for (ssid_index = 0; ssid_index < n_ssid; ssid_index++) { |
| iface_sec_5G = info->wifi_info[dev_5g_index].ap_5G.iface[ssid_index]; |
| WIFI_DBG("setting 5G ISOLATE"); |
| if (current_isolate_status) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "isolate"; |
| ptr.value = "1"; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } else { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "isolate"; |
| ptr.value = "0"; |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| } |
| |
| /*set DTIM_PERIOD */ |
| if (tb_info_5G[DTIM_PERIOD]) { |
| WIFI_DBG("setting DTIM_PERIOD is %s", blobmsg_get_string(tb_info_5G[DTIM_PERIOD])); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "dtim_period"; |
| ptr.value = blobmsg_get_string(tb_info_5G[DTIM_PERIOD]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| |
| } |
| } |
| |
| if (bs_enable >= 0) { |
| if (info->sec_bs == NULL) { |
| uci_add_section(local_ctx, p, WIFI_SECTION_BS, &(info->sec_bs)); |
| } |
| |
| if (info->sec_bs) { |
| WIFI_DBG("setting bs_enable %d", bs_enable); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = info->sec_bs; |
| ptr.option = "bs_enable"; |
| ptr.value = blobmsg_get_string(tb_basic_setting[WIFI_BS]); |
| uci_set(local_ctx, &ptr); |
| need_commit = 1; |
| } |
| } |
| |
| set_current_ap_index(dev_index); |
| |
| EXIT: |
| if (current_isolate_status == 0) { |
| if (g_isolate_status == current_isolate_status) |
| ap_isolate_state = AP_ISOLATE_NO_CHANGE; |
| else |
| ap_isolate_state = AP_ISOLATE_ON_OFF; |
| } else if (current_isolate_status == 1) { |
| if (g_isolate_status == current_isolate_status) |
| ap_isolate_state = AP_ISOLATE_NO_CHANGE; |
| else |
| ap_isolate_state = AP_ISOLATE_OFF_ON; |
| } else { |
| WIFI_ERR("Unknown isolate_status \r\n"); |
| ap_isolate_state = AP_ISOLATE_NO_CHANGE; |
| } |
| g_isolate_status = current_isolate_status; |
| WIFI_DBG("ap_isolate_state %d, stop_start_wifi %d, current ap index %d, bs_enable %d", ap_isolate_state, stop_start_wifi, dev_index, bs_enable); |
| |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| if (p) { |
| if (p->e.name) { |
| WIFI_DBG("package name is %s", p->e.name); |
| } |
| memset(dev_name, 0, sizeof(dev_name)); |
| memset(system_buf, 0, sizeof(system_buf)); |
| WIFI_DBG("bs_enable %d, dev_5g_index %d, 5G_dev_section %p", bs_enable, dev_5g_index, info->wifi_info[dev_5g_index].ap_5G.device); |
| if (bs_enable >= 0) { |
| if (bs_enable == 1) |
| snprintf(system_buf, sizeof(system_buf), "echo 1 > /sys/module/asr5861/parameters/bs_enable"); |
| else |
| snprintf(system_buf, sizeof(system_buf), "echo 0 > /sys/module/asr5861/parameters/bs_enable"); |
| |
| my_system(system_buf); |
| if ( info->wifi_info[dev_index].ap_2G.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].ap_2G.device->e.name); |
| |
| if ( info->wifi_info[dev_5g_index].ap_5G.device) |
| { |
| WIFI_DBG("e.name [%s]", info->wifi_info[dev_5g_index].ap_5G.device->e.name); |
| snprintf(dev_name1, sizeof(dev_name1), "%s", info->wifi_info[dev_5g_index].ap_5G.device->e.name); |
| WIFI_DBG("dev_name1 [%s]", dev_name1); |
| } |
| |
| if (need_commit) { |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| } |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop %s", dev_name); |
| my_system(system_buf); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop %s", dev_name1); |
| my_system(system_buf); |
| |
| if (stop_start_wifi != 1) |
| { |
| sleep(3); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan start %s", dev_name); |
| my_system(system_buf); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan start %s", dev_name1); |
| my_system(system_buf); |
| |
| while(wait_seconds++ < 20) { |
| if (wireless_lookup_hostapd_id(&obj_id, dev_index) != 0) |
| sleep(1); |
| else |
| break; |
| } |
| |
| if (wait_seconds >= 20) { |
| WIFI_DBG("wifi not ready in %d seconds", wait_seconds); |
| } |
| else { |
| WIFI_DBG("wifi ready again in %d seconds", wait_seconds); |
| } |
| wait_seconds = 0; |
| while(wait_seconds++ < 20) { |
| if (wireless_lookup_hostapd_id(&obj_id, dev_5g_index) != 0) |
| sleep(1); |
| else |
| break; |
| } |
| |
| if (wait_seconds >= 20) { |
| WIFI_DBG("wifi not ready in %d seconds", wait_seconds); |
| } |
| else { |
| WIFI_DBG("wifi ready again in %d seconds", wait_seconds); |
| } |
| } |
| goto end; |
| } |
| else { |
| if (chip_type_support_dual_ap()) |
| { |
| if ( info->wifi_info[dev_index].sta.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].sta.device->e.name); |
| else if ( info->wifi_info[dev_index].ap_2G.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].ap_2G.device->e.name); |
| else if ( info->wifi_info[dev_index].ap_5G.device) |
| snprintf(dev_name, sizeof(dev_name), "%s", info->wifi_info[dev_index].ap_5G.device->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| } |
| } |
| |
| if (need_commit) { |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| |
| if (stop_start_wifi == 1) { |
| //my_system("/etc/init.d/mwlan stop"); |
| if (strlen(dev_name) > 0) |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop %s", dev_name); |
| else |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop"); |
| |
| WIFI_DBG("wifi will stop\r\n"); |
| } else if (stop_start_wifi == 0){ |
| //my_system("/etc/init.d/mwlan reload"); |
| if (strlen(dev_name) > 0) |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| else |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload"); |
| |
| WIFI_DBG("wifi will reload\r\n"); |
| } else { |
| //my_system("/etc/init.d/mwlan stop"); |
| WIFI_DBG("wifi will restart\r\n"); |
| if (strlen(dev_name) > 0) |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop %s", dev_name); |
| else |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan stop"); |
| |
| my_system(system_buf); |
| sleep(3); |
| //my_system("/etc/init.d/mwlan start"); |
| if (strlen(dev_name) > 0) |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan start %s", dev_name); |
| else |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan start"); |
| //my_system("/etc/init.d/mwlan restart"); |
| } |
| #ifdef AP_ISOLATE_SCRIPT |
| switch(ap_isolate_state) { |
| case AP_ISOLATE_OFF_ON: |
| sleep(10); |
| my_system("/etc/init.d/mwlan_isolate on"); |
| break; |
| case AP_ISOLATE_ON_OFF: |
| sleep(10); |
| my_system("/etc/init.d/mwlan_isolate off"); |
| break; |
| case AP_ISOLATE_NO_CHANGE: |
| default: |
| break; |
| } |
| #endif |
| WIFI_DBG("executing [%s] ", system_buf); |
| my_system(system_buf); |
| } |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| |
| if (stop_start_wifi == 0 || stop_start_wifi == 2) { |
| while(wait_seconds++ < 20) { |
| if (wireless_lookup_hostapd_id(&obj_id, dev_index) != 0) |
| sleep(1); |
| else |
| break; |
| } |
| |
| if (wait_seconds >= 20) { |
| WIFI_DBG("wifi not ready in %d seconds", wait_seconds); |
| } |
| else { |
| WIFI_DBG("wifi ready again in %d seconds", wait_seconds); |
| } |
| } |
| |
| end: |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| /*notify that the ssid has been changed */ |
| if ((ssid_change == 1) && new_ssid) { |
| ssid_change_notify(ctx, new_ssid); |
| } |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| /*================================================ |
| method: wifi_get_MAC_filter_cb |
| |
| <wirless> |
| <wireless_num/> |
| <AP0> |
| <wifi_if_24G> |
| <macfilter/> |
| <maclist_allow/> |
| </wifi_if_24G> |
| <wifi_if_5G> |
| ... |
| </wifi_if_5G> |
| </AP0> |
| </wireless> |
| ================================================*/ |
| |
| static int wifi_get_MAC_filter_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec = NULL; |
| struct uci_section *iface_sec = NULL; |
| struct wireless_info *info = &g_wireless_info; |
| |
| const char *option_value = NULL; |
| void *tb_wireless = NULL, *tb_device = NULL; |
| char tmp[10] = { 0 }; |
| int i; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| blobmsg_buf_init(&wifi_buf); |
| |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| parse_wireless_package_info(local_ctx, p, info); |
| |
| }else { |
| goto EXIT; |
| } |
| } |
| |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| |
| blobmsg_add_u32(&wifi_buf, "wireless_num", (unsigned int)info->n_dev); |
| WIFI_DBG("wireless number %d", info->n_dev); |
| |
| for ( i = 0; i < info->n_dev; i++) { |
| if (info->wifi_info[i].ap_2G.device ||info->wifi_info[i].ap_5G.device) { |
| snprintf(tmp, sizeof(tmp) - 1, "AP%d", i); |
| } |
| else { |
| continue; |
| } |
| |
| WIFI_DBG("device name %s", tmp); |
| tb_device = blobmsg_open_table(&wifi_buf, tmp); |
| dev_sec = info->wifi_info[i].ap_2G.device; |
| iface_sec = info->wifi_info[i].ap_2G.iface[0]; |
| if (!dev_sec || !iface_sec) { |
| dev_sec = info->wifi_info[i].ap_5G.device; |
| iface_sec = info->wifi_info[i].ap_5G.iface[0]; |
| } |
| |
| option_value = uci_lookup_option_string(local_ctx, iface_sec, "macfilter"); |
| if (option_value) { |
| WIFI_DBG("macfilter is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "macfilter", option_value); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec, "maclist_allow"); |
| if (option_value) { |
| WIFI_DBG("maclist_allow is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "maclist_allow", option_value); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec, "maclist_deny"); |
| if (option_value) { |
| WIFI_DBG("maclist_deny is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "maclist_deny", option_value); |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "macfilter", "disable"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_device); |
| |
| } |
| |
| EXIT: |
| if (tb_wireless) { |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| } |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| WIFI_DBG("done"); |
| blob_buf_free(&wifi_buf); |
| return 0; |
| |
| } |
| |
| enum { |
| MACFILTER = 1, |
| MACLIST_ALLOW, |
| MACLIST_DENY, |
| ADD_MACLIST_ALLOW, |
| ADD_MACLIST_DENY, |
| DEL_MACLIST_ALLOW, |
| DEL_MACLIST_DENY, |
| }; |
| static const struct blobmsg_policy wifi_MAC_filter_pol[] = { |
| [WIFI_DEVICE] = { |
| .name = "wifi_device", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [MACFILTER] = { |
| .name = "macfilter", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [MACLIST_ALLOW] = { |
| .name = "maclist_allow", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [MACLIST_DENY] = { |
| .name = "maclist_deny", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [ADD_MACLIST_ALLOW] = { |
| .name = "add_maclist_allow", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [ADD_MACLIST_DENY] = { |
| .name = "add_maclist_deny", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [DEL_MACLIST_ALLOW] = { |
| .name = "del_maclist_allow", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [DEL_MACLIST_DENY] = { |
| .name = "del_maclist_deny", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| static int wifi_set_MAC_filter_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| |
| struct blob_attr *tb_mac_setting[ARRAY_SIZE(wifi_MAC_filter_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL; |
| void *tb_wireless = NULL; |
| int ret_val = 0, dev_index = 0; |
| const char *before_macfilter = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_MAC_filter_pol, ARRAY_SIZE(wifi_MAC_filter_pol), tb_mac_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_mac_setting[MACFILTER] && !tb_mac_setting[MACLIST_ALLOW] && !tb_mac_setting[MACLIST_DENY]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| ret_val = parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| } |
| |
| if (tb_mac_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_mac_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| |
| dev_sec_24G = info->wifi_info[dev_index].ap_2G.device; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.device; |
| iface_sec_24G = info->wifi_info[dev_index].ap_2G.iface[0]; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.iface[0]; |
| |
| /*set Mac filters to 2.4G */ |
| if (dev_sec_24G && iface_sec_24G) { |
| before_macfilter = uci_lookup_option_string(local_ctx, iface_sec_24G, "macfilter"); |
| if (tb_mac_setting[MACFILTER]) { |
| WIFI_DBG("setting MACFILTER 24G is %s", blobmsg_get_string(tb_mac_setting[MACFILTER])); |
| if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "disable")) { |
| if (!before_macfilter |
| || strcmp(before_macfilter, blobmsg_get_string(tb_mac_setting[MACFILTER]))) { |
| WIFI_DBG("macfilter change"); |
| if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "allow") == 0) { |
| if (!tb_mac_setting[MACLIST_ALLOW]) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_24G, |
| "maclist_allow"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| ptr.value = option_value; |
| uci_set(local_ctx, &ptr); |
| } else { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| uci_delete(local_ctx, &ptr); |
| } |
| } |
| } else if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "deny") == 0) { |
| if (!tb_mac_setting[MACLIST_DENY]) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_24G, |
| "maclist_deny"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| ptr.value = option_value; |
| uci_set(local_ctx, &ptr); |
| } else { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| uci_delete(local_ctx, &ptr); |
| } |
| } |
| |
| } |
| |
| } |
| } |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "macfilter"); |
| if (tb_mac_setting[MACLIST_ALLOW]) { |
| WIFI_DBG("setting MACFILTER ALLOW 2.4G is %s", |
| blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_allow"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW]); |
| uci_set(local_ctx, &ptr); |
| if (option_value && strcmp(option_value, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| WIFI_DBG("option_value 2.4G is %s", option_value); |
| ptr.option = "maclist"; |
| WIFI_DBG("setting maclist 2.4G %s", |
| blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW])); |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| if (tb_mac_setting[MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 2.4G is %s", blobmsg_get_string(tb_mac_setting[MACLIST_DENY])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_deny"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_DENY]); |
| uci_set(local_ctx, &ptr); |
| if (option_value && strcmp(option_value, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_DENY]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| } |
| /*Set MAC filters 5G */ |
| if (dev_sec_5G && iface_sec_5G) { |
| before_macfilter = uci_lookup_option_string(local_ctx, iface_sec_5G, "macfilter"); |
| |
| if (tb_mac_setting[MACFILTER]) { |
| WIFI_DBG("setting MACFILTER is %s", blobmsg_get_string(tb_mac_setting[MACFILTER])); |
| if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "disable")) { |
| if (!before_macfilter |
| || strcmp(before_macfilter, blobmsg_get_string(tb_mac_setting[MACFILTER]))) { |
| WIFI_DBG("macfilter change"); |
| if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "allow") == 0) { |
| if (!tb_mac_setting[MACLIST_ALLOW]) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_24G, |
| "maclist_allow"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| ptr.value = option_value; |
| uci_set(local_ctx, &ptr); |
| } else { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| uci_delete(local_ctx, &ptr); |
| } |
| } |
| } else if (strcmp(blobmsg_get_string(tb_mac_setting[MACFILTER]), "deny") == 0) { |
| if (!tb_mac_setting[MACLIST_DENY]) { |
| option_value = |
| uci_lookup_option_string(local_ctx, iface_sec_24G, |
| "maclist_deny"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| ptr.value = option_value; |
| uci_set(local_ctx, &ptr); |
| } else { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| uci_delete(local_ctx, &ptr); |
| } |
| } |
| |
| } |
| |
| } |
| } |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| } |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "macfilter"); |
| if (tb_mac_setting[MACLIST_ALLOW]) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| WIFI_DBG("setting MACFILTER ALLOW 5G is %s", blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW])); |
| ptr.option = "maclist_allow"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW]); |
| uci_set(local_ctx, &ptr); |
| if (option_value && strcmp(option_value, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_ALLOW]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| if (tb_mac_setting[MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 5G is %s", blobmsg_get_string(tb_mac_setting[MACLIST_DENY])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist_deny"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_DENY]); |
| uci_set(local_ctx, &ptr); |
| if (option_value && strcmp(option_value, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACLIST_DENY]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| |
| if (p) { |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| |
| if (dev_sec_24G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_24G->e.name); |
| else if (dev_sec_5G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_5G->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| //my_system("/etc/init.d/mwlan reload"); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| my_system(system_buf); |
| WIFI_DBG("wifi restart\r\n"); |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| static char *get_next_non_space_char(char *in_str) |
| { |
| char *ch = NULL; |
| int nExit = 0; |
| if (!in_str) { |
| return NULL; |
| } |
| ch = in_str; |
| while (nExit == 0) { |
| switch (*ch) { |
| case '\n': |
| case ' ': |
| case '\t': |
| case '\r': |
| continue; |
| default: |
| nExit = 1; |
| } |
| ch++; |
| } |
| return ch; |
| } |
| |
| static char *add_multi_mac(const char *cur_mac, char *new_mac_str) |
| { |
| char *new_buf; |
| int buf_len = 0; |
| if (!cur_mac || !new_mac_str) { |
| return NULL; |
| } |
| buf_len = strlen(cur_mac) + strlen(new_mac_str) + 3; |
| new_buf = malloc(buf_len); |
| if (new_buf) { |
| memset(new_buf, 0, buf_len); |
| memcpy(new_buf, cur_mac, strlen(cur_mac)); |
| strcat(new_buf, " "); |
| strcat(new_buf, new_mac_str); |
| } |
| return new_buf; |
| } |
| |
| static char *delete_one_mac(char *cur_mac, char *new_mac) |
| { |
| char *new_buf = NULL; |
| int buf_len = 0; |
| char *begin = NULL; |
| char *end = NULL; |
| char one_mac[18]; |
| |
| if (!cur_mac) { |
| return NULL; |
| } |
| buf_len = strlen(cur_mac) + 3; |
| new_buf = (char *)malloc(buf_len); |
| if (!new_buf) { |
| WIFI_ERR("malloc fail"); |
| return NULL; |
| } |
| memset(new_buf, 0, buf_len); |
| begin = get_next_non_space_char(cur_mac); |
| while (*begin) { |
| end = strchr(begin, ' '); |
| if (!end) { |
| if (strlen(begin) < 18) { |
| memset(one_mac, 0, sizeof(one_mac)); |
| memcpy(one_mac, begin, strlen(begin)); |
| if (strcmp(one_mac, new_mac) == 0) { |
| break; |
| } |
| strcat(new_buf, one_mac); |
| } |
| break; |
| } |
| if (end - begin < 18) { |
| memset(one_mac, 0, sizeof(one_mac)); |
| memcpy(one_mac, begin, end - begin); |
| if (strcmp(one_mac, new_mac) == 0) { |
| continue; |
| } |
| } |
| strcat(new_buf, one_mac); |
| begin = end + 1; |
| } |
| return new_buf; |
| } |
| |
| static char *del_multi_mac(const char *cur_mac, char *del_mac_str) |
| { |
| char *begin = NULL; |
| char *end = NULL; |
| char one_mac[18]; |
| char *origin_mac = NULL; |
| char *new_buf = NULL; |
| if (!cur_mac) { |
| return NULL; |
| } |
| if (!del_mac_str) { |
| new_buf = malloc(strlen(cur_mac) + 1); |
| memset(new_buf, 0, sizeof(cur_mac) + 1); |
| memcpy(new_buf, cur_mac, strlen(cur_mac)); |
| return new_buf; |
| } |
| begin = (char *)cur_mac; |
| origin_mac = (char *)cur_mac; |
| while (*begin) { |
| end = strchr(begin, ' '); |
| if (!end) { |
| memset(one_mac, 0, sizeof(one_mac)); |
| if (strlen(begin) < 18) { |
| memcpy(one_mac, begin, strlen(begin)); |
| if(origin_mac){ |
| new_buf = delete_one_mac(origin_mac, one_mac); |
| } |
| if (origin_mac && origin_mac != cur_mac) { |
| free(origin_mac); |
| } |
| origin_mac = new_buf; |
| } |
| break; |
| } |
| memset(one_mac, 0, sizeof(one_mac)); |
| if (end - begin < 18) { |
| memcpy(one_mac, begin, end - begin); |
| new_buf = delete_one_mac(origin_mac, one_mac); |
| if (origin_mac && origin_mac != cur_mac) { |
| free(origin_mac); |
| } |
| origin_mac = new_buf; |
| } |
| begin = end + 1; |
| } |
| return new_buf; |
| } |
| |
| static int wifi_add_MAC_filter_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct blob_attr *tb_mac_setting[ARRAY_SIZE(wifi_MAC_filter_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL; |
| const char *macfilter_mode = NULL; |
| void *tb_wireless = NULL; |
| int ret_val = 0, dev_index = 0; |
| char *new_mac_list = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_MAC_filter_pol, ARRAY_SIZE(wifi_MAC_filter_pol), tb_mac_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_mac_setting[ADD_MACLIST_ALLOW] && !tb_mac_setting[ADD_MACLIST_DENY]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| ret_val = parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| } |
| |
| if (tb_mac_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_mac_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| |
| dev_sec_24G = info->wifi_info[dev_index].ap_2G.device; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.device; |
| iface_sec_24G = info->wifi_info[dev_index].ap_2G.iface[0]; |
| iface_sec_5G = info->wifi_info[dev_index].ap_5G.iface[0]; |
| |
| |
| /*set Mac filters to 2.4G */ |
| if (dev_sec_24G && iface_sec_24G) { |
| if (tb_mac_setting[MACFILTER]) { |
| WIFI_DBG("macfilter %s", blobmsg_get_string(tb_mac_setting[MACFILTER])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| macfilter_mode = (const char *)blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| } else |
| macfilter_mode = uci_lookup_option_string(local_ctx, iface_sec_24G, "macfilter"); |
| |
| if (tb_mac_setting[ADD_MACLIST_ALLOW]) { |
| WIFI_DBG("add MACFILTER ALLOW 2.4G is %s", |
| blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW])); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "maclist_allow"); |
| if (option_value) { |
| new_mac_list = |
| add_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW])); |
| } |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_allow"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW]); |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| WIFI_DBG("option_value 2.4G is %s", option_value); |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW]); |
| } |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW]); |
| uci_set(local_ctx, &ptr); |
| } |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| if (tb_mac_setting[ADD_MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 2.4G is %s", |
| blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_deny"; |
| |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "maclist_deny"); |
| if (option_value) { |
| new_mac_list = |
| add_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| } |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY]); |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| WIFI_DBG("deny list %s ", new_mac_list); |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY]); |
| WIFI_DBG("deny list %s ", blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| } |
| /*Set MAC filters 5G */ |
| if (dev_sec_5G && iface_sec_5G) { |
| if (tb_mac_setting[MACFILTER]) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| macfilter_mode = (const char *)blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| } else |
| macfilter_mode = uci_lookup_option_string(local_ctx, iface_sec_5G, "macfilter"); |
| |
| if (tb_mac_setting[ADD_MACLIST_ALLOW]) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "maclist_allow"); |
| if (option_value) { |
| new_mac_list = |
| add_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW])); |
| } |
| WIFI_DBG("setting MACFILTER ALLOW 5G is %s", |
| blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW])); |
| ptr.option = "maclist_allow"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW]); |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW]); |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| if (tb_mac_setting[ADD_MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 5G is %s", |
| blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist_deny"; |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "maclist_deny"); |
| if (option_value) { |
| new_mac_list = |
| add_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| } |
| WIFI_DBG("setting MACFILTER DENY 5G is %s", |
| blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY])); |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY]); |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = blobmsg_get_string(tb_mac_setting[ADD_MACLIST_DENY]); |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| if (p) { |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| |
| if (dev_sec_24G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_24G->e.name); |
| else if (dev_sec_5G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_5G->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| //my_system("/etc/init.d/mwlan reload"); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| my_system(system_buf); |
| WIFI_DBG("wifi restart\r\n"); |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| static int wifi_del_MAC_filter_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| |
| struct blob_attr *tb_mac_setting[ARRAY_SIZE(wifi_MAC_filter_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *dev_sec_24G = NULL, *dev_sec_5G = NULL; |
| struct uci_section *iface_sec_24G = NULL, *iface_sec_5G = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| const char *option_value = NULL; |
| const char *macfilter_mode = NULL; |
| void *tb_wireless = NULL; |
| int ret_val = 0, dev_index = 0; |
| char *new_mac_list = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_MAC_filter_pol, ARRAY_SIZE(wifi_MAC_filter_pol), tb_mac_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_mac_setting[DEL_MACLIST_ALLOW] && !tb_mac_setting[DEL_MACLIST_DENY]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| ret_val = parse_wireless_package_info(local_ctx, p, info); |
| }else { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| } |
| |
| if (tb_mac_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_mac_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| |
| dev_sec_24G = info->wifi_info[dev_index].ap_2G.device; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.device; |
| iface_sec_24G = info->wifi_info[dev_index].ap_2G.iface[0]; |
| dev_sec_5G = info->wifi_info[dev_index].ap_5G.iface[0]; |
| |
| /*set Mac filters to 2.4G */ |
| if (dev_sec_24G && iface_sec_24G) { |
| if (tb_mac_setting[MACFILTER]) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| macfilter_mode = (const char *)blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| } else |
| macfilter_mode = uci_lookup_option_string(local_ctx, iface_sec_24G, "macfilter"); |
| |
| if (tb_mac_setting[DEL_MACLIST_ALLOW]) { |
| WIFI_DBG("del MACFILTER ALLOW 2.4G is %s", |
| blobmsg_get_string(tb_mac_setting[DEL_MACLIST_ALLOW])); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "maclist_allow"); |
| if (option_value) { |
| new_mac_list = |
| del_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[ADD_MACLIST_ALLOW])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_allow"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| if (tb_mac_setting[DEL_MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 2.4G is %s", |
| blobmsg_get_string(tb_mac_setting[DEL_MACLIST_DENY])); |
| |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "maclist_deny"); |
| if (option_value) { |
| new_mac_list = |
| del_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[DEL_MACLIST_DENY])); |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist_deny"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| } |
| } |
| /*Set MAC filters 5G */ |
| if (dev_sec_5G && iface_sec_5G) { |
| if (tb_mac_setting[MACFILTER]) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "macfilter"; |
| ptr.value = blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| uci_set(local_ctx, &ptr); |
| macfilter_mode = (const char *)blobmsg_get_string(tb_mac_setting[MACFILTER]); |
| } else |
| macfilter_mode = uci_lookup_option_string(local_ctx, iface_sec_5G, "macfilter"); |
| |
| if (tb_mac_setting[DEL_MACLIST_ALLOW]) { |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "maclist_allow"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist_allow"; |
| new_mac_list = |
| del_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[DEL_MACLIST_ALLOW])); |
| if (new_mac_list) { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "allow") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| } |
| } |
| if (tb_mac_setting[DEL_MACLIST_DENY]) { |
| WIFI_DBG("setting MACFILTER DENY 5G is %s", |
| blobmsg_get_string(tb_mac_setting[DEL_MACLIST_DENY])); |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_5G, "maclist_deny"); |
| if (option_value) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist_deny"; |
| new_mac_list = |
| del_multi_mac(option_value, blobmsg_get_string(tb_mac_setting[DEL_MACLIST_DENY])); |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| |
| if (macfilter_mode && strcmp(macfilter_mode, "deny") == 0) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| ptr.option = "maclist"; |
| if (new_mac_list) { |
| ptr.value = new_mac_list; |
| } else { |
| ptr.value = " "; |
| } |
| uci_set(local_ctx, &ptr); |
| if (new_mac_list) { |
| free(new_mac_list); |
| new_mac_list = NULL; |
| } |
| } |
| } |
| } |
| |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| if (p) { |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| |
| if ( dev_sec_24G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_24G->e.name); |
| else if (dev_sec_5G) |
| snprintf(dev_name, sizeof(dev_name), "%s",dev_sec_5G->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| //my_system("/etc/init.d/mwlan reload"); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| my_system(system_buf); |
| WIFI_DBG("wifi restart\r\n"); |
| } |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| #define BUFSIZE 512 |
| static int wifi_get_WPS_disable_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_package *p = NULL; |
| struct uci_element *e = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_section *dev_sec_24G = NULL; |
| struct uci_section *iface_sec_24G = NULL; |
| const char *option_value = NULL; |
| int ret_val = 0; |
| void *tb_wireless = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) { |
| ret_val = 1; |
| goto EXIT; |
| } |
| |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| |
| /*get basic info -- 2.4G begin */ |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WIFI_SECTION_DEVICE) == 0) { |
| WIFI_DBG("find one wifi-device, section name is %s", uci_sec->e.name); |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "hwmode"); |
| if (option_value) { |
| WIFI_DBG("hwmode value is %s", option_value); |
| if (!strchr(option_value, 'a')) { |
| dev_sec_24G = uci_sec; |
| } |
| } |
| } else if (strcmp(uci_sec->type, WIFI_SECTION_IFACE) == 0) { |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "device"); |
| if (option_value) { |
| WIFI_DBG("device value is %s", option_value); |
| if (dev_sec_24G && dev_sec_24G->e.name) { |
| if (strcmp(option_value, dev_sec_24G->e.name) == 0) { |
| WIFI_DBG("find wifi-iface(24G)"); |
| iface_sec_24G = uci_sec; |
| } |
| } |
| } |
| } |
| } |
| |
| /*form response blobmsg */ |
| if (dev_sec_24G && iface_sec_24G) { |
| option_value = uci_lookup_option_string(local_ctx, iface_sec_24G, "wps_pushbutton"); |
| if (option_value) { |
| WIFI_DBG("wps_pushbutton is %s", option_value); |
| blobmsg_add_string(&wifi_buf, "wps_enable", option_value); |
| } else { |
| blobmsg_add_string(&wifi_buf, "wps_enable", "0"); |
| } |
| } |
| EXIT: |
| if (tb_wireless) { |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| } |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| enum { |
| WPS_ENABLE, |
| WPS_PIN, |
| WPS_IFACE_INDEX, |
| WPS_5G_PREFER |
| }; |
| static const struct blobmsg_policy wifi_WPS_set_disable_pol[] = { |
| [WPS_ENABLE] = { |
| .name = "wps_enable", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WPS_PIN] = { |
| .name = "wps_pin", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WPS_IFACE_INDEX] = { |
| .name = "wifi_iface_index", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WPS_5G_PREFER] = { |
| .name = "wifi_5g_prefer", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| }; |
| |
| static int wifi_set_WPS_disable_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct uci_context *local_ctx = NULL; |
| struct uci_package *p = NULL; |
| struct uci_element *e = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_section *dev_sec_5G = NULL; |
| struct uci_section *dev_sec_24G = NULL; |
| struct uci_section *iface_sec_24G = NULL; |
| struct uci_section *iface_sec_5G = NULL; |
| const char *option_value = NULL; |
| int ret_val = 1; |
| void *tb_wireless = NULL; |
| struct uci_ptr ptr; |
| struct blob_attr *tb_wps_setting[ARRAY_SIZE(wifi_WPS_set_disable_pol)]; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_WPS_set_disable_pol, ARRAY_SIZE(wifi_WPS_set_disable_pol), tb_wps_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_wps_setting[WPS_ENABLE]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| |
| uci_foreach_element(&local_ctx->root, e) { |
| if (strcmp(e->name, WIFI_PACKAGE_NAME) != 0) |
| continue; |
| p = uci_to_package(e); //have found |
| } |
| if (!p) { |
| uci_load(local_ctx, WIFI_PACKAGE_NAME, &p); |
| } |
| if (p) { |
| WIFI_DBG("load wireless config successfully"); |
| } else { |
| ret_val = 1; |
| goto EXIT; |
| } |
| /*get basic info -- 2.4G begin */ |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, WIFI_SECTION_DEVICE) == 0) { |
| WIFI_DBG("find one wifi-device, section name is %s", uci_sec->e.name); |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "hwmode"); |
| if (option_value) { |
| WIFI_DBG("hwmode value is %s", option_value); |
| if (strchr(option_value, 'a')) { |
| dev_sec_5G = uci_sec; |
| } else { |
| dev_sec_24G = uci_sec; |
| } |
| } |
| } else if (strcmp(uci_sec->type, WIFI_SECTION_IFACE) == 0) { |
| option_value = uci_lookup_option_string(local_ctx, uci_sec, "device"); |
| if (option_value) { |
| WIFI_DBG("device value is %s", option_value); |
| if (dev_sec_24G && dev_sec_24G->e.name) { |
| if (strcmp(option_value, dev_sec_24G->e.name) == 0) { |
| WIFI_DBG("find wifi-iface(24G)"); |
| iface_sec_24G = uci_sec; |
| } |
| } |
| if (dev_sec_5G && dev_sec_5G->e.name) { |
| if (strcmp(option_value, dev_sec_5G->e.name) == 0) { |
| WIFI_DBG("find wifi-iface(5G)"); |
| iface_sec_5G = uci_sec; |
| } |
| } |
| } |
| } |
| } |
| |
| /*set Mac filters to 2.4G */ |
| if (dev_sec_24G && iface_sec_24G) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| if (tb_wps_setting[WPS_ENABLE]) { |
| ret_val = 0; |
| WIFI_DBG("setting wps enable is %s", blobmsg_get_string(tb_wps_setting[WPS_ENABLE])); |
| ptr.option = "wps_pushbutton"; |
| ptr.value = blobmsg_get_string(tb_wps_setting[WPS_ENABLE]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| /*Set MAC filters 5G */ |
| if (dev_sec_5G && iface_sec_5G) { |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_5G; |
| memset(&ptr, 0, sizeof(ptr)); |
| ptr.p = p; |
| ptr.s = iface_sec_24G; |
| if (tb_wps_setting[WPS_ENABLE]) { |
| ret_val = 0; |
| WIFI_DBG("setting wps enable is %s", blobmsg_get_string(tb_wps_setting[WPS_ENABLE])); |
| ptr.option = "wps_pushbutton"; |
| ptr.value = blobmsg_get_string(tb_wps_setting[WPS_ENABLE]); |
| uci_set(local_ctx, &ptr); |
| } |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| char system_buf[50] = { 0 }; |
| char dev_name[20] = { 0 }; |
| |
| if ( dev_sec_24G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_24G->e.name); |
| else if ( dev_sec_5G) |
| snprintf(dev_name, sizeof(dev_name), "%s", dev_sec_5G->e.name); |
| else |
| snprintf(dev_name, sizeof(dev_name), "AP0_24G"); |
| |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| int com_ret = uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| WIFI_DBG("commit ret is %d", com_ret); |
| //my_system("/etc/init.d/mwlan reload"); |
| snprintf(system_buf, sizeof(system_buf), "/etc/init.d/mwlan reload %s", dev_name); |
| my_system(system_buf); |
| WIFI_DBG("wifi restart\r\n"); |
| |
| } else { |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| } |
| |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| static int wifi_call_WPS_PBC_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| int ret_val = 1; |
| void *tb_wireless = NULL; |
| char in_buf[64] = { 0 }; |
| int ap_index = 0; |
| int wps_5g_prefer = 0; |
| struct wireless_info *info = &g_wireless_info; |
| |
| struct blob_attr *tb_wps_setting[ARRAY_SIZE(wifi_WPS_set_disable_pol)]; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| if (blobmsg_parse |
| (wifi_WPS_set_disable_pol, ARRAY_SIZE(wifi_WPS_set_disable_pol), tb_wps_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| |
| if (!tb_wps_setting[WPS_IFACE_INDEX]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| |
| if (tb_wps_setting[WPS_5G_PREFER]) { |
| wps_5g_prefer = atoi(blobmsg_get_string(tb_wps_setting[WPS_5G_PREFER])); |
| } |
| |
| WIFI_DBG("iface index %s, wps_5g_prefer %d, wfi_5g_index %d", blobmsg_get_string(tb_wps_setting[WPS_IFACE_INDEX]), wps_5g_prefer, info->wifi_5g_index); |
| ap_index = atoi(blobmsg_get_string(tb_wps_setting[WPS_IFACE_INDEX])); |
| memset(&g_wps_info[ap_index], 0, sizeof(struct wps_conn_info)); |
| memset(&g_wps_conn_ctx, 0, sizeof(struct wps_conn_ctx)); |
| |
| if (wps_5g_prefer == 1) |
| { |
| if (info->wifi_5g_index == WIFI_AP0 || info->wifi_5g_index == WIFI_AP1) |
| { |
| WIFI_DBG("current wifi status %d for AP %d", wifi_status[info->wifi_5g_index], info->wifi_5g_index); |
| if (wifi_status[info->wifi_5g_index] == WIFI_READY) |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pbc", get_wireless_ifname(info->wifi_5g_index)); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| else |
| { |
| g_wps_conn_ctx.state = WPS_STATE_5G_PREFER; |
| g_wps_conn_ctx.method = 0; |
| g_wps_conn_ctx.ap_5g_index = info->wifi_5g_index; |
| g_wps_conn_ctx.ap_24g_index = info->wifi_24g_index; |
| g_wps_conn_ctx.ap_index = info->wifi_5g_index; |
| } |
| } |
| else |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pbc", get_wireless_ifname(info->wifi_24g_index)); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| } |
| } |
| } |
| else |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pbc", get_wireless_ifname(ap_index)); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "wps_call_pbc_result", "OK"); |
| } else { |
| blobmsg_add_string(&wifi_buf, "wps_call_pbc_result", "FAIL"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| static int wifi_call_WPS_PIN_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| int ret_val = 0; |
| void *tb_wireless = NULL; |
| char in_buf[64] = { 0 }; |
| int ap_index = 0; |
| int wps_5g_prefer = 0; |
| struct wireless_info *info = &g_wireless_info; |
| |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| struct blob_attr *tb_wps_setting[ARRAY_SIZE(wifi_WPS_set_disable_pol)]; |
| |
| if (blobmsg_parse |
| (wifi_WPS_set_disable_pol, ARRAY_SIZE(wifi_WPS_set_disable_pol), tb_wps_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_wps_setting[WPS_PIN]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_wps_setting[WPS_IFACE_INDEX]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (tb_wps_setting[WPS_5G_PREFER]) { |
| wps_5g_prefer = atoi(blobmsg_get_string(tb_wps_setting[WPS_5G_PREFER])); |
| } |
| |
| WIFI_DBG("wps pin is %s, iface index %s, wps_5g_prefer %d, wifi_5g_index %d", blobmsg_get_string(tb_wps_setting[WPS_PIN]), |
| blobmsg_get_string(tb_wps_setting[WPS_IFACE_INDEX]), wps_5g_prefer, info->wifi_5g_index); |
| ap_index = atoi(blobmsg_get_string(tb_wps_setting[WPS_IFACE_INDEX])); |
| /*force to clear the wps status*/ |
| memset(&g_wps_info[ap_index], 0, sizeof(struct wps_conn_info)); |
| memset(&g_wps_conn_ctx, 0, sizeof(struct wps_conn_ctx)); |
| |
| if (wps_5g_prefer == 1) |
| { |
| if (info->wifi_5g_index == WIFI_AP0 || info->wifi_5g_index == WIFI_AP1) |
| { |
| WIFI_DBG("current wifi status %d for AP %d", wifi_status[info->wifi_5g_index], info->wifi_5g_index); |
| if (wifi_status[info->wifi_5g_index] == WIFI_READY) |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pin any %s", get_wireless_ifname(info->wifi_5g_index), blobmsg_get_string(tb_wps_setting[WPS_PIN])); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| else |
| { |
| g_wps_conn_ctx.state = WPS_STATE_5G_PREFER; |
| g_wps_conn_ctx.method = 1; |
| strncpy(g_wps_conn_ctx.pin, blobmsg_get_string(tb_wps_setting[WPS_PIN]), sizeof(g_wps_conn_ctx.pin) - 1); |
| g_wps_conn_ctx.ap_5g_index = info->wifi_5g_index; |
| g_wps_conn_ctx.ap_24g_index = info->wifi_24g_index; |
| g_wps_conn_ctx.ap_index = info->wifi_5g_index; |
| } |
| } |
| else |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pin any %s", get_wireless_ifname(info->wifi_24g_index), blobmsg_get_string(tb_wps_setting[WPS_PIN])); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| } |
| } |
| } |
| else |
| { |
| snprintf(in_buf, sizeof(in_buf), "hostapd_cli -i %s wps_pin any %s", get_wireless_ifname(ap_index), blobmsg_get_string(tb_wps_setting[WPS_PIN])); |
| ret_val = my_system(in_buf); |
| if (ret_val != 0) |
| ret_val = UBUS_STATUS_INVALID_COMMAND; |
| } |
| |
| EXIT: |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "wps_call_pin_result", "OK"); |
| } else { |
| blobmsg_add_string(&wifi_buf, "wps_call_pin_result", "FAIL"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| static int wifi_call_WPS_status_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| void *tb_wireless = NULL; |
| int ap_index = get_current_ap_index(); |
| |
| if (g_wps_conn_ctx.state > WPS_STATE_INIT) |
| { |
| ap_index = g_wps_conn_ctx.ap_index; |
| } |
| |
| WIFI_DBG("wps_status %d, peer mac %s, ap_index %d", g_wps_info[ap_index].wps_status, g_wps_info[ap_index].peer_mac, ap_index); |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| blobmsg_add_u32(&wifi_buf, "wps_status", g_wps_info[ap_index].wps_status); |
| blobmsg_add_string(&wifi_buf, "peer_mac", g_wps_info[ap_index].peer_mac); |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| |
| return 0; |
| } |
| |
| |
| static int wifi_call_WPS_cancel_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| FILE *read_fp = NULL; |
| char *read_buf = NULL; |
| int char_read = 0; |
| int ret_val = 1; |
| void *tb_wireless = NULL; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| read_fp = popen("hostapd_cli wps_cancel", "r"); |
| if (read_fp) { |
| read_buf = malloc(BUFSIZE); |
| if (read_buf) { |
| memset(read_buf, 0, BUFSIZE); |
| char_read = fread(read_buf, sizeof(char), BUFSIZE - 1, read_fp); |
| if (char_read > 0) { |
| WIFI_DBG("size %d read_buf %s", char_read,read_buf); |
| if (strstr(read_buf, "OK")) { |
| ret_val = 0; |
| } |
| } |
| free(read_buf); |
| read_buf = NULL; |
| } |
| pclose(read_fp); |
| } |
| |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| blobmsg_add_string(&wifi_buf, "wps_call_cancel_result", "OK"); |
| } else { |
| blobmsg_add_string(&wifi_buf, "wps_call_cancel_result", "FAIL"); |
| } |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| blob_buf_free(&wifi_buf); |
| WIFI_DBG("done with ret %d", ret_val); |
| return ret_val; |
| } |
| |
| enum { |
| AUTO_OFF_ENABLE = 1, |
| AUTO_OFF_TIMEOUT, |
| }; |
| static const struct blobmsg_policy wifi_auto_off_setting_pol[] = { |
| [WIFI_DEVICE] = { |
| .name = "wifi_device", |
| .type = BLOBMSG_TYPE_STRING |
| }, |
| [AUTO_OFF_ENABLE] = { |
| .name = "auto_off_enable", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [AUTO_OFF_TIMEOUT] = { |
| .name = "auto_off_timeout", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| |
| }; |
| |
| static int wifi_get_auto_off_settings_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| struct wireless_info *info = &g_wireless_info; |
| void *tb_wireless = NULL, *tb_dev = NULL; |
| char buf[32]; |
| int i; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| UNUSESET(msg); |
| |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| |
| if (info->n_dev > MAX_WIFI_CHIP_NUM) { |
| info->n_dev = MAX_WIFI_CHIP_NUM; |
| } |
| blobmsg_add_u32(&wifi_buf, "wireless_num", (unsigned int)info->n_dev); |
| for (i = 0; i < info->n_dev; i++) { |
| memset(buf, 0, sizeof(buf)); |
| snprintf(buf, sizeof(buf) - 1, "AP%d", i); |
| tb_dev = blobmsg_open_table(&wifi_buf, buf); |
| |
| memset(buf, 0, sizeof(buf)); |
| snprintf(buf, sizeof(buf), "%d", info->wifi_info[i].auto_off_enable); |
| blobmsg_add_string(&wifi_buf, "auto_off_enable", buf); |
| memset(buf, 0, sizeof(buf)); |
| snprintf(buf, sizeof(buf), "%d", info->wifi_info[i].auto_off_timeout); |
| blobmsg_add_string(&wifi_buf, "auto_off_timeout", buf); |
| blobmsg_close_table(&wifi_buf, tb_dev); |
| WIFI_DBG("AP%d, auto_off_enable %d, auto_off_timeout %d\n", i, info->wifi_info[i].auto_off_enable, info->wifi_info[i].auto_off_timeout); |
| } |
| |
| if (tb_wireless) { |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| } |
| |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| WIFI_DBG("done"); |
| blob_buf_free(&wifi_buf); |
| return 0; |
| } |
| |
| static int wifi_set_auto_off_settings_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| |
| struct blob_attr *tb_auto_off_setting[ARRAY_SIZE(wifi_auto_off_setting_pol)]; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| struct uci_ptr ptr; |
| struct wireless_info *info = &g_wireless_info; |
| void *tb_wireless = NULL; |
| int ret_val = 0; |
| char dev_name[MAX_DEV_NAME_LEN] = { 0 }; |
| int dev_index; |
| |
| UNUSESET(obj); |
| UNUSESET(method); |
| |
| if (blobmsg_parse |
| (wifi_auto_off_setting_pol, ARRAY_SIZE(wifi_auto_off_setting_pol), tb_auto_off_setting, blob_data(msg), |
| blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| if (!tb_auto_off_setting[AUTO_OFF_ENABLE] && !tb_auto_off_setting[AUTO_OFF_TIMEOUT]) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| goto EXIT; |
| } |
| /*load /etc/config/wireless */ |
| local_ctx = uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) { |
| ret_val = UBUS_STATUS_NO_DATA; |
| goto EXIT; |
| } |
| |
| if (tb_auto_off_setting[WIFI_DEVICE]) { |
| dev_index = atoi(blobmsg_get_string(tb_auto_off_setting[WIFI_DEVICE])); |
| } else { |
| dev_index = 0; |
| } |
| |
| snprintf(dev_name, sizeof(dev_name), "AP%d", dev_index); |
| |
| uci_sec = uci_lookup_section(local_ctx, p, dev_name); |
| if (!uci_sec) { |
| uci_add_section(local_ctx, p, WIFI_SECTION_SETTING, &uci_sec); |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.value = dev_name; |
| uci_rename(local_ctx, &ptr); |
| } |
| if (uci_sec) { |
| if (tb_auto_off_setting[AUTO_OFF_ENABLE]) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "auto_off_enable"; |
| ptr.value = blobmsg_get_string(tb_auto_off_setting[AUTO_OFF_ENABLE]); |
| if (!strcmp(dev_name, "AP0")) |
| info->wifi_info[WIFI_AP0].auto_off_enable= atoi(ptr.value); |
| else if (!strcmp(dev_name, "AP1")) |
| info->wifi_info[WIFI_AP1].auto_off_enable= atoi(ptr.value); |
| else { |
| WIFI_ERR("unsupported device %s", dev_name); |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| if (tb_auto_off_setting[AUTO_OFF_TIMEOUT]) { |
| memset(&ptr, 0, sizeof(struct uci_ptr)); |
| ptr.p = p; |
| ptr.s = uci_sec; |
| ptr.option = "auto_off_timeout"; |
| ptr.value = blobmsg_get_string(tb_auto_off_setting[AUTO_OFF_TIMEOUT]); |
| if (!strcmp(dev_name, "AP0")) |
| info->wifi_info[WIFI_AP0].auto_off_timeout= atoi(ptr.value); |
| else if (!strcmp(dev_name, "AP1")) |
| info->wifi_info[WIFI_AP1].auto_off_timeout= atoi(ptr.value); |
| else { |
| WIFI_ERR("unsupported device %s", dev_name); |
| } |
| uci_set(local_ctx, &ptr); |
| } |
| |
| WIFI_DBG("dev_name %s, auto_off_enable %s, auto_off_timeout %s\n", dev_name, |
| blobmsg_get_string(tb_auto_off_setting[AUTO_OFF_ENABLE]), blobmsg_get_string(tb_auto_off_setting[AUTO_OFF_TIMEOUT])); |
| } |
| |
| set_current_ap_index(dev_index); |
| EXIT: |
| |
| WIFI_ERR("dev_name %s, active_clients %d, auto_off_enable %d", dev_name, active_clients[WIFI_AP0], info->wifi_info[WIFI_AP0].auto_off_enable); |
| if (ret_val == 0) { |
| if ((info->wifi_info[WIFI_AP0].auto_off_enable == 1)) { |
| if (!strcmp(dev_name, "AP0")) { |
| if (active_clients[WIFI_AP0] == 0) |
| set_wifi_auto_off_on(); |
| } |
| else if (!strcmp(dev_name, "AP1")) { |
| if (active_clients[WIFI_AP1] == 0) |
| set_wifi_auto_off_on(); |
| } |
| } else if (info->wifi_info[WIFI_AP0].auto_off_enable == 0) { |
| shutdown_wifi_auto_off(); |
| } |
| } |
| |
| blobmsg_buf_init(&wifi_buf); |
| tb_wireless = blobmsg_open_table(&wifi_buf, "wireless"); |
| if (ret_val == 0) { |
| uci_commit(local_ctx, &p, false); |
| free_wifi_uci_ctx(); |
| blobmsg_add_string(&wifi_buf, "setting_response", "OK"); |
| } else |
| blobmsg_add_string(&wifi_buf, "setting_response", "ERROR"); |
| blobmsg_close_table(&wifi_buf, tb_wireless); |
| |
| ubus_send_reply(ctx, req, wifi_buf.head); |
| WIFI_DBG("done"); |
| |
| blob_buf_free(&wifi_buf); |
| return 0; |
| } |
| |
| static const struct ubus_method wifi_methods[] = { |
| //UBUS_METHOD("WIFI_WATCH", wifi_watch, NULL), |
| UBUS_METHOD_NOARG("wifi_get_basic_info", wifi_get_basic_info_cb), |
| UBUS_METHOD_NOARG("wifi_get_detail", wifi_get_detail_info_cb), |
| UBUS_METHOD("wifi_set_basic_info", wifi_set_basic_info_cb, wifi_setting_pol), |
| UBUS_METHOD("wifi_set_2.4g", wifi_set_all_setting_cb, wifi_setting_pol), |
| UBUS_METHOD("wifi_set_5g", wifi_set_all_setting_cb, wifi_setting_pol), |
| UBUS_METHOD("wifi_set_all", wifi_set_all_setting_cb, wifi_setting_pol), |
| UBUS_METHOD_NOARG("wifi_get_mac_filter", wifi_get_MAC_filter_cb), |
| UBUS_METHOD("wifi_set_mac_filter", wifi_set_MAC_filter_cb, wifi_setting_pol), |
| UBUS_METHOD("wifi_add_mac_filter", wifi_add_MAC_filter_cb, wifi_setting_pol), |
| UBUS_METHOD("wifi_del_mac_filter", wifi_del_MAC_filter_cb, wifi_setting_pol), |
| UBUS_METHOD_NOARG("wifi_get_wps_disable", wifi_get_WPS_disable_cb), |
| UBUS_METHOD_NOARG("wifi_set_wps_disable", wifi_set_WPS_disable_cb), |
| UBUS_METHOD_NOARG("wifi_call_wps_pbc", wifi_call_WPS_PBC_cb), |
| UBUS_METHOD_NOARG("wifi_call_wps_cancle", wifi_call_WPS_cancel_cb), |
| UBUS_METHOD("wifi_call_wps_pin", wifi_call_WPS_PIN_cb, wifi_WPS_set_disable_pol), |
| UBUS_METHOD_NOARG("wifi_get_auto_off_setting", wifi_get_auto_off_settings_cb), |
| UBUS_METHOD("wifi_set_auto_off_setting", wifi_set_auto_off_settings_cb, wifi_auto_off_setting_pol), |
| UBUS_METHOD_NOARG("wifi_call_wps_status", wifi_call_WPS_status_cb), |
| }; |
| |
| static struct ubus_object_type wifi_object_type = UBUS_OBJECT_TYPE("wireless", wifi_methods); |
| |
| static struct ubus_object wifi_service_object = { |
| .name = "wireless", |
| .type = &wifi_object_type, |
| .methods = wifi_methods, |
| .n_methods = ARRAY_SIZE(wifi_methods), |
| }; |
| |
| enum { |
| CLIENTS_NUM_INT, |
| WIFI_STATUS_STR, |
| WIFI_CLIENTS_NUM_STR, |
| WIFI_AP_INDEX_INT, |
| }; |
| static const struct blobmsg_policy stat_notify_pol[] = { |
| [CLIENTS_NUM_INT] = { |
| .name = "clients_num", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WIFI_STATUS_STR] = { |
| .name = "wifi_status", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WIFI_CLIENTS_NUM_STR] = { |
| .name = "wifi_clients_num", |
| .type = BLOBMSG_TYPE_STRING, |
| }, |
| [WIFI_AP_INDEX_INT] = { |
| .name = "ap_index", |
| .type = BLOBMSG_TYPE_INT32, |
| }, |
| }; |
| |
| static int |
| stat_notify_event_cb(struct ubus_context *ctx, struct ubus_object *obj, |
| struct ubus_request_data *req, const char *method, struct blob_attr *msg) |
| { |
| int ret_val = 0; |
| struct blob_attr *stat_msg[ARRAY_SIZE(stat_notify_pol)]; |
| struct wireless_info *info = &g_wireless_info; |
| int clients_num = 0; |
| char *status_str = 0; |
| int ap_index = 0; |
| |
| UNUSESET(req); |
| UNUSESET(ctx); |
| UNUSESET(obj); |
| |
| WIFI_DBG("method :%s ", method); |
| |
| if (blobmsg_parse(stat_notify_pol, ARRAY_SIZE(stat_notify_pol), stat_msg, blob_data(msg), blob_len(msg)) != 0) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| return ret_val; |
| } |
| if ((strcmp(method, "wifi_clients_change") == 0) && stat_msg[WIFI_CLIENTS_NUM_STR]) { |
| clients_num = atoi(blobmsg_get_string(stat_msg[WIFI_CLIENTS_NUM_STR])); |
| ap_index = blobmsg_get_u32(stat_msg[WIFI_AP_INDEX_INT]); |
| if (ap_index >= MAX_WIFI_CHIP_NUM) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| return ret_val; |
| } |
| |
| WIFI_DBG("wifi_clients_change,active_clients %d, wifi_clients_num %d, ap_index %d\n", |
| active_clients[ap_index], clients_num, ap_index); |
| |
| if (info->wifi_info[ap_index].auto_off_enable) { |
| if ((active_clients[ap_index] > 0) && |
| (clients_num == 0)) { |
| set_wifi_auto_off_on(); |
| } else if ((active_clients[ap_index] == 0) && |
| (clients_num > 0)) { |
| shutdown_wifi_auto_off(); |
| } |
| } |
| active_clients[ap_index] = clients_num; |
| } else if ((strcmp(method, "wifi_status_change") == 0) && stat_msg[WIFI_STATUS_STR]) { |
| status_str = blobmsg_get_string(stat_msg[WIFI_STATUS_STR]); |
| ap_index = blobmsg_get_u32(stat_msg[WIFI_AP_INDEX_INT]); |
| if (ap_index >= MAX_WIFI_CHIP_NUM) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| return ret_val; |
| } |
| WIFI_DBG("wifi_status_change, active_clients %d, wifi_status_str %s, wifi_status %d, ap_index %d\n", |
| active_clients[ap_index], status_str, wifi_status[ap_index], ap_index); |
| |
| if (strcmp(status_str, "start") == 0) { |
| wifi_status[ap_index] = WIFI_START; |
| } else if (strcmp(status_str, "ready") == 0) { |
| wifi_status[ap_index] = WIFI_READY; |
| if ((active_clients[ap_index] == 0) && |
| (info->wifi_info[ap_index].auto_off_enable == 1)) { |
| set_wifi_auto_off_on(); |
| } |
| } else if (strcmp(status_str, "off") == 0) { |
| /* For WIFI restart, report status is READY->START->OFF */ |
| unsigned int obj_id = 0; |
| wifi_status[ap_index] = WIFI_OFF; |
| /* query again */ |
| wireless_lookup_hostapd_id(&obj_id, ap_index); |
| if (info->wifi_info[ap_index].auto_off_enable && wifi_status[ap_index] == WIFI_OFF) { |
| shutdown_wifi_auto_off(); |
| } |
| } |
| WIFI_DBG("wifi_status_change, wifi_status %d\n", |
| wifi_status[ap_index]); |
| } else if (strcmp(method, "ubus_object_add") == 0) { |
| ap_index = blobmsg_get_u32(stat_msg[WIFI_AP_INDEX_INT]); |
| WIFI_DBG("ubus_object_add, will listen to hostapd.wlan%d", ap_index); |
| if (ap_index >= MAX_WIFI_CHIP_NUM) { |
| ret_val = UBUS_STATUS_INVALID_ARGUMENT; |
| return ret_val; |
| } |
| |
| if (wireless_listen_to_hostapd(ctx, ap_index) == UBUS_STATUS_OK) { |
| WIFI_DBG("listen hostapd.wlan%d event ready"); |
| } else { |
| WIFI_DBG("listen hostapd.wlan%d event not ready"); |
| } |
| } |
| |
| return ret_val; |
| } |
| |
| /*listen events from hostapd.uap0*/ |
| static struct ubus_subscriber stat_event; |
| static int listen_to_statistics_ser(struct ubus_context *ctx) |
| { |
| unsigned int id; |
| int ret; |
| |
| if (ubus_lookup_id(ctx, "statistics", &id)) { |
| return -1; |
| } |
| |
| stat_event.cb = stat_notify_event_cb; |
| ret = ubus_subscribe(ctx, &stat_event, id); |
| WIFI_DBG("watching object %08x: %s", id, ubus_strerror(ret)); |
| return ret; |
| } |
| |
| /*============================================ |
| Notify other services that the SSID has been changed from WEBUI |
| format |
| { |
| "id":"0", |
| "new_ssid":"" |
| } |
| ============================================*/ |
| enum { |
| SSID_CHANGE_NOTIFY_ID, |
| }; |
| static void ssid_change_notify_complete_cb(struct ubus_request *req, int ret) |
| { |
| UNUSESET(req); |
| UNUSESET(ret); |
| return; |
| } |
| |
| int ssid_change_notify(struct ubus_context *ctx, char *new_ssid) |
| { |
| struct ubus_notify_request nreq; |
| |
| if (!new_ssid) |
| return 0; |
| blobmsg_buf_init(&wifi_buf); |
| blobmsg_add_u32(&wifi_buf, "id", SSID_CHANGE_NOTIFY_ID); |
| blobmsg_add_string(&wifi_buf, "new_ssid", new_ssid); |
| if (ubus_notify_async(ctx, &wifi_service_object, "ssid_change", wifi_buf.head, &nreq)) |
| return 0; |
| blob_buf_free(&wifi_buf); |
| nreq.complete_cb = (void *)&ssid_change_notify_complete_cb; |
| ubus_complete_request(ctx, &nreq.req, 100); |
| return 0; |
| |
| } |
| |
| static void obj_add_event_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, |
| const char *type, struct blob_attr *msg) |
| { |
| static const struct blobmsg_policy policy = { |
| "path", BLOBMSG_TYPE_STRING |
| }; |
| struct blob_attr *attr; |
| const char *path; |
| char *hostapd_name = NULL; |
| int i = 0; |
| |
| UNUSESET(ev); |
| |
| if (strcmp(type, "ubus.object.add") != 0) |
| return; |
| |
| blobmsg_parse(&policy, 1, &attr, blob_data(msg), blob_len(msg)); |
| if (!attr) |
| return; |
| |
| path = blobmsg_data(attr); |
| WIFI_DBG("obj:%s connect", path); |
| |
| //obj_cm_add_ev(ctx, (char *)path); |
| |
| if (strcmp(path, CHARGER_UBUS_ID) == 0) { |
| /*charger connects to ubusd*/ |
| listen_to_charger_ser(ctx); |
| invoke_to_get_charger_data(ctx); |
| WIFI_DBG("charger ready"); |
| } |
| |
| for ( i = 0; i < MAX_WIFI_CHIP_NUM; i++) { |
| hostapd_name = get_hostapd_obj_name(i); |
| if (hostapd_name && strcmp(path, hostapd_name) == 0) { |
| /*hostapd connects to ubusd*/ |
| if (wireless_listen_to_hostapd(ctx, i) == UBUS_STATUS_OK) { |
| WIFI_DBG("wifi%d event ready", i); |
| } |
| else { |
| WIFI_DBG("wifi%d event not ready",i); |
| } |
| } |
| } |
| return; |
| } |
| |
| /*========================================= |
| * If MAC address exists in UCI and /NVM/wifi_addr is empty |
| * Read MAC and write it to /NVM/wifi_addr |
| *==========================================*/ |
| #define WIFIMAC_FILE "/NVM/wifi_addr" |
| |
| static int read_mac_from_uci(void) |
| { |
| FILE *fp = NULL; |
| struct uci_context *local_ctx = NULL; |
| struct uci_element *e = NULL; |
| struct uci_package *p = NULL; |
| struct uci_section *uci_sec = NULL; |
| const char *opt_val = NULL; |
| |
| fp = fopen(WIFIMAC_FILE, "r+"); |
| if (fp) { |
| if (!feof(fp)) //not empty file |
| return 0; |
| } |
| if (!fp) { |
| //file is not exists,create file |
| fp = fopen(WIFIMAC_FILE, "a+"); |
| } |
| if (fp) { |
| //read MAC from UCI |
| |
| /*load /etc/config/wireless */ |
| local_ctx = (struct uci_context *)uci_wifi_ctx_get(); |
| if (!local_ctx) { |
| assert(0); |
| } |
| |
| if (wireless_load_config_package(local_ctx, WIFI_PACKAGE_NAME, &p) != 0) { |
| return -1; |
| } |
| |
| uci_foreach_element(&p->sections, e) { |
| uci_sec = uci_to_section(e); |
| if (strcmp(uci_sec->type, "wifi-iface") == 0) { |
| opt_val = uci_lookup_option_string(local_ctx, uci_sec, "macaddr"); |
| if (opt_val) { |
| fputs(opt_val, fp); |
| break; |
| } |
| } |
| } |
| } |
| if (fp) |
| fclose(fp); |
| return 0; |
| } |
| |
| #define WIFI_DETECT_FILE "/etc/config/wireless" |
| #define WIFI_DETECT_FILE_PCIE "/tmp/wifi_ok" |
| #define WIFI_DETECT_FILE_PCIE_AP0 "/tmp/wifi_ok/AP0_2G" |
| #define WIFI_DETECT_FILE_PCIE_AP1 "/tmp/wifi_ok/AP1_5G" |
| |
| static int is_wifi_card_detected(void) |
| { |
| int ret = 0; |
| if (access(WIFI_DETECT_FILE, F_OK) < 0) { |
| WIFI_ERR("WIFI not exist or init error"); |
| } else if (access(WIFI_DETECT_FILE_PCIE, F_OK) < 0) { |
| WIFI_ERR("WIFI not exist or init error"); |
| } else { |
| if (access(WIFI_DETECT_FILE_PCIE_AP0, F_OK) == 0) |
| ret |= 0x01; |
| |
| if (access(WIFI_DETECT_FILE_PCIE_AP1, F_OK) == 0) |
| ret |= 0x02; |
| } |
| |
| return ret; |
| } |
| |
| void wifi_server_main(void) |
| { |
| struct wireless_info *info = &g_wireless_info; |
| int ret; |
| unsigned int id; |
| int i = 0; |
| #if 1 |
| struct ubus_event_handler add_ev; |
| memset(&add_ev, 0, sizeof(add_ev)); |
| add_ev.cb = obj_add_event_cb; |
| #endif |
| |
| wifi_ubus_ctx = applet_ubus_ctx; |
| ret = is_wifi_card_detected(); |
| if (ret == 0) { |
| wifi_status[WIFI_AP0] = NO_WIFI; |
| wifi_status[WIFI_AP1] = NO_WIFI; |
| } |
| else |
| { |
| if (ret & 0x01 == 0) |
| wifi_status[WIFI_AP0] = NO_WIFI; |
| |
| if (ret & 0x02 == 0) |
| wifi_status[WIFI_AP1] = NO_WIFI; |
| } |
| |
| read_mac_from_uci(); |
| ret = ubus_add_object(applet_ubus_ctx, &wifi_service_object); |
| if (ret) |
| WIFI_ERR("Failed to add object: %s\n", ubus_strerror(ret)); |
| #if 0 |
| ret = ubus_register_event_handler(applet_ubus_ctx, &add_ev, "ubus.object.add"); |
| if (ret) |
| WIFI_ERR("register event ubus.object.add error:%d", ret); |
| #endif |
| |
| ret = ubus_register_subscriber(applet_ubus_ctx, &stat_event); |
| if (ret) |
| WIFI_ERR("Failed to register subscriber: %s", ubus_strerror(ret)); |
| listen_to_statistics_ser(applet_ubus_ctx); |
| ret = ubus_register_subscriber(applet_ubus_ctx, &charger_event); |
| if (ret) |
| WIFI_ERR("Failed to register subscriber: %s", ubus_strerror(ret)); |
| |
| ret = ubus_register_subscriber(applet_ubus_ctx, &hostapd_event_subscriber); |
| if (ret) |
| WIFI_ERR("Failed to register subscriber: %s", ubus_strerror(ret)); |
| |
| ret = ubus_register_subscriber(applet_ubus_ctx, &hostapd_wlan1_event_subscriber); |
| if (ret) |
| WIFI_ERR("Failed to register subscriber: %s", ubus_strerror(ret)); |
| |
| if (ubus_lookup_id(applet_ubus_ctx, CHARGER_UBUS_ID, &id) == UBUS_STATUS_OK) { |
| WIFI_ERR("Lookup object aoc aoc SUCCESS"); |
| listen_to_charger_ser(applet_ubus_ctx); |
| invoke_to_get_charger_data(applet_ubus_ctx); |
| } |
| |
| for (i = 0; i < MAX_WIFI_CHIP_NUM; i++) |
| { |
| if (wireless_lookup_hostapd_id(&id, i) == 0) |
| wireless_listen_to_hostapd(applet_ubus_ctx, i); |
| |
| info->wifi_info[i].auto_off_timeout = MIN_AUTO_OFF_TIMEOUT; |
| info->wifi_info[i].auto_off_enable = 0; |
| } |
| |
| invoke_to_get_client_number(applet_ubus_ctx); |
| WIFI_ERR("Get clinet number SUCCESS"); |
| init_wifi_settings(); |
| WIFI_ERR("Init wifi setting SUCCESS"); |
| } |
| |