196a7f077Sopenharmony_ci/* 296a7f077Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd. 396a7f077Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 496a7f077Sopenharmony_ci * you may not use this file except in compliance with the License. 596a7f077Sopenharmony_ci * You may obtain a copy of the License at 696a7f077Sopenharmony_ci * 796a7f077Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 896a7f077Sopenharmony_ci * 996a7f077Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1096a7f077Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1196a7f077Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1296a7f077Sopenharmony_ci * See the License for the specific language governing permissions and 1396a7f077Sopenharmony_ci * limitations under the License. 1496a7f077Sopenharmony_ci */ 1596a7f077Sopenharmony_ci 1696a7f077Sopenharmony_ci#include "utils/includes.h" 1796a7f077Sopenharmony_ci#include "pthread.h" 1896a7f077Sopenharmony_ci#include "common/wpa_ctrl.h" 1996a7f077Sopenharmony_ci#include "securec.h" 2096a7f077Sopenharmony_ci 2196a7f077Sopenharmony_ci 2296a7f077Sopenharmony_ci#define WPA_IFACE_NAME "wlan0" 2396a7f077Sopenharmony_ci#define WIFI_AUTH_FAILED_REASON_STR "WRONG_KEY" 2496a7f077Sopenharmony_ci#define WIFI_AUTH_FAILED_REASON_CODE "reason=2" 2596a7f077Sopenharmony_ci#define WPA_CTRL_REQUEST_OK "OK" 2696a7f077Sopenharmony_ci#define WPA_CTRL_REQUEST_FAIL "FAIL" 2796a7f077Sopenharmony_ci 2896a7f077Sopenharmony_ci#define SAMPLE_INFO(format, args...) \ 2996a7f077Sopenharmony_ci do { \ 3096a7f077Sopenharmony_ci fprintf(stderr, "\033[1;32m WpaCliSample(%s:%d):\t\033[0m" format, __func__, __LINE__, ##args); \ 3196a7f077Sopenharmony_ci printf("\n"); \ 3296a7f077Sopenharmony_ci } while (0) 3396a7f077Sopenharmony_ci 3496a7f077Sopenharmony_ci#define SAMPLE_ERROR(format, args...) \ 3596a7f077Sopenharmony_ci do { \ 3696a7f077Sopenharmony_ci fprintf(stderr, "\033[1;31m WpaCliSample(%s:%d):\t\033[0m" format, __func__, __LINE__, ##args); \ 3796a7f077Sopenharmony_ci printf("\n"); \ 3896a7f077Sopenharmony_ci } while (0) 3996a7f077Sopenharmony_ci 4096a7f077Sopenharmony_ci 4196a7f077Sopenharmony_cistatic struct wpa_ctrl *g_monitorConn; 4296a7f077Sopenharmony_cistatic struct wpa_ctrl *g_ctrlConn; 4396a7f077Sopenharmony_cistatic pthread_t g_wpaThreadId; 4496a7f077Sopenharmony_cistatic int g_scanAvailable = 0; 4596a7f077Sopenharmony_ci 4696a7f077Sopenharmony_cistatic void DumpString(const char *buf, int len, const char *tag) 4796a7f077Sopenharmony_ci{ 4896a7f077Sopenharmony_ci SAMPLE_INFO("%s dump start.", tag); 4996a7f077Sopenharmony_ci for (int i = 0; i < len; i++) { 5096a7f077Sopenharmony_ci printf("%c", buf[i]); 5196a7f077Sopenharmony_ci } 5296a7f077Sopenharmony_ci printf("\n"); 5396a7f077Sopenharmony_ci SAMPLE_INFO("%s dump end.", tag); 5496a7f077Sopenharmony_ci} 5596a7f077Sopenharmony_ci 5696a7f077Sopenharmony_cistatic int StrMatch(const char *a, const char *b) 5796a7f077Sopenharmony_ci{ 5896a7f077Sopenharmony_ci return strncmp(a, b, strlen(b)) == 0; 5996a7f077Sopenharmony_ci} 6096a7f077Sopenharmony_ci 6196a7f077Sopenharmony_cistatic void WifiEventHandler(char *rawEvent, int len) 6296a7f077Sopenharmony_ci{ 6396a7f077Sopenharmony_ci char *pos = rawEvent; 6496a7f077Sopenharmony_ci if (*pos == '<') { 6596a7f077Sopenharmony_ci pos = strchr(pos, '>'); 6696a7f077Sopenharmony_ci if (pos) { 6796a7f077Sopenharmony_ci pos++; 6896a7f077Sopenharmony_ci } else { 6996a7f077Sopenharmony_ci pos = rawEvent; 7096a7f077Sopenharmony_ci } 7196a7f077Sopenharmony_ci } 7296a7f077Sopenharmony_ci if (StrMatch(pos, WPA_EVENT_CONNECTED)) { 7396a7f077Sopenharmony_ci SAMPLE_INFO("WIFI_EVENT_CONNECTED"); 7496a7f077Sopenharmony_ci return; 7596a7f077Sopenharmony_ci } 7696a7f077Sopenharmony_ci if (StrMatch(pos, WPA_EVENT_SCAN_RESULTS)) { 7796a7f077Sopenharmony_ci SAMPLE_INFO("WIFI_EVENT_SCAN_DONE"); 7896a7f077Sopenharmony_ci g_scanAvailable = 1; 7996a7f077Sopenharmony_ci return; 8096a7f077Sopenharmony_ci } 8196a7f077Sopenharmony_ci if (StrMatch(pos, WPA_EVENT_TEMP_DISABLED) && strstr(pos, WIFI_AUTH_FAILED_REASON_STR)) { 8296a7f077Sopenharmony_ci SAMPLE_INFO("WIFI_EVENT_WRONG_KEY"); 8396a7f077Sopenharmony_ci return; 8496a7f077Sopenharmony_ci } 8596a7f077Sopenharmony_ci if (StrMatch(pos, WPA_EVENT_DISCONNECTED) && !strstr(pos, WIFI_AUTH_FAILED_REASON_CODE)) { 8696a7f077Sopenharmony_ci SAMPLE_INFO("WIFI_EVENT_DISCONNECTED"); 8796a7f077Sopenharmony_ci return; 8896a7f077Sopenharmony_ci } 8996a7f077Sopenharmony_ci} 9096a7f077Sopenharmony_ci 9196a7f077Sopenharmony_cistatic void CliRecvPending(void) 9296a7f077Sopenharmony_ci{ 9396a7f077Sopenharmony_ci while (wpa_ctrl_pending(g_monitorConn)) { 9496a7f077Sopenharmony_ci char buf[4096]; 9596a7f077Sopenharmony_ci size_t len = sizeof(buf) - 1; 9696a7f077Sopenharmony_ci if (wpa_ctrl_recv(g_monitorConn, buf, &len) == 0) { 9796a7f077Sopenharmony_ci buf[len] = '\0'; 9896a7f077Sopenharmony_ci SAMPLE_INFO("event received %s", buf); 9996a7f077Sopenharmony_ci WifiEventHandler(buf, len); 10096a7f077Sopenharmony_ci } else { 10196a7f077Sopenharmony_ci SAMPLE_INFO("could not read pending message."); 10296a7f077Sopenharmony_ci break; 10396a7f077Sopenharmony_ci } 10496a7f077Sopenharmony_ci } 10596a7f077Sopenharmony_ci} 10696a7f077Sopenharmony_ci 10796a7f077Sopenharmony_cistatic void* MonitorTask(void *args) 10896a7f077Sopenharmony_ci{ 10996a7f077Sopenharmony_ci (void)args; 11096a7f077Sopenharmony_ci int fd, ret; 11196a7f077Sopenharmony_ci fd_set rfd; 11296a7f077Sopenharmony_ci while (1) { 11396a7f077Sopenharmony_ci fd = wpa_ctrl_get_fd(g_monitorConn); 11496a7f077Sopenharmony_ci FD_ZERO(&rfd); 11596a7f077Sopenharmony_ci FD_SET(fd, &rfd); 11696a7f077Sopenharmony_ci ret = select(fd + 1, &rfd, NULL, NULL, NULL); 11796a7f077Sopenharmony_ci if (ret <= 0) { 11896a7f077Sopenharmony_ci SAMPLE_INFO("select failed ret = %d\n", ret); 11996a7f077Sopenharmony_ci break; 12096a7f077Sopenharmony_ci } 12196a7f077Sopenharmony_ci CliRecvPending(); 12296a7f077Sopenharmony_ci sleep(1); 12396a7f077Sopenharmony_ci } 12496a7f077Sopenharmony_ci return NULL; 12596a7f077Sopenharmony_ci} 12696a7f077Sopenharmony_ci 12796a7f077Sopenharmony_cistatic int SendCtrlCommand(const char *cmd, char *reply, size_t *replyLen) 12896a7f077Sopenharmony_ci{ 12996a7f077Sopenharmony_ci size_t len = *replyLen - 1; 13096a7f077Sopenharmony_ci wpa_ctrl_request(g_ctrlConn, cmd, strlen(cmd), reply, &len, 0); 13196a7f077Sopenharmony_ci DumpString(reply, len, "SendCtrlCommand raw return"); 13296a7f077Sopenharmony_ci if (len != 0 && !StrMatch(reply, WPA_CTRL_REQUEST_FAIL)) { 13396a7f077Sopenharmony_ci *replyLen = len; 13496a7f077Sopenharmony_ci return 0; 13596a7f077Sopenharmony_ci } 13696a7f077Sopenharmony_ci SAMPLE_ERROR("send ctrl request [%s] failed.", cmd); 13796a7f077Sopenharmony_ci return -1; 13896a7f077Sopenharmony_ci} 13996a7f077Sopenharmony_ci 14096a7f077Sopenharmony_cistatic void TestNetworkConfig(void) 14196a7f077Sopenharmony_ci{ 14296a7f077Sopenharmony_ci char networkId[20] = {0}; 14396a7f077Sopenharmony_ci size_t networkIdLen = sizeof(networkId); 14496a7f077Sopenharmony_ci int ret = SendCtrlCommand("DISCONNECT", networkId, &networkIdLen); 14596a7f077Sopenharmony_ci ret += SendCtrlCommand("ADD_NETWORK", networkId, &networkIdLen); 14696a7f077Sopenharmony_ci if (ret != 0) { 14796a7f077Sopenharmony_ci SAMPLE_ERROR("add network failed."); 14896a7f077Sopenharmony_ci return; 14996a7f077Sopenharmony_ci } 15096a7f077Sopenharmony_ci SAMPLE_INFO("add network success, network id [%.*s]", networkIdLen, networkId); 15196a7f077Sopenharmony_ci char reply[100] = {0}; 15296a7f077Sopenharmony_ci size_t replyLen = sizeof(reply); 15396a7f077Sopenharmony_ci char cmd[200] = {0}; 15496a7f077Sopenharmony_ci int temp = 0; 15596a7f077Sopenharmony_ci temp = sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s ssid \"example\"", networkIdLen, networkId); 15696a7f077Sopenharmony_ci if (temp != 0) { 15796a7f077Sopenharmony_ci printf("result is %d\n", temp); 15896a7f077Sopenharmony_ci }; 15996a7f077Sopenharmony_ci ret += SendCtrlCommand(cmd, reply, &replyLen); 16096a7f077Sopenharmony_ci replyLen = sizeof(reply); 16196a7f077Sopenharmony_ci temp = sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s psk \"012345678\"", networkIdLen, networkId); 16296a7f077Sopenharmony_ci if (temp != 0) { 16396a7f077Sopenharmony_ci printf("result is %d\n", temp); 16496a7f077Sopenharmony_ci }; 16596a7f077Sopenharmony_ci ret += SendCtrlCommand(cmd, reply, &replyLen); 16696a7f077Sopenharmony_ci replyLen = sizeof(reply); 16796a7f077Sopenharmony_ci temp = sprintf_s(cmd, sizeof(cmd), "ENABLE_NETWORK %.*s", networkIdLen, networkId); 16896a7f077Sopenharmony_ci if (temp != 0) { 16996a7f077Sopenharmony_ci printf("result is %d\n", temp); 17096a7f077Sopenharmony_ci }; 17196a7f077Sopenharmony_ci ret += SendCtrlCommand(cmd, reply, &replyLen); 17296a7f077Sopenharmony_ci replyLen = sizeof(reply); 17396a7f077Sopenharmony_ci ret += SendCtrlCommand("RECONNECT", reply, &replyLen); 17496a7f077Sopenharmony_ci replyLen = sizeof(reply); 17596a7f077Sopenharmony_ci if (ret == 0) { 17696a7f077Sopenharmony_ci SAMPLE_INFO("network config success."); 17796a7f077Sopenharmony_ci return; 17896a7f077Sopenharmony_ci } 17996a7f077Sopenharmony_ci temp = sprintf_s(cmd, sizeof(cmd), "REMOVE_NETWORK %.*s", networkIdLen, networkId); 18096a7f077Sopenharmony_ci if (temp != 0) { 18196a7f077Sopenharmony_ci printf("result is %d\n", temp); 18296a7f077Sopenharmony_ci }; 18396a7f077Sopenharmony_ci SendCtrlCommand(cmd, reply, &replyLen); 18496a7f077Sopenharmony_ci SAMPLE_ERROR("network config failed remove network [%.*s].", networkIdLen, networkId); 18596a7f077Sopenharmony_ci} 18696a7f077Sopenharmony_ci 18796a7f077Sopenharmony_cistatic void TestCliConnection(void) 18896a7f077Sopenharmony_ci{ 18996a7f077Sopenharmony_ci char reply[100] = {0}; 19096a7f077Sopenharmony_ci size_t replyLen = sizeof(reply); 19196a7f077Sopenharmony_ci int ret = SendCtrlCommand("PING", reply, &replyLen); 19296a7f077Sopenharmony_ci if (ret == 0 && StrMatch(reply, "PONG")) { 19396a7f077Sopenharmony_ci SAMPLE_INFO("connect to wpa success."); 19496a7f077Sopenharmony_ci return; 19596a7f077Sopenharmony_ci } 19696a7f077Sopenharmony_ci SAMPLE_INFO("connect to wpa failed, err = %s.", reply); 19796a7f077Sopenharmony_ci} 19896a7f077Sopenharmony_ci 19996a7f077Sopenharmony_cistatic void TestScan() 20096a7f077Sopenharmony_ci{ 20196a7f077Sopenharmony_ci char reply[100] = {0}; 20296a7f077Sopenharmony_ci size_t replyLen = sizeof(reply); 20396a7f077Sopenharmony_ci g_scanAvailable = 0; 20496a7f077Sopenharmony_ci SendCtrlCommand("SCAN", reply, &replyLen); 20596a7f077Sopenharmony_ci while (1) { 20696a7f077Sopenharmony_ci sleep(1); 20796a7f077Sopenharmony_ci if (g_scanAvailable == 1) { 20896a7f077Sopenharmony_ci SAMPLE_INFO("scan result received."); 20996a7f077Sopenharmony_ci break; 21096a7f077Sopenharmony_ci } 21196a7f077Sopenharmony_ci SAMPLE_INFO("waiting scan result."); 21296a7f077Sopenharmony_ci } 21396a7f077Sopenharmony_ci char scanResult[4096] = {0}; 21496a7f077Sopenharmony_ci size_t scanLen = sizeof(scanResult); 21596a7f077Sopenharmony_ci int ret = SendCtrlCommand("SCAN_RESULTS", scanResult, &scanLen); 21696a7f077Sopenharmony_ci if (ret != 0) { 21796a7f077Sopenharmony_ci SAMPLE_ERROR("request scan results failed."); 21896a7f077Sopenharmony_ci return; 21996a7f077Sopenharmony_ci } 22096a7f077Sopenharmony_ci DumpString(scanResult, scanLen, "scan results"); 22196a7f077Sopenharmony_ci} 22296a7f077Sopenharmony_ci 22396a7f077Sopenharmony_cistatic void StartTest() 22496a7f077Sopenharmony_ci{ 22596a7f077Sopenharmony_ci TestCliConnection(); // test if wpa control interface connected successfully 22696a7f077Sopenharmony_ci TestScan(); // test scan and get scan results 22796a7f077Sopenharmony_ci TestNetworkConfig(); // test config network and connect 22896a7f077Sopenharmony_ci} 22996a7f077Sopenharmony_ci 23096a7f077Sopenharmony_ciint InitControlInterface() 23196a7f077Sopenharmony_ci{ 23296a7f077Sopenharmony_ci g_ctrlConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for send cmd 23396a7f077Sopenharmony_ci g_monitorConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for event monitor 23496a7f077Sopenharmony_ci if (!g_ctrlConn || !g_monitorConn) { 23596a7f077Sopenharmony_ci SAMPLE_ERROR("open wpa control interface failed."); 23696a7f077Sopenharmony_ci return -1; 23796a7f077Sopenharmony_ci } 23896a7f077Sopenharmony_ci if (wpa_ctrl_attach(g_monitorConn) == 0) { // start monitor 23996a7f077Sopenharmony_ci pthread_create(&g_wpaThreadId, NULL, MonitorTask, NULL); // create thread for read event 24096a7f077Sopenharmony_ci return 0; 24196a7f077Sopenharmony_ci } 24296a7f077Sopenharmony_ci return -1; 24396a7f077Sopenharmony_ci} 24496a7f077Sopenharmony_ci 24596a7f077Sopenharmony_ciint main() 24696a7f077Sopenharmony_ci{ 24796a7f077Sopenharmony_ci if (InitControlInterface() != 0) { 24896a7f077Sopenharmony_ci SAMPLE_ERROR("control interface init failed, exit client."); 24996a7f077Sopenharmony_ci return -1; 25096a7f077Sopenharmony_ci } 25196a7f077Sopenharmony_ci SAMPLE_INFO("control interface init success."); 25296a7f077Sopenharmony_ci StartTest(); 25396a7f077Sopenharmony_ci pthread_join(g_wpaThreadId, NULL); 25496a7f077Sopenharmony_ci SAMPLE_INFO("test finished, exit client."); 25596a7f077Sopenharmony_ci} 256