OpenHarmony 分散ソフトバスプロセス分析 v1.0丨2。ソフトバスを開いて接続を確立する

OpenHarmony 分散ソフトバスプロセス分析 v1.0丨2。ソフトバスを開いて接続を確立する

[[408696]]

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

2. ネットワークに接続したら、WifiEventTrigger()をトリガーしてソフトバスを開始します。

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\discovery_service.c
  2. void WifiEventTrigger(符号なし整数パラメタ)
  3. {
  4. デバイス情報 *localDev = GetCommonDeviceInfo();
  5. (localDev == NULL )の場合{
  6. 戻る;
  7. }
  8.  
  9. 整数戻り値;
  10. if (パラグラフ) {
  11. char wifiIp[MAX_DEV_IP_LEN] = {0};
  12. CoapGetIp(wifiIp、MAX_DEV_IP_LEN、0); //1. このデバイスのIPアドレスを取得するを参照
  13. (strcmp(wifiIp、 「0.0.0.0」 )== 0)の場合{
  14. SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger 新しいイベント割り込み。\n" );
  15. 戻る;
  16. }
  17. ret = memcpy_s(localDev->deviceIp, sizeof(localDev->deviceIp), wifiIp, sizeof(wifiIp));
  18. }それ以外{
  19. ret = memset_s(localDev->deviceIp, sizeof(localDev->deviceIp), 0, sizeof(localDev->deviceIp));
  20. }
  21.  
  22. 戻り値 != ERROR_SUCCESS の場合 {
  23. 戻る;
  24. }
  25.  
  26. if (BusManager(para) != ERROR_SUCCESS) { //ソフトバスを開始するには2.BusManager()を参照してください
  27. SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger StartBusManager(%d) が失敗しました\n" , para);
  28. 戻る;
  29. }
  30.  
  31. CoapRegisterDeviceInfo() の場合 != ERROR_SUCCESS {
  32. SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger CoapRegisterDeviceInfo 失敗\n" );
  33. 戻る;
  34. }
  35.  
  36. (DoRegistService(COAP) != ERROR_SUCCESS) の場合 {
  37. SOFTBUS_PRINT( "[DISCOVERY] WifiEventTrigger DoRegistService が失敗しました\n" );
  38. 戻る;
  39. }
  40. }

1. このデバイスのIPアドレスを取得する

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
  2. //CoapGetIp() を使用して、ローカル デバイスの Wi-Fi 接続をループし、それを deviceInfo->deviceIp に格納します。後で使います。
  3. void CoapGetIp( char *ip, int長さ, int有限)
  4. {
  5. ip == NULL || 長さ != NSTACKX_MAX_IP_STRING_LEN の場合 {
  6. 戻る;
  7. }
  8.  
  9. g_queryIpFlag = 1;
  10. 整数 カウント= 有限? GET_IP_TIMES: GET_IP_INFINITE;
  11. (g_queryIpFlag) の間{
  12. IPアドレスを取得します。 //カーネルに応じて、IP を取得する方法は複数あります。
  13. CheckIpIsValid(ip, strlen(ip)) == 0の場合{
  14. 壊す;
  15. }
  16.  
  17. カウント== 0)の場合{
  18. 壊す;
  19. }
  20. カウント--;  
  21. スリープ(TEN_MS); //#define TEN_MS (10 * 1000)//usleep 10ms、IPアドレスを取得するたびに、間隔は10msになります
  22. }
  23. 戻る;
  24. }

2.BusManager()はソフトバスを起動する

  1. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
  2. intバスマネージャ(符号なしint開始フラグ)
  3. {
  4. 開始フラグ == 1 の場合
  5. StartBus()を返します
  6. }それ以外{
  7. StopBus()を返します
  8. }
  9. }
  10. ======================================================================
  11. intスタートバス(void)
  12. {
  13. g_busStartFlag == 1の場合{
  14. 0を返します
  15. }
  16. デバイス情報 *info = GetCommonDeviceInfo();
  17. if (情報 == NULL ) {
  18. ERROR_FAIL を返します
  19. }
  20.  
  21. g_baseLister.onConnectEvent = OnConnectEvent; //新しい接続があるときにこの関数を呼び出す
  22. g_baseLister.onDataEvent = OnDataEvent; //新しいデータがあるときにこの関数を呼び出す
  23. //StartListener() 関数は、認証モジュールが初期化を完了するためのチャネルを提供する役割を担います。
  24. int authPort = StartListener(&g_baseLister, info->deviceIp); //参考: 2.1.聴き始める
  25. 認証ポートが0未満の場合
  26. SOFTBUS_PRINT( "[AUTH] StartBus StartListener が失敗しました\n" );
  27. ERROR_FAIL を返します
  28. }
  29. info->デバイスポート = authPort;
  30. //StartSession()関数は、ビジネスのセッション管理を初期化する役割を担います。
  31. int sessionPort = StartSession(info->deviceIp); //参考: 2.2.セッションを開始する
  32. セッションポートが0未満の場合
  33. SOFTBUS_PRINT( "[AUTH] StartBus StartSession 失敗\n" );
  34. リスナーを停止します。
  35. ERROR_FAIL を返します
  36. }
  37.  
  38. AuthMngInit(認証ポート、セッションポート);
  39. g_busStartFlag = 1;
  40.  
  41. SOFTBUS_PRINT( "[AUTH] StartBus ok\n" );
  42. 0を返します
  43. }
  44. ======================================================================
  45. //コールバック関数の処理
  46. //trans_serviceモジュールのユーザーが設定したコールバック関数は、新しい接続と新しいデータがあるときに呼び出されます。
  47. //たとえば、認証モジュールは次の関数を通じて認証アクションを完了します。OnConnectEvent() 関数は新しい接続の処理を完了し、OnDataEvent() 関数は新しいデータの処理を完了します。
  48.  
  49. int OnConnectEvent( int fd, const char *ip)
  50. ProcessConnectEvent(fd, ip);
  51. 0を返します
  52. }
  53.  
  54. 整数OnDataEvent(整数fd)
  55. プロセスデータイベント(fd);
  56. 0を返します
  57. }

