OpenHarmony 分散ソフトバスプロセス分析 v1.0丨1。発見終了、リリースサービス

OpenHarmony 分散ソフトバスプロセス分析 v1.0丨1。発見終了、リリースサービス

[[408690]]

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

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

https://harmonyos..com

ソースコードディレクトリ:

ホームディレクトリ\foundation\communication\softbus_lite

  1. ├── authmanager【デバイス認証メカニズムとデバイス知識ベース管理を提供】
  2. ├── discovery【coapプロトコルに基づくデバイス検出メカニズムを提供する】
  3. ├── インターフェース
  4. ├── os_adapter【オペレーティングシステム適応層】
  5. ├── trans_service【認証とデータ転送チャネルを提供】
  6. └──ビルド.gn
  7. BUILD.gn の分析により、softbus_lite ディレクトリ全体のすべてのソース コード ファイルが動的ライブラリにコンパイルされることがわかります。
  8. ソフト バスに依存する他のモジュールは、コンパイル時にこの動的ライブラリの依存関係を追加するだけです。
  9. たとえば、分散スケジューリング サブシステムが配置されている bin ファイル基盤のコンパイルは、この動的ライブラリに依存します。

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 型のデータの受信関数が別々に実装されています。

検出 [coap プロトコルに基づくデバイス検出メカニズムを提供する]

  1. ├──ビルド.gn
  2. ├── coap [このディレクトリは主にCOAPプロトコルを担当しています]
  3. │ ├── 含む
  4. │ │ ├── coap_adapter.h
  5. │ │ ├── coap_def.h
  6. │ │ ├── coap_discover.h
  7. │ │ ├── coap_socket.h
  8. │ │ ├── json_payload.h
  9. │ │ ├── nstackx_common.h
  10. │ │ ├── nstackx_database.h
  11. │ │ ├── nstackx_device.h
  12. │ │ ├── nstackx_error.h
  13. │ │ └── nstackx.h
  14. │ └── ソース
  15. │ ├── coap_adapter.c
  16. │ ├── coap_discover.c【COAPベースのデバイス検出機能を実装】
  17. │ ├── coap_socket.c
  18. │ ├── json_payload.c
  19. │ ├── nstackx_common.c
  20. │ └── nstackx_device.c
  21. └── discovery_service【coapプロトコルをベースに軽量デバイス上でサービスを公開する機能を実現】
  22. ├── 含む
  23. │ ├── coap_service.h
  24. │ ├── common_info_manager.h
  25. │ └── 検出エラー.h
  26. └── 出典
  27. ├── coap_service.c
  28. ├── common_info_manager.c
  29. └── discovery_service.c
  30.          
  31. 検出を実装するための前提は、検出デバイスと受信デバイスが同じ LAN にあり、お互いのメッセージを受信できることを保証することです。一般的なプロセスは次のとおりです。
  32.  
  33. エンド デバイスを検出し、coap プロトコルを使用してローカル エリア ネットワークでブロードキャストを送信します。
  34. 受信デバイスは、PublishService インターフェースを使用してサービスを公開します。ブロードキャストを受信した後、受信側は検出側に coap プロトコル ユニキャストを送信します。
  35. 検出エンドデバイスは、メッセージを受信した後、デバイス情報を更新します。

os_adapter [オペレーティング システム適応層]

  1. ├── 含む
  2. │ └── os_adapter.h
  3. └── 出典
  4. ├── L0
  5. │ └── os_adapter.c
  6. └── L1
  7. └── os_adapter.c

trans_service [認証とデータ転送チャネルを提供する]

  1. 主にソケット、cJSON、スレッドロックインターフェースをカプセル化し、ユーザーの作成、監視、セッション管理、デバイス、コマンド、データなどの情報の取得を実現し、最終的に暗号化された伝送と復号化された伝送の 2 つの伝送チャネルを提供します。
  2. ├──ビルド.gn
  3. ├── 含む
  4. │ ├── libdistbus
  5. │ │ ├── auth_conn_manager.h
  6. │ │ └── tcp_session_manager.h
  7. │ └── ユーティリティ
  8. │ ├── aes_gcm.h
  9. │ ├── comm_defs.h
  10. │ ├── data_bus_error.h
  11. │ ├── メッセージ.h
  12. │ └── tcp_socket.h
  13. └── 出典
  14. ├── libdistbus
  15. │ ├── auth_conn_manager.c 【ユーザー作成、監視、接続、その他サービス管理】
  16. │ ├── tcp_session.c 【セッション管理】
  17. │ ├── tcp_session.h
  18. │ ├── tcp_session_manager.c
  19. │ ├── trans_lock.c [ミューテックスの初期化とミューテックスリソースの取得と解放]
  20. │ └── trans_lock.h
  21. └──ユーティリティ
  22. ├── aes_gcm.c [暗号化送信と復号化送信のインターフェースを提供]
  23. ├── message.c [cJSON形式で管理されているデバイス(デバイス名、デバイスタイプ、デバイスIDなどを含む)、命令、データ、セッション(ユーザーポート、セッションポートなどを含む)などの情報を取得するために使用されます]
  24. └── tcp_socket.c [ポート番号管理とデータ転送管理]

