nvidia设置wifi和接口

文章介绍了在嵌入式开发中如何使用nmcli命令来创建、删除、启动和关闭WiFi连接,包括通过QT或PAD进行远程设置。同时,展示了相关C++代码示例,用于获取WiFi扫描列表、连接信息,并设置了设置WiFi连接的函数。在调试部分提到了可能出现的问题,如SSID不存在或密码错误。
摘要由CSDN通过智能技术生成

前言

针对嵌入式开发,有时候通过QT或PAD跨网络对设备设置WIFI,在此记录下,方便后续的查阅。


基础知识点

1.创建和删除一个wifi连接

创建WIFI 连接

nmcli device wifi connect "SSID" password "passwd"

每次创建在/etc/NetworkManager/system-connections/目录下TR106-4文件多个,分别为"TR106" “TR106-4 1” TR106-4 2 …为什么有多个,笔者可能觉得是因为存在相同的SSID,不同的PASSWD的原因吧!

删除wifi连接
p.s:不允许手动rm删除,删除依然会保留到nmcli con show中

nmcli con del "SSID"

2. 启动连接和关闭连接

启动

nmcli connection up "TR106"或 nmcli device con wlan0
nmcli device con wlan0

关闭wifi连接

nmcli connection down "TR106"或nmcli device dis wlan0
  1. 创建热点 暂不描述,后续如增加再做记录。

代码和调试

1. 代码展示

#ifndef WIFI_MANAGE_H__
#define WIFI_MANAGE_H__

#include <vector>
#include <string>

#ifndef NMCCLI_CON_SHOW_ACTIVE
#define NMCCLI_CON_SHOW_ACTIVE	"nmcli con show -active |grep wifi |grep wlan"
#endif 



#define OUT		//param out 
#define IN		//param in
#define MAX_STRING (1024)
#define MIN_STRING (128)
namespace NMV
{
	
};
class CWifiManage
{
public:
	static CWifiManage *inst()
	{
		static CWifiManage wm;
		return &wm;
	}
	
	/**获取设备WIFI扫描的列表*/
	int getWifiSSIDScanf();
	
	const std::vector<std::string> &getSsidList()const {return m_ssid_list;}
	/**获取当前wlanx已连接的WIFI ssid和passwd,当前只有wlan0,如果有多个wlan,需要做修改*/
	int getSystemWlanxInfo(std::string &rhs_ssid, std::string &rhs_passwd);
	
	/**获取当前的SSID和PASSWD*/
	int getWifiInfo(std::string &rhs_ssid, std::string &rhs_passwd)const {rhs_ssid = m_WifiSsid; rhs_passwd = m_WifiPasswd;}
	/**设置一个wifi信息到系统,切换WIFI的操作*/
	int setWifiInfo2SystemNetwork(const std::string &rhs_ssid, const std::string &rhs_passwd,
			OUT char *sys_response);
	/**外部接口,设置WIFI*/
	int setWifiInfo(const std::string &rhs_ssid, const std::string &rhs_passwd);
private:
	CWifiManage();
	~CWifiManage();
	std::string m_WifiSsid, m_WifiPasswd;
	std::vector<std::string> m_ssid_list;
};

#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <string.h>

#include <string>
#include <iostream>
#include <codecvt>

#include "wifi_manage.h"

CWifiManage::CWifiManage():m_WifiSsid(""), m_WifiPasswd("")
{
	m_ssid_list.clear();
}

CWifiManage::~CWifiManage()
{}

int CWifiManage::getSystemWlanxInfo(OUT std::string &rhs_ssid, OUT std::string &rhs_passwd)
{
	char pipeBuf[MAX_STRING] = {0};
	char tssid[MIN_STRING] = {0};
	
	FILE * pPipe = popen(NMCCLI_CON_SHOW_ACTIVE, "r");
	if(!pPipe)
	{
		printf("PIPE ERROR\n");
		return -1;
	}
	size_t pipeSiz = ftell(pPipe);
	fseek(pPipe, 0, SEEK_SET);
	fread(pipeBuf, 1, pipeSiz, pPipe);

	if(pPipe){pclose(pPipe); pPipe = (FILE*)0;}
	if(!strlen(pipeBuf))
	{
		printf("无连接上的WIFI!\n");
		return -1;
	}
	
	sscanf(pipeBuf, "%s", tssid);
	
	
	/*根据SSID查看Passwd*/
	char ssidFileConfigure[MIN_STRING] = {0};
	snprintf(ssidFileConfigure, MIN_STRING-1, "/etc/NetworkManager/system-connections/%s", tssid);
	FILE *fp = fopen(ssidFileConfigure, "r");
	if(!fp)
	{
		printf("打开%s失败!\n", ssidFileConfigure);
		return -1;
	}

	char line_buf[MIN_STRING] = {0};
	char tpasswd[MIN_STRING] = {0};
	
	while(!feof(fp))
	{
		memset(line_buf, 0, MIN_STRING);
		fgets(line_buf, MIN_STRING, fp);
		if(strstr(line_buf, "psk="))
		{
			
			size_t line_siz = strlen(line_buf);
			if(line_buf[line_siz-1] == '\n') line_buf[line_siz-1] = '\0';
			memcpy(tpasswd, line_buf+strlen("psk="), strlen(line_buf+strlen("psk=")));
			
			printf("passwd:%s, siz:%lu!\n" , tpasswd, strlen(tpasswd));
		}
	}

	if(fp){fclose(fp); fp = (FILE*)0;}

	if(strlen(tssid)&& strlen(tpasswd)){rhs_ssid = tssid; rhs_passwd = tpasswd;}

	return 0;
	
}