2.1.リスニングを開始し、StartListener() を実行して、リスナーと検出エンド間の接続を確立します。

StartListener() 関数の基底層には、プラットフォームのさまざまなバージョンに対応する適応関数があり、Hongmeng OS のさまざまな部分を分離するというモジュール設計コンセプトを裏付け、さまざまなハードウェア デバイスをデバイスに最適な OS に組み合わせます。たとえば、スレッドを作成するときに、統合された static void WaitProcess(void) 関数が使用され、さまざまな基礎 API の適応コードがその中にカプセル化されます。

  1. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c
  2. //StartListener() 関数は、認証モジュールが初期化を完了するためのチャネルを提供する役割を担います。
  3. // この関数は主に、 select関数を使用して g_maxFd で表されるファイル記述子を監視するために使用される WaitProcess スレッドを作成します。戻り値が 0 より大きい場合は、ProcessAuthData 関数が呼び出されます。この機能は、確立されたリンクのデータの送受信を完了し、受信したデータを処理します。イベントを処理する 2 つの関数は onConnectEvent と onDataEvent で、これらは以前に登録した 2 つのコールバック関数です。 onConnectEvent 関数は主に、新しく接続されたデバイスの AuthConnNode タイプのノードを作成し、それをリンク リストに追加するために使用されます。 onDataEvent 関数は、AuthConnNode ノードのデータ メンバーにメモリを割り当て、データを処理するために使用されます。
  4. # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
  5. int StartListener(BaseListener *callback, const char *ip) // *callback、コールバック関数
  6. {
  7. if (コールバック == NULL || ip == NULL ) {
  8. -DBE_BAD_PARAM を返します
  9. }
  10.  
  11. g_callback = コールバック;
  12. //InitListenFd() 関数は、上位レベルの呼び出し元によって IP アドレスとポート番号が指定されている TCP ソケットの作成と監視を完了します。
  13. int rc = InitListenFd(ip, セッションポート); //
  14. rc != DBE_SUCCESS の場合 {
  15. -DBE_BAD_PARAM を返します
  16. }
  17.  
  18. osThreadAttr_t 属性;
  19. attr.name = "trans_auth_task" ;
  20. attr.attr_bits = 0U;
  21. attr.cb_mem = NULL ;
  22. attr.cb_size = 0U;
  23. attr.stack_mem = NULL ;
  24. attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
  25. attr.priority = osPriorityNormal5; // LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO -> cmsis 優先度
  26. //osThreadNew() はプラットフォームによって実装が異なります。 LITEOS_A および Linux プラットフォームでは、osThreadNew() は POSIX 互換の pthread_create() を呼び出してスレッドの作成を完了します。
  27. g_uwTskLoID = osThreadNew((osThreadFunc_t)WaitProcess, NULL , &attr); //新しい接続とデータを待機する WaitProcess(void)
  28. NULLの場合== g_uwTskLoID) {
  29. SOFTBUS_PRINT( "[TRANS] StartListenerタスクの作成に失敗しました\n" );
  30. -1 を返します
  31. }
  32.  
  33. SOFTBUS_PRINT( "[TRANS] StartListener ok\n" );
  34. GetSockPort(g_listenFd)を返します
  35. }
  36. ======================================================================
  37. static void WaitProcess(void) //新しい接続とデータをリッスンする WaitProcess(void)
  38. {
  39. SOFTBUS_PRINT( "[TRANS] WaitProcess 開始\n" );
  40. fd_set 読み取りセット;
  41. fd_set exceptfds;
  42.  
  43. (1) その間、{//WaitProcess()はbusy waitメソッドを使用してselect ()を呼び出し、listenFdとデータg_dataFdの情報をリッスンします。読み取るデータがあることが検出されると、処理のために ProcessAuthData に入ります。
  44. FD_ZERO(&readSet);
  45. FD_ZERO(&exceptfds);
  46. FD_SET(g_listenFd、&readSet);
  47. g_dataFd >= 0 の場合
  48. FD_SET(g_dataFd、&readSet);
  49. FD_SET(g_dataFd, &exceptfds);
  50. }
  51. int ret = select (g_maxFd + 1, &readSet, NULL , &exceptfds, NULL ); //g_listenFd の情報とデータ g_dataFd をリッスンする
  52. if (ret > 0){//データが読み取り可能であることが検出された場合は、処理のために ProcessAuthData に入ります。
  53. if (!ProcessAuthData(g_listenFd, &readSet)){//【重要な監視】参照:
  54. SOFTBUS_PRINT( "[TRANS] WaitProcess ProcessAuthData 失敗\n" );
  55. リスナーを停止します。
  56. 壊す;
  57. }
  58. } else if (ret < 0){//g_dataFd に異常な情報が含まれていることが判明した場合は、それを閉じます。このうち、g_dataFd は listenFd が接続をリッスンするときに作成されるソケットです。
  59. errno == EINTR || (g_dataFd > 0 && FD_ISSET(g_dataFd, &exceptfds)) の場合 {
  60. SOFTBUS_PRINT( "[TRANS] errno == EINTR または g_dataFd が exceptfds セット内にあります。\n" );
  61. AuthSessionFd(g_dataFd) を閉じます。
  62. 続く;
  63. }
  64. SOFTBUS_PRINT( "[TRANS] WaitProcess の選択に失敗しました。リスナーを停止します\n" );
  65. リスナーを停止します。
  66. 壊す;
  67. }
  68. }
  69. }