1. ソフトバスの初期化方法

ソフト バス モジュールの呼び出しは複雑ではありません。ドラゴンを召喚するには、略して StartBus() と呼ばれる 2 つの構造体を準備するだけで済みます。以下では、Hi3861 を例に簡単な例を記述します。

  1. 静的void InitSoftbus(void)
  2. {printf( ">>>>>%s:%d:%s()\n" ,__FILE__,__LINE__,__FUNCTION__);
  3. 静的パブリッシュ情報 g_publishInfo = {
  4. .capabilityData = (符号なしchar *) "1" ,
  5. .capability = "ddmpCapability"
  6. .データ長 = 1,
  7. .publishId = 1、
  8. .mode = DISCOVER_MODE_ACTIVE、
  9. .medium = COAP、
  10. .freq = 中、
  11. };
  12. 静的IPublishCallback g_publishCallback = {
  13. .onPublishSuccess = 成功時、
  14. .onPublishFail = 失敗時、
  15. };
  16.  
  17. int ret = PublishService(g_demoModuleName、&g_publishInfo、&g_publishCallback);
  18. 戻り値が 0 の場合
  19. printf( "PublishServiceエラー\n" );
  20. }
  21. 睡眠(5);
  22. ret = CreateSessionServer(g_demoModuleName、g_demoSessionName、&g_sessionCallback);
  23. 戻り値が 0 の場合
  24. printf( "CreateSessionServerエラー\n" );
  25. }
  26. printf( "InitSoftbus ok\n" );
  27. }

1. 発見者になってサービスを公開します。 【発見ディレクトリ】

分散ソフト バス サブシステムでは、デバイスは検出端と検出端に分割されます。ここでは、携帯電話を検出側として使用し、Hi3861 開発ボードを検出側としてサービスを公開します。

サービスの公開は主に PublishService() 関数を通じて行われます。関連するコードは、メイン ディレクトリ\foundation\communication\softbus_lite\discovery_service フォルダーにあります。

デバイスがソフト バス サービスを公開する場合は、次の関数を呼び出す必要があります。

  1. //moduleName: 呼び出しモジュール名
  2. //info: PublishInfo 構造体
  3. //cb: 公開の成功または失敗のコールバック関数
  4. int PublishService(const char *moduleName、const struct PublishInfo *info、const struct IPublishCallback *cb)
  5. {printf( "[>>>>%s:%d:%s()[ソフトバス初期化開始]\n" ,__FILE__,__LINE__,__FUNCTION__);
  6. //権限チェック。まず公開権限があるかどうかを確認します。ここで、os_adapter [オペレーティング システム適応層] の関連部分が呼び出されます。
  7. if (SoftBusCheckPermission(SOFTBUS_PERMISSION) != 0 || info == NULL || cb == NULL ) {
  8. SOFTBUS_PRINT( "[DISCOVERY] PublishService のパラメータ(info または cb)が無効です\n" );
  9. ERROR_INVALID を返します
  10. }
  11.  
  12. //パラメータの有効性チェック: 公開されたいくつかのパラメータの有効性をチェックし、公開プロトコルが COAP であるかどうかを確認します。
  13. if (moduleName == NULL || strlen(moduleName) >= MAX_PACKAGE_NAME || info->publishId <= 0 ||
  14. info->dataLen > MAX_CAPABILITY_DATA_LEN) {
  15. SOFTBUS_PRINT( "[DISCOVERY] PublishService パラメータが無効です\n" );
  16. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_PARAMETER_INVALID、 NULL 、cb);
  17. ERROR_INVALID を返します
  18. }//パラメータチェックが失敗した場合は、PublishCallback() を呼び出して、cb 内の失敗コールバック関数をコールバックします。
  19. if (info->medium != COAP) {
  20. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_NOT_SUPPORT_MEDIUM、 NULL 、cb);
  21. ERROR_INVALID を返します
  22. }
  23.  
  24. //複数のデバイスがサービスを公開することで発生する競合を防ぐために g_discoveryMutex を使用する
  25. g_discoveryMutex == NULLの場合{
  26. g_discoveryMutex = MutexInit();
  27. g_discoveryMutex == NULLの場合{
  28. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_UNKNOWN、 NULL 、cb);
  29. ERROR_FAIL を返します
  30. }
  31. }
  32. ミューテックスロック(g_discoveryMutex); //ミューテックスロックを解除する
  33.      
  34. //InitService() この関数はより重要です。 1. InitService() を初期化してサービスを発見するを参照してください。
  35. (InitService() != ERROR_SUCCESS) の場合 {
  36. SOFTBUS_PRINT( "[DISCOVERY] PublishService InitService が失敗しました\n" );
  37. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_UNKNOWN、 NULL 、cb);
  38. Mutex のロックを解除します。
  39. ERROR_FAIL を返します
  40. }
  41.  
  42. //AddPublishModule() 関数、2. g_publishModule にモジュールを追加するを参照してください
  43. PublishModule *findModule = AddPublishModule(モジュール名、情報);
  44. (findModule == NULL )の場合{
  45. SOFTBUS_PRINT( "[DISCOVERY] PublishService AddPublishModule が失敗しました\n" );
  46. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_UNKNOWN、 NULL 、cb);
  47. Mutex のロックを解除します。
  48. ERROR_FAIL を返します
  49. }
  50.  
  51. //COAP サービスを登録します。3.CoapRegisterDefualtService() を参照してください。
  52. 戻り値: ERROR_SUCCESS;
  53. if (info->capability == NULL || info->capabilityData == NULL ) {
  54. (void)CoapRegisterDefaultService();
  55. }それ以外{
  56. ret = DoRegistService(info->medium);
  57. }
  58.      
  59. Mutex のロックを解除します。
  60.  
  61. //この PublishCallback() は非常にシンプルです。上に何度も出てきます。初期化が成功または失敗した場合のコールバック関数です。
  62. 戻り値 != ERROR_SUCCESS の場合 {
  63. PublishCallback(info->publishId、PUBLISH_FAIL_REASON_UNKNOWN、findModule、cb);
  64. ERROR_FAIL を返します
  65. }それ以外{
  66. PublishCallback(info->publishId、ERROR_SUCCESS、findModule、cb);
  67. ERROR_SUCCESS を返します
  68. }
  69. }