int CWifiManage::setWifiInfo2SystemNetwork(const std::string &rhs_ssid, const std::string &rhs_passwd,char *sys_response)
{

	
	char cmd_string[MIN_STRING] = {0};
	memset(cmd_string, 0, MIN_STRING);
	snprintf(cmd_string, MIN_STRING, "nmcli device wifi connect %s password %s", rhs_ssid.c_str(), rhs_passwd.c_str());

 	FILE *pPipe = popen(cmd_string, "r"); //阻塞
 	if(!pPipe)
 	{
 		printf("cmdString: %s, err:%s\n" , cmd_string, strerror(errno));
 		memcpy(sys_response, "pipe null", strlen("pipe null"));
		return -1;
 	}
	fread(sys_response, 1, MAX_STRING-1, pPipe);
	
	
	pclose(pPipe); pPipe = (FILE*)0;
	if(!strstr(sys_response, "successfully"))			//如果设置失败
	{
		return -2;
	}
	printf("SSID:%s 设置成功!\n", rhs_ssid.c_str());

	/*重置wifi为设置的ssid和信息,更新 "nmcli con show"*/
	//1. 关闭之前的连接
	pPipe = popen("nmcli device dis wlan0", "r");
	
	if(pPipe){pclose(pPipe); pPipe = (FILE*)0;}
	//2 开启设置的连接
	memset(cmd_string, 0, MIN_STRING);
	snprintf(cmd_string, MIN_STRING, "nmcli connection up %s", rhs_ssid.c_str());
	pPipe = popen(cmd_string, "r");
	
	if(pPipe){pclose(pPipe); pPipe = (FILE*)0;}

#if 0		//配置暂先不做处理
	//3 删除(忘记)不需要的WIFI连接 cmd:nmcli con del "SSID",仅保留设置的wifi有效
	pPipe = popen("ls /etc/NetworkManager/system-connections/ |grep -v 'Wire'", "r");
	char ssid[MIN_STRING];
	if(pPipe)
	{
		while(!feof(pPipe))
		{
			memset(ssid, 0, MIN_STRING);
			fgets(ssid, MIN_STRING-1, pPipe);
			if(ssid[strlen(ssid)-1] == '\n') ssid[strlen(ssid)-1] = '\0';
			if(rhs_ssid == std::string(ssid))
			{
				continue;
			}
			comm_sys_cmd("nmcli con del %s", ssid);
		}
	}
#endif
	
 
	
	return 0;
}




int CWifiManage::getWifiSSIDScanf()
{
	//扫描WIFI ESSID
	//do somethings

	char cmd_string[MIN_STRING] = {0};
	char sline[MIN_STRING], ssid[MIN_STRING];
	
	memset(cmd_string, 0, MIN_STRING);
	
	snprintf(cmd_string, MIN_STRING, "iw wlan0 scan |grep SSID");	
	FILE *pPipe = (FILE*)0;
	pPipe = popen(cmd_string, "r");
	if(!pPipe)
	{
		printf("cmdString: %s, err:%s\n" , cmd_string, strerror(errno));
 		
		return -1;
	}

	while(!feof(pPipe))
	{
		memset(sline, 0, MIN_STRING);memset(ssid, 0 , MIN_STRING);
		fgets(sline, MIN_STRING, pPipe);
		int j = 0;
		for(int i = 0; i < strlen(sline); ++i)
		{
			if(sline[i] == '\t' || sline[i] == '\n' || sline[i] == ' ')
			{
				continue ;
			}
			ssid[j] = sline[i];
			j++;
		}
		//printf("ssid:%s, siz:%lu\n", ssid, strlen(ssid));
		if(0 == strlen(ssid) - strlen("SSID:") || strlen(sline) == 0 )
		{
			//printf("ssid为空\n");
			continue;
		}

		if(strstr(ssid, "x00"))
		{
			printf("含有x00\n");
			continue;
		}
		static std::wstring_convert<std::codecvt_utf8<wchar_t> > strCnv;
	//	std::wstring test = strCnv.from_bytes(ssid);
		printf("%s\n", test.c_str());
		m_ssid_list.push_back(ssid+strlen("SSID:"));
		
		
		
	}
	auto vit = m_ssid_list.begin();
	for(; vit != m_ssid_list.end();++vit)
	{	
		static int cnt = 0;
		std::cout <<  "SSID_siz:" << (*vit).size() << " "<< *vit << std::endl;;
	}
	
	if(pPipe){pclose(pPipe); pPipe = (FILE*)0;}

	return 0;
}