2.2.セッションを開始する、StartSession()

  1. //StartSession()関数は、ビジネスのセッション管理を初期化する役割を担います。
  2. //StartSession この関数には、 IP であるconst char *ip という 1 つのパラメーターのみがあり、これは StartListener 関数の IP と同じです。この関数はスペースに適用され、グローバル変数 g_sessionMgr を初期化し、ソケット ファイル記述子を作成し、指定されたパラメータに従ってリッスンし、StartSelectLoop 関数を呼び出して SelectSessionLoop スレッドを作成します。スレッドは、ソケット ファイル記述子をコレクションに追加し、監視のためにselect関数を呼び出します。関数の戻り値が 0 より大きい場合、ProcessData 関数が呼び出されます。この機能には 2 つのブランチがあります。ソケットがセッションを作成していない場合は、ソケットに対してセッションを作成します。セッションが作成されている場合は、そのデータ部分を処理します。
  3. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
  4. int StartSession(const char *ip)
  5. {
  6. intポート = CreateTcpSessionMgr( true 、 ip );
  7. 戻りポート;
  8. }
  9. ======================================================================
  10. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
  11. int CreateTcpSessionMgr(bool asServer、const char * localIp)を設定します。
  12. {
  13. ローカルIPNULLの場合
  14. TRANS_FAILEDを返します
  15. }
  16.  
  17. (InitTcpMgrLock() != 0 || GetTcpMgrLock() != 0) の場合 {
  18. TRANS_FAILEDを返します
  19. }
  20.  
  21. int ret = InitGSessionMgr();
  22. (ReleaseTcpMgrLock() != 0 || ret != 0) の場合 {
  23. セッションマネージャを解放します。
  24. TRANS_FAILEDを返します
  25. }
  26. g_sessionMgr->asServer = asServer; //この関数はスペースを申請し、グローバル変数g_sessionMgrを初期化します
  27. int listenFd = OpenTcpServer(localIp、DEFAULT_TRANS_PORT);
  28. (listenFd < 0)の場合{
  29. SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr OpenTcpServer が失敗しました\n" );
  30. セッションマネージャを解放します。
  31. TRANS_FAILEDを返します
  32. }
  33. int rc = listen(listenFd、LISTEN_BACKLOG); //次にソケットファイル記述子を作成し、指定されたパラメータに従ってリッスンします
  34. rc != 0 の場合
  35. SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr listen 失敗\n" );
  36. セッションをクローズします(listenFd);
  37. セッションマネージャを解放します。
  38. TRANS_FAILEDを返します
  39. }
  40. g_sessionMgr->listenFd = listenFd;
  41.  
  42. シグナル(SIGPIPE、SIG_IGN);
  43. if (StartSelectLoop(g_sessionMgr) != 0){//StartSelectLoop関数を呼び出してSelectSessionLoopスレッドを作成します。
  44. SOFTBUS_PRINT( "[TRANS] CreateTcpSessionMgr StartSelectLoop 失敗\n" );
  45. セッションをクローズします(listenFd);
  46. セッションマネージャを解放します。
  47. TRANS_FAILEDを返します
  48. }
  49. GetSockPort(listenFd)を返します
  50. }
  51. ======================================================================
  52. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
  53. # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
  54. int StartSelectLoop(TcpSessionMgr *tsm)
  55. {
  56. tsm == NULLの場合{
  57. TRANS_FAILEDを返します
  58. }
  59.  
  60. tsm->isSelectLoopRunning の場合 {
  61. 0を返します
  62. }
  63.  
  64. osThreadId_t セッションループタスクId;
  65.  
  66. osThreadAttr_t 属性;
  67. 属性。名前= "trans_session_task" ;
  68. attr.attr_bits = 0U;
  69. attr.cb_mem = NULL ;
  70. attr.cb_size = 0U;
  71. attr.stack_mem = NULL ;
  72. attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
  73. attr.priority = osPriorityNormal5; // LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO -> cmsis 優先度
  74. // スレッドはソケット ファイル記述子をセットに追加し、それを監視するためにselect関数を呼び出します。
  75. セッション ループ タスク ID = osThreadNew((osThreadFunc_t)SelectSessionLoop、(void *)tsm、&attr);
  76. if ( NULL == セッションループタスクID) {
  77. SOFTBUS_PRINT( "[TRANS] StartSelectLoop TaskCreate 失敗\n" );
  78. TRANS_FAILEDを返します
  79. }
  80.  
  81. 0を返します
  82. }
  83. ======================================================================
  84. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
  85. 静的void SelectSessionLoop(TcpSessionMgr *tsm)
  86. {
  87. tsm == NULLの場合{
  88. 戻る;
  89. }
  90. SOFTBUS_PRINT( "[TRANS] SelectSessionLoop 開始\n" );
  91. tsm->isSelectLoopRunning = true ;
  92. )の間{
  93. fd_set 読み取りファイルを設定します。
  94. fd_set exceptfds;
  95. int maxFd = InitSelectList(tsm、&readfds、&exceptfds);
  96. (maxFd < 0)の場合{
  97. 壊す;
  98. }
  99.          
  100. エラー番号 = 0;
  101. int ret = select (maxFd + 1, &readfds, NULL , &exceptfds, NULL );
  102. 戻り値 < 0 の場合
  103. SOFTBUS_PRINT( "RemoveExceptSessionFd\r\n" );
  104. (errno == EINTR || RemoveExceptSessionFd(tsm, &exceptfds) == 0)の場合{
  105. 続く;
  106. }
  107. SOFTBUS_PRINT( "[TRANS] SelectSessionLoop すべてのセッションを閉じる\n" );
  108. すべてのセッションを閉じます(tsm);
  109. 壊す;
  110. }そうでない場合 (ret == 0) {
  111. 続く;
  112. } else //関数の戻り値が0より大きい場合は、ProcessData関数を呼び出します。
  113. ProcessData(tsm、&readfds);
  114. }
  115. }
  116. tsm->isSelectLoopRunning = false ;
  117. }
  118. ======================================================================
  119. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\tcp_session_manager.c
  120. 静的void ProcessData(TcpSessionMgr *tsm、fd_set *rfds)
  121. {
  122. tsm == NULL || tsm->listenFd == -1 の場合 {
  123. 戻る;
  124. }
  125. //この関数には 2 つの分岐があります。ソケットがセッションを作成していない場合は、ソケットに対してセッションを作成します。セッションが作成されている場合は、そのデータ部分を処理します
  126. FD_ISSET(tsm->listenFd, rfds)の場合{
  127. プロセス接続(tsm);
  128. 戻る;
  129. }
  130.  
  131. プロセスセッションデータ(tsm、rfds);
  132. }