1. InitService() を初期化してサービスを検出する

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\discovery_service.c
  2. int InitService(void)
  3. {
  4. if (g_isServiceInit != 0) { //グローバル変数 g_isServiceInit: サービスが開始されているかどうかを確認します。他のモジュールが開始されている場合は、成功が直接返されます。
  5. ERROR_SUCCESS を返します
  6. }
  7.  
  8. //g_deviceInfo 構造体を初期化します。 1.1を参照してください。 g_deviceInfo構造体、関連ファイル[common_info_manager.c]を初期化します。
  9. (InitCommonManager() != 0) の場合 {
  10. DeinitService();
  11. ERROR_FAIL を返します
  12. }
  13.      
  14. // メモリを割り当てます。1.2 を参照してください。グローバル g_publishModule と g_capabilityData を初期化します
  15. g_publishModule = calloc(1, sizeof(PublishModule) * MAX_MODULE_COUNT);
  16. g_publishModule == NULL の場合{
  17. DeinitService();
  18. ERROR_NOMEMORYを返します
  19. }
  20. g_capabilityData = calloc(1, MAX_SERVICE_DATA_LEN);
  21. g_capabilityData == NULLの場合{
  22. DeinitService();
  23. ERROR_NOMEMORYを返します
  24. }
  25. //ソフトバスは、ネットワークが接続されたときにトリガーされる最初の監視関数WifiEventTrigger()を登録します。  
  26. //Wifi コールバックを登録し、WifiEventTrigger()↓関数をグローバル変数 g_wifiCallback に割り当て、b.COAP を参照して Wifi イベントを初期化します。
  27. Wifiコールバックを登録します(Wifiイベントトリガー)。
  28.      
  29. //COAP の初期化。 1.3を参照してください。 COAP プロトコル サービスを初期化します (関連ファイル [coap_service.c])
  30. int ret = CoapInit();
  31. 戻り値 != ERROR_SUCCESS の場合 {
  32. SOFTBUS_PRINT( "[DISCOVERY] InitService CoapInit 失敗\n" );
  33. DeinitService();
  34. retを返します
  35. }printf( ">>>>>%s:%d[WifiEventTring() を登録]\n" ,__FILE__,__LINE__);// 印刷デバッグを追加
  36.      
  37. //COAP はメッセージ キューに書き込み、上記のメッセージ コールバック関数 WifiEventTrigger() をトリガーします。この機能はより重要です、TODO 1.4。
  38. CoapWriteMsgQueue(UPDATE_IP_EVENT);
  39.      
  40. //COAP登録デバイス情報
  41. ret = CoapRegisterDeviceInfo();
  42. 戻り値 != ERROR_SUCCESS の場合 {
  43. SOFTBUS_PRINT( "[DISCOVERY] InitService CoapRegisterDeviceInfo 失敗\n" );
  44. DeinitService();
  45. retを返します
  46. }
  47.      
  48. g_isServiceInit = 1;
  49. SOFTBUS_PRINT( "[DISCOVERY] InitService ok\n" );
  50. ERROR_SUCCESS を返します
  51. }