int CWifiManage::setWifiInfo(const std::string &rhs_ssid, const std::string &rhs_passwd)
{
	char sys_resp[MAX_STRING] = {0};
	if(setWifiInfo2SystemNetwork(rhs_ssid, rhs_passwd,  sys_resp))
	{
		printf("设置wifi失败!");
	}
	std::cout << "设置wifi系统提示: " << sys_resp << std::endl;

	m_WifiSsid = rhs_ssid;
	m_WifiPasswd = rhs_passwd;
	

	return  0;
}

int main(int argc, char *argv[])
{
	int ret = 0;
#if 0
	std::string str_ssid = "", str_passwd = "";
	
	ret = CWifiManage::inst()->getSystemWlanxInfo(str_ssid, str_passwd);
	if(ret == 0)
	{
		printf("当前wifi已连接成功, ssid:%s, passwd:%s\n", str_ssid.c_str(), str_passwd.c_str());
	}

	if(CWifiManage::inst()->setWifiInfo("HONOR-Hello-Ouyang_2.4", "woshisunouyangaaaa"))
	{
		printf("设置wifi失败!\n");
	}
#else 

	CWifiManage::inst()->getWifiSSIDScanf();
#endif 
	
}

2. 调试

扫描中踢出了空格,换行和制表符
获取WIFI扫描

{
	"Jsonrpc": "1.0",
	"Method": "GetWifiScan",
	"Result": true,
	"SsidList": [
		"TR106-4",
		"HONOR-Hello-Ouyang_2.4",
		"HUAWEI-WANG",
		"Maxvision-2.4G",
		"HUAWEI-MV_SLAM_02",
		"ymg",
		"fanyiji-ceshi",
		"Tenda_1D0130",
		"cleanRobot",
		"Xiaomi_DESKT",
		"YUN",
		"siweite7wifi",
		"HUAWEI-MV_SLAM_00",
		"HONOR-xunjian-Mast",
		"HONOR-xunjian-Mast",
		"jxkjc",
		"Trans-4G-SanFanTest",
		"TP-LINK_2.4G_D6D088",
		"TR106-4",
		"Maxvision-2.4G",
		"ChinaNet-5pV3-5G",
		"HUAWEI-MV_SLAM_00",
		"HONOR-Hello-Ouyang_5G",
		"HUAWEI-MV_SLAM_02",
		"ROBOT_TEST",
		"HONOR-0J14YA",
		"xunjian"
	]
}

设置wifi过程中遇到的问题:

1. SSID不存在,返回如下错误
{
	"Jsonrpc": "1.0",
	"Method": "SetWifiConnect",
	"Params": null,
	"ResponseMsg": "ERROR:未扫描到SSID:TR106-41",
	"Result": false
}
之前使用PAD对设备设置,用的是android的API扫描WIFI SSID,可能设备和WIFI处的位置不同,以及无线网卡的差异性,导致PAD搜索的SSID可能设备网卡搜不到的情况。

2.输入的密码错误

{
	"Jsonrpc": "1.0",
	"Method": "SetWifiConnect",
	"Params": null,
	"ResponseMsg": "ERROR:Error: Connection activation failed: (7) Secrets were required, but not provided.\n",
	"Result": false
}

写到最后

1. 每次设置一个新WIFI,将之前的配置都删除掉,让设备只连最近更新的WIFI,后面考虑合理性以及手机android等
都采用保存配置的情况, 该功能就删除了。
2. 还有比较多的功能可以实现,比如忘记WIFI名称等功能。
忘记WIFI名称
pPipe = popen("ls /etc/NetworkManager/system-connections/ |grep -v 'Wire'", "r");
	char ssid[128];
	if(pPipe)
	{
		while(!feof(pPipe))
		{
			memset(ssid, 0, MIN_STRING);
			fgets(ssid, MIN_STRING-1, pPipe);
			if(ssid[strlen(ssid)-1] == '\n') ssid[strlen(ssid)-1] = '\0';
			if(rhs_ssid == std::string(ssid))
			{
				continue;
			}
			std::string str_cmd = "nmcli con del" + " " + ssid;
			system(str_cmd.c_str());
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值