要約:

ソフト バスが開始されると、新しい接続の監視が開始され、OnConnectEvent() 関数で新しい接続の処理が完了し、OnDataEvent() 関数で新しいデータの処理が完了します。

3. 検出側(携帯電話など)がブロードキャストを送信すると

Hongmeng の携帯電話がロック画面をオンにすると、ローカル エリア ネットワークで UDP ブロードキャストが送信されます。開発ボード(サーバー)がブロードキャストを検出すると、次の関数を呼び出します。

1. LAN内でUDPブロードキャストパケットが検出されると、HandleReadEvent()

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
  2. 静的voidHandleReadEvent( int fd)
  3. {
  4. ソケットFd = fd;
  5. 符号なしchar *recvBuffer = calloc(1, COAP_MAX_PDU_SIZE + 1);
  6. 受信バッファNULLの場合
  7. 戻る;
  8. }
  9. ssize_t n読み取り;
  10. 読み取り専用ソケット。 //この関数はソケットの内容を読み取ります
  11. ((nRead == 0) || (nRead < 0 && errno != EAGAIN &&
  12. エラー番号 != EWOULDBLOCK && エラー番号 != EINTR)) {
  13. 解放(recvBuffer);
  14. 戻る;
  15. }
  16.  
  17. COAP_Packet デコードパケット;
  18. (void)memset_s(&decodePacket, sizeof(COAP_Packet), 0, sizeof(COAP_Packet));
  19. デコードパケットプロトコル = COAP_UDP;
  20. COAP_SoftBusDecode(&decodePacket、recvBuffer、nRead); //次にCOAP_SoftBusDecodeを呼び出してデコードします
  21. PostServiceDiscover(&decodePacket); //デコードされたメッセージはPostServiceDiscoverによって処理されます。次の分析を参照してください。
  22. 解放(recvBuffer);
  23. }
  24. ======================================================================
  25. void PostServiceDiscover(const COAP_Packet *pkt)
  26. {
  27. char *remoteUrl = NULL ;
  28. デバイス情報 デバイス情報;
  29.  
  30. (パケットがNULLの場合){
  31. 戻る;
  32. }
  33.  
  34. (void)memset_s(&deviceInfo, sizeof(deviceInfo), 0, sizeof(deviceInfo));
  35. // 今のところ GetServiceDiscoverInfo() の展開関数については詳しく説明しません。TODO
  36. (GetServiceDiscoverInfo(pkt->payload.buffer, pkt->payload.len, &deviceInfo, &remoteUrl) != NSTACKX_EOK) の場合 {
  37. 戻る;
  38. }
  39.  
  40. char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
  41. (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));
  42. (void)inet_ntop(AF_INET、&deviceInfo.netChannelInfo.wifiApInfo.ip、wifiIpAddr、sizeof(wifiIpAddr));
  43. printf( ">>>>>%s:%d\nremoteUrl:%s\nwifiIpAddr:%s\n" ,__FILE__,__LINE__,remoteUrl,wifiIpAddr);//印刷デバッグを追加
  44. リモートURLNULLの場合
  45. CoapResponseService(pkt、リモートUrl、wifiIpAddr); //解決された携帯電話(検出終了)アドレスを介した応答サービス
  46. 無料(リモート URL);
  47. }
  48. }
  49. ======================================================================
  50. 静的  int CoapResponseService(const COAP_Packet *pkt、const char * remoteUrl、const char * remoteIp)
  51. {
  52. 整数戻り値;
  53. CoapRequestCoapRequest;
  54. (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest));
  55. coapRequest.remoteUrl = リモートUrl;
  56. coapRequest.remoteIp = リモートIp;
  57. char *ペイロード = PrepareServiceDiscover();
  58. ペイロード == NULL の場合{
  59. NSTACKX_EFAILED を返します
  60. }
  61. printf( ">>>>>%s:%d\npayload:%s\n" ,__FILE__,__LINE__,payload);//印刷デバッグを追加
  62. COAP_ReadWriteBuffer sndPktBuff = {0};
  63. sndPktBuff.readWriteBuf = calloc(1, COAP_MAX_PDU_SIZE);
  64. sndPktBuff.readWriteBuf == NULL の場合{
  65. 無料(ペイロード)
  66. NSTACKX_EFAILED を返します
  67. }
  68. sndPktバフ。サイズ= COAP_MAX_PDU_SIZE;
  69. sndPktバッファの長さ = 0;
  70.  
  71. ret = BuildSendPkt(pkt、remoteIp、ペイロード、&sndPktBuff); //送り返すパケットを構築する
  72. 無料(ペイロード)
  73. 戻り値 != DISCOVERY_ERR_SUCCESS の場合 {
  74. 解放します(sndPktBuff.readWriteBuf);
  75. sndPktBuff.readWriteBuf = NULL ;
  76. retを返します
  77. }
  78. sndPktBuff を readWriteBuf に格納します。
  79. coapRequest.dataLength = sndPktBuff.len;
  80. ret = CoapSendRequest(&coapRequest); //送信
  81. 解放します(sndPktBuff.readWriteBuf);
  82. sndPktBuff.readWriteBuf = NULL ;
  83.  
  84. retを返します
  85. }