1.1. g_deviceInfo構造体を初期化する

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\common_info_manager.c
  2.      
  3. int InitCommonManager(void)
  4. {
  5. if (InitLocalDeviceInfo() != 0) { //ローカルデバイス情報を初期化する
  6. SOFTBUS_PRINT( "[DISCOVERY] InitCommonManager が失敗しました\n" );
  7. ERROR_FAIL を返します
  8. }
  9. ERROR_SUCCESS を返します
  10. }
  11. ===================================================================================
  12. int InitLocalDeviceInfo(void) //ローカルデバイス情報を初期化する
  13. {
  14. charデバイスID[DEVICEID_MAX_NUM] = {0};
  15.  
  16. if (g_deviceInfo != NULL ) { //g_deviceInfo 構造体を初期化します。ローカルデバイスに関するさまざまな情報が含まれます。
  17. memset_s(g_deviceInfo, サイズ(デバイス情報)、0、サイズ(デバイス情報));
  18. }それ以外{
  19. g_deviceInfo = (デバイス情報 *)calloc(1, サイズ(デバイス情報));
  20. g_deviceInfo == NULLの場合{
  21. ERROR_FAIL を返します
  22. }
  23. }
  24.  
  25. g_deviceInfo->デバイスポート = -1; //デフォルト、g_deviceInfo.Device ポート -1
  26. g_deviceInfo->isAccountTrusted = 1; //デフォルトでは、g_deviceInfo.account が信頼されます
  27.  
  28. 符号なし整数ret;
  29. //ファイルからデバイス ID を取得します。この機能には複数のレイヤーがあるため、これ以上詳しく説明しません。基本的には、DEVICE_ID_FILE ファイルから読み取られます。
  30. //# DEVICE_ID_FILE を"/storage/data/softbus/deviceid"と定義します 
  31. ret = GetDeviceIdFromFile(デバイスID、MAX_VALUE_SIZE);
  32. 戻り値 != ERROR_SUCCESS の場合 {
  33. SOFTBUS_PRINT( "[DISCOVERY] デバイスの取得に失敗しました\n" );
  34. ERROR_FAIL を返します
  35. }
  36.  
  37. # 定義されている場合(__LITEOS_M__) || __LITEOS_RISCV__ が定義されています //g_deviceInfo。デバイスタイプ、現在はL0とL1に分かれています
  38. g_deviceInfo->デバイスタイプ = L0;
  39. ret = (unsigned int )strcpy_s(g_deviceInfo->deviceName, sizeof(g_deviceInfo->deviceName), L0_DEVICE_NAME);
  40. それ以外 
  41. g_deviceInfo->デバイスタイプ = L1;
  42. ret = (符号なし整数)strcpy_s(g_deviceInfo->deviceName, sizeof(g_deviceInfo->deviceName), L1_DEVICE_NAME);
  43. #終了
  44.  
  45. ret |= (unsigned int )strcpy_s(g_deviceInfo->deviceId, sizeof(g_deviceInfo->deviceId), deviceId);//g_deviceInfo.deviceid
  46. ret |= (unsigned int )strcpy_s(g_deviceInfo->version, sizeof(g_deviceInfo->version), "1.0.0" );//g_deviceInfo.version番号
  47. 戻り値が 0 の場合
  48. ERROR_FAIL を返します
  49. }
  50.  
  51. SOFTBUS_PRINT( "[DISCOVERY] InitLocalDeviceInfo ok\n" );
  52. ERROR_SUCCESS を返します
  53. }

1.2.グローバル g_publishModule と g_capabilityData を初期化します

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\discovery_service.c
  2. //まず、これらの 2 つのグローバル変数は discovery_service.c の先頭で定義されます。
  3.  
  4. PublishModule *g_publishModule = NULL ; //公開されたモジュールを保存する
  5. char *g_capabilityData = NULL ; //機能説明データ
  6.  
  7. typedef構造体{
  8. charパッケージ[MAX_PACKAGE_NAME];
  9. 公開IDをintで指定します。
  10. 符号なしショート媒体;
  11. 符号なしショート機能ビットマップ;
  12. char *機能データ;
  13. 符号なしショートデータ長;
  14. unsigned short が使用されます。
  15. } モジュールを公開します。 //モジュール構造を公開する
  16.  
  17. //InitService() を初期化してサービスを検出すると、モジュールはグローバル変数 g_publishModule に登録され、サービスは g_capabilityData に登録されます。

1.3. COAPプロトコルサービスを初期化する

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\coap_service.c
  2. int CoapInit(void)
  3. {
  4. int ret = NSTACKX_Init();
  5. 戻り値が 0 の場合
  6. SOFTBUS_PRINT( "[DISCOVERY] CoapInit NSTACKX_Init 失敗\n" );
  7. ERROR_FAIL を返します
  8. }
  9. ERROR_SUCCESS を返します
  10. }
  11. ===================================================================================
  12. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\nstackx_common.c
  13. 整数NSTACKX_Init()
  14. {
  15. 整数戻り値;
  16. g_nstackInitState != NSTACKX_INIT_STATE_START の場合 {
  17. NSTACKX_EOKを返します
  18. }
  19.  
  20. g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
  21. cJSON_InitHooks( NULL );
  22.  
  23. ret = CoapInitDiscovery(); //COAPポート監視を開始する
  24. (NSTACKX_EOK が返されない場合){
  25. L_ERR_INITに移動します
  26. }
  27. g_nstackInitState = NSTACKX_INIT_STATE_DONE;
  28. NSTACKX_EOKを返します
  29.  
  30. 例外:
  31. ret = NSTACKX_Deinit();
  32. (NSTACKX_EOK が返されない場合){
  33. SOFTBUS_PRINT( "[DISCOVERY] deinit 失敗\n" );
  34. }
  35. NSTACKX_EFAILED を返します
  36. }
  37. ===================================================================================
  38. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
  39. int CoapInitDiscovery(void)
  40. {
  41. CoapInitSocket を呼び出します。 //a.COAP を参照 ソケットの初期化 //リスニングポートを開始
  42. (NSTACKX_EOK が返されない場合){
  43. SOFTBUS_PRINT( "[DISCOVERY] ソケットの初期化に失敗しました\n" );
  44. retを返します
  45. }
  46.  
  47. ret = CoapInitWifiEvent(); //b.COAP初期化wifiイベントを参照
  48. (NSTACKX_EOK が返されない場合){
  49. SOFTBUS_PRINT( "[DISCOVERY] Wi-Fi初期化イベント失敗\n" );
  50. retを返します
  51. }
  52. #定義されている場合(__LITEOS_A__)
  53. ret = CreateQueryIpThread();
  54. (NSTACKX_EOK が返されない場合){
  55. SOFTBUS_PRINT( "[DISCOVERY] 初期クエリIP失敗\n" );
  56. retを返します
  57. }
  58. #終了
  59. (CreateMsgQueThread() != NSTACKX_EOK) の場合 {
  60. NSTACKX_EFAILED を返します
  61. }
  62.      
  63. CreateCoapListenThread() を返します//c を参照してください。 COAPリスニングスレッドを作成する
  64. }
  65. ===================================================================================

