二、当接入网络,触发WifiEventTrigger(),开启软总线
- Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\discovery_service.c
- void WifiEventTrigger(unsigned int para)
- {
- DeviceInfo *localDev = GetCommonDeviceInfo();
- if (localDev == NULL) {
- return;
- }
- int ret;
- if (para) {
- char wifiIp[MAX_DEV_IP_LEN] = {0};
- CoapGetIp(wifiIp, MAX_DEV_IP_LEN, 0); //参考1.获取本设备ip
- if (strcmp(wifiIp, "0.0.0.0") == 0) {
- SOFTBUS_PRINT("[DISCOVERY] WifiEventTrigger new event interupt.\n");
- return;
- }
- ret = memcpy_s(localDev->deviceIp, sizeof(localDev->deviceIp), wifiIp, sizeof(wifiIp));
- } else {
- ret = memset_s(localDev->deviceIp, sizeof(localDev->deviceIp), 0, sizeof(localDev->deviceIp));
- }
- if (ret != ERROR_SUCCESS) {
- return;
- }
- if (BusManager(para) != ERROR_SUCCESS) { //参考2.BusManager()启动软总线
- SOFTBUS_PRINT("[DISCOVERY] WifiEventTrigger StartBusManager(%d) fail\n", para);
- return;
- }
- if (CoapRegisterDeviceInfo() != ERROR_SUCCESS) {
- SOFTBUS_PRINT("[DISCOVERY] WifiEventTrigger CoapRegisterDeviceInfo fail\n");
- return;
- }
- if (DoRegistService(COAP) != ERROR_SUCCESS) {
- SOFTBUS_PRINT("[DISCOVERY] WifiEventTrigger DoRegistService fail\n");
- return;
- }
- }
1.获取本设备ip
- Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
- //通过CoapGetIp()循环获取本地设备wifi连接后的IP地址,并放入到deviceInfo->deviceIp中。后续会使用。
- void CoapGetIp(char *ip, int length, int finite)
- {
- if (ip == NULL || length != NSTACKX_MAX_IP_STRING_LEN) {
- return;
- }
- g_queryIpFlag = 1;
- int count = finite ? GET_IP_TIMES : GET_IP_INFINITE;
- while (g_queryIpFlag) {
- CoapGetWifiIp(ip, length);//获取ip方式根据内核不同,会有多个方式
- if (CheckIpIsValid(ip, strlen(ip)) == 0) {
- break;
- }
- if (count == 0) {
- break;
- }
- count--;
- usleep(TEN_MS); //#define TEN_MS (10 * 1000)//usleep 10ms,每次获取IP间隔10ms
- }
- return;
- }
2.BusManager()启动软总线
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- int BusManager(unsigned int startFlag)
- {
- if (startFlag == 1) {
- return StartBus();
- } else {
- return StopBus();
- }
- }
- ==============================================================================
- int StartBus(void)
- {
- if (g_busStartFlag == 1) {
- return 0;
- }
- DeviceInfo *info = GetCommonDeviceInfo();
- if (info == NULL) {
- return ERROR_FAIL;
- }
- g_baseLister.onConnectEvent = OnConnectEvent; //当存在新连接时调用此函数
- g_baseLister.onDataEvent = OnDataEvent; //当存在新数据时调用此函数
- //StartListener()函数负责为认证模块提供通道完成初始化
- int authPort = StartListener(&g_baseLister, info->deviceIp); //参考:2.1.启动侦听
- if (authPort < 0) {
- SOFTBUS_PRINT("[AUTH] StartBus StartListener fail\n");
- return ERROR_FAIL;
- }
- info->devicePort = authPort;
- //StartSession()函数负责初始化业务的session管理
- int sessionPort = StartSession(info->deviceIp); //参考:2.2.启动会话
- if (sessionPort < 0) {
- SOFTBUS_PRINT("[AUTH] StartBus StartSession fail\n");
- StopListener();
- return ERROR_FAIL;
- }
- AuthMngInit(authPort, sessionPort);
- g_busStartFlag = 1;
- SOFTBUS_PRINT("[AUTH] StartBus ok\n");
- return 0;
- }
- ==============================================================================
- //回调函数的处理
- //trans_service模块的使用者设置的回调函数将在存在新连接、和新数据时被调用
- //比如认证模块通过以下函数完成认证动作:OnConnectEvent()函数中完成对新连接的处理, OnDataEvent()函数中完成对新数据的处理。
- int OnConnectEvent(int fd, const char *ip)
- ProcessConnectEvent(fd, ip);
- return 0;
- }
- int OnDataEvent(int fd)
- ProcessDataEvent(fd);
- return 0;
- }
2.1.启动监听,StartListener(),监听与发现端建立连接
StartListener()函数的底层存在对应不同版本平台的适配函数,这印证了鸿蒙OS各部分解耦的模块化设计思想,针对不同的硬件设备,组合成最适合该设备的OS。比如创建线程时采用了统一的static void WaitProcess(void)函数,而其内部封装了不同底层API的适配代码。
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c
- //StartListener()函数负责为认证模块提供通道完成初始化
- //该函数主要是创建了一个WaitProcess 的线程,该线程用于对g_maxFd 所代表的文件描述符利用select 函数进行监控,若返回值大于0,则调用ProcessAuthData 函数。该函数完成对建立的链接的数据进行收发,并对收到的数据进行处理的工作,两个处理事件的函数分别是onConnectEvent和onDataEvent,即前面注册的两个回调函数。其中onConnectEvent 函数主要是为新建立连接的设备创建AuthConnNode 类型的节点,并将其加入链表中;onDataEvent 函数是对AuthConnNode节点中的数据成员进行内存分配及对数据进行处理。
- #if defined(__LITEOS_M__) || defined(__LITEOS_RISCV__)
- int StartListener(BaseListener *callback, const char *ip) // *callback,回调函数
- {
- if (callback == NULL || ip == NULL) {
- return -DBE_BAD_PARAM;
- }
- g_callback = callback;
- //InitListenFd()函数完成监听TCP socket的创建和监听,其中IP地址和端口号由上层调用者指定。
- int rc = InitListenFd(ip, SESSIONPORT); //
- if (rc != DBE_SUCCESS) {
- return -DBE_BAD_PARAM;
- }
- osThreadAttr_t attr;
- attr.name = "trans_auth_task";
- attr.attr_bits = 0U;
- attr.cb_mem = NULL;
- attr.cb_size = 0U;
- attr.stack_mem = NULL;
- attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
- attr.priority = osPriorityNormal5; // LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO -> cmsis prio
- //osThreadNew()在不同平台上会有不同的实现,在LITEOS_A和Linux平台上, osThreadNew()会调用兼容POSIX的pthread_create()完成线程的创建
- g_uwTskLoID = osThreadNew((osThreadFunc_t)WaitProcess, NULL, &attr);//监听新连接和数据WaitProcess(void)
- if (NULL == g_uwTskLoID) {
- SOFTBUS_PRINT("[TRANS] StartListener task create fail\n");
- return -1;
- }
- SOFTBUS_PRINT("[TRANS] StartListener ok\n");
- return GetSockPort(g_listenFd);
- }
- ==============================================================================
- static void WaitProcess(void)//监听新连接和数据WaitProcess(void)
- {
- SOFTBUS_PRINT("[TRANS] WaitProcess begin\n");
- fd_set readSet;
- fd_set exceptfds;
- while (1) {//WaitProcess()使用忙等方式,调用select()来监听listenFd和数据g_dataFd的信息,如果监听到有数据可读,则进入ProcessAuthData来处理。
- FD_ZERO(&readSet);
- FD_ZERO(&exceptfds);
- FD_SET(g_listenFd, &readSet);
- if (g_dataFd >= 0) {
- FD_SET(g_dataFd, &readSet);
- FD_SET(g_dataFd, &exceptfds);
- }
- int ret = select(g_maxFd + 1, &readSet, NULL, &exceptfds, NULL);//监听g_listenFd和数据g_dataFd的信息
- if (ret > 0) {//如果监听到有数据可读,则进入ProcessAuthData来处理。
- if (!ProcessAuthData(g_listenFd, &readSet)) {//【重要的监听】参考:
- SOFTBUS_PRINT("[TRANS] WaitProcess ProcessAuthData fail\n");
- StopListener();
- break;
- }
- } else if (ret < 0) {//如果发现g_dataFd有异常信息,则将其关闭。其中g_dataFd是由listenFd监听到连接时创建的socket。
- if (errno == EINTR || (g_dataFd > 0 && FD_ISSET(g_dataFd, &exceptfds))) {
- SOFTBUS_PRINT("[TRANS] errno == EINTR or g_dataFd is in exceptfds set.\n");
- CloseAuthSessionFd(g_dataFd);
- continue;
- }
- SOFTBUS_PRINT("[TRANS] WaitProcess select fail, stop listener\n");
- StopListener();
- break;
- }
- }
- }
2.2.启动会话,StartSession()
- //StartSession()函数负责初始化业务的session管理
- //StartSession 该函数只有一个参数,即const char *ip,也就是一个IP,和StartListener函数中的IP 是一样的。该函数是为全局变量g_sessionMgr 申请空间及初始化,然后根据所给的参数创建socket 文件描述符并监听,之后通过调用StartSelectLoop 函数创建SelectSessionLoop 的线程,该线程将socket 文件描述符加入集合,并调用select 函数进行监控,若函数的返回值大于0,则调用ProcessData 函数,该函数有两个分支,若socket 未创建session则为其创建session;若已创建session,则处理其数据部分
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- int StartSession(const char *ip)
- {
- int port = CreateTcpSessionMgr(true, ip);
- return port;
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- int CreateTcpSessionMgr(bool asServer, const char* localIp)
- {
- if (localIp == NULL) {
- return TRANS_FAILED;
- }
- if (InitTcpMgrLock() != 0 || GetTcpMgrLock() != 0) {
- return TRANS_FAILED;
- }
- int ret = InitGSessionMgr();
- if (ReleaseTcpMgrLock() != 0 || ret != 0) {
- FreeSessionMgr();
- return TRANS_FAILED;
- }
- g_sessionMgr->asServer = asServer;//该函数是为全局变量g_sessionMgr 申请空间及初始化
- int listenFd = OpenTcpServer(localIp, DEFAULT_TRANS_PORT);
- if (listenFd < 0) {
- SOFTBUS_PRINT("[TRANS] CreateTcpSessionMgr OpenTcpServer fail\n");
- FreeSessionMgr();
- return TRANS_FAILED;
- }
- int rc = listen(listenFd, LISTEN_BACKLOG);//然后根据所给的参数创建socket 文件描述符并监听
- if (rc != 0) {
- SOFTBUS_PRINT("[TRANS] CreateTcpSessionMgr listen fail\n");
- CloseSession(listenFd);
- FreeSessionMgr();
- return TRANS_FAILED;
- }
- g_sessionMgr->listenFd = listenFd;
- signal(SIGPIPE, SIG_IGN);
- if (StartSelectLoop(g_sessionMgr) != 0) {//之后通过调用StartSelectLoop 函数创建SelectSessionLoop 的线程
- SOFTBUS_PRINT("[TRANS] CreateTcpSessionMgr StartSelectLoop fail\n");
- CloseSession(listenFd);
- FreeSessionMgr();
- return TRANS_FAILED;
- }
- return GetSockPort(listenFd);
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- #if defined(__LITEOS_M__) || defined(__LITEOS_RISCV__)
- int StartSelectLoop(TcpSessionMgr *tsm)
- {
- if (tsm == NULL) {
- return TRANS_FAILED;
- }
- if (tsm->isSelectLoopRunning) {
- return 0;
- }
- osThreadId_t sessionLoopTaskId;
- osThreadAttr_t attr;
- attr.name = "trans_session_task";
- attr.attr_bits = 0U;
- attr.cb_mem = NULL;
- attr.cb_size = 0U;
- attr.stack_mem = NULL;
- attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
- attr.priority = osPriorityNormal5; // LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO -> cmsis prio
- //该线程将socket 文件描述符加入集合,并调用select 函数进行监控,
- sessionLoopTaskId = osThreadNew((osThreadFunc_t)SelectSessionLoop, (void *)tsm, &attr);
- if (NULL == sessionLoopTaskId) {
- SOFTBUS_PRINT("[TRANS] StartSelectLoop TaskCreate fail\n");
- return TRANS_FAILED;
- }
- return 0;
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- static void SelectSessionLoop(TcpSessionMgr *tsm)
- {
- if (tsm == NULL) {
- return;
- }
- SOFTBUS_PRINT("[TRANS] SelectSessionLoop begin\n");
- tsm->isSelectLoopRunning = true;
- while (true) {
- fd_set readfds;
- fd_set exceptfds;
- int maxFd = InitSelectList(tsm, &readfds, &exceptfds);
- if (maxFd < 0) {
- break;
- }
- errno = 0;
- int ret = select(maxFd + 1, &readfds, NULL, &exceptfds, NULL);
- if (ret < 0) {
- SOFTBUS_PRINT("RemoveExceptSessionFd\r\n");
- if (errno == EINTR || RemoveExceptSessionFd(tsm, &exceptfds) == 0) {
- continue;
- }
- SOFTBUS_PRINT("[TRANS] SelectSessionLoop close all Session\n");
- CloseAllSession(tsm);
- break;
- } else if (ret == 0) {
- continue;
- } else {//若函数的返回值大于0,则调用ProcessData 函数,
- ProcessData(tsm, &readfds);
- }
- }
- tsm->isSelectLoopRunning = false;
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- static void ProcessData(TcpSessionMgr *tsm, fd_set *rfds)
- {
- if (tsm == NULL || tsm->listenFd == -1) {
- return;
- }
- //该函数有两个分支,若socket 未创建session则为其创建session;若已创建session,则处理其数据部分
- if (FD_ISSET(tsm->listenFd, rfds)) {
- ProcessConnection(tsm);
- return;
- }
- ProcessSesssionData(tsm, rfds);
- }
总结:
当软总线启动后,就会开始监听新连接,OnConnectEvent()函数中完成对新连接的处理, OnDataEvent()函数中完成对新数据的处理。
三、当发现端(比如手机)发送广播
当鸿蒙手机开启锁屏后,会在局域网内发送UDP广播,当开发板(服务端)检测到广播会调用下面的函数。
1.当检测到局域网内UDP广播包,HandleReadEvent()
- Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
- static void HandleReadEvent(int fd)
- {
- int socketFd = fd;
- unsigned char *recvBuffer = calloc(1, COAP_MAX_PDU_SIZE + 1);
- if (recvBuffer == NULL) {
- return;
- }
- ssize_t nRead;
- nRead = CoapSocketRecv(socketFd, recvBuffer, COAP_MAX_PDU_SIZE);//这个函数读取socket的内容
- if ((nRead == 0) || (nRead < 0 && errno != EAGAIN &&
- errno != EWOULDBLOCK && errno != EINTR)) {
- free(recvBuffer);
- return;
- }
- COAP_Packet decodePacket;
- (void)memset_s(&decodePacket, sizeof(COAP_Packet), 0, sizeof(COAP_Packet));
- decodePacket.protocol = COAP_UDP;
- COAP_SoftBusDecode(&decodePacket, recvBuffer, nRead);//然后调用COAP_SoftBusDecode来解码
- PostServiceDiscover(&decodePacket);//解码后的报文由PostServiceDiscover来处理,参考下面解析
- free(recvBuffer);
- }
- ==============================================================================
- void PostServiceDiscover(const COAP_Packet *pkt)
- {
- char *remoteUrl = NULL;
- DeviceInfo deviceInfo;
- if (pkt == NULL) {
- return;
- }
- (void)memset_s(&deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo));
- //关于GetServiceDiscoverInfo()这个解包函数暂时不深挖了,TODO
- if (GetServiceDiscoverInfo(pkt->payload.buffer, pkt->payload.len, &deviceInfo, &remoteUrl) != NSTACKX_EOK) {
- return;
- }
- char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
- (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));
- (void)inet_ntop(AF_INET, &deviceInfo.netChannelInfo.wifiApInfo.ip, wifiIpAddr, sizeof(wifiIpAddr));
- printf(">>>>>%s:%d\nremoteUrl:%s\nwifiIpAddr:%s\n",__FILE__,__LINE__,remoteUrl,wifiIpAddr);//添加打印调试
- if (remoteUrl != NULL) {
- CoapResponseService(pkt, remoteUrl, wifiIpAddr);//通过解析到的手机(发现端)的地址,应答服务
- free(remoteUrl);
- }
- }
- ==============================================================================
- static int CoapResponseService(const COAP_Packet *pkt, const char* remoteUrl, const char* remoteIp)
- {
- int ret;
- CoapRequest coapRequest;
- (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest));
- coapRequest.remoteUrl = remoteUrl;
- coapRequest.remoteIp = remoteIp;
- char *payload = PrepareServiceDiscover();
- if (payload == NULL) {
- return NSTACKX_EFAILED;
- }
- printf(">>>>>%s:%d\npayload:%s\n",__FILE__,__LINE__,payload);//添加打印调试
- COAP_ReadWriteBuffer sndPktBuff = {0};
- sndPktBuff.readWriteBuf = calloc(1, COAP_MAX_PDU_SIZE);
- if (sndPktBuff.readWriteBuf == NULL) {
- free(payload);
- return NSTACKX_EFAILED;
- }
- sndPktBuff.size = COAP_MAX_PDU_SIZE;
- sndPktBuff.len = 0;
- ret = BuildSendPkt(pkt, remoteIp, payload, &sndPktBuff);//构建要发回的包
- free(payload);
- if (ret != DISCOVERY_ERR_SUCCESS) {
- free(sndPktBuff.readWriteBuf);
- sndPktBuff.readWriteBuf = NULL;
- return ret;
- }
- coapRequest.data = sndPktBuff.readWriteBuf;
- coapRequest.dataLength = sndPktBuff.len;
- ret = CoapSendRequest(&coapRequest); //发送
- free(sndPktBuff.readWriteBuf);
- sndPktBuff.readWriteBuf = NULL;
- return ret;
- }
2.当检测到新连接,ProcessAuthData()
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c:85
- //无论是新连接请求,还是已有连接中有数据到来,均会进入本函数。
- static bool ProcessAuthData(int listenFd, const fd_set *readSet)
- {
- if (readSet == NULL || g_callback == NULL || g_callback->onConnectEvent == NULL ||
- g_callback->onDataEvent == NULL) {
- return false;
- }
- if (FD_ISSET(listenFd, readSet)) {//判断是否是listenFd上存在消息
- struct sockaddr_in addrClient = {0};
- socklen_t addrLen = sizeof(addrClient);
- //如果是,则说明当前存在新的连接,这时调用accept()完成链接创建,新创建的socket的fd被存储在g_dataFd中,
- g_dataFd = accept(listenFd, (struct sockaddr *)(&addrClient), &addrLen);
- if (g_dataFd < 0) {
- CloseAuthSessionFd(listenFd);
- return false;
- }
- RefreshMaxFd(g_dataFd);
- //同时调用g_callback->onConnectEvent通知认证模块有新的连接事件发生,并将新创建的fd和client的IP地址告知认证模块。
- //与此同时,创建g_dataFd时候需要刷新g_maxFd,以保证在WaitProcess()中的下一次select()操作时中,会监听到g_dataFd上的事件。
- if (g_callback->onConnectEvent(g_dataFd, inet_ntoa(addrClient.sin_addr)) != 0) { //参考下面解析OnConnectEvent()
- CloseAuthSessionFd(g_dataFd);
- }
- }
- //如果FD_ISSET()判断出g_dataFd上存在消息,则说明已完成握手的连接向本节点发送了数据,
- if (g_dataFd > 0 && FD_ISSET(g_dataFd, readSet)) { //参考下面解析OnDataEvent()
- g_callback->onDataEvent(g_dataFd);//这时函数回调g_callback->onDataEvent(),把控制权返回给调用者,以处理接收到的数据。
- }
- return true;
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- int OnConnectEvent(int fd, const char *ip)
- {
- ProcessConnectEvent(fd, ip); //2.1当建立新连接
- return 0;
- }
- int OnDataEvent(int fd)
- {
- ProcessDataEvent(fd); //2.2当接收到新数据
- return 0;
- }
2.1当建立新连接,OnConnectEvent()
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:192行
- void ProcessConnectEvent(int fd, const char *ip)
- {
- SOFTBUS_PRINT("[AUTH] ProcessConnectEvent fd = %d\n", fd);
- AuthConn *aconn = FindAuthConnByFd(fd); //通过fd查找验证连接
- aconn = calloc(1, sizeof(AuthConn)); //? 系统声明吗?
- int ret = strcpy_s(aconn->deviceIp, sizeof(aconn->deviceIp), ip);//字符串复制函数
- aconn->fd = fd;
- ret = AddAuthConnToList(aconn);//添加认证连接到列表
- }
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:554
- 这个函数被调用3次??
- 数据事件进程
- void ProcessDataEvent(int fd)
- {
- SOFTBUS_PRINT("[AUTH] ProcessDataEvent fd = %d\n", fd);
- AuthConn *conn = FindAuthConnByFd(fd); //通过fd查找验证连接
- if (conn->db.buf == NULL) {
- conn->db.buf = (char *)malloc(DEFAULT_BUF_SIZE);
- if (conn->db.buf == NULL) {
- return;
- }
- (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
- conn->db.size = DEFAULT_BUF_SIZE;
- conn->db.used = 0;
- }
- DataBuffer *db = &conn->db;
- char *buf = db->buf;
- int used = db->used;
- int size = db->size;
- int rc = AuthConnRecv(fd, buf, used, size - used, 0);
- if (rc == 0) {
- return;
- } else if (rc < 0) {
- CloseConn(conn);
- return;
- }
- used += rc;
- int processed = ProcessPackets(conn, buf, size, used); //参考下面解析1
- if (processed > 0) {
- used -= processed;
- if (used != 0) {
- if (memmove_s(buf, processed, buf, used) != EOK) {
- CloseConn(conn);
- return;
- }
- }
- } else if (processed < 0) {
- CloseConn(conn);
- return;
- }
- db->used = used;
- SOFTBUS_PRINT("[AUTH] ProcessDataEvent ok\n");
- }
1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:527行
- static int ProcessPackets(AuthConn *conn, const char *buf, int size, int used)
- {
- int processed = 0;
- while (processed + PACKET_HEAD_SIZE < used) {
- Packet *pkt = ParsePacketHead(buf, processed, used - processed, size);//参考下面解析1
- int len = pkt->dataLen;//将解析完包的大小,赋值给len
- processed += PACKET_HEAD_SIZE;//+24
- OnDataReceived(conn, pkt, buf + processed);//参考下面解析2
- processed += len;
- free(pkt);
- pkt = NULL;
- }
- return processed;
- }
1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:485行
- //解析包头,这个函数返回一个packet的结构体
- static Packet *ParsePacketHead(const char *buf, int offset, int len, int size)
- {
- unsigned int identifier = GetIntFromBuf(buf, offset); //1.从buf获取识别码
- offset += DEFAULT_INT_LEN; //将偏移量+4
- int module = GetIntFromBuf(buf, offset);//2.从buf获取module
- offset += DEFAULT_INT_LEN;//将偏移量+4
- long long seq = 0;
- if (GetLongFromBuf(buf, offset, &seq) != 0) {//3.从buf获取序列号
- return NULL;
- }
- offset += DEFAULT_LONG_LEN;//将偏移量+4
- int flags = GetIntFromBuf(buf, offset);//4.从buf获取标志位
- offset += DEFAULT_INT_LEN;//将偏移量+4
- int dataLen = GetIntFromBuf(buf, offset);//5.从buf获取数据长度
- SOFTBUS_PRINT("[AUTH] ParsePacketHead module=%d, seq=%lld, flags=%d, datalen=%d\n", module, seq, flags, dataLen);
- Packet *packet = (Packet *)malloc(sizeof(Packet));
- packet->module = module;
- packet->seq = seq;
- packet->flags = flags;
- packet->dataLen = dataLen;
- return packet;
- }
2.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:446行
- static void OnDataReceived(AuthConn *conn, const Packet *pkt, const char *data)
- {
- SOFTBUS_PRINT("[AUTH] OnDataReceived\n"); //数据接收
- if ((pkt->module > MODULE_HICHAIN) && (pkt->module <= MODULE_AUTH_SDK)) {
- //接收数据的认证接口函数,参考解析1
- AuthInterfaceOnDataReceived(conn, pkt->module, pkt->seq, data, pkt->dataLen);
- return;
- }
- cJSON *msg = DecryptMessage(pkt->module, data, pkt->dataLen);
- if (msg == NULL) {
- SOFTBUS_PRINT("[AUTH] OnDataReceived DecryptMessage fail\n");
- return;
- }
- OnModuleMessageReceived(conn, pkt->module, pkt->flags, pkt->seq, msg);
- cJSON_Delete(msg);
- msg = NULL;
- }
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\auth_interface.c
- void AuthInterfaceOnDataReceived(const AuthConn *conn, int module, long long seqId, const char *data, int dataLen)
- {
- SOFTBUS_PRINT("[AUTH] AuthInterfaceOnDataReceived begin\n");
- if (AuthSessionMapInit() != 0) { //认证会话初始化
- return;
- }
- AuthSession *auth = AuthGetAuthSessionBySeqId(seqId);//身份验证-通过序列ID获取验证会话
- if (auth == NULL) {
- auth = AuthGetNewAuthSession(conn, seqId, g_authSessionId);//身份验证-获取新的验证会话
- if (auth == NULL) {
- return;
- }
- ++g_authSessionId;
- }
- switch (module) {
- case MODULE_AUTH_SDK:
- AuthProcessReceivedData(auth->sessionId, data, dataLen);//身份验证线程接收数据
- break;
- default:
- break;
- }
- return;
- }
2.2当接收到新数据,OnDataEvent()
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c
- void ProcessDataEvent(int fd)
- {
- SOFTBUS_PRINT("[AUTH] ProcessDataEvent fd = %d\n", fd);
- AuthConn *conn = FindAuthConnByFd(fd);
- if (conn == NULL) {
- SOFTBUS_PRINT("ProcessDataEvent get authConn fail\n");
- return;
- }
- if (conn->db.buf == NULL) {
- conn->db.buf = (char *)malloc(DEFAULT_BUF_SIZE);
- if (conn->db.buf == NULL) {
- return;
- }
- (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
- conn->db.size = DEFAULT_BUF_SIZE;
- conn->db.used = 0;
- }
- DataBuffer *db = &conn->db;
- char *buf = db->buf;
- int used = db->used;
- int size = db->size;
- printf(">>>>>%s:%d\nbuf:%s\n",__FILE__,__LINE__,buf);
- int rc = AuthConnRecv(fd, buf, used, size - used, 0);//认证连接的返回信息
- if (rc == 0) {
- return;
- } else if (rc < 0) {
- CloseConn(conn);
- return;
- }
- used += rc;
- int processed = ProcessPackets(conn, buf, size, used);//对收到的包处理
- if (processed > 0) {
- used -= processed;
- if (used != 0) {
- if (memmove_s(buf, processed, buf, used) != EOK) {
- CloseConn(conn);
- return;
- }
- }
- } else if (processed < 0) {
- CloseConn(conn);
- return;
- }
- db->used = used;
- SOFTBUS_PRINT("[AUTH] ProcessDataEvent ok\n");
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\auth_conn.c
- int AuthConnRecv(int fd, char *buf, int offset, int count, int timeout)
- {
- if ((buf == NULL) || (offset < 0) || (count <= 0) || (offset + count <= 0)) {
- return -1;
- }
- return TcpRecvData(fd, buf + offset, count, timeout);
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\utils\tcp_socket.c
- int TcpRecvData(int fd, char *buf, int len, int timeout)
- {
- return TcpRecvMessages(fd, buf, len, timeout, 0);
- }
- ==============================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\utils\tcp_socket.c
- static int32_t TcpRecvMessages(int fd, char *buf, uint32_t len, int timeout, int flags)
- {printf(">>>>>%s:%d:%s()\n",__FILE__,__LINE__,__FUNCTION__);
- if (fd < 0 || buf == NULL || len == 0 || timeout < 0) {
- return -1;
- }
- printf(">>>>>%s:%d\nfd:%d,len:%d,flags:%d\nTcpRecvMessages:buf:%s\n",__FILE__,__LINE__,fd,len,flags,buf);
- errno = 0;
- int32_t rc = recv(fd, buf, len, flags);
- printf(">>>>>%s:%d\nfd:%d,len:%d,flags:%d,rc:%d\nTcpRecvMessages:buf:%s\n",__FILE__,__LINE__,fd,len,flags,rc,buf);
- if ((rc == -1) && (errno == EAGAIN)) {
- rc = 0;
- } else if (rc <= 0) {
- rc = -1;//rc = -1; //这里rc = -1,程序在这里跳出了,但是却找不到int32_t rc = recv(fd, buf, len, flags);的来源
- }
- return rc;
- }
- //通过添加2条打印信息发现,经过recv(fd, buf, len, flags)之后,buf有了数据,这数据来自手机端,并加密了。关于recv()打开下面文件
- //Z:\harmony110\device\hisilicon\hispark_pegasus\sdk_liteos\third_party\lwip_sack\include\lwip\sockets.h:1589
- //在函数的描述里可以看做,这里的recv()是作为API提供的,所以只能挖到这里了。
auth.设备认证机制
authmanager【提供设备认证机制和设备知识库管理】
- 当发现有请求时,调用ProcessDataEvent函数,收包,检验包头,根据数据包的类型确定不同的处理方式。类型主要包括以下三种:
- MODULE_AUTH_SDK 加密数据类型
- MODULE_TRUST_ENGINE 可信类型,直接进行数据传输
- MODULE_CONNECTION 进行ip及设备认证
- ├── BUILD.gn
- ├── include
- │ ├── auth_conn.h
- │ ├── auth_interface.h
- │ ├── bus_manager.h
- │ ├── msg_get_deviceid.h
- │ └── wifi_auth_manager.h
- └── source
- ├── auth_conn.c【提供发送、接收、认证、获取秘钥功能】
- ├── auth_interface.c【管理各个会话节点、各个链接节点、各个秘钥节点,提供包括增删改查等功能】
- ├── bus_manager.c【主要通过deviceIp创建两个不同的listen,主要用来监听系统上有哪些device及新的device节点的创建;其中有两个回调函数OnConnectEvent和OnDataEvent,分别是用来处理设备节点的基本操作及节点数据的处理】
- ├── msg_get_deviceid.c【提供以cJSON格式获取各个设备的信息,包括设备id、链接信息、设备名、设备类型等】
- └── wifi_auth_manager.c【主要实现了连接管理和数据接收功能。连接管理包括连接的建立、断开及连接的查找。数据接收包括数据获取、包头及包长等的校验,并且为了简化包头数据读取,单独实现了对一个int型和一个long型数据的接收函数
reference:
communication_dsoftbus: DSoftBus capabilities, including discovery, networking, and transmission | 软总线发现、组网、传输功能实现 (gitee.com)
文章相关附件可以点击下面的原文链接前往下载
原文链接:https://harmonyos.51cto.com/posts/4776