2. 新しい接続が検出されると、ProcessAuthData()

  1. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\libdistbus\auth_conn_manager.c:85
  2. //新しい接続要求であっても、既存の接続でデータが着信する場合でも、この関数が開始されます。
  3. 静的ブール ProcessAuthData( int listenFd, const fd_set *readSet)
  4. {
  5. readSet == NULL || g_callback == NULL || g_callback->onConnectEvent == NULL || の場合
  6. g_callback->onDataEvent == NULL ) {
  7. 戻る 間違い;
  8. }
  9.  
  10. if (FD_ISSET(listenFd, readSet)){//listenFdにメッセージがあるかどうかを判定する
  11. 構造体sockaddr_in addrClient = {0};
  12. socklen_t addrLen = sizeof(addrClient);
  13. // はいの場合は、新しい接続があることを意味します。この時点で、accept() を呼び出してリンクの作成を完了します。新しく作成されたソケットの fd は g_dataFd に格納されます。
  14. g_dataFd = accept(listenFd、(struct sockaddr *)(&addrClient)、&addrLen);
  15. g_dataFd < 0 の場合 {
  16. CloseAuthSessionFd(listenFd);
  17. 戻る 間違い;
  18. }
  19. g_dataFd をリフレッシュします。
  20. //同時に、g_callback->onConnectEvent を呼び出して、新しい接続イベントが発生したことを認証モジュールに通知し、新しく作成された fd とクライアントの IP アドレスを認証モジュールに通知します。
  21. //同時に、g_dataFd を作成するときに、WaitProcess() の次のselect () 操作中に g_dataFd のイベントが監視されるように、g_maxFd を更新する必要があります。
  22. if (g_callback->onConnectEvent(g_dataFd, inet_ntoa(addrClient.sin_addr)) != 0) { //次の分析を参照してくださいOnConnectEvent()
  23. AuthSessionFd(g_dataFd) を閉じます。
  24. }
  25. }
  26. //FD_ISSET() が g_dataFd にメッセージがあると判断した場合、ハンドシェイク接続が完了し、このノードにデータが送信されたことを意味します。
  27. if (g_dataFd > 0 && FD_ISSET(g_dataFd, readSet)) { //次の分析を参照 OnDataEvent()
  28. g_callback->onDataEvent(g_dataFd);//関数は次に g_callback->onDataEvent() をコールバックし、受信したデータを処理するために呼び出し元に制御を返します。
  29. }
  30.  
  31. 戻る 真実;
  32. }
  33. ======================================================================
  34. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\bus_manager.c
  35. int OnConnectEvent( int fd, const char *ip)
  36. {
  37. ProcessConnectEvent(fd, ip); //2.1 新しい接続を確立するとき
  38. 0を返します
  39. }
  40. 整数OnDataEvent(整数fd)
  41. {
  42. プロセスデータイベント(fd); //2.2 新しいデータを受信したとき
  43. 0を返します
  44. }