a.COAPソケットの初期化

  1. //この関数はcoapにジャンプします[ディレクトリは主にCOAPプロトコルを担当します]
  2. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_socket.c
  3. int CoapInitSocket(void)
  4. {
  5. g_serverFd >= 0 の場合
  6. NSTACKX_EOKを返します
  7. }
  8. 構造体 sockaddr_in sockAddr;
  9. (void)memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr));
  10. sockAddr.sin_port = htons(COAP_DEFAULT_PORT);
  11. g_serverFd = CoapCreateUdpServer(&sockAddr); //udpサーバーを作成し、このソケットをg_serverFdに割り当てます
  12. g_serverFd < 0 の場合
  13. NSTACKX_OVERFLOW を返します
  14. }
  15. COAP_SoftBusInitMsgId();
  16. NSTACKX_EOKを返します
  17. }
  18. ===================================================================================
  19. int CoapCreateUdpServer(const struct sockaddr_in *sockAddr) //udpサーバーを作成する
  20. {
  21. (sockAddr == NULL )の場合{
  22. NSTACKX_EINVALを返します
  23. }
  24.  
  25. 構造体 sockaddr_in ローカルアドレス;
  26. socklen_t len ​​= sizeof(localAddr);
  27. int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  28. (sockfd < 0)の場合{
  29. NSTACKX_OVERFLOW を返します
  30. }
  31.  
  32. (void)memset_s(&localAddr, sizeof(localAddr), 0, sizeof(localAddr));
  33. localAddr.sin_family = AF_INET; //構造 sockaddr_in.sin_family = 2
  34. localAddr.sin_port = sockAddr->sin_port; //構造体 sockaddr_in.sin_port = 5684、coap_socket.h で定義
  35. (sockAddr->sin_addr.s_addr != 0) の場合 {
  36. ローカルアドレス.sin_addr.s_addr = sockAddr->sin_addr.s_addr; //テストでは、ここでの実行はelseであることが分かりました 
  37. }それ以外{
  38. ローカルアドレス.sin_addr.s_addr = htonl(INADDR_ANY); //構造 sockaddr_in.sin_addr.s_addr = 0 印刷テストの結果は0です
  39. }
  40.  
  41. if (bind(sockfd, (struct sockaddr *)&localAddr, len) == -1) { //ソケットを作成し、bind() を使用して指定された IP+PORT にバインドします。
  42. ソケットを閉じます(&sockfd);
  43. NSTACKX_EFAILED を返します
  44. }
  45.  
  46. if (getsockname(sockfd, (struct sockaddr *)&localAddr, &len) == -1) { //ソケット名を取得する
  47. ソケットを閉じます(&sockfd);
  48. NSTACKX_EFAILED を返します
  49. }
  50. sockfdを返します
  51. }

