[[408696]] 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com 2. ネットワークに接続したら、WifiEventTrigger()をトリガーしてソフトバスを開始します。- Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\discovery_service.c
- void WifiEventTrigger(符号なし整数パラメタ)
- {
- デバイス情報 *localDev = GetCommonDeviceInfo();
- (localDev == NULL )の場合{
- 戻る;
- }
-
- 整数戻り値;
- if (パラグラフ) {
- char wifiIp[MAX_DEV_IP_LEN] = {0};
- CoapGetIp(wifiIp、MAX_DEV_IP_LEN、0); //1. このデバイスのIPアドレスを取得するを参照
- (strcmp(wifiIp、 「0.0.0.0」 )== 0)の場合{
- SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger 新しいイベント割り込み。\n" );
- 戻る;
- }
- ret = memcpy_s(localDev->deviceIp, sizeof(localDev->deviceIp), wifiIp, sizeof(wifiIp));
- }それ以外{
- ret = memset_s(localDev->deviceIp, sizeof(localDev->deviceIp), 0, sizeof(localDev->deviceIp));
- }
-
- 戻り値 != ERROR_SUCCESS の場合 {
- 戻る;
- }
-
- if (BusManager(para) != ERROR_SUCCESS) { //ソフトバスを開始するには2.BusManager()を参照してください
- SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger StartBusManager(%d) が失敗しました\n" , para);
- 戻る;
- }
-
- CoapRegisterDeviceInfo() の場合 != ERROR_SUCCESS {
- SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger CoapRegisterDeviceInfo 失敗\n" );
- 戻る;
- }
-
- (DoRegistService(COAP) != ERROR_SUCCESS) の場合 {
- SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger DoRegistService が失敗しました\n" );
- 戻る;
- }
- }
1. このデバイスのIPアドレスを取得する- Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
- //CoapGetIp() を使用して、ローカル デバイスの Wi-Fi 接続をループし、それを deviceInfo->deviceIp に格納します。後で使います。
- void CoapGetIp( char *ip, int長さ, int有限)
- {
- ip == NULL || 長さ != NSTACKX_MAX_IP_STRING_LEN の場合 {
- 戻る;
- }
-
- g_queryIpFlag = 1;
- 整数 カウント= 有限? GET_IP_TIMES: GET_IP_INFINITE;
- (g_queryIpFlag) の間{
- IPアドレスを取得します。 //カーネルに応じて、IP を取得する方法は複数あります。
- CheckIpIsValid(ip, strlen(ip)) == 0の場合{
- 壊す;
- }
-
- (カウント== 0)の場合{
- 壊す;
- }
- カウント
- スリープ(TEN_MS); //#define TEN_MS (10 * 1000)//usleep 10ms、IPアドレスを取得するたびに、間隔は10msになります
- }
- 戻る;
- }
2.BusManager()はソフトバスを起動する- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- intバスマネージャ(符号なしint開始フラグ)
- {
- 開始フラグ == 1 の場合
- StartBus()を返します。
- }それ以外{
- StopBus()を返します。
- }
- }
- ======================================================================
- intスタートバス(void)
- {
- g_busStartFlag == 1の場合{
- 0を返します。
- }
- デバイス情報 *info = GetCommonDeviceInfo();
- if (情報 == NULL ) {
- ERROR_FAIL を返します。
- }
-
- g_baseLister.onConnectEvent = OnConnectEvent; //新しい接続があるときにこの関数を呼び出す
- g_baseLister.onDataEvent = OnDataEvent; //新しいデータがあるときにこの関数を呼び出す
- //StartListener() 関数は、認証モジュールが初期化を完了するためのチャネルを提供する役割を担います。
- int authPort = StartListener(&g_baseLister, info->deviceIp); //参考: 2.1.聴き始める
- 認証ポートが0未満の場合
- SOFTBUS_PRINT( "[AUTH] StartBus StartListener が失敗しました\n" );
- ERROR_FAIL を返します。
- }
- info->デバイスポート = authPort;
- //StartSession()関数は、ビジネスのセッション管理を初期化する役割を担います。
- int sessionPort = StartSession(info->deviceIp); //参考: 2.2.セッションを開始する
- セッションポートが0未満の場合
- SOFTBUS_PRINT( "[AUTH] StartBus StartSession 失敗\n" );
- リスナーを停止します。
- ERROR_FAIL を返します。
- }
-
- AuthMngInit(認証ポート、セッションポート);
- g_busStartFlag = 1;
-
- SOFTBUS_PRINT( "[AUTH] StartBus ok\n" );
- 0を返します。
- }
- ======================================================================
- //コールバック関数の処理
- //trans_serviceモジュールのユーザーが設定したコールバック関数は、新しい接続と新しいデータがあるときに呼び出されます。
- //たとえば、認証モジュールは次の関数を通じて認証アクションを完了します。OnConnectEvent() 関数は新しい接続の処理を完了し、OnDataEvent() 関数は新しいデータの処理を完了します。
-
- int OnConnectEvent( int fd, const char *ip)
- ProcessConnectEvent(fd, ip);
- 0を返します。
- }
-
- 整数OnDataEvent(整数fd)
- プロセスデータイベント(fd);
- 0を返します。
- }
2.1.リスニングを開始し、StartListener() を実行して、リスナーと検出エンド間の接続を確立します。 StartListener() 関数の基底層には、プラットフォームのさまざまなバージョンに対応する適応関数があり、Hongmeng OS のさまざまな部分を分離するというモジュール設計コンセプトを裏付け、さまざまなハードウェア デバイスをデバイスに最適な OS に組み合わせます。たとえば、スレッドを作成するときに、統合された static void WaitProcess(void) 関数が使用され、さまざまな基礎 API の適応コードがその中にカプセル化されます。 - Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c
- //StartListener() 関数は、認証モジュールが初期化を完了するためのチャネルを提供する役割を担います。
- // この関数は主に、 select関数を使用して g_maxFd で表されるファイル記述子を監視するために使用される WaitProcess スレッドを作成します。戻り値が 0 より大きい場合は、ProcessAuthData 関数が呼び出されます。この機能は、確立されたリンクのデータの送受信を完了し、受信したデータを処理します。イベントを処理する 2 つの関数は onConnectEvent と onDataEvent で、これらは以前に登録した 2 つのコールバック関数です。 onConnectEvent 関数は主に、新しく接続されたデバイスの AuthConnNode タイプのノードを作成し、それをリンク リストに追加するために使用されます。 onDataEvent 関数は、AuthConnNode ノードのデータ メンバーにメモリを割り当て、データを処理するために使用されます。
- # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
- int StartListener(BaseListener *callback, const char *ip) // *callback、コールバック関数
- {
- if (コールバック == NULL || ip == NULL ) {
- -DBE_BAD_PARAM を返します。
- }
-
- g_callback = コールバック;
- //InitListenFd() 関数は、上位レベルの呼び出し元によって IP アドレスとポート番号が指定されている TCP ソケットの作成と監視を完了します。
- int rc = InitListenFd(ip, セッションポート); //
- rc != DBE_SUCCESS の場合 {
- -DBE_BAD_PARAM を返します。
- }
-
- osThreadAttr_t 属性;
- 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 優先度
- //osThreadNew() はプラットフォームによって実装が異なります。 LITEOS_A および Linux プラットフォームでは、osThreadNew() は POSIX 互換の pthread_create() を呼び出してスレッドの作成を完了します。
- g_uwTskLoID = osThreadNew((osThreadFunc_t)WaitProcess, NULL , &attr); //新しい接続とデータを待機する WaitProcess(void)
- NULLの場合== g_uwTskLoID) {
- SOFTBUS_PRINT( "[TRANS] StartListenerタスクの作成に失敗しました\n" );
- -1 を返します。
- }
-
- SOFTBUS_PRINT( "[TRANS] StartListener ok\n" );
- GetSockPort(g_listenFd)を返します。
- }
- ======================================================================
- static void WaitProcess(void) //新しい接続とデータをリッスンする WaitProcess(void)
- {
- SOFTBUS_PRINT( "[TRANS] WaitProcess 開始\n" );
- fd_set 読み取りセット;
- fd_set exceptfds;
-
- (1) その間、{//WaitProcess()はbusy waitメソッドを使用してselect ()を呼び出し、listenFdとデータg_dataFdの情報をリッスンします。読み取るデータがあることが検出されると、処理のために ProcessAuthData に入ります。
- FD_ZERO(&readSet);
- FD_ZERO(&exceptfds);
- FD_SET(g_listenFd、&readSet);
- 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 失敗\n" );
- リスナーを停止します。
- 壊す;
- }
- } else if (ret < 0){//g_dataFd に異常な情報が含まれていることが判明した場合は、それを閉じます。このうち、g_dataFd は listenFd が接続をリッスンするときに作成されるソケットです。
- errno == EINTR || (g_dataFd > 0 && FD_ISSET(g_dataFd, &exceptfds)) の場合 {
- SOFTBUS_PRINT( "[TRANS] errno == EINTR または g_dataFd が exceptfds セット内にあります。\n" );
- AuthSessionFd(g_dataFd) を閉じます。
- 続く;
- }
- SOFTBUS_PRINT( "[TRANS] WaitProcess の選択に失敗しました。リスナーを停止します\n" );
- リスナーを停止します。
- 壊す;
- }
- }
- }
2.2.セッションを開始する、StartSession()- //StartSession()関数は、ビジネスのセッション管理を初期化する役割を担います。
- //StartSession この関数には、 IP であるconst char *ip という 1 つのパラメーターのみがあり、これは StartListener 関数の IP と同じです。この関数はスペースに適用され、グローバル変数 g_sessionMgr を初期化し、ソケット ファイル記述子を作成し、指定されたパラメータに従ってリッスンし、StartSelectLoop 関数を呼び出して SelectSessionLoop スレッドを作成します。スレッドは、ソケット ファイル記述子をコレクションに追加し、監視のためにselect関数を呼び出します。関数の戻り値が 0 より大きい場合、ProcessData 関数が呼び出されます。この機能には 2 つのブランチがあります。ソケットがセッションを作成していない場合は、ソケットに対してセッションを作成します。セッションが作成されている場合は、そのデータ部分を処理します。
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- int StartSession(const char *ip)
- {
- intポート = CreateTcpSessionMgr( true 、 ip );
- 戻りポート;
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- int CreateTcpSessionMgr(bool asServer、const char * localIp)を設定します。
- {
- ローカルIPがNULLの場合
- TRANS_FAILEDを返します。
- }
-
- (InitTcpMgrLock() != 0 || GetTcpMgrLock() != 0) の場合 {
- TRANS_FAILEDを返します。
- }
-
- int ret = InitGSessionMgr();
- (ReleaseTcpMgrLock() != 0 || ret != 0) の場合 {
- セッションマネージャを解放します。
- TRANS_FAILEDを返します。
- }
- g_sessionMgr->asServer = asServer; //この関数はスペースを申請し、グローバル変数g_sessionMgrを初期化します
- int listenFd = OpenTcpServer(localIp、DEFAULT_TRANS_PORT);
- (listenFd < 0)の場合{
- SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr OpenTcpServer が失敗しました\n" );
- セッションマネージャを解放します。
- TRANS_FAILEDを返します。
- }
- int rc = listen(listenFd、LISTEN_BACKLOG); //次にソケットファイル記述子を作成し、指定されたパラメータに従ってリッスンします
- rc != 0 の場合
- SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr listen 失敗\n" );
- セッションをクローズします(listenFd);
- セッションマネージャを解放します。
- TRANS_FAILEDを返します。
- }
- g_sessionMgr->listenFd = listenFd;
-
- シグナル(SIGPIPE、SIG_IGN);
- if (StartSelectLoop(g_sessionMgr) != 0){//StartSelectLoop関数を呼び出してSelectSessionLoopスレッドを作成します。
- SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr StartSelectLoop 失敗\n" );
- セッションをクローズします(listenFd);
- セッションマネージャを解放します。
- TRANS_FAILEDを返します。
- }
- GetSockPort(listenFd)を返します。
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
- int StartSelectLoop(TcpSessionMgr *tsm)
- {
- tsm == NULLの場合{
- TRANS_FAILEDを返します。
- }
-
- tsm->isSelectLoopRunning の場合 {
- 0を返します。
- }
-
- osThreadId_t セッションループタスクId;
-
- osThreadAttr_t 属性;
- 属性。名前= "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 優先度
- // スレッドはソケット ファイル記述子をセットに追加し、それを監視するためにselect関数を呼び出します。
- セッション ループ タスク ID = osThreadNew((osThreadFunc_t)SelectSessionLoop、(void *)tsm、&attr);
- if ( NULL == セッションループタスクID) {
- SOFTBUS_PRINT( "[TRANS] StartSelectLoop TaskCreate 失敗\n" );
- TRANS_FAILEDを返します。
- }
-
- 0を返します。
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- 静的void SelectSessionLoop(TcpSessionMgr *tsm)
- {
- tsm == NULLの場合{
- 戻る;
- }
- SOFTBUS_PRINT( "[TRANS] SelectSessionLoop 開始\n" );
- tsm->isSelectLoopRunning = true ;
- (真)の間{
- fd_set 読み取りファイルを設定します。
- fd_set exceptfds;
- int maxFd = InitSelectList(tsm、&readfds、&exceptfds);
- (maxFd < 0)の場合{
- 壊す;
- }
-
- エラー番号 = 0;
- int ret = select (maxFd + 1, &readfds, NULL , &exceptfds, NULL );
- 戻り値 < 0 の場合
- SOFTBUS_PRINT( "RemoveExceptSessionFd\r\n" );
- (errno == EINTR || RemoveExceptSessionFd(tsm, &exceptfds) == 0)の場合{
- 続く;
- }
- SOFTBUS_PRINT( "[TRANS] SelectSessionLoop すべてのセッションを閉じる\n" );
- すべてのセッションを閉じます(tsm);
- 壊す;
- }そうでない場合 (ret == 0) {
- 続く;
- } else //関数の戻り値が0より大きい場合は、ProcessData関数を呼び出します。
- ProcessData(tsm、&readfds);
- }
- }
- tsm->isSelectLoopRunning = false ;
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
- 静的void ProcessData(TcpSessionMgr *tsm、fd_set *rfds)
- {
- tsm == NULL || tsm->listenFd == -1 の場合 {
- 戻る;
- }
- //この関数には 2 つの分岐があります。ソケットがセッションを作成していない場合は、ソケットに対してセッションを作成します。セッションが作成されている場合は、そのデータ部分を処理します
- FD_ISSET(tsm->listenFd, rfds)の場合{
- プロセス接続(tsm);
- 戻る;
- }
-
- プロセスセッションデータ(tsm、rfds);
- }
要約:ソフト バスが開始されると、新しい接続の監視が開始され、OnConnectEvent() 関数で新しい接続の処理が完了し、OnDataEvent() 関数で新しいデータの処理が完了します。 3. 検出側(携帯電話など)がブロードキャストを送信するとHongmeng の携帯電話がロック画面をオンにすると、ローカル エリア ネットワークで UDP ブロードキャストが送信されます。開発ボード(サーバー)がブロードキャストを検出すると、次の関数を呼び出します。 1. LAN内でUDPブロードキャストパケットが検出されると、HandleReadEvent()- Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
- 静的voidHandleReadEvent( int fd)
- {
- ソケットFd = fd;
- 符号なしchar *recvBuffer = calloc(1, COAP_MAX_PDU_SIZE + 1);
- 受信バッファがNULLの場合
- 戻る;
- }
- ssize_t n読み取り;
- 読み取り専用ソケット。 //この関数はソケットの内容を読み取ります
- ((nRead == 0) || (nRead < 0 && errno != EAGAIN &&
- エラー番号 != EWOULDBLOCK && エラー番号 != EINTR)) {
- 解放(recvBuffer);
- 戻る;
- }
-
- COAP_Packet デコードパケット;
- (void)memset_s(&decodePacket, sizeof(COAP_Packet), 0, sizeof(COAP_Packet));
- デコードパケットプロトコル = COAP_UDP;
- COAP_SoftBusDecode(&decodePacket、recvBuffer、nRead); //次にCOAP_SoftBusDecodeを呼び出してデコードします
- PostServiceDiscover(&decodePacket); //デコードされたメッセージはPostServiceDiscoverによって処理されます。次の分析を参照してください。
- 解放(recvBuffer);
- }
- ======================================================================
- void PostServiceDiscover(const COAP_Packet *pkt)
- {
- char *remoteUrl = NULL ;
- デバイス情報 デバイス情報;
-
- (パケットがNULLの場合){
- 戻る;
- }
-
- (void)memset_s(&deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo));
- // 今のところ GetServiceDiscoverInfo() の展開関数については詳しく説明しません。TODO
- (GetServiceDiscoverInfo(pkt->payload.buffer, pkt->payload.len, &deviceInfo, &remoteUrl) != NSTACKX_EOK) の場合 {
- 戻る;
- }
-
- 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);//印刷デバッグを追加
- リモートURLがNULLの場合
- CoapResponseService(pkt、リモートUrl、wifiIpAddr); //解決された携帯電話(検出終了)アドレスを介した応答サービス
- 無料(リモート URL);
- }
- }
- ======================================================================
- 静的 int CoapResponseService(const COAP_Packet *pkt、const char * remoteUrl、const char * remoteIp)
- {
- 整数戻り値;
- CoapRequestCoapRequest;
- (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest));
- coapRequest.remoteUrl = リモートUrl;
- coapRequest.remoteIp = リモートIp;
- char *ペイロード = PrepareServiceDiscover();
- ペイロード == NULL の場合{
- NSTACKX_EFAILED を返します。
- }
- printf( ">>>>>%s:%d\npayload:%s\n" ,__FILE__,__LINE__,payload);//印刷デバッグを追加
- COAP_ReadWriteBuffer sndPktBuff = {0};
- sndPktBuff.readWriteBuf = calloc(1, COAP_MAX_PDU_SIZE);
- sndPktBuff.readWriteBuf == NULL の場合{
- 無料(ペイロード)
- NSTACKX_EFAILED を返します。
- }
- sndPktバフ。サイズ= COAP_MAX_PDU_SIZE;
- sndPktバッファの長さ = 0;
-
- ret = BuildSendPkt(pkt、remoteIp、ペイロード、&sndPktBuff); //送り返すパケットを構築する
- 無料(ペイロード)
- 戻り値 != DISCOVERY_ERR_SUCCESS の場合 {
- 解放します(sndPktBuff.readWriteBuf);
- sndPktBuff.readWriteBuf = NULL ;
- retを返します。
- }
- sndPktBuff を readWriteBuf に格納します。
- coapRequest.dataLength = sndPktBuff.len;
- ret = CoapSendRequest(&coapRequest); //送信
- 解放します(sndPktBuff.readWriteBuf);
- sndPktBuff.readWriteBuf = NULL ;
-
- retを返します。
- }
2. 新しい接続が検出されると、ProcessAuthData()- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c:85
- //新しい接続要求であっても、既存の接続でデータが着信する場合でも、この関数が開始されます。
- 静的ブール ProcessAuthData( int listenFd, const fd_set *readSet)
- {
- readSet == NULL || g_callback == NULL || g_callback->onConnectEvent == NULL || の場合
- g_callback->onDataEvent == NULL ) {
- 戻る 間違い;
- }
-
- if (FD_ISSET(listenFd, readSet)){//listenFdにメッセージがあるかどうかを判定する
- 構造体sockaddr_in addrClient = {0};
- socklen_t addrLen = sizeof(addrClient);
- // はいの場合は、新しい接続があることを意味します。この時点で、accept() を呼び出してリンクの作成を完了します。新しく作成されたソケットの fd は g_dataFd に格納されます。
- g_dataFd = accept(listenFd、(struct sockaddr *)(&addrClient)、&addrLen);
- g_dataFd < 0 の場合 {
- CloseAuthSessionFd(listenFd);
- 戻る 間違い;
- }
- g_dataFd をリフレッシュします。
- //同時に、g_callback->onConnectEvent を呼び出して、新しい接続イベントが発生したことを認証モジュールに通知し、新しく作成された fd とクライアントの IP アドレスを認証モジュールに通知します。
- //同時に、g_dataFd を作成するときに、WaitProcess() の次のselect () 操作中に g_dataFd のイベントが監視されるように、g_maxFd を更新する必要があります。
- if (g_callback->onConnectEvent(g_dataFd, inet_ntoa(addrClient.sin_addr)) != 0) { //次の分析を参照してくださいOnConnectEvent()
- AuthSessionFd(g_dataFd) を閉じます。
- }
- }
- //FD_ISSET() が g_dataFd にメッセージがあると判断した場合、ハンドシェイク接続が完了し、このノードにデータが送信されたことを意味します。
- if (g_dataFd > 0 && FD_ISSET(g_dataFd, readSet)) { //次の分析を参照 OnDataEvent()
- g_callback->onDataEvent(g_dataFd);//関数は次に g_callback->onDataEvent() をコールバックし、受信したデータを処理するために呼び出し元に制御を返します。
- }
-
- 戻る 真実;
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
- int OnConnectEvent( int fd, const char *ip)
- {
- ProcessConnectEvent(fd, ip); //2.1 新しい接続を確立するとき
- 0を返します。
- }
- 整数OnDataEvent(整数fd)
- {
- プロセスデータイベント(fd); //2.2 新しいデータを受信したとき
- 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 プロセスデータイベント( int fd)
- {
- SOFTBUS_PRINT( "[AUTH] ProcessDataEvent fd = %d\n" , fd);
- AuthConn *conn = FindAuthConnByFd(fd); //fdを通じて検証接続を見つける
-
- conn->db.buf == NULLの場合{
- conn->db.buf = ( char *)malloc(DEFAULT_BUF_SIZE);
- conn->db.buf == NULLの場合{
- 戻る;
- }
- (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
- 接続->db。サイズ= DEFAULT_BUF_SIZE;
- conn->db.used = 0;
- }
-
- データバッファ *db = &conn->db;
- char *buf = db->buf;
- int使用済み = db->使用済み;
- 整数 サイズ= db->サイズ;
-
- int rc = AuthConnRecv(fd, buf, used, size - used, 0);
- rc == 0 の場合
- 戻る;
- }それ以外の場合 (rc < 0) {
- CloseConn(conn);
- 戻る;
- }
-
- 使用済み += rc;
- int処理済み = ProcessPackets(conn, buf, size , used); //以下の分析1を参照
- (処理済み > 0)の場合{
- 使用済み -= 処理済み;
- (使用済み!= 0)の場合{
- memmove_s(buf, 処理済み, buf, 使用済み) != EOK の場合 {
- CloseConn(conn);
- 戻る;
- }
- }
- }そうでなければ(処理済み < 0){
- CloseConn(conn);
- 戻る;
- }
-
- db->used = 使用済み;
- SOFTBUS_PRINT( "[AUTH] ProcessDataEvent ok\n" );
- }
1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 527 - 静的 int ProcessPackets(AuthConn *conn, const char *buf, int サイズ、 int使用)
- {
- 処理されたint = 0;
- (処理済み + PACKET_HEAD_SIZE < 使用済み){
- パケット *pkt = ParsePacketHead(buf, processes, used - processes, size );//以下の分析 1 を参照
-
- int len = pkt->dataLen; //解析したパケットのサイズをlenに代入する
- 処理済み += PACKET_HEAD_SIZE;//+24
- OnDataReceived(conn、pkt、buf + 処理済み); //次の分析2を参照
- 処理済み += 長さ;
- 無料(pkt);
- パケット = NULL ;
- }
- 返品処理済み。
- }
1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 485 - //パケット ヘッダーを解析します。この関数はパケット構造を返します。
- 静的パケット *ParsePacketHead(const char *buf, int offset, int len, int サイズ)
- {
- 符号なし整数識別子 = GetIntFromBuf(buf, offset); //1. bufから識別コードを取得する
-
- オフセット += DEFAULT_INT_LEN; //オフセットを4に追加
- int module = GetIntFromBuf(buf, offset);//2. bufからモジュールを取得する
-
- オフセット += DEFAULT_INT_LEN; //オフセットを4に追加
- 長い長いシーケンス = 0;
- if (GetLongFromBuf(buf, offset, &seq) != 0) { //3. bufからシーケンス番号を取得します
- 戻る NULL ;
- }
-
- オフセット += DEFAULT_LONG_LEN; //オフセットを4に追加
- intフラグ = GetIntFromBuf(buf, オフセット); //4. bufからフラグを取得する
-
- オフセット += 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 *)malloc(sizeof(Packet));
- パケット->モジュール = モジュール;
- パケット->seq = seq;
- パケット->フラグ = フラグ;
- パケット->dataLen = dataLen;
-
- 返送パケット;
- }
2.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 446 - 静的void OnDataReceived(AuthConn *conn、const Packet *pkt、const char *data)
- {
- SOFTBUS_PRINT( "[AUTH] OnDataReceived\n" ); //データ受信
- pkt->module > MODULE_HICHAIN の場合 && (pkt->module <= MODULE_AUTH_SDK)) {
- //データ受信用の認証インターフェース関数、分析1を参照
- AuthInterfaceOnDataReceived(conn, pkt->module, pkt->seq, data, pkt->dataLen);
- 戻る;
- }
-
- cJSON *msg = DecryptMessage(pkt->module, data, pkt->dataLen);
- メッセージ == NULL の場合
- SOFTBUS_PRINT( "[AUTH] OnDataReceived DecryptMessage 失敗\n" );
- 戻る;
- }
-
- OnModuleMessageReceived(conn、pkt->module、pkt->flags、pkt->seq、msg);
- cJSON_Delete(メッセージ);
- メッセージ = 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 開始\n" );
-
- if (AuthSessionMapInit() != 0) { //認証セッションの初期化
- 戻る;
- }
- AuthSession *auth = AuthGetAuthSessionBySeqId(seqId); //認証 - シーケンスIDで検証セッションを取得する
- 認証 == NULL の場合
- auth = AuthGetNewAuthSession(conn、seqId、g_authSessionId); //認証 - 新しい認証セッションを取得する
- 認証 == NULL の場合
- 戻る;
- }
- ++g_authセッションID;
- }
-
- スイッチ(モジュール){
- MODULE_AUTH_SDKの場合:
- AuthProcessReceivedData(auth->sessionId, data, dataLen); //認証スレッドがデータを受信
- 壊す;
- デフォルト:
- 壊す;
- }
- 戻る;
- }
2.2 新しいデータが受信されると、OnDataEvent()- Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c
- void プロセスデータイベント( int fd)
- {
- SOFTBUS_PRINT( "[AUTH] ProcessDataEvent fd = %d\n" , fd);
- AuthConn *conn = FindAuthConnByFd(fd);
- (接続 == NULL )の場合{
- SOFTBUS_PRINT( "ProcessDataEvent get authConn 失敗\n" );
- 戻る;
- }
-
- conn->db.buf == NULLの場合{
- conn->db.buf = ( char *)malloc(DEFAULT_BUF_SIZE);
- conn->db.buf == NULLの場合{
- 戻る;
- }
- (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
- 接続->db。サイズ= DEFAULT_BUF_SIZE;
- conn->db.used = 0;
- }
-
- データバッファ *db = &conn->db;
- char *buf = db->buf;
- int使用済み = db->使用済み;
- 整数 サイズ= db->サイズ;
- printf( ">>>>>%s:%d\nbuf:%s\n" ,__FILE__,__LINE__,buf);
- int rc = AuthConnRecv(fd, buf, used, size - used, 0); //認証接続の情報を返す
- rc == 0 の場合
- 戻る;
- }それ以外の場合 (rc < 0) {
- CloseConn(conn);
- 戻る;
- }
- 使用済み += rc;
- int処理済み = ProcessPackets(conn, buf, size , used); //受信したパケットを処理する
- (処理済み > 0)の場合{
- 使用済み -= 処理済み;
- (使用済み!= 0)の場合{
- memmove_s(buf, 処理済み, buf, 使用済み) != EOK の場合 {
- CloseConn(conn);
- 戻る;
- }
- }
- }そうでなければ(処理済み < 0){
- CloseConn(conn);
- 戻る;
- }
- db->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 カウント、 intタイムアウト)
- {
- if ((buf == NULL ) || (オフセット < 0) || ( count <= 0) || (オフセット + count <= 0)) {
- -1 を返します。
- }
-
- 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タイムアウト)
- {
- TcpRecvMessages(fd, buf, len, timeout, 0)を返します。
- }
- ======================================================================
- Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\utils\tcp_socket.c
- 静的int32_t TcpRecvMessages( int fd, char *buf, uint32_t len, intタイムアウト, intフラグ)
- {printf( ">>>>>%s:%d:%s()\n" ,__FILE__,__LINE__,__FUNCTION__);
- fd < 0 || buf == NULL || len == 0 || タイムアウト < 0) {
- -1 を返します。
- }
- printf( ">>>>>%s:%d\nfd:%d,len:%d,flags:%d\nTcpRecvMessages:buf:%s\n" ,__FILE__,__LINE__,fd,len,flags,buf);
- エラー番号 = 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);
- ((rc == -1) && (errno == EAGAIN)) の場合 {
- rc = 0;
- }それ以外の場合 (rc <= 0) {
- rc = -1;//rc = -1; //ここで rc = -1 なので、プログラムはここで飛び出しますが、int32_t のソース rc = recv(fd, buf, len, flags);見つかりません
- }
- 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 関数が呼び出され、パケットを受信し、パケット ヘッダーをチェックし、データ パケットの種類に基づいてさまざまな処理方法を決定します。主なタイプは3つあります。
- MODULE_AUTH_SDK 暗号化されたデータ タイプ
- MODULE_TRUST_ENGINE 信頼型、直接データ転送
- MODULE_CONNECTIONはIPとデバイスの認証を実行します
-
- ├──ビルド.gn
- ├── 含む
- │ ├── auth_conn.h
- │ ├── auth_interface.h
- │ ├── bus_manager.h
- │ ├── msg_get_deviceid.h
- │ └── wifi_auth_manager.h
- └── 出典
- ├── auth_conn.c [送信、受信、認証、鍵取得機能を提供]
- ├── auth_interface.c [各セッションノード、各リンクノード、各キーノードを管理し、追加、削除、変更、照会などの機能を提供する]
- ├── bus_manager.c [主に、システム上にあるデバイスと新しいデバイス ノードの作成を監視するために使用される、deviceIp を介して 2 つの異なるリスナーを作成します。 OnConnectEventとOnDataEventの2つのコールバック関数があり、それぞれデバイスノードの基本操作とノードデータの処理に使用されます。
- ├── msg_get_deviceid.c [デバイスID、リンク情報、デバイス名、デバイスタイプなど、各デバイスに関する情報をcJSON形式で提供します。]
- └── wifi_auth_manager.c【主に接続管理とデータ受信機能を実装しています。接続管理には、接続の確立、切断、接続の検索が含まれます。データ受信には、データ取得、パケットヘッダーおよびパケット長の検証が含まれ、パケットヘッダーデータの読み取りを簡素化するために、 int型とlong型のデータの受信関数が別々に実装されています。
参照: communication_dsoftbus: 検出、ネットワーク、送信などの DSoftBus 機能 | SoftBus の検出、ネットワーク、および伝送機能 (gitee.com) 記事に関連する添付ファイルをダウンロードするには、以下のリンクをクリックしてください。 オリジナルリンク: https://harmonyos..com/posts/4776 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com |