2.1 新しい接続が確立されると、OnConnectEvent()

  1. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 192
  2. void ProcessConnectEvent( int fd, const char *ip)
  3. {
  4. SOFTBUS_PRINT( "[AUTH] ProcessConnectEvent fd = %d\n" , fd);
  5. AuthConn *aconn = FindAuthConnByFd(fd); //fdを通じて検証接続を見つける
  6.  
  7. aconn = calloc(1, sizeof(AuthConn)); //?システム宣言?
  8.  
  9. int ret = strcpy_s(aconn->deviceIp, sizeof(aconn->deviceIp), ip); // 文字列コピー関数
  10.  
  11. aconn->fd = fd;
  12.  
  13. ret = AddAuthConnToList(aconn); //認証接続をリストに追加する
  14. }
  1. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c:554
  2. この関数は3回呼び出されますか?
  3. データイベントプロセス
  4. void プロセスデータイベント( int fd)
  5. {
  6. SOFTBUS_PRINT( "[AUTH] ProcessDataEvent fd = %d\n" , fd);
  7. AuthConn *conn = FindAuthConnByFd(fd); //fdを通じて検証接続を見つける
  8.  
  9. conn->db.buf == NULLの場合{
  10. conn->db.buf = ( char *)malloc(DEFAULT_BUF_SIZE);
  11. conn->db.buf == NULLの場合{
  12. 戻る;
  13. }
  14. (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
  15. 接続->db。サイズ= DEFAULT_BUF_SIZE;
  16. conn->db.used = 0;
  17. }
  18.  
  19. データバッファ *db = &conn->db;
  20. char *buf = db->buf;
  21. int使用済み = db->使用済み;
  22. 整数 サイズ= db->サイズ;
  23.  
  24. int rc = AuthConnRecv(fd, buf, used, size - used, 0);
  25. rc == 0 の場合
  26. 戻る;
  27. }それ以外の場合 (rc < 0) {
  28. CloseConn(conn);
  29. 戻る;
  30. }
  31.  
  32. 使用済み += rc;
  33. int処理済み = ProcessPackets(conn, buf, size , used); //以下の分析1を参照
  34. (処理済み > 0)の場合{
  35. 使用済み -= 処理済み;
  36. (使用済み!= 0)の場合{
  37. memmove_s(buf, 処理済み, buf, 使用済み) != EOK の場合 {
  38. CloseConn(conn);
  39. 戻る;
  40. }
  41. }
  42. }そうでなければ(処理済み < 0){
  43. CloseConn(conn);
  44. 戻る;
  45. }
  46.  
  47. db->used = 使用済み;
  48. SOFTBUS_PRINT( "[AUTH] ProcessDataEvent ok\n" );
  49. }

1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 527

  1. 静的  int ProcessPackets(AuthConn *conn, const char *buf, int  サイズ int使用)
  2. {
  3. 処理されたint = 0;
  4. (処理済み + PACKET_HEAD_SIZE < 使用済み){
  5. パケット *pkt = ParsePacketHead(buf, processes, used - processes, size );//以下の分析 1 を参照
  6.  
  7. int len ​​= pkt->dataLen; //解析したパケットのサイズをlenに代入する
  8. 処理済み += PACKET_HEAD_SIZE;//+24
  9. OnDataReceived(conn、pkt、buf + 処理済み); //次の分析2を参照
  10. 処理済み += 長さ;
  11. 無料(pkt);
  12. パケット = NULL ;
  13. }
  14. 返品処理済み。
  15. }

1.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 485

  1. //パケット ヘッダーを解析します。この関数はパケット構造を返します。
  2. 静的パケット *ParsePacketHead(const char *buf, int offset, int len, int  サイズ
  3. {
  4. 符号なし整数識別子 = GetIntFromBuf(buf, offset); //1. bufから識別コードを取得する
  5.      
  6. オフセット += DEFAULT_INT_LEN; //オフセットを4に追加
  7. int module = GetIntFromBuf(buf, offset);//2. bufからモジュールを取得する
  8.      
  9. オフセット += DEFAULT_INT_LEN; //オフセットを4に追加
  10. 長い長いシーケンス = 0;
  11. if (GetLongFromBuf(buf, offset, &seq) != 0) { //3. bufからシーケンス番号を取得します
  12. 戻る  NULL ;
  13. }
  14.      
  15. オフセット += DEFAULT_LONG_LEN; //オフセットを4に追加
  16. intフラグ = GetIntFromBuf(buf, オフセット); //4. bufからフラグを取得する
  17.      
  18. オフセット += DEFAULT_INT_LEN; //オフセットを4に追加
  19. int dataLen = GetIntFromBuf(buf, offset); //5. bufからデータ長を取得する
  20.  
  21. SOFTBUS_PRINT( "[AUTH] ParsePacketHead module=%d, seq=%lld, flags=%d, datalen=%d\n" , module, seq, flags, dataLen);
  22.  
  23. パケット *packet = (Packet *)malloc(sizeof(Packet));
  24. パケット->モジュール = モジュール;
  25. パケット->seq = seq;
  26. パケット->フラグ = フラグ;
  27. パケット->dataLen = dataLen;
  28.  
  29. 返送パケット;
  30. }

2.\Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c: 行 446

  1. 静的void OnDataReceived(AuthConn *conn、const Packet *pkt、const char *data)
  2. {
  3. SOFTBUS_PRINT( "[AUTH] OnDataReceived\n" ); //データ受信
  4. pkt->module > MODULE_HICHAIN の場合 && (pkt->module <= MODULE_AUTH_SDK)) {
  5. //データ受信用の認証インターフェース関数、分析1を参照
  6. AuthInterfaceOnDataReceived(conn, pkt->module, pkt->seq, data, pkt->dataLen);
  7. 戻る;
  8. }
  9.  
  10. cJSON *msg = DecryptMessage(pkt->module, data, pkt->dataLen);
  11. メッセージ == NULL の場合
  12. SOFTBUS_PRINT( "[AUTH] OnDataReceived DecryptMessage 失敗\n" );
  13. 戻る;
  14. }
  15.  
  16. OnModuleMessageReceived(conn、pkt->module、pkt->flags、pkt->seq、msg);
  17. cJSON_Delete(メッセージ);
  18. メッセージ = NULL ;
  19. }
  1. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\auth_interface.c
  2. void AuthInterfaceOnDataReceived(const AuthConn *conn、 int module、long long seqId、const char *data、 int dataLen)
  3. {
  4. SOFTBUS_PRINT( "[AUTH] AuthInterfaceOnDataReceived 開始\n" );
  5.  
  6. if (AuthSessionMapInit() != 0) { //認証セッションの初期化
  7. 戻る;
  8. }
  9. AuthSession *auth = AuthGetAuthSessionBySeqId(seqId); //認証 - シーケンスIDで検証セッションを取得する
  10. 認証 == NULL の場合
  11. auth = AuthGetNewAuthSession(conn、seqId、g_authSessionId); //認証 - 新しい認証セッションを取得する
  12. 認証 == NULL の場合
  13. 戻る;
  14. }
  15. ++g_authセッションID;
  16. }
  17.  
  18. スイッチ(モジュール){
  19. MODULE_AUTH_SDKの場合:
  20. AuthProcessReceivedData(auth->sessionId, data, dataLen); //認証スレッドがデータを受信
  21. 壊す;
  22. デフォルト
  23. 壊す;
  24. }
  25. 戻る;
  26. }