b.COAPはWiFiイベントを初期化します

  1. //基本的な原則は、wifi_liteのようなイベントコールバック関数を登録することです
  2. //最後にWifiEventTrigger()関数を呼び出します
  3. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
  4. int CoapInitWifiEvent(void)
  5. {
  6. SOFTBUS_PRINT( "[DISCOVERY] CoapInitWifiEvent\n" );
  7. 符号なし整数ret;
  8. g_wifiQueueId == -1の場合{
  9. ret = CreateMsgQue( "/wifiQue" , ​​//メッセージキューを作成する
  10. WIFI_QUEUE_SIZE、(符号なし整数*)&g_wifiQueueId、
  11. 0、サイズ(AddressEventHandler));
  12. 戻り値が 0 の場合
  13. SOFTBUS_PRINT( "[DISCOVERY]CreateMsgQue 失敗\n" );
  14. (void)CoapDeinitWifiEvent();
  15. retを返します
  16. }
  17.  
  18. # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
  19. g_coapEventHandler.OnWifiConnectionChanged = CoapConnectionChangedHandler; //以下の分析を参照
  20. WifiErrorCode エラー = RegisterWifiEvent(&g_coapEventHandler); //wifiイベントを登録、グローバル変数g_coapEventHandler
  21. if (エラー != WIFI_SUCCESS) {
  22. SOFTBUS_PRINT( "[DISCOVERY]RegisterWifiEvent 失敗、エラー:%d\n" 、エラー);
  23. (void)CoapDeinitWifiEvent();
  24. g_wifiキューID = -1;
  25. エラーを返します
  26. }
  27. #終了
  28. }
  29. NSTACKX_EOKを返します
  30. }
  31. ===================================================================================
  32. # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
  33. 静的void CoapConnectionChangedHandler( int状態、 WifiLinkedInfo* 情報)
  34. {
  35. (void)情報;
  36. CoapWriteMsgQueue(状態); //以下の分析を参照
  37. }
  38. ===================================================================================
  39. void CoapWriteMsgQueue( int状態)
  40. {
  41. SOFTBUS_PRINT( "[DISCOVERY] CoapWriteMsgQueue\n" );
  42. AddressEventHandler ハンドラ;
  43. ハンドラ.handler = CoapHandleWifiEvent; //以下の分析を参照
  44. ハンドラの状態 = 状態;
  45. /* 新しいイベントが来る間は、前のループを停止する必要があります */
  46. g_queryIpFlag = 0;
  47. (void)WriteMsgQue(g_wifiQueueId、&handler、sizeof(AddressEventHandler));
  48. }
  49. ===================================================================================
  50. void CoapHandleWifiEvent(符号なし整数パラメタ)
  51. {
  52. if (g_wifiCallback != NULL ) { //g_wifiCallback in int InitService(void){RegisterWifiCallback(WifiEventTrigger);}
  53. g_wifiCallback(パラレル); //Wifiイベントトリガー()
  54. }
  55. }

紀元前COAPリスニングスレッドHandleReadEvent()を作成する

  1. // COAP_DEFAULT_PORT ポート上の UDP ソケットのデータ (つまり、COAP プロトコルに基づく検出ブロードキャスト メッセージ) を処理するための CoapReadHandle スレッドを作成します。
  2. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\coap_discover.c
  3. int CoapListenThread の作成(void)
  4. {
  5. g_terminalフラグ = 1;
  6.  
  7. # 定義されている場合(__LITEOS_M__) ||定義済み(__LITEOS_RISCV__)
  8. g_coapTaskId != NULL の場合{
  9. NSTACKX_EOKを返します
  10. }
  11.  
  12. osThreadAttr_t 属性; //osThreadAttr_t構造体を作成する
  13. 属性。名前= "coap_listen_task" ;
  14. attr.attr_bits = 0U;
  15. attr.cb_mem = NULL ;
  16. attr.cb_size = 0U;
  17. attr.stack_mem = NULL ;
  18. attr.stack_size = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
  19. attr.priority = osPriorityNormal4; // COAP_DEFAULT_PRIO -> cmsis 優先度
  20. //新しいシステムスレッド、グローバル変数g_coapTaskIdを作成します
  21. g_coapTaskId = osThreadNew((osThreadFunc_t)CoapReadHandle, NULL , &attr); //CoapReadHandleを解析するには以下を参照してください
  22. g_coapTaskId == NULLの場合{
  23. g_terminalフラグ = 0;
  24. SOFTBUS_PRINT( "[DISCOVERY] タスクの作成に失敗しました\n" );
  25. NSTACKX_EFAILED を返します
  26. }
  27. それ以外 
  28. g_coapTaskId != -1 の場合 {
  29. NSTACKX_EOKを返します
  30. }
  31.  
  32. スレッド属性 attr = { "coap_listen_task" , 0x800, 20, 0, 0};
  33. int error = CreateThread((Runnable)CoapReadHandle、 NULL 、&attr、(unsigned int *)&g_coapTaskId);
  34. (エラー!= 0)の場合{
  35. g_terminalフラグ = 0;
  36. SOFTBUS_PRINT( "[DISCOVERY] タスクの作成に失敗しました\n" );
  37. NSTACKX_EFAILED を返します
  38. }
  39. #終了
  40. NSTACKX_EOKを返します
  41. }
  42. ===================================================================================
  43. #TIME_MICRO_SEC 10000 を定義します
  44. 静的void CoapReadHandle(unsigned int uwParam1、unsigned int uwParam2、unsigned int uwParam3、unsigned int uwParam4)
  45. {
  46. (void)uwParam1;
  47. (void)uwParam2;
  48. (void)uwParam3;
  49. (void)uwParam4;
  50. 整数戻り値;
  51. fd_set 読み取りセット;
  52. int serverFd = GetCoapServerSocket();
  53. SOFTBUS_PRINT( "[DISCOVERY] CoapReadHandle コイン選択開始\n" );
  54. (g_terminalFlag) の間{
  55. FD_ZERO(&readSet);
  56. FD_SET(serverFd, &readSet);
  57. //非同期通信はselectを呼び出すことで実現されます
  58. ret = select (serverFd + 1, &readSet, NULL , NULL , NULL );
  59. 戻り値 > 0 の場合 {
  60. FD_ISSET(serverFd, &readSet)の場合{
  61. //ポートで監視されているパケットはHandleReadEvent関数によって処理され、受信されたデータパケットが処理されます
  62. ハンドル読み取りイベント(serverFd); //[3. を参照。検出側(携帯電話など)がブロードキャストを送信する場合]
  63. }
  64. }それ以外{
  65. SOFTBUS_PRINT( "[DISCOVERY]ret:%d,error:%d\n" , ret, errno);
  66. }
  67. }
  68. SOFTBUS_PRINT( "[DISCOVERY] CoapReadHandle 終了\n" );
  69. }

