| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822 |
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <linux/nl80211.h>
- #include <ifaddrs.h>
- #include <net/if.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <asm/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include "common.h"
- #include "lock.h"
- #include "sys.h"
- #include "wifi.h"
- #include "paras.h"
- #include "cfg.h"
- #include <netlink/msg.h>
- #include <netlink/attr.h>
- #include <netlink/netlink.h>
- #include <netlink/cache.h>
- #include <netlink/genl/genl.h>
- #include <netlink/genl/ctrl.h>
- #include <netlink/route/link.h>
- #include <netlink/route/addr.h>
- #define ONCE_CNT 20
- #define WLAN_IFNAME "wlan0"
- #define AP_CONF "/etc/hostapd.conf"
- #define STA_CONF "/etc/wpa_supplicant.conf"
- #define AP_IP "192.168.2.132"
- enum {
- EVT_ERR=0,
- EVT_ACK,
- EVT_FIN,
- };
- typedef struct {
- int evt;
- ap_list_t list;
- }result_t;
- typedef struct {
- int ifindex;
- char *ifname;
- int nl_id; //nl80211_id
- struct nl_cb *cb;
- struct nl_msg *msg;
- struct nl_sock *sock;
- }nl_handle_t;
- typedef struct {
- int flag;
- }wifi_handle_t;
- static wifi_handle_t wfHandle={0};
- const char *auth_str[AUTH_MAX]={
- "NONE",
- "ERR",
- "PSK",
- "EAP",
- };
- const char *crypt_str[CRYPT_MAX]={
- "NONE",
- "ERR",
- "WEP",
- "WPA",
- "WPA2",
- };
- static void res_print(result_t *res)
- {
- int i;
- ap_info_t *info;
- if(res && res->list.cnt>0) {
- for(i=0; i<res->list.cnt; i++) {
- info = &res->list.info[i];
- printf("___[%d].ssid: %s\n", i, info->ssid);
- printf("___[%d].bssid: %s\n", i, info->bssid);
- printf("___[%d].freq: %dMHz\n", i, info->freq);
- printf("___[%d].auth: %s\n", i, auth_str[info->auth]);
- printf("___[%d].crypt: %s\n", i, crypt_str[info->crypt]);
- printf("\n");
- }
- }
- }
- static void res_free(result_t *res)
- {
- if(res) {
- if(res->list.info) {
- free(res->list.info);
- }
- }
- }
- static int udhcpc_start(int on)
- {
- int r;
- char tmp[200],path[100];
- sprintf(path, "/var/run/udhcpc_%s.pid", WLAN_IFNAME);
- if(on) {
- sprintf(tmp, "udhcpc -R -b -t 1 -A 1 -i %s -p %s", WLAN_IFNAME, path);
- }
- else {
- sprintf(tmp, "kill $(cat %s)", path);
- }
- r = system(tmp);
- return r;
- }
- static int sta_start(ap_info_t *info, int on)
- {
- int r,ipv,mask=24;
- char tmp[400],txt[200];
-
- //https://www.cnblogs.com/lidabo/p/5076560.html
- if(on) {
- snprintf(txt, sizeof(txt), "ctrl_interface=/var/run/wpa_supplicant\n"
- "network={\n"
- "ssid=\"%s\"\n"
- "psk=\"%s\"\n"
- "}\n", info->ssid, info->password);
- sprintf(tmp, "echo '%s' > %s", txt, STA_CONF);
- r = system(tmp);
- r = system("killall wpa_supplicant");
- sprintf(tmp, "wpa_supplicant -B -i %s -c %s", WLAN_IFNAME, STA_CONF);
- r = system(tmp);
- r = udhcpc_start(1);
- }
- else {
- r = system("wpa_cli disconnect");
- r = system("killall wpa_supplicant");
- r = udhcpc_start(0);
- }
- return r;
- }
- static int ap_start(ap_info_t *info, int on)
- {
- int r,ipv,mask=24;
- char tmp[100];
- //https://blog.csdn.net/qq_40311939/article/details/139552431
- r = system("killall hostapd udhcpd");
- if(on) {
- sprintf(tmp, "hostapd -B %s", AP_CONF);
- r = system(tmp);
- ipv = sys_get_ip_ver(info->ipaddr);
- if(ipv==IP_V6) {
- mask = 64;
- }
- sprintf(tmp, "ip addr add %s/%d dev %s", info->ipaddr, mask, WLAN_IFNAME);
- r = system(tmp);
- sprintf(tmp, "udhcpd -i %s -SC /etc/udhcpd.conf", WLAN_IFNAME);
- r = system(tmp);
- }
- return r;
- }
- static void priv_parse(uint8_t *ie, size_t ie_len, ap_info_t *info)
- {
- uint8_t *pos = ie;
-
- info->auth = AUTH_NONE;
- info->crypt = CRYPT_NONE;
- while (pos + 1 < ie + ie_len) {
- uint8_t id = pos[0];
- uint8_t len = pos[1];
- if (pos + 2 + len > ie + ie_len) {
- info->auth = AUTH_ERR;
- info->crypt = CRYPT_ERR;
- break; // ���� IE
- }
- // ���� RSN (WPA2) IE
- if (id == 48) { // RSN IE ID
- uint16_t auth = *((uint16_t *)(pos + 12)); // RSN ��֤��ƫ��
-
- info->crypt = CRYPT_WPA2;
- switch (auth) {
- case 0x0001:
- info->auth = AUTH_PSK;
- break;
- case 0x0002:
- info->auth = AUTH_EAP;
- break;
- default:
- info->auth = AUTH_ERR;
- break;
- }
- break;
- }
- else if (id == 221 && len >= 4 && pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xF2 && pos[5] == 0x01) {
- uint16_t auth = *((uint16_t *)(pos + 12)); // WPA ��֤��ƫ��
-
- info->crypt = CRYPT_WPA;
- switch (auth) {
- case 0x0001:
- info->auth = AUTH_PSK;
- break;
- case 0x0002:
- info->auth = AUTH_EAP;
- break;
- default:
- info->auth = AUTH_ERR;
- break;
- }
- break;
- }
- else if (id == 1 && len >= 4 && (pos[2] & 0x10)) { // Privacy bit in Capability Info
- printf("Encryption: WEP\n");
- info->crypt = CRYPT_WEP;
- break;
- }
- pos += 2 + len;
- }
- }
- struct trigger_results {
- int done;
- int aborted;
- };
- static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
- {
- // Callback for errors.
- printf("error_handler, %d\n", err->error);
- int *ret = arg;
- *ret = err->error;
- return NL_STOP;
- }
- static int finish_handler(struct nl_msg *msg, void *arg)
- {
- // Callback for NL_CB_FINISH.
- int *ret = arg;
- *ret = 0;
- return NL_SKIP;
- }
- static int ack_handler(struct nl_msg *msg, void *arg)
- {
- // Callback for NL_CB_ACK.
- int *ret = arg;
- *ret = 0;
- return NL_STOP;
- }
- static int no_seq_check(struct nl_msg *msg, void *arg)
- {
- // Callback for NL_CB_SEQ_CHECK.
- return NL_OK;
- }
- static int callback_stat(struct nl_msg *msg, void *arg)
- {
- struct nlattr *tb[NL80211_ATTR_MAX + 1];
- struct nlattr *bss[NL80211_BSS_MAX + 1];
- struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
- [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 }, // 信号强度
- [NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 }, // 连接时间
- };
- ap_stat_t *stat=(ap_stat_t*)arg;
- nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
- if (!tb[NL80211_ATTR_STA_INFO]) {
- fprintf(stderr, "sta stats missing!\n");
- return NL_SKIP;
- }
- stat->link = 1;
- if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, tb[NL80211_ATTR_STA_INFO], stats_policy)) {
- fprintf(stderr, "failed to parse nested attributes!\n");
- return NL_SKIP;
- }
- if (sinfo[NL80211_STA_INFO_SIGNAL]) {
- stat->signal = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
- }
- printf("___________________PPPPP_______________________link: %d, signal: %d\n", stat->link, stat->signal);
- return NL_SKIP;
- }
- static int callback_trigger(struct nl_msg *msg, void *arg)
- {
- // Called by the kernel when the scan is done or has been aborted.
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct trigger_results *results = arg;
- //printf("Got something.\n");
- //printf("%d\n", arg);
- //nl_msg_dump(msg, stdout);
- if (gnlh->cmd == NL80211_CMD_SCAN_ABORTED) {
- printf("Got NL80211_CMD_SCAN_ABORTED.\n");
- results->done = 1;
- results->aborted = 1;
- } else if (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS) {
- printf("Got NL80211_CMD_NEW_SCAN_RESULTS.\n");
- results->done = 1;
- results->aborted = 0;
- } // else probably an uninteresting multicast message.
- return NL_SKIP;
- }
- static int callback_dump(struct nl_msg *msg, void *arg)
- {
- // Called by the kernel with a dump of the successful scan's data. Called for each SSID.
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct nlattr *tb[NL80211_ATTR_MAX + 1];
- struct nlattr *bss[NL80211_BSS_MAX + 1];
- static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
- [NL80211_BSS_TSF] = { .type = NLA_U64 },
- [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
- [NL80211_BSS_BSSID] = { },
- [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
- [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
- [NL80211_BSS_INFORMATION_ELEMENTS] = { },
- [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
- [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
- [NL80211_BSS_STATUS] = { .type = NLA_U32 },
- [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
- [NL80211_BSS_BEACON_IES] = { },
- };
- result_t *res=(result_t*)arg;
- ap_info_t *info=&res->list.info[res->list.cnt];
- // Parse and error check.
- nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
- if (!tb[NL80211_ATTR_BSS]) {
- printf("bss info missing!\n");
- return NL_SKIP;
- }
- if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], bss_policy)) {
- printf("failed to parse nested attributes!\n");
- return NL_SKIP;
- }
- if (bss[NL80211_BSS_BSSID]) {
- uint8_t *bssid = nla_data(bss[NL80211_BSS_BSSID]);
- sprintf(info->bssid, "%02x:%02x:%02x:%02x:%02x:%02x", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
- }
- if (bss[NL80211_BSS_FREQUENCY]) {
- uint32_t freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
- info->freq = freq;
- }
-
- if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
- uint8_t *ies = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
- int ies_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
- priv_parse(ies, nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), info);
-
- // ���� SSID����ϢԪ�� ID Ϊ 0��
- int offset = 0;
- while (offset < ies_len) {
- uint8_t ie_id = ies[offset];
- uint8_t ie_len = ies[offset + 1];
- if (ie_id == 0 && ie_len > 0 && ie_len <= 32) { // SSID �� ID Ϊ 0
- memcpy(info->ssid, &ies[offset + 2], ie_len);
- info->ssid[ie_len] = 0;
- break;
- }
- offset += ie_len + 2;
- }
- }
- res->list.cnt++;
- if(res->list.cnt>=res->list.max) {
- int max = res->list.max+ONCE_CNT;
- res->list.info = (ap_info_t*)realloc(res->list.info, sizeof(ap_info_t)*max);
- if(res->list.info) {
- res->list.max = max;
- }
- else {
- fprintf(stderr, "res->info realloc failed\n");
- return NL_STOP;
- }
- }
- return NL_SKIP;
- }
- static int scan_trigger(nl_handle_t *h)
- {
- // Starts the scan and waits for it to finish. Does not return until the scan is done or has been aborted.
- struct trigger_results results = { .done = 0, .aborted = 0 };
- struct nl_msg *ssids_to_scan;
- int err,ret;
- int mcid = genl_ctrl_resolve_grp(h->sock, "nl80211", "scan");
- nl_socket_add_membership(h->sock, mcid); // Without this, callback_trigger() won't be called.
- // Allocate the messages and callback handler.
- ssids_to_scan = nlmsg_alloc();
- if (!ssids_to_scan) {
- printf("ERROR: Failed to allocate netlink message for ssids_to_scan.\n");
- return -ENOMEM;
- }
- // Setup the messages and callback handler.
- genlmsg_put(h->msg, 0, 0, h->nl_id, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0); // Setup which command to run.
- nla_put_u32(h->msg, NL80211_ATTR_IFINDEX, h->ifindex); // Add message attribute, which interface to use.
- nla_put(ssids_to_scan, 1, 0, ""); // Scan all SSIDs.
- nla_put_nested(h->msg, NL80211_ATTR_SCAN_SSIDS, ssids_to_scan); // Add message attribute, which SSIDs to scan for.
- nlmsg_free(ssids_to_scan); // Copied to `msg` above, no longer need this.
- nl_cb_set(h->cb, NL_CB_VALID, NL_CB_CUSTOM, callback_trigger, &results); // Add the callback.
- nl_cb_err(h->cb, NL_CB_CUSTOM, error_handler, &err);
- nl_cb_set(h->cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
- nl_cb_set(h->cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
- nl_cb_set(h->cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); // No sequence checking for multicast messages.
- // Send NL80211_CMD_TRIGGER_SCAN to start the scan. The kernel may reply with NL80211_CMD_NEW_SCAN_RESULTS on
- // success or NL80211_CMD_SCAN_ABORTED if another scan was started by another process.
- err = 1;
- ret = nl_send_auto(h->sock, h->msg); // Send the message.
- printf("NL80211_CMD_TRIGGER_SCAN sent %d bytes to the kernel.\n", ret);
- printf("Waiting for scan to complete...\n");
- while (err > 0) ret = nl_recvmsgs(h->sock, h->cb); // First wait for ack_handler(). This helps with basic errors.
- if (err < 0) {
- printf("WARNING: err has a value of %d.\n", err);
- }
- if (ret < 0) {
- printf("ERROR: nl_recvmsgs() returned %d (%s).\n", ret, nl_geterror(-ret));
- return ret;
- }
- while (!results.done) nl_recvmsgs(h->sock, h->cb); // Now wait until the scan is done or aborted.
- if (results.aborted) {
- printf("ERROR: Kernel aborted scan.\n");
- return 1;
- }
- printf("Scan is done.\n");
- // Cleanup.
- nl_socket_drop_membership(h->sock, mcid); // No longer need this.
- return 0;
- }
- static int nl80211_init(nl_handle_t *h, int dbg)
- {
- h->ifname = WLAN_IFNAME;
- h->ifindex = if_nametoindex(h->ifname);
- if (!h->ifindex) {
- fprintf(stderr, "Failed to get interface index\n");
- return -1;
- }
-
- h->cb = nl_cb_alloc(dbg?NL_CB_DEBUG:NL_CB_DEFAULT);
- if (!h->cb) {
- fprintf(stderr, "Failed to allocate netlink callback.\n");
- goto fail;
- }
- h->msg = nlmsg_alloc();
- if (!h->msg) {
- fprintf(stderr, "Failed to allocate netlink message\n");
- goto fail;
- }
-
- h->sock = nl_socket_alloc();
- if (!h->sock) {
- fprintf(stderr, "Failed to allocate socket\n");
- goto fail;
- }
- nl_socket_set_buffer_size(h->sock, 8192, 8192);
-
- if (genl_connect(h->sock)) {
- fprintf(stderr, "Failed to connect to generic netlink.\n");
- goto fail;
- }
- h->nl_id = genl_ctrl_resolve(h->sock, "nl80211");
- return 0;
-
- fail:
- return -1;
- }
- static int nl80211_free(nl_handle_t *h)
- {
- if(h->cb) nl_cb_put(h->cb);
- if(h->msg) nlmsg_free(h->msg);
- if(h->sock) {
- nl_close(h->sock);
- nl_socket_free(h->sock);
- }
-
- return 0;
- }
- static int get_ipaddr(char *ifname, int family, char *ipaddr)
- {
- int r=-1;
- struct ifaddrs *ifap, *ifa;
- if (getifaddrs(&ifap) == -1) {
- printf("___getifaddrs() error\n");
- return -1;
- }
- for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr != NULL && strcmp(ifa->ifa_name, ifname)==0 && ifa->ifa_addr->sa_family==family) {
- if(family==AF_INET) {
- struct sockaddr_in *sa,*msk;
- sa = (struct sockaddr_in *) ifa->ifa_addr;
- msk = (struct sockaddr_in *) ifa->ifa_netmask;
- char *p = (char*)inet_ntop(ifa->ifa_addr->sa_family, &sa->sin_addr, ipaddr, INET6_ADDRSTRLEN);
- if(p) r = 0;
- if(r==0) break;
- }
- else {
- struct sockaddr_in6 *sa,*msk;
- sa = (struct sockaddr_in6 *) ifa->ifa_addr;
- msk = (struct sockaddr_in6 *) ifa->ifa_netmask;
-
- char *p = (char*)inet_ntop(ifa->ifa_addr->sa_family, &sa->sin6_addr, ipaddr, INET6_ADDRSTRLEN);
- if(p) r = 0;
- if(r==0) break;
- }
- }
- }
- freeifaddrs(ifap);
-
- return r;
- }
- static int nl_get_ip(ap_stat_t *stat)
- {
- int r;
- stat->ipaddr[0] = 0;
- r = get_ipaddr(WLAN_IFNAME, AF_INET, stat->ipaddr);
- return r;
- }
- static int nl_get_signal(ap_stat_t *stat)
- {
- int r,err=1;
- nl_handle_t nl,*h;
-
- //https://github.com/Alamot/code-snippets/blob/master/nl80211_info/nl80211_info.c
- r = nl80211_init(&nl, 0);
- if(r) {
- return -1;
- }
- h = &nl;
- stat->link = stat->signal = 0;
- nl_cb_err(h->cb, NL_CB_CUSTOM, error_handler, &err);
- nl_cb_set(h->cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
- nl_cb_set(h->cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
- r = nl_cb_set(h->cb, NL_CB_VALID, NL_CB_CUSTOM, callback_stat, stat);
- genlmsg_put(h->msg, NL_AUTO_PORT, NL_AUTO_SEQ, h->nl_id, 0, NLM_F_DUMP, NL80211_CMD_GET_STATION, 0); // Setup which command to run.
- nla_put_u32(h->msg, NL80211_ATTR_IFINDEX, h->ifindex); // Add message attribute, which interface to use.
- r = nl_send_auto(h->sock, h->msg);
- if(r<0) {
- nl80211_free(h);
- return -1;
- }
- r = 0;
- while(err>0) nl_recvmsgs(h->sock, h->cb);
- nl80211_free(h);
- return r;
- }
- static int nl_scan(result_t *res)
- {
- int r;
- nl_handle_t nl,*h;
-
- r = nl80211_init(&nl, 0);
- if(r) {
- return -1;
- }
- h = &nl;
-
- res->list.cnt = 0;
- res->list.max = 0;
- res->list.info = (ap_info_t*)malloc(sizeof(ap_info_t)*ONCE_CNT);
- if(!res->list.info) {
- nl80211_free(h);
- return -1;
- }
- res->list.max = ONCE_CNT;
-
- r = scan_trigger(h);
- if (r != 0) {
- printf("scan_trigger() failed with %d.\n", r);
- return -1;
- }
- genlmsg_put(h->msg, 0, 0, h->nl_id, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0); // Setup which command to run.
- nla_put_u32(h->msg, NL80211_ATTR_IFINDEX, h->ifindex); // Add message attribute, which interface to use.
- nl_socket_modify_cb(h->sock, NL_CB_VALID, NL_CB_CUSTOM, callback_dump, res); // Add the callback.
- r = nl_send_auto(h->sock, h->msg);
- r = nl_recvmsgs_default(h->sock);
- if (r < 0) {
- printf("ERROR: nl_recvmsgs_default() returned %d (%s).\n", r, nl_geterror(-r));
- }
- nl80211_free(h);
- return r;
- }
- static int nl_conn(ap_info_t *info)
- {
- int err,r=0;
- nl_handle_t nl,*h;
-
- r = nl80211_init(&nl, 0);
- if(r) {
- return r;
- }
- h = &nl;
-
- genlmsg_put(h->msg, 0, 0, h->nl_id, 0, (NLM_F_REQUEST|NLM_F_ACK), NL80211_CMD_CONNECT, 0);
- nla_put_u32(h->msg, NL80211_ATTR_IFINDEX, h->ifindex);
- nla_put(h->msg, NL80211_ATTR_SSID, strlen(info->ssid), info->ssid);
- if (strlen(info->bssid)>0) {
- nla_put(h->msg, NL80211_ATTR_MAC, 6, info->bssid);
- }
- if (strlen(info->password)>0) {
- struct nlattr *sae_data = nla_nest_start(h->msg, NL80211_ATTR_AUTH_DATA);
- if (!sae_data) {
- fprintf(stderr, "Failed to nest auth data\n");
- r = -1;
- }
- nla_put(h->msg, NL80211_ATTR_AKM_SUITES, 2, "\x00\x0F"); // WPA2-PSK
- nla_put(h->msg, NL80211_ATTR_IE, strlen(info->password), info->password);
- nla_nest_end(h->msg, sae_data);
- }
- if (nl_send_auto_complete(h->sock, h->msg) < 0) {
- fprintf(stderr, "nl_send_auto_complete failed\n");
- r = -1;
- }
- if (r==0 && (err=nl_wait_for_ack(h->sock))<0) {
- fprintf(stderr, "Failed to receive ack: %s\n", nl_geterror(err));
- r = -1;
- }
- nl80211_free(h);
-
- return r;
- }
- static int nl_disconn(void)
- {
- int err,r;
- nl_handle_t nl,*h;
-
- r = nl80211_init(&nl, 0);
- if(r) {
- return r;
- }
- h = &nl;
-
- genlmsg_put(h->msg, 0, 0, h->nl_id, 0, 0, NL80211_CMD_DISCONNECT, 0);
- nla_put_u32(h->msg, NL80211_ATTR_IFINDEX, h->ifindex);
- // ������Ϣ
- if (nl_send_auto(h->sock, h->msg) < 0) {
- fprintf(stderr, "Failed to send disconnect request\n");
- r = -1;
- }
- // �ȴ���Ӧ
- if (r==0 && (err=nl_wait_for_ack(h->sock)) < 0) {
- fprintf(stderr, "Failed to receive ack: %s\n", nl_geterror(err));
- r = -1;
- }
- nl80211_free(h);
-
- return r;
- }
- static int nl_link(int on)
- {
- int r,fd;
- struct ifreq ifr;
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd>=0) {
- strcpy(ifr.ifr_name, WLAN_IFNAME);
- r = ioctl(fd, SIOCGIFFLAGS, &ifr);
- if(r>=0) {
- if(on) {
- ifr.ifr_flags |= IFF_UP;
- }
- else {
- ifr.ifr_flags &= ~IFF_UP;
- }
- r = ioctl(fd, SIOCSIFFLAGS, &ifr);
- }
- close(fd);
- r = (r>=0)?0:-1;
- }
- return r;
- }
- ////////////////////////////////////////////////////////////////
- int wifi_init(void)
- {
- int r=-1;
- WIFIInfo_t *wm=&__globalDeviceManage._globalDevInfo.wifi;
- wifi_handle_t *h=&wfHandle;
- system("insmod /lib/modules/5.4.61/cfg80211.ko");
- system("insmod /lib/modules/5.4.61/lib80211.ko");
- r = wifi_set(wm);
-
- return r;
- }
- int wifi_scan(ap_list_t *list)
- {
- int r=-1;
- result_t res;
- wifi_handle_t *h=&wfHandle;
- r = nl_scan(&res);
- if(r==0) {
- if(list) {
- *list = res.list;
- }
- }
- return r;
- }
- int wifi_set(WIFIInfo_t *wm)
- {
- int r=-1;
- ap_info_t info;
- wifi_handle_t *h=&wfHandle;
- r = nl_link(wm->mode);
- if(wm->mode) {
- memset(&info, 0, sizeof(info));
- strcpy(info.ssid, wm->WIFI_name);
- strcpy(info.password, wm->WIFI_code);
- sta_start(&info, 0);
- r = sta_start(&info, 1);
- }
- else {
- sta_start(&info, 0);
- }
- return r;
- }
- int wifi_sta_info(ap_info_t *info)
- {
- int r=-1;
- wifi_handle_t *h=&wfHandle;
-
- return 0;
- }
- int wifi_sta_stat(ap_stat_t *stat)
- {
- int r=-1;
- wifi_handle_t *h=&wfHandle;
-
- if(!stat) {
- return -1;
- }
- nl_get_signal(stat);
- r = nl_get_ip(stat);
- if(r==0) {
- stat->link = 1; //不知道何原因导致获取信号强度的回调函数触发不了,暂时绕过
- }
- //printf("______ link: %d, signal: %d, ip: %s\n", stat->link, stat->signal, stat->ipaddr);
-
- return r;
- }
- int wifi_ap_info(ap_info_t *info)
- {
- int r=-1;
- wifi_handle_t *h=&wfHandle;
-
- return 0;
- }
- int wifi_list_free(ap_list_t *list)
- {
- if(!list || !list->info) {
- return -1;
- }
- free(list->info);
- list->cnt = 0;
- list->info = NULL;
- return 0;
- }
|