2.2 新しいデータが受信されると、OnDataEvent()

  1. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\wifi_auth_manager.c
  2. void プロセスデータイベント( int fd)
  3. {
  4. SOFTBUS_PRINT( "[AUTH] ProcessDataEvent fd = %d\n" , fd);
  5. AuthConn *conn = FindAuthConnByFd(fd);
  6. (接続 == NULL )の場合{
  7. SOFTBUS_PRINT( "ProcessDataEvent get authConn 失敗\n" );
  8. 戻る;
  9. }
  10.  
  11. conn->db.buf == NULLの場合{
  12. conn->db.buf = ( char *)malloc(DEFAULT_BUF_SIZE);
  13. conn->db.buf == NULLの場合{
  14. 戻る;
  15. }
  16. (void)memset_s(conn->db.buf, DEFAULT_BUF_SIZE, 0, DEFAULT_BUF_SIZE);
  17. 接続->db。サイズ= DEFAULT_BUF_SIZE;
  18. conn->db.used = 0;
  19. }
  20.  
  21. データバッファ *db = &conn->db;
  22. char *buf = db->buf;
  23. int使用済み = db->使用済み;
  24. 整数 サイズ= db->サイズ;
  25. printf( ">>>>>%s:%d\nbuf:%s\n" ,__FILE__,__LINE__,buf);
  26. int rc = AuthConnRecv(fd, buf, used, size - used, 0); //認証接続の情報を返す
  27. rc == 0 の場合
  28. 戻る;
  29. }それ以外の場合 (rc < 0) {
  30. CloseConn(conn);
  31. 戻る;
  32. }
  33. 使用済み += rc;
  34. int処理済み = ProcessPackets(conn, buf, size , used); //受信したパケットを処理する
  35. (処理済み > 0)の場合{
  36. 使用済み -= 処理済み;
  37. (使用済み!= 0)の場合{
  38. memmove_s(buf, 処理済み, buf, 使用済み) != EOK の場合 {
  39. CloseConn(conn);
  40. 戻る;
  41. }
  42. }
  43. }そうでなければ(処理済み < 0){
  44. CloseConn(conn);
  45. 戻る;
  46. }
  47. db->used = 使用済み;
  48. SOFTBUS_PRINT( "[AUTH] ProcessDataEvent ok\n" );
  49. }
  50. ======================================================================
  51. Z:\harmony110\foundation\communication\softbus_lite\authmanager\source\auth_conn.c
  52. int AuthConnRecv( int fd, char *buf, int offset, int  カウント intタイムアウト)
  53. {
  54. if ((buf == NULL ) || (オフセット < 0) || ( count <= 0) || (オフセット + count <= 0)) {
  55. -1 を返します
  56. }
  57.  
  58. TcpRecvData(fd, buf + offset, count , timeout)を返します
  59. }
  60. ======================================================================
  61. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\utils\tcp_socket.c
  62. int TcpRecvData( int fd, char *buf, int len, intタイムアウト)
  63. {
  64. TcpRecvMessages(fd, buf, len, timeout, 0)を返します
  65. }
  66. ======================================================================
  67. Z:\harmony110\foundation\communication\softbus_lite\trans_service\source\utils\tcp_socket.c
  68. 静的int32_t TcpRecvMessages( int fd, char *buf, uint32_t len, intタイムアウト, intフラグ)
  69. {printf( ">>>>>%s:%d:%s()\n" ,__FILE__,__LINE__,__FUNCTION__);
  70. fd < 0 || buf == NULL || len == 0 || タイムアウト < 0) {
  71. -1 を返します
  72. }
  73. printf( ">>>>>%s:%d\nfd:%d,len:%d,flags:%d\nTcpRecvMessages:buf:%s\n" ,__FILE__,__LINE__,fd,len,flags,buf);
  74. エラー番号 = 0;
  75. int32_t rc = recv(fd, buf, len, flags);
  76. printf( ">>>>>%s:%d\nfd:%d,len:%d,flags:%d,rc:%d\nTcpRecvMessages:buf:%s\n" ,__FILE__,__LINE__,fd,len,flags,rc,buf);
  77. ((rc == -1) && (errno == EAGAIN)) の場合 {
  78. rc = 0;
  79. }それ以外の場合 (rc <= 0) {
  80. rc = -1;//rc = -1; //ここで rc = -1 なので、プログラムはここで飛び出しますが、int32_t のソース rc = recv(fd, buf, len, flags);見つかりません
  81. }
  82. rcを返します
  83. }
  84. // 2 つの印刷メッセージを追加すると、recv(fd, buf, len, flags) の後に buf にデータがあることがわかります。このデータは携帯電話から取得され、暗号化されます。次のファイルを開くためのrecv()について
  85. //Z:\harmony110\device\hisilicon\hispark_pegasus\sdk_liteos\third_party\lwip_sack\include\lwip\sockets.h:1589
  86. // 関数の説明から、recv() は API として提供されていることがわかりますので、ここでしか掘り下げることができません。