2. g_publishModuleにモジュールを追加

  1. //g_publishModule とは何ですか?上記の分析を参照してください: 1.2。グローバル g_publishModule と g_capabilityData を初期化します
  2. // 入力パラメータは PublishInfo *info であり、g_publishModule のコンテンツのほとんどは PublishInfo を継承します
  3. //PublishInfo構造体の内容は、PublishService()を呼び出すときに提供する必要があるパラメータです。
  4. //簡単に言えば、システム g_publishModule にソフト バスのモジュール名と情報を追加します。
  5. PublishModule *AddPublishModule(const char *packageName, const PublishInfo *info)
  6. {
  7. //パラメータを確認する
  8. if (packageName == NULL || g_publishModule == NULL || info == NULL ) {
  9. 戻る  NULL ;
  10. }
  11. if (info->dataLen > MAX_SERVICE_DATA_LEN) {
  12. 戻る  NULL ;
  13. }
  14. (FindExistModule(パッケージ名、info->publishId) != NULL ) の場合 {
  15. 戻る  NULL ;
  16. }
  17. (FindFreeModule() == NULL )の場合{
  18. 戻る  NULL ;
  19. }
  20.      
  21. //
  22. 整数戻り値;
  23. for ( int i = 0; i < MAX_MODULE_COUNT; i++) { //# MAX_MODULE_COUNT 3 を定義する
  24. g_publishModule[i].used == 1の場合{
  25. 続く;
  26. }
  27.  
  28. (ParseCapability(info->capability、&g_publishModule[i].capabilityBitmap)){
  29. 戻る  NULL ;
  30. }
  31.  
  32. g_publishModule[i].used = 1;
  33. g_publishModule[i].capabilityData = calloc(1, info->dataLen + 1);
  34. g_publishModule[i].capabilityData == NULLの場合{
  35. memset_s(&g_publishModule[i], サイズ(g_publishModule[i]), 0, サイズ(g_publishModule[i]));
  36. 戻る  NULL ;
  37. }
  38. g_publishModule[i].dataLength = info->dataLen + 1;
  39. ret = memcpy_s(g_publishModule[i].capabilityData,
  40. g_publishModule[i].dataLength、
  41. info->capabilityData、info->dataLen);
  42. 戻り値が 0 の場合
  43. g_publishModule[i].capabilityDataを解放します
  44. g_publishModule[i].capabilityData = NULL ;
  45. memset_s(&g_publishModule[i], サイズ(g_publishModule[i]), 0, サイズ(g_publishModule[i]));
  46. 戻る  NULL ;
  47. }
  48. g_publishModule[i].medium = 情報->medium;
  49. g_publishModule[i].publishId = info->publishId;
  50. ret = memcpy_s(g_publishModule[i].package, MAX_PACKAGE_NAME, packageName, strlen(packageName));
  51. 戻り値が 0 の場合
  52. g_publishModule[i].capabilityDataを解放します
  53. g_publishModule[i].capabilityData = NULL ;
  54. memset_s(&g_publishModule[i], サイズ(g_publishModule[i]), 0, サイズ(g_publishModule[i]));
  55. 戻る  NULL ;
  56. }
  57. &g_publishModule[i] を返します
  58. }
  59. 戻る  NULL ;
  60. }