auth.デバイス認証メカニズム

authmanager [デバイス認証メカニズムとデバイス知識ベース管理を提供する]

  1. 要求が見つかると、ProcessDataEvent 関数が呼び出され、パケットを受信し、パケット ヘッダーをチェックし、データ パケットの種類に基づいてさまざまな処理方法を決定します。主なタイプは3つあります。
  2. MODULE_AUTH_SDK 暗号化されたデータ タイプ
  3. MODULE_TRUST_ENGINE 信頼型、直接データ転送
  4. MODULE_CONNECTIONはIPとデバイスの認証を実行します
  5.  
  6. ├──ビルド.gn
  7. ├── 含む
  8. │ ├── auth_conn.h
  9. │ ├── auth_interface.h
  10. │ ├── bus_manager.h
  11. │ ├── msg_get_deviceid.h
  12. │ └── wifi_auth_manager.h
  13. └── 出典
  14. ├── auth_conn.c [送信、受信、認証、鍵取得機能を提供]
  15. ├── auth_interface.c [各セッションノード、各リンクノード、各キーノードを管理し、追加、削除、変更、照会などの機能を提供する]
  16. ├── bus_manager.c [主に、システム上にあるデバイスと新しいデバイス ノードの作成を監視するために使用される、deviceIp を介して 2 つの異なるリスナーを作成します。 OnConnectEventとOnDataEventの2つのコールバック関数があり、それぞれデバイスノードの基本操作とノードデータの処理に使用されます。
  17. ├── msg_get_deviceid.c [デバイスID、リンク情報、デバイス名、デバイスタイプなど、各デバイスに関する情報をcJSON形式で提供します。]
  18. └── wifi_auth_manager.c【主に接続管理とデータ受信機能を実装しています。接続管理には、接続の確立、切断、接続の検索が含まれます。データ受信には、データ取得、パケットヘッダーおよびパケット長の検証が含まれ、パケットヘッダーデータの読み取りを簡素化するために、 int型とlong型のデータの受信関数が別々に実装されています。

参照:

communication_dsoftbus: 検出、ネットワーク、送信などの DSoftBus 機能 | SoftBus の検出、ネットワーク、および伝送機能 (gitee.com)

記事に関連する添付ファイルをダウンロードするには、以下のリンクをクリックしてください。

オリジナルリンク: https://harmonyos..com/posts/4776

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

<<:  Redisson 分散ロック ソースコード フェアロック リリース

>>:  クラウド コンピューティングで「モンスターを倒してレベルアップする」には 7 つのステップがあります。あなたはどの段階にいますか?

推薦する

2022 年の書籍およびコミック アプリ市場の洞察

2020年以降、書籍・コミックアプリの世界収益は3年連続で急成長を維持しています。2022年1月から...

最初のリリース チャネルを選択するにはどうすればよいでしょうか?アプリ操作の8つの隠れたルール

まず、Zhuge を利用してアプリ操作の位置づけを理解しましょう。オペレーション職の内容は、チャネル...

メーカーが PTC と Rockwell Automation のテクノロジー スイートでデジタル変革をリード

[[258826]] PTC とロックウェル・オートメーションの戦略的提携この戦略的提携は、両社の...

効率を向上し、コストを削減: 知っておくべきクラウド アーキテクチャの秘密

クラウド コンピューティング ソリューションの構成について知っておくべきことはすべて知っていると思わ...

SEO トレンドに関する考察: 軽量 Web サイトがトレンドになりつつあるのでしょうか?

今年6月、蔡蔡はA5に「ウェブサイトのコンテンツは毎日更新する必要があるか?」と題する記事を掲載した...

cloudcone: $130/E5-1650v3/64g/2*2T/ロサンゼルスMCデータセンター | 高防御サーバー

私たちは、常に cloudcone の安価な VPS に注目してきました。今日は、cloudcone...

Sharktech データセンター: 159 ドル/2*E5-2670 販売中 | 10Gbps 無制限データ

15 年の歴史を持つ高防御サーバー販売業者 Sharktech (Shark Data Center...

ワールドカップ広告:市場は勝ち取ったが感情は失った

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています中国サッカ...

Woothosting - 中国ユーザー向けのロサンゼルス特別VPS、年間3.99ドルから

Woothosting は、公式発表によると 2007 年に設立されましたが、明らかにこの声明はでた...

ドロワーナビゲーションにより、ユーザーはコア機能に集中できます

[編集者注] この記事は@kentzhuの個人ブログから転載したものです。ナビゲーションはプロダクト...

ロングテールキーワードについての私の理解とロングテールキーワードを選択する利点について話す

ロングテールキーワードとは、文字通り、より長い単語を含むキーワードを指します。多くの場合、単なる単語...

本当のプログラミングの達人はどのように学ぶのでしょうか?何を学ぶべきか?

みなさんこんにちは。私はNezhaです。数日前、私の友人が面接に行き、K8S について多くの詳細な質...

ウェブサイト最適化の目的を明確に理解し、最適化作業を進める

ウェブサイト最適化はインターネットのあらゆる分野に浸透しており、ウェブサイト最適化を行う人の数も増加...

人生を大切にしてSEOから離れましょう

長い間、SEO について語っていませんでした。基本的に、私を知っている人は、SEO に携わっている人...