3.CoapRegisterDefaultService()

  1. Z:\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\source\coap_service.c
  2.  
  3. int CoapRegisterDefaultService(void) は、
  4. {
  5. デバイス情報 *info = GetCommonDeviceInfo(); //infoはグローバル変数g_deviceInfo構造体を継承します
  6. if (情報 == NULL ) {
  7. ERROR_FAIL を返します
  8. }
  9.  
  10. charサービスデータ[MAX_DEFAULT_SERVICE_DATA_LEN] = {0};
  11. if (sprintf_s(serviceData, sizeof(serviceData), "port:%d" , info->devicePort) == -1) {
  12. ERROR_FAIL を返します
  13. }
  14.  
  15. NSTACKX_RegisterServiceData(serviceData)を返します
  16. }
  17. ======================================================================
  18. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\nstackx_common.c
  19.  
  20. int NSTACKX_RegisterServiceData(const char *サービスデータ)
  21. {
  22. サービスデータ== NULL の場合
  23. NSTACKX_EINVALを返します
  24. }
  25.  
  26. g_nstackInitState != NSTACKX_INIT_STATE_DONE の場合 {
  27. NSTACKX_EFAILED を返します
  28. }
  29. 符号なし整数serviceLen = strlen(serviceData);
  30. サービス長さ >= NSTACKX_MAX_SERVICE_DATA_LEN の場合 {
  31. NSTACKX_EINVALを返します
  32. }
  33.  
  34. RegisterServiceData(serviceData, serviceLen + 1) != NSTACKX_EOK の場合 {
  35. NSTACKX_EINVALを返します
  36. }
  37. NSTACKX_EOKを返します
  38. }
  39. ======================================================================
  40. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\nstackx_device.c
  41.  
  42. int RegisterServiceData(const char * serviceData, int長さ)
  43. {
  44. サービスデータ== NULL の場合
  45. NSTACKX_EINVALを返します
  46. }
  47.  
  48. (void)memset_s(g_localDeviceInfo.serviceData, sizeof(g_localDeviceInfo.serviceData),
  49. 0、サイズ(g_localDeviceInfo.serviceData));
  50. strcpy_s(g_localDeviceInfo.serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData) が EOK の場合 {
  51. NSTACKX_EFAILED を返します
  52. }
  53.  
  54. (void)長さ;
  55. NSTACKX_EOKを返します
  56. }
  57. ======================================================================
  58. Z:\harmony110\foundation\communication\softbus_lite\discovery\coap\source\nstackx_device.c
  59.  
  60. int RegisterServiceData(const char * serviceData, int長さ)
  61. {
  62. サービスデータ== NULL の場合
  63. NSTACKX_EINVALを返します
  64. }
  65.  
  66. (void)memset_s(g_localDeviceInfo.serviceData, sizeof(g_localDeviceInfo.serviceData),
  67. 0、サイズ(g_localDeviceInfo.serviceData));
  68. strcpy_s(g_localDeviceInfo.serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData) が EOK の場合 {
  69. NSTACKX_EFAILED を返します
  70. }
  71.  
  72. (void)長さ;
  73. NSTACKX_EOKを返します
  74. }

要約:

モジュール情報を通じてサービスを登録および公開すると、システムは 2 つのスレッドを生成します。1 つはネットワークを監視するスレッド、もう 1 つはローカル エリア ネットワーク内の UDP の検出終了要求を監視するスレッドです。

ネットワークにアクセスし、[2]を実行します。ネットワークにアクセスするときに、WifiEventTrigger() をトリガーしてソフトバスを開始します]

UDPブロードキャストを聴く[3.端末(携帯電話など)がブロードキャストを送信する場合]

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

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

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

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

https://harmonyos..com

<<:  Prometheus と Grafana を使用して Kubernetes クラスターを監視します。

>>:  ガートナー:Amazon、Microsoft、Alibabaが2020年の世界パブリッククラウドサービスのトップ3にランクイン

推薦する

フォーカス |機械学習に役立つ 7 つのクラウド コンピューティング サービス

データ分析は、多くの組織がクラウド コンピューティング プラットフォーム上で実行する主要なコンピュー...

周紅一:携帯電話と検索は避けられない戦争だ

おそらく数十年後のある日、批評家たちは周紅一点(Weibo)を次のように評するだろう。「周紅一点氏の...

エッジコンピューティング: コンピューティングをネットワークのエッジに押し上げる

デジタル時代において、私たちの生活はさまざまなスマートデバイスやインターネット サービスにますます依...

WeChatプロモーション:WeChatモーメンツの3番目の広告が全面オープンしました!

広告収入の約70%を占めるソーシャル広告のうち、大部分はWeChat Momentsから得られている...

Myspace Chinaの閉鎖の裏側:取締役会はひそかに新プロジェクトを支援

Myspace Chinaに関する最後の公のニュースは、2011年10月にウェブサイトが故障で閉鎖さ...

私のように新しいウェブサイトを構築しようとしている新しいウェブサイト所有者向けに書かれています

私のデビュー記事が A5 ウェブマスター プラットフォームに掲載されたときはうれしかったです。今日は...

ウェイト8ウェブサイトの内部ページ最適化の簡単な分析

中国のトップ比較ショッピング サイトの 1 つとして、SmartPoint は誰もが知っていると思い...

クラウドセキュリティ: 攻撃者の一歩先を行く

クラウド セキュリティは現在、あらゆる主要なデジタル変革の取り組みにおいて重要な役割を果たしており、...

地域観光小規模ポータルの設立計画プロセス

著者はプロの SEO 運用および保守担当者です。多くの SEO 担当者と同様に、私は日中は仕事に行き...

ウェブサイトのデザイン: ユーザーがフォームの入力をより効率的に完了できるようにする

インターネットフォームへの入力は、ほぼすべてのユーザーにとって日常的な経験です。たとえば、ユーザーは...

クラウドへの移行を成功させる方法

クラウド移行が適切に実施されると、速度、生産性、弾力性、スケーラビリティが向上します。しかし、適切に...

SEO 起業プロジェクトが多数あるため、Weikebaba SEO に参加してみてはいかがでしょうか。

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

画像とテキスト |あなたのガールフレンドでも Kubernetes を理解できます!

私は最近 Kubernetes を使い始め、その内部をより深く理解したいと考えていました。これらにつ...

現在のソーシャルツールの分析:実際にはお金にならない

SNSやWeibo(WEB2.0)の台頭により、数多くのソーシャルツールが登場。その年は毎月のように...

公共部門と民間部門におけるクラウドコンピューティング導入の4つの共通課題

2020 年を迎えるにあたり、多くの組織は、リソース、ネットワーク セキュリティ、データ主権、クラウ...