From 21fef0fee02da658dbecc0adf48db09bb47dbf1c Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Wed, 2 Jun 2021 00:05:35 +0800 Subject: [PATCH] update OpenHarmony 2.0 Canary --- .gitattributes | 15 + BUILD.gn | 22 + LICENSE | 177 ++ OAT.xml | 63 + README.en.md | 36 - README.md | 270 ++- README_zh.md | 257 +++ components/mbedtls/BUILD.gn | 114 ++ components/nstackx/nstackx_ctrl/BUILD.gn | 55 + .../core/coap_discover/coap_app.c | 469 +++++ .../core/coap_discover/coap_client.c | 306 +++ .../core/coap_discover/coap_discover.c | 1104 +++++++++++ .../core/coap_discover/json_payload.c | 370 ++++ .../nstackx_ctrl/core/nstackx_common.c | 815 ++++++++ .../nstackx_ctrl/core/nstackx_database.c | 241 +++ .../nstackx_ctrl/core/nstackx_device.c | 1306 +++++++++++++ .../nstackx_ctrl/core/nstackx_smartgenius.c | 255 +++ .../include/coap_discover/coap_app.h | 44 + .../include/coap_discover/coap_client.h | 47 + .../include/coap_discover/coap_discover.h | 64 + .../include/coap_discover/json_payload.h | 34 + .../nstackx_ctrl/include/nstackx_common.h | 36 + .../nstackx_ctrl/include/nstackx_database.h | 38 + .../nstackx_ctrl/include/nstackx_device.h | 128 ++ .../include/nstackx_smartgenius.h | 31 + .../nstackx/nstackx_ctrl/interface/nstackx.h | 202 ++ components/nstackx/nstackx_util/BUILD.gn | 44 + .../nstackx/nstackx_util/core/nstackx_dev.c | 43 + .../nstackx/nstackx_util/core/nstackx_event.c | 94 + .../nstackx/nstackx_util/core/nstackx_log.c | 55 + .../nstackx/nstackx_util/core/nstackx_timer.c | 62 + .../nstackx/nstackx_util/core/nstackx_util.c | 174 ++ .../interface/nstackx_common_header.h | 39 + .../nstackx_util/interface/nstackx_config.h | 53 + .../nstackx_util/interface/nstackx_dev.h | 59 + .../nstackx_util/interface/nstackx_epoll.h | 67 + .../nstackx_util/interface/nstackx_error.h | 84 + .../nstackx_util/interface/nstackx_event.h | 47 + .../nstackx_util/interface/nstackx_list.h | 117 ++ .../nstackx_util/interface/nstackx_log.h | 69 + .../nstackx_util/interface/nstackx_timer.h | 52 + .../nstackx_util/interface/nstackx_util.h | 77 + .../platform/unix/sys_common_header.h | 57 + .../nstackx_util/platform/unix/sys_dev.c | 406 ++++ .../nstackx_util/platform/unix/sys_epoll.c | 109 ++ .../nstackx_util/platform/unix/sys_epoll.h | 45 + .../nstackx_util/platform/unix/sys_event.c | 190 ++ .../nstackx_util/platform/unix/sys_event.h | 25 + .../nstackx_util/platform/unix/sys_log.c | 27 + .../nstackx_util/platform/unix/sys_timer.c | 159 ++ .../nstackx_util/platform/unix/sys_util.c | 217 +++ .../nstackx_util/platform/unix/sys_util.h | 54 + core/BUILD.gn | 27 + core/adapter/br/include/bt_rfcom.h | 84 + .../adapter/br/include/wrapper_br_interface.h | 70 + core/adapter/br/mock/BUILD.gn | 24 + core/adapter/br/mock/wrapper_br_interface.c | 151 ++ core/adapter/bus_center/BUILD.gn | 34 + .../bus_center/include/bus_center_adapter.h | 47 + .../platform/bus_center_adapter_weak.c | 51 + core/adapter/kernel/BUILD.gn | 45 + .../kernel/include/softbus_mem_interface.h | 42 + .../kernel/include/softbus_os_interface.h | 43 + .../kernel/liteos_a/softbus_mem_interface.c | 81 + .../kernel/liteos_a/softbus_os_interface.c | 170 ++ .../kernel/liteos_m/softbus_mem_interface.c | 94 + .../kernel/liteos_m/softbus_os_interface.c | 123 ++ core/authentication/include/auth_common.h | 37 + core/authentication/include/auth_connection.h | 47 + core/authentication/include/auth_manager.h | 93 + core/authentication/include/auth_sessionkey.h | 64 + core/authentication/include/auth_socket.h | 35 + .../authentication/interface/auth_interface.h | 126 ++ core/authentication/src/auth_common.c | 127 ++ core/authentication/src/auth_connection.c | 404 ++++ core/authentication/src/auth_manager.c | 1064 +++++++++++ core/authentication/src/auth_sessionkey.c | 306 +++ core/authentication/src/auth_socket.c | 224 +++ core/bus_center/BUILD.gn | 132 ++ .../interface/bus_center_info_key.h | 54 + .../bus_center/interface/bus_center_manager.h | 46 + .../ipc/include/lnn_bus_center_ipc.h | 40 + .../ipc/mini_system/lnn_bus_center_ipc.c | 75 + .../standard_system/lnn_bus_center_ipc.cpp | 228 +++ .../lane_manager/include/lnn_lane_info.h | 57 + .../lane_manager/include/lnn_lane_manager.h | 36 + .../include/lnn_smart_communication.h | 31 + .../lane_hub/lane_manager/src/lnn_lane_info.c | 166 ++ .../lane_manager/src/lnn_lane_manager.c | 87 + .../src/lnn_smart_communication.c | 135 ++ .../net_builder/include/lnn_conn_type_hook.h | 44 + .../lnn/net_builder/include/lnn_net_builder.h | 62 + .../lnn/net_builder/include/lnn_network_id.h | 31 + .../net_builder/include/lnn_state_machine.h | 75 + core/bus_center/lnn/net_builder/ip/ip_hook.c | 434 +++++ .../lnn/net_builder/src/lnn_net_builder.c | 1131 +++++++++++ .../lnn/net_builder/src/lnn_network_id.c | 90 + .../lnn/net_builder/src/lnn_state_machine.c | 373 ++++ .../common/include/lnn_connect_info.h | 44 + .../common/include/lnn_device_info.h | 55 + .../lnn/net_ledger/common/include/lnn_map.h | 107 ++ .../common/include/lnn_net_capability.h | 43 + .../net_ledger/common/include/lnn_node_info.h | 90 + .../net_ledger/common/src/lnn_device_info.c | 101 + .../lnn/net_ledger/common/src/lnn_map.c | 362 ++++ .../common/src/lnn_net_capability.c | 38 + .../lnn/net_ledger/common/src/lnn_node_info.c | 203 ++ .../include/lnn_distributed_net_ledger.h | 60 + .../src/lnn_distributed_net_ledger.c | 945 ++++++++++ .../include/lnn_local_net_ledger.h | 55 + .../local_ledger/src/lnn_local_net_ledger.c | 640 +++++++ .../include/lnn_exchange_ledger_info.h | 80 + .../include/lnn_sync_ledger_item_info.h | 57 + .../src/lnn_exchange_ledger_info.c | 307 +++ .../src/lnn_sync_ledger_item_info.c | 496 +++++ .../service/include/bus_center_event.h | 38 + .../bus_center/service/src/bus_center_event.c | 63 + .../service/src/bus_center_manager.c | 166 ++ .../utils/include/lnn_connection_addr_utils.h | 33 + .../utils/src/lnn_connection_addr_utils.c | 35 + core/common/BUILD.gn | 23 + core/common/include/common_list.h | 146 ++ core/common/include/softbus.h | 41 + core/common/include/softbus_crypto.h | 77 + core/common/include/softbus_def.h | 119 ++ core/common/include/softbus_errcode.h | 131 ++ core/common/include/softbus_json_utils.h | 46 + core/common/include/softbus_log.h | 96 + core/common/include/softbus_permission.h | 52 + core/common/include/softbus_property.h | 46 + core/common/include/softbus_type_def.h | 42 + core/common/include/softbus_utils.h | 73 + .../c/softbus_client_interface.c | 152 ++ .../c/softbus_client_interface_impl.c | 22 + .../c/softbus_server_interface.c | 164 ++ .../c/softbus_server_interface_impl.c | 21 + .../ipc/include/softbus_client_weak.h | 73 + .../ipc/include/softbus_server_weak.h | 73 + .../ipc/softbus_client_interface.c | 68 + .../ipc/softbus_client_interface_impl.c | 223 +++ .../ipc/softbus_client_weak.c | 117 ++ .../ipc/softbus_server_interface.c | 144 ++ .../ipc/softbus_server_interface_impl.c | 203 ++ .../ipc/softbus_server_weak.c | 175 ++ .../inner_communication/softbus_interface.h | 130 ++ core/common/json_utils/BUILD.gn | 41 + core/common/json_utils/softbus_json_utils.c | 118 ++ core/common/message_handler/BUILD.gn | 40 + .../message_handler/include/message_handler.h | 82 + core/common/message_handler/message_handler.c | 493 +++++ core/common/security/BUILD.gn | 41 + core/common/security/mbedtls/softbus_crypto.c | 173 ++ core/common/security/permission/BUILD.gn | 23 + .../permission/common/permission_entry.c | 489 +++++ .../permission/include/permission_entry.h | 80 + .../permission/include/permission_utils.h | 35 + .../mini_system/softbus_permission.c | 45 + .../security/permission/permission.json | 14 + .../small_system/softbus_permission.c | 45 + .../standard_system/permission_utils.cpp | 47 + .../standard_system/softbus_permission.cpp | 184 ++ .../security/sequence_verification/BUILD.gn | 45 + .../include/softbus_sequence_verification.h | 49 + .../src/softbus_sequence_verification.c | 178 ++ core/common/softbus_property/BUILD.gn | 44 + .../softbus_property/include/softbus_config.h | 44 + .../softbus_property/src/softbus_property.c | 111 ++ core/common/utils/BUILD.gn | 45 + core/common/utils/softbus_utils.c | 270 +++ core/connection/BUILD.gn | 18 + core/connection/br/BUILD.gn | 29 + core/connection/br/br_connection.c | 1664 +++++++++++++++++ core/connection/common/BUILD.gn | 60 + .../common/include/softbus_thread_pool.h | 75 + .../common/src/softbus_base_listener.c | 790 ++++++++ .../common/src/softbus_tcp_socket.c | 358 ++++ .../common/src/softbus_thread_pool.c | 351 ++++ .../interface/softbus_base_listener.h | 76 + .../interface/softbus_conn_interface.h | 159 ++ .../connection/interface/softbus_tcp_socket.h | 66 + core/connection/manager/BUILD.gn | 43 + .../connection/manager/softbus_conn_manager.c | 501 +++++ .../connection/manager/softbus_conn_manager.h | 56 + .../manager/softbus_conn_manager_weak.c | 34 + .../manager/softbus_conn_manager_weak.h | 35 + core/connection/tcp/BUILD.gn | 51 + .../tcp/include/softbus_tcp_connect_manager.h | 59 + .../tcp/src/softbus_tcp_connect_manager.c | 528 ++++++ core/discovery/BUILD.gn | 21 + core/discovery/coap/BUILD.gn | 53 + core/discovery/coap/include/disc_coap.h | 36 + .../coap/include/disc_nstackx_adapter.h | 50 + core/discovery/coap/src/disc_coap.c | 438 +++++ .../discovery/coap/src/disc_nstackx_adapter.c | 407 ++++ core/discovery/interface/disc_interface.h | 237 +++ core/discovery/manager/BUILD.gn | 42 + core/discovery/manager/include/disc_manager.h | 80 + core/discovery/manager/src/disc_manager.c | 1251 +++++++++++++ .../service/include/softbus_disc_server.h | 34 + .../service/src/softbus_disc_server.c | 103 + core/frame/lite/BUILD.gn | 78 + .../include/softbus_client_info_manager.h | 41 + .../frame/lite/include/softbus_server_frame.h | 29 + .../lite/include/softbus_server_frame_weak.h | 43 + .../lite/src/softbus_client_info_manager.c | 159 ++ core/frame/lite/src/softbus_server_frame.c | 86 + .../lite/src/softbus_server_frame_weak.c | 62 + core/frame/lite/src/softbus_server_main.c | 26 + core/frame/standard/client/BUILD.gn | 230 +++ .../client/include/if_softbus_client.h | 48 + .../client/include/softbus_client_proxy.h | 50 + .../client/include/softbus_client_stub.h | 66 + .../standard/client/src/if_softbus_client.cpp | 17 + .../client/src/softbus_client_proxy.cpp | 470 +++++ .../client/src/softbus_client_stub.cpp | 509 +++++ core/frame/standard/sa_profile/4700.xml | 24 + core/frame/standard/sa_profile/BUILD.gn | 20 + core/frame/standard/server/BUILD.gn | 339 ++++ .../server/include/if_softbus_server.h | 53 + .../include/softbus_client_death_recipient.h | 30 + .../standard/server/include/softbus_server.h | 74 + .../include/softbus_server_death_recipient.h | 30 + .../server/include/softbus_server_frame.h | 44 + .../server/include/softbus_server_proxy.h | 59 + .../server/include/softbus_server_stub.h | 56 + .../standard/server/src/if_softbus_server.cpp | 17 + .../src/softbus_client_death_recipient.cpp | 27 + .../server/src/softbus_interface_client.cpp | 222 +++ .../server/src/softbus_interface_server.cpp | 365 ++++ .../standard/server/src/softbus_server.cpp | 295 +++ .../standard/server/src/softbus_server.rc | 21 + .../src/softbus_server_death_recipient.cpp | 28 + .../server/src/softbus_server_frame.c | 120 ++ .../server/src/softbus_server_proxy.cpp | 613 ++++++ .../server/src/softbus_server_stub.cpp | 440 +++++ core/transmission/BUILD.gn | 22 + core/transmission/common/BUILD.gn | 37 + .../common/include/softbus_app_info.h | 90 + .../include/softbus_message_open_channel.h | 56 + .../common/softbus_message_open_channel.c | 213 +++ .../softbus_transmission_interface.h | 38 + core/transmission/pending_packet/BUILD.gn | 32 + .../include/trans_pending_pkt.h | 61 + .../pending_packet/src/trans_pending_pkt.c | 204 ++ core/transmission/session/BUILD.gn | 61 + .../session/include/trans_session_manager.h | 37 + .../session/src/trans_session_manager.c | 279 +++ core/transmission/trans_channel/BUILD.gn | 63 + .../manager/include/trans_channel_manager.h | 40 + .../manager/src/trans_channel_manager.c | 243 +++ .../transmission/trans_channel/proxy/BUILD.gn | 83 + .../include/softbus_proxychannel_control.h | 27 + .../include/softbus_proxychannel_listener.h | 26 + .../include/softbus_proxychannel_manager.h | 47 + .../include/softbus_proxychannel_message.h | 111 ++ .../include/softbus_proxychannel_network.h | 32 + .../include/softbus_proxychannel_session.h | 43 + .../softbus_proxychannel_transceiver.h | 47 + .../proxy/src/softbus_proxychannel_control.c | 220 +++ .../proxy/src/softbus_proxychannel_listener.c | 261 +++ .../proxy/src/softbus_proxychannel_manager.c | 1023 ++++++++++ .../proxy/src/softbus_proxychannel_message.c | 422 +++++ .../proxy/src/softbus_proxychannel_network.c | 77 + .../proxy/src/softbus_proxychannel_session.c | 378 ++++ .../src/softbus_proxychannel_transceiver.c | 679 +++++++ .../trans_channel/tcp_direct/BUILD.gn | 51 + .../include/trans_tcp_direct_listener.h | 33 + .../include/trans_tcp_direct_manager.h | 100 + .../include/trans_tcp_direct_message.h | 40 + .../src/trans_tcp_direct_listener.c | 248 +++ .../tcp_direct/src/trans_tcp_direct_manager.c | 304 +++ .../tcp_direct/src/trans_tcp_direct_message.c | 413 ++++ dsoftbus.gni | 14 + figures/dsoftbus-architecture.png | Bin 0 -> 23536 bytes figures/dsoftbus-architecture_zh.png | Bin 0 -> 21386 bytes .../kits/bus_center/softbus_bus_center.h | 129 ++ interfaces/kits/common/softbus_common.h | 33 + interfaces/kits/discovery/discovery_service.h | 404 ++++ interfaces/kits/transport/session.h | 260 +++ ohos.build | 39 + sdk/BUILD.gn | 23 + sdk/bus_center/BUILD.gn | 48 + sdk/bus_center/include/client_bus_center.h | 36 + sdk/bus_center/src/client_bus_center.c | 601 ++++++ sdk/discovery/BUILD.gn | 46 + sdk/discovery/include/client_disc_manager.h | 39 + sdk/discovery/src/client_disc_manager.c | 329 ++++ sdk/frame/BUILD.gn | 90 + .../include/softbus_client_event_manager.h | 32 + .../include/softbus_client_frame_manager.h | 31 + .../softbus_client_frame_manager_weak.h | 40 + sdk/frame/softbus_client_event_manager.c | 147 ++ sdk/frame/softbus_client_frame_manager.c | 196 ++ sdk/frame/softbus_client_frame_manager_weak.c | 54 + sdk/transmission/BUILD.gn | 22 + sdk/transmission/session/BUILD.gn | 70 + .../session/cpp/include/CommDefs.h | 27 + .../session/cpp/include/ISessionListener.h | 43 + .../session/cpp/include/ISessionService.h | 53 + .../session/cpp/include/Session.h | 98 + .../session/cpp/src/session_callback_mock.cpp | 45 + .../session/cpp/src/session_callback_mock.h | 34 + .../session/cpp/src/session_impl.cpp | 122 ++ .../session/cpp/src/session_impl.h | 96 + .../session/cpp/src/session_mock.cpp | 84 + .../session/cpp/src/session_mock.h | 40 + .../session/cpp/src/session_service_impl.cpp | 245 +++ .../session/cpp/src/session_service_impl.h | 69 + .../include/client_trans_message_service.h | 29 + .../include/client_trans_session_callback.h | 36 + .../include/client_trans_session_manager.h | 107 ++ .../include/client_trans_session_service.h | 29 + .../src/client_trans_message_service.c | 66 + .../src/client_trans_session_callback.c | 177 ++ .../src/client_trans_session_manager.c | 818 ++++++++ .../src/client_trans_session_service.c | 238 +++ sdk/transmission/trans_channel/BUILD.gn | 78 + .../include/client_trans_channel_callback.h | 37 + .../client_trans_channel_callback_weak.h | 35 + .../include/client_trans_channel_manager.h | 38 + .../client_trans_channel_manager_weak.h | 48 + .../src/client_trans_channel_callback.c | 85 + .../src/client_trans_channel_callback_weak.c | 30 + .../src/client_trans_channel_manager.c | 113 ++ .../src/client_trans_channel_manager_weak.c | 70 + .../include/client_trans_proxy_manager.h | 36 + .../proxy/src/client_trans_proxy_manager.c | 46 + .../trans_channel/tcp_direct/BUILD.gn | 47 + .../client_trans_tcp_direct_listener.h | 31 + .../include/client_trans_tcp_direct_manager.h | 57 + .../include/client_trans_tcp_direct_message.h | 56 + .../src/client_trans_tcp_direct_listener.c | 117 ++ .../src/client_trans_tcp_direct_manager.c | 203 ++ .../src/client_trans_tcp_direct_message.c | 278 +++ tests/core/authentication/BUILD.gn | 57 + .../authentication/unittest/auth_test.cpp | 270 +++ tests/core/bus_center/lnn/BUILD.gn | 62 + .../lnn/unittest/ledger_lane_hub_test.cpp | 649 +++++++ .../lnn/unittest/net_builder_test.cpp | 108 ++ tests/core/common/security/BUILD.gn | 72 + .../security/softbus_permission_test.cpp | 334 ++++ .../security/softbus_permission_test.json | 175 ++ tests/core/connection/BUILD.gn | 21 + tests/core/connection/common/BUILD.gn | 39 + .../common/softbus_conn_common_test.cpp | 513 +++++ tests/core/connection/manager/BUILD.gn | 42 + .../manager/connection_manager_test.cpp | 410 ++++ tests/core/connection/tcp/BUILD.gn | 42 + .../core/connection/tcp/tcp_manager_test.cpp | 408 ++++ tests/core/discovery/manager/BUILD.gn | 50 + .../manager/unittest/disc_manager_test.cpp | 1301 +++++++++++++ .../trans_channel/tcp_direct/BUILD.gn | 61 + .../unittest/trans_tcp_direct_test.cpp | 140 ++ tests/sdk/bus_center/unittest/BUILD.gn | 51 + .../unittest/bus_center_sdk_test.cpp | 255 +++ tests/sdk/discovery/unittest/BUILD.gn | 51 + .../sdk/discovery/unittest/disc_sdk_test.cpp | 457 +++++ .../trans_channel/tcp_direct/BUILD.gn | 62 + .../unittest/trans_tcp_direct_test.cpp | 324 ++++ 359 files changed, 56149 insertions(+), 61 deletions(-) create mode 100644 .gitattributes create mode 100755 BUILD.gn create mode 100644 LICENSE create mode 100755 OAT.xml delete mode 100644 README.en.md mode change 100644 => 100755 README.md create mode 100755 README_zh.md create mode 100755 components/mbedtls/BUILD.gn create mode 100755 components/nstackx/nstackx_ctrl/BUILD.gn create mode 100644 components/nstackx/nstackx_ctrl/core/coap_discover/coap_app.c create mode 100644 components/nstackx/nstackx_ctrl/core/coap_discover/coap_client.c create mode 100644 components/nstackx/nstackx_ctrl/core/coap_discover/coap_discover.c create mode 100644 components/nstackx/nstackx_ctrl/core/coap_discover/json_payload.c create mode 100644 components/nstackx/nstackx_ctrl/core/nstackx_common.c create mode 100644 components/nstackx/nstackx_ctrl/core/nstackx_database.c create mode 100644 components/nstackx/nstackx_ctrl/core/nstackx_device.c create mode 100644 components/nstackx/nstackx_ctrl/core/nstackx_smartgenius.c create mode 100644 components/nstackx/nstackx_ctrl/include/coap_discover/coap_app.h create mode 100644 components/nstackx/nstackx_ctrl/include/coap_discover/coap_client.h create mode 100644 components/nstackx/nstackx_ctrl/include/coap_discover/coap_discover.h create mode 100644 components/nstackx/nstackx_ctrl/include/coap_discover/json_payload.h create mode 100644 components/nstackx/nstackx_ctrl/include/nstackx_common.h create mode 100644 components/nstackx/nstackx_ctrl/include/nstackx_database.h create mode 100644 components/nstackx/nstackx_ctrl/include/nstackx_device.h create mode 100644 components/nstackx/nstackx_ctrl/include/nstackx_smartgenius.h create mode 100644 components/nstackx/nstackx_ctrl/interface/nstackx.h create mode 100755 components/nstackx/nstackx_util/BUILD.gn create mode 100644 components/nstackx/nstackx_util/core/nstackx_dev.c create mode 100644 components/nstackx/nstackx_util/core/nstackx_event.c create mode 100644 components/nstackx/nstackx_util/core/nstackx_log.c create mode 100644 components/nstackx/nstackx_util/core/nstackx_timer.c create mode 100644 components/nstackx/nstackx_util/core/nstackx_util.c create mode 100644 components/nstackx/nstackx_util/interface/nstackx_common_header.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_config.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_dev.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_epoll.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_error.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_event.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_list.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_log.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_timer.h create mode 100644 components/nstackx/nstackx_util/interface/nstackx_util.h create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_common_header.h create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_dev.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_epoll.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_epoll.h create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_event.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_event.h create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_log.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_timer.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_util.c create mode 100644 components/nstackx/nstackx_util/platform/unix/sys_util.h create mode 100755 core/BUILD.gn create mode 100755 core/adapter/br/include/bt_rfcom.h create mode 100755 core/adapter/br/include/wrapper_br_interface.h create mode 100755 core/adapter/br/mock/BUILD.gn create mode 100755 core/adapter/br/mock/wrapper_br_interface.c create mode 100755 core/adapter/bus_center/BUILD.gn create mode 100644 core/adapter/bus_center/include/bus_center_adapter.h create mode 100644 core/adapter/bus_center/platform/bus_center_adapter_weak.c create mode 100755 core/adapter/kernel/BUILD.gn create mode 100755 core/adapter/kernel/include/softbus_mem_interface.h create mode 100755 core/adapter/kernel/include/softbus_os_interface.h create mode 100755 core/adapter/kernel/liteos_a/softbus_mem_interface.c create mode 100755 core/adapter/kernel/liteos_a/softbus_os_interface.c create mode 100755 core/adapter/kernel/liteos_m/softbus_mem_interface.c create mode 100755 core/adapter/kernel/liteos_m/softbus_os_interface.c create mode 100644 core/authentication/include/auth_common.h create mode 100644 core/authentication/include/auth_connection.h create mode 100644 core/authentication/include/auth_manager.h create mode 100644 core/authentication/include/auth_sessionkey.h create mode 100644 core/authentication/include/auth_socket.h create mode 100755 core/authentication/interface/auth_interface.h create mode 100644 core/authentication/src/auth_common.c create mode 100644 core/authentication/src/auth_connection.c create mode 100755 core/authentication/src/auth_manager.c create mode 100644 core/authentication/src/auth_sessionkey.c create mode 100644 core/authentication/src/auth_socket.c create mode 100755 core/bus_center/BUILD.gn create mode 100644 core/bus_center/interface/bus_center_info_key.h create mode 100644 core/bus_center/interface/bus_center_manager.h create mode 100755 core/bus_center/ipc/include/lnn_bus_center_ipc.h create mode 100755 core/bus_center/ipc/mini_system/lnn_bus_center_ipc.c create mode 100755 core/bus_center/ipc/standard_system/lnn_bus_center_ipc.cpp create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_info.h create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_manager.h create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/include/lnn_smart_communication.h create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_info.c create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_manager.c create mode 100644 core/bus_center/lnn/lane_hub/lane_manager/src/lnn_smart_communication.c create mode 100644 core/bus_center/lnn/net_builder/include/lnn_conn_type_hook.h create mode 100644 core/bus_center/lnn/net_builder/include/lnn_net_builder.h create mode 100644 core/bus_center/lnn/net_builder/include/lnn_network_id.h create mode 100644 core/bus_center/lnn/net_builder/include/lnn_state_machine.h create mode 100644 core/bus_center/lnn/net_builder/ip/ip_hook.c create mode 100644 core/bus_center/lnn/net_builder/src/lnn_net_builder.c create mode 100644 core/bus_center/lnn/net_builder/src/lnn_network_id.c create mode 100644 core/bus_center/lnn/net_builder/src/lnn_state_machine.c create mode 100644 core/bus_center/lnn/net_ledger/common/include/lnn_connect_info.h create mode 100644 core/bus_center/lnn/net_ledger/common/include/lnn_device_info.h create mode 100644 core/bus_center/lnn/net_ledger/common/include/lnn_map.h create mode 100644 core/bus_center/lnn/net_ledger/common/include/lnn_net_capability.h create mode 100644 core/bus_center/lnn/net_ledger/common/include/lnn_node_info.h create mode 100644 core/bus_center/lnn/net_ledger/common/src/lnn_device_info.c create mode 100644 core/bus_center/lnn/net_ledger/common/src/lnn_map.c create mode 100644 core/bus_center/lnn/net_ledger/common/src/lnn_net_capability.c create mode 100644 core/bus_center/lnn/net_ledger/common/src/lnn_node_info.c create mode 100644 core/bus_center/lnn/net_ledger/distributed_ledger/include/lnn_distributed_net_ledger.h create mode 100644 core/bus_center/lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c create mode 100644 core/bus_center/lnn/net_ledger/local_ledger/include/lnn_local_net_ledger.h create mode 100644 core/bus_center/lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c create mode 100644 core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_exchange_ledger_info.h create mode 100644 core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_sync_ledger_item_info.h create mode 100644 core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c create mode 100644 core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c create mode 100644 core/bus_center/service/include/bus_center_event.h create mode 100644 core/bus_center/service/src/bus_center_event.c create mode 100644 core/bus_center/service/src/bus_center_manager.c create mode 100644 core/bus_center/utils/include/lnn_connection_addr_utils.h create mode 100644 core/bus_center/utils/src/lnn_connection_addr_utils.c create mode 100755 core/common/BUILD.gn create mode 100644 core/common/include/common_list.h create mode 100644 core/common/include/softbus.h create mode 100644 core/common/include/softbus_crypto.h create mode 100755 core/common/include/softbus_def.h create mode 100755 core/common/include/softbus_errcode.h create mode 100644 core/common/include/softbus_json_utils.h create mode 100755 core/common/include/softbus_log.h create mode 100755 core/common/include/softbus_permission.h create mode 100755 core/common/include/softbus_property.h create mode 100644 core/common/include/softbus_type_def.h create mode 100644 core/common/include/softbus_utils.h create mode 100644 core/common/inner_communication/c/softbus_client_interface.c create mode 100644 core/common/inner_communication/c/softbus_client_interface_impl.c create mode 100755 core/common/inner_communication/c/softbus_server_interface.c create mode 100755 core/common/inner_communication/c/softbus_server_interface_impl.c create mode 100644 core/common/inner_communication/ipc/include/softbus_client_weak.h create mode 100644 core/common/inner_communication/ipc/include/softbus_server_weak.h create mode 100644 core/common/inner_communication/ipc/softbus_client_interface.c create mode 100755 core/common/inner_communication/ipc/softbus_client_interface_impl.c create mode 100644 core/common/inner_communication/ipc/softbus_client_weak.c create mode 100644 core/common/inner_communication/ipc/softbus_server_interface.c create mode 100644 core/common/inner_communication/ipc/softbus_server_interface_impl.c create mode 100644 core/common/inner_communication/ipc/softbus_server_weak.c create mode 100755 core/common/inner_communication/softbus_interface.h create mode 100755 core/common/json_utils/BUILD.gn create mode 100644 core/common/json_utils/softbus_json_utils.c create mode 100755 core/common/message_handler/BUILD.gn create mode 100755 core/common/message_handler/include/message_handler.h create mode 100755 core/common/message_handler/message_handler.c create mode 100755 core/common/security/BUILD.gn create mode 100644 core/common/security/mbedtls/softbus_crypto.c create mode 100755 core/common/security/permission/BUILD.gn create mode 100755 core/common/security/permission/common/permission_entry.c create mode 100755 core/common/security/permission/include/permission_entry.h create mode 100755 core/common/security/permission/include/permission_utils.h create mode 100755 core/common/security/permission/mini_system/softbus_permission.c create mode 100755 core/common/security/permission/permission.json create mode 100755 core/common/security/permission/small_system/softbus_permission.c create mode 100755 core/common/security/permission/standard_system/permission_utils.cpp create mode 100755 core/common/security/permission/standard_system/softbus_permission.cpp create mode 100755 core/common/security/sequence_verification/BUILD.gn create mode 100644 core/common/security/sequence_verification/include/softbus_sequence_verification.h create mode 100644 core/common/security/sequence_verification/src/softbus_sequence_verification.c create mode 100755 core/common/softbus_property/BUILD.gn create mode 100644 core/common/softbus_property/include/softbus_config.h create mode 100755 core/common/softbus_property/src/softbus_property.c create mode 100755 core/common/utils/BUILD.gn create mode 100755 core/common/utils/softbus_utils.c create mode 100644 core/connection/BUILD.gn create mode 100644 core/connection/br/BUILD.gn create mode 100644 core/connection/br/br_connection.c create mode 100755 core/connection/common/BUILD.gn create mode 100644 core/connection/common/include/softbus_thread_pool.h create mode 100755 core/connection/common/src/softbus_base_listener.c create mode 100755 core/connection/common/src/softbus_tcp_socket.c create mode 100755 core/connection/common/src/softbus_thread_pool.c create mode 100644 core/connection/interface/softbus_base_listener.h create mode 100755 core/connection/interface/softbus_conn_interface.h create mode 100644 core/connection/interface/softbus_tcp_socket.h create mode 100755 core/connection/manager/BUILD.gn create mode 100755 core/connection/manager/softbus_conn_manager.c create mode 100755 core/connection/manager/softbus_conn_manager.h create mode 100755 core/connection/manager/softbus_conn_manager_weak.c create mode 100755 core/connection/manager/softbus_conn_manager_weak.h create mode 100755 core/connection/tcp/BUILD.gn create mode 100644 core/connection/tcp/include/softbus_tcp_connect_manager.h create mode 100755 core/connection/tcp/src/softbus_tcp_connect_manager.c create mode 100755 core/discovery/BUILD.gn create mode 100755 core/discovery/coap/BUILD.gn create mode 100755 core/discovery/coap/include/disc_coap.h create mode 100755 core/discovery/coap/include/disc_nstackx_adapter.h create mode 100755 core/discovery/coap/src/disc_coap.c create mode 100755 core/discovery/coap/src/disc_nstackx_adapter.c create mode 100755 core/discovery/interface/disc_interface.h create mode 100755 core/discovery/manager/BUILD.gn create mode 100755 core/discovery/manager/include/disc_manager.h create mode 100755 core/discovery/manager/src/disc_manager.c create mode 100755 core/discovery/service/include/softbus_disc_server.h create mode 100755 core/discovery/service/src/softbus_disc_server.c create mode 100755 core/frame/lite/BUILD.gn create mode 100644 core/frame/lite/include/softbus_client_info_manager.h create mode 100644 core/frame/lite/include/softbus_server_frame.h create mode 100755 core/frame/lite/include/softbus_server_frame_weak.h create mode 100755 core/frame/lite/src/softbus_client_info_manager.c create mode 100644 core/frame/lite/src/softbus_server_frame.c create mode 100755 core/frame/lite/src/softbus_server_frame_weak.c create mode 100644 core/frame/lite/src/softbus_server_main.c create mode 100755 core/frame/standard/client/BUILD.gn create mode 100644 core/frame/standard/client/include/if_softbus_client.h create mode 100644 core/frame/standard/client/include/softbus_client_proxy.h create mode 100644 core/frame/standard/client/include/softbus_client_stub.h create mode 100644 core/frame/standard/client/src/if_softbus_client.cpp create mode 100755 core/frame/standard/client/src/softbus_client_proxy.cpp create mode 100755 core/frame/standard/client/src/softbus_client_stub.cpp create mode 100644 core/frame/standard/sa_profile/4700.xml create mode 100755 core/frame/standard/sa_profile/BUILD.gn create mode 100644 core/frame/standard/server/BUILD.gn create mode 100755 core/frame/standard/server/include/if_softbus_server.h create mode 100755 core/frame/standard/server/include/softbus_client_death_recipient.h create mode 100755 core/frame/standard/server/include/softbus_server.h create mode 100755 core/frame/standard/server/include/softbus_server_death_recipient.h create mode 100755 core/frame/standard/server/include/softbus_server_frame.h create mode 100755 core/frame/standard/server/include/softbus_server_proxy.h create mode 100755 core/frame/standard/server/include/softbus_server_stub.h create mode 100644 core/frame/standard/server/src/if_softbus_server.cpp create mode 100755 core/frame/standard/server/src/softbus_client_death_recipient.cpp create mode 100755 core/frame/standard/server/src/softbus_interface_client.cpp create mode 100755 core/frame/standard/server/src/softbus_interface_server.cpp create mode 100755 core/frame/standard/server/src/softbus_server.cpp create mode 100644 core/frame/standard/server/src/softbus_server.rc create mode 100755 core/frame/standard/server/src/softbus_server_death_recipient.cpp create mode 100755 core/frame/standard/server/src/softbus_server_frame.c create mode 100755 core/frame/standard/server/src/softbus_server_proxy.cpp create mode 100755 core/frame/standard/server/src/softbus_server_stub.cpp create mode 100755 core/transmission/BUILD.gn create mode 100755 core/transmission/common/BUILD.gn create mode 100755 core/transmission/common/include/softbus_app_info.h create mode 100755 core/transmission/common/include/softbus_message_open_channel.h create mode 100755 core/transmission/common/softbus_message_open_channel.c create mode 100644 core/transmission/interface/softbus_transmission_interface.h create mode 100755 core/transmission/pending_packet/BUILD.gn create mode 100755 core/transmission/pending_packet/include/trans_pending_pkt.h create mode 100755 core/transmission/pending_packet/src/trans_pending_pkt.c create mode 100755 core/transmission/session/BUILD.gn create mode 100644 core/transmission/session/include/trans_session_manager.h create mode 100755 core/transmission/session/src/trans_session_manager.c create mode 100755 core/transmission/trans_channel/BUILD.gn create mode 100644 core/transmission/trans_channel/manager/include/trans_channel_manager.h create mode 100755 core/transmission/trans_channel/manager/src/trans_channel_manager.c create mode 100755 core/transmission/trans_channel/proxy/BUILD.gn create mode 100644 core/transmission/trans_channel/proxy/include/softbus_proxychannel_control.h create mode 100755 core/transmission/trans_channel/proxy/include/softbus_proxychannel_listener.h create mode 100755 core/transmission/trans_channel/proxy/include/softbus_proxychannel_manager.h create mode 100755 core/transmission/trans_channel/proxy/include/softbus_proxychannel_message.h create mode 100644 core/transmission/trans_channel/proxy/include/softbus_proxychannel_network.h create mode 100644 core/transmission/trans_channel/proxy/include/softbus_proxychannel_session.h create mode 100755 core/transmission/trans_channel/proxy/include/softbus_proxychannel_transceiver.h create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_control.c create mode 100644 core/transmission/trans_channel/proxy/src/softbus_proxychannel_listener.c create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_manager.c create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_message.c create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_network.c create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_session.c create mode 100755 core/transmission/trans_channel/proxy/src/softbus_proxychannel_transceiver.c create mode 100755 core/transmission/trans_channel/tcp_direct/BUILD.gn create mode 100755 core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_listener.h create mode 100755 core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_manager.h create mode 100755 core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_message.h create mode 100755 core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_listener.c create mode 100755 core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_manager.c create mode 100644 core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_message.c create mode 100755 dsoftbus.gni create mode 100755 figures/dsoftbus-architecture.png create mode 100755 figures/dsoftbus-architecture_zh.png create mode 100644 interfaces/kits/bus_center/softbus_bus_center.h create mode 100644 interfaces/kits/common/softbus_common.h create mode 100755 interfaces/kits/discovery/discovery_service.h create mode 100644 interfaces/kits/transport/session.h create mode 100755 ohos.build create mode 100755 sdk/BUILD.gn create mode 100755 sdk/bus_center/BUILD.gn create mode 100644 sdk/bus_center/include/client_bus_center.h create mode 100644 sdk/bus_center/src/client_bus_center.c create mode 100755 sdk/discovery/BUILD.gn create mode 100755 sdk/discovery/include/client_disc_manager.h create mode 100755 sdk/discovery/src/client_disc_manager.c create mode 100755 sdk/frame/BUILD.gn create mode 100755 sdk/frame/include/softbus_client_event_manager.h create mode 100755 sdk/frame/include/softbus_client_frame_manager.h create mode 100755 sdk/frame/include/softbus_client_frame_manager_weak.h create mode 100755 sdk/frame/softbus_client_event_manager.c create mode 100755 sdk/frame/softbus_client_frame_manager.c create mode 100755 sdk/frame/softbus_client_frame_manager_weak.c create mode 100644 sdk/transmission/BUILD.gn create mode 100755 sdk/transmission/session/BUILD.gn create mode 100755 sdk/transmission/session/cpp/include/CommDefs.h create mode 100755 sdk/transmission/session/cpp/include/ISessionListener.h create mode 100755 sdk/transmission/session/cpp/include/ISessionService.h create mode 100755 sdk/transmission/session/cpp/include/Session.h create mode 100755 sdk/transmission/session/cpp/src/session_callback_mock.cpp create mode 100755 sdk/transmission/session/cpp/src/session_callback_mock.h create mode 100755 sdk/transmission/session/cpp/src/session_impl.cpp create mode 100755 sdk/transmission/session/cpp/src/session_impl.h create mode 100755 sdk/transmission/session/cpp/src/session_mock.cpp create mode 100755 sdk/transmission/session/cpp/src/session_mock.h create mode 100755 sdk/transmission/session/cpp/src/session_service_impl.cpp create mode 100755 sdk/transmission/session/cpp/src/session_service_impl.h create mode 100644 sdk/transmission/session/include/client_trans_message_service.h create mode 100644 sdk/transmission/session/include/client_trans_session_callback.h create mode 100644 sdk/transmission/session/include/client_trans_session_manager.h create mode 100644 sdk/transmission/session/include/client_trans_session_service.h create mode 100644 sdk/transmission/session/src/client_trans_message_service.c create mode 100755 sdk/transmission/session/src/client_trans_session_callback.c create mode 100755 sdk/transmission/session/src/client_trans_session_manager.c create mode 100644 sdk/transmission/session/src/client_trans_session_service.c create mode 100755 sdk/transmission/trans_channel/BUILD.gn create mode 100644 sdk/transmission/trans_channel/manager/include/client_trans_channel_callback.h create mode 100755 sdk/transmission/trans_channel/manager/include/client_trans_channel_callback_weak.h create mode 100644 sdk/transmission/trans_channel/manager/include/client_trans_channel_manager.h create mode 100755 sdk/transmission/trans_channel/manager/include/client_trans_channel_manager_weak.h create mode 100644 sdk/transmission/trans_channel/manager/src/client_trans_channel_callback.c create mode 100755 sdk/transmission/trans_channel/manager/src/client_trans_channel_callback_weak.c create mode 100644 sdk/transmission/trans_channel/manager/src/client_trans_channel_manager.c create mode 100755 sdk/transmission/trans_channel/manager/src/client_trans_channel_manager_weak.c create mode 100644 sdk/transmission/trans_channel/proxy/include/client_trans_proxy_manager.h create mode 100644 sdk/transmission/trans_channel/proxy/src/client_trans_proxy_manager.c create mode 100755 sdk/transmission/trans_channel/tcp_direct/BUILD.gn create mode 100755 sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_listener.h create mode 100755 sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_manager.h create mode 100755 sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_message.h create mode 100755 sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_listener.c create mode 100755 sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_manager.c create mode 100755 sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_message.c create mode 100755 tests/core/authentication/BUILD.gn create mode 100644 tests/core/authentication/unittest/auth_test.cpp create mode 100755 tests/core/bus_center/lnn/BUILD.gn create mode 100644 tests/core/bus_center/lnn/unittest/ledger_lane_hub_test.cpp create mode 100644 tests/core/bus_center/lnn/unittest/net_builder_test.cpp create mode 100755 tests/core/common/security/BUILD.gn create mode 100755 tests/core/common/security/softbus_permission_test.cpp create mode 100755 tests/core/common/security/softbus_permission_test.json create mode 100755 tests/core/connection/BUILD.gn create mode 100755 tests/core/connection/common/BUILD.gn create mode 100755 tests/core/connection/common/softbus_conn_common_test.cpp create mode 100755 tests/core/connection/manager/BUILD.gn create mode 100755 tests/core/connection/manager/connection_manager_test.cpp create mode 100755 tests/core/connection/tcp/BUILD.gn create mode 100755 tests/core/connection/tcp/tcp_manager_test.cpp create mode 100755 tests/core/discovery/manager/BUILD.gn create mode 100755 tests/core/discovery/manager/unittest/disc_manager_test.cpp create mode 100755 tests/core/transmission/trans_channel/tcp_direct/BUILD.gn create mode 100755 tests/core/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp create mode 100755 tests/sdk/bus_center/unittest/BUILD.gn create mode 100755 tests/sdk/bus_center/unittest/bus_center_sdk_test.cpp create mode 100755 tests/sdk/discovery/unittest/BUILD.gn create mode 100755 tests/sdk/discovery/unittest/disc_sdk_test.cpp create mode 100755 tests/sdk/transmission/trans_channel/tcp_direct/BUILD.gn create mode 100755 tests/sdk/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..51c63e295 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +*.tgz filter=lfs diff=lfs merge=lfs -text +*.trp filter=lfs diff=lfs merge=lfs -text +*.apk filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.asm filter=lfs diff=lfs merge=lfs -text +*.8svn filter=lfs diff=lfs merge=lfs -text +*.9svn filter=lfs diff=lfs merge=lfs -text +*.dylib filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text +*.a filter=lfs diff=lfs merge=lfs -text +*.so filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.dll filter=lfs diff=lfs merge=lfs -text diff --git a/BUILD.gn b/BUILD.gn new file mode 100755 index 000000000..3a14b0e9e --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_component("dsoftbus") { + features = [ + "core:softbus_server", + "sdk:softbus_client", + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..4a459866a --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/OAT.xml b/OAT.xml new file mode 100755 index 000000000..1586bc56e --- /dev/null +++ b/OAT.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index f754951bb..000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# communication_dsoftbus - -#### Description -DSoftBus capabilities, including discovery, networking, and transmission | 软总线发现、组网、传输功能实现 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md old mode 100644 new mode 100755 index e3bd566d7..a088e76b0 --- a/README.md +++ b/README.md @@ -1,37 +1,257 @@ -# communication_dsoftbus +# communication\_dsoftbus -#### 介绍 -DSoftBus capabilities, including discovery, networking, and transmission | 软总线发现、组网、传输功能实现 +- [Introduction](#section13587125816351) +- [Architecture](#section13587185873516) +- [Directory Structure](#section161941989596) +- [Constraints](#section119744591305) +- [Usage](#section1312121216216) + - [Usage Guidelines](#section1698318421816) -#### 软件架构 -软件架构说明 +- [Repositories Involved](#section1371113476307) + +## Introduction + +There are various communication modes \(such as Wi-Fi and Bluetooth\), and the usage of different communication modes varies greatly and often leads to problems. In addition, the convergence, sharing, and conflict of communication links cannot be handled. DSoftBus manages unified distributed communications between near-field devices and provides APIs for device discovery, connection, networking, and data transmission, regardless of the link type. It mainly provides the following capabilities: + +- Device discovery and connection in various communication modes, such as WLAN and Bluetooth +- Unified device networking and topology management, and device information provisioning for data transmission +- Channel setup for transmitting messages and bytes + +You can use the APIs provided by DSoftBus to implement fast communications between devices without caring about the communication details, thereby deploying and running services across platforms. + +## Architecture + +**Figure 1** DSoftBus architecture -#### 安装教程 +![](figures/dsoftbus-architecture.png) -1. xxxx -2. xxxx -3. xxxx +## Directory Structure -#### 使用说明 +The main code directory structure of DSoftBus is as follows: -1. xxxx -2. xxxx -3. xxxx +``` +/foundation/communication/dsoftbus +├── interfaces # APIs +├── core # Core code +│ ├── common # Common code +│ ├── adapter # Adaptation code +│ ├── authentication # Authentication code +│ ├── bus_center # Networking code +│ ├── connection # Connection code +│ ├── discovery # Discovery code +│ ├── transmission # Transmission code +│ └── frame # Framework code +├── sdk # Service process code +│ ├── bus_center # Networking code +│ ├── discovery # Discovery code +│ ├── transmission # Transmission code +│ └── frame # Framework code +└── components # Dependent component code +``` -#### 参与贡献 +## Constraints -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +- The devices between which you want to set up a connection must be in the same LAN. +- Before setting up a connection between two devices, you must bind the devices. For details about the binding process, see relevant descriptions in the Security subsystem readme file. +- A device can only be connected to another one device. + +## Usage + +### Usage Guidelines + +>**NOTICE:** +>To use RPC across devices, you must have the **ohos.permission.DISTRIBUTED\_DATASYNC** permission \(which is a dangerous one\). + +**1. Discovery** + +- **Publishing process** + +1. Publish a service of your application. + + ``` + // Callbacks for service publishing + typedef struct { + void (*OnPublishSuccess)(int publishId); // Called when the service is published successfully. + void (*OnPublishFail)(int publishId, PublishFailReason reason);// Called when the service fails to be published. + } IPublishCallback; + + // Publish the service. + int PublishService(const char *pkgName, const PublishInfo *info, const IPublishCallback *cb); + ``` + +2. Unpublish a service of your application. + + ``` + // Unpublish a service. + int UnPublishService(const char *pkgName, int publishId); + ``` -#### 特技 +- **Discovery process** -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +1. Discovery a specified device. + + ``` + // Callbacks for device discovery + typedef struct { + void (*OnDeviceFound)(const DeviceInfo *device); // Called when a device is found. + void (*OnDiscoverFailed)(int subscribeId, DiscoveryFailReason failReason); // Called when the discovery fails to start. + void (*OnDiscoverySuccess)(int subscribeId); // Called when the discovery starts successfully. + } IDiscoveryCallback; + + // Start a device discovery. + int StartDiscovery(const char *pkgName, const SubscribeInfo *info, const IDiscoveryCallback *cb); + ``` + +2. The DSoftBus notifies you of the device information via the callback once a device is found. +3. Stop the discovery as you need. + + ``` + // Stop the discovery. + int StopDiscovery(const char *pkgName, int subscribeId); + ``` + + +**2. Networking** + +1. Initiate a connection request with the address of the target device and the connection callback. + + ``` + // Address to connect to + typedef struct { + ConnectionAddrType type; + union { + struct BrAddr { + char brMac[BT_MAC_LEN]; + } br; + struct BleAddr { + char bleMac[BT_MAC_LEN]; + } ble; + struct IpAddr { + char ip[IP_STR_MAX_LEN]; + int port; + } ip; + } info; + } ConnectionAddr; + + // Address types + typedef enum { + CONNECTION_ADDR_WLAN = 0, + CONNECTION_ADDR_BR, + CONNECTION_ADDR_BLE, + CONNECTION_ADDR_ETH, + CONNECTION_ADDR_MAX + } ConnectionAddrType; + + // Callback for the connection result + typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode); + + // Initiate a connection request. + int32_t JoinLNN(ConnectionAddr *target, OnJoinLNNResult cb); + ``` + +2. Wait for the connection result. If **JoinLNN\(\)** returns success, the DSoftBus accepts the connection request and notifies you of the connection result through the callback. The **addr** parameter in the callback matches the **target** parameter in **JoinLNN\(\)**. If **retCode** in the callback is **0**, the connection is successful. In this case, the value of **networkId** is valid and will be used in the data transmission and disconnection APIs. If the value of **retCode** is not **0**, the connection fails, and the value of **networkId** is invalid. +3. Transmit data using transmission APIs. +4. Initiate a disconnection request with the **networkId** and the callback. + + ``` + // Callback for the disconnection result + typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode); + + // Initiate a disconnection request. + int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb); + ``` + +5. Wait until the disconnection is complete. The **networkId** parameter in **OnLeaveLNNResult\(\)** matches **networkId** in **LeaveLNN\(\)**. If **retCode** in the callback is **0**, the disconnection is successful; otherwise, the disconnection fails. If the disconnection is successful, **networkId** becomes invalid and can no longer be used. +6. Register and unregister callbacks for device state changes. + + ``` + // Device state events + #define EVENT_NODE_STATE_ONLINE 0x1 + #define EVENT_NODE_STATE_OFFLINE 0x02 + #define EVENT_NODE_STATE_INFO_CHANGED 0x04 + #define EVENT_NODE_STATE_MASK 0x07 + + // Device information + typedef struct { + char networkId[NETWORK_ID_BUF_LEN]; + char deviceName[DEVICE_NAME_BUF_LEN]; + uint8_t deviceTypeId; + } NodeBasicInfo; + + // Device state event callbacks + typedef struct { + uint32_t events; // Networking event mask + void (*onNodeOnline)(NodeBasicInfo *info); // Called when the device gets online. + void (*onNodeOffline)(NodeBasicInfo *info); // Called when the device gets offline. + void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // Called when the device information changes. + } INodeStateCb; + + // Register the callback for device state events. + int32_t RegNodeDeviceStateCb(INodeStateCb *callback); + + // Unregister the callback for device state events. + int32_t UnregNodeDeviceStateCb(INodeStateCb *callback); + ``` + + +**3. Transmission** + +1. Create a session server with a listener. You can use the listener to monitor events such as opening and closing a session, and receiving messages or bytes. + + ``` + // Callbacks for session management + typedef struct { + int (*OnSessionOpened)(int sessionId, int result); + void (*OnSessionClosed)(int sessionId); + void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen); + void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen); + } ISessionListener; + + // Create a session server. + int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener* listener); + ``` + +2. Open a session for sending and receiving data. + + ``` + // Open a session. + int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, const char *groupId, const SessionAttribute* attr); + ``` + +3. Send data to the peer device based on the session ID. + + ``` + // Send bytes. + int SendBytes(int sessionId, const void *data, unsigned int len); + // Send messages. + int SendMessage(int sessionId, const void *data, unsigned int len); + ``` + +4. Close a session with a specified ID. + + ``` + // Close a session. + void CloseSession(int sessionId); + ``` + +5. Remove the session server. + + ``` + // Remove the session server. + int RemoveSessionServer(const char *pkgName, const char *sessionName); + ``` + + +## Repositories Involved + +DSoftBus subsystem + +**communication_dsoftbus** + +communication_bluetooth + +communication_ipc + +communication_wifi diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 000000000..9d18527ba --- /dev/null +++ b/README_zh.md @@ -0,0 +1,257 @@ +# 分布式软总线组件 + +- [简介](#section13587125816351) +- [系统架构](#section13587185873516) +- [目录](#section161941989596) +- [约束](#section119744591305) +- [说明](#section1312121216216) + - [使用说明](#section1698318421816) + +- [相关仓](#section1371113476307) + +## 简介 + +由于设备通信方式多种多样\(WIFI、蓝牙等\),不同通信方式使用差异大,问题多。同时通信链路的融合共享和冲突无法处理。分布式软总线实现近场设备间统一的分布式通信能力管理,提供不区分链路的设备发现连接、组网和传输能力,主要包括如下: + +- 发现连接:提供基于Wifi、蓝牙等通信方式的设备发现连接能力。 +- 设备组网:提供统一的设备组网和拓扑管理能力,为数据传输提供已组网设备信息。 +- 数据传输:提供数据传输通道,支持消息、字节数据传输等能力。 + +业务方通过使用分布式软总线提供的API实现设备间高速通信,不用关心通信细节,进而实现业务平台部署与运行能力。 + +## 系统架构 + +**图 1** 分布式软总线组件架构图 + + +![](figures/dsoftbus-architecture_zh.png) + +## 目录 + +分布式软总线组件主要代码目录结构如下: + +``` +/foundation/communication/dsoftbus +├── interfaces # 接口代码 +├── core # 核心代码 +│ ├── common # 通用代码 +│ ├── adapter # 适配层代码 +│ ├── authentication # 认证代码 +│ ├── bus_center # 组网代码 +│ ├── connection # 连接代码 +│ ├── discovery # 发现代码 +│ ├── transmission # 传输代码 +│ └── frame # 框架代码 +├── sdk # 运行业务进程代码 +│ ├── bus_center # 组网代码 +│ ├── discovery # 发现代码 +│ ├── transmission # 传输代码 +│ └── frame # 框架代码 +└── components # 依赖组件代码 +``` + +## 约束 + +- 组网设备需在同一局域网中。 +- 组网之前,需先完成设备绑定,绑定流程参见安全子系统中说明。 +- 只能和一个设备进行组网。 + +## 说明 + +### 使用说明 + +>**须知:** +>使用跨设备通信时,必须添加权限ohos.permission.DISTRIBUTED\_DATASYNC,该权限类型为dangerous。 + +**1、发现** + +- **发布流程** + +1. 上层应用需要对外发布自身能力时,调用服务发布接口发布自身能力。 + + ``` + // 发布回调 + typedef struct { + void (*OnPublishSuccess)(int publishId); //发布成功时回调 + void (*OnPublishFail)(int publishId, PublishFailReason reason);//发布失败时回调 + } IPublishCallback; + + // 发布服务 + int PublishService(const char *pkgName, const PublishInfo *info, const IPublishCallback *cb); + ``` + +2. 上层应用不再需要对外发布自身能力时,调用UnpublishService接口注销服务。 + + ``` + // 注销服务 + int UnPublishService(const char *pkgName, int publishId); + ``` + + +- **发现流程** + +1. 上层应用需要发现特定能力设备时,调用发现接口启动发现。 + + ``` + // 发现回调 + typedef struct { + void (*OnDeviceFound)(const DeviceInfo *device); //发现设备回调 + void (*OnDiscoverFailed)(int subscribeId, DiscoveryFailReason failReason); //启动发现失败回调 + void (*OnDiscoverySuccess)(int subscribeId); //启动发现成功回调 + } IDiscoveryCallback; + + // 发现服务 + int StartDiscovery(const char *pkgName, const SubscribeInfo *info, const IDiscoveryCallback *cb); + ``` + +2. 软总线发现到设备时,通过回调接口通知业务发现的设备信息。 +3. 上层应用不再需要发现时,调用StopDiscovery接口停止设备发现。 + + ``` + // 停止服务 + int StopDiscovery(const char *pkgName, int subscribeId); + ``` + + +**2、组网** + +1. 发起组网请求,携带组网连接地址信息,并且提供组网执行结果回调函数。 + + ``` + // 组网连接地址 + typedef struct { + ConnectionAddrType type; + union { + struct BrAddr { + char brMac[BT_MAC_LEN]; + } br; + struct BleAddr { + char bleMac[BT_MAC_LEN]; + } ble; + struct IpAddr { + char ip[IP_STR_MAX_LEN]; + int port; + } ip; + } info; + } ConnectionAddr; + + // 组网连接地址类型 + typedef enum { + CONNECTION_ADDR_WLAN = 0, + CONNECTION_ADDR_BR, + CONNECTION_ADDR_BLE, + CONNECTION_ADDR_ETH, + CONNECTION_ADDR_MAX + } ConnectionAddrType; + + // 组网请求执行结果回调 + typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode); + + // 发起组网请求 + int32_t JoinLNN(ConnectionAddr *target, OnJoinLNNResult cb); + ``` + +2. 等待组网结果,JoinLNN\(\)返回成功表示软总线接受了组网请求,组网结果通过回调函数通知业务;组网回调函数中addr参数内容和JoinLNN\(\)的入参互相匹配;retCode如果为0,表示组网成功,此时networkId为有效值,后续传输、退网等接口均需使用该参数;retCode如果不为0,表示组网失败,此时networkId为无效值。 +3. 使用传输相关接口进行数据传输。 +4. 发送退网请求,携带组网成功后返回的networkId,并且提供退网执行结果回调。 + + ``` + // 退网执行结果回调 + typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode); + + // 退网请求 + int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb); + ``` + +5. 等待退网完成,OnLeaveLNNResult\(\)的networkId和退网请求接口中的networkId互相匹配;retCode为0表示退网成功,否则退网失败。退网成功后,networkId变为无效值,后续不应该被继续使用。 +6. 使用节点(即设备)注册和注销接口,监听网络中节点状态变化等事件。 + + ``` + // 事件掩码 + #define EVENT_NODE_STATE_ONLINE 0x1 + #define EVENT_NODE_STATE_OFFLINE 0x02 + #define EVENT_NODE_STATE_INFO_CHANGED 0x04 + #define EVENT_NODE_STATE_MASK 0x07 + + // 节点信息 + typedef struct { + char networkId[NETWORK_ID_BUF_LEN]; + char deviceName[DEVICE_NAME_BUF_LEN]; + uint8_t deviceTypeId; + } NodeBasicInfo; + + // 节点状态事件回调 + typedef struct { + uint32_t events; // 组网事件掩码 + void (*onNodeOnline)(NodeBasicInfo *info); // 节点上线事件回调 + void (*onNodeOffline)(NodeBasicInfo *info); // 节点下线事件回调 + void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // 节点信息变化事件回调 + } INodeStateCb; + + // 注册节点状态事件回调 + int32_t RegNodeDeviceStateCb(INodeStateCb *callback); + + // 注销节点状态事件回调 + int32_t UnregNodeDeviceStateCb(INodeStateCb *callback); + ``` + + +**3、传输** + +1. 创建会话服务,并设置会话相关回调,用户可在回调中处理打开/关闭和消息接收事件。 + + ``` + // 会话管理回调 + typedef struct { + int (*OnSessionOpened)(int sessionId, int result); + void (*OnSessionClosed)(int sessionId); + void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen); + void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen); + } ISessionListener; + + // 创建会话服务 + int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener* listener); + ``` + +2. 创建会话 ,用于收发数据。 + + ``` + // 创建会话 + int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, const char *groupId, const SessionAttribute* attr); + ``` + +3. 通过sessionId向对端设备发送数据。 + + ``` + // 发送字节数据 + int SendBytes(int sessionId, const void *data, unsigned int len); + // 发送消息数据 + int SendMessage(int sessionId, const void *data, unsigned int len); + ``` + +4. 通过sessionId关闭会话。 + + ``` + // 关闭会话 + void CloseSession(int sessionId); + ``` + +5. 删除会话服务。 + + ``` + // 删除会话服务 + int RemoveSessionServer(const char *pkgName, const char *sessionName); + ``` + + +## 相关仓 + +分布式软总线子系统 + +**communication_dsoftbus** + +communication_bluetooth + +communication_ipc + +communication_wifi diff --git a/components/mbedtls/BUILD.gn b/components/mbedtls/BUILD.gn new file mode 100755 index 000000000..62c8bb2a2 --- /dev/null +++ b/components/mbedtls/BUILD.gn @@ -0,0 +1,114 @@ +# +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import("//build/ohos.gni") +library = "//third_party/mbedtls/library" + +mbedtls_sources = [] +mbedtls_sources += [ + "$library/aes.c", + "$library/aesni.c", + "$library/arc4.c", + "$library/aria.c", + "$library/asn1parse.c", + "$library/asn1write.c", + "$library/base64.c", + "$library/bignum.c", + "$library/blowfish.c", + "$library/camellia.c", + "$library/ccm.c", + "$library/chacha20.c", + "$library/chachapoly.c", + "$library/cipher.c", + "$library/cipher_wrap.c", + "$library/cmac.c", + "$library/ctr_drbg.c", + "$library/des.c", + "$library/dhm.c", + "$library/ecdh.c", + "$library/ecdsa.c", + "$library/ecjpake.c", + "$library/ecp.c", + "$library/ecp_curves.c", + "$library/entropy.c", + "$library/entropy_poll.c", + "$library/error.c", + "$library/gcm.c", + "$library/havege.c", + "$library/hkdf.c", + "$library/hmac_drbg.c", + "$library/md.c", + "$library/md2.c", + "$library/md4.c", + "$library/md5.c", + "$library/md_wrap.c", + "$library/memory_buffer_alloc.c", + "$library/net_sockets.c", + "$library/nist_kw.c", + "$library/oid.c", + "$library/padlock.c", + "$library/pem.c", + "$library/pk.c", + "$library/pk_wrap.c", + "$library/pkcs12.c", + "$library/pkcs5.c", + "$library/pkparse.c", + "$library/pkwrite.c", + "$library/platform.c", + "$library/platform_util.c", + "$library/poly1305.c", + "$library/ripemd160.c", + "$library/rsa.c", + "$library/rsa_internal.c", + "$library/sha1.c", + "$library/sha256.c", + "$library/sha512.c", + "$library/ssl_ciphersuites.c", + "$library/ssl_cli.c", + "$library/ssl_tls.c", + "$library/threading.c", + "$library/timing.c", + "$library/version.c", + "$library/version_features.c", + "$library/x509.c", + "$library/x509_crl.c", + "$library/x509_crt.c", + "$library/xtea.c", +] + +config("mbedtls_config") { + include_dirs = [ "//third_party/mbedtls/include" ] + + cflags = [ "-Wno-error" ] +} + +ohos_shared_library("mbedtls_shared") { + sources = mbedtls_sources + output_name = "mbedtls" + public_configs = [ ":mbedtls_config" ] + + part_name = "dsoftbus_standard" + subsystem_name = "communication" +} + +static_library("mbedtls_static") { + sources = mbedtls_sources + output_name = "mbedtls" + public_configs = [ ":mbedtls_config" ] +} + +group("mbedtls") { + deps = [ ":mbedtls_shared" ] +} diff --git a/components/nstackx/nstackx_ctrl/BUILD.gn b/components/nstackx/nstackx_ctrl/BUILD.gn new file mode 100755 index 000000000..c3cbd97ba --- /dev/null +++ b/components/nstackx/nstackx_ctrl/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (defined(ohos_lite)) { + import("//build/lite/config/component/lite_component.gni") +} else { + import("//build/ohos.gni") + + config("dfinder_interface") { + include_dirs = [ "interface" ] + } + ohos_shared_library("nstackx_ctrl") { + sources = [ + "core/coap_discover/coap_app.c", + "core/coap_discover/coap_client.c", + "core/coap_discover/coap_discover.c", + "core/coap_discover/json_payload.c", + "core/nstackx_common.c", + "core/nstackx_database.c", + "core/nstackx_device.c", + "core/nstackx_smartgenius.c", + ] + include_dirs = [ + "//third_party/libcoap/include/coap2", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + "include", + "include/coap_discover", + "../nstackx_util/interface", + "../nstackx_util/platform/unix", + ] + public_configs = [ ":dfinder_interface" ] + deps = [ + "../nstackx_util:nstackx_util", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + "//third_party/libcoap:libcoap", + ] + defines = [ "SUPPORT_SMARTGENIUS" ] + subsystem_name = "communication" + part_name = "dsoftbus_standard" + } +} diff --git a/components/nstackx/nstackx_ctrl/core/coap_discover/coap_app.c b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_app.c new file mode 100644 index 000000000..adc8ebc70 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_app.c @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "coap_app.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "coap.h" +#include "coap_client.h" +#include "coap_discover.h" +#include "nstackx_util.h" +#include "nstackx_device.h" +#include "nstackx_epoll.h" +#include "nstackx_error.h" +#include "nstackx_log.h" + +#define TAG "nStackXCoAP" + +#define DEFAULT_COAP_TIMEOUT (COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND) +#define MAX_COAP_SOCKET_NUM 64 + +static coap_context_t *g_ctx = NULL; +static EpollTask g_taskList[MAX_COAP_SOCKET_NUM] = {0}; +static uint32_t g_socketNum = 0; +static uint8_t g_ctxSocketErrFlag = NSTACKX_FALSE; + +static coap_context_t *g_p2pCtx = NULL; +static EpollTask g_p2pTaskList[MAX_COAP_SOCKET_NUM] = {0}; +static uint32_t g_p2pSocketNum = 0; +static uint8_t g_p2pCtxSocketErrFlag = NSTACKX_FALSE; + +static coap_context_t *g_usbCtx = NULL; +static EpollTask g_usbTaskList[MAX_COAP_SOCKET_NUM] = {0}; +static uint32_t g_usbSocketNum = 0; +static uint8_t g_usbCtxSocketErrFlag = NSTACKX_FALSE; + +typedef enum { + SOCKET_READ_EVENT = 0, + SOCKET_WRITE_EVENT, + SOCKET_ERROR_EVENT, + SOCKET_END_EVENT +} SocketEventType; +static uint64_t g_socketEventNum[SOCKET_END_EVENT]; + +static void CoAPEpollReadHandle(void *data) +{ + if (data == NULL) { + return; + } + EpollTask *task = (EpollTask*)data; + if (task->taskfd < 0) { + return; + } + coap_socket_t *socket = task->ptr; + + if (socket->flags & COAP_SOCKET_WANT_READ) { + socket->flags |= COAP_SOCKET_CAN_READ; + } + + if (socket->flags & COAP_SOCKET_WANT_ACCEPT) { + socket->flags |= COAP_SOCKET_CAN_ACCEPT; + } + g_socketEventNum[SOCKET_READ_EVENT]++; +} + +static void CoAPEpollWriteHandle(void *data) +{ + if (data == NULL) { + return; + } + EpollTask *task = data; + if (task->taskfd < 0) { + return; + } + coap_socket_t *socket = task->ptr; + + if (socket->flags & COAP_SOCKET_WANT_WRITE) { + socket->flags |= COAP_SOCKET_CAN_WRITE; + } + + if (socket->flags & COAP_SOCKET_WANT_CONNECT) { + socket->flags |= COAP_SOCKET_CAN_CONNECT; + } + g_socketEventNum[SOCKET_WRITE_EVENT]++; +} + +static void CoAPEpollErrorHandle(void *data) +{ + if (data == NULL) { + return; + } + EpollTask *task = data; + if (task->taskfd < 0) { + return; + } + coap_socket_t *socket = task->ptr; + g_socketEventNum[SOCKET_ERROR_EVENT]++; + if (IsCoapCtxEndpointSocket(g_ctx, socket->fd)) { + LOGE(TAG, "error of g_ctx's socket occurred"); + g_ctxSocketErrFlag = NSTACKX_TRUE; + return; + } + + if (IsCoapCtxEndpointSocket(g_p2pCtx, socket->fd)) { + LOGE(TAG, "error of g_p2pCtx's socket occurred"); + g_p2pCtxSocketErrFlag = NSTACKX_TRUE; + return; + } + + if (IsCoapCtxEndpointSocket(g_usbCtx, socket->fd)) { + LOGE(TAG, "error of g_usbCtx's socket occurred"); + g_usbCtxSocketErrFlag = NSTACKX_TRUE; + return; + } + + LOGE(TAG, "coap session socket error occurred and close it"); + DeRegisterEpollTask(task); + CloseDesc(socket->fd); + socket->fd = -1; + task->taskfd = -1; +} + +uint32_t RegisterCoAPEpollTask(EpollDesc epollfd) +{ + uint32_t timeoutWlan, timeoutP2p, timeoutUsb, minTimeout; + + if ((g_ctx == NULL) && (g_p2pCtx == NULL) && (g_usbCtx == NULL)) { + return DEFAULT_COAP_TIMEOUT; + } + + timeoutWlan = GetTimeout(g_ctx, &g_socketNum, g_taskList, epollfd); + timeoutP2p = GetTimeout(g_p2pCtx, &g_p2pSocketNum, g_p2pTaskList, epollfd); + timeoutUsb = GetTimeout(g_usbCtx, &g_usbSocketNum, g_usbTaskList, epollfd); + if (timeoutWlan == DEFAULT_COAP_TIMEOUT && + timeoutP2p == DEFAULT_COAP_TIMEOUT && + timeoutUsb == DEFAULT_COAP_TIMEOUT) { + return DEFAULT_COAP_TIMEOUT; + } else { + minTimeout = (timeoutWlan < timeoutP2p) ? timeoutWlan : timeoutP2p; + return (minTimeout < timeoutUsb) ? minTimeout : timeoutUsb; + } +} + +uint32_t GetTimeout(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList, EpollDesc epollfd) +{ + uint32_t events; + coap_tick_t now; + uint32_t i; + uint32_t timeout; + coap_socket_t *sockets[MAX_COAP_SOCKET_NUM] = {0}; + + if (ctx == NULL) { + return DEFAULT_COAP_TIMEOUT; + } + + coap_ticks(&now); + timeout = coap_write(ctx, sockets, + (uint32_t)(sizeof(sockets) / sizeof(sockets[0])), socketNum, now); + if (timeout == 0 || timeout > DEFAULT_COAP_TIMEOUT) { + timeout = DEFAULT_COAP_TIMEOUT; + } + if (*socketNum > MAX_COAP_SOCKET_NUM) { + *socketNum = MAX_COAP_SOCKET_NUM; + LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM"); + } + for (i = 0; i < *socketNum; i++) { + events = 0; + if ((sockets[i]->flags & COAP_SOCKET_WANT_READ) || (sockets[i]->flags & COAP_SOCKET_WANT_ACCEPT)) { + events = EPOLLIN; + } + if ((sockets[i]->flags & COAP_SOCKET_WANT_WRITE) || (sockets[i]->flags & COAP_SOCKET_WANT_CONNECT)) { + events = events | EPOLLOUT; + } + if (sockets[i]->flags & COAP_SOCKET_WANT_CONNECT) { + events = events | EPOLLHUP | EPOLLERR; + } + taskList[i].taskfd = sockets[i]->fd; + taskList[i].epollfd = epollfd; + taskList[i].readHandle = CoAPEpollReadHandle; + taskList[i].writeHandle = CoAPEpollWriteHandle; + taskList[i].errorHandle = CoAPEpollErrorHandle; + taskList[i].ptr = sockets[i]; + if (taskList[i].taskfd < 0) { + continue; + } + RegisterEpollTask(&taskList[i], events); + } + + return timeout; +} + +void DeRegisterCoAPEpollTask(void) +{ + if (g_ctxSocketErrFlag) { + LOGI(TAG, "error of g_ctx's socket occurred and destroy g_ctx"); + g_ctxSocketErrFlag = NSTACKX_FALSE; + NotifyDFinderMsgRecver(DFINDER_ON_INNER_ERROR); + } else { + DeRegisteCoAPEpollTaskCtx(g_ctx, &g_socketNum, g_taskList); + } + if (g_p2pCtxSocketErrFlag) { + LOGI(TAG, "error of g_p2pctx's socket occurred and destroy g_ctx"); + CoapP2pServerDestroy(); + } else { + DeRegisteCoAPEpollTaskCtx(g_p2pCtx, &g_p2pSocketNum, g_p2pTaskList); + } + + if (g_usbCtxSocketErrFlag) { + LOGI(TAG, "error of g_usbCtx's socket occurred and destroy g_ctx"); + CoapUsbServerDestroy(); + } else { + DeRegisteCoAPEpollTaskCtx(g_usbCtx, &g_usbSocketNum, g_usbTaskList); + } +} + +void DeRegisteCoAPEpollTaskCtx(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList) +{ + coap_tick_t now; + uint32_t i; + + if (ctx == NULL) { + return; + } + + if (*socketNum > MAX_COAP_SOCKET_NUM) { + *socketNum = MAX_COAP_SOCKET_NUM; + LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM"); + } + + for (i = 0; i < *socketNum; i++) { + if (taskList[i].taskfd < 0) { + continue; + } + DeRegisterEpollTask(&taskList[i]); + } + *socketNum = 0; + + coap_ticks(&now); + coap_read(ctx, now); +} + +int32_t CoapServerInit(const struct in_addr *ip) +{ + LOGD(TAG, "CoapServerInit is called"); + + char addrStr[NI_MAXHOST] = COAP_SRV_DEFAULT_ADDR; + char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT; + + if (!IsWifiApConnected()) { + LOGD(TAG, "wifi not connected"); + return NSTACKX_EOK; + } + + if (g_ctx != NULL) { + LOGI(TAG, "coap server need to change"); + CoapServerDestroy(); + } + + coap_startup(); + g_ctx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip); + if (g_ctx == NULL) { + LOGE(TAG, "coap init get context failed"); + return NSTACKX_EFAILED; + } + + CoapInitResources(g_ctx, SERVER_TYPE_WLANORETH); + coap_register_response_handler(g_ctx, CoapMessageHandler); + + return NSTACKX_EOK; +} + +int32_t CoapP2pServerInit(const struct in_addr *ip) +{ + LOGD(TAG, "CoapP2pServerInit is called"); + + char addrStr[NI_MAXHOST] = {0}; + char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT; + + if (g_p2pCtx != NULL) { + LOGI(TAG, "coap p2p server init has finished"); + return NSTACKX_EOK; + } + + if (ip == NULL) { + return NSTACKX_EFAILED; + } + + if (inet_ntop(AF_INET, ip, addrStr, NI_MAXHOST) == NULL) { + LOGE(TAG, "inet_ntop failed"); + return NSTACKX_EFAILED; + } + + coap_startup(); + g_p2pCtx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip); + if (g_p2pCtx == NULL) { + LOGE(TAG, "coap p2p init get context failed"); + return NSTACKX_EFAILED; + } + + /* if g_p2pCtx has been created, update the g_p2pIp */ + SetP2pIp(ip); + CoapInitResources(g_p2pCtx, SERVER_TYPE_P2P); + coap_register_response_handler(g_p2pCtx, CoapMessageHandler); + return NSTACKX_EOK; +} + +int32_t CoapUsbServerInit(const struct in_addr *ip) +{ + LOGD(TAG, "CoapUsbServerInit is called"); + + char addrStr[NI_MAXHOST] = {0}; + char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT; + + if (g_usbCtx != NULL) { + LOGI(TAG, "coap usb server init has finished"); + return NSTACKX_EOK; + } + + if (ip == NULL) { + return NSTACKX_EFAILED; + } + + if (inet_ntop(AF_INET, ip, addrStr, NI_MAXHOST) == NULL) { + LOGE(TAG, "inet_ntop failed"); + return NSTACKX_EFAILED; + } + + coap_startup(); + g_usbCtx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip); + if (g_usbCtx == NULL) { + LOGE(TAG, "coap usb init get context failed"); + return NSTACKX_EFAILED; + } + SetUsbIp(ip); + + CoapInitResources(g_usbCtx, SERVER_TYPE_USB); + coap_register_response_handler(g_usbCtx, CoapMessageHandler); + + return NSTACKX_EOK; +} + +void CoapServerDestroy(void) +{ + LOGD(TAG, "CoapServerDestroy is called"); + + uint32_t i; + g_ctxSocketErrFlag = NSTACKX_FALSE; + if (g_ctx == NULL) { + return; + } + for (i = 0; i < g_socketNum && i < MAX_COAP_SOCKET_NUM; i++) { + if (g_taskList[i].taskfd < 0) { + continue; + } + DeRegisterEpollTask(&g_taskList[i]); + } + g_socketNum = 0; + + coap_free_context(g_ctx); + g_ctx = NULL; + CoapDestroyCtx(SERVER_TYPE_WLANORETH); +} + +void CoapP2pServerDestroy(void) +{ + LOGD(TAG, "CoapP2pServerDestroy is called"); + + uint32_t i; + g_p2pCtxSocketErrFlag = NSTACKX_FALSE; + if (g_p2pCtx == NULL) { + return; + } + + if (g_p2pSocketNum > MAX_COAP_SOCKET_NUM) { + g_p2pSocketNum = MAX_COAP_SOCKET_NUM; + LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM"); + } + + for (i = 0; i < g_p2pSocketNum; i++) { + if (g_p2pTaskList[i].taskfd < 0) { + continue; + } + DeRegisterEpollTask(&g_p2pTaskList[i]); + } + g_p2pSocketNum = 0; + + coap_free_context(g_p2pCtx); + g_p2pCtx = NULL; + CoapDestroyCtx(SERVER_TYPE_P2P); +} + +void CoapUsbServerDestroy(void) +{ + LOGD(TAG, "CoapUsbServerDestroy is called"); + + uint32_t i; + g_usbCtxSocketErrFlag = NSTACKX_FALSE; + if (g_usbCtx == NULL) { + return; + } + + if (g_usbSocketNum > MAX_COAP_SOCKET_NUM) { + g_usbSocketNum = MAX_COAP_SOCKET_NUM; + LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM"); + } + + for (i = 0; i < g_usbSocketNum; i++) { + if (g_usbTaskList[i].taskfd < 0) { + continue; + } + DeRegisterEpollTask(&g_usbTaskList[i]); + } + g_usbSocketNum = 0; + + coap_free_context(g_usbCtx); + g_usbCtx = NULL; + CoapDestroyCtx(SERVER_TYPE_USB); +} + +void ResetCoapSocketTaskCount(uint8_t isBusy) +{ + uint64_t totalTaskCount = 0; + uint64_t totalP2pTaskCount = 0; + uint64_t totalUsbTaskCount = 0; + for (uint32_t i = 0; i < g_socketNum && i < MAX_COAP_SOCKET_NUM; i++) { + if (totalTaskCount < UINT64_MAX && g_taskList[i].count <= UINT64_MAX - totalTaskCount) { + totalTaskCount += g_taskList[i].count; + } + g_taskList[i].count = 0; + } + for (uint32_t i = 0; i < g_p2pSocketNum && i < MAX_COAP_SOCKET_NUM; i++) { + if (totalP2pTaskCount < UINT64_MAX && g_p2pTaskList[i].count <= UINT64_MAX - totalP2pTaskCount) { + totalP2pTaskCount += g_p2pTaskList[i].count; + } + g_p2pTaskList[i].count = 0; + } + for (uint32_t i = 0; i < g_usbSocketNum && i < MAX_COAP_SOCKET_NUM; i++) { + if (totalUsbTaskCount < UINT64_MAX && g_usbTaskList[i].count <= UINT64_MAX - totalUsbTaskCount) { + totalUsbTaskCount += g_usbTaskList[i].count; + } + g_usbTaskList[i].count = 0; + } + if (isBusy) { + LOGI(TAG, "in this busy interval, socket task count: wifi %llu, p2p %llu, usb %llu," + "read %llu, write %llu, error %llu", + totalTaskCount, totalP2pTaskCount, totalUsbTaskCount, + g_socketEventNum[SOCKET_READ_EVENT], + g_socketEventNum[SOCKET_WRITE_EVENT], g_socketEventNum[SOCKET_ERROR_EVENT]); + } + (void)memset_s(g_socketEventNum, sizeof(g_socketEventNum), 0, sizeof(g_socketEventNum)); +} diff --git a/components/nstackx/nstackx_ctrl/core/coap_discover/coap_client.c b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_client.c new file mode 100644 index 000000000..3c34941c2 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_client.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "coap_client.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "coap_session_internal.h" +#include "nstackx_device.h" +#include "nstackx_error.h" +#include "nstackx_log.h" +#include "nstackx_util.h" +#include "utlist.h" + +#define TAG "nStackXCoAP" + +#define FLAGS_BLOCK 0x01 +#define DEFAULT_COAP_BUFFER_LENGTH 256 +#define COAP_CODE_RIGHT_PART_LENGTH 5 +#define COAP_CERT_CHAIN_DEPTH 2 + +/* + * the initial timeout will be set to a random duration between COAP_ACK_TIMEOUT and + * (COAP_ACK_TIMEOUT * COAP_ACK_RANDOM_FACTOR). + */ +#define COAP_ACK_TIMEOUT ((coap_fixed_point_t){1, 0}) // 1 seconds +#define COAP_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1, 200}) // 1.2 + +/* Request URI. + * associate the resources with transaction id and make it expireable + */ +coap_uri_t g_uri; + +int32_t CoapResolveAddress(const coap_str_const_t *server, struct sockaddr *dst) +{ + struct addrinfo *res = NULL; + struct addrinfo *ainfo = NULL; + struct addrinfo hints; + char addrstr[DEFAULT_COAP_BUFFER_LENGTH]; /* Get a char array with length 256 to save host name. */ + int error; + int32_t len = -1; + + (void)memset_s(addrstr, sizeof(addrstr), 0, sizeof(addrstr)); + if (server->length) { + if (memcpy_s(addrstr, sizeof(addrstr), server->s, server->length) != EOK) { + LOGD(TAG, "addrstr copy error"); + return len; + } + } else { + if (memcpy_s(addrstr, sizeof(addrstr), "localhost", strlen("localhost")) != EOK) { + LOGD(TAG, "addrstr copy error"); + return len; + } + } + + (void)memset_s((char *)&hints, sizeof(hints), 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_family = AF_UNSPEC; + + error = getaddrinfo(addrstr, NULL, &hints, &res); + if (error != 0) { + LOGE(TAG, "getaddrinfo error"); + return error; + } + + for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { + switch (ainfo->ai_family) { + case AF_INET6: + /* fall-through */ + case AF_INET: + len = ainfo->ai_addrlen; + if (memcpy_s(dst, sizeof(struct sockaddr), ainfo->ai_addr, len) != EOK) { + LOGE(TAG, "ai_addr copy error"); + len = -1; + break; + } + goto finish; + default: + break; + } + } + +finish: + freeaddrinfo(res); + return len; +} + +void CoapMessageHandler(struct coap_context_t *ctx, + coap_session_t *session, + coap_pdu_t *sent, + coap_pdu_t *received, + const coap_tid_t id) +{ + if (received == NULL) { + LOGE(TAG, "received error"); + return; + } + (void)ctx; + (void)session; + (void)sent; + (void)id; + coap_opt_t *blockOpt1 = NULL; + coap_opt_t *blockOpt2 = NULL; + coap_opt_iterator_t optIter; + + (void)memset_s(&optIter, sizeof(optIter), 0, sizeof(optIter)); + if (received->type == COAP_MESSAGE_RST) { + LOGD(TAG, "got RST"); + return; + } + + if (coap_check_option(received, COAP_OPTION_OBSERVE, &optIter)) { + LOGE(TAG, "observe not support."); + return; + } + blockOpt2 = coap_check_option(received, COAP_OPTION_BLOCK2, &optIter); + blockOpt1 = coap_check_option(received, COAP_OPTION_BLOCK1, &optIter); + if ((blockOpt1 != NULL) || (blockOpt2 != NULL)) { + LOGE(TAG, "block not support."); + return; + } + + LOGD(TAG, "%u.%02u", (received->code >> COAP_CODE_RIGHT_PART_LENGTH), received->code & 0x1F); +} + +static void InitAddrinfo(struct addrinfo *hints) +{ + if (hints == NULL) { + return; + } + (void)memset_s(hints, sizeof(struct addrinfo), 0, sizeof(struct addrinfo)); + hints->ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints->ai_socktype = SOCK_DGRAM; /* Coap uses UDP */ + hints->ai_flags = AI_PASSIVE | AI_NUMERICHOST; +} + +coap_context_t *CoapGetContext(const char *node, const char *port, uint8_t needBind, const struct in_addr *ip) +{ + struct addrinfo hints; + struct addrinfo *result = NULL; + struct addrinfo *rp = NULL; + coap_endpoint_t *ep = NULL; + coap_context_t *ctx = coap_new_context(NULL); + if (ctx == NULL) { + return NULL; + } + InitAddrinfo(&hints); + + if (getaddrinfo(node, port, &hints, &result) != 0) { + coap_free_context(ctx); + return NULL; + } + coap_address_t addr; + /* iterate through results until success */ + for (rp = result; rp != NULL; rp = rp->ai_next) { + if (rp->ai_addrlen > (socklen_t)sizeof(addr.addr)) { + continue; + } + + coap_address_init(&addr); + addr.size = rp->ai_addrlen; + if (memcpy_s(&addr.addr, sizeof(addr.addr), rp->ai_addr, rp->ai_addrlen) != EOK || + (addr.addr.sa.sa_family != AF_INET && addr.addr.sa.sa_family != AF_INET6)) { + continue; + } + + ep = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP); + if (ep != NULL) { + struct sockaddr_in sockIp; + struct sockaddr_in *sockIpPtr = NULL; + (void)memset_s(&sockIp, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in)); + if (ip != NULL && needBind) { + (void)memcpy_s(&sockIp.sin_addr, sizeof(struct in_addr), ip, sizeof(struct in_addr)); + sockIpPtr = &sockIp; + } + if (needBind && BindToDevice(ep->sock.fd, sockIpPtr) != NSTACKX_EOK) { + LOGE(TAG, "bind to device fail"); + } + } else { + LOGE(TAG, "coap_new_endpoint get null"); + coap_free_context(ctx); + ctx = NULL; + } + break; + } + freeaddrinfo(result); + return ctx; +} + +static coap_session_t *CoapGetSessionInner(struct addrinfo *result, coap_context_t *ctx, + const CoapServerParameter *coapServerParameter) +{ + coap_session_t *session = NULL; + struct addrinfo *rp = NULL; + coap_proto_t proto = coapServerParameter->proto; + const coap_address_t *dst = coapServerParameter->dst; + + if (proto != COAP_PROTO_UDP) { + LOGE(TAG, "unsupported proto"); + return NULL; + } + + for (rp = result; rp != NULL; rp = rp->ai_next) { + coap_address_t bindAddr; + if (rp->ai_addrlen > (socklen_t)sizeof(bindAddr.addr)) { + continue; + } + coap_address_init(&bindAddr); + bindAddr.size = rp->ai_addrlen; + if (memcpy_s(&bindAddr.addr, sizeof(bindAddr.addr), rp->ai_addr, rp->ai_addrlen) != EOK) { + LOGE(TAG, "ai_addr copy error"); + continue; + } + session = coap_new_client_session(ctx, &bindAddr, dst, proto); + if (session != NULL) { + break; + } + } + return session; +} + +static void CoapSetAckTimeOut(coap_session_t *session) +{ + if (session == NULL) { + return; + } + coap_session_set_ack_timeout(session, COAP_ACK_TIMEOUT); + coap_session_set_ack_random_factor(session, COAP_ACK_RANDOM_FACTOR); +} + +coap_session_t *CoapGetSession(coap_context_t *ctx, const char *localAddr, const char *localPort, + const CoapServerParameter *coapServerParameter) +{ + coap_session_t *session = NULL; + coap_proto_t proto; + const coap_address_t *dst = NULL; + + if (coapServerParameter == NULL) { + return NULL; + } + + proto = coapServerParameter->proto; + dst = coapServerParameter->dst; + if (proto != COAP_PROTO_UDP) { + LOGE(TAG, "unsupported proto"); + return NULL; + } + + if (localAddr != NULL) { + int s; + struct addrinfo hints; + struct addrinfo *result = NULL; + + (void)memset_s(&hints, sizeof(struct addrinfo), 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = COAP_PROTO_RELIABLE(proto) ? SOCK_STREAM : SOCK_DGRAM; /* Coap uses UDP */ + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + s = getaddrinfo(localAddr, localPort, &hints, &result); + if (s != 0) { + LOGE(TAG, "getaddrinfo error"); + return NULL; + } + session = CoapGetSessionInner(result, ctx, coapServerParameter); + freeaddrinfo(result); + } else { + session = coap_new_client_session(ctx, NULL, dst, proto); + } + CoapSetAckTimeOut(session); + return session; +} + +uint8_t IsCoapCtxEndpointSocket(const coap_context_t *ctx, int fd) +{ + coap_endpoint_t *ep = NULL; + coap_endpoint_t *tmp = NULL; + if (ctx == NULL || ctx->endpoint == NULL) { + return NSTACKX_FALSE; + } + LL_FOREACH_SAFE(ctx->endpoint, ep, tmp) { + if (ep->sock.fd == fd) { + return NSTACKX_TRUE; + } + } + return NSTACKX_FALSE; +} \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/core/coap_discover/coap_discover.c b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_discover.c new file mode 100644 index 000000000..e85325a14 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/coap_discover/coap_discover.c @@ -0,0 +1,1104 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "coap_discover.h" +#include +#include +#include + +#include "coap.h" +#include "coap_app.h" +#include "coap_client.h" +#include "nstackx_log.h" +#include "nstackx_util.h" +#include "nstackx_timer.h" +#include "nstackx_error.h" +#include "nstackx_device.h" +#include "json_payload.h" + +#define TAG "nStackXCoAP" + +#define COAP_URI_BUFFER_LENGTH 64 /* the size of the buffer or variable used to save uri. */ +#define COAP_MAX_NUM_SUBSCRIBE_MODULE_COUNT 32 /* the maximum count of subscribed module */ + +/* + * 1st discover interval: 100ms + * 2nd ~ 3rd discover interval: 200ms + * Remaining discover interval (9 times): 500ms + */ +#define COAP_DEFAULT_DISCOVER_COUNT 12 +#define COAP_FIRST_DISCOVER_COUNT_RANGE 1 +#define COAP_SECOND_DISCOVER_COUNT_RANGE 3 +#define COAP_FIRST_DISCOVER_INTERVAL 100 +#define COAP_SECOND_DISCOVER_INTERVAL 200 +#define COAP_LAST_DISCOVER_INTERVAL 500 +#define COAP_RECV_COUNT_INTERVAL 1000 +#define COAP_DISVOCER_MAX_RATE 200 +#define COAP_MSGID_SURVIVAL_SECONDS 100 +#define COAP_MAX_MSGID_RESERVE_NUM 100 + +static coap_context_t *g_context = NULL; +static coap_context_t *g_p2pContext = NULL; +static coap_context_t *g_usbContext = NULL; + +typedef struct CoapRequest { + uint8_t type; + uint8_t code; + const char *remoteUrl; + uint8_t *token; + size_t tokenLength; + char *data; + size_t dataLength; +} CoapRequest; + +typedef struct { + uint16_t msgId; + struct timespec recvTime; +} MsgIdRecord; + +typedef struct { + MsgIdRecord msgIdRecord[COAP_MAX_MSGID_RESERVE_NUM]; + uint32_t startIdx; + uint32_t endIdx; +} MsgIdList; + +static int g_resourceFlags = COAP_RESOURCE_FLAGS_NOTIFY_CON; +static Timer *g_discoverTimer = NULL; +static uint32_t g_discoverCount; +static uint32_t g_coapMaxDiscoverCount = COAP_DEFAULT_DISCOVER_COUNT; +static uint32_t g_coapDiscoverTargetCount; +static uint8_t g_userRequest; +static uint8_t g_forceUpdate; +static Timer *g_recvRecountTimer = NULL; +static uint32_t g_recvDiscoverMsgNum; +static MsgIdList *g_msgIdList = NULL; +static uint8_t g_subscribeCount; + +static int32_t CoapUriParse(const char *uriString, coap_uri_t *uriPtr) +{ + coap_uri_t localUri; + + (void)memset_s(&localUri, sizeof(localUri), 0, sizeof(localUri)); + if ((uriString == NULL) || (uriPtr == NULL)) { + return NSTACKX_EFAILED; + } + + if (coap_split_uri((unsigned char *)uriString, strlen(uriString), &localUri) < 0) { + LOGE(TAG, "invalid CoAP URI"); + return NSTACKX_EFAILED; + } + if (localUri.scheme != COAP_URI_SCHEME_COAP) { + LOGE(TAG, "coaps URI scheme not supported in this version of libcoap"); + return NSTACKX_EFAILED; + } + + (void)memcpy_s(uriPtr, sizeof(coap_uri_t), &localUri, sizeof(coap_uri_t)); + return NSTACKX_EOK; +} + +static coap_pdu_t *CoapPackToPdu(const CoapRequest *coapRequest, const coap_uri_t *uriPtr, coap_session_t *session) +{ + coap_pdu_t *pdu = NULL; + if (coapRequest == NULL) { + return NULL; + } + if (coapRequest->remoteUrl == NULL) { + return NULL; + } + if (session == NULL) { + return NULL; + } + pdu = coap_new_pdu(session); + if (pdu == NULL) { + return NULL; + } + pdu->type = coapRequest->type; + pdu->tid = coap_new_message_id(session); + pdu->code = coapRequest->code; + if (coapRequest->tokenLength) { + if (!coap_add_token(pdu, coapRequest->tokenLength, coapRequest->token)) { + LOGW(TAG, "can't add token to request"); + } + } + coap_add_option(pdu, COAP_OPTION_URI_HOST, uriPtr->host.length, uriPtr->host.s); + coap_add_option(pdu, COAP_OPTION_URI_PATH, uriPtr->path.length, uriPtr->path.s); + if (coapRequest->dataLength) { + coap_add_data(pdu, coapRequest->dataLength, (uint8_t *)(coapRequest->data)); + } + + return pdu; +} + +static int32_t GetTargetIpString(uint8_t serverType, char *ipString, size_t length) +{ + if (ipString == NULL || length == 0) { + return NSTACKX_EFAILED; + } + + if (serverType == SERVER_TYPE_WLANORETH) { + return GetLocalIpString(ipString, length); + } + + if (serverType == SERVER_TYPE_P2P) { + return GetP2pIpString(ipString, length); + } + + if (serverType == SERVER_TYPE_USB) { + return GetUsbIpString(ipString, length); + } + + return NSTACKX_EFAILED; +} + +coap_session_t *CoapGetSessionOnTargetServer(uint8_t serverType, const CoapServerParameter *coapServerParameter) +{ + coap_context_t *context = GetContext(serverType); + if (context == NULL) { + LOGE(TAG, "can't get target context with type %hhu", serverType); + return NULL; + } + char ipString[INET_ADDRSTRLEN] = {0}; + + if (GetTargetIpString(serverType, ipString, sizeof(ipString)) != NSTACKX_EOK) { + LOGE(TAG, "can't get target IP with type %hhu", serverType); + return NULL; + } + return CoapGetSession(context, ipString, COAP_SRV_DEFAULT_PORT, coapServerParameter); +} + +int32_t CoapSendRequest(const CoapRequest *coapRequest, coap_session_t **sessionPtr, uint8_t serverType) +{ + coap_session_t *session = NULL; + coap_address_t dst = {0}; + coap_str_const_t remote; + int32_t tid; + int32_t res; + coap_pdu_t *pdu = NULL; + coap_uri_t coapUri; + CoapServerParameter coapServerParameter = {0}; + + (void)memset_s(&remote, sizeof(remote), 0, sizeof(remote)); + (void)memset_s(&coapUri, sizeof(coapUri), 0, sizeof(coapUri)); + + if (coapRequest == NULL || coapRequest->remoteUrl == NULL || sessionPtr == NULL) { + return NSTACKX_EFAILED; + } + if (CoapUriParse(coapRequest->remoteUrl, &coapUri) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + remote = coapUri.host; + res = CoapResolveAddress(&remote, &dst.addr.sa); + if (res < 0) { + LOGE(TAG, "fail to resolve address"); + return NSTACKX_EFAILED; + } + + dst.size = res; + dst.addr.sin.sin_port = htons(COAP_DEFAULT_PORT); + + coapServerParameter.proto = COAP_PROTO_UDP; + coapServerParameter.dst = &dst; + + if (*sessionPtr == NULL) { + session = CoapGetSessionOnTargetServer(serverType, &coapServerParameter); + if (session == NULL) { + LOGE(TAG, "coap_get_client_session failed"); + return NSTACKX_EFAILED; + } + *sessionPtr = session; + } else { + session = *sessionPtr; + } + + pdu = CoapPackToPdu(coapRequest, &coapUri, session); + if (pdu == NULL) { + return NSTACKX_EFAILED; + } + + tid = coap_send(session, pdu); + if (tid == COAP_INVALID_TID) { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + + +static int32_t CoapResponseService(const char *remoteUrl) +{ + int32_t ret; + CoapRequest coapRequest; + coap_session_t *session = NULL; + + (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest)); + + coapRequest.type = COAP_MESSAGE_CON; + coapRequest.code = COAP_REQUEST_POST; + coapRequest.remoteUrl = remoteUrl; + coapRequest.data = PrepareServiceDiscover(NSTACKX_FALSE); + if (coapRequest.data == NULL) { + LOGE(TAG, "failed to prepare coap data"); + return NSTACKX_EFAILED; + } else { + coapRequest.dataLength = strlen(coapRequest.data) + 1; + } + + ret = CoapSendRequest(&coapRequest, &session, SERVER_TYPE_WLANORETH); + if (ret != NSTACKX_EOK) { + LOGE(TAG, "failed to send coap request"); + } + free(coapRequest.data); + coap_session_release(session); + + return ret; +} + +static int32_t GetServiceDiscoverInfo(uint8_t *buf, size_t size, DeviceInfo *deviceInfo, char **remoteUrlPtr) +{ + uint8_t *newBuf = NULL; + if (size <= 0) { + return NSTACKX_EFAILED; + } + if (buf[size - 1] != '\0') { + newBuf = (uint8_t *)calloc(size + 1, 1U); + if (newBuf == NULL) { + LOGE(TAG, "data is not end with 0 and new buf calloc error"); + return NSTACKX_ENOMEM; + } + if (memcpy_s(newBuf, size + 1, buf, size) != EOK) { + LOGE(TAG, "data is not end with 0 and memcpy data error"); + goto L_COAP_ERR; + } + LOGI(TAG, "data is not end with 0"); + buf = newBuf; + } + if (ParseServiceDiscover(buf, deviceInfo, remoteUrlPtr) != NSTACKX_EOK) { + LOGE(TAG, "parse service discover error"); + goto L_COAP_ERR; + } + + if (newBuf != NULL) { + free(newBuf); + } + + return NSTACKX_EOK; +L_COAP_ERR: + if (newBuf != NULL) { + free(newBuf); + } + return NSTACKX_EFAILED; +} + +static void IncreaseRecvDiscoverNum(void) +{ + if (g_recvDiscoverMsgNum < UINT32_MAX) { + g_recvDiscoverMsgNum++; + } +} + +static int32_t HndPostServiceDiscoverInner(coap_pdu_t *request, char **remoteUrl, DeviceInfo *deviceInfo) +{ + size_t size; + uint8_t *buf = NULL; + IncreaseRecvDiscoverNum(); + if (g_recvDiscoverMsgNum > COAP_DISVOCER_MAX_RATE) { + return NSTACKX_EFAILED; + } + if (coap_get_data(request, &size, &buf) == 0 || size == 0 || size > COAP_RXBUFFER_SIZE) { + return NSTACKX_EFAILED; + } + (void)memset_s(deviceInfo, sizeof(*deviceInfo), 0, sizeof(*deviceInfo)); + if (GetServiceDiscoverInfo(buf, size, deviceInfo, remoteUrl) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + if (deviceInfo->mode == PUBLISH_MODE_UPLINE || deviceInfo->mode == PUBLISH_MODE_OFFLINE) { + LOGD(TAG, "peer is not DISCOVER_MODE"); + NSTACKX_DeviceInfo deviceList[PUBLISH_DEVICE_NUM]; + (void)memset_s(deviceList, sizeof(deviceList), 0, sizeof(deviceList)); + PushPublishInfo(deviceInfo, deviceList, PUBLISH_DEVICE_NUM); + NotifyDeviceFound(deviceList, PUBLISH_DEVICE_NUM); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void HndPostServiceDiscover(coap_context_t *ctx, struct coap_resource_t *resource, coap_session_t *session, + coap_pdu_t *request, coap_binary_t *token, coap_string_t *query, coap_pdu_t *response) +{ + (void)ctx; + (void)resource; + (void)session; + (void)token; + (void)query; + if (request == NULL || response == NULL) { + return; + } + char *remoteUrl = NULL; + DeviceInfo deviceInfo; + if (HndPostServiceDiscoverInner(request, &remoteUrl, &deviceInfo) != NSTACKX_EOK) { + free(remoteUrl); + return; + } + if (GetModeInfo() == PUBLISH_MODE_UPLINE || GetModeInfo() == PUBLISH_MODE_OFFLINE) { + LOGD(TAG, "local is not DISCOVER_MODE"); + free(remoteUrl); + return; + } + if (UpdateDeviceDb(&deviceInfo, g_forceUpdate) != NSTACKX_EOK) { + free(remoteUrl); + return; + } + if (g_forceUpdate) { + g_forceUpdate = NSTACKX_FALSE; + } + if (deviceInfo.mode == PUBLISH_MODE_PROACTIVE) { + LOGD(TAG, "peer is PUBLISH_MODE_PROACTIVE"); + free(remoteUrl); + return; + } + if (remoteUrl != NULL) { + CoapResponseService(remoteUrl); + free(remoteUrl); + } else { + response->code = COAP_RESPONSE_CODE(COAP_RESPONSE_201); + } +} + +static void DeleteOverTimeMsgIdRecord(MsgIdList *msgIdList, struct timespec *curTime) +{ + uint32_t i = msgIdList->startIdx; + if (msgIdList->startIdx >= COAP_MAX_MSGID_RESERVE_NUM || msgIdList->endIdx >= COAP_MAX_MSGID_RESERVE_NUM) { + return; + } + uint32_t cycleTimes = 0; + while (NSTACKX_TRUE) { + if (curTime->tv_sec - msgIdList->msgIdRecord[i].recvTime.tv_sec < COAP_MSGID_SURVIVAL_SECONDS) { + return; + } + if (i == g_msgIdList->endIdx) { + msgIdList->startIdx = COAP_MAX_MSGID_RESERVE_NUM; + msgIdList->endIdx = COAP_MAX_MSGID_RESERVE_NUM; + return; + } + msgIdList->startIdx = (msgIdList->startIdx + 1) % COAP_MAX_MSGID_RESERVE_NUM; + i = msgIdList->startIdx; + if (cycleTimes > COAP_MAX_MSGID_RESERVE_NUM) { + LOGE(TAG, "cycle too many times, error must occurred and init msgList"); + g_msgIdList->startIdx = COAP_MAX_MSGID_RESERVE_NUM; + g_msgIdList->endIdx = COAP_MAX_MSGID_RESERVE_NUM; + break; + } + cycleTimes++; + } +} + +static void AddMsgIdRecord(MsgIdList *msgIdList, uint16_t msgId, struct timespec *curTime) +{ + int32_t ret; + uint32_t idx; + if (msgIdList->endIdx == COAP_MAX_MSGID_RESERVE_NUM) { + msgIdList->endIdx = 0; + msgIdList->startIdx = 0; + idx = 0; + } else { + idx = (msgIdList->endIdx + 1) % COAP_MAX_MSGID_RESERVE_NUM; + if (idx == msgIdList->startIdx) { + msgIdList->startIdx = (msgIdList->startIdx + 1) % COAP_MAX_MSGID_RESERVE_NUM; + } + } + msgIdList->msgIdRecord[idx].msgId = msgId; + ret = memcpy_s(&msgIdList->msgIdRecord[idx].recvTime, sizeof(struct timespec), curTime, sizeof(struct timespec)); + if (ret != NSTACKX_EOK) { + LOGE(TAG, "set msg id time error"); + return; + } + msgIdList->endIdx = idx; +} + +static uint8_t RefreshMsgIdList(uint16_t msgId) +{ + struct timespec curTime; + uint32_t i; + if (g_msgIdList == NULL) { + return NSTACKX_TRUE; + } + ClockGetTime(CLOCK_MONOTONIC, &curTime); + DeleteOverTimeMsgIdRecord(g_msgIdList, &curTime); + if (g_msgIdList->startIdx >= COAP_MAX_MSGID_RESERVE_NUM || g_msgIdList->endIdx >= COAP_MAX_MSGID_RESERVE_NUM) { + AddMsgIdRecord(g_msgIdList, msgId, &curTime); + return NSTACKX_TRUE; + } + i = g_msgIdList->startIdx; + uint32_t cycleTimes = 0; + while (NSTACKX_TRUE) { + if (g_msgIdList->msgIdRecord[i].msgId == msgId) { + (void)memcpy_s(&g_msgIdList->msgIdRecord[i].recvTime, sizeof(struct timespec), &curTime, + sizeof(struct timespec)); + return NSTACKX_FALSE; + } + if (i == g_msgIdList->endIdx) { + break; + } + i = (i + 1) % COAP_MAX_MSGID_RESERVE_NUM; + if (cycleTimes > COAP_MAX_MSGID_RESERVE_NUM) { + LOGE(TAG, "cycle too many times, error must occurred and init msgList"); + g_msgIdList->startIdx = COAP_MAX_MSGID_RESERVE_NUM; + g_msgIdList->endIdx = COAP_MAX_MSGID_RESERVE_NUM; + break; + } + cycleTimes++; + } + AddMsgIdRecord(g_msgIdList, msgId, &curTime); + return NSTACKX_TRUE; +} + +static uint16_t GetServiceMsgFrameLen(const uint8_t *frame, uint16_t size) +{ + uint16_t frameLen, ret; + if (size < sizeof(frameLen)) { + LOGE(TAG, "input size %u is too small", size); + return 0; + } + if (memcpy_s(&frameLen, sizeof(frameLen), frame, sizeof(frameLen)) != EOK) { + LOGE(TAG, "memcpy frame len failed"); + return 0; + } + ret = ntohs(frameLen); + if (size < ret) { + LOGE(TAG, "input size %u is smaller than decoded frame len %u", size, ret); + return 0; + } + return ret; +} + +static uint16_t GetUnitInfo(const uint8_t *data, uint16_t dataLen, uint8_t *outBuf, uint32_t outLen, uint8_t unitType) +{ + if (dataLen < sizeof(CoapMsgUnit)) { + LOGE(TAG, "dataLen %u is too small", dataLen); + return 0; + } + CoapMsgUnit *unit = (CoapMsgUnit *)data; + if (unit->type != unitType) { + LOGE(TAG, "unit type %u does match target type %u", unit->type, unitType); + return 0; + } + uint16_t valueLen = ntohs(unit->len); + if (valueLen == 0 || valueLen > outLen || valueLen + sizeof(CoapMsgUnit) > dataLen) { + LOGE(TAG, "valueLen %u is illegal", valueLen); + return 0; + } + if (memcpy_s(outBuf, outLen, unit->value, valueLen) != EOK) { + LOGE(TAG, "memcpy unit->value failed"); + return 0; + } + if (unitType == COAP_MODULE_NAME_TYPE || unitType == COAP_DEVICE_ID_TYPE) { + if (outBuf[valueLen - 1] != '\0') { + LOGE(TAG, "uint type is %u but value is not end with 0", unitType); + return 0; + } + } + return valueLen; +} + +static uint16_t ParseServiceMsgFrame(const uint8_t *frame, uint16_t size, char *moduleName, char *deviceId, + uint8_t **msg) +{ + if (frame == NULL || size == 0) { + return 0; + } + uint16_t frameLen = GetServiceMsgFrameLen(frame, size); + if (frameLen < sizeof(frameLen) + sizeof(CoapMsgUnit)) { + return 0; + } + + /* get modulename info */ + uint16_t len = sizeof(frameLen); + uint16_t moduleNameLen = GetUnitInfo(frame + len, frameLen - len, (uint8_t *)moduleName, + NSTACKX_MAX_MODULE_NAME_LEN, COAP_MODULE_NAME_TYPE); + if (moduleNameLen == 0 || moduleNameLen + sizeof(CoapMsgUnit) >= frameLen - len) { + return 0; + } + + /* get deviceIdLen info */ + len += moduleNameLen + sizeof(CoapMsgUnit); + uint16_t deviceIdLen = GetUnitInfo(frame + len, frameLen - len, (uint8_t *)deviceId, + NSTACKX_MAX_DEVICE_ID_LEN, COAP_DEVICE_ID_TYPE); + if (deviceIdLen == 0 || deviceIdLen + sizeof(CoapMsgUnit) >= frameLen - len) { + return 0; + } + + /* get msg info */ + len += deviceIdLen + sizeof(CoapMsgUnit); + uint8_t *msgPtr = (uint8_t *)calloc(1U, frameLen - len); + if (msgPtr == NULL) { + return 0; + } + uint16_t msgLen = GetUnitInfo(frame + len, frameLen - len, msgPtr, frameLen - len, COAP_MSG_TYPE); + if (msgLen == 0) { + free(msgPtr); + return 0; + } + *msg = msgPtr; + return msgLen; +} + +static void HndPostServiceMsg(coap_context_t *ctx, struct coap_resource_t *resource, coap_session_t *session, + coap_pdu_t *request, coap_binary_t *token, coap_string_t *query, coap_pdu_t *response) +{ + (void)ctx; + (void)resource; + (void)session; + (void)token; + (void)query; + if (request == NULL || response == NULL) { + return; + } + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN] = {0}; + char moduleName[NSTACKX_MAX_MODULE_NAME_LEN] = {0}; + uint8_t *msg = NULL; + uint8_t *buf = NULL; + uint16_t msgLen; + size_t size; + + if (coap_get_data(request, &size, &buf) == 0 || size == 0 || size > COAP_RXBUFFER_SIZE) { + return; + } + + if (!RefreshMsgIdList(request->tid)) { + LOGE(TAG, "repeated msg id"); + return; + } + + LOGD(TAG, "handling post service msg request"); + msgLen = ParseServiceMsgFrame(buf, size, moduleName, deviceId, &msg); + if (msgLen == 0) { + LOGD(TAG, "parse service msg frame error"); + return; + } + + NotifyMsgReceived(moduleName, deviceId, msg, msgLen); + + response->code = COAP_RESPONSE_CODE(COAP_RESPONSE_201); + free(msg); + return; +} + +static int32_t CoapPostServiceDiscover(void) +{ + int32_t ret; + coap_session_t *session = NULL; + char ifName[NSTACKX_MAX_INTERFACE_NAME_LEN] = {0}; + char ipString[NSTACKX_MAX_IP_STRING_LEN] = {0}; + char discoverUri[COAP_URI_BUFFER_LENGTH] = {0}; + CoapRequest coapRequest = {0}; + (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest)); + + if (GetLocalInterfaceName(ifName, sizeof(ifName)) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + + if (GetIfBroadcastIp(ifName, ipString, sizeof(ipString)) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + + if (sprintf_s(discoverUri, sizeof(discoverUri), "coap://%s/%s", ipString, COAP_DEVICE_DISCOVER_URI) < 0) { + return NSTACKX_EFAILED; + } + coapRequest.type = COAP_MESSAGE_NON; + coapRequest.code = COAP_REQUEST_POST; + coapRequest.remoteUrl = discoverUri; + coapRequest.data = PrepareServiceDiscover(NSTACKX_TRUE); + if (coapRequest.data == NULL) { + LOGE(TAG, "failed to prepare coap data"); + return NSTACKX_EFAILED; + } else { + coapRequest.dataLength = strlen(coapRequest.data) + 1; + } + + ret = CoapSendRequest(&coapRequest, &session, SERVER_TYPE_WLANORETH); + if (ret != NSTACKX_EOK) { + LOGE(TAG, "failed to send coap request"); + } + free(coapRequest.data); + coap_session_release(session); + + return ret; +} + +static uint32_t GetDiscoverInterval(uint32_t discoverCount) +{ + if (discoverCount < COAP_FIRST_DISCOVER_COUNT_RANGE) { + return COAP_FIRST_DISCOVER_INTERVAL; + } else if (discoverCount < COAP_SECOND_DISCOVER_COUNT_RANGE) { + return COAP_SECOND_DISCOVER_INTERVAL; + } + return COAP_LAST_DISCOVER_INTERVAL; +} + +static void CoapServiceDiscoverStop(void) +{ + g_discoverCount = 0; + g_forceUpdate = NSTACKX_FALSE; + SetModeInfo(DISCOVER_MODE); + ClearDevices(GetDeviceDBBackup()); + LOGW(TAG, "clear device list backup"); + /* Can call PostDeviceFindWrapper() to notify user if needed. */ + g_userRequest = NSTACKX_FALSE; +} + +static void CoapServiceDiscoverTimerHandle(void *argument) +{ + uint32_t discoverInterval; + + (void)argument; + + if (g_discoverCount >= g_coapDiscoverTargetCount || !IsWifiApConnected()) { + /* Discover done, or wifi AP disconnected. */ + CoapServiceDiscoverStop(); + return; + } + + if (CoapPostServiceDiscover() != NSTACKX_EOK) { + LOGE(TAG, "failed to post service discover request"); + goto L_ERR_SERVICE_DISCOVER; + } + LOGI(TAG, "the %d times for device discover.", g_discoverCount + 1); + + /* Restart timer */ + discoverInterval = GetDiscoverInterval(g_discoverCount); + + ++g_discoverCount; + if (TimerSetTimeout(g_discoverTimer, discoverInterval, NSTACKX_FALSE) != NSTACKX_EOK) { + LOGE(TAG, "failed to set timer for service discover"); + goto L_ERR_SERVICE_DISCOVER; + } + return; + +L_ERR_SERVICE_DISCOVER: + /* Abort service discover by not starting timer. */ + LOGE(TAG, "abort service discover, have tried %u request", g_discoverCount); + /* Reset g_discoverCount to allow new request from user. */ + g_discoverCount = 0; + return; +} + +void CoapInitSubscribeModuleInner(void) +{ + g_subscribeCount = 0; + return; +} + +void CoapSubscribeModuleInner(uint8_t isSubscribe) +{ + if (isSubscribe && (g_subscribeCount < COAP_MAX_NUM_SUBSCRIBE_MODULE_COUNT)) { + g_subscribeCount++; + } + return; +} + +void CoapUnsubscribeModuleInner(uint8_t isUnsubscribe) +{ + if (isUnsubscribe && (g_subscribeCount > 0)) { + g_subscribeCount--; + } + return; +} + +void CoapServiceDiscoverInner(uint8_t userRequest) +{ + uint32_t discoverInterval; + if (!IsWifiApConnected() || g_context == NULL) { + return; + } + + if (userRequest) { + g_userRequest = NSTACKX_TRUE; + g_forceUpdate = NSTACKX_TRUE; + } + + if (g_coapDiscoverTargetCount > 0 && g_discoverCount >= g_coapDiscoverTargetCount) { + g_discoverCount = 0; + SetModeInfo(DISCOVER_MODE); + ClearDevices(GetDeviceDBBackup()); + LOGW(TAG, "clear device list backup"); + TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE); + } + + if (g_discoverCount) { + /* Service discover is ongoing, return. */ + return; + } else { + /* First discover */ + if (BackupDeviceDB() != NSTACKX_EOK) { + LOGE(TAG, "backup device list fail"); + return; + } + ClearDevices(GetDeviceDB()); + LOGW(TAG, "clear device list"); + g_coapDiscoverTargetCount = g_coapMaxDiscoverCount; + } + SetModeInfo(DISCOVER_MODE); + if (CoapPostServiceDiscover() != NSTACKX_EOK) { + LOGE(TAG, "failed to post service discover request"); + return; + } + + discoverInterval = GetDiscoverInterval(g_discoverCount); + if (TimerSetTimeout(g_discoverTimer, discoverInterval, NSTACKX_FALSE) != NSTACKX_EOK) { + LOGE(TAG, "failed to set timer for service discover"); + return; + } + ++g_discoverCount; + LOGI(TAG, "the first time for device discover."); + + return; +} + +void CoapServiceDiscoverInnerAn(uint8_t userRequest) +{ + if (!IsWifiApConnected() || g_context == NULL) { + return; + } + + if (userRequest) { + g_userRequest = NSTACKX_TRUE; + } + + if (g_discoverCount) { + g_discoverCount = 0; + /* Service discover is ongoing, reset. */ + TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE); + } else { + g_coapDiscoverTargetCount = g_coapMaxDiscoverCount; + } + + if (CoapPostServiceDiscover() != NSTACKX_EOK) { + LOGE(TAG, "failed to post service discover request"); + return; + } + + uint32_t discoverInterval = GetDiscoverInterval(g_discoverCount); + if (TimerSetTimeout(g_discoverTimer, discoverInterval, NSTACKX_FALSE) != NSTACKX_EOK) { + LOGE(TAG, "failed to set timer for service discover"); + return; + } + ++g_discoverCount; + LOGI(TAG, "the first time for device discover."); + + return; +} + +void CoapServiceDiscoverStopInner(void) +{ + TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE); + CoapServiceDiscoverStop(); + LOGI(TAG, "device discover stopped"); +} + +uint8_t CoapDiscoverRequestOngoing(void) +{ + return ((g_discoverCount > 0 && g_userRequest) || (g_subscribeCount > 0)); +} + +static uint8_t *CreateServiceMsgFrame(const char *moduleName, const char *deviceId, const uint8_t *msg, uint32_t msgLen, + uint16_t *dataLen) +{ + uint16_t frameLen, moduleNameUnitLen, deviceIdUnitLen, msgUnitLen, bufferLen; + uint8_t *frame = NULL; + uint16_t len = 0; + CoapMsgUnit *unit = NULL; + + moduleNameUnitLen = sizeof(CoapMsgUnit) + strlen(moduleName) + 1; + deviceIdUnitLen = sizeof(CoapMsgUnit) + strlen(deviceId) + 1; + msgUnitLen = sizeof(CoapMsgUnit) + msgLen; + bufferLen = sizeof(frameLen) + moduleNameUnitLen + deviceIdUnitLen + msgUnitLen; + frameLen = htons(bufferLen); + + frame = (uint8_t *)calloc(1U, bufferLen); + if (frame == NULL) { + return NULL; + } + + if (memcpy_s(frame, bufferLen, &frameLen, sizeof(frameLen)) != EOK) { + goto L_ERR_SEND_MSG; + } + len += sizeof(frameLen); + + unit = (CoapMsgUnit *)(frame + len); + unit->type = COAP_MODULE_NAME_TYPE; + unit->len = htons(moduleNameUnitLen - sizeof(CoapMsgUnit)); + if (memcpy_s(unit->value, bufferLen - len - sizeof(CoapMsgUnit), moduleName, strlen(moduleName) + 1) != EOK) { + goto L_ERR_SEND_MSG; + } + len += moduleNameUnitLen; + + unit = (CoapMsgUnit *)(frame + len); + unit->type = COAP_DEVICE_ID_TYPE; + unit->len = htons(deviceIdUnitLen - sizeof(CoapMsgUnit)); + if (memcpy_s(unit->value, bufferLen - len - sizeof(CoapMsgUnit), deviceId, strlen(deviceId) + 1) != EOK) { + goto L_ERR_SEND_MSG; + } + len += deviceIdUnitLen; + + unit = (CoapMsgUnit *)(frame + len); + unit->type = COAP_MSG_TYPE; + unit->len = htons(msgUnitLen - sizeof(CoapMsgUnit)); + if (memcpy_s(unit->value, bufferLen - len - sizeof(CoapMsgUnit), msg, msgLen) != EOK) { + goto L_ERR_SEND_MSG; + } + *dataLen = bufferLen; + return frame; +L_ERR_SEND_MSG: + free(frame); + return NULL; +} + +int32_t CoapSendServiceMsg(MsgCtx *msgCtx, DeviceInfo *deviceInfo) +{ + return CoapSendServiceMsgWithDefiniteTargetIp(msgCtx, deviceInfo); +} + +coap_context_t *GetContext(uint8_t serverType) +{ + if (serverType == SERVER_TYPE_WLANORETH) { + if (g_context == NULL) { + LOGE(TAG, "DefiniteTargetIp getContext: g_context for wlan or eth is null"); + } + return g_context; + } else if (serverType == SERVER_TYPE_P2P) { + if (g_p2pContext == NULL) { + LOGE(TAG, "DefiniteTargetIp getContext: g_p2pContext for p2p is null"); + } + return g_p2pContext; + } else if (serverType == SERVER_TYPE_USB) { + if (g_usbContext == NULL) { + LOGE(TAG, "DefiniteTargetIp getContext: g_usbContext for usb is null"); + } + return g_usbContext; + } else { + LOGE(TAG, "Coap serverType is unknown"); + return NULL; + } +} + +int32_t CoapSendServiceMsgWithDefiniteTargetIp(MsgCtx *msgCtx, DeviceInfo *deviceInfo) +{ + char ipString[INET_ADDRSTRLEN] = {0}; + char uriBuffer[COAP_URI_BUFFER_LENGTH] = {0}; + int32_t ret; + CoapRequest coapRequest; + coap_session_t *session = NULL; + uint16_t dataLen = 0; + uint8_t actualType = GetActualType(msgCtx->type, msgCtx->p2pAddr); + LOGD(TAG, "actualType is %hhu", actualType); + if (msgCtx->len == 0 || msgCtx->len > NSTACKX_MAX_SENDMSG_DATA_LEN) { + return NSTACKX_EINVAL; + } + + (void)memset_s(&coapRequest, sizeof(coapRequest), 0, sizeof(coapRequest)); + + coapRequest.type = COAP_MESSAGE_CON; + coapRequest.code = COAP_REQUEST_POST; + + if (strlen(msgCtx->p2pAddr) == 0) { + if (deviceInfo == NULL) { + return NSTACKX_EFAILED; + } + if (inet_ntop(AF_INET, &deviceInfo->netChannelInfo.wifiApInfo.ip, ipString, sizeof(ipString)) == NULL) { + LOGE(TAG, "inet_ntop failed: %d", errno); + return NSTACKX_EFAILED; + } + } else { + if (strcpy_s(ipString, sizeof(ipString), msgCtx->p2pAddr) != EOK) { + LOGE(TAG, "failed to get ip"); + return NSTACKX_EFAILED; + } + } + + if (sprintf_s(uriBuffer, sizeof(uriBuffer), "coap://%s/" COAP_SERVICE_MSG_URI, ipString) < 0) { + return NSTACKX_EFAILED; + } + coapRequest.remoteUrl = uriBuffer; + coapRequest.data = (char *)CreateServiceMsgFrame(msgCtx->moduleName, + GetLocalDeviceInfoPtr()->deviceId, msgCtx->data, msgCtx->len, &dataLen); + if (coapRequest.data == NULL) { + LOGE(TAG, "failed to prepare msg data"); + return NSTACKX_EFAILED; + } + coapRequest.dataLength = dataLen; + + ret = CoapSendRequest(&coapRequest, &session, actualType); + if (ret != NSTACKX_EOK) { + LOGE(TAG, "failed to send coap request"); + } + free(coapRequest.data); + coap_session_release(session); + return ret; +} + +uint8_t GetActualType(const uint8_t type, const char *dstIp) +{ + if (type != INVALID_TYPE) { + return type; + } + struct sockaddr_in localAddr; + localAddr.sin_addr.s_addr = inet_addr(dstIp); + struct ifreq localDev; + GetTargetInterface(&localAddr, &localDev); + if (IsWlanIpAddr(localDev.ifr_ifrn.ifrn_name) == NSTACKX_TRUE) { + return SERVER_TYPE_WLANORETH; + } + if (IsEthIpAddr(localDev.ifr_ifrn.ifrn_name) == NSTACKX_TRUE) { + return SERVER_TYPE_WLANORETH; + } + if (IsP2pIpAddr(localDev.ifr_ifrn.ifrn_name) == NSTACKX_TRUE) { + return SERVER_TYPE_P2P; + } + if (IsUsbIpAddr(localDev.ifr_ifrn.ifrn_name) == NSTACKX_TRUE) { + return SERVER_TYPE_USB; + } + return type; +} + +static void CoapRecvRecountTimerHandle(void *argument) +{ + (void)argument; + if (g_recvDiscoverMsgNum > COAP_DISVOCER_MAX_RATE) { + LOGI(TAG, "received %u discover msg in this interval", g_recvDiscoverMsgNum); + } + g_recvDiscoverMsgNum = 0; + return; +} + +void CoapInitResources(coap_context_t *ctx, uint8_t serverType) +{ + coap_resource_t *r = NULL; + + r = coap_resource_init(coap_make_str_const(COAP_DEVICE_DISCOVER_URI), g_resourceFlags); + if (r == NULL) { + return; + } + coap_register_handler(r, COAP_REQUEST_POST, HndPostServiceDiscover); + coap_resource_set_get_observable(r, NSTACKX_TRUE); + coap_add_resource(ctx, r); + + r = coap_resource_init(coap_make_str_const(COAP_SERVICE_MSG_URI), 0); + if (r == NULL) { + return; + } + coap_register_handler(r, COAP_REQUEST_POST, HndPostServiceMsg); + coap_add_resource(ctx, r); + + if (serverType == SERVER_TYPE_WLANORETH) { + g_context = ctx; + LOGD(TAG, "CoapInitResources g_wlanOrEthContext update"); + } else if (serverType == SERVER_TYPE_P2P) { + g_p2pContext = ctx; + LOGD(TAG, "CoapInitResources g_p2pContext update"); + } else if (serverType == SERVER_TYPE_USB) { + g_usbContext = ctx; + LOGD(TAG, "CoapInitResources g_usbContext update"); + } else { + LOGE(TAG, "CoapInitResources serverType is unknown!"); + } +} + +int32_t CoapDiscoverInit(EpollDesc epollfd) +{ + if (g_recvRecountTimer == NULL) { + g_recvRecountTimer = TimerStart(epollfd, COAP_RECV_COUNT_INTERVAL, NSTACKX_TRUE, + CoapRecvRecountTimerHandle, NULL); + } + if (g_recvRecountTimer == NULL) { + LOGE(TAG, "failed to start timer for receive discover message recount"); + return NSTACKX_EFAILED; + } + + if (g_discoverTimer == NULL) { + g_discoverTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapServiceDiscoverTimerHandle, NULL); + } + if (g_discoverTimer == NULL) { + LOGE(TAG, "failed to start timer for service discover"); + TimerDelete(g_recvRecountTimer); + g_recvRecountTimer = NULL; + return NSTACKX_EFAILED; + } + + g_msgIdList = (MsgIdList *)calloc(1U, sizeof(MsgIdList)); + if (g_msgIdList == NULL) { + LOGE(TAG, "message Id record list calloc error"); + TimerDelete(g_discoverTimer); + g_discoverTimer = NULL; + TimerDelete(g_recvRecountTimer); + g_recvRecountTimer = NULL; + return NSTACKX_EFAILED; + } + + g_msgIdList->startIdx = COAP_MAX_MSGID_RESERVE_NUM; + g_msgIdList->endIdx = COAP_MAX_MSGID_RESERVE_NUM; + g_userRequest = NSTACKX_FALSE; + g_forceUpdate = NSTACKX_FALSE; + g_recvDiscoverMsgNum = 0; + g_subscribeCount = 0; + g_discoverCount = 0; + return NSTACKX_EOK; +} + +void CoapDestroyCtx(uint8_t serverType) +{ + if (serverType == SERVER_TYPE_WLANORETH) { + g_context = NULL; + LOGD(TAG, "CoapDestroyCtx, g_context is set to NULL"); + } else if (serverType == SERVER_TYPE_P2P) { + g_p2pContext = NULL; + LOGD(TAG, "CoapDestroyCtx, g_p2pContext is set to NULL"); + } else if (serverType == SERVER_TYPE_USB) { + g_usbContext = NULL; + LOGD(TAG, "CoapDestroyCtx, g_usbContext is set to NULL"); + } else { + LOGE(TAG, "CoapDestroyCtx, serverType is unknown"); + } +} + +void CoapDiscoverDeinit(void) +{ + if (g_discoverTimer != NULL) { + TimerDelete(g_discoverTimer); + g_discoverTimer = NULL; + } + if (g_recvRecountTimer != NULL) { + TimerDelete(g_recvRecountTimer); + g_recvRecountTimer = NULL; + } + if (g_msgIdList != NULL) { + free(g_msgIdList); + g_msgIdList = NULL; + } +} + +void ResetCoapDiscoverTaskCount(uint8_t isBusy) +{ + if (g_discoverTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_discoverTimer task count %llu", g_discoverTimer->task.count); + } + g_discoverTimer->task.count = 0; + } + if (g_recvRecountTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_recvRecountTimer task count %llu", g_recvRecountTimer->task.count); + } + g_recvRecountTimer->task.count = 0; + } +} diff --git a/components/nstackx/nstackx_ctrl/core/coap_discover/json_payload.c b/components/nstackx/nstackx_ctrl/core/coap_discover/json_payload.c new file mode 100644 index 000000000..7a3f3c897 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/coap_discover/json_payload.c @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "json_payload.h" +#include + +#include "cJSON.h" +#include "coap_client.h" +#include "nstackx_log.h" +#include "nstackx_error.h" +#include "nstackx_device.h" + +#define TAG "nStackXCoAP" + +#define JSON_COAP_URI "coapUri" +#define JSON_CAPABILITY_BITMAP "capabilityBitmap" + +#define JSON_DEVICE_ID "deviceId" +#define JSON_DEVICE_NAME "devicename" +#define JSON_DEVICE_WLAN_IP "wlanIp" +#define JSON_DEVICE_TYPE "type" +#define JSON_HICOM_VERSION "hicomversion" +#define JSON_REQUEST_MODE "mode" +#define JSON_DEVICE_HASH "deviceHash" +#define JSON_SERVICE_DATA "serviceData" +#define NSTACKX_MAX_URI_BUFFER_LENGTH 64 + +static int32_t AddDeviceJsonData(cJSON *data, const DeviceInfo *deviceInfo) +{ + cJSON *item; + + item = cJSON_CreateString(deviceInfo->deviceId); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_ID, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateString(deviceInfo->deviceName); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_NAME, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateNumber(deviceInfo->deviceType); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_TYPE, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateString(deviceInfo->version); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_HICOM_VERSION, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateNumber(deviceInfo->mode); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_REQUEST_MODE, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateString(deviceInfo->deviceHash); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_HASH, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + item = cJSON_CreateString(deviceInfo->serviceData); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_SERVICE_DATA, item)) { + cJSON_Delete(item); + LOGE(TAG, "cJSON_CreateString for serviceData failed"); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +static int32_t AddWifiApJsonData(cJSON *data) +{ + cJSON *item = NULL; + char ipString[INET_ADDRSTRLEN] = {0}; + + if (GetLocalIpString(ipString, sizeof(ipString)) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + + item = cJSON_CreateString(ipString); + if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_WLAN_IP, item)) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +static int32_t AddCapabilityBitmap(cJSON *data, const DeviceInfo *deviceInfo) +{ + cJSON *capabilityArray = NULL; + cJSON *capability = NULL; + uint32_t i; + + if (deviceInfo->capabilityBitmapNum == 0) { + return NSTACKX_EOK; + } + + capabilityArray = cJSON_CreateArray(); + if (capabilityArray == NULL) { + goto L_END_JSON; + } + + for (i = 0; i < deviceInfo->capabilityBitmapNum; i++) { + capability = cJSON_CreateNumber(deviceInfo->capabilityBitmap[i]); + if (capability == NULL || !cJSON_AddItemToArray(capabilityArray, capability)) { + cJSON_Delete(capability); + goto L_END_JSON; + } + } + if (!cJSON_AddItemToObject(data, JSON_CAPABILITY_BITMAP, capabilityArray)) { + goto L_END_JSON; + } + + return NSTACKX_EOK; + +L_END_JSON: + cJSON_Delete(capabilityArray); + return NSTACKX_EFAILED; +} + +static int32_t ParseDeviceJsonData(const cJSON *data, DeviceInfo *dev) +{ + cJSON *item = NULL; + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_ID); + if (!cJSON_IsString(item) || !strlen(item->valuestring)) { + LOGE(TAG, "Cannot find device ID or invalid device ID"); + return NSTACKX_EINVAL; + } + if (strcpy_s(dev->deviceId, sizeof(dev->deviceId), item->valuestring) != EOK) { + return NSTACKX_EFAILED; + } + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_NAME); + if (!cJSON_IsString(item) || !strlen(item->valuestring)) { + LOGE(TAG, "Cannot find device name or invalid device name"); + return NSTACKX_EINVAL; + } + if (strcpy_s(dev->deviceName, sizeof(dev->deviceName), item->valuestring) != EOK) { + return NSTACKX_EFAILED; + } + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_TYPE); + if (!cJSON_IsNumber(item) || (item->valuedouble < 0) || (item->valuedouble > 0xFF)) { + LOGE(TAG, "Cannot find device type or invalid device type"); + return NSTACKX_EINVAL; + } + dev->deviceType = (uint8_t)item->valuedouble; + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_HICOM_VERSION); + if (!cJSON_IsString(item) || !strlen(item->valuestring)) { + LOGW(TAG, "Can't find hicom version"); + return NSTACKX_EOK; + } + if (strcpy_s(dev->version, sizeof(dev->version), item->valuestring) != EOK) { + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +static void ParseWifiApJsonData(const cJSON *data, DeviceInfo *dev) +{ + cJSON *item = NULL; + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_WLAN_IP); + if (cJSON_IsString(item)) { + if (inet_pton(AF_INET, item->valuestring, &(dev->netChannelInfo.wifiApInfo.ip)) != 1) { + LOGW(TAG, "Invalid ip address"); + } else { + dev->netChannelInfo.wifiApInfo.state = NET_CHANNEL_STATE_CONNETED; + } + } +} + +static void ParseModeJsonData(const cJSON *data, DeviceInfo *dev) +{ + cJSON *item = NULL; + item = cJSON_GetObjectItemCaseSensitive(data, JSON_REQUEST_MODE); + if (item == NULL) { + LOGE(TAG, "Cannot get mode json"); + return; + } + if (!cJSON_IsNumber(item) || (item->valuedouble < 0)) { + LOGE(TAG, "Cannot find mode or invalid mode"); + } else { + if (dev == NULL) { + LOGE(TAG, "device info is null"); + return; + } + dev->mode = (uint8_t)item->valuedouble; + } +} + +static void ParseDeviceHashData(const cJSON *data, DeviceInfo *dev) +{ + cJSON *item = NULL; + item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_HASH); + if (item == NULL) { + LOGD(TAG, "Cannot get hash json"); + return; + } + if (!cJSON_IsString(item) || !strlen(item->valuestring)) { + LOGD(TAG, "Cannot find device hash or invalid hash"); + return; + } + if (strcpy_s(dev->deviceHash, sizeof(dev->deviceHash), item->valuestring) != EOK) { + LOGE(TAG, "parse device hash data error"); + return; + } +} + +static void ParseServiceDataJsonData(const cJSON *data, DeviceInfo *dev) +{ + cJSON *item = NULL; + item = cJSON_GetObjectItemCaseSensitive(data, JSON_SERVICE_DATA); + if (item == NULL) { + LOGE(TAG, "Cannot get service data"); + return; + } + if (!cJSON_IsString(item)) { + LOGE(TAG, "Cannot find serviceData"); + return; + } + if (strcpy_s(dev->serviceData, sizeof(dev->serviceData), item->valuestring)) { + LOGE(TAG, "parse device serviceData error"); + return; + } +} + +static void ParseCapabilityBitmap(const cJSON *data, DeviceInfo *deviceInfo) +{ + cJSON *capability = NULL; + cJSON *item = NULL; + uint32_t capabilityBitmapNum = 0; + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_CAPABILITY_BITMAP); + if (cJSON_IsArray(item)) { + cJSON_ArrayForEach(capability, item) { + if (capabilityBitmapNum >= NSTACKX_MAX_CAPABILITY_NUM) { + break; + } + + if (!cJSON_IsNumber(capability) || + capability->valuedouble < 0 || + capability->valuedouble > 0xFFFFFFFF) { + /* skip invalid capability */ + continue; + } + deviceInfo->capabilityBitmap[capabilityBitmapNum++] = (uint32_t)capability->valuedouble; + } + } + deviceInfo->capabilityBitmapNum = capabilityBitmapNum; +} + +/* + * Service Discover JSON format + * { + * "deviceId":[device ID, string], + * "deviceName":[device name, string], + * "type": [device type, number], + * "version":[hicom version, string], + * "wlanIp":[WLAN IP address, string], + * "capabilityBitmap":[bitmap, bitmap, bitmap, ...] + * "coapUri":[coap uri for discover, string] <-- optional. When present, means it's broadcast request. + * } + */ +char *PrepareServiceDiscover(uint8_t isBroadcast) +{ + char coapUriBuffer[NSTACKX_MAX_URI_BUFFER_LENGTH] = {0}; + char host[NSTACKX_MAX_IP_STRING_LEN] = {0}; + char *formatString = NULL; + const DeviceInfo *deviceInfo = GetLocalDeviceInfoPtr(); + cJSON *data = NULL; + cJSON *localCoapString = NULL; + + data = cJSON_CreateObject(); + if (data == NULL) { + goto L_END_JSON; + } + + /* Prepare local device info */ + if ((AddDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) || + (AddWifiApJsonData(data) != NSTACKX_EOK) || + (AddCapabilityBitmap(data, deviceInfo) != NSTACKX_EOK)) { + goto L_END_JSON; + } + + if (isBroadcast) { + if (GetLocalIpString(host, sizeof(host)) != NSTACKX_EOK) { + goto L_END_JSON; + } + if (sprintf_s(coapUriBuffer, sizeof(coapUriBuffer), "coap://%s/" COAP_DEVICE_DISCOVER_URI, host) < 0) { + goto L_END_JSON; + } + localCoapString = cJSON_CreateString(coapUriBuffer); + if (localCoapString == NULL || !cJSON_AddItemToObject(data, JSON_COAP_URI, localCoapString)) { + cJSON_Delete(localCoapString); + goto L_END_JSON; + } + } + + formatString = cJSON_PrintUnformatted(data); + if (formatString == NULL) { + LOGE(TAG, "cJSON_PrintUnformatted failed"); + } + +L_END_JSON: + cJSON_Delete(data); + return formatString; +} + +int32_t ParseServiceDiscover(const uint8_t *buf, DeviceInfo *deviceInfo, char **remoteUrlPtr) +{ + char *remoteUrl = NULL; + cJSON *data = NULL; + cJSON *item = NULL; + + if (buf == NULL || deviceInfo == NULL || remoteUrlPtr == NULL) { + return NSTACKX_EINVAL; + } + + data = cJSON_Parse((char *)buf); + if (data == NULL) { + return NSTACKX_EINVAL; + } + + if (ParseDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) { + cJSON_Delete(data); + return NSTACKX_EINVAL; + } + + ParseWifiApJsonData(data, deviceInfo); + ParseCapabilityBitmap(data, deviceInfo); + ParseModeJsonData(data, deviceInfo); + ParseDeviceHashData(data, deviceInfo); + ParseServiceDataJsonData(data, deviceInfo); + + item = cJSON_GetObjectItemCaseSensitive(data, JSON_COAP_URI); + if (item != NULL) { + if (cJSON_IsString(item)) { + remoteUrl = strdup(item->valuestring); + LOGD(TAG, "new device join"); + } + } + + *remoteUrlPtr = remoteUrl; + cJSON_Delete(data); + return NSTACKX_EOK; +} diff --git a/components/nstackx/nstackx_ctrl/core/nstackx_common.c b/components/nstackx/nstackx_ctrl/core/nstackx_common.c new file mode 100644 index 000000000..b731bdaad --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/nstackx_common.c @@ -0,0 +1,815 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_common.h" + +#include +#include +#include +#include +#include "cJSON.h" + +#include "coap_discover/coap_app.h" +#include "coap_discover/coap_discover.h" +#include "nstackx.h" +#include "nstackx_device.h" +#include "nstackx_epoll.h" +#include "nstackx_error.h" +#include "nstackx_event.h" +#include "nstackx_log.h" +#include "nstackx_smartgenius.h" +#include "nstackx_timer.h" +#include "nstackx_util.h" + +#define TAG "nStackXDFinder" + +enum { + NSTACKX_INIT_STATE_START = 0, + NSTACKX_INIT_STATE_ONGOING, + NSTACKX_INIT_STATE_DONE, +}; + +static EpollDesc g_epollfd = INVALID_EPOLL_DESC; +static List g_eventNodeChain = {&(g_eventNodeChain), &(g_eventNodeChain)}; +static pthread_t g_tid; +static uint8_t g_validTidFlag = NSTACKX_FALSE; +static uint8_t g_terminateFlag = NSTACKX_FALSE; + +static NSTACKX_Parameter g_parameter; +static uint8_t g_nstackInitState; + +#define EVENT_COUNT_RATE_INTERVAL 2000 /* 2 SECONDS */ +#define MAX_EVENT_PROCESS_NUM_PER_INTERVAL 700 +#define MAX_CONTINUOUS_BUSY_INTERVAL_NUM 20 + +typedef struct { + uint32_t epollWaitTimeoutCount; + uint32_t epollWaitEventCount; + struct timespec measureBefore; +} EventProcessRatePara; +static EventProcessRatePara g_processRatePara; +static uint32_t g_continuousBusyIntervals; + +void NotifyDFinderMsgRecver(DFinderMsgType msgType) +{ + if (g_parameter.onDFinderMsgReceived != NULL) { + g_parameter.onDFinderMsgReceived(msgType); + } +} + +static void ResetMainEpollTaskCount(uint8_t isBusy) +{ + EpollTask *task = GetEpollTask(&g_eventNodeChain, g_epollfd); + if (task == NULL) { + return; + } + if (isBusy) { + LOGI(TAG, "in this busy interval: main epoll task count %llu", task->count); + } + task->count = 0; +} + +uint8_t IsBusyInterval(uint32_t eventCount, uint32_t timeMs) +{ + uint8_t retFlag; + if ((uint64_t)eventCount * EVENT_COUNT_RATE_INTERVAL < + MAX_EVENT_PROCESS_NUM_PER_INTERVAL * (uint64_t)timeMs) { + retFlag = NSTACKX_FALSE; + } else { + retFlag = NSTACKX_TRUE; + } + + ResetMainEpollTaskCount(retFlag); + ResetCoapSocketTaskCount(retFlag); + ResetCoapDiscoverTaskCount(retFlag); + ResetDeviceTaskCount(retFlag); + ResetSmartGeniusTaskCount(retFlag); + + return retFlag; +} + +static void CalculateEventProcessRate(void) +{ + struct timespec now; + ClockGetTime(CLOCK_MONOTONIC, &now); + uint32_t measureElapse = GetTimeDiffMs(&now, &g_processRatePara.measureBefore); + if (measureElapse > EVENT_COUNT_RATE_INTERVAL) { + uint32_t totalCount = g_processRatePara.epollWaitEventCount + g_processRatePara.epollWaitTimeoutCount; + if (!IsBusyInterval(totalCount, measureElapse)) { + g_continuousBusyIntervals = 0; + } else { + LOGI(TAG, "main loop seems to be busy in the past interval. Timeout count %u, event count %u", + g_processRatePara.epollWaitTimeoutCount, g_processRatePara.epollWaitEventCount); + g_continuousBusyIntervals++; + if (g_continuousBusyIntervals >= MAX_CONTINUOUS_BUSY_INTERVAL_NUM) { + LOGE(TAG, "main loop seems to be busy in the past %u intervals. notify user to restart", + g_continuousBusyIntervals); + NotifyDFinderMsgRecver(DFINDER_ON_TOO_BUSY); + g_continuousBusyIntervals = 0; + } + } + g_processRatePara.epollWaitTimeoutCount = 0; + g_processRatePara.epollWaitEventCount = 0; + ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore); + } +} + +static void *NstackMainLoop(void *arg) +{ + uint32_t timeout; + int32_t ret; + + (void)arg; + (void)memset_s(&g_processRatePara, sizeof(g_processRatePara), 0, sizeof(g_processRatePara)); + g_continuousBusyIntervals = 0; + ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore); + while (g_terminateFlag == NSTACKX_FALSE) { + timeout = RegisterCoAPEpollTask(g_epollfd); + ret = EpollLoop(g_epollfd, timeout); + if (ret == NSTACKX_EFAILED) { + LOGE(TAG, "epoll loop failed"); + DeRegisterCoAPEpollTask(); + break; + } else if (ret == NSTACKX_ETIMEOUT) { + g_processRatePara.epollWaitTimeoutCount++; + } else if (ret > 0) { + g_processRatePara.epollWaitEventCount++; + } + CalculateEventProcessRate(); + DeRegisterCoAPEpollTask(); + } + return NULL; +} + +EpollDesc GetMainLoopEpollFd(void) +{ + return g_epollfd; +} + +List *GetMainLoopEvendChain(void) +{ + return &g_eventNodeChain; +} + +static int32_t InternalInit(EpollDesc epollfd) +{ + int32_t ret = EventModuleInit(&g_eventNodeChain, g_epollfd); + if (ret != NSTACKX_EOK) { + return ret; + } + + ret = DeviceModuleInit(epollfd); + if (ret != NSTACKX_EOK) { + return ret; + } + + ret = P2pUsbTimerInit(epollfd); + if (ret != NSTACKX_EOK) { + return ret; + } + + ret = CoapServerInit(NULL); + if (ret != NSTACKX_EOK) { + return ret; + } + + ret = CoapDiscoverInit(epollfd); + if (ret != NSTACKX_EOK) { + return ret; + } + + return SmartGeniusInit(epollfd); +} + +int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter) +{ + int32_t ret; + + if (g_nstackInitState != NSTACKX_INIT_STATE_START) { + return NSTACKX_EOK; + } + + g_nstackInitState = NSTACKX_INIT_STATE_ONGOING; + cJSON_InitHooks(NULL); + + SetLogLevel(NSTACKX_LOG_LEVEL_DEBUG); + + g_epollfd = CreateEpollDesc(); + if (!IsEpollDescValid(g_epollfd)) { + LOGE(TAG, "epoll create fail! errno: %d", errno); + g_nstackInitState = NSTACKX_INIT_STATE_START; + return NSTACKX_EFAILED; + } + + LOGD(TAG, "nstack ctrl create epollfd %d", REPRESENT_EPOLL_DESC(g_epollfd)); + g_terminateFlag = NSTACKX_FALSE; + g_validTidFlag = NSTACKX_FALSE; + ret = PthreadCreate(&g_tid, NULL, NstackMainLoop, NULL); + if (ret != 0) { + LOGE(TAG, "thread create failed"); + goto L_ERR_INIT; + } + g_validTidFlag = NSTACKX_TRUE; + ret = InternalInit(g_epollfd); + if (ret != NSTACKX_EOK) { + goto L_ERR_INIT; + } + (void)memset_s(&g_parameter, sizeof(g_parameter), 0, sizeof(g_parameter)); + if (parameter != NULL) { + (void)memcpy_s(&g_parameter, sizeof(g_parameter), parameter, sizeof(NSTACKX_Parameter)); + } + + CoapInitSubscribeModuleInner(); /* initialize subscribe module number */ + + g_nstackInitState = NSTACKX_INIT_STATE_DONE; + LOGI(TAG, "DFinder init successfully"); + return NSTACKX_EOK; + +L_ERR_INIT: + NSTACKX_Deinit(); + return ret; +} + +void NSTACKX_Deinit(void) +{ + if (g_nstackInitState == NSTACKX_INIT_STATE_START) { + return; + } + if (g_validTidFlag) { + g_terminateFlag = NSTACKX_TRUE; + PthreadJoin(g_tid, NULL); + g_validTidFlag = NSTACKX_FALSE; + } + SmartGeniusClean(); + CoapDiscoverDeinit(); + DestroyP2pUsbServerInitRetryTimer(); + CoapServerDestroy(); + CoapP2pServerDestroy(); + CoapUsbServerDestroy(); + DeviceModuleClean(); + EventNodeChainClean(&g_eventNodeChain); + if (IsEpollDescValid(g_epollfd)) { + CloseEpollDesc(g_epollfd); + g_epollfd = INVALID_EPOLL_DESC; + } + + g_nstackInitState = NSTACKX_INIT_STATE_START; + LOGI(TAG, "deinit successfully"); +} + +static void DeviceDiscoverInner(void *argument) +{ + (void)argument; + CoapServiceDiscoverInner(INNER_DISCOVERY); + + /* If both Wifi AP and BLE are disabled, we should also notify user, with empty list. */ + if (!IsWifiApConnected()) { + NotifyDeviceFound(NULL, 0); + } +} + +static void DeviceDiscoverInnerAn(void *argument) +{ + (void)argument; + CoapServiceDiscoverInnerAn(INNER_DISCOVERY); +} + +static void DeviceDiscoverStopInner(void *argument) +{ + (void)argument; + CoapServiceDiscoverStopInner(); +} + +int32_t NSTACKX_StartDeviceFind(void) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInner, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to start device discover!"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_StartDeviceFindAn(uint8_t mode) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + SetModeInfo(mode); + if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerAn, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to start device discover!"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_StopDeviceFind(void) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverStopInner, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to stop device discover!"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void SubscribeModuleInner(void *argument) +{ + (void)argument; + CoapSubscribeModuleInner(INNER_DISCOVERY); +} + +int32_t NSTACKX_SubscribeModule(void) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, SubscribeModuleInner, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to subscribe module!"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void UnsubscribeModuleInner(void *argument) +{ + (void)argument; + CoapUnsubscribeModuleInner(INNER_DISCOVERY); +} + +int32_t NSTACKX_UnsubscribeModule(void) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + return NSTACKX_EFAILED; + } + + if (PostEvent(&g_eventNodeChain, g_epollfd, UnsubscribeModuleInner, NULL) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void ConfigureLocalDeviceInfoInner(void *argument) +{ + NSTACKX_LocalDeviceInfo *localDeviceInfo = argument; + + ConfigureLocalDeviceInfo(localDeviceInfo); + free(localDeviceInfo); +} + +int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo) +{ + NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = NULL; + LOGE(TAG, "begin to NSTACKX_RegisterDevice!"); + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + + if (localDeviceInfo == NULL) { + LOGE(TAG, "Invalid local device info"); + return NSTACKX_EINVAL; + } + + dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo)); + if (dupLocalDeviceInfo == NULL) { + LOGE(TAG, "malloc failed"); + return NSTACKX_ENOMEM; + } + + if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo), + localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) { + LOGE(TAG, "cp failed"); + free(dupLocalDeviceInfo); + return NSTACKX_EFAILED; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) { + LOGE(TAG, "Failed to configure local device info!"); + free(dupLocalDeviceInfo); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash) +{ + NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = NULL; + + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + + if (localDeviceInfo == NULL) { + LOGE(TAG, "Invalid local device info"); + return NSTACKX_EINVAL; + } + + dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo)); + if (dupLocalDeviceInfo == NULL) { + return NSTACKX_ENOMEM; + } + + if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo), + localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) { + free(dupLocalDeviceInfo); + return NSTACKX_EFAILED; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) { + LOGE(TAG, "Failed to configure local device info!"); + free(dupLocalDeviceInfo); + return NSTACKX_EFAILED; + } + SetDeviceHash(deviceHash); + return NSTACKX_EOK; +} + +typedef struct { + uint32_t capabilityBitmapNum; + uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM]; +} CapabilityProcessData; + +static void RegisterCapabilityInner(void *argument) +{ + CapabilityProcessData *capabilityData = argument; + + RegisterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap); + free(capabilityData); +} + +static void SetFilterCapabilityInner(void *argument) +{ + CapabilityProcessData *capabilityData = argument; + + SetFilterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap); + free(capabilityData); +} + +static int32_t NSTACKX_CapabilityHandle(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[], EventHandle handle) +{ + CapabilityProcessData *capabilityData = NULL; + + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + + if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) { + LOGE(TAG, "capabilityBitmapNum (%u) exceed max number", capabilityBitmapNum); + return NSTACKX_EINVAL; + } + + capabilityData = calloc(1U, sizeof(CapabilityProcessData)); + if (capabilityData == NULL) { + return NSTACKX_ENOMEM; + } + + if ((capabilityBitmapNum != 0) && memcpy_s(capabilityData->capabilityBitmap, + sizeof(capabilityData->capabilityBitmap), capabilityBitmap, capabilityBitmapNum * sizeof(uint32_t)) != EOK) { + free(capabilityData); + return NSTACKX_EINVAL; + } + capabilityData->capabilityBitmapNum = capabilityBitmapNum; + + if (PostEvent(&g_eventNodeChain, g_epollfd, handle, capabilityData) != NSTACKX_EOK) { + LOGE(TAG, "Failed to register capability!"); + free(capabilityData); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + LOGI(TAG, "Register Capability"); + return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, RegisterCapabilityInner); +} + +int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + LOGI(TAG, "Set Filter Capability"); + return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, SetFilterCapabilityInner); +} + +static void RegisterServiceDataInner(void *argument) +{ + char *serviceData = argument; + if (RegisterServiceData(serviceData) != NSTACKX_EOK) { + LOGE(TAG, "RegisterServiceData failed"); + } + free(serviceData); +} + +int32_t NSTACKX_RegisterServiceData(const char *serviceData) +{ + char *serviceDataTmp = NULL; + + if (serviceData == NULL) { + LOGE(TAG, "serviceData is null"); + return NSTACKX_EINVAL; + } + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (strlen(serviceData) >= NSTACKX_MAX_SERVICE_DATA_LEN) { + LOGE(TAG, "serviceData (%u) exceed max number", strlen(serviceData)); + return NSTACKX_EINVAL; + } + + serviceDataTmp = calloc(1U, NSTACKX_MAX_SERVICE_DATA_LEN); + if (serviceDataTmp == NULL) { + return NSTACKX_ENOMEM; + } + if (strncpy_s(serviceDataTmp, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData, strlen(serviceData)) != EOK) { + LOGE(TAG, "Failed to copy serviceData"); + free(serviceDataTmp); + return NSTACKX_EINVAL; + } + if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterServiceDataInner, serviceDataTmp) != NSTACKX_EOK) { + LOGE(TAG, "Failed to register serviceData!"); + free(serviceDataTmp); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +static void SendMsgInner(void *arg) +{ + MsgCtx *msg = arg; + DeviceInfo *deviceInfo = NULL; + if (msg == NULL) { + LOGE(TAG, "SendMsgInner: msg is NULL"); + return; + } + if (strlen(msg->p2pAddr) != 0) { + LOGD(TAG, "Enter WifiDirect send"); + CoapSendServiceMsgWithDefiniteTargetIp(msg, deviceInfo); + } else { + deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDB()); + if (deviceInfo == NULL) { + LOGW(TAG, "no device found in device list, try to find in backup"); + deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDBBackup()); + if (deviceInfo == NULL) { + LOGE(TAG, "no device found in device list backup yet"); + goto FINISH; + } + } + CoapSendServiceMsg(msg, deviceInfo); + } + +FINISH: + free(msg->data); + free(msg); +} + +int32_t NSTACKX_SendMsgParamCheck(const char *moduleName, const char *deviceId, const uint8_t *data, + uint32_t len) +{ + if (moduleName == NULL || strlen(moduleName) > NSTACKX_MAX_MODULE_NAME_LEN) { + LOGE(TAG, "Invalid module name"); + return NSTACKX_EINVAL; + } + + if (deviceId == NULL || strlen(deviceId) > NSTACKX_MAX_DEVICE_ID_LEN) { + LOGE(TAG, "Invalid device id"); + return NSTACKX_EINVAL; + } + + if (data == NULL || len == 0 || len > NSTACKX_MAX_SENDMSG_DATA_LEN) { + LOGE(TAG, "Null data to send"); + return NSTACKX_EINVAL; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data, + uint32_t len, const char *ipaddr, uint8_t type) +{ + MsgCtx *msg = NULL; + LOGD(TAG, "NSTACKX_SendMsgDirect"); + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) { + return NSTACKX_EINVAL; + } + msg = calloc(1U, sizeof(MsgCtx)); + if (msg == NULL) { + LOGE(TAG, "MsgCtx malloc fail"); + return NSTACKX_ENOMEM; + } + if ((strcpy_s(msg->deviceId, sizeof(msg->deviceId), deviceId) != EOK) || + (strcpy_s(msg->moduleName, sizeof(msg->moduleName), moduleName) != EOK)) { + LOGE(TAG, "Cpy deviceId fail"); + free(msg); + return NSTACKX_EFAILED; + } + if (strcpy_s(msg->p2pAddr, sizeof(msg->p2pAddr), ipaddr) != EOK) { + LOGE(TAG, "Cpy p2pAddr fail."); + free(msg); + return NSTACKX_EFAILED; + } + msg->data = malloc(len); + if (msg->data == NULL) { + LOGE(TAG, "Msg data malloc fail"); + free(msg); + return NSTACKX_ENOMEM; + } + if (memcpy_s(msg->data, len, data, len) != EOK) { + LOGE(TAG, "Msg data memcpy error"); + free(msg->data); + free(msg); + return NSTACKX_EFAILED; + } + msg->len = len; + msg->type = type; + if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) { + LOGE(TAG, "Failed to send msg"); + free(msg->data); + free(msg); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len) +{ + MsgCtx *msg = NULL; + + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) { + return NSTACKX_EINVAL; + } + msg = calloc(1U, sizeof(MsgCtx)); + if (msg == NULL) { + LOGE(TAG, "MsgCtx malloc fail"); + return NSTACKX_ENOMEM; + } + + if ((strcpy_s(msg->deviceId, sizeof(msg->deviceId), deviceId) != EOK) || + (strcpy_s(msg->moduleName, sizeof(msg->moduleName), moduleName) != EOK)) { + free(msg); + return NSTACKX_EFAILED; + } + + msg->data = malloc(len); + if (msg->data == NULL) { + LOGE(TAG, "msg data malloc fail"); + free(msg); + return NSTACKX_ENOMEM; + } + + if (memcpy_s(msg->data, len, data, len) != EOK) { + LOGE(TAG, "msg data memcpy error"); + free(msg->data); + free(msg); + return NSTACKX_EFAILED; + } + + msg->len = len; + msg->type = SERVER_TYPE_WLANORETH; + if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) { + LOGE(TAG, "failed to send msg"); + free(msg->data); + free(msg); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +typedef struct { + NSTACKX_DeviceInfo *deviceList; + uint32_t *deviceCountPtr; + sem_t wait; +} GetDeviceListMessage; + +static void GetDeviceListInner(void *argument) +{ + GetDeviceListMessage *message = argument; + + GetDeviceList(message->deviceList, message->deviceCountPtr, true); + SemPost(&message->wait); +} + +int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr) +{ + GetDeviceListMessage message = { + .deviceList = deviceList, + .deviceCountPtr = deviceCountPtr, + }; + + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return NSTACKX_EFAILED; + } + + if (deviceList == NULL || deviceCountPtr == NULL) { + LOGE(TAG, "Device list or count pointer is NULL"); + return NSTACKX_EINVAL; + } + + if (SemInit(&message.wait, 0, 0)) { + return NSTACKX_EFAILED; + } + + if (PostEvent(&g_eventNodeChain, g_epollfd, GetDeviceListInner, &message) != NSTACKX_EOK) { + LOGE(TAG, "Failed to get device list"); + SemDestroy(&message.wait); + return NSTACKX_EFAILED; + } + + SemWait(&message.wait); + SemDestroy(&message.wait); + return NSTACKX_EOK; +} + +void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount) +{ + if (g_parameter.onDeviceListChanged != NULL) { + LOGI(TAG, "notify callback: device list changed"); + g_parameter.onDeviceListChanged(deviceList, deviceCount); + LOGI(TAG, "finish to notify device list changed"); + } else { + LOGI(TAG, "notify callback: device list changed callback is null"); + } +} + +void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount) +{ + if (g_parameter.onDeviceFound != NULL) { + LOGI(TAG, "notify callback: device found"); + g_parameter.onDeviceFound(deviceList, deviceCount); + LOGI(TAG, "finish to notify device found"); + } else { + LOGI(TAG, "notify callback: device found callback is null"); + } +} + +void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len) +{ + if (g_parameter.onMsgReceived != NULL) { + LOGI(TAG, "notify callback: message received, data length %u", len); + g_parameter.onMsgReceived(moduleName, deviceId, data, len); + LOGI(TAG, "finish to notify msg received"); + } else { + LOGI(TAG, "notify callback: message received callback is null"); + } +} + +int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter) +{ + LOGI(TAG, "NSTACKX_InitRestart"); + int32_t ret = NSTACKX_Init(parameter); + if (ret == NSTACKX_EOK) { + if (PostEvent(&g_eventNodeChain, g_epollfd, GetLocalNetworkInterface, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to GetLocalNetworkInterface"); + } + } + return ret; +} + +static void DeviceDiscoverInnerRestart(void *argument) +{ + (void)argument; + CoapServiceDiscoverInner(NSTACKX_FALSE); +} + +void NSTACKX_StartDeviceFindRestart(void) +{ + if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) { + LOGE(TAG, "NSTACKX_Ctrl is not initiated yet"); + return; + } + LOGI(TAG, "start device find for restart"); + if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerRestart, NULL) != NSTACKX_EOK) { + LOGE(TAG, "Failed to start device discover!"); + return; + } + return; +} diff --git a/components/nstackx/nstackx_ctrl/core/nstackx_database.c b/components/nstackx/nstackx_ctrl/core/nstackx_database.c new file mode 100644 index 000000000..a134a0187 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/nstackx_database.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_database.h" +#include +#include +#include +#include + +#include "nstackx_log.h" +#include "nstackx_error.h" + +#define TAG "nStackXDFinder" + +#define NSTACKX_USEDMAP_ROW_SIZE 32U /* Row size suit for uint32_t */ + +typedef struct { + uint8_t *blk; + uint32_t *usedMap; + uint32_t mapSize; + uint32_t useCount; + uint32_t maxCount; + size_t recSize; + RecCompareCallback cb; +} DatabaseInfo; + +static inline int64_t GetRecordIndex(const DatabaseInfo *db, const void *rec) +{ + if (db->recSize == 0) { + return -1; + } + return ((uint8_t *)rec - db->blk) / db->recSize; +} + +/* Make sure that recNum is valid */ +static uint8_t IsRecordOccupied(const DatabaseInfo *db, uint32_t recNum, uint32_t *iptr, uint32_t *offptr) +{ + uint32_t i; + uint32_t off; + + i = recNum / NSTACKX_USEDMAP_ROW_SIZE; + off = recNum % NSTACKX_USEDMAP_ROW_SIZE; + if (iptr != NULL) { + *iptr = i; + } + if (offptr != NULL) { + *offptr = off; + } + if (db->usedMap[i] & (1U << off)) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +static inline void *GetRecord(const DatabaseInfo *db, uint32_t index) +{ + return db->blk + (index * db->recSize); +} + +void *DatabaseSearchRecord(const void *dbptr, void *ptr) +{ + const DatabaseInfo *db = dbptr; + void *rec = NULL; + uint32_t i, j; + + if (dbptr == NULL || ptr == NULL || db->cb == NULL) { + return NULL; + } + + for (i = 0; i < db->mapSize; i++) { + if (!db->usedMap[i]) { + continue; + } + for (j = 0; j < NSTACKX_USEDMAP_ROW_SIZE; j++) { + if (!(db->usedMap[i] & (1U << j))) { + continue; + } + rec = GetRecord(db, i * NSTACKX_USEDMAP_ROW_SIZE + j); + if (db->cb(rec, ptr)) { + return rec; + } + } + } + return NULL; +} + +uint32_t GetDatabaseUseCount(const void *dbptr) +{ + if (dbptr == NULL) { + return 0; + } + + return ((const DatabaseInfo *)dbptr)->useCount; +} + +void *DatabaseGetNextRecord(void *dbptr, int64_t *idx) +{ + DatabaseInfo *db = dbptr; + void *rec = NULL; + uint32_t i; + + if (dbptr == NULL || idx == NULL || *idx >= UINT32_MAX) { + return NULL; + } + if (*idx >= 0) { + *idx = *idx + 1; + } else { + *idx = 0; + } + + for (i = (uint32_t)(*idx); i < db->maxCount; i++) { + if (IsRecordOccupied(db, i, NULL, NULL)) { + rec = GetRecord(db, i); + *idx = (int64_t)i; + return rec; + } + } + return NULL; +} + +void *DatabaseAllocRecord(void *dbptr) +{ + DatabaseInfo *db = dbptr; + void *rec = NULL; + uint32_t i, j; + + if (dbptr == NULL) { + return NULL; + } + + if (db->useCount >= db->maxCount) { + LOGE(TAG, "DB max limit exceeded maxcnt:%u, usecnt:%u", db->maxCount, db->useCount); + return NULL; + } + + for (i = 0; i < db->mapSize; i++) { + if (db->usedMap[i] == ~(uint32_t)0) { + continue; + } + for (j = 0; j < NSTACKX_USEDMAP_ROW_SIZE; j++) { + if (db->usedMap[i] & (1U << j)) { + continue; + } + rec = GetRecord(db, i * NSTACKX_USEDMAP_ROW_SIZE + j); + if (memset_s(rec, db->recSize, 0, db->recSize) != EOK) { + return NULL; + } else { + db->usedMap[i] |= (1U << j); + db->useCount++; + return rec; + } + } + } + return NULL; +} + +void DatabaseFreeRecord(void *dbptr, const void *ptr) +{ + DatabaseInfo *db = dbptr; + uint32_t i, off; + int64_t recNum; + + if (dbptr == NULL || ptr == NULL || db->useCount == 0) { + LOGE(TAG, "Sanity chk failed"); + return; + } + + recNum = GetRecordIndex(db, ptr); + if (recNum < 0 || recNum >= db->maxCount) { + LOGE(TAG, "Invalid record"); + return; + } + if (!IsRecordOccupied(db, (uint32_t)recNum, &i, &off)) { + LOGE(TAG, "Unused record"); + return; + } + + db->usedMap[i] &= ~(1U << off); + db->useCount--; +} + +void DatabaseClean(void *ptr) +{ + DatabaseInfo *db = ptr; + if (db == NULL) { + return; + } + free(db->blk); + free(db->usedMap); + free(db); +} + +void *DatabaseInit(uint32_t recNumber, size_t recSize, RecCompareCallback cb) +{ + DatabaseInfo *db = NULL; + + if (recNumber == 0 || recSize == 0) { + return NULL; + } + + db = (DatabaseInfo *)calloc(1U, sizeof(DatabaseInfo)); + if (db == NULL) { + LOGE(TAG, "calloc dbinfo failed"); + return NULL; + } + + db->mapSize = recNumber / NSTACKX_USEDMAP_ROW_SIZE + 1; + db->usedMap = calloc(db->mapSize, sizeof(uint32_t)); + if (db->usedMap == NULL) { + LOGE(TAG, "calloc usedmap failed"); + free(db); + return NULL; + } + + db->blk = (uint8_t *)malloc(recNumber * recSize); + if (db->blk == NULL) { + LOGE(TAG, "malloc %u %zu failed", recNumber, recSize); + free(db->usedMap); + free(db); + return NULL; + } + + db->maxCount = recNumber; + db->useCount = 0; + db->recSize = recSize; + db->cb = cb; + + return db; +} \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/core/nstackx_device.c b/components/nstackx/nstackx_ctrl/core/nstackx_device.c new file mode 100644 index 000000000..1bd4dbc45 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/nstackx_device.c @@ -0,0 +1,1306 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_device.h" + +#include +#include +#include +#include +#include +#ifdef SUPPORT_SMARTGENIUS +#include +#include +#endif /* SUPPORT_SMARTGENIUS */ + +#include "cJSON.h" +#include "nstackx_log.h" +#include "nstackx_event.h" +#include "nstackx_timer.h" +#include "nstackx_error.h" +#include "nstackx_util.h" +#include "nstackx_common.h" +#include "nstackx_database.h" +#include "coap_discover/coap_app.h" +#include "coap_discover/coap_discover.h" + +#define TAG "nStackXDFinder" + +#define NSTACKX_OFFLINE_DEFERRED_DURATION 5000 /* Defer local device offline event, 5 seconds */ +#define NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES 4 + +#define NSTACKX_DEFAULT_DEVICE_NAME "nStack Device" + +#define NSTACKX_RESERVED_INFO_WIFI_IP "wifiIpAddr" + +#define NSTACKX_WLAN_INDEX 0 +#define NSTACKX_ETH_INDEX 1 +#define NSTACKX_P2P_INDEX 2 +#define NSTACKX_USB_INDEX 3 +#define NSTACKX_MAX_INTERFACE_NUM 4 +#define NETWORKTYPE_LENGTH 20 +#define NSTACKX_WLAN_INTERFACE_NAME_PREFIX "wlan" +#define NSTACKX_ETH_INTERFACE_NAME_PREFIX "eth" +#define NSTACKX_P2P_INTERFACE_NAME_PREFIX "p2p-p2p0-" +#define NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX "p2p-wlan0-" +#define NSTACKX_USB_INTERFACE_NAME_PREFIX "rndis0" +#define NSTACKX_DEFAULT_VER "1.0.0.0" + +/* + * Reserved info JSON format: + * {"wifiIpAddr":[ip string]} + */ +#define NSTACKX_RESERVED_INFO_JSON_FORMAT \ + "{\"" NSTACKX_RESERVED_INFO_WIFI_IP "\":\"%s\"}" + +#define NET_CHANNEL_INFO_STATE_INVALID(info) \ + ((info)->state <= NET_CHANNEL_STATE_START || (info)->state >= NET_CHANNEL_STATE_END) + +static void *g_deviceList = NULL; +static void *g_deviceListBackup = NULL; +static Timer *g_offlineDeferredTimer = NULL; +static Timer *g_p2pServerInitDeferredTimer = NULL; +static Timer *g_usbServerInitDeferredTimer = NULL; +static uint8_t g_deviceInited; +static DeviceInfo g_localDeviceInfo; +static uint32_t g_filterCapabilityBitmapNum = 0; +static uint32_t g_filterCapabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM] = {0}; +static NetworkInterfaceInfo g_interfaceList[NSTACKX_MAX_INTERFACE_NUM]; +static char g_networkType[NETWORKTYPE_LENGTH] = {0}; +static const uint32_t g_serverInitRetryBackoffList[NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES] = { 10, 15, 25, 100 }; +static uint32_t g_p2pRetryCount = 0; +static uint32_t g_usbRetryCount = 0; + +static struct in_addr g_p2pIp; +static struct in_addr g_usbIp; + +static void DeviceListChangeHandle(void); +static void GetLocalIp(struct in_addr *ip); + +uint8_t ClearDevices(void *deviceList) +{ + int32_t i; + int64_t idx = -1; + DeviceInfo *dev = NULL; + uint8_t deviceRemoved = NSTACKX_FALSE; + + if (deviceList == NULL) { + return deviceRemoved; + } + + for (i = 0; i < NSTACKX_MAX_DEVICE_NUM; i++) { + dev = DatabaseGetNextRecord(deviceList, &idx); + if (dev == NULL) { + break; + } + DatabaseFreeRecord(deviceList, (void *)dev); + deviceRemoved = NSTACKX_TRUE; + } + return deviceRemoved; +} + +static void LocalDeviceOffline(void *data) +{ + uint8_t deviceRemoved; + (void)data; + + (void)ClearDevices(g_deviceListBackup); + LOGW(TAG, "clear device list backup"); + deviceRemoved = ClearDevices(g_deviceList); + LOGW(TAG, "clear device list"); + + CoapServerDestroy(); + + if (deviceRemoved) { + DeviceListChangeHandle(); + } +} + +static void StopP2pServerInitRetryTimer(void) +{ + if (g_p2pRetryCount != 0 && g_p2pServerInitDeferredTimer != NULL) { + TimerSetTimeout(g_p2pServerInitDeferredTimer, 0, NSTACKX_FALSE); // stop previous timer + g_p2pRetryCount = 0; + } +} + +static void StopUsbServerInitRetryTimer(void) +{ + if (g_usbRetryCount != 0 && g_usbServerInitDeferredTimer != NULL) { + TimerSetTimeout(g_usbServerInitDeferredTimer, 0, NSTACKX_FALSE); // stop previous timer + g_usbRetryCount = 0; + (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp)); + } +} + +void DestroyP2pUsbServerInitRetryTimer(void) +{ + if (g_p2pServerInitDeferredTimer != NULL) { + StopP2pServerInitRetryTimer(); + TimerDelete(g_p2pServerInitDeferredTimer); + g_p2pServerInitDeferredTimer = NULL; + } + if (g_usbServerInitDeferredTimer != NULL) { + StopUsbServerInitRetryTimer(); + TimerDelete(g_usbServerInitDeferredTimer); + g_usbServerInitDeferredTimer = NULL; + } +} + +static void CoapP2pServerInitDelayHandler(void *data) +{ + (void)data; + LOGD(TAG, "CoapP2pServerInitDelay, retry %u times", g_p2pRetryCount); + if (CoapP2pServerInit(&g_p2pIp) == NSTACKX_EOK) { + LOGE(TAG, "CoapP2pServerInitDelay success"); + g_p2pRetryCount = 0; + return; + } + if (g_p2pRetryCount >= NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES) { + LOGE(TAG, "CoapP2pServerInitDelay retry reach max times"); + g_p2pRetryCount = 0; + (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp)); + return; + } + TimerSetTimeout(g_p2pServerInitDeferredTimer, g_serverInitRetryBackoffList[g_p2pRetryCount], NSTACKX_FALSE); + g_p2pRetryCount++; +} + +static void CoapUsbServerInitDelayHandler(void *data) +{ + LOGD(TAG, "CoapUsbServerInitDelay, retry %u times", g_usbRetryCount); + (void)data; + if (CoapUsbServerInit(&g_usbIp) == NSTACKX_EOK) { + LOGE(TAG, "CoapUsbServerInitDelay success"); + g_usbRetryCount = 0; + (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp)); + return; + } + if (g_usbRetryCount >= NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES) { + LOGE(TAG, "CoapUsbServerInitDelay retry reach max times"); + g_usbRetryCount = 0; + (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp)); + return; + } + + TimerSetTimeout(g_usbServerInitDeferredTimer, g_serverInitRetryBackoffList[g_usbRetryCount], NSTACKX_FALSE); + g_usbRetryCount++; +} + +int32_t P2pUsbTimerInit(EpollDesc epollfd) +{ + g_p2pRetryCount = 0; + g_usbRetryCount = 0; + g_p2pServerInitDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapP2pServerInitDelayHandler, NULL); + if (g_p2pServerInitDeferredTimer == NULL) { + LOGE(TAG, "g_p2pServerInitDeferredTimer start failed"); + return NSTACKX_EFAILED; + } + (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp)); + g_usbServerInitDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapUsbServerInitDelayHandler, NULL); + if (g_usbServerInitDeferredTimer == NULL) { + LOGE(TAG, "g_UsbServerInitDeferredTimer start failed"); + return NSTACKX_EFAILED; + } + (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp)); + return NSTACKX_EOK; +} + +static DeviceInfo *CreateNewDevice(const DeviceInfo *deviceInfo) +{ + DeviceInfo *internalDevice = NULL; + + /* Allocate DB for newly joined device */ + internalDevice = DatabaseAllocRecord(g_deviceList); + if (internalDevice == NULL) { + LOGE(TAG, "Failed to allocate device info"); + return NULL; + } + + (void)memcpy_s(internalDevice, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo)); + + return internalDevice; +} + +static int32_t UpdateCapabilityBitmap(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, int8_t *updated) +{ + if (internalDevice == NULL || deviceInfo == NULL || updated == NULL) { + LOGE(TAG, "UpdateCapabilityBitmap, input parameter error"); + return NSTACKX_EFAILED; + } + + /* judge capabilityBitmap is or not different with new deviceInfo */ + if ((internalDevice->capabilityBitmapNum != deviceInfo->capabilityBitmapNum) || + (deviceInfo->capabilityBitmapNum && + memcmp(internalDevice->capabilityBitmap, deviceInfo->capabilityBitmap, + deviceInfo->capabilityBitmapNum * sizeof(uint32_t)))) { + *updated = NSTACKX_TRUE; + } + + internalDevice->capabilityBitmapNum = deviceInfo->capabilityBitmapNum; + + if (memset_s(internalDevice->capabilityBitmap, sizeof(internalDevice->capabilityBitmap), + 0, sizeof(internalDevice->capabilityBitmap)) != EOK) { + LOGE(TAG, "UpdateCapabilityBitmap, memset_s fails"); + return NSTACKX_EFAILED; + } + if (deviceInfo->capabilityBitmapNum) { + if (memcpy_s(internalDevice->capabilityBitmap, sizeof(internalDevice->capabilityBitmap), + deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) { + LOGE(TAG, "UpdateCapabilityBitmap, capabilityBitmap copy error"); + return NSTACKX_EFAILED; + } + } + return NSTACKX_EOK; +} + +static int32_t UpdateDeviceInfoInner(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, int8_t *updated) +{ + if (internalDevice == NULL || deviceInfo == NULL) { + LOGE(TAG, "UpdateDeviceInfo input error"); + return NSTACKX_EFAILED; + } + if (internalDevice->deviceType != deviceInfo->deviceType) { + LOGE(TAG, "deviceType is different"); + return NSTACKX_EFAILED; + } + + if (strcmp(internalDevice->deviceName, deviceInfo->deviceName)) { + if (strcpy_s(internalDevice->deviceName, sizeof(internalDevice->deviceName), deviceInfo->deviceName) != EOK) { + LOGE(TAG, "deviceName copy error"); + return NSTACKX_EFAILED; + } + *updated = NSTACKX_TRUE; + } + + if (strlen(deviceInfo->version) > 0 && strcmp(internalDevice->version, deviceInfo->version)) { + if (strcpy_s(internalDevice->version, sizeof(internalDevice->version), deviceInfo->version) != EOK) { + LOGE(TAG, "hicom version copy error"); + return NSTACKX_EFAILED; + } + *updated = NSTACKX_TRUE; + } + + if (UpdateCapabilityBitmap(internalDevice, deviceInfo, updated) != NSTACKX_EOK) { + LOGE(TAG, "UpdateCapabilityBitmap fails"); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +static int32_t UpdateDeviceInfo(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, int8_t *updatedPtr) +{ + int8_t updated = NSTACKX_FALSE; + if (UpdateDeviceInfoInner(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) { + LOGE(TAG, "UpdateDeviceInfoInner error"); + return NSTACKX_EFAILED; + } + + if (strcmp(internalDevice->deviceHash, deviceInfo->deviceHash)) { + if (strcpy_s(internalDevice->deviceHash, sizeof(internalDevice->deviceHash), deviceInfo->deviceHash) != EOK) { + LOGE(TAG, "deviceHash copy error"); + return NSTACKX_EFAILED; + } + updated = NSTACKX_TRUE; + } + + if (internalDevice->mode != deviceInfo->mode) { + internalDevice->mode = deviceInfo->mode; + updated = NSTACKX_TRUE; + } + + if (strcmp(internalDevice->serviceData, deviceInfo->serviceData)) { + if (strcpy_s(internalDevice->serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, deviceInfo->serviceData) != EOK) { + LOGE(TAG, "serviceData copy error"); + return NSTACKX_EFAILED; + } + updated = NSTACKX_TRUE; + } + + if (memcmp(&internalDevice->netChannelInfo, &deviceInfo->netChannelInfo, sizeof(deviceInfo->netChannelInfo)) || + (internalDevice->portNumber != deviceInfo->portNumber)) { + (void)memcpy_s(&internalDevice->netChannelInfo, sizeof(internalDevice->netChannelInfo), + &deviceInfo->netChannelInfo, sizeof(deviceInfo->netChannelInfo)); + internalDevice->portNumber = deviceInfo->portNumber; + updated = NSTACKX_TRUE; + } + + *updatedPtr = updated; + return NSTACKX_EOK; +} + +int32_t UpdateDeviceDb(const DeviceInfo *deviceInfo, uint8_t forceUpdate) +{ + DeviceInfo *internalDevice = NULL; + int8_t updated = NSTACKX_FALSE; + + if (deviceInfo == NULL) { + return NSTACKX_EINVAL; + } + + internalDevice = GetDeviceInfoById(deviceInfo->deviceId, g_deviceList); + if (internalDevice == NULL) { + internalDevice = CreateNewDevice(deviceInfo); + if (internalDevice == NULL) { + return NSTACKX_ENOMEM; + } + updated = NSTACKX_TRUE; + } else { + if (UpdateDeviceInfo(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) { + return NSTACKX_EFAILED; + } + } + internalDevice->update = updated; + + if (updated || forceUpdate) { + DeviceListChangeHandle(); + } + + return NSTACKX_EOK; +} + +static int32_t GetReservedInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList) +{ + 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)); + if (sprintf_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo), + NSTACKX_RESERVED_INFO_JSON_FORMAT, wifiIpAddr) == NSTACKX_EFAILED) { + return NSTACKX_EFAILED; + } + cJSON *item = cJSON_Parse(deviceList[0].reservedInfo); + if (item == NULL) { + LOGE(TAG, "pares deviceList fails"); + return NSTACKX_EFAILED; + } + + if (deviceInfo->mode != DEFAULT_MODE) { + if (!cJSON_AddNumberToObject(item, "mode", deviceInfo->mode)) { + LOGE(TAG, "add mode to object failed"); + } + } + if (!cJSON_AddStringToObject(item, "hwAccountHashVal", deviceInfo->deviceHash)) { + LOGE(TAG, "add hwAccountHashVal to object failed"); + } + const char *ver = (strlen(deviceInfo->version) == 0) ? NSTACKX_DEFAULT_VER : deviceInfo->version; + if (!cJSON_AddStringToObject(item, "version", ver)) { + LOGE(TAG, "add hwAccountHashVal to object failed"); + } + char *newData = cJSON_Print(item); + if (newData == NULL) { + cJSON_Delete(item); + return NSTACKX_EFAILED; + } + (void)memset_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo), 0, + sizeof(deviceList[0].reservedInfo)); + if (strcpy_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo), newData) != EOK) { + cJSON_Delete(item); + free(newData); + return NSTACKX_EFAILED; + } + cJSON_Delete(item); + free(newData); + return NSTACKX_EOK; +} + +void PushPublishInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList, uint32_t deviceNum) +{ + if (deviceNum != PUBLISH_DEVICE_NUM || deviceInfo == NULL) { + return; + } + if (strcpy_s(deviceList[0].deviceId, sizeof(deviceList[0].deviceId), deviceInfo->deviceId) != EOK || + strcpy_s(deviceList[0].deviceName, sizeof(deviceList[0].deviceName), deviceInfo->deviceName) != EOK || + strcpy_s(deviceList[0].version, sizeof(deviceList[0].version), deviceInfo->version) != EOK) { + return; + } + deviceList[0].capabilityBitmapNum = deviceInfo->capabilityBitmapNum; + if (deviceInfo->capabilityBitmapNum) { + if (memcpy_s(deviceList[0].capabilityBitmap, sizeof(deviceList[0].capabilityBitmap), + deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) { + return; + } + } + + if (GetReservedInfo(deviceInfo, deviceList) != NSTACKX_EOK) { + LOGE(TAG, "GetReservedInfo Failed"); + return; + } + deviceList[0].deviceType = deviceInfo->deviceType; +} + +static bool MatchDeviceFilter(DeviceInfo *deviceInfo) +{ + uint32_t i, ret; + + if (g_filterCapabilityBitmapNum == 0) { + return true; + } + + for (i = 0; ((i < g_filterCapabilityBitmapNum) && (i < deviceInfo->capabilityBitmapNum)); i++) { + ret = (g_filterCapabilityBitmap[i] & (deviceInfo->capabilityBitmap[i])); + if (ret != 0) { + return true; + } + } + return false; +} + +void GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter) +{ + DeviceInfo *deviceInfo = NULL; + int64_t idx = -1; + uint32_t count = 0; + int32_t i; + + for (i = 0; i < NSTACKX_MAX_DEVICE_NUM; i++) { + if (count >= *deviceCountPtr) { + break; + } + + deviceInfo = DatabaseGetNextRecord(g_deviceList, &idx); + if (deviceInfo == NULL) { + break; + } + + if (doFilter && !MatchDeviceFilter(deviceInfo)) { + continue; + } + + if (strcpy_s(deviceList[count].deviceId, sizeof(deviceList[count].deviceId), deviceInfo->deviceId) != EOK || + strcpy_s(deviceList[count].deviceName, sizeof(deviceList[count].deviceName), + deviceInfo->deviceName) != EOK || + strcpy_s(deviceList[count].version, sizeof(deviceList[count].version), deviceInfo->version) != EOK) { + break; + } + deviceList[count].capabilityBitmapNum = deviceInfo->capabilityBitmapNum; + if (deviceInfo->capabilityBitmapNum) { + if (memcpy_s(deviceList[count].capabilityBitmap, sizeof(deviceList[count].capabilityBitmap), + deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) { + break; + } + } + + int8_t result = SetReservedInfoFromDeviceInfo(deviceList, count, deviceInfo); + if (result == NSTACKX_EAGAIN) { + LOGE(TAG, "SetReservedInfoFromDeviceInfo fails, sprintf_s or strcpy_s fails"); + break; + } else if (result == NSTACKX_EINVAL || result == NSTACKX_EFAILED) { + LOGE(TAG, "SetReservedInfoFromDeviceInfo fails"); + return; + } + + deviceList[count].deviceType = deviceInfo->deviceType; + deviceList[count].mode = deviceInfo->mode; + deviceList[count].update = deviceInfo->update; + deviceInfo->update = NSTACKX_FALSE; + ++count; + } + + *deviceCountPtr = count; +} + +int8_t SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t count, DeviceInfo *deviceInfo) +{ + char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN]; + int ret = NSTACKX_EFAILED; + if (deviceList == NULL) { + LOGE(TAG, "deviceList or deviceInfo is null"); + return NSTACKX_EINVAL; + } + + (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr)); + (void)inet_ntop(AF_INET, &deviceInfo->netChannelInfo.wifiApInfo.ip, wifiIpAddr, sizeof(wifiIpAddr)); + if (sprintf_s(deviceList[count].reservedInfo, sizeof(deviceList[count].reservedInfo), + NSTACKX_RESERVED_INFO_JSON_FORMAT, wifiIpAddr) == -1) { + LOGE(TAG, "sprintf_s reservedInfo with wifiIpAddr fails"); + return NSTACKX_EAGAIN; + } + cJSON *item = cJSON_Parse(deviceList[count].reservedInfo); + if (item == NULL) { + LOGE(TAG, "pares deviceList fails"); + return NSTACKX_EINVAL; + } + + if (deviceInfo->mode != 0 && !cJSON_AddNumberToObject(item, "mode", deviceInfo->mode)) { + goto L_END; + } + if (!cJSON_AddStringToObject(item, "hwAccountHashVal", deviceInfo->deviceHash)) { + goto L_END; + } + const char *ver = (strlen(deviceInfo->version) == 0) ? NSTACKX_DEFAULT_VER : deviceInfo->version; + if (!cJSON_AddStringToObject(item, "version", ver)) { + goto L_END; + } + if (strlen(deviceInfo->serviceData) != 0 && strlen(deviceInfo->serviceData) < NSTACKX_MAX_SERVICE_DATA_LEN) { + if (!cJSON_AddStringToObject(item, "serviceData", deviceInfo->serviceData)) { + goto L_END; + } + } + char *newData = cJSON_Print(item); + if (newData == NULL) { + goto L_END; + } + (void)memset_s(deviceList[count].reservedInfo, sizeof(deviceList[count].reservedInfo), + 0, sizeof(deviceList[count].reservedInfo)); + if (strcpy_s(deviceList[count].reservedInfo, sizeof(deviceList[count].reservedInfo), newData) != EOK) { + free(newData); + LOGE(TAG, "strcpy_s fails"); + goto L_END; + } + free(newData); + ret = NSTACKX_EOK; +L_END: + cJSON_Delete(item); + return ret; +} + +static void DeviceListChangeHandle(void) +{ + NSTACKX_DeviceInfo deviceList[NSTACKX_MAX_DEVICE_NUM]; + uint32_t count = NSTACKX_MAX_DEVICE_NUM; + + (void)memset_s(deviceList, sizeof(deviceList), 0, sizeof(deviceList)); + GetDeviceList(deviceList, &count, true); + + NotifyDeviceListChanged(deviceList, count); + if (CoapDiscoverRequestOngoing()) { + NotifyDeviceFound(deviceList, count); + } +} + +DeviceInfo *GetDeviceInfoById(const char *deviceId, const void *db) +{ + DeviceInfo dev; + (void)memset_s(&dev, sizeof(dev), 0, sizeof(dev)); + if (strcpy_s(dev.deviceId, sizeof(dev.deviceId), deviceId) != EOK) { + return NULL; + } + return DatabaseSearchRecord(db, &dev); +} + +static uint8_t IsSameDevice(void *recptr, void *myptr) +{ + DeviceInfo *rec = recptr; + DeviceInfo *my = myptr; + + if (recptr == NULL || myptr == NULL) { + LOGE(TAG, "NULL input, can't compare"); + return NSTACKX_FALSE; + } + + if (strcmp(rec->deviceId, my->deviceId) == 0) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +static const NetworkInterfaceInfo *GetLocalInterface(void) +{ + /* Ethernet have higher priority */ + if (g_interfaceList[NSTACKX_ETH_INDEX].ip.s_addr) { + return &g_interfaceList[NSTACKX_ETH_INDEX]; + } + + if (g_interfaceList[NSTACKX_WLAN_INDEX].ip.s_addr) { + return &g_interfaceList[NSTACKX_WLAN_INDEX]; + } + + if (g_interfaceList[NSTACKX_P2P_INDEX].ip.s_addr) { + return &g_interfaceList[NSTACKX_P2P_INDEX]; + } + + if (g_interfaceList[NSTACKX_USB_INDEX].ip.s_addr) { + return &g_interfaceList[NSTACKX_USB_INDEX]; + } + + return NULL; +} + +static void GetLocalIp(struct in_addr *ip) +{ + const NetworkInterfaceInfo *ifInfo = GetLocalInterface(); + if (ifInfo != NULL) { + (void)memcpy_s(ip, sizeof(struct in_addr), + &ifInfo->ip, sizeof(struct in_addr)); + } else { + (void)memset_s(ip, sizeof(struct in_addr), 0, sizeof(struct in_addr)); + } +} + +/* Return NSTACKX_TRUE if ifName prefix is the same, else return false */ +static uint8_t NetworkInterfaceNamePrefixCmp(const char *ifName, const char *prefix) +{ + if (strlen(ifName) < strlen(prefix)) { + return NSTACKX_FALSE; + } + + if (memcmp(ifName, prefix, strlen(prefix)) == 0) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +int32_t UpdateLocalNetworkInterface(const NetworkInterfaceInfo *interfaceInfo) +{ + uint32_t i; + struct in_addr preIp, newIp; + + if (interfaceInfo == NULL) { + return NSTACKX_EINVAL; + } + + GetLocalIp(&preIp); + for (i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) { + if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[i].name) && + (i == NSTACKX_ETH_INDEX || i == NSTACKX_WLAN_INDEX)) { + (void)memcpy_s(&g_interfaceList[i].ip, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)); + break; + } + } + + if (i == NSTACKX_MAX_INTERFACE_NUM) { + return NSTACKX_EINVAL; + } + + GetLocalIp(&newIp); + if (newIp.s_addr == preIp.s_addr) { + LOGI(TAG, "ip not changed"); + return NSTACKX_EOK; + } + + /* Cleanup device db when Wifi AP disconnected. */ + if (interfaceInfo->ip.s_addr == 0) { + /* + * We don't cleanup DB and transport immediately. + * Instead, defer the event for a while in case WiFi connected again. + */ + LOGE(TAG, "g_networkType is %s and interfaceInfo is %s", g_networkType, interfaceInfo->name); + if (strcmp(g_networkType, interfaceInfo->name) != 0 && strcmp(g_networkType, "") != 0) { + LOGE(TAG, "into ignore"); + return NSTACKX_EOK; + } + TimerSetTimeout(g_offlineDeferredTimer, NSTACKX_OFFLINE_DEFERRED_DURATION, NSTACKX_FALSE); + } else { + TimerSetTimeout(g_offlineDeferredTimer, 0, NSTACKX_FALSE); + int ret = memcpy_s(g_networkType, sizeof(g_networkType), interfaceInfo->name, sizeof(interfaceInfo->name)); + if (ret != EOK) { + LOGE(TAG, "memcpy_s error"); + return NSTACKX_EFAILED; + } + struct in_addr ip; + (void)memcpy_s(&ip, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)); + CoapServerInit(&ip); + } + + return NSTACKX_EOK; +} + +void SetP2pIp(const struct in_addr *ip) +{ + if (ip == NULL) { + return; + } + if (memcpy_s(&g_p2pIp, sizeof(struct in_addr), ip, sizeof(struct in_addr)) != EOK) { + LOGE(TAG, "memcpy_s failed"); + } +} + +static void TryToInitP2pCoapServer(struct in_addr ip) +{ + /* ignore p2p service when new ip is 0. */ + if (ip.s_addr == 0) { + LOGE(TAG, "p2p newIp is 0"); + return; + } + StopP2pServerInitRetryTimer(); + if (CoapP2pServerInit(&ip) != NSTACKX_EOK) { /* If init fail, start retry */ + LOGE(TAG, "start p2p init delayed"); + if (g_p2pServerInitDeferredTimer == NULL) { + return; + } + /* if CoapP2pServerInit failed, update the g_p2pIp */ + SetP2pIp(&ip); + TimerSetTimeout(g_p2pServerInitDeferredTimer, g_serverInitRetryBackoffList[0], NSTACKX_FALSE); + g_p2pRetryCount++; + return; + } + LOGD(TAG, "start p2p init success"); +} + +int32_t UpdateLocalNetworkInterfaceP2pMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType) +{ + struct in_addr newIp; + + if (interfaceInfo == NULL) { + return NSTACKX_EINVAL; + } + +#ifdef SUPPORT_SMARTGENIUS + if (nlmsgType == RTM_DELADDR) { + LOGD(TAG, "p2p delete address, call CoapP2pServerDestroy()"); + CoapP2pServerDestroy(); + StopP2pServerInitRetryTimer(); + (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp)); + return NSTACKX_EOK; + } +#else + (void)nlmsgType; +#endif /* SUPPORT_SMARTGENIUS */ + + /* p2p new ip does not write to g_interfaceList */ + if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_P2P_INDEX].name) || + NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_P2P_INDEX].alias)) { + if (memcpy_s(&newIp, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)) != EOK) { + LOGE(TAG, "newIp memcpy_s failed"); + return NSTACKX_EFAILED; + } + } else { + LOGI(TAG, "NetworkInterfaceNamePrefixCmp p2p fail"); + return NSTACKX_EINVAL; + } + TryToInitP2pCoapServer(newIp); + return NSTACKX_EOK; +} + +void SetUsbIp(const struct in_addr *ip) +{ + if (ip == NULL) { + return; + } + if (memcpy_s(&g_usbIp, sizeof(struct in_addr), ip, sizeof(struct in_addr)) != EOK) { + LOGE(TAG, "memcpy_s failed"); + } +} + +static void TryToInitUsbCoapServer(struct in_addr ip) +{ + /* ignore usb service when new ip is 0. */ + if (ip.s_addr == 0) { + LOGE(TAG, "usb newIp is 0"); + return; + } + + StopUsbServerInitRetryTimer(); + if (CoapUsbServerInit(&ip) != NSTACKX_EOK) { + LOGE(TAG, "start usb init delayed"); + if (g_usbServerInitDeferredTimer == NULL) { + return; + } + + /* if CoapUsbServerInit failed, update the g_p2pIp */ + SetUsbIp(&ip); + + TimerSetTimeout(g_usbServerInitDeferredTimer, g_serverInitRetryBackoffList[0], NSTACKX_FALSE); + g_usbRetryCount++; + return; + } + LOGI(TAG, "start usb init success"); +} + +int32_t UpdateLocalNetworkInterfaceUsbMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType) +{ + struct in_addr newIp; + + if (interfaceInfo == NULL) { + return NSTACKX_EINVAL; + } + +#ifdef SUPPORT_SMARTGENIUS + if (nlmsgType == RTM_DELADDR) { + LOGD(TAG, "usb delete address, call CoapUsbServerDestroy()"); + CoapUsbServerDestroy(); + StopUsbServerInitRetryTimer(); + (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp)); + return NSTACKX_EOK; + } +#else + (void)nlmsgType; +#endif /* SUPPORT_SMARTGENIUS */ + + /* usb new ip does not write to g_interfaceList */ + if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_USB_INDEX].name)) { + if (memcpy_s(&newIp, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)) != EOK) { + LOGE(TAG, "newIp memcpy_s failed"); + return NSTACKX_EFAILED; + } + } else { + return NSTACKX_EINVAL; + } + TryToInitUsbCoapServer(newIp); + return NSTACKX_EOK; +} + +void SetModeInfo(uint8_t mode) +{ + g_localDeviceInfo.mode = mode; +} + +uint8_t GetModeInfo(void) +{ + return g_localDeviceInfo.mode; +} + +void SetDeviceHash(uint64_t deviceHash) +{ + (void)memset_s(g_localDeviceInfo.deviceHash, sizeof(g_localDeviceInfo.deviceHash), + 0, sizeof(g_localDeviceInfo.deviceHash)); + if (sprintf_s(g_localDeviceInfo.deviceHash, DEVICE_HASH_LEN, + "%ju", deviceHash) == -1) { + LOGE(TAG, "set device hash error"); + } +} + +int32_t ConfigureLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *localDeviceInfo) +{ + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN]; + struct in_addr ipAddr; + NetworkInterfaceInfo interfaceInfo; + + (void)memset_s(&interfaceInfo, sizeof(interfaceInfo), 0, sizeof(interfaceInfo)); + /* Backup device id */ + (void)memcpy_s(deviceId, sizeof(deviceId), g_localDeviceInfo.deviceId, sizeof(deviceId)); + if (strcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId), localDeviceInfo->deviceId) != EOK) { + LOGE(TAG, "Invalid device id!"); + /* Restore device id if some error happens */ + if (memcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId), + deviceId, sizeof(deviceId)) != EOK) { + LOGE(TAG, "deviceId copy error and can't restore device id!"); + } + return NSTACKX_EINVAL; + } + + if ((inet_pton(AF_INET, localDeviceInfo->networkIpAddr, &ipAddr) == 1) && + (strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), localDeviceInfo->networkName) == EOK)) { + interfaceInfo.ip = ipAddr; + UpdateLocalNetworkInterface(&interfaceInfo); + } else { + LOGD(TAG, "Invalid if name or ip address. Ignore"); + } + + if (strlen(localDeviceInfo->name) == 0 || (strncpy_s(g_localDeviceInfo.deviceName, + sizeof(g_localDeviceInfo.deviceName), localDeviceInfo->name, NSTACKX_MAX_DEVICE_NAME_LEN - 1) != EOK)) { + LOGW(TAG, "Invalid device name. Will use default name"); + (void)strcpy_s(g_localDeviceInfo.deviceName, sizeof(g_localDeviceInfo.deviceName), NSTACKX_DEFAULT_DEVICE_NAME); + } + + if (strcpy_s(g_localDeviceInfo.version, sizeof(g_localDeviceInfo.version), localDeviceInfo->version) != EOK) { + LOGE(TAG, "Invalid version!"); + return NSTACKX_EINVAL; + } + + g_localDeviceInfo.deviceType = localDeviceInfo->deviceType; + + return NSTACKX_EOK; +} + +const DeviceInfo *GetLocalDeviceInfoPtr(void) +{ + return &g_localDeviceInfo; +} + +uint8_t IsWifiApConnected(void) +{ + struct in_addr ip; + GetLocalIp(&ip); + if (ip.s_addr != 0) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +int32_t GetLocalIpString(char *ipString, size_t length) +{ + struct in_addr ip; + GetLocalIp(&ip); + if (ip.s_addr == 0) { + return NSTACKX_EFAILED; + } + if (inet_ntop(AF_INET, &ip, ipString, length) == NULL) { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t GetP2pIpString(char *ipString, size_t length) +{ + if (ipString == NULL || length == 0) { + return NSTACKX_EFAILED; + } + if (inet_ntop(AF_INET, &g_p2pIp, ipString, length) == NULL) { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t GetUsbIpString(char *ipString, size_t length) +{ + if (ipString == NULL || length == 0) { + return NSTACKX_EFAILED; + } + if (inet_ntop(AF_INET, &g_usbIp, ipString, length) == NULL) { + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t GetLocalInterfaceName(char *ifName, size_t ifNameLength) +{ + const NetworkInterfaceInfo *ifInfo = GetLocalInterface(); + if (ifInfo == NULL) { + return NSTACKX_EFAILED; + } + + if (strcpy_s(ifName, ifNameLength, ifInfo->name) != EOK) { + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +uint8_t FilterNetworkInterface(const char *ifName) +{ + uint32_t i; + if (ifName == NULL) { + return NSTACKX_FALSE; + } + + for (i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) { + if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[i].name) || + NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[i].alias)) { + return NSTACKX_TRUE; + } + } + return NSTACKX_FALSE; +} + +uint8_t IsWlanIpAddr(const char *ifName) +{ + if (ifName == NULL) { + return NSTACKX_FALSE; + } + + if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_WLAN_INDEX].name)) { + LOGE(TAG, "IsWlanIpAddr success"); + return NSTACKX_TRUE; + } + + return NSTACKX_FALSE; +} + +uint8_t IsEthIpAddr(const char *ifName) +{ + if (ifName == NULL) { + return NSTACKX_FALSE; + } + + if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_ETH_INDEX].name)) { + LOGE(TAG, "IsEthIpAddr success"); + return NSTACKX_TRUE; + } + + return NSTACKX_FALSE; +} + +uint8_t IsP2pIpAddr(const char *ifName) +{ + if (ifName == NULL) { + return NSTACKX_FALSE; + } + + if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_P2P_INDEX].name) || + NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_P2P_INDEX].alias)) { + LOGE(TAG, "IsP2pIpAddr success"); + return NSTACKX_TRUE; + } + + return NSTACKX_FALSE; +} + +uint8_t IsUsbIpAddr(const char *ifName) +{ + if (ifName == NULL) { + return NSTACKX_FALSE; + } + + if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_USB_INDEX].name)) { + LOGE(TAG, "IsUsbIpAddr success"); + return NSTACKX_TRUE; + } + + return NSTACKX_FALSE; +} + +int32_t RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + (void)memset_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap), + 0, sizeof(g_localDeviceInfo.capabilityBitmap)); + if (capabilityBitmapNum) { + if (memcpy_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap), + capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) { + LOGE(TAG, "capabilityBitmap copy error"); + return NSTACKX_EFAILED; + } + } + g_localDeviceInfo.capabilityBitmapNum = capabilityBitmapNum; + return NSTACKX_EOK; +} + +int32_t SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + (void)memset_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap), + 0, sizeof(g_filterCapabilityBitmap)); + if (capabilityBitmapNum) { + if (memcpy_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap), + capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) { + LOGE(TAG, "FilterCapabilityBitmap copy error"); + return NSTACKX_EFAILED; + } + } + g_filterCapabilityBitmapNum = capabilityBitmapNum; + return NSTACKX_EOK; +} + +int32_t RegisterServiceData(const char *serviceData) +{ + if (serviceData == NULL) { + LOGE(TAG, "device db init failed"); + return NSTACKX_EINVAL; + } + + if (strcpy_s(g_localDeviceInfo.serviceData, NSTACKX_MAX_SERVICE_DATA_LEN - 1, serviceData) != EOK) { + LOGE(TAG, "serviceData copy error"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +void DeviceModuleClean(void) +{ + if (g_deviceInited == NSTACKX_FALSE) { + return; + } + + TimerDelete(g_offlineDeferredTimer); + g_offlineDeferredTimer = NULL; + + if (g_deviceList != NULL) { + ClearDevices(g_deviceList); + LOGW(TAG, "clear device list"); + DatabaseClean(g_deviceList); + g_deviceList = NULL; + } + if (g_deviceListBackup != NULL) { + ClearDevices(g_deviceListBackup); + LOGW(TAG, "clear device list backup"); + DatabaseClean(g_deviceListBackup); + g_deviceListBackup = NULL; + } + + g_deviceInited = NSTACKX_FALSE; + return; +} + +int32_t DeviceModuleInit(EpollDesc epollfd) +{ + int32_t ret = NSTACKX_EFAILED; + + if (g_deviceInited) { + return NSTACKX_EOK; + } + (void)memset_s(&g_localDeviceInfo, sizeof(g_localDeviceInfo), 0, sizeof(g_localDeviceInfo)); + (void)memset_s(g_networkType, sizeof(g_networkType), 0, sizeof(g_networkType)); + g_deviceList = DatabaseInit(NSTACKX_MAX_DEVICE_NUM, sizeof(DeviceInfo), IsSameDevice); + if (g_deviceList == NULL) { + LOGE(TAG, "device db init failed"); + ret = NSTACKX_ENOMEM; + goto L_ERR_DEVICE_DB_LIST; + } + g_deviceListBackup = DatabaseInit(NSTACKX_MAX_DEVICE_NUM, sizeof(DeviceInfo), IsSameDevice); + if (g_deviceListBackup == NULL) { + LOGE(TAG, "device db backup init failed"); + ret = NSTACKX_ENOMEM; + goto L_ERR_DEVICE_DB_BACKUP_LIST; + } + + g_offlineDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, LocalDeviceOffline, NULL); + if (g_offlineDeferredTimer == NULL) { + LOGE(TAG, "device offline deferred timer start failed"); + goto L_ERR_DEFERRED_TIMER; + } + (void)memset_s(g_interfaceList, sizeof(g_interfaceList), 0, sizeof(g_interfaceList)); + (void)strcpy_s(g_interfaceList[NSTACKX_WLAN_INDEX].name, + sizeof(g_interfaceList[NSTACKX_WLAN_INDEX].name), NSTACKX_WLAN_INTERFACE_NAME_PREFIX); + (void)strcpy_s(g_interfaceList[NSTACKX_ETH_INDEX].name, + sizeof(g_interfaceList[NSTACKX_ETH_INDEX].name), NSTACKX_ETH_INTERFACE_NAME_PREFIX); + (void)strcpy_s(g_interfaceList[NSTACKX_P2P_INDEX].name, + sizeof(g_interfaceList[NSTACKX_P2P_INDEX].name), NSTACKX_P2P_INTERFACE_NAME_PREFIX); + (void)strcpy_s(g_interfaceList[NSTACKX_P2P_INDEX].alias, + sizeof(g_interfaceList[NSTACKX_P2P_INDEX].alias), NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX); + (void)strcpy_s(g_interfaceList[NSTACKX_USB_INDEX].name, + sizeof(g_interfaceList[NSTACKX_USB_INDEX].name), NSTACKX_USB_INTERFACE_NAME_PREFIX); + g_deviceInited = NSTACKX_TRUE; + return NSTACKX_EOK; + + /* Call TimerDelete(g_offlineDeferredTimer) when add module. */ +L_ERR_DEFERRED_TIMER: + DatabaseClean(g_deviceListBackup); + g_deviceListBackup = NULL; +L_ERR_DEVICE_DB_BACKUP_LIST: + DatabaseClean(g_deviceList); + g_deviceList = NULL; +L_ERR_DEVICE_DB_LIST: + return ret; +} + +int32_t BackupDeviceDB(void) +{ + void *db = g_deviceList; + void *backupDB = g_deviceListBackup; + int64_t idx = -1; + DeviceInfo *deviceInfo = NULL; + + if (db == NULL || backupDB == NULL) { + return NSTACKX_EFAILED; + } + uint8_t result = ClearDevices(backupDB); + if (result == NSTACKX_FALSE) { + LOGE(TAG, "clear backupDB error"); + } + + for (int i = 0; i < NSTACKX_MAX_DEVICE_NUM; i++) { + deviceInfo = DatabaseGetNextRecord(db, &idx); + if (deviceInfo == NULL) { + break; + } + + DeviceInfo *newDeviceInfo = DatabaseAllocRecord(backupDB); + if (newDeviceInfo == NULL) { + LOGE(TAG, "allocate device info failure"); + return NSTACKX_EFAILED; + } + if (memcpy_s(newDeviceInfo, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo)) != EOK) { + LOGE(TAG, "memcpy failure"); + return NSTACKX_EFAILED; + } + } + return NSTACKX_EOK; +} + +void *GetDeviceDB(void) +{ + return g_deviceList; +} + +void *GetDeviceDBBackup(void) +{ + return g_deviceListBackup; +} + +static void PadNetworkInterfaceInfo(NetworkInterfaceInfo *intInfo, const struct in_addr *addr, const char *name) +{ + if (intInfo == NULL || addr == NULL || name == NULL) { + return; + } + (void)memset_s(intInfo, sizeof(NetworkInterfaceInfo), 0, sizeof(NetworkInterfaceInfo)); + (void)memcpy_s(&intInfo->ip, sizeof(struct in_addr), addr, sizeof(struct in_addr)); + if (strcpy_s(intInfo->name, sizeof(intInfo->name), name) != EOK) { + LOGE(TAG, "interface name copy failed"); + } +} + +void GetLocalNetworkInterface(void *arg) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + uint8_t isUpdated[NSTACKX_MAX_INTERFACE_NUM] = {0}; + NetworkInterfaceInfo wlanIntInfo, ethIntInfo; + (void)arg; + int fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + return; + } + + int interfaceNum = ifc.ifc_len / sizeof(struct ifreq); + for (int i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + /* get IP of this interface */ + int state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + close(fd); + return; + } else if (state == NSTACKX_EINVAL) { + continue; + } + struct sockaddr_in *sa = (struct sockaddr_in *)&(buf[i].ifr_addr); + if (IsEthIpAddr(buf[i].ifr_name) && !isUpdated[NSTACKX_ETH_INDEX]) { + PadNetworkInterfaceInfo(ðIntInfo, &sa->sin_addr, buf[i].ifr_name); + isUpdated[NSTACKX_ETH_INDEX] = NSTACKX_TRUE; + continue; + } + if (IsWlanIpAddr(buf[i].ifr_name) && !isUpdated[NSTACKX_WLAN_INDEX]) { + PadNetworkInterfaceInfo(&wlanIntInfo, &sa->sin_addr, buf[i].ifr_name); + isUpdated[NSTACKX_WLAN_INDEX] = NSTACKX_TRUE; + continue; + } + + /* p2p or usb new ip does not write to g_interfaceList */ + if (IsP2pIpAddr(buf[i].ifr_name) && !isUpdated[NSTACKX_P2P_INDEX]) { + TryToInitP2pCoapServer(sa->sin_addr); + isUpdated[NSTACKX_P2P_INDEX] = NSTACKX_TRUE; + continue; + } + if (IsUsbIpAddr(buf[i].ifr_name) && !isUpdated[NSTACKX_USB_INDEX]) { + TryToInitUsbCoapServer(sa->sin_addr); + isUpdated[NSTACKX_USB_INDEX] = NSTACKX_TRUE; + continue; + } + } + close(fd); + if (isUpdated[NSTACKX_ETH_INDEX] && UpdateLocalNetworkInterface(ðIntInfo) != NSTACKX_EOK) { + LOGE(TAG, "Update eth interface failed"); + } + if (!isUpdated[NSTACKX_ETH_INDEX] && isUpdated[NSTACKX_WLAN_INDEX] && + UpdateLocalNetworkInterface(&wlanIntInfo) != NSTACKX_EOK) { + LOGE(TAG, "Update wlan interface failed"); + } +} + +void ResetDeviceTaskCount(uint8_t isBusy) +{ + if (g_offlineDeferredTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_offlineDeferredTimer task count %llu", + g_offlineDeferredTimer->task.count); + } + g_offlineDeferredTimer->task.count = 0; + } + + if (g_p2pServerInitDeferredTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_p2pServerInitDeferredTimer task count %llu", + g_p2pServerInitDeferredTimer->task.count); + } + g_p2pServerInitDeferredTimer->task.count = 0; + } + + if (g_usbServerInitDeferredTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_usbServerInitDeferredTimer task count %llu", + g_usbServerInitDeferredTimer->task.count); + } + g_usbServerInitDeferredTimer->task.count = 0; + } +} + diff --git a/components/nstackx/nstackx_ctrl/core/nstackx_smartgenius.c b/components/nstackx/nstackx_ctrl/core/nstackx_smartgenius.c new file mode 100644 index 000000000..193710177 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/core/nstackx_smartgenius.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_smartgenius.h" +#include +#include +#include +#include +#ifdef SUPPORT_SMARTGENIUS +#include +#include +#include +#include +#endif /* SUPPORT_SMARTGENIUS */ + +#include "nstackx_log.h" +#include "nstackx_error.h" +#include "nstackx_util.h" +#include "nstackx_epoll.h" +#include "nstackx_device.h" +#include "nstackx_timer.h" +#include "coap_discover/coap_discover.h" + +#define TAG "nStackXDFinder" +#ifdef SUPPORT_SMARTGENIUS +#define BUFLEN 256 +#define NSTACKX_POSTPONE_DELAY_MS 500 +static EpollTask g_netlinkTask; +static Timer *g_postponeTimer; +static uint8_t g_smartGeniusInit = NSTACKX_FALSE; + +static void ParseRTattr(struct rtattr **tb, uint32_t max, struct rtattr *attr, uint32_t len) +{ + /* + * Use macro RTA_OK() and RTA_NEXT() to iterate attribute list, and fill table "tb" with attribute whose type is not + * greater than "max". + */ + for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) { + if (attr->rta_type <= max) { + tb[attr->rta_type] = attr; + } + } +} + +static void IfAddrMsgHandle(struct nlmsghdr *msgHdr) +{ + struct rtattr *tb[IFA_MAX + 1] = {0}; /* Table to store rtnetlink attribute pointers */ + struct ifaddrmsg *ifAddr = NLMSG_DATA(msgHdr); /* Get IP address information from message */ + if (msgHdr->nlmsg_len < NLMSG_SPACE(sizeof(struct ifaddrmsg))) { + return; + } + uint32_t len = msgHdr->nlmsg_len - NLMSG_SPACE(sizeof(struct ifaddrmsg)); + NetworkInterfaceInfo interfaceInfo; + + (void)memset_s(&interfaceInfo, sizeof(interfaceInfo), 0, sizeof(interfaceInfo)); + /* Parse attribute in "ifAddr", and store attribute pointers in "tb" */ + ParseRTattr(tb, IFA_MAX, IFA_RTA(ifAddr), len); + if (tb[IFA_LABEL] == NULL || tb[IFA_ADDRESS] == NULL) { + return; + } + + /* Use macro RTA_DATA() to get network insterface name from attribute "IFA_LABEL". */ + if (!FilterNetworkInterface((char *)RTA_DATA(tb[IFA_LABEL]))) { + return; + } + + if (ifAddr->ifa_family != AF_INET) { + return; + } + + if (strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), (char *)RTA_DATA(tb[IFA_LABEL])) != EOK) { + return; + } + + if (msgHdr->nlmsg_type == RTM_NEWADDR) { + if (memcpy_s(&interfaceInfo.ip, sizeof(interfaceInfo.ip), + RTA_DATA(tb[IFA_ADDRESS]), sizeof(interfaceInfo.ip)) != EOK) { + return; + } + /* delay 500 ms after WiFi connection avoid "Network Unreachable" error, only activate when wlan/eth online */ + if (!(IsUsbIpAddr((char *)RTA_DATA(tb[IFA_LABEL])) || IsP2pIpAddr((char *)RTA_DATA(tb[IFA_LABEL])))) { + TimerSetTimeout(g_postponeTimer, NSTACKX_POSTPONE_DELAY_MS, NSTACKX_FALSE); + } + LOGD(TAG, "Interface %s got new address.", interfaceInfo.name); + } else { + LOGD(TAG, "Interface %s delete address.", interfaceInfo.name); + } + + if (IsP2pIpAddr((char *)RTA_DATA(tb[IFA_LABEL]))) { + UpdateLocalNetworkInterfaceP2pMode(&interfaceInfo, msgHdr->nlmsg_type); + } else if (IsUsbIpAddr((char *)RTA_DATA(tb[IFA_LABEL]))) { + UpdateLocalNetworkInterfaceUsbMode(&interfaceInfo, msgHdr->nlmsg_type); + } else { + UpdateLocalNetworkInterface(&interfaceInfo); + } +} + +static void SmartGeniusCallback(void *arg) +{ + struct nlmsghdr *innerNlmsghdr = NULL; + struct nlmsgerr *nlmErr = NULL; + char innerBuf[BUFLEN] = {0}; + struct sockaddr_nl peer = {AF_NETLINK, 0, 0, 0}; + int len; + socklen_t socklen; + EpollTask *task = arg; + + socklen = sizeof(struct sockaddr_nl); + len = recvfrom(task->taskfd, innerBuf, BUFLEN, 0, (struct sockaddr *)&peer, &socklen); + if (len <= 0) { + LOGE(TAG, "recvfrom error %d", errno); + return; + } + + innerNlmsghdr = (struct nlmsghdr *)innerBuf; + switch (innerNlmsghdr->nlmsg_type) { + case RTM_NEWADDR: + case RTM_DELADDR: { + IfAddrMsgHandle(innerNlmsghdr); + break; + } + case NLMSG_ERROR: { + nlmErr = NLMSG_DATA(innerNlmsghdr); + if (nlmErr->error == 0) { + LOGD(TAG, "NLMSG_ACK"); + } else { + LOGE(TAG, "NLMSG_ERROR"); + } + break; + } + default: + break; + } + return; +} + +static void PostponeTimerHandle(void *data) +{ + (void)data; + CoapServiceDiscoverInner(0); +} + +int32_t SmartGeniusInit(EpollDesc epollfd) +{ + socklen_t len; + struct sockaddr_nl local = {0}; + int fd = -1; + + if (g_smartGeniusInit) { + return NSTACKX_EOK; + } + + local.nl_family = AF_NETLINK; + local.nl_groups = RTMGRP_NOTIFY | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_LINK; + local.nl_pid = getpid(); + len = sizeof(local); + + fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) { + LOGE(TAG, "unable to create netlink socket: %d", errno); + return NSTACKX_EFAILED; + } + + if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) { + LOGE(TAG, "bind for netlink socket failed: %d", errno); + close(fd); + return NSTACKX_EFAILED; + } + + if (getsockname(fd, (struct sockaddr *)&local, &len) < 0) { + LOGE(TAG, "getsockname failed: %d", errno); + close(fd); + return NSTACKX_EFAILED; + } + + g_netlinkTask.taskfd = fd; + g_netlinkTask.epollfd = epollfd; + g_netlinkTask.readHandle = SmartGeniusCallback; + g_netlinkTask.writeHandle = NULL; + g_netlinkTask.errorHandle = NULL; + g_netlinkTask.endHandle = NULL; + g_netlinkTask.count = 0; + if (RegisterEpollTask(&g_netlinkTask, EPOLLIN) != NSTACKX_EOK) { + close(fd); + LOGE(TAG, "RegisterEpollTask fail"); + return NSTACKX_EFAILED; + } + + g_postponeTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, PostponeTimerHandle, NULL); + if (g_postponeTimer == NULL) { + DeRegisterEpollTask(&g_netlinkTask); + close(g_netlinkTask.taskfd); + LOGE(TAG, "Create timer fail"); + return NSTACKX_EFAILED; + } + + g_smartGeniusInit = NSTACKX_TRUE; + return NSTACKX_EOK; +} + +void SmartGeniusClean(void) +{ + if (!g_smartGeniusInit) { + return; + } + + TimerDelete(g_postponeTimer); + g_postponeTimer = NULL; + DeRegisterEpollTask(&g_netlinkTask); + close(g_netlinkTask.taskfd); + g_smartGeniusInit = NSTACKX_FALSE; +} + +void ResetSmartGeniusTaskCount(uint8_t isBusy) +{ + if (isBusy) { + LOGI(TAG, "in this busy interval: g_netlinkTask count %llu", g_netlinkTask.count); + } + g_netlinkTask.count = 0; + + if (g_postponeTimer != NULL) { + if (isBusy) { + LOGI(TAG, "in this busy interval: g_postponeTimer task count %llu", g_postponeTimer->task.count); + } + g_postponeTimer->task.count = 0; + } +} +#else +int32_t SmartGeniusInit(EpollDesc epollfd) +{ + (void)epollfd; + return NSTACKX_EOK; +} + +void SmartGeniusClean(void) +{ +} + +void ResetSmartGeniusTaskCount(uint8_t isBusy) +{ + (void)isBusy; +} +#endif /* SUPPORT_SMARTGENIUS */ diff --git a/components/nstackx/nstackx_ctrl/include/coap_discover/coap_app.h b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_app.h new file mode 100644 index 000000000..939668ce1 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_app.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COAP_APP_H +#define COAP_APP_H + +#include + +#include "nstackx_epoll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define COAP_SRV_DEFAULT_PORT "5684" +#define COAP_SRV_DEFAULT_ADDR "0.0.0.0" +int32_t CoapServerInit(const struct in_addr *ip); +void CoapServerDestroy(void); +int32_t CoapP2pServerInit(const struct in_addr *ip); +void CoapP2pServerDestroy(void); +int32_t CoapUsbServerInit(const struct in_addr *ip); +void CoapUsbServerDestroy(void); +uint32_t RegisterCoAPEpollTask(EpollDesc epollfd); +uint32_t GetTimeout(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList, EpollDesc epollfd); +void DeRegisterCoAPEpollTask(void); +void DeRegisteCoAPEpollTaskCtx(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList); +void ResetCoapSocketTaskCount(uint8_t isBusy); +#ifdef __cplusplus +} +#endif + +#endif /* COAP_APP_H */ \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/include/coap_discover/coap_client.h b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_client.h new file mode 100644 index 000000000..d229ee9be --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_client.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COAP_CLIENT_H +#define COAP_CLIENT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define COAP_DEVICE_DISCOVER_URI "device_discover" +#define COAP_SERVICE_DISCOVER_URI "service_discover" +#define COAP_SERVICE_MSG_URI "service_msg" + +typedef struct { + coap_proto_t proto; + const coap_address_t *dst; +} CoapServerParameter; + +coap_context_t *CoapGetContext(const char *node, const char *port, uint8_t needBind, const struct in_addr *ip); +coap_session_t *CoapGetSession(coap_context_t *ctx, const char *localAddr, const char *localPort, + const CoapServerParameter *coapServerParameter); + +int32_t CoapResolveAddress(const coap_str_const_t *server, struct sockaddr *dst); +void CoapMessageHandler(struct coap_context_t *ctx, coap_session_t *session, + coap_pdu_t *sent, coap_pdu_t *received, const coap_tid_t id); + +uint8_t IsCoapCtxEndpointSocket(const coap_context_t *ctx, int fd); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef COAP_CLIENT_H */ diff --git a/components/nstackx/nstackx_ctrl/include/coap_discover/coap_discover.h b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_discover.h new file mode 100644 index 000000000..ad12cc443 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/coap_discover/coap_discover.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COAP_DISCOVER_H +#define COAP_DISCOVER_H +#include +#include "nstackx_common.h" + +#define COAP_MODULE_NAME_TYPE 0x01 +#define COAP_DEVICE_ID_TYPE 0x02 +#define COAP_MSG_TYPE 0x03 + +#define SERVER_TYPE_WLANORETH 0 +#define SERVER_TYPE_P2P 1 +#define SERVER_TYPE_USB 2 + +#define INVALID_TYPE 255 + +typedef struct { + uint8_t type; + uint16_t len; /* must be a positive integer */ + uint8_t value[0]; +} __attribute__((packed)) CoapMsgUnit; + +struct coap_session_t; +struct DeviceInfo; +typedef struct { + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN]; + char moduleName[NSTACKX_MAX_MODULE_NAME_LEN]; + char p2pAddr[NSTACKX_MAX_IP_STRING_LEN]; + uint8_t *data; + uint32_t len; + uint8_t type; +} MsgCtx; + +void CoapServiceDiscoverInner(uint8_t userRequest); +void CoapServiceDiscoverInnerAn(uint8_t userRequest); +void CoapServiceDiscoverStopInner(void); +uint8_t CoapDiscoverRequestOngoing(void); +void CoapInitResources(coap_context_t *ctx, uint8_t isNeedInitCtx); +int32_t CoapDiscoverInit(EpollDesc epollfd); +void CoapDiscoverDeinit(void); +void CoapDestroyCtx(uint8_t serverType); +int32_t CoapSendServiceMsg(MsgCtx *msgCtx, struct DeviceInfo *deviceInfo); +int32_t CoapSendServiceMsgWithDefiniteTargetIp(MsgCtx *msgCtx, struct DeviceInfo *deviceInfo); +coap_context_t *GetContext(uint8_t serverType); +void CoapSubscribeModuleInner(uint8_t isSubscribe); +void CoapUnsubscribeModuleInner(uint8_t isUnsubscribe); +void CoapInitSubscribeModuleInner(void); +void ResetCoapDiscoverTaskCount(uint8_t isBusy); +uint8_t GetActualType(const uint8_t type, const char *dstIp); +#endif /* #ifndef COAP_DISCOVER_H */ diff --git a/components/nstackx/nstackx_ctrl/include/coap_discover/json_payload.h b/components/nstackx/nstackx_ctrl/include/coap_discover/json_payload.h new file mode 100644 index 000000000..edf96a259 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/coap_discover/json_payload.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSON_PAYLOAD_H +#define JSON_PAYLOAD_H + +#include +#include "nstackx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct DeviceInfo; + +char *PrepareServiceDiscover(uint8_t isBroadcast); +int32_t ParseServiceDiscover(const uint8_t *buf, struct DeviceInfo *deviceInfo, char **remoteUrlPtr); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef JSON_PAYLOAD_H */ \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/include/nstackx_common.h b/components/nstackx/nstackx_ctrl/include/nstackx_common.h new file mode 100644 index 000000000..20b2d7141 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/nstackx_common.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACK_COMMON_H +#define NSTACK_COMMON_H +#include "nstackx.h" +#include "nstackx_list.h" +#include "nstackx_epoll.h" +#ifdef __cplusplus +extern "C"{ +#endif + +void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount); +void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount); +void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len); +void NotifyDFinderMsgRecver(DFinderMsgType msgType); +EpollDesc GetMainLoopEpollFd(void); +List *GetMainLoopEvendChain(void); + +#ifdef __cplusplus +}; +#endif + +#endif /* #ifndef NSTACK_COMMON_H */ \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/include/nstackx_database.h b/components/nstackx/nstackx_ctrl/include/nstackx_database.h new file mode 100644 index 000000000..91f611b91 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/nstackx_database.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_DATABASE_H +#define NSTACKX_DATABASE_H + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t (*RecCompareCallback)(void *, void *); + +void *DatabaseInit(uint32_t recnum, size_t recsz, RecCompareCallback cb); +void DatabaseClean(void *ptr); +uint32_t GetDatabaseUseCount(const void *dbptr); +void *DatabaseAllocRecord(void *dbptr); +void DatabaseFreeRecord(void *dbptr, const void *ptr); +void *DatabaseSearchRecord(const void *dbptr, void *ptr); +void *DatabaseGetNextRecord(void *dbptr, int64_t *state); + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef NSTACKX_DATABASE_H */ \ No newline at end of file diff --git a/components/nstackx/nstackx_ctrl/include/nstackx_device.h b/components/nstackx/nstackx_ctrl/include/nstackx_device.h new file mode 100644 index 000000000..3a38c561c --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/nstackx_device.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_DEVICE_H +#define NSTACKX_DEVICE_H + +#include +#include + +#include "nstackx.h" +#include "coap_discover.h" + +#define MAX_ADDRESS_LEN 64 +#define MAX_MAC_ADDRESS_LENGTH 6 +#define MAX_IPV4_ADDRESS_LEN 4 + +enum DeviceState { + IDEL, + ACTIVE, + LEAVE +}; + +typedef enum { + NSTACKX_EVENT_JOIN, + NSTACKX_EVENT_UPDATE, + NSTACKX_EVENT_LEAVE, +} NSTACKX_Event; + +enum NetChannelState { + NET_CHANNEL_STATE_START, + NET_CHANNEL_STATE_DISABLED, + NET_CHANNEL_STATE_DISCONNECT, + NET_CHANNEL_STATE_CONNETING, + NET_CHANNEL_STATE_CONNETED, + NET_CHANNEL_STATE_END, +}; + +typedef struct { + char name[NSTACKX_MAX_INTERFACE_NAME_LEN]; + char alias[NSTACKX_MAX_INTERFACE_NAME_LEN]; + struct in_addr ip; +} NetworkInterfaceInfo; + +typedef struct { + struct in_addr ip; + uint8_t state; + /* AP information? */ +} WifiApChannelInfo; + +typedef struct { + WifiApChannelInfo wifiApInfo; +} NetChannelInfo; + +typedef struct DeviceInfo { + char deviceName[NSTACKX_MAX_DEVICE_NAME_LEN]; + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN]; + uint8_t update : 1; + uint8_t reserved : 7; + uint8_t deviceType; + uint16_t portNumber; + NetChannelInfo netChannelInfo; + /* Capability data */ + uint32_t capabilityBitmapNum; + uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM]; + char version[NSTACKX_MAX_HICOM_VERSION]; + uint8_t mode; + char deviceHash[DEVICE_HASH_LEN]; + char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN]; +} DeviceInfo; + +int32_t DeviceModuleInit(EpollDesc epollfd); +int32_t P2pUsbTimerInit(EpollDesc epollfd); +void DestroyP2pUsbServerInitRetryTimer(void); + +void DeviceModuleClean(void); +void PushPublishInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList, uint32_t deviceNum); + +int32_t UpdateDeviceDb(const DeviceInfo *deviceInfo, uint8_t forceUpdate); +uint8_t ClearDevices(void *deviceList); +int32_t BackupDeviceDB(void); +void *GetDeviceDB(void); +void *GetDeviceDBBackup(void); + +DeviceInfo *GetDeviceInfoById(const char *deviceId, const void *db); + +void GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter); +int8_t SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t count, DeviceInfo *deviceInfo); +void SetModeInfo(uint8_t mode); +uint8_t GetModeInfo(void); +void SetDeviceHash(uint64_t deviceHash); + +int32_t ConfigureLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *localDeviceInfo); +int32_t UpdateLocalNetworkInterface(const NetworkInterfaceInfo *interfaceInfo); +int32_t UpdateLocalNetworkInterfaceP2pMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType); +int32_t UpdateLocalNetworkInterfaceUsbMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType); +uint8_t FilterNetworkInterface(const char *ifName); +uint8_t IsWlanIpAddr(const char *ifName); +uint8_t IsEthIpAddr(const char *ifName); +uint8_t IsP2pIpAddr(const char *ifName); +uint8_t IsUsbIpAddr(const char *ifName); + +const DeviceInfo *GetLocalDeviceInfoPtr(void); +uint8_t IsWifiApConnected(void); +int32_t GetLocalIpString(char *ipString, size_t length); +int32_t GetLocalInterfaceName(char *ifName, size_t ifNameLength); + +int32_t RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); +int32_t SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); +int32_t RegisterServiceData(const char *serviceData); +void GetLocalNetworkInterface(void *arg); +void ResetDeviceTaskCount(uint8_t isBusy); +void SetP2pIp(const struct in_addr *ip); +void SetUsbIp(const struct in_addr *ip); +int32_t GetP2pIpString(char *ipString, size_t length); +int32_t GetUsbIpString(char *ipString, size_t length); +#endif /* #ifndef NSTACKX_DEVICE_H */ diff --git a/components/nstackx/nstackx_ctrl/include/nstackx_smartgenius.h b/components/nstackx/nstackx_ctrl/include/nstackx_smartgenius.h new file mode 100644 index 000000000..e8021d118 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/include/nstackx_smartgenius.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_SMARTGENIUS_H +#define NSTACKX_SMARTGENIUS_H +#include +#include "nstackx_epoll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t SmartGeniusInit(EpollDesc epollfd); +void SmartGeniusClean(void); +void ResetSmartGeniusTaskCount(uint8_t isBusy); +#ifdef __cplusplus +} +#endif +#endif /* #ifndef NSTACKX_SMARTGENIUS_H */ diff --git a/components/nstackx/nstackx_ctrl/interface/nstackx.h b/components/nstackx/nstackx_ctrl/interface/nstackx.h new file mode 100644 index 000000000..fa19c7f07 --- /dev/null +++ b/components/nstackx/nstackx_ctrl/interface/nstackx.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_H +#define NSTACKX_H + +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +#define NSTACKX_MAX_DEVICE_NAME_LEN 64 +#define NSTACKX_MAX_MODULE_NAME_LEN 64 +#define NSTACKX_MAX_DEVICE_ID_LEN 96 +#define NSTACKX_MAX_SENDMSG_DATA_LEN 512 +#define NSTACKX_MAX_MAC_STRING_LEN 18 +#define NSTACKX_MAX_IP_STRING_LEN 16 +#define NSTACKX_MAX_CAPABILITY_NUM 2 +#define NSTACKX_MAX_DEVICE_NUM 20 +#define NSTACKX_MAX_INTERFACE_NAME_LEN 16 +#define NSTACKX_MAX_HICOM_VERSION 16 +#define NSTACKX_MAX_SERVICE_DATA_LEN 64 + +#define NSTACKX_MAX_RESERVED_INFO_LEN 219 // expand from 131 to 219 (+88) bytes to hold service data +#define DEVICE_HASH_LEN 21 +#define DEFAULT_MODE 0 +#define DISCOVER_MODE 1 +#define PUBLISH_MODE_UPLINE 2 +#define PUBLISH_MODE_OFFLINE 3 +#define PUBLISH_MODE_PROACTIVE 10 +#define PUBLISH_DEVICE_NUM 1 +#define INNER_DISCOVERY 1 +#define PUBLISH_NUM 1 + +/* Remote device information */ +typedef struct NSTACKX_DeviceInfo { + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN]; + char deviceName[NSTACKX_MAX_DEVICE_NAME_LEN]; + uint32_t capabilityBitmapNum; + uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM]; + uint8_t deviceType; + uint8_t mode; + uint8_t update : 1; + uint8_t reserved : 7; + char version[NSTACKX_MAX_HICOM_VERSION]; + char reservedInfo[NSTACKX_MAX_RESERVED_INFO_LEN]; +} NSTACKX_DeviceInfo; + +/* Local device information */ +typedef struct { + char name[NSTACKX_MAX_DEVICE_NAME_LEN]; + char deviceId[NSTACKX_MAX_DEVICE_ID_LEN]; + char btMacAddr[NSTACKX_MAX_MAC_STRING_LEN]; + char wifiMacAddr[NSTACKX_MAX_MAC_STRING_LEN]; + char networkIpAddr[NSTACKX_MAX_IP_STRING_LEN]; + char networkName[NSTACKX_MAX_INTERFACE_NAME_LEN]; + uint8_t is5GHzBandSupported; + uint8_t deviceType; + char version[NSTACKX_MAX_HICOM_VERSION]; +} NSTACKX_LocalDeviceInfo; + +/* Register local device information */ +int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo); + +/* Register local device information with deviceHash */ +int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash); + +/* Device list change callback type */ +typedef void (*NSTACKX_OnDeviceListChanged)(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount); + +/* Data receive callback type */ +typedef void (*NSTACKX_OnMsgReceived)(const char *moduleName, const char *deviceId, + const uint8_t *data, uint32_t len); + +/* DFinder message type list. */ +typedef enum { + DFINDER_ON_TOO_BUSY = 1, + DFINDER_ON_INNER_ERROR, +} DFinderMsgType; + +/* Data receive callback type */ +typedef void (*NSTACKX_OnDFinderMsgReceived)(DFinderMsgType msgType); + +/* NSTACKX parameter, which contains callback list */ +typedef struct { + NSTACKX_OnDeviceListChanged onDeviceListChanged; + NSTACKX_OnDeviceListChanged onDeviceFound; + NSTACKX_OnMsgReceived onMsgReceived; + NSTACKX_OnDFinderMsgReceived onDFinderMsgReceived; +} NSTACKX_Parameter; + +/* + * NSTACKX Initialization + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter); + +/* NSTACKX Destruction */ +void NSTACKX_Deinit(void); + +/* + * Start device discovery + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_StartDeviceFind(void); + +/* + * Start device discovery by mode + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_StartDeviceFindAn(uint8_t mode); + +/* + * Stop device discovery + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_StopDeviceFind(void); + +/* + * subscribe module + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_SubscribeModule(void); + +/* + * unsubscribe module + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_UnsubscribeModule(void); + +/* + * Register the capability of local device. + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); + +/* + * Set the capability to filter remote devices. + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); + +/* + * Register the serviceData of local device. + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_RegisterServiceData(const char* serviceData); + +/* + * Send Msg to remote peer + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data, + uint32_t len); + +/* + * Send Msg to remote peer + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data, + uint32_t len, const char *ipaddr, uint8_t sendType); + +/* + * Get device list from cache + * param: deviceList - Device list return from NSTACKX, user should prepare sufficient buffer to store + * device list. + * param: deviceCountPtr - In/Out parameter. It indicates buffer size (number of elements) in deviceList + * When returns, it indicates numbers of valid device in deviceList. + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr); + +/* + * NSTACKX Initialization, only used for restart. + * return 0 on success, negative value on failure + */ +int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter); + +/* + * NSTACKX Initialization, only used for restart. + * return 0 on success, negative value on failure + */ +void NSTACKX_StartDeviceFindRestart(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NSTACKX_H */ diff --git a/components/nstackx/nstackx_util/BUILD.gn b/components/nstackx/nstackx_util/BUILD.gn new file mode 100755 index 000000000..3e4c6fd1a --- /dev/null +++ b/components/nstackx/nstackx_util/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (defined(ohos_lite)) { + import("//build/lite/config/component/lite_component.gni") +} else { + import("//build/ohos.gni") + + ohos_shared_library("nstackx_util") { + sources = [ + "core/nstackx_dev.c", + "core/nstackx_event.c", + "core/nstackx_log.c", + "core/nstackx_timer.c", + "core/nstackx_util.c", + "platform/unix/sys_dev.c", + "platform/unix/sys_epoll.c", + "platform/unix/sys_event.c", + "platform/unix/sys_log.c", + "platform/unix/sys_timer.c", + "platform/unix/sys_util.c", + ] + include_dirs = [ + "platform/unix", + "interface", + "//third_party/bounds_checking_function/include", + ] + deps = [ "//third_party/bounds_checking_function:libsec_static" ] + subsystem_name = "communication" + part_name = "dsoftbus_standard" + } +} diff --git a/components/nstackx/nstackx_util/core/nstackx_dev.c b/components/nstackx/nstackx_util/core/nstackx_dev.c new file mode 100644 index 000000000..2bdf2c0d3 --- /dev/null +++ b/components/nstackx/nstackx_util/core/nstackx_dev.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_dev.h" +#include "nstackx_util.h" +#include "nstackx_error.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXDev" + +int32_t GetConnectionTypeByDev(const uint32_t sourceIp, uint16_t *connectType); + +static int32_t GetConnectionTypeByIP(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType) +{ + if (sourceIp == htonl(SOFTAP_ADDR_KEY) || destinationIp == htonl(SOFTAP_ADDR_KEY) || + sourceIp == htonl(P2P_ADDR_KEY) || destinationIp == htonl(P2P_ADDR_KEY)) { + *connectType = CONNECT_TYPE_P2P; + LOGI(TAG, "connType is P2P(%hu)", *connectType); + return NSTACKX_EOK; + } + return NSTACKX_EFAILED; +} + +int32_t GetConnectionType(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType) +{ + if (GetConnectionTypeByIP(sourceIp, destinationIp, connectType) == NSTACKX_EOK) { + return NSTACKX_EOK; + } + return GetConnectionTypeByDev(sourceIp, connectType); +} diff --git a/components/nstackx/nstackx_util/core/nstackx_event.c b/components/nstackx/nstackx_util/core/nstackx_event.c new file mode 100644 index 000000000..c3f27ab70 --- /dev/null +++ b/components/nstackx/nstackx_util/core/nstackx_event.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_event.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXEvent" + +void DeleteEventNode(EventNode *node); + +EventNode *SearchEventNode(const List *eventNodeChain, EpollDesc epollfd) +{ + List *pos = NULL; + EventNode *node = NULL; + + LIST_FOR_EACH(pos, eventNodeChain) { + node = (EventNode *)pos; + if (IsEpollDescEqual(node->epollfd, epollfd)) { + break; + } + node = NULL; + } + return node; +} + +void EventModuleClean(const List *eventNodeChain, EpollDesc epollfd) +{ + List *pos = NULL; + EventNode *node = NULL; + if (eventNodeChain == NULL) { + LOGE(TAG, "eventNodeChain is null"); + return; + } + LIST_FOR_EACH(pos, eventNodeChain) { + node = (EventNode *)pos; + if (IsEpollDescEqual(node->epollfd, epollfd)) { + break; + } + node = NULL; + } + + if (node == NULL) { + return; + } + + DeleteEventNode(node); +} + +void EventNodeChainClean(List *eventNodeChain) +{ + List *tmp = NULL; + List *pos = NULL; + EventNode *node = NULL; + + if (eventNodeChain == NULL) { + LOGE(TAG, "eventNodeChain is null"); + return; + } + + LIST_FOR_EACH_SAFE(pos, tmp, eventNodeChain) { + node = (EventNode *)pos; + if (node != NULL) { + DeleteEventNode(node); + } + } +} + +EpollTask *GetEpollTask(List *eventNodeChain, EpollDesc epollfd) +{ + if (eventNodeChain == NULL) { + LOGE(TAG, "eventNodeChain is null"); + return NULL; + } + + EventNode *node = SearchEventNode(eventNodeChain, epollfd); + if (node == NULL) { + LOGE(TAG, "Cannot find event node for %d", REPRESENT_EPOLL_DESC(epollfd)); + return NULL; + } + return &node->task; +} diff --git a/components/nstackx/nstackx_util/core/nstackx_log.c b/components/nstackx/nstackx_util/core/nstackx_log.c new file mode 100644 index 000000000..4c1a04803 --- /dev/null +++ b/components/nstackx/nstackx_util/core/nstackx_log.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_log.h" + +static uint32_t g_logLevel = NSTACKX_LOG_LEVEL_INFO; + +#ifdef BUILD_FOR_WINDOWS +static void DefaultLogImpl(const char *tag, uint32_t level, const char *format, va_list args) +{ + SYSTEMTIME st = { 0 }; + + GetLocalTime(&st); + printf("%02d-%02d %02d:%02d:%02d.%03d %d %d %d %s: ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, + st.wMilliseconds, GetCurrentProcessId(), GetCurrentThreadId(), level, tag); + vprintf(format, args); +} + +static LogImplInternal g_logImpl = DefaultLogImpl; +#endif + +uint32_t GetLogLevel(void) +{ + return g_logLevel; +} + +void SetLogLevel(uint32_t logLevel) +{ + if (logLevel >= NSTACKX_LOG_LEVEL_END) { + return; + } + g_logLevel = logLevel; +} + +void SetLogImpl(LogImplInternal fn) +{ + if (fn == NULL) { + return; + } +#ifdef BUILD_FOR_WINDOWS + g_logImpl = fn; +#endif +} diff --git a/components/nstackx/nstackx_util/core/nstackx_timer.c b/components/nstackx/nstackx_util/core/nstackx_timer.c new file mode 100644 index 000000000..ca8881400 --- /dev/null +++ b/components/nstackx/nstackx_util/core/nstackx_timer.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_timer.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXTimer" + +uint32_t GetTimeDiffMs(const struct timespec *etv, const struct timespec *stv) +{ + uint64_t ms; + + if (etv->tv_sec < stv->tv_sec || (etv->tv_sec == stv->tv_sec && etv->tv_nsec < stv->tv_nsec)) { + LOGE(TAG, "invalid input: etv is smaller than stv"); + return 0; + } + + if (etv->tv_nsec < stv->tv_nsec) { + ms = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec - 1) * NSTACKX_MILLI_TICKS; + ms += (NSTACKX_NANO_TICKS + (uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_MICRO_TICKS; + } else { + ms = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec) * NSTACKX_MILLI_TICKS; + ms += ((uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_MICRO_TICKS; + } + if (ms > UINT32_MAX) { + ms = UINT32_MAX; + } + return (uint32_t)ms; +} + +uint32_t GetTimeDiffUs(const struct timespec *etv, const struct timespec *stv) +{ + uint64_t us; + if (etv->tv_sec < stv->tv_sec || (etv->tv_sec == stv->tv_sec && etv->tv_nsec < stv->tv_nsec)) { + LOGE(TAG, "invalid input: etv is smaller than stv"); + return 0; + } + if (etv->tv_nsec < stv->tv_nsec) { + us = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec - 1) * NSTACKX_MICRO_TICKS; + us += (NSTACKX_NANO_TICKS + (uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_NANO_SEC_PER_MICRO_SEC; + } else { + us = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec) * NSTACKX_MILLI_TICKS; + us += ((uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_NANO_SEC_PER_MICRO_SEC; + } + if (us > UINT32_MAX) { + us = UINT32_MAX; + } + return (uint32_t)us; +} diff --git a/components/nstackx/nstackx_util/core/nstackx_util.c b/components/nstackx/nstackx_util/core/nstackx_util.c new file mode 100644 index 000000000..6aea558af --- /dev/null +++ b/components/nstackx/nstackx_util/core/nstackx_util.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_util.h" +#include "nstackx_error.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXUtil" +#define DEFAULT_NEW_PATH_AUTHORITY 0755 + +int32_t GetTargetFileSize(const char *dir, uint64_t *size) +{ + struct stat statbuf; + + if (dir == NULL || size == NULL) { + LOGE(TAG, "Invalid dir or size"); + return NSTACKX_EINVAL; + } + + if (stat(dir, &statbuf) != 0 || statbuf.st_size < 0) { + LOGE(TAG, "stat error: %d", GetErrno()); + return NSTACKX_EFAILED; + } + + *size = (uint64_t)statbuf.st_size; + return NSTACKX_EOK; +} + +int32_t CheckPathSeprator(const char *path) +{ + if (strlen(path) > 0 && path[strlen(path) - 1] == PATH_SEPARATOR) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +int32_t CheckFilenameSeprator(const char *fileName) +{ + if (strlen(fileName) > 0 && fileName[0] == PATH_SEPARATOR) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +/* + * return value includes the length of terminator '\0' + * return value 0 means the input dir is null or it's last char is PATH_SEPARATOR + */ +uint32_t GetFileNameLen(const char *dir) +{ + int32_t i; + + if (dir == NULL || strlen(dir) < 1 || dir[strlen(dir) - 1] == PATH_SEPARATOR) { + LOGE(TAG, "Invalid input param"); + return 0; + } + + int32_t dirLen = (int32_t)strlen(dir); + for (i = dirLen - 1; i >= 0; i--) { + if (dir[i] == PATH_SEPARATOR) { + i++; + break; + } + if (i == 0) { + break; + } + } + return (uint32_t)(dirLen + 1 - i); +} + +int32_t GetFileName(const char *dir, char *name, uint32_t nameLen) +{ + uint32_t fileNameLen, startIdx; + + if (dir == NULL || name == NULL) { + LOGE(TAG, "Invalid dir or name"); + return NSTACKX_EINVAL; + } + + fileNameLen = GetFileNameLen(dir); + if (fileNameLen == 0 || fileNameLen > nameLen) { + LOGE(TAG, "Invalid fileNameLen dir: %s", dir); + return NSTACKX_EINVAL; + } + startIdx = (uint32_t)(strlen(dir) + 1 - fileNameLen); + if (strcpy_s(name, nameLen, dir + startIdx) != EOK) { + LOGE(TAG, "strcpy_s name error"); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +uint8_t IsAccessiblePath(const char *pathName, int32_t mode, uint32_t fileType) +{ + struct stat statbuf; + if (pathName == NULL) { + LOGE(TAG, "invalid input"); + return NSTACKX_FALSE; + } + if (stat(pathName, &statbuf) != 0) { + LOGE(TAG, "can't get file stat.error: %d", GetErrno()); + return NSTACKX_FALSE; + } + if (((statbuf.st_mode) & S_IFMT) != fileType) { + LOGE(TAG, "this path name is not target file type"); + return NSTACKX_FALSE; + } + + if (access(pathName, F_OK) != 0) { + return NSTACKX_FALSE; + } + + if (access(pathName, mode) != 0) { + return NSTACKX_FALSE; + } + return NSTACKX_TRUE; +} + +uint8_t IsExistingFile(const char *fileName) +{ + if (access(fileName, F_OK) != 0) { + return NSTACKX_FALSE; + } + return NSTACKX_TRUE; +} + +int32_t TestAndCreateDirectory(const char *path) +{ + uint32_t len, i; + char *tmp = NULL; + int32_t ret; + + if (path == NULL || strlen(path) == 0) { + return NSTACKX_EINVAL; + } + + len = (uint32_t)strlen(path); + + tmp = (char *)calloc(len + 1, sizeof(char)); + if (tmp == NULL) { + LOGE(TAG, "tmp calloc error"); + return NSTACKX_EFAILED; + } + + for (i = 0; i < len; i++) { + tmp[i] = path[i]; + if (tmp[i] != PATH_SEPARATOR) { + continue; + } + if (access(tmp, 0) == -1) { + ret = mkdir(tmp, DEFAULT_NEW_PATH_AUTHORITY); + if (ret == -1 && errno != EEXIST) { + LOGI(TAG, "mkdir failed(%d)", errno); + free(tmp); + return NSTACKX_EFAILED; + } + } + } + free(tmp); + return NSTACKX_EOK; +} diff --git a/components/nstackx/nstackx_util/interface/nstackx_common_header.h b/components/nstackx/nstackx_util/interface/nstackx_common_header.h new file mode 100644 index 000000000..f7c121729 --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_common_header.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_COMMON_HEADER_H +#define NSTACKX_COMMON_HEADER_H + +#include "sys_common_header.h" + +#include +#include +#include + +// C standard library header files +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIPE_OUT 0 +#define PIPE_IN 1 +#define PIPE_FD_NUM 2 + +#endif // NSTACKX_COMMON_HEADER_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_config.h b/components/nstackx/nstackx_util/interface/nstackx_config.h new file mode 100644 index 000000000..733c71896 --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_config.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_CONFIG_H +#define NSTACKX_CONFIG_H + +#ifdef NSTACKX_WITH_LITEOS + +/** + * Enable(1) or Disable(0) fillp support in nStackx + */ +#ifndef NSTACKX_SUPPORT_FILLP +#define NSTACKX_SUPPORT_FILLP 0 +#endif + +/** + * Enable(1) or Disable(0) encrypt support in nStackx + */ +#ifndef NSTACKX_SUPPORT_ENCRYPT +#define NSTACKX_SUPPORT_ENCRYPT 0 +#endif + +#endif /* NSTACKX_WITH_LITEOS */ + +#ifdef NSTACKX_WITH_HMOS_LINUX + +#ifndef NSTACKX_SUPPORT_ENCRYPT +#define NSTACKX_SUPPORT_ENCRYPT 0 +#endif + +#endif /* NSTACKX_WITH_HMOS_LINUX */ + +#ifndef NSTACKX_SUPPORT_FILLP +#define NSTACKX_SUPPORT_FILLP 1 +#endif + +#ifndef NSTACKX_SUPPORT_ENCRYPT +#define NSTACKX_SUPPORT_ENCRYPT 1 +#endif + +#endif /* NSTACKX_CONFIG_H */ diff --git a/components/nstackx/nstackx_util/interface/nstackx_dev.h b/components/nstackx/nstackx_util/interface/nstackx_dev.h new file mode 100644 index 000000000..ce7846aad --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_dev.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_DEV_H +#define NSTACKX_DEV_H + +#include "nstackx_common_header.h" + +#ifndef UNUSED +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else /* not a GCC */ +#define UNUSED +#endif /* GCC */ +#endif + +/* DFile connect type list. */ +typedef enum { + CONNECT_TYPE_NONE = 0, + CONNECT_TYPE_P2P, + CONNECT_TYPE_WLAN, + CONNECT_TYPE_MAX, +} ConnectType; + +#define P2P_DEV_NAME_PRE "p2p" +#define WLAN_DEV_NAME_PRE "wlan" +#define ETH_DEV_NAME_PRE "eth" +#define USB_DEV_NAME_PRE "rndis" +#define WIFI_DIRECT_NAME "Wi-Fi Direct" +#define INTERFCAE_NAME_MAX_LENGTH (128 + 4) +#define INTERFACE_GUID_MAX_LENGTH (256 + 4) +#define INTERFACE_NETMASK (0xffffff) +#define INTERFCAE_DES_MAX_LENGTH 128 +#define INTERFCAE_ADDR_MAX_LENGTH 16 +#define INTERFCAE_TYPE_MAX_LENGTH 20 +#define INTERFACE_MAX 16 +#define SOFTAP_ADDR_KEY (0xc0a82b01) +#define P2P_ADDR_KEY (0xc0a83101) + +NSTACKX_EXPORT int32_t BindToDevice(SocketDesc sockfd, const struct sockaddr_in *localAddr); +NSTACKX_EXPORT int32_t GetIfBroadcastIp(const char *ifName, char *ipString, size_t ipStringLen); +NSTACKX_EXPORT int32_t GetConnectionType(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType); +NSTACKX_EXPORT int32_t BindToTargetDev(SocketDesc sockfd, const char *targetInterfaceName); +NSTACKX_EXPORT int32_t GetInterfaceNameByIP(uint32_t sourceIp, char *interfaceName); +NSTACKX_EXPORT void BindToDevInTheSameLan(SocketDesc sockfd, const struct sockaddr_in *sockAddr); + +#endif // NSTACKX_DEV_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_epoll.h b/components/nstackx/nstackx_util/interface/nstackx_epoll.h new file mode 100644 index 000000000..e062336f6 --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_epoll.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_EPOLL_H +#define NSTACKX_EPOLL_H + +#include "sys_epoll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EPOLLIN +#define EPOLLIN 0x00000001U +#endif + +#ifndef EPOLLOUT +#define EPOLLOUT 0x00000004U +#endif + +#ifndef EPOLLERR +#define EPOLLERR 0x00000008U +#endif + +#ifndef EPOLLHUP +#define EPOLLHUP 0x00000010U +#endif + +typedef void (*TaskHandle)(void *arg); + +typedef struct { + EpollDesc epollfd; + TaskDesc taskfd; + TaskHandle readHandle; + TaskHandle writeHandle; + TaskHandle errorHandle; + TaskHandle endHandle; + void *ptr; + uint64_t count; +} EpollTask; + +NSTACKX_EXPORT int32_t RegisterEpollTask(EpollTask *task, uint32_t events); +NSTACKX_EXPORT int32_t DeRegisterEpollTask(EpollTask *task); +NSTACKX_EXPORT int32_t RefreshEpollTask(EpollTask *task, uint32_t events); +NSTACKX_EXPORT EpollDesc CreateEpollDesc(void); +NSTACKX_EXPORT int32_t EpollLoop(EpollDesc epollfd, int32_t timeout); +static inline bool IsEpollDescValid(EpollDesc epollfd); +static inline bool IsEpollDescEqual(EpollDesc epollfd1, EpollDesc epollfd2); +static inline void CloseEpollDesc(EpollDesc epollfd); + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_EPOLL_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_error.h b/components/nstackx/nstackx_util/interface/nstackx_error.h new file mode 100644 index 000000000..e0613d7cd --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_error.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_ERROR_H +#define NSTACKX_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define NSTACKX_EOK 0 /* OK */ +#define NSTACKX_EFAILED (-1) /* Operation failed */ + +/* + * Description:Invalid argument. + * Solution: Verify that related input parameters are correctly set. + */ +#define NSTACKX_EINVAL (-2) +#define NSTACKX_EINPROGRESS (-3) /* Operation now in progress */ + +/* + * Description: Device or resource busy. + * Solution: Please retry later. + */ +#define NSTACKX_EBUSY (-4) + +/* + * Description: Out of memory. + * Solution: 1. Verify that the memory usage exceeds the threshold. + * 2. Release the memory and try again + */ +#define NSTACKX_ENOMEM (-5) +#define NSTACKX_EEXIST (-6) /* Resource already exist */ + +/* + * Description: The resource is temporarily unavailable. + * Solution: Try again later. + */ +#define NSTACKX_EAGAIN (-7) + +/* + * Description: Timeout. + * Solution: Try again. + */ +#define NSTACKX_ETIMEOUT (-8) + +/* + * Description: Overflow. + * Solution: Try again. + */ +#define NSTACKX_OVERFLOW (-9) + +/* + * Description: Not exist. + * Solution: Try again. + */ +#define NSTACKX_NOEXIST (-10) + +/* + * Description: Interrupted system call. + * Solution: Try again. + */ +#define NSTACKX_EINTR (-11) + +#define NSTACKX_TRUE 1 +#define NSTACKX_FALSE 0 + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_ERROR_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_event.h b/components/nstackx/nstackx_util/interface/nstackx_event.h new file mode 100644 index 000000000..aa7f938aa --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_event.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_EVENT_H +#define NSTACKX_EVENT_H + +#include "sys_event.h" +#include "nstackx_epoll.h" +#include "nstackx_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*EventHandle)(void *arg); + +typedef struct EventNode { + List list; + EpollDesc epollfd; + PipeDesc pipeFd[PIPE_FD_NUM]; + EpollTask task; +} EventNode; + +NSTACKX_EXPORT int32_t PostEvent(const List *eventNodeChain, EpollDesc epollfd, EventHandle handle, void *arg); +NSTACKX_EXPORT void ClearEvent(const List *eventNodeChain, EpollDesc epollfd); +NSTACKX_EXPORT int32_t EventModuleInit(List *eventNodeChain, EpollDesc epollfd); +NSTACKX_EXPORT void EventModuleClean(const List *eventNodeChain, EpollDesc epollfd); +NSTACKX_EXPORT void EventNodeChainClean(List *eventNodeChain); +NSTACKX_EXPORT EpollTask *GetEpollTask(List *eventNodeChain, EpollDesc epollfd); + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_EVENT_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_list.h b/components/nstackx/nstackx_util/interface/nstackx_list.h new file mode 100644 index 000000000..cbe53386a --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_list.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_LIST_H +#define NSTACKX_LIST_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct List { + struct List *prev; + struct List *next; +} List; + +static inline void ListInitHead(List *head) +{ + head->next = head; + head->prev = head; +} + +static inline void ListInsertHead(List *head, List *node) +{ + node->next = head->next; + node->next->prev = node; + node->prev = head; + head->next = node; +} + +static inline void ListInsertTail(List *head, List *node) +{ + node->prev = head->prev; + node->prev->next = node; + node->next = head; + head->prev = node; +} + +static inline void ListRemoveNode(List *node) +{ + if (node == NULL) { + return; + } + node->next->prev = node->prev; + node->prev->next = node->next; + node->next = NULL; + node->prev = NULL; +} + +static inline uint8_t ListIsEmpty(const List *head) +{ + return (head == head->next); +} + +static inline List *ListGetFront(List *head) +{ + return head->next; +} + +static inline List *ListPopFront(List *head) +{ + List *element = NULL; + if (head == NULL || ListIsEmpty(head)) { + return NULL; + } + + element = head->next; + ListRemoveNode(element); + return element; +} + +static inline void ListInsertNewHead(List *prevHead, List *newHead) +{ + prevHead->prev->next = newHead->next; + newHead->next->prev = prevHead->prev; + newHead->prev->next = prevHead; + prevHead->prev = newHead->prev; +} + +static inline void ListMove(List *from, List *to) +{ + List *first = from->next; + List *last = from->prev; + + to->next = first; + to->prev = last; + first->prev = to; + last->next = to; + ListInitHead(from); +} + +#define LIST_FOR_EACH(curr, head) \ + for ((curr) = (head)->next; (curr) != (head); (curr) = (curr)->next) + +#define LIST_FOR_EACH_SAFE(pos, tmp, head) \ + for ((pos) = (head)->next, (tmp) = (pos)->next; (pos) != (head); \ + (pos) = (tmp), (tmp) = (pos)->next) + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_LIST_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_log.h b/components/nstackx/nstackx_util/interface/nstackx_log.h new file mode 100644 index 000000000..c7114275c --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_log.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_LOG_H +#define NSTACKX_LOG_H + +#include "nstackx_common_header.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NSTACKX_LOG_LEVEL_OFF = 0, + NSTACKX_LOG_LEVEL_FATAL = 1, + NSTACKX_LOG_LEVEL_ERROR = 2, + NSTACKX_LOG_LEVEL_WARNING = 3, + NSTACKX_LOG_LEVEL_INFO = 4, + NSTACKX_LOG_LEVEL_DEBUG = 5, + NSTACKX_LOG_LEVEL_END, +}; + +#define NSTACKX_DEFAULT_TAG "nStackX" + +/* Log module initialization */ +NSTACKX_EXPORT void SetLogLevel(uint32_t logLevel); + +/* Get current log level */ +NSTACKX_EXPORT uint32_t GetLogLevel(void); + +/* Actual implementation of "print", which is platform dependent */ +NSTACKX_EXPORT void PrintfImpl(const char *moduleName, uint32_t logLevel, const char *format, ...); + +/* internal log implementation for windows */ +typedef void (*LogImplInternal)(const char *tag, uint32_t level, const char *format, va_list args); + +/* Set log implementation */ +NSTACKX_EXPORT void SetLogImpl(LogImplInternal fn); + +#define NSTACKX_LOG_COMMON(moduleName, logLevel, format, ...) \ + do { \ + if (logLevel <= GetLogLevel()) { \ + PrintfImpl(moduleName, logLevel, "%s:[%d] :" format "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + +#define LOGF(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_FATAL, format, ##__VA_ARGS__) +#define LOGE(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_ERROR, format, ##__VA_ARGS__) +#define LOGW(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_WARNING, format, ##__VA_ARGS__) +#define LOGI(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_INFO, format, ##__VA_ARGS__) +#define LOGD(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_LOG_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_timer.h b/components/nstackx/nstackx_util/interface/nstackx_timer.h new file mode 100644 index 000000000..8cb4fd5ba --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_timer.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_TIMER_H +#define NSTACKX_TIMER_H + +#include "nstackx_epoll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NSTACKX_MILLI_TICKS 1000 +#define NSTACKX_MICRO_TICKS 1000000 +#define NSTACKX_NANO_TICKS 1000000000 +#define NSTACKX_MICRO_SEC_PER_MILLI_SEC (NSTACKX_MICRO_TICKS / NSTACKX_MILLI_TICKS) +#define NSTACKX_NANO_SEC_PER_MILLI_SEC (NSTACKX_NANO_TICKS / NSTACKX_MILLI_TICKS) +#define NSTACKX_NANO_SEC_PER_MICRO_SEC (NSTACKX_NANO_TICKS / NSTACKX_MICRO_TICKS) + +typedef void (*TimeoutHandle)(void *data); + +typedef struct { + EpollTask task; + TimeoutHandle timeoutHandle; + void *data; + uint8_t disabled; +} Timer; + +NSTACKX_EXPORT uint32_t GetTimeDiffMs(const struct timespec *etv, const struct timespec *stv); +NSTACKX_EXPORT int32_t TimerSetTimeout(Timer *timer, uint32_t timeoutMs, uint8_t repeated); +NSTACKX_EXPORT int32_t TimerGetRemainTime(Timer *timer, uint32_t *remainTimeMsPtr); +NSTACKX_EXPORT Timer *TimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data); +NSTACKX_EXPORT void TimerDelete(Timer *timer); +NSTACKX_EXPORT uint32_t GetTimeDiffUs(const struct timespec *etv, const struct timespec *stv); + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_TIMER_H diff --git a/components/nstackx/nstackx_util/interface/nstackx_util.h b/components/nstackx/nstackx_util/interface/nstackx_util.h new file mode 100644 index 000000000..94e56a212 --- /dev/null +++ b/components/nstackx/nstackx_util/interface/nstackx_util.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NSTACKX_UTIL_H +#define NSTACKX_UTIL_H + +#include "nstackx_dev.h" +#include "sys_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + CPU_IDX_0 = 0, + CPU_IDX_1, + CPU_IDX_2, + CPU_IDX_3, + CPU_IDX_4, + CPU_IDX_5, + CPU_IDX_6, + CPU_IDX_7, +} CpuIdx; + +#define FIRST_CPU_NUM_LEVEL 8 +#define SECOND_CPU_NUM_LEVEL 4 +#define THIRD_CPU_NUM_LEVEL 2 +#define MAX_THREAD_NAME_LEN 100 +#define THREAD_MAXIMUM_PRIORITY (-20) + +NSTACKX_EXPORT int32_t GetTargetFileSize(const char *dir, uint64_t *size); +NSTACKX_EXPORT int32_t CheckPathSeprator(const char *path); +NSTACKX_EXPORT int32_t CheckFilenameSeprator(const char *fileName); +NSTACKX_EXPORT uint32_t GetFileNameLen(const char *dir); +NSTACKX_EXPORT int32_t GetFileName(const char *dir, char *name, uint32_t nameLen); +NSTACKX_EXPORT uint8_t IsAccessiblePath(const char *fileName, int32_t mode, uint32_t fileType); +NSTACKX_EXPORT int32_t TestAndCreateDirectory(const char *path); +NSTACKX_EXPORT uint8_t IsFileNameLegal(const char *fileName); +NSTACKX_EXPORT uint8_t IsExistingFile(const char *fileName); + +NSTACKX_EXPORT void StartThreadBindCore(int32_t cpu); +NSTACKX_EXPORT void BindThreadToTargetMask(pid_t tid, uint32_t cpuMask); +NSTACKX_EXPORT int32_t GetCpuNum(void); +NSTACKX_EXPORT void SetThreadName(const char *name); +NSTACKX_EXPORT void ClockGetTime(clockid_t id, struct timespec *tp); +NSTACKX_EXPORT void SetMaximumPriorityForThread(void); + +/* pthread series */ +NSTACKX_EXPORT void SemGetValue(sem_t *sem, int *sval); +NSTACKX_EXPORT void SemPost(sem_t *sem); +NSTACKX_EXPORT void SemWait(sem_t *sem); +NSTACKX_EXPORT void SemDestroy(sem_t *sem); +NSTACKX_EXPORT int32_t SemInit(sem_t *sem, int pshared, unsigned int value); +NSTACKX_EXPORT int32_t PthreadMutexInit(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); +NSTACKX_EXPORT void PthreadMutexDestroy(pthread_mutex_t *mutex); +NSTACKX_EXPORT int32_t PthreadMutexLock(pthread_mutex_t *mutex); +NSTACKX_EXPORT int32_t PthreadMutexUnlock(pthread_mutex_t *mutex); +NSTACKX_EXPORT int32_t PthreadCreate(pthread_t *tid, const pthread_attr_t *attr, void *(*entry)(void *), void *arg); +NSTACKX_EXPORT void PthreadJoin(pthread_t thread, void **retval); + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_UTIL_H diff --git a/components/nstackx/nstackx_util/platform/unix/sys_common_header.h b/components/nstackx/nstackx_util/platform/unix/sys_common_header.h new file mode 100644 index 000000000..b8ecf1794 --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_common_header.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYS_COMMON_HEADER_H +#define SYS_COMMON_HEADER_H + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef offsetof +#define offsetof(type, member) __builtin_offsetof(type, member) +#endif + +#define container_of(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ +}) + +#define NSTACKX_EXPORT extern + +typedef int32_t SocketDesc; + +#define INVALID_SOCKET (-1) + +#endif // SYS_COMMON_HEADER_H diff --git a/components/nstackx/nstackx_util/platform/unix/sys_dev.c b/components/nstackx/nstackx_util/platform/unix/sys_dev.c new file mode 100644 index 000000000..b7b180e27 --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_dev.c @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_dev.h" +#include "nstackx_util.h" +#include "nstackx_error.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXDev" + +static int32_t GetConnectionTypeByDevName(const char *devName, uint32_t devNameLen, uint16_t *connectType) +{ + int32_t ret = NSTACKX_EFAILED; + uint32_t p2pNameLen = (uint32_t)strlen(P2P_DEV_NAME_PRE); + uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE); + + if (devNameLen >= p2pNameLen && memcmp(devName, P2P_DEV_NAME_PRE, p2pNameLen) == 0) { + *connectType = CONNECT_TYPE_P2P; + ret = NSTACKX_EOK; + LOGI(TAG, "connType is P2P(%u)", *connectType); + } else if (devNameLen >= wlanNameLen && memcmp(devName, WLAN_DEV_NAME_PRE, wlanNameLen) == 0) { + *connectType = CONNECT_TYPE_WLAN; + LOGI(TAG, "connType is WLAN(%u)", *connectType); + ret = NSTACKX_EOK; + } + return ret; +} + +static int32_t GetInterfaceInfo(int32_t fd, int32_t option, struct ifreq *interface) +{ + if (interface == NULL) { + return NSTACKX_EINVAL; + } + if (ioctl(fd, SIOCGIFFLAGS, (char*)interface) < 0) { + LOGE(TAG, "ioctl fail, errno = %d", errno); + return NSTACKX_EFAILED; + } + if (!((uint16_t)interface->ifr_flags & IFF_UP)) { + LOGE(TAG, "interface is not up"); + return NSTACKX_EINVAL; + } + + /* get IP of this interface */ + if (ioctl(fd, option, (char*)interface) < 0) { + LOGE(TAG, "ioctl fail, errno = %d", errno); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t GetInterfaceIP(int32_t fd, struct ifreq *interface) +{ + return GetInterfaceInfo(fd, SIOCGIFADDR, interface); +} + +static int32_t GetInterfaceNetMask(int32_t fd, struct ifreq *interface) +{ + return GetInterfaceInfo(fd, SIOCGIFNETMASK, interface); +} + +int32_t GetInterfaceList(struct ifconf *ifc, struct ifreq *buf, uint32_t size) +{ + int32_t fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return NSTACKX_EFAILED; + } + ifc->ifc_len = (int32_t)size; + ifc->ifc_buf = (char*)buf; + if (ioctl(fd, SIOCGIFCONF, (char*)ifc) < 0) { + LOGE(TAG, "ioctl fail, errno = %d", errno); + CloseSocketInner(fd); + return NSTACKX_EFAILED; + } + return fd; +} + +int32_t GetConnectionTypeByDev(const uint32_t sourceIp, uint16_t *connectType) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + + uint32_t ethNameLen = (uint32_t)strlen(ETH_DEV_NAME_PRE); + uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE); + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + LOGE(TAG, "get interfacelist failed"); + return NSTACKX_EFAILED; + } + + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + LOGI(TAG, "ndevice name: %s", buf[i].ifr_name); + uint32_t ifrNameLen = (uint32_t)strlen(buf[i].ifr_name); + if (ifrNameLen < ethNameLen && ifrNameLen < wlanNameLen) { + continue; + } + + /* get IP of this interface */ + int32_t state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + goto L_ERROR; + } else if (state == NSTACKX_EINVAL) { + continue; + } + if (sourceIp == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) { + if (GetConnectionTypeByDevName(buf[i].ifr_name, ifrNameLen, connectType) == NSTACKX_EOK) { + break; + } + } + } + CloseSocketInner(fd); + return NSTACKX_EOK; +L_ERROR: + CloseSocketInner(fd); + LOGE(TAG, "get connect type failed"); + return NSTACKX_EFAILED; +} + +static int32_t FindDevByInterfaceIP(int32_t fd, struct ifconf ifc, struct ifreq buf[], uint32_t sourceIP) +{ + int32_t i; + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + /* get IP of this interface */ + int32_t state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + return NSTACKX_EFAILED; + } else if (state == NSTACKX_EINVAL) { + continue; + } + if (sourceIP == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) { + return i; + } + } + return NSTACKX_EFAILED; +} + +int32_t GetInterfaceNameByIP(uint32_t sourceIP, char *interfaceName) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + int32_t devIndex; + int32_t ret = NSTACKX_EOK; + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + LOGE(TAG, "can't GetInterfaceList"); + return NSTACKX_EFAILED; + } + devIndex = FindDevByInterfaceIP(fd, ifc, buf, sourceIP); + CloseSocketInner(fd); + if (devIndex >= 0) { + if (strcpy_s(interfaceName, strlen(buf[devIndex].ifr_name) + 1, buf[devIndex].ifr_name) != EOK) { + LOGE(TAG, "strcpy failed"); + ret = NSTACKX_EFAILED; + } + } + return ret; +} + +static int32_t BindToDeviceInner(int32_t sockfd, const struct ifreq *ifBinding) +{ + struct ifreq ifr; + + if (ifBinding == NULL) { + LOGE(TAG, "no right interface for binding"); + return NSTACKX_EFAILED; + } + if (strncpy_s(ifr.ifr_ifrn.ifrn_name, IFNAMSIZ, ifBinding->ifr_name, strlen(ifBinding->ifr_name)) != EOK) { + LOGE(TAG, "strncpy fail"); + return NSTACKX_EFAILED; + } + if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr)) < 0) { + LOGE(TAG, "setsockopt fail, errno = %d", errno); + return NSTACKX_EFAILED; + } + LOGI(TAG, "binding interface %s success", ifBinding->ifr_name); + return NSTACKX_EOK; +} + +/* + * If localAddr isn't NULL, bind to interface correspond to ip, + * otherwise, bind to interface which is choosed by strategy. + */ +int32_t BindToDevice(SocketDesc sockfd, const struct sockaddr_in *localAddr) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + struct ifreq *ifBinding = NULL; + uint32_t ethNameLen = (uint32_t)strlen(ETH_DEV_NAME_PRE); + uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE); + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + return NSTACKX_EFAILED; + } + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + LOGI(TAG, "device name: %s", buf[i].ifr_name); + if (strlen(buf[i].ifr_name) < ethNameLen && strlen(buf[i].ifr_name) < wlanNameLen) { + continue; + } + /* get IP of this interface */ + int32_t state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + goto L_ERROR; + } else if (state == NSTACKX_EINVAL) { + continue; + } + if (localAddr != NULL) { + /* find corresponding interface by ip */ + if (localAddr->sin_addr.s_addr == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) { + ifBinding = &buf[i]; + break; + } + } else { + /* strategy: ethernet have higher priority */ + if (memcmp(buf[i].ifr_name, ETH_DEV_NAME_PRE, ethNameLen) == 0) { + ifBinding = &buf[i]; + break; + } else if (memcmp(buf[i].ifr_name, WLAN_DEV_NAME_PRE, wlanNameLen) == 0) { + ifBinding = &buf[i]; + } + } + } + CloseSocketInner(fd); + return BindToDeviceInner(sockfd, ifBinding); +L_ERROR: + LOGE(TAG, "ioctl fail, errno = %d", errno); + CloseSocketInner(fd); + return NSTACKX_EFAILED; +} + +int32_t GetIfBroadcastIp(const char *ifName, char *ipString, size_t ipStringLen) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + uint8_t foundIp = NSTACKX_FALSE; + + if (ifName == NULL) { + return NSTACKX_EFAILED; + } + + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + return NSTACKX_EFAILED; + } + + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + if (strlen(buf[i].ifr_name) < strlen(ifName)) { + continue; + } + if (memcmp(buf[i].ifr_name, ifName, strlen(ifName)) != 0) { + continue; + } + if (GetInterfaceInfo(fd, SIOCGIFBRDADDR, &buf[i]) != NSTACKX_EOK) { + continue; + } + if (buf[i].ifr_addr.sa_family != AF_INET) { + continue; + } + + if (inet_ntop(AF_INET, &(((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr), ipString, + (socklen_t)ipStringLen) == NULL) { + continue; + } + foundIp = NSTACKX_TRUE; + break; + } + CloseSocketInner(fd); + + if (!foundIp) { + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +static uint8_t IsValidInterface(const char *interfaceName) +{ + if (interfaceName == NULL) { + return NSTACKX_FALSE; + } + uint32_t targetDevLen = (uint32_t)strlen(P2P_DEV_NAME_PRE); + if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, P2P_DEV_NAME_PRE, targetDevLen) == 0) { + return NSTACKX_TRUE; + } + targetDevLen = (uint32_t)strlen(ETH_DEV_NAME_PRE); + if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, ETH_DEV_NAME_PRE, targetDevLen) == 0) { + return NSTACKX_TRUE; + } + targetDevLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE); + if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, WLAN_DEV_NAME_PRE, targetDevLen) == 0) { + return NSTACKX_TRUE; + } + return NSTACKX_FALSE; +} + +int32_t GetTargetInterface(const struct sockaddr_in *dstAddr, struct ifreq *localDev) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + uint32_t localIp; + uint32_t netMask; + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + return NSTACKX_EFAILED; + } + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + if (!IsValidInterface(buf[i].ifr_name)) { + continue; + } + /* get IP of this interface */ + int32_t state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + goto L_ERROR; + } else if (state == NSTACKX_EINVAL) { + continue; + } + localIp = ((struct sockaddr_in *)(&buf[i].ifr_addr))->sin_addr.s_addr; + state = GetInterfaceNetMask(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + goto L_ERROR; + } else if (state == NSTACKX_EINVAL) { + continue; + } + netMask = ((struct sockaddr_in *)&(buf[i].ifr_netmask))->sin_addr.s_addr; + /* if localIp and dstIp are in the same LAN, fetch the interface name of thie localIp and return */ + if ((dstAddr->sin_addr.s_addr & netMask) == (localIp & netMask)) { + if (strncpy_s(localDev->ifr_ifrn.ifrn_name, IFNAMSIZ, buf[i].ifr_name, strlen(buf[i].ifr_name)) != EOK) { + LOGE(TAG, "ifreq name copy failed"); + goto L_ERROR; + } + CloseSocketInner(fd); + return NSTACKX_EOK; + } + } +L_ERROR: + CloseSocketInner(fd); + return NSTACKX_EFAILED; +} + +void BindToDevInTheSameLan(SocketDesc sockfd, const struct sockaddr_in *sockAddr) +{ + struct ifreq localInterface; + if (sockfd < 0) { + return; + } + (void)memset_s(&localInterface, sizeof(localInterface), 0, sizeof(localInterface)); + if (GetTargetInterface(sockAddr, &localInterface) != NSTACKX_EOK) { + LOGE(TAG, "get target interface fail"); + return; + } + if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&localInterface, sizeof(localInterface)) < 0) { + LOGE(TAG, "bind to device fail, errno = %d", errno); + return; + } + LOGI(TAG, "bind to %s successfully", localInterface.ifr_name); +} + +int32_t BindToTargetDev(SocketDesc sockfd, const char *targetInterfaceName) +{ + struct ifreq buf[INTERFACE_MAX]; + struct ifconf ifc; + int32_t ret = NSTACKX_EFAILED; + int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf)); + if (fd < 0) { + return NSTACKX_EFAILED; + } + int32_t ifreqLen = (int32_t)sizeof(struct ifreq); + int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen); + for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) { + /* get IP of this interface */ + int32_t state = GetInterfaceIP(fd, &buf[i]); + if (state == NSTACKX_EFAILED) { + break; + } else if (state == NSTACKX_EINVAL) { + continue; + } + if (strlen(buf[i].ifr_name) == strlen(targetInterfaceName) && + strcmp(buf[i].ifr_name, targetInterfaceName) == 0) { + ret = BindToDeviceInner(sockfd, &buf[i]); + break; + } + } + CloseSocketInner(fd); + return ret; +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_epoll.c b/components/nstackx/nstackx_util/platform/unix/sys_epoll.c new file mode 100644 index 000000000..dd86efd8f --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_epoll.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_epoll.h" +#include "nstackx_log.h" +#include "nstackx_error.h" + +#define TAG "nStackXEpoll" +#define MAX_EPOLL_SIZE 128 + +int32_t RefreshEpollTask(EpollTask *task, uint32_t events) +{ + struct epoll_event event; + if (task == NULL) { + return NSTACKX_EINVAL; + } + event.data.ptr = task; + event.events = events; + + if (epoll_ctl(task->epollfd, EPOLL_CTL_MOD, task->taskfd, &event) < 0) { + LOGE(TAG, "Refresh task failed: %d", errno); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +int32_t RegisterEpollTask(EpollTask *task, uint32_t events) +{ + struct epoll_event event; + if (task == NULL) { + return NSTACKX_EINVAL; + } + event.data.ptr = task; + event.events = events; + if (epoll_ctl(task->epollfd, EPOLL_CTL_ADD, task->taskfd, &event) < 0) { + LOGE(TAG, "Register task failed: %d", errno); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +int32_t DeRegisterEpollTask(EpollTask *task) +{ + if (task == NULL) { + return NSTACKX_EINVAL; + } + if (epoll_ctl(task->epollfd, EPOLL_CTL_DEL, task->taskfd, NULL) < 0) { + LOGE(TAG, "De-register task failed: %d", errno); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +EpollDesc CreateEpollDesc(void) +{ + return epoll_create(1); +} + +int32_t EpollLoop(EpollDesc epollfd, int32_t timeout) +{ + int32_t i, nfds; + EpollTask *task = NULL; + struct epoll_event events[MAX_EPOLL_SIZE]; + + nfds = epoll_wait(epollfd, events, MAX_EPOLL_SIZE, timeout); + if (nfds < 0) { + LOGE(TAG, "epoll_wait returned n=%d, error: %d", nfds, errno); + if (errno != EINTR) { + return NSTACKX_EFAILED; + } else { + return NSTACKX_EINTR; + } + } + + for (i = 0; i < nfds; i++) { + task = events[i].data.ptr; + if (task == NULL) { + continue; + } + + if (events[i].events & EPOLLIN) { + if (task->readHandle != NULL) { + task->readHandle(task); + } + } + + if (events[i].events & EPOLLOUT) { + if (task->writeHandle != NULL) { + task->writeHandle(task); + } + } + } + + return ((nfds > 0) ? nfds : NSTACKX_ETIMEOUT); +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_epoll.h b/components/nstackx/nstackx_util/platform/unix/sys_epoll.h new file mode 100644 index 000000000..6433392bb --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_epoll.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYS_EPOLL_H +#define SYS_EPOLL_H + +#include "nstackx_common_header.h" +#include "sys_util.h" + +typedef int32_t EpollDesc; +typedef int32_t TaskDesc; + +#define INVALID_EPOLL_DESC (-1) +#define INVALID_TASK_DESC (-1) + +#define REPRESENT_EPOLL_DESC(epollfd) (epollfd) + +static inline bool IsEpollDescValid(EpollDesc epollfd) +{ + return (epollfd >= 0); +} + +static inline bool IsEpollDescEqual(EpollDesc epollfd1, EpollDesc epollfd2) +{ + return (epollfd1 == epollfd2); +} + +static inline void CloseEpollDesc(EpollDesc epollfd) +{ + CloseDesc(epollfd); +} + +#endif // SYS_EPOLL_H diff --git a/components/nstackx/nstackx_util/platform/unix/sys_event.c b/components/nstackx/nstackx_util/platform/unix/sys_event.c new file mode 100644 index 000000000..12713305c --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_event.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_event.h" +#include "nstackx_log.h" +#include "nstackx_error.h" +#include "nstackx_util.h" +#include "securec.h" + +#define TAG "nStackXEvent" + +typedef struct { + EventHandle handle; + void *arg; +} EventInfo; + +EventNode *SearchEventNode(const List *eventNodeChain, EpollDesc epollfd); + +void CloseNodePipe(const EventNode *node) +{ + CloseDesc(node->pipeFd[PIPE_OUT]); + CloseDesc(node->pipeFd[PIPE_IN]); +} + +static void EventProcessHandle(void *arg) +{ + int32_t ret; + EventInfo event = {0}; + EpollTask *task = arg; + EventNode *node = container_of(task, EventNode, task); + + ret = (int32_t)read(node->pipeFd[PIPE_OUT], &event, sizeof(event)); + if (ret != (int32_t)sizeof(event)) { + LOGE(TAG, "failed to read from pipe: %d", GetErrno()); + return; + } + + if (event.handle != NULL) { + event.handle(event.arg); + } +} + +int32_t PostEvent(const List *eventNodeChain, EpollDesc epollfd, EventHandle handle, void *arg) +{ + int32_t ret; + EventNode *node = NULL; + EventInfo event = { + .handle = handle, + .arg = arg, + }; + + if (eventNodeChain == NULL || handle == NULL) { + return NSTACKX_EINVAL; + } + + node = SearchEventNode(eventNodeChain, epollfd); + if (node == NULL) { + LOGE(TAG, "Cannot find event node for %d", epollfd); + return NSTACKX_EFAILED; + } + + ret = (int32_t)write(node->pipeFd[PIPE_IN], &event, sizeof(event)); + if (ret != (int32_t)sizeof(event)) { + LOGE(TAG, "failed to write to pipe: %d", errno); + return NSTACKX_EFAILED; + } + return NSTACKX_EOK; +} + +void ClearEvent(const List *eventNodeChain, EpollDesc epollfd) +{ + EventNode *node = NULL; + EventInfo event = {0}; + int32_t eventLen = (int32_t)sizeof(event); + if (eventNodeChain == NULL) { + LOGE(TAG, "eventNodeChain is null"); + return; + } + + node = SearchEventNode(eventNodeChain, epollfd); + if (node == NULL) { + return; + } + + int32_t ret = eventLen; + while (ret == eventLen) { + ret = (int32_t)read(node->pipeFd[PIPE_OUT], &event, sizeof(event)); + if (ret != eventLen) { + break; + } + + if (event.handle != NULL) { + event.handle(event.arg); + } + } +} + +static int32_t CreateNonBlockPipe(EventNode *node) +{ + int32_t ret; + int32_t i, flags; + + if (pipe(node->pipeFd) < 0) { + LOGE(TAG, "create pipe error: %d", errno); + return NSTACKX_EFAILED; + } + + for (i = 0; i < PIPE_FD_NUM; i++) { + flags = fcntl(node->pipeFd[i], F_GETFL, 0); + if (flags < 0) { + LOGE(TAG, "fcntl get flags failed: %d", errno); + CloseNodePipe(node); + return NSTACKX_EFAILED; + } + + flags = (int32_t)((uint32_t)flags | O_NONBLOCK); + ret = fcntl(node->pipeFd[i], F_SETFL, flags); + if (ret < 0) { + LOGE(TAG, "fcntl set flags to non-blocking failed: %d", errno); + CloseNodePipe(node); + return NSTACKX_EFAILED; + } + } + + return NSTACKX_EOK; +} + +int32_t EventModuleInit(List *eventNodeChain, EpollDesc epollfd) +{ + List *pos = NULL; + EventNode *node = NULL; + if (eventNodeChain == NULL) { + LOGE(TAG, "eventNodeChain is null"); + return NSTACKX_EINVAL; + } + LIST_FOR_EACH(pos, eventNodeChain) { + node = (EventNode *)pos; + if (node->epollfd == epollfd) { + return NSTACKX_EOK; + } + } + + node = calloc(1, sizeof(EventNode)); + if (node == NULL) { + return NSTACKX_ENOMEM; + } + + if (CreateNonBlockPipe(node) != NSTACKX_EOK) { + goto L_ERR_FAILED; + } + + node->task.taskfd = node->pipeFd[PIPE_OUT]; + node->task.epollfd = epollfd; + node->task.readHandle = EventProcessHandle; + + node->epollfd = epollfd; + if (RegisterEpollTask(&node->task, EPOLLIN) != NSTACKX_EOK) { + LOGE(TAG, "RegisterEpollTask failed"); + CloseNodePipe(node); + goto L_ERR_FAILED; + } + + ListInsertTail(eventNodeChain, &(node->list)); + return NSTACKX_EOK; +L_ERR_FAILED: + free(node); + return NSTACKX_EFAILED; +} + +void DeleteEventNode(EventNode *node) +{ + ListRemoveNode(&node->list); + if (DeRegisterEpollTask(&node->task) != NSTACKX_EOK) { + LOGE(TAG, "DeRegisterEpollTask failed"); + } + CloseNodePipe(node); + free(node); +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_event.h b/components/nstackx/nstackx_util/platform/unix/sys_event.h new file mode 100644 index 000000000..900883583 --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_event.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYS_EVENT_H +#define SYS_EVENT_H + +#include "nstackx_common_header.h" + +typedef int32_t PipeDesc; + +#define INVALID_PIPE_DESC (-1) + +#endif // SYS_EVENT_H diff --git a/components/nstackx/nstackx_util/platform/unix/sys_log.c b/components/nstackx/nstackx_util/platform/unix/sys_log.c new file mode 100644 index 000000000..6fda96191 --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_log.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_log.h" + +__attribute__((format(printf, 3, 4))) +void PrintfImpl(const char *moduleName, uint32_t logLevel, const char *format, ...) +{ + va_list args; + + va_start(args, format); + printf("%u %s: ", logLevel, moduleName); + vprintf(format, args); + va_end(args); +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_timer.c b/components/nstackx/nstackx_util/platform/unix/sys_timer.c new file mode 100644 index 000000000..f124e057e --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_timer.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_timer.h" +#include "nstackx_log.h" +#include "nstackx_error.h" +#include "securec.h" + +#define TAG "nStackXTimer" + +void TimerDelete(Timer *timer) +{ + if (timer == NULL) { + return; + } + if (timer->task.taskfd != INVALID_TASK_DESC) { + if (DeRegisterEpollTask(&(timer->task)) != NSTACKX_EOK) { + LOGE(TAG, "DeRegisterEpollTask failed"); + } + if (close(timer->task.taskfd) < 0) { + LOGE(TAG, "close timer task failed"); + } + timer->task.taskfd = INVALID_TASK_DESC; + } + free(timer); +} + +static void TimerReadHandle(void *arg) +{ + EpollTask *task = arg; + Timer *timer = NULL; + uint64_t exp; + if (task == NULL) { + LOGE(TAG, "Timer task is NULL"); + return; + } + + timer = task->ptr; + if (timer == NULL) { + LOGE(TAG, "Timer is NULL"); + return; + } + + if (timer->disabled) { + LOGD(TAG, "User disable timer before timer callback."); + return; + } + + if (read(task->taskfd, &exp, sizeof(exp)) != (ssize_t)(sizeof(uint64_t))) { + LOGE(TAG, "read invalid exp"); + return; + } + + if (timer->timeoutHandle != NULL) { + timer->timeoutHandle(timer->data); + } + return; +} + +int32_t TimerGetRemainTime(Timer *timer, uint32_t *remainTimeMsPtr) +{ + struct itimerspec currValue = {{0}, {0}}; + + if (timer == NULL || remainTimeMsPtr == NULL) { + LOGE(TAG, "Invalid timer parameter"); + return NSTACKX_EINVAL; + } + + if (timerfd_gettime(timer->task.taskfd, &currValue) < 0) { + LOGE(TAG, "timerfd_gettime() failed! %d", errno); + return NSTACKX_EFAILED; + } + + *remainTimeMsPtr = (uint32_t)(currValue.it_value.tv_sec * NSTACKX_MILLI_TICKS + + currValue.it_value.tv_nsec / NSTACKX_MILLI_TICKS / NSTACKX_MILLI_TICKS); + + return NSTACKX_EOK; +} + +int32_t TimerSetTimeout(Timer *timer, uint32_t timeoutMs, uint8_t repeated) +{ + struct itimerspec ts; + + if (timer == NULL) { + LOGE(TAG, "Invalid timer parameter"); + return NSTACKX_EINVAL; + } + + (void)memset_s(&ts, sizeof(ts), 0, sizeof(ts)); + if (timeoutMs) { + ts.it_value.tv_sec = timeoutMs / NSTACKX_MILLI_TICKS; + ts.it_value.tv_nsec = (timeoutMs % NSTACKX_MILLI_TICKS) * NSTACKX_NANO_SEC_PER_MILLI_SEC; + if (repeated) { + ts.it_interval.tv_sec = ts.it_value.tv_sec; + ts.it_interval.tv_nsec = ts.it_value.tv_nsec; + } + timer->disabled = NSTACKX_FALSE; + } else { + timer->disabled = NSTACKX_TRUE; + } + + if (timerfd_settime(timer->task.taskfd, 0, &ts, NULL) < 0) { + LOGE(TAG, "timerfd_settime failed! %d", errno); + return NSTACKX_EFAILED; + } + + return NSTACKX_EOK; +} + +Timer *TimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data) +{ + Timer *timer = calloc(1, sizeof(Timer)); + if (timer == NULL) { + LOGE(TAG, "timer malloc failed"); + return NULL; + } + + timer->timeoutHandle = handle; + timer->data = data; + timer->disabled = NSTACKX_FALSE; + + timer->task.taskfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + if (timer->task.taskfd < 0) { + LOGE(TAG, "timer create failed! errno %d", errno); + TimerDelete(timer); + return NULL; + } + + if (TimerSetTimeout(timer, ms, repeated) != NSTACKX_EOK) { + TimerDelete(timer); + return NULL; + } + + timer->task.epollfd = epollfd; + timer->task.readHandle = TimerReadHandle; + timer->task.writeHandle = NULL; + timer->task.endHandle = NULL; + timer->task.errorHandle = NULL; + timer->task.ptr = timer; + + if (RegisterEpollTask(&timer->task, EPOLLIN) != NSTACKX_EOK) { + LOGE(TAG, "RegisterEpollTask failed"); + TimerDelete(timer); + return NULL; + } + return timer; +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_util.c b/components/nstackx/nstackx_util/platform/unix/sys_util.c new file mode 100644 index 000000000..163f48c1c --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_util.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nstackx_util.h" +#include "nstackx_error.h" +#include "nstackx_log.h" +#include "securec.h" + +#define TAG "nStackXUtil" + +static const char *g_illegalPathString[] = { + "/../", +}; + +static const char *g_illegalPathHeadString[] = { + "../", +}; + +uint8_t IsFileNameLegal(const char *fileName) +{ + if (fileName == NULL || strlen(fileName) == 0) { + return NSTACKX_FALSE; + } + + for (uint32_t idx = 0; idx < sizeof(g_illegalPathHeadString) / sizeof(g_illegalPathHeadString[0]); idx++) { + if (g_illegalPathHeadString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathHeadString[idx])) { + continue; + } + if (memcmp(fileName, g_illegalPathHeadString[idx], strlen(g_illegalPathHeadString[idx])) == 0) { + LOGE(TAG, "illegal filename"); + return NSTACKX_FALSE; + } + } + + for (uint32_t idx = 0; idx < sizeof(g_illegalPathString) / sizeof(g_illegalPathString[0]); idx++) { + if (g_illegalPathString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathString[idx])) { + continue; + } + if (strstr(fileName, g_illegalPathString[idx]) != NULL) { + LOGE(TAG, "illegal filename"); + return NSTACKX_FALSE; + } + } + return NSTACKX_TRUE; +} + +int32_t GetCpuNum(void) +{ + return (int)sysconf(_SC_NPROCESSORS_CONF); +} + +void StartThreadBindCore(int32_t cpu) +{ + int32_t cpus; + cpu_set_t mask; + int32_t syscallres; + pid_t tid = gettid(); + if (cpu < 0) { + return; + } + cpus = GetCpuNum(); + if (cpus < cpu + 1) { + return; + } + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask); + if (syscallres < 0) { + LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno); + return; + } +} + +void BindThreadToTargetMask(pid_t tid, uint32_t cpuMask) +{ + if (tid == 0) { + LOGE(TAG, "invalid tid"); + return; + } + + int32_t cpus = GetCpuNum(); + if (cpus < 0) { + return; + } + + if (cpuMask == 0 || cpuMask >= (1U << (uint32_t)cpus)) { + LOGE(TAG, "invalid cpu mask"); + return; + } + cpu_set_t mask; + int32_t syscallres; + uint32_t cpu = CPU_IDX_0; + CPU_ZERO(&mask); + LOGI(TAG, "bind thread %d to target core :%x", tid, cpuMask); + while (cpuMask > 0) { + if ((cpuMask & 1) == 1) { + CPU_SET(cpu, &mask); + } + cpu++; + cpuMask = cpuMask >> 1; + } + syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask); + if (syscallres < 0) { + LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno); + return; + } +} + +void SetThreadName(const char *name) +{ + if (name == NULL || strlen(name) == 0 || strlen(name) >= MAX_THREAD_NAME_LEN) { + LOGE(TAG, "invalid input"); + } + if (prctl(PR_SET_NAME, name) < 0) { + LOGE(TAG, "prctl errno %d", errno); + } +} + +void SetMaximumPriorityForThread(void) +{ + if (nice(THREAD_MAXIMUM_PRIORITY) == -1) { + LOGE(TAG, "nice set error: %d", errno); + } +} + +void ClockGetTime(clockid_t id, struct timespec *tp) +{ + if (clock_gettime(id, tp) != 0) { + LOGE(TAG, "clock_gettime error: %d", errno); + } +} + +int32_t SemInit(sem_t *sem, int pshared, unsigned int value) +{ + return sem_init(sem, pshared, value); +} + +void SemGetValue(sem_t *sem, int *sval) +{ + if (sem_getvalue(sem, sval) != 0) { + LOGE(TAG, "sem get error: %d", errno); + } +} + +void SemPost(sem_t *sem) +{ + if (sem_post(sem) != 0) { + LOGE(TAG, "sem post error: %d", errno); + } +} + +void SemWait(sem_t *sem) +{ + if (sem_wait(sem) != 0) { + LOGE(TAG, "sem wait error: %d", errno); + } +} + +void SemDestroy(sem_t *sem) +{ + if (sem_destroy(sem) != 0) { + LOGE(TAG, "sem destroy error: %d", errno); + } +} + +int32_t PthreadCreate(pthread_t *tid, const pthread_attr_t *attr, void *(*entry)(void *), void *arg) +{ + return pthread_create(tid, attr, entry, arg); +} + +void PthreadJoin(pthread_t thread, void **retval) +{ + if (pthread_join(thread, retval) != 0) { + LOGE(TAG, "pthread_join failed error: %d", errno); + } +} + +int32_t PthreadMutexInit(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + return pthread_mutex_init(mutex, attr); +} + +void PthreadMutexDestroy(pthread_mutex_t *mutex) +{ + if (pthread_mutex_destroy(mutex) != 0) { + LOGE(TAG, "pthread mutex destroy error: %d", errno); + } +} + +int32_t PthreadMutexLock(pthread_mutex_t *mutex) +{ + return pthread_mutex_lock(mutex); +} + +int32_t PthreadMutexUnlock(pthread_mutex_t *mutex) +{ + return pthread_mutex_unlock(mutex); +} + +void CloseDesc(int32_t desc) +{ + if (close(desc) != 0) { + LOGE(TAG, "close desc error : %d", errno); + } +} diff --git a/components/nstackx/nstackx_util/platform/unix/sys_util.h b/components/nstackx/nstackx_util/platform/unix/sys_util.h new file mode 100644 index 000000000..c8ad2ffb9 --- /dev/null +++ b/components/nstackx/nstackx_util/platform/unix/sys_util.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYS_UTIL_H +#define SYS_UTIL_H + +#include "nstackx_common_header.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PATH_SEPARATOR '/' +#define INVALID_TID (pthread_t)(-1) + +typedef uint64_t atomic_t; + +#define NSTACKX_ATOM_FETCH(ptr) (*ptr) +#define NSTACKX_ATOM_SET(ptr, i) ((*ptr) = (i)) +#define NSTACKX_ATOM_FETCH_INC(ptr) __sync_fetch_and_add((ptr), 1) +#define NSTACKX_ATOM_FETCH_DEC(ptr) __sync_fetch_and_sub((ptr), 1) +#define NSTACKX_ATOM_ADD_RETURN(ptr, i) __sync_add_and_fetch((ptr), i) +#define NSTACKX_ATOM_FETCH_ADD(ptr, val) __sync_fetch_and_add((ptr), (val)) +#define NSTACKX_ATOM_FETCH_SUB(ptr, val) __sync_fetch_and_sub((ptr), (val)) + +static inline int32_t GetErrno(void) +{ + return errno; +} + +#define CloseSocketInner CloseDesc +#define gettid() (pid_t)syscall(__NR_gettid) +NSTACKX_EXPORT void CloseDesc(int32_t desc); +NSTACKX_EXPORT int32_t GetInterfaceList(struct ifconf *ifc, struct ifreq *buf, uint32_t size); +NSTACKX_EXPORT int32_t GetInterfaceIP(int32_t fd, struct ifreq *interface); +NSTACKX_EXPORT int32_t GetTargetInterface(const struct sockaddr_in *dstAddr, struct ifreq *localDev); + +#ifdef __cplusplus +} +#endif + +#endif // NSTACKX_UTIL_H diff --git a/core/BUILD.gn b/core/BUILD.gn new file mode 100755 index 000000000..8a3cfdd65 --- /dev/null +++ b/core/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") + +lite_component("softbus_server") { + features = [ + "connection:softbus_connection", + "frame/lite:softbus_server_frame", + "common:softbus_core_common", + "bus_center:softbus_bus_center", + + "transmission:softbus_server_transmission", + "adapter/kernel:softbus_adapter_kernel", + "adapter/bus_center:softbus_adapter_bus_center", + ] +} diff --git a/core/adapter/br/include/bt_rfcom.h b/core/adapter/br/include/bt_rfcom.h new file mode 100755 index 000000000..a4263491a --- /dev/null +++ b/core/adapter/br/include/bt_rfcom.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BT_RFCOM_H +#define BT_RFCOM_H + +#include "ohos_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BT_ADDR_LEN 6 +#define BT_UUID_LEN 16 +#define BT_RFCOM_NAME_MAX_LEN 31 +#define BT_RFCOM_CLIENT_INVALID_HANDLE 0xFF + +typedef uint8 BT_UUID[BT_UUID_LEN]; +typedef uint8 BD_ADDR[BT_ADDR_LEN]; + +typedef enum { + BT_RFCOM_EVENT_READ = 0x00, /* not used */ + BT_RFCOM_EVENT_ACCEPT, + BT_RFCOM_EVENT_DISCONNECT, + BT_RFCOM_EVENT_CONNECT, + BT_RFCOM_EVENT_CONGEST, +} BtRfcomEventType; + +typedef struct { + /* event type BtRfcomEventType */ + void (*OnEvent)(uint8 type, uint8 handle, int value); + void (*OnDataReceived)(uint8 handle, const uint8 *buf, uint16 len); +} BtRfcomEventCallback; + +typedef enum { + BT_RFCOM_STATUS_OK, + BT_RFCOM_STATUS_INVALID_HANDLE, + BT_RFCOM_STATUS_UNUSED_HANDLE, + BT_RFCOM_STATUS_INVALID_PARAM, +} BtRfcomStatus; + +/* + * return handle, BT_RFCOM_CLIENT_INVALID_HANDLE is invalid + */ +uint8 BtRfcomClientCreate(const BD_ADDR mac, const BT_UUID uuid); +/* + * BT_RFCOM_STATUS_OK means success, otherwise fail + */ +uint8 BtRfcomClientConnect(uint8 handle, BtRfcomEventCallback *cb); +/* + * BT_RFCOM_STATUS_OK means success, otherwise fail + */ +uint8 BtRfcomClientDisconnect(uint8 handle); +/* + * BT_RFCOM_STATUS_OK means success, otherwise fail + */ +uint8 BtRfcomClientWrite(uint8 handle, uint8 *data, uint16 dataLen); +/* + * BT_RFCOM_STATUS_OK means success, otherwise fail + */ +uint8 BtRfcomServerAccept(uint8 handle, BtRfcomEventCallback *cb); +/* + * return handle, BT_RFCOM_CLIENT_INVALID_HANDLE is invalid + */ +uint8 BtRfcomServerCreate(const char *name, const BT_UUID uuid); + +void BtRfcomHandleResponse(const uint8 *data, uint16 dataLen); + +#ifdef __cplusplus +} +#endif +#endif /* BT_RFCOM_H */ diff --git a/core/adapter/br/include/wrapper_br_interface.h b/core/adapter/br/include/wrapper_br_interface.h new file mode 100755 index 000000000..f0d05f30f --- /dev/null +++ b/core/adapter/br/include/wrapper_br_interface.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WRAPPER_BR_INTERFACE_H +#define WRAPPER_BR_INTERFACE_H + +#include +#include "ohos_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BR_NAME_LEN 16 +#define BT_ADDR_LEN 6 +#define BT_UUID_LEN 16 + +typedef uint8_t BT_UUIDL[BT_UUID_LEN]; +typedef uint8_t BT_ADDR[BT_ADDR_LEN]; + +enum SppEventType { + SPP_EVENT_TYPE_ACCEPT = 1, + SPP_EVENT_TYPE_DISCONNECTED, + SPP_EVENT_TYPE_CONNECTED, + SPP_EVENT_TYPE_CONGEST +}; + +typedef struct { + // 0:read, 1:accept, 2:disconnected, 3:congest, 4:connteced + void (*OnEvent)(int32_t type, int32_t socketFd, int32_t value); + void (*OnDataReceived)(int32_t socketFd, const char* buf, int32_t len); +} SppSocketEventCallback; + +typedef struct { + BT_UUIDL uuid; + BT_ADDR mac; + char name[BR_NAME_LEN]; +} BluetoothRemoteDevice; + +typedef struct tagSppSocketDriver { + void (*Init)(const struct tagSppSocketDriver* this_p); + int32_t (*OpenSppServer)(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure); + int32_t (*OpenSppClient)(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure); + int32_t (*CloseClient)(int32_t clientFd); + void (*CloseServer)(int32_t serverFd); + int32_t (*Connect)(int32_t clientFd, const SppSocketEventCallback* callback); + int32_t (*GetRemoteDeviceInfo)(int32_t clientFd, const BluetoothRemoteDevice* device); + int32_t (*IsConnected)(int32_t clientFd); + int32_t (*Accept)(int32_t serverFd, const SppSocketEventCallback* callback); + int32_t (*Write)(int32_t clientFd, const char* buf, const int32_t length); +} SppSocketDriver; + +SppSocketDriver* InitSppSocketDriver(); + +#ifdef __cplusplus +} +#endif +#endif /* WRAPPER_BR_INTERFACE_H */ \ No newline at end of file diff --git a/core/adapter/br/mock/BUILD.gn b/core/adapter/br/mock/BUILD.gn new file mode 100755 index 000000000..d211f7c42 --- /dev/null +++ b/core/adapter/br/mock/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +static_library("br_adapter") { + sources = [ "wrapper_br_interface.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/adapter/br/include", + "$dsoftbus_root_path/core/common/message_handler/include", + ] +} diff --git a/core/adapter/br/mock/wrapper_br_interface.c b/core/adapter/br/mock/wrapper_br_interface.c new file mode 100755 index 000000000..ad13b9ccd --- /dev/null +++ b/core/adapter/br/mock/wrapper_br_interface.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "wrapper_br_interface.h" + +#include "bt_rfcom.h" +#include "message_handler.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +static SppSocketEventCallback *g_connectCallback = NULL; +static SppSocketEventCallback *g_connectServiceCallback = NULL; + +static void OnEventRfcom(uint8 type, uint8 handle, int value) +{ + g_connectCallback->OnEvent((int32_t)type, (int32_t)handle, value); +} + +static void OnDataReceivedRfcom(uint8 handle, const uint8 *buf, uint16 len) +{ + g_connectCallback->OnDataReceived((int32_t)handle, (char*)buf, (int32_t)len); +} + +static BtRfcomEventCallback g_rfcomEventcb = { + .OnEvent = OnEventRfcom, + .OnDataReceived = OnDataReceivedRfcom +}; + +static void OnEventServiceRfcom(uint8 type, uint8 handle, int value) +{ + LOG_INFO("[Client event call back form bt, and socketid = %u, tpye = %u]", handle, type); + if (g_connectServiceCallback == NULL) { + LOG_INFO("[g_connectServiceCallback is NULL]"); + return; + } + g_connectServiceCallback->OnEvent((int32_t)type, (int32_t)handle, value); +} + +static void OnDataReceivedServiceRfcom(uint8 handle, const uint8 *buf, uint16 len) +{ + LOG_INFO("[Client received call back form bt, and socketid = %u, len = %u]", handle, len); + if (g_connectServiceCallback == NULL) { + LOG_INFO("[g_connectServiceCallback is NULL]"); + return; + } + g_connectServiceCallback->OnDataReceived((int32_t)handle, (char*)buf, (int32_t)len); +} + +static BtRfcomEventCallback g_rfcomServiceEventcb = { + .OnEvent = OnEventServiceRfcom, + .OnDataReceived = OnDataReceivedServiceRfcom +}; + +static int32_t Connect(int32_t clientFd, const SppSocketEventCallback *callback) +{ + LOG_INFO("[mock clientFd = %d]", clientFd); + g_connectCallback = (SppSocketEventCallback*)callback; + int ret = BtRfcomClientConnect((uint8)clientFd, &g_rfcomEventcb); + LOG_INFO("[BtRfcom return = %d]", ret); + ret = (ret == BT_RFCOM_STATUS_OK) ? SOFTBUS_OK : SOFTBUS_ERR; + return ret; +} + +static void Init(const struct tagSppSocketDriver *sppDriver) +{ + (void)sppDriver; +} + +static int32_t OpenSppServer(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure) +{ + LOG_INFO("[OpenSppServer connect]"); + return SOFTBUS_ERR; +} + +static int32_t OpenSppClient(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure) +{ + (void)isSecure; + int ret = BtRfcomClientCreate(mac, uuid); + if (ret == BT_RFCOM_CLIENT_INVALID_HANDLE) { + return SOFTBUS_ERR; + } + return ret; +} + +static int32_t CloseClient(int32_t clientFd) +{ + LOG_INFO("[CloseClient connect, and serverFd = %d]", clientFd); + return BtRfcomClientDisconnect((uint8)clientFd); +} + +static void CloseServer(int32_t serverFd) +{ + LOG_INFO("[CloseServer Connect, and serverFd = %d]", serverFd); +} + + +static int32_t GetRemoteDeviceInfo(int32_t clientFd, const BluetoothRemoteDevice *device) +{ + LOG_INFO("[to get remotedeviceinfo, clientFd = %d]", clientFd); + return 0; +} + +static int32_t IsConnected(int32_t clientFd) +{ + LOG_INFO("[to get connected state from bt, clientFd = %d]", clientFd); + return true; +} + +static int32_t Accept(int32_t serverFd, const SppSocketEventCallback *callback) +{ + LOG_INFO("[Accept remote device to connect, and serverFd = %d]", serverFd); + g_connectServiceCallback = (SppSocketEventCallback*)callback; + return 0; +} + +static int32_t Write(int32_t g_clientFd, const char *buf, const int32_t length) +{ + LOG_INFO("[mock Write] g_clientFd=%d,len=%d", g_clientFd, length); + return BtRfcomClientWrite((uint8)g_clientFd, (uint8 *)buf, (uint16)length); +} + +static SppSocketDriver g_sppSocketDriver = { + .Init = Init, + .OpenSppServer = OpenSppServer, + .OpenSppClient = OpenSppClient, + .CloseClient = CloseClient, + .CloseServer = CloseServer, + .Connect = Connect, + .GetRemoteDeviceInfo = GetRemoteDeviceInfo, + .IsConnected = IsConnected, + .Accept = Accept, + .Write = Write +}; + +SppSocketDriver *InitSppSocketDriver() +{ + LOG_INFO("[InitSppSocketDriver]"); + Init(&g_sppSocketDriver); + return &g_sppSocketDriver; +} \ No newline at end of file diff --git a/core/adapter/bus_center/BUILD.gn b/core/adapter/bus_center/BUILD.gn new file mode 100755 index 000000000..5fc6bb857 --- /dev/null +++ b/core/adapter/bus_center/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_adapter_bus_center") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ "platform/bus_center_adapter_weak.c" ] + } +} else { + shared_library("softbus_adapter_bus_center") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + ] + sources = [ "platform/bus_center_adapter_weak.c" ] + } +} diff --git a/core/adapter/bus_center/include/bus_center_adapter.h b/core/adapter/bus_center/include/bus_center_adapter.h new file mode 100644 index 000000000..cdfcc4c5f --- /dev/null +++ b/core/adapter/bus_center/include/bus_center_adapter.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_BUS_CENTER_ADAPTER_H +#define SOFTBUS_BUS_CENTER_ADAPTER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + COMM_DEVICE_KEY_UDID, + COMM_DEVICE_KEY_DEVTYPE, + COMM_DEVICE_KEY_DEVNAME, + COMM_DEVICE_KEY_BT_MAC, + COMM_DEVICE_KEY_BUTT +} CommonDeviceKey; + +#define TYPE_UNKNOWN "UNKNOWN" +#define TYPE_PHONE "PHONE" +#define TYPE_PAD "PAD" +#define TYPE_TV "TV" +#define TYPE_PC "PC" +#define TYPE_CAR "CAR" +#define TYPE_WATCH "WATCH" +#define TYPE_IPCAMERA "WiFiCamara" + +int32_t GetCommonDevInfo(const CommonDeviceKey key, char *value, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif // SOFTBUS_BUS_CENTER_ADAPTER_H diff --git a/core/adapter/bus_center/platform/bus_center_adapter_weak.c b/core/adapter/bus_center/platform/bus_center_adapter_weak.c new file mode 100644 index 000000000..8a35a9819 --- /dev/null +++ b/core/adapter/bus_center/platform/bus_center_adapter_weak.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include + +#include "bus_center_adapter.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +#define DEFAULT_DEVICE_NAME "UNKNOWN" +#define DEFAULT_UDID_NAME "ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00" + +int __attribute__ ((weak)) GetCommonDevInfo(const CommonDeviceKey key, char *value, uint32_t len) +{ + if (value == NULL) { + LOG_ERR("fail: para error!"); + return SOFTBUS_INVALID_PARAM; + } + switch (key) { + case COMM_DEVICE_KEY_DEVNAME: + if (strncpy_s(value, len, DEFAULT_DEVICE_NAME, strlen(DEFAULT_DEVICE_NAME)) != EOK) { + return SOFTBUS_ERR; + } + break; + case COMM_DEVICE_KEY_UDID: + if (strncpy_s(value, len, DEFAULT_UDID_NAME, strlen(DEFAULT_UDID_NAME)) != EOK) { + return SOFTBUS_ERR; + } + break; + case COMM_DEVICE_KEY_DEVTYPE: + break; + default: + break; + } + return SOFTBUS_OK; +} diff --git a/core/adapter/kernel/BUILD.gn b/core/adapter/kernel/BUILD.gn new file mode 100755 index 000000000..f0ca62b2e --- /dev/null +++ b/core/adapter/kernel/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_adapter_kernel") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//kernel/liteos_m/components/bounds_checking_function/include", + "//kernel/liteos_m/kal/cmsis", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ + "liteos_m/softbus_mem_interface.c", + "liteos_m/softbus_os_interface.c", + ] + } +} else { + shared_library("softbus_adapter_kernel") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ + "liteos_a/softbus_mem_interface.c", + "liteos_a/softbus_os_interface.c", + ] + public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ] + } +} diff --git a/core/adapter/kernel/include/softbus_mem_interface.h b/core/adapter/kernel/include/softbus_mem_interface.h new file mode 100755 index 000000000..1e1328951 --- /dev/null +++ b/core/adapter/kernel/include/softbus_mem_interface.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_MEM_INTERFACE_H +#define SOFTBUS_MEM_INTERFACE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define MAX_MALLOC_SIZE (512 * 1024 * 1024) // 512M + +/* Low speed memory pool */ +void *SoftBusMalloc(unsigned int size); +void *SoftBusCalloc(unsigned int size); +void SoftBusFree(void *pt); +/* High speed memory pool */ +void *SoftBusHighSpeedMalloc(unsigned int size); +void *SoftBusHighSpeedCalloc(unsigned int size); +void SoftBusHighSpeedFree(void *pt); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/core/adapter/kernel/include/softbus_os_interface.h b/core/adapter/kernel/include/softbus_os_interface.h new file mode 100755 index 000000000..86852e562 --- /dev/null +++ b/core/adapter/kernel/include/softbus_os_interface.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_OS_INTERFACE_H +#define SOFTBUS_OS_INTERFACE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* Timer */ +void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type); +int SoftBusStartTimer(void *timerId, unsigned int tickets); +int SoftBusDeleteTimer(void *timerId); + +/* Sleep */ +int SoftBusSleepMs(unsigned int ms); + +/* File operation */ +int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen); +int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/core/adapter/kernel/liteos_a/softbus_mem_interface.c b/core/adapter/kernel/liteos_a/softbus_mem_interface.c new file mode 100755 index 000000000..498186f73 --- /dev/null +++ b/core/adapter/kernel/liteos_a/softbus_mem_interface.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_mem_interface.h" +#include +#include + +#include "softbus_log.h" + +void *SoftBusMalloc(unsigned int size) +{ + if (size > MAX_MALLOC_SIZE) { + return NULL; + } + return malloc(size); +} + +void *SoftBusCalloc(unsigned int size) +{ + void *tmp = SoftBusMalloc(size); + if (tmp == NULL) { + return NULL; + } + + errno_t err = memset_s(tmp, size, 0, size); + if (err != EOK) { + LOG_ERR("memset_s failed"); + SoftBusFree(tmp); + return NULL; + } + return tmp; +} + +void SoftBusFree(void *pt) +{ + if (pt == NULL) { + return; + } + free(pt); +} + +void *SoftBusHighSpeedMalloc(unsigned int size) +{ + return SoftBusMalloc(size); +} + +void *SoftBusHighSpeedCalloc(unsigned int size) +{ + void *tmp = SoftBusHighSpeedMalloc(size); + if (tmp == NULL) { + return NULL; + } + + errno_t err = memset_s(tmp, size, 0, size); + if (err != EOK) { + LOG_ERR("memset_s failed"); + SoftBusHighSpeedFree(tmp); + return NULL; + } + return tmp; +} + +void SoftBusHighSpeedFree(void *pt) +{ + if (pt == NULL) { + return; + } + free(pt); +} \ No newline at end of file diff --git a/core/adapter/kernel/liteos_a/softbus_os_interface.c b/core/adapter/kernel/liteos_a/softbus_os_interface.c new file mode 100755 index 000000000..b35547f19 --- /dev/null +++ b/core/adapter/kernel/liteos_a/softbus_os_interface.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_os_interface.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "securec.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +#define MS_PER_SECOND 1000 +#define US_PER_MSECOND 1000 + +static unsigned int g_timerType; + +void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type) +{ + if (timerId == NULL) { + LOG_ERR("timerId is null"); + return NULL; + } + struct sigevent envent; + (void)memset_s(&envent, sizeof(envent), 0, sizeof(envent)); + envent.sigev_notify = SIGEV_SIGNAL; + envent.sigev_signo = SIGUSR1; + signal(SIGUSR1, timerFunc); + + g_timerType = type; + if (timer_create(CLOCK_REALTIME, &envent, timerId) != 0) { + LOG_ERR("timer create error, errno code: [%d]", errno); + return NULL; + } + + return *timerId; +} + +int SoftBusStartTimer(void *timerId, unsigned int tickets) +{ + if (timerId == NULL) { + LOG_ERR("timerId is null"); + return SOFTBUS_ERR; + } + + struct itimerspec value; + (void)memset_s(&value, sizeof(value), 0, sizeof(value)); + value.it_value.tv_sec = tickets / MS_PER_SECOND; + value.it_value.tv_nsec = 0; + if (g_timerType == TIMER_TYPE_ONCE) { + value.it_interval.tv_sec = tickets = 0; + value.it_interval.tv_nsec = 0; + } else { + value.it_interval.tv_sec = tickets / MS_PER_SECOND; + value.it_interval.tv_nsec = 0; + } + + if (timer_settime(timerId, 0, &value, NULL) != 0) { + LOG_ERR("timer start error, errno code: [%d]", errno); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int SoftBusDeleteTimer(void *timerId) +{ + if (timerId == NULL) { + LOG_ERR("timerId is null"); + return SOFTBUS_ERR; + } + + if (timer_delete(timerId) != 0) { + LOG_ERR("timer delete err, errno code: [%d]", errno); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int SoftBusSleepMs(unsigned int ms) +{ + int ret; + struct timeval tm; + tm.tv_sec = ms / MS_PER_SECOND; + tm.tv_usec = (ms % MS_PER_SECOND) * US_PER_MSECOND; + + do { + ret = select(0, NULL, NULL, NULL, &tm); + } while ((ret == -1) && (errno == EINTR)); + + return SOFTBUS_ERR; +} + +int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen) +{ + if (fileName == NULL || readBuf == NULL || maxLen <= 0) { + return SOFTBUS_FILE_ERR; + } + + int fd = open(fileName, O_RDONLY, S_IRUSR | S_IWUSR); + if (fd < 0) { + LOG_ERR("ReadFile get deviceid open file fail"); + return SOFTBUS_FILE_ERR; + } + int fileLen = lseek(fd, 0, SEEK_END); + if (fileLen <= 0 || fileLen > maxLen) { + LOG_ERR("ReadFile maxLen failed or over maxLen"); + close(fd); + return SOFTBUS_FILE_ERR; + } + int ret = lseek(fd, 0, SEEK_SET); + if (ret < 0) { + LOG_ERR("ReadFile get deviceid lseek file fail"); + close(fd); + return SOFTBUS_FILE_ERR; + } + ret = read(fd, readBuf, fileLen); + if (ret < 0) { + LOG_ERR("ReadFile read deviceid fail, ret=%d", ret); + close(fd); + return SOFTBUS_FILE_ERR; + } + close(fd); + return SOFTBUS_OK; +} + +int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len) +{ + if (fileName == NULL || writeBuf == NULL || len <= 0) { + return SOFTBUS_FILE_ERR; + } + + int ret; + int fd; + + fd = open(fileName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + LOG_ERR("WriteDeviceId open file fail"); + return SOFTBUS_FILE_ERR; + } + ret = write(fd, writeBuf, len); + if (ret != len) { + LOG_ERR("WriteDeviceId write fail"); + close(fd); + return SOFTBUS_FILE_ERR; + } + close(fd); + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/adapter/kernel/liteos_m/softbus_mem_interface.c b/core/adapter/kernel/liteos_m/softbus_mem_interface.c new file mode 100755 index 000000000..86a28ff48 --- /dev/null +++ b/core/adapter/kernel/liteos_m/softbus_mem_interface.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_mem_interface.h" +#include +#include + +#if defined(OHOS_MEM) +#include "ohos_mem_pool.h" +#endif + +void *SoftBusMalloc(unsigned int size) +{ + if (size > MAX_MALLOC_SIZE) { + return NULL; + } + +#if defined(OHOS_MEM) + void *tmp = OhosMalloc(MEM_TYPE_SOFTBUS_LSRAM, size); +#else + void *tmp = malloc(size); +#endif + return tmp; +} + +void *SoftBusCalloc(unsigned int size) +{ + void *tmp = SoftBusMalloc(size); + if (tmp == NULL) { + return NULL; + } + + errno_t err = memset_s(tmp, size, 0, size); + if (err != EOK) { + SoftBusFree(tmp); + return NULL; + } + return tmp; +} + +void SoftBusFree(void *pt) +{ + if (pt == NULL) { + return; + } +#if defined(OHOS_MEM) + OhosFree(pt); +#else + free(pt); +#endif +} + +void *SoftBusHighSpeedMalloc(unsigned int size) +{ + if (size > MAX_MALLOC_SIZE) { + return NULL; + } + return malloc(size); +} + +void *SoftBusHighSpeedCalloc(unsigned int size) +{ + void *tmp = SoftBusHighSpeedMalloc(size); + if (tmp == NULL) { + return NULL; + } + + errno_t err = memset_s(tmp, size, 0, size); + if (err != EOK) { + SoftBusHighSpeedFree(tmp); + return NULL; + } + return tmp; +} + +void SoftBusHighSpeedFree(void *pt) +{ + if (pt == NULL) { + return; + } + free(pt); +} \ No newline at end of file diff --git a/core/adapter/kernel/liteos_m/softbus_os_interface.c b/core/adapter/kernel/liteos_m/softbus_os_interface.c new file mode 100755 index 000000000..8b4de503f --- /dev/null +++ b/core/adapter/kernel/liteos_m/softbus_os_interface.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_os_interface.h" + +#include "cmsis_os2.h" +#include "securec.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "utils_file.h" + +#define MS_PER_SECOND 1000 + +void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type) +{ + (void)timerId; + + void *id = osTimerNew((osTimerFunc_t)timerFunc, type, NULL, NULL); + if (id != NULL) { + LOG_INFO("create timer success"); + return id; + } + LOG_ERR("create timer failed"); + return NULL; +} + +int SoftBusStartTimer(void *timerId, unsigned int ms) +{ + if (osTimerStart(timerId, ms * osKernelGetTickFreq() / MS_PER_SECOND) != osOK) { + LOG_ERR("start timer failed"); + (void)osTimerDelete(timerId); + return SOFTBUS_ERR; + } + + LOG_INFO("start timer success"); + return SOFTBUS_OK; +} + +int SoftBusDeleteTimer(void *timerId) +{ + if (osTimerDelete(timerId) != osOK) { + LOG_ERR("delete timer failed"); + return SOFTBUS_ERR; + } + + LOG_INFO("delete timer success"); + return SOFTBUS_OK; +} + +int SoftBusSleepMs(unsigned int ms) +{ + osDelay(ms * osKernelGetTickFreq() / MS_PER_SECOND); + return SOFTBUS_OK; +} + +int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen) +{ + if (fileName == NULL || readBuf == NULL || maxLen <= 0) { + return SOFTBUS_INVALID_PARAM; + } + uint32_t fileLen = 0; + int fd = UtilsFileOpen(fileName, O_RDONLY_FS, 0); + if (fd < 0) { + LOG_ERR("Read UtilsFileOpen fail"); + return SOFTBUS_FILE_ERR; + } + int ret = UtilsFileStat(fileName, &fileLen); + if (ret < 0) { + UtilsFileClose(fd); + goto EXIT; + } + ret = UtilsFileSeek(fd, 0, SEEK_SET_FS); + if (ret < 0) { + LOG_ERR("Read UtilsFileSeek fail"); + goto EXIT; + } + if (fileLen > maxLen) { + LOG_ERR("Read file len not legal, clear buf"); + goto EXIT; + } + ret = UtilsFileRead(fd, readBuf, maxLen); + if (ret < 0) { + LOG_ERR("Read UtilsFileRead, ret=%d", ret); + goto EXIT; + } + UtilsFileClose(fd); + return SOFTBUS_OK; + +EXIT: + UtilsFileClose(fd); + return SOFTBUS_FILE_ERR; +} + +int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len) +{ + int ret; + int fd; + fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0); + if (fd < 0) { + LOG_ERR("WriteDeviceId UtilsFileOpen fail"); + return SOFTBUS_FILE_ERR; + } + ret = UtilsFileWrite(fd, writeBuf, len); + if (ret != len) { + LOG_ERR("UtilsFileOpen UtilsFileWrite fail"); + UtilsFileClose(fd); + return SOFTBUS_FILE_ERR; + } + UtilsFileClose(fd); + return SOFTBUS_OK; +} diff --git a/core/authentication/include/auth_common.h b/core/authentication/include/auth_common.h new file mode 100644 index 000000000..102b43144 --- /dev/null +++ b/core/authentication/include/auth_common.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_COMMON_H +#define AUTH_COMMON_H + +#include +#include + +#include "auth_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int64_t GetSeq(AuthSideFlag flag); +void UniqueIdInit(void); +AuthSideFlag AuthGetSideByRemoteSeq(int64_t seq); +int32_t AuthGetDeviceKey(char *key, uint32_t size, uint32_t *len, const ConnectOption *option); +int32_t AuthConvertConnInfo(ConnectOption *option, const ConnectionInfo *connInfo); + +#ifdef __cplusplus +} +#endif +#endif /* AUTH_COMMON_H */ diff --git a/core/authentication/include/auth_connection.h b/core/authentication/include/auth_connection.h new file mode 100644 index 000000000..4a831f9c6 --- /dev/null +++ b/core/authentication/include/auth_connection.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_CONNECTION_H +#define AUTH_CONNECTION_H + +#include "auth_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TAG "MsgGetDeviceId" +#define CMD_TAG "TECmd" +#define DATA_TAG "TEData" +#define TE_DEVICE_ID_TAG "TEDeviceId" +#define DATA_BUF_SIZE_TAG "DataBufSize" +#define CMD_GET_AUTH_INFO "getAuthInfo" +#define CMD_RET_AUTH_INFO "retAuthInfo" +#define SOFTBUS_VERSION_INFO "softbusVersion" + +#define CMD_TAG_LEN 30 +#define PACKET_SIZE (64 * 1024) + +int32_t AuthSyncDeviceUuid(AuthManager *auth); +int32_t AuthUnpackDeviceInfo(AuthManager *auth, uint8_t *data); +char *AuthGenDeviceLevelParam(const AuthManager *auth, bool isClient); +void AuthTryCloseConnection(uint32_t connectionId); +bool AuthOnTransmit(int64_t authId, const uint8_t *data, uint32_t len); +void AuthSendCloseAck(uint32_t connectionId); + +#ifdef __cplusplus +} +#endif +#endif /* AUTH_CONNECTION_H */ diff --git a/core/authentication/include/auth_manager.h b/core/authentication/include/auth_manager.h new file mode 100644 index 000000000..203e12b01 --- /dev/null +++ b/core/authentication/include/auth_manager.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_MANAGER_H +#define AUTH_MANAGER_H + +#include +#include +#include + +#include "auth_interface.h" +#include "bus_center_info_key.h" +#include "common_list.h" +#include "device_auth.h" +#include "softbus_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AUTH_APPID "softbus_auth" + +/* auth timeout delay */ +#define AUTH_DELAY_MS (10 * 1000) + +/* auth data max length */ +#define AUTH_MAX_DATA_LEN (2 * 1024) + +/* auth status */ +#define INIT_STATE 0 +#define WAIT_CONNECTION_ESTABLISHED 1 +#define IN_AUTH_PROGRESS 2 +#define IN_SYNC_PROGRESS 3 +#define SYNC_FINISH 4 +#define AUTH_PASSED 5 +#define AUTH_FAIL 6 + +typedef struct { + uint32_t type; + int32_t module; + int64_t authId; + int32_t flag; + uint32_t dataLen; +} AuthDataInfo; + +typedef struct { + uint32_t requestId; + uint32_t connectionId; + + int64_t authId; + AuthSideFlag side; + uint8_t status; + int32_t fd; + ConnectOption option; + + const GroupAuthManager *hichain; + VerifyCallback *cb; + + char peerUdid[UDID_BUF_LEN]; + char peerUuid[UUID_BUF_LEN]; + int32_t softbusVersion; + SoftBusVersion peerVersion; + + uint8_t *encryptDevData; + uint32_t encryptLen; + + pthread_mutex_t lock; + ListNode node; +} AuthManager; + +AuthManager *AuthGetManagerByRequestId(uint32_t requestId); +AuthManager *AuthGetManagerByAuthId(int64_t authId, AuthSideFlag side); +AuthManager *AuthGetManagerByFd(int32_t fd); +void AuthHandlePeerSyncDeviceInfo(AuthManager *auth, uint8_t *data, uint32_t len); +void HandleReceiveDeviceId(AuthManager *auth, uint8_t *data); +void HandleReceiveAuthData(AuthManager *auth, int32_t module, uint8_t *data, uint32_t dataLen); + +#ifdef __cplusplus +} +#endif +#endif /* AUTH_MANAGER_H */ diff --git a/core/authentication/include/auth_sessionkey.h b/core/authentication/include/auth_sessionkey.h new file mode 100644 index 000000000..b044b9bdf --- /dev/null +++ b/core/authentication/include/auth_sessionkey.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_SESSIONKEY_H +#define AUTH_SESSIONKEY_H + +#include "auth_manager.h" +#include "common_list.h" +#include "softbus_crypto.h" +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MESSAGE_INDEX_LEN 4 +#define ENCRYPT_OVER_HEAD_LEN (OVERHEAD_LEN + MESSAGE_INDEX_LEN) +#define MAX_KEY_LIST_SIZE 10 +#define LOW_32_BIT 0xFFFFFFFF + +typedef struct { + uint32_t type; + char deviceKey[MAX_DEVICE_KEY_LEN]; + uint32_t deviceKeyLen; + AuthSideFlag side; + int32_t seq; +} NecessaryDevInfo; + +typedef struct { + char deviceKey[MAX_DEVICE_KEY_LEN]; + uint32_t deviceKeyLen; + uint32_t type; + int32_t seq; + uint8_t sessionKey[SESSION_KEY_LENGTH]; + uint32_t sessionKeyLen; + char peerUdid[UDID_BUF_LEN]; + AuthSideFlag side; + ListNode node; +} SessionKeyList; + +void AuthSetLocalSessionKey(const NecessaryDevInfo *devInfo, const char *peerUdid, + const uint8_t *sessionKey, uint32_t sessionKeyLen); +bool AuthIsDeviceVerified(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen); +bool AuthIsSeqInKeyList(int32_t seq); +void AuthSessionKeyListInit(void); +void AuthClearSessionKeyByDeviceInfo(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen); +void AuthClearAllSessionKey(void); + +#ifdef __cplusplus +} +#endif +#endif /* AUTH_SESSIONKEY_H */ diff --git a/core/authentication/include/auth_socket.h b/core/authentication/include/auth_socket.h new file mode 100644 index 000000000..7af26d123 --- /dev/null +++ b/core/authentication/include/auth_socket.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_SOCKET_H +#define AUTH_SOCKET_H + +#include "auth_manager.h" +#include "softbus_conn_interface.h" +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t HandleIpVerifyDevice(AuthManager *auth, const ConnectOption *option); +void AuthCloseTcpFd(int32_t fd); +int32_t OpenAuthServer(void); +int32_t AuthSocketSendData(AuthManager *auth, const AuthDataHead *head, const uint8_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif /* AUTH_SOCKET_H */ diff --git a/core/authentication/interface/auth_interface.h b/core/authentication/interface/auth_interface.h new file mode 100755 index 000000000..1ad23771b --- /dev/null +++ b/core/authentication/interface/auth_interface.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTH_INTERFACE_H +#define AUTH_INTERFACE_H + +#include +#include + +#include "softbus_conn_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_DEVICE_KEY_LEN 64 +#define AUTH_ERROR_CODE (-1) + +typedef enum { + /* nearby type v1 */ + SOFT_BUS_OLD_V1 = 1, + + /* nearby type v2 */ + SOFT_BUS_OLD_V2 = 2, + + /* softbus type v1 */ + SOFT_BUS_NEW_V1 = 100, +} SoftBusVersion; + +typedef enum { + /* data type for device authentication */ + DATA_TYPE_AUTH = 0xFFFF0001, + + /* data type for synchronizing peer device information */ + DATA_TYPE_SYNC = 0xFFFF0002, + + /* data type for synchronizing peer device id */ + DATA_TYPE_DEVICE_ID = 0xFFFF0003, + + /* data type for connection */ + DATA_TYPE_CONNECTION = 0xFFFF0004, + + /* data type for closing ack */ + DATA_TYPE_CLOSE_ACK = 0xFFFF0005, +} AuthDataType; + +typedef enum { + /* reserved */ + NONE = 0, + + /* trust Engine, use plain text */ + TRUST_ENGINE = 1, + + /* hiChain, use plain text */ + HICHAIN = 2, + + /* authentication SDK, use plain text */ + AUTH_SDK = 3, + + /* hichain sync data, use plain text */ + HICHAIN_SYNC = 4, +} AuthDataModule; + +typedef enum { + CLIENT_SIDE_FLAG = 0, + SERVER_SIDE_FLAG = 1, +} AuthSideFlag; + +typedef enum { + LNN = 0, + MODULE_NUM, +} AuthModuleId; + +typedef struct { + uint8_t *buf; + uint32_t bufLen; + uint32_t outLen; +} OutBuf; + +typedef struct { + AuthDataType dataType; + int32_t module; + int64_t authId; + AuthSideFlag flag; +} AuthDataHead; + +typedef struct { + void (*onDeviceVerifyPass)(int64_t authId, ConnectOption *option, SoftBusVersion peerVersion); + void (*onDeviceVerifyFail)(int64_t authId, ConnectOption *option); + void (*onRecvSyncDeviceInfo)(int64_t authId, AuthSideFlag side, const char *peerUuid, uint8_t *data, uint32_t len); + void (*onDeviceNotTrusted)(const char *peerUdid); +} VerifyCallback; + +uint32_t AuthGetEncryptHeadLen(void); +int32_t AuthEncrypt(const ConnectOption *option, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf); +int32_t AuthDecrypt(const ConnectOption *option, AuthSideFlag side, uint8_t *data, uint32_t len, OutBuf *outbuf); + +int32_t OpenAuthServer(void); +void CloseAuthServer(void); +int32_t AuthRegCallback(AuthModuleId moduleId, VerifyCallback *cb); + +int32_t AuthVerifyInit(void); +int32_t AuthVerifyDevice(AuthModuleId moduleId, const ConnectOption *option); +int32_t AuthVerifyDeinit(void); + +int32_t AuthPostData(const AuthDataHead *head, const uint8_t *data, uint32_t len); +int32_t AuthHandleLeaveLNN(int64_t authId); + +int32_t AuthGetUuidByOption(const ConnectOption *option, char *buf, uint32_t bufLen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/authentication/src/auth_common.c b/core/authentication/src/auth_common.c new file mode 100644 index 000000000..a4a7c2ab6 --- /dev/null +++ b/core/authentication/src/auth_common.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_common.h" + +#include +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INTERVAL_VALUE 2 +#define OFFSET_BITS 24 +#define INT_MAX_VALUE 0xFFFFFEL +#define LOW_24_BITS 0xFFFFFFL +static uint64_t g_uniqueId = 0; + +int64_t GetSeq(AuthSideFlag flag) +{ + static uint64_t integer = 0; + if (integer == INT_MAX_VALUE) { + integer = 0; + } + integer += INTERVAL_VALUE; + uint64_t temp = integer; + temp = ((g_uniqueId << OFFSET_BITS) | (temp & LOW_24_BITS)); + int64_t seq = 0; + if (memcpy_s(&seq, sizeof(int64_t), &temp, sizeof(uint64_t)) != EOK) { + LOG_ERR("memcpy_s seq error"); + } + return seq; +} + +AuthSideFlag AuthGetSideByRemoteSeq(int64_t seq) +{ + /* even odd check */ + return (seq % 2) == 0 ? SERVER_SIDE_FLAG : CLIENT_SIDE_FLAG; +} + +void UniqueIdInit(void) +{ + struct timeval time = {0}; + gettimeofday(&time, NULL); + g_uniqueId = (uint64_t)(time.tv_usec); +} + +int32_t AuthGetDeviceKey(char *key, uint32_t size, uint32_t *len, const ConnectOption *option) +{ + if (key == NULL || len == NULL || option == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_ERR; + } + switch (option->type) { + case CONNECT_BR: { + if (strncpy_s(key, size, option->info.brOption.brMac, BT_MAC_LEN) != EOK) { + LOG_ERR("strncpy_s failed"); + return SOFTBUS_ERR; + } + *len = BT_MAC_LEN; + break; + } + case CONNECT_TCP: { + if (strncpy_s(key, size, option->info.ipOption.ip, IP_LEN) != EOK) { + LOG_ERR("strncpy_s failed"); + return SOFTBUS_ERR; + } + *len = IP_LEN; + break; + } + default: { + LOG_ERR("unknown type"); + return SOFTBUS_ERR; + } + } + return SOFTBUS_OK; +} + +int32_t AuthConvertConnInfo(ConnectOption *option, const ConnectionInfo *connInfo) +{ + if (option == NULL || connInfo == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_ERR; + } + option->type = connInfo->type; + switch (connInfo->type) { + case CONNECT_BR: { + if (strncpy_s(option->info.brOption.brMac, BT_MAC_LEN, connInfo->info.brInfo.brMac, BT_MAC_LEN) != EOK) { + LOG_ERR("strncpy_s failed"); + return SOFTBUS_ERR; + } + break; + } + case CONNECT_TCP: { + if (strncpy_s(option->info.ipOption.ip, IP_LEN, connInfo->info.ipInfo.ip, IP_LEN) != EOK) { + LOG_ERR("strncpy_s failed"); + return SOFTBUS_ERR; + } + option->info.ipOption.port = connInfo->info.ipInfo.port; + break; + } + default: { + LOG_ERR("unknown type"); + return SOFTBUS_ERR; + } + } + return SOFTBUS_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/core/authentication/src/auth_connection.c b/core/authentication/src/auth_connection.c new file mode 100644 index 000000000..ddd2f902a --- /dev/null +++ b/core/authentication/src/auth_connection.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_connection.h" + +#include +#include "auth_common.h" +#include "bus_center_manager.h" +#include "device_auth.h" +#include "softbus_conn_interface.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t __attribute__ ((weak)) AuthSocketSendData(AuthManager *auth, + const AuthDataHead *head, const uint8_t *data, uint32_t len) +{ + (void)auth; + (void)head; + (void)data; + (void)len; + return SOFTBUS_ERR; +} + +typedef struct { + AuthSideFlag side; + int64_t seq; + uint32_t connectionId; + int32_t connModule; +} PostDataInfo; + +static int32_t PostDataByConn(const PostDataInfo *info, char *buf, uint32_t postDataLen) +{ + int64_t seq = 0; + if (info->connModule == MODULE_DEVICE_AUTH || + info->connModule == MODULE_TRUST_ENGINE || info->connModule == MODULE_AUTH_SDK) { + seq = info->seq; + } else if (info->connModule == MODULE_AUTH_CONNECTION) { + seq = GetSeq(info->side); + } else { + LOG_ERR("invalid conn module."); + SoftBusFree(buf); + return SOFTBUS_INVALID_PARAM; + } + + ConnPostData postParam; + postParam.module = info->connModule; + postParam.seq = seq; + postParam.flag = info->side; + postParam.pid = 0; + postParam.buf = buf; + postParam.len = postDataLen + ConnGetHeadSize(); + + return ConnPostBytes(info->connectionId, &postParam); +} + +static int32_t SetBufData(char *buf, const AuthManager *auth, const AuthDataHead *head, + const uint8_t *data, uint32_t len) +{ + buf += ConnGetHeadSize(); + if (auth->option.type != CONNECT_TCP) { + *(int32_t *)buf = head->dataType; + buf += sizeof(int32_t); + *(int32_t *)buf = head->module; + buf += sizeof(int32_t); + *(int64_t *)buf = head->authId; + buf += sizeof(int64_t); + *(int32_t *)buf = head->flag; + buf += sizeof(int32_t); + *(int32_t *)buf = len; + buf += sizeof(int32_t); + } + if (memcpy_s(buf, len, data, len) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void HandlePeerSyncDeviceInfo(AuthManager *auth, const AuthDataHead *head) +{ + if (head->dataType == DATA_TYPE_SYNC) { + auth->status = SYNC_FINISH; + } + if (head->dataType == DATA_TYPE_SYNC && auth->encryptDevData != NULL) { + AuthHandlePeerSyncDeviceInfo(auth, auth->encryptDevData, auth->encryptLen); + SoftBusFree(auth->encryptDevData); + auth->encryptDevData = NULL; + } +} + +int32_t AuthPostData(const AuthDataHead *head, const uint8_t *data, uint32_t len) +{ + if (head == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId(head->authId, false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId(head->authId, true); + if (auth == NULL) { + LOG_ERR("no match auth found, AuthPostData failed"); + return SOFTBUS_ERR; + } + } + + if (auth->option.type == CONNECT_TCP) { + if (AuthSocketSendData(auth, head, data, len) != SOFTBUS_OK) { + LOG_ERR("AuthSocketSendData failed"); + return SOFTBUS_ERR; + } + } else { + PostDataInfo info; + uint32_t postDataLen; + info.side = auth->side; + info.connectionId = auth->connectionId; + postDataLen = sizeof(AuthDataInfo) + len; + info.connModule = MODULE_DEVICE_AUTH; + info.seq = GetSeq(auth->side); + char *connPostData = NULL; + char *buf = (char *)SoftBusMalloc(ConnGetHeadSize() + postDataLen); + if (buf == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return SOFTBUS_ERR; + } + connPostData = buf; + if (SetBufData(buf, auth, head, data, len) != SOFTBUS_OK) { + LOG_ERR("SetBufData failed"); + SoftBusFree(connPostData); + return SOFTBUS_ERR; + } + LOG_INFO("auth start post data, authId is %lld, connectionId is %u, moduleId is %d, seq is %lld", + auth->authId, info.connectionId, info.connModule, info.seq); + if (PostDataByConn(&info, connPostData, postDataLen) != SOFTBUS_OK) { + LOG_ERR("PostDataByConn failed"); + return SOFTBUS_ERR; + } + } + HandlePeerSyncDeviceInfo(auth, head); + return SOFTBUS_OK; +} + +static cJSON *AuthPackDeviceInfo(const AuthManager *auth) +{ + if (auth == NULL) { + return NULL; + } + cJSON *msg = cJSON_CreateObject(); + if (msg == NULL) { + return NULL; + } + char uuid[UUID_BUF_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_UUID, uuid, UUID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("auth get uuid failed!"); + cJSON_Delete(msg); + return NULL; + } + char udid[UDID_BUF_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("auth get device udid failed!"); + cJSON_Delete(msg); + return NULL; + } + if (auth->option.type == CONNECT_TCP && auth->side == CLIENT_SIDE_FLAG) { + if (AddStringToJsonObject(msg, CMD_TAG, CMD_GET_AUTH_INFO) == false) { + LOG_ERR("AddStringToJsonObject failed!"); + cJSON_Delete(msg); + return NULL; + } + } else { + if (AddStringToJsonObject(msg, CMD_TAG, CMD_RET_AUTH_INFO) == false) { + LOG_ERR("AddStringToJsonObject failed!"); + cJSON_Delete(msg); + return NULL; + } + } + if (!AddStringToJsonObject(msg, DATA_TAG, uuid) || + !AddStringToJsonObject(msg, TE_DEVICE_ID_TAG, udid) || + !AddNumberToJsonObject(msg, DATA_BUF_SIZE_TAG, PACKET_SIZE) || + !AddNumberToJsonObject(msg, SOFTBUS_VERSION_INFO, auth->softbusVersion)) { + LOG_ERR("AddStringToJsonObject Fail."); + cJSON_Delete(msg); + return NULL; + } + return msg; +} + +int32_t AuthSyncDeviceUuid(AuthManager *auth) +{ + if (auth == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + AuthDataHead head; + (void)memset_s(&head, sizeof(head), 0, sizeof(head)); + cJSON *obj = AuthPackDeviceInfo(auth); + if (obj == NULL) { + LOG_ERR("AuthPackDeviceInfo failed"); + return SOFTBUS_ERR; + } + char *msgStr = cJSON_PrintUnformatted(obj); + if (msgStr == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + cJSON_Delete(obj); + return SOFTBUS_ERR; + } + auth->status = IN_AUTH_PROGRESS; + if (auth->option.type == CONNECT_TCP) { + head.module = MODULE_TRUST_ENGINE; + } else { + head.dataType = DATA_TYPE_DEVICE_ID; + head.module = NONE; + } + head.authId = auth->authId; + head.flag = auth->side; + if (AuthPostData(&head, (uint8_t *)msgStr, strlen(msgStr) + 1) != SOFTBUS_OK) { + LOG_ERR("AuthPostData failed"); + cJSON_free(msgStr); + cJSON_Delete(obj); + return SOFTBUS_ERR; + } + cJSON_free(msgStr); + cJSON_Delete(obj); + return SOFTBUS_OK; +} + +static int32_t UnpackDeviceId(cJSON *msg, AuthManager *auth) +{ + if (!GetJsonObjectStringItem(msg, DATA_TAG, auth->peerUuid, UUID_BUF_LEN)) { + LOG_ERR("auth get peer uuid failed"); + return SOFTBUS_ERR; + } + if (!GetJsonObjectStringItem(msg, TE_DEVICE_ID_TAG, auth->peerUdid, UDID_BUF_LEN)) { + LOG_ERR("auth get peer udid failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t AuthUnpackDeviceInfo(AuthManager *auth, uint8_t *data) +{ + if (auth == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + cJSON *msg = cJSON_Parse((char*)data); + if (msg == NULL) { + LOG_ERR("json parse failed."); + return SOFTBUS_ERR; + } + char cmd[CMD_TAG_LEN] = {0}; + if (!GetJsonObjectStringItem(msg, CMD_TAG, cmd, CMD_TAG_LEN)) { + LOG_ERR("auth get cmd tag failed"); + cJSON_Delete(msg); + return SOFTBUS_ERR; + } + if (auth->option.type == CONNECT_TCP && auth->side == SERVER_SIDE_FLAG) { + if (strncmp(cmd, CMD_GET_AUTH_INFO, strlen(CMD_GET_AUTH_INFO)) != 0) { + LOG_ERR("auth cmd tag error"); + cJSON_Delete(msg); + return SOFTBUS_ERR; + } + } else { + if (strncmp(cmd, CMD_RET_AUTH_INFO, strlen(CMD_RET_AUTH_INFO)) != 0) { + LOG_ERR("auth cmd tag error"); + cJSON_Delete(msg); + return SOFTBUS_ERR; + } + } + if (UnpackDeviceId(msg, auth) != SOFTBUS_OK) { + LOG_ERR("UnpackDeviceId failed"); + cJSON_Delete(msg); + return SOFTBUS_ERR; + } + int32_t packetSize; + if (!GetJsonObjectNumberItem(msg, DATA_BUF_SIZE_TAG, &packetSize)) { + LOG_ERR("auth get packet size failed"); + cJSON_Delete(msg); + return SOFTBUS_ERR; + } + + int32_t peerVersion; + if (!GetJsonObjectNumberItem(msg, SOFTBUS_VERSION_INFO, &peerVersion)) { + auth->peerVersion = SOFT_BUS_OLD_V2; + } else { + auth->peerVersion = (SoftBusVersion)peerVersion; + } + cJSON_Delete(msg); + return SOFTBUS_OK; +} + +char *AuthGenDeviceLevelParam(const AuthManager *auth, bool isClient) +{ + if (auth == NULL) { + LOG_ERR("invalid parameter"); + return NULL; + } + cJSON *msg = cJSON_CreateObject(); + if (msg == NULL) { + return NULL; + } + if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, auth->peerUdid) || + !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) || + cJSON_AddBoolToObject(msg, FIELD_IS_CLIENT, isClient) == NULL || + !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, SESSION_KEY_LENGTH)) { + LOG_ERR("AddStringToJsonObject Fail."); + cJSON_Delete(msg); + return NULL; + } + char *data = cJSON_PrintUnformatted(msg); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + } + cJSON_Delete(msg); + return data; +} + +void AuthSendCloseAck(uint32_t connectionId) +{ + LOG_INFO("auth finished, send close ack"); + const char *closeData = "close ack"; + uint32_t closeDataLen = strlen(closeData) + 1; + + PostDataInfo info; + uint32_t postDataLen = sizeof(AuthDataInfo) + closeDataLen; + char *connPostData = NULL; + char *buf = (char *)SoftBusMalloc(ConnGetHeadSize() + postDataLen); + if (buf == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return; + } + connPostData = buf; + buf += ConnGetHeadSize(); + *(int32_t *)buf = DATA_TYPE_CLOSE_ACK; + buf += sizeof(int32_t); + *(int32_t *)buf = NONE; + buf += sizeof(int32_t); + *(int64_t *)buf = 0; + buf += sizeof(int64_t); + *(int32_t *)buf = 0; + buf += sizeof(int32_t); + *(int32_t *)buf = closeDataLen; + buf += sizeof(int32_t); + if (memcpy_s(buf, closeDataLen, closeData, closeDataLen) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(connPostData); + return; + } + info.side = (AuthSideFlag)0; + info.seq = 0; + info.connectionId = connectionId; + info.connModule = MODULE_DEVICE_AUTH; + if (PostDataByConn(&info, connPostData, postDataLen) != SOFTBUS_OK) { + LOG_ERR("PostDataByConn failed"); + return; + } +} + +void AuthTryCloseConnection(uint32_t connectionId) +{ + (void)ConnDisconnectDevice(connectionId); +} + +bool AuthOnTransmit(int64_t authId, const uint8_t *data, uint32_t len) +{ + AuthManager *auth = NULL; + AuthDataHead head; + (void)memset_s(&head, sizeof(head), 0, sizeof(head)); + auth = AuthGetManagerByAuthId(authId, false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId(authId, true); + if (auth == NULL) { + LOG_ERR("no match auth found"); + return false; + } + } + head.dataType = DATA_TYPE_AUTH; + head.module = AUTH_SDK; + head.authId = auth->authId; + head.flag = auth->side; + return AuthPostData(&head, data, len) == SOFTBUS_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/core/authentication/src/auth_manager.c b/core/authentication/src/auth_manager.c new file mode 100755 index 000000000..c1f7a87a3 --- /dev/null +++ b/core/authentication/src/auth_manager.c @@ -0,0 +1,1064 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_manager.h" + +#include +#include + +#include "auth_common.h" +#include "auth_connection.h" +#include "auth_sessionkey.h" +#include "auth_socket.h" +#include "message_handler.h" +#include "softbus_base_listener.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static ListNode g_authClientHead; +static ListNode g_authServerHead; +static VerifyCallback *g_verifyCallback = NULL; +static ConnectCallback g_connCallback = {0}; +static ConnectResult g_connResult = {0}; +static const GroupAuthManager *g_hichainGaInstance = NULL; +static const DeviceGroupManager *g_hichainGmInstance = NULL; +static DeviceAuthCallback g_hichainCallback = {0}; +static DataChangeListener g_hichainListener = {0}; +static SoftBusHandler g_authHandler = {0}; + +static pthread_mutex_t g_authLock; +static bool g_isAuthInit = false; +static int32_t HichainServiceInit(void); + +int32_t __attribute__ ((weak)) HandleIpVerifyDevice(AuthManager *auth, const ConnectOption *option) +{ + (void)auth; + (void)option; + return SOFTBUS_ERR; +} + +void __attribute__ ((weak)) AuthCloseTcpFd(int32_t fd) +{ + (void)fd; + return; +} + +int32_t __attribute__ ((weak)) OpenAuthServer(void) +{ + return SOFTBUS_ERR; +} + +static int32_t EventInLooper(int64_t authId) +{ + SoftBusMessage *msgDelay = (SoftBusMessage *)SoftBusMalloc(sizeof(SoftBusMessage)); + if (msgDelay == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return SOFTBUS_ERR; + } + (void)memset_s(msgDelay, sizeof(SoftBusMessage), 0, sizeof(SoftBusMessage)); + msgDelay->arg1 = (uint64_t)authId; + msgDelay->handler = &g_authHandler; + if (g_authHandler.looper == NULL || g_authHandler.looper->PostMessageDelay == NULL) { + LOG_ERR("softbus handler is null"); + return SOFTBUS_ERR; + } + g_authHandler.looper->PostMessageDelay(g_authHandler.looper, msgDelay, AUTH_DELAY_MS); + return SOFTBUS_OK; +} + +static int32_t CustomFunc(const SoftBusMessage *msg, void *authId) +{ + if (msg == NULL || authId == NULL) { + LOG_ERR("invalid parameter"); + return 0; + } + int64_t id = *(int64_t *)authId; + if ((int64_t)(msg->arg1) == id) { + SoftBusFree(authId); + return SOFTBUS_OK; + } + return SOFTBUS_ERR; +} + +static void EventRemove(int64_t authId) +{ + int64_t *id = (int64_t *)SoftBusMalloc(sizeof(int64_t)); + if (id == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return; + } + *id = authId; + g_authHandler.looper->RemoveMessageCustom(g_authHandler.looper, &g_authHandler, CustomFunc, (void *)id); +} + +AuthManager *AuthGetManagerByAuthId(int64_t authId, AuthSideFlag side) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return NULL; + } + ListNode *item = NULL; + ListNode *head = NULL; + if (side == CLIENT_SIDE_FLAG) { + head = &g_authClientHead; + } else { + head = &g_authServerHead; + } + LIST_FOR_EACH(item, head) { + AuthManager *auth = LIST_ENTRY(item, AuthManager, node); + if (auth->authId == authId) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("cannot find auth by authId, authId is %lld", authId); + return NULL; +} + +AuthManager *AuthGetManagerByFd(int32_t fd) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return NULL; + } + AuthManager *auth = NULL; + ListNode *item = NULL; + ListNode *head = NULL; + head = &g_authClientHead; + LIST_FOR_EACH(item, head) { + auth = LIST_ENTRY(item, AuthManager, node); + if (auth->fd == fd) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + head = &g_authServerHead; + LIST_FOR_EACH(item, head) { + auth = LIST_ENTRY(item, AuthManager, node); + if (auth->fd == fd) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("cannot find auth by fd, fd is %d", fd); + return NULL; +} + +static AuthManager *GetAuthByPeerUdid(const char *peerUdid) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return NULL; + } + AuthManager *auth = NULL; + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_authClientHead) { + auth = LIST_ENTRY(item, AuthManager, node); + if (strncmp(auth->peerUdid, peerUdid, strlen(peerUdid)) == 0) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + LIST_FOR_EACH(item, &g_authServerHead) { + auth = LIST_ENTRY(item, AuthManager, node); + if (strncmp(auth->peerUdid, peerUdid, strlen(peerUdid)) == 0) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("cannot find auth by peerUdid!"); + return NULL; +} + +static VerifyCallback *GetAuthCallback(uint32_t moduleId) +{ + if (moduleId >= MODULE_NUM) { + LOG_ERR("invalid parameter"); + return NULL; + } + if (g_verifyCallback == NULL) { + LOG_ERR("verify callback is null"); + return NULL; + } + return &g_verifyCallback[moduleId]; +} + +static VerifyCallback *GetDefaultAuthCallback(void) +{ + if (g_verifyCallback == NULL) { + LOG_ERR("verify callback is null"); + return NULL; + } + return &g_verifyCallback[LNN]; +} + +AuthManager *AuthGetManagerByRequestId(uint32_t requestId) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return NULL; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_authClientHead) { + AuthManager *auth = LIST_ENTRY(item, AuthManager, node); + if (auth->requestId == requestId) { + (void)pthread_mutex_unlock(&g_authLock); + return auth; + } + } + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("cannot find auth by requestId, requestId is %u", requestId); + return NULL; +} + +static bool IsDeviceAuthingNow(const ConnectOption *option) +{ + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_authClientHead) { + AuthManager *auth = LIST_ENTRY(item, AuthManager, node); + if (memcmp(&auth->option, option, sizeof(ConnectOption)) == 0 && + auth->status != AUTH_PASSED && auth->status != AUTH_FAIL) { + return true; + } + } + LIST_FOR_EACH(item, &g_authServerHead) { + AuthManager *auth = LIST_ENTRY(item, AuthManager, node); + if (memcmp(&auth->option, option, sizeof(ConnectOption)) == 0 && + auth->status != AUTH_PASSED && auth->status != AUTH_FAIL) { + return true; + } + } + return false; +} + +static bool IsNeedVerify(const ConnectOption *option) +{ + char deviceKey[MAX_DEVICE_KEY_LEN] = {0}; + uint32_t deviceKeyLen = 0; + if (AuthGetDeviceKey(deviceKey, MAX_DEVICE_KEY_LEN, &deviceKeyLen, option) != SOFTBUS_OK) { + LOG_ERR("auth get device key failed"); + return true; + } + return !AuthIsDeviceVerified(option->type, deviceKey, deviceKeyLen); +} + +static void DeleteAuth(AuthManager *auth) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + ListDelete(&auth->node); + if (auth->encryptDevData != NULL) { + SoftBusFree(auth->encryptDevData); + auth->encryptDevData = NULL; + } + LOG_INFO("delete auth manager, authId is %lld", auth->authId); + SoftBusFree(auth); + (void)pthread_mutex_unlock(&g_authLock); +} + +static void HandleAuthFail(AuthManager *auth) +{ + if (auth == NULL) { + return; + } + if (auth->status != AUTH_PASSED) { + auth->cb->onDeviceVerifyFail(auth->authId, &auth->option); + } + EventRemove(auth->authId); + DeleteAuth(auth); +} + +static int32_t InitNewAuthManager(AuthManager *auth, uint32_t moduleId, const ConnectOption *option) +{ + auth->cb = GetAuthCallback(moduleId); + if (auth->cb == NULL) { + return SOFTBUS_ERR; + } + auth->status = WAIT_CONNECTION_ESTABLISHED; + auth->side = CLIENT_SIDE_FLAG; + auth->authId = GetSeq(CLIENT_SIDE_FLAG); + auth->requestId = ConnGetNewRequestId(MODULE_DEVICE_AUTH); + auth->softbusVersion = SOFT_BUS_NEW_V1; + auth->option = *option; + auth->hichain = g_hichainGaInstance; + ListNodeInsert(&g_authClientHead, &auth->node); + return SOFTBUS_OK; +} + +static int32_t HandleVerifyDevice(AuthModuleId moduleId, const ConnectOption *option) +{ + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + AuthManager *auth = (AuthManager *)SoftBusMalloc(sizeof(AuthManager)); + if (auth == NULL) { + LOG_ERR("SoftBusMalloc failed"); + (void)pthread_mutex_unlock(&g_authLock); + return SOFTBUS_ERR; + } + (void)memset_s(auth, sizeof(AuthManager), 0, sizeof(AuthManager)); + if (InitNewAuthManager(auth, moduleId, option) != SOFTBUS_OK) { + LOG_ERR("auth InitNewAuthManager failed"); + (void)pthread_mutex_unlock(&g_authLock); + SoftBusFree(auth); + return SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&g_authLock); + + if (option->type == CONNECT_TCP) { + if (HandleIpVerifyDevice(auth, option) != SOFTBUS_OK) { + LOG_ERR("HandleIpVerifyDevice failed"); + DeleteAuth(auth); + return SOFTBUS_ERR; + } + } else if (option->type == CONNECT_BR) { + if (ConnConnectDevice(option, auth->requestId, &g_connResult) != SOFTBUS_OK) { + LOG_ERR("auth ConnConnectDevice failed"); + DeleteAuth(auth); + return SOFTBUS_ERR; + } + } else { + LOG_ERR("auth conn type %d is not support", option->type); + DeleteAuth(auth); + return SOFTBUS_ERR; + } + if (EventInLooper(auth->authId) != SOFTBUS_OK) { + LOG_ERR("auth EventInLooper failed"); + DeleteAuth(auth); + return SOFTBUS_ERR; + } + LOG_INFO("start authentication process, authId is %lld", auth->authId); + return SOFTBUS_OK; +} + +int32_t AuthVerifyDevice(AuthModuleId moduleId, const ConnectOption *option) +{ + if (option == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + if (IsNeedVerify(option) == false) { + (void)pthread_mutex_unlock(&g_authLock); + LOG_INFO("there is no need to verify!"); + return SOFTBUS_AUTH_VERIFIED; + } + if (IsDeviceAuthingNow(option) == true) { + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("authentication between two devices is in progress, please verify later"); + return SOFTBUS_AUTH_VERIFYING; + } + (void)pthread_mutex_unlock(&g_authLock); + if (g_hichainGaInstance == NULL || g_hichainGmInstance == NULL) { + LOG_ERR("need to call AuthVerifyInit!"); + return SOFTBUS_ERR; + } + if (HandleVerifyDevice(moduleId, option) != SOFTBUS_OK) { + LOG_ERR("auth HandleVerifyDevice failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +void AuthOnConnectSuccessful(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info) +{ + (void)info; + AuthManager *auth = NULL; + auth = AuthGetManagerByRequestId(requestId); + if (auth == NULL) { + return; + } + auth->connectionId = connectionId; + if (AuthSyncDeviceUuid(auth) != SOFTBUS_OK) { + HandleAuthFail(auth); + } +} + +void AuthOnConnectFailed(uint32_t requestId, int reason) +{ + LOG_ERR("auth create connection failed, fail reason is %d", reason); + AuthManager *auth = NULL; + auth = AuthGetManagerByRequestId(requestId); + if (auth == NULL) { + return; + } + HandleAuthFail(auth); +} + +void HandleReceiveAuthData(AuthManager *auth, int32_t module, uint8_t *data, uint32_t dataLen) +{ + if (auth == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return; + } + if (module == MODULE_AUTH_SDK) { + if (auth->hichain->processData(auth->authId, data, dataLen, &g_hichainCallback) != 0) { + LOG_ERR("Hichain process data failed"); + HandleAuthFail(auth); + } + } else { + LOG_ERR("unknown auth data module"); + } +} + +static void StartAuth(AuthManager *auth, char *groupId, bool isDeviceLevel, bool isClient) +{ + (void)groupId; + char *authParams = NULL; + if (isDeviceLevel) { + authParams = AuthGenDeviceLevelParam(auth, isClient); + } else { + LOG_ERR("not supported session level"); + return; + } + if (authParams == NULL) { + LOG_ERR("generate auth param failed"); + return; + } + if (auth->hichain->authDevice(auth->authId, authParams, &g_hichainCallback) != 0) { + LOG_ERR("authDevice failed"); + HandleAuthFail(auth); + return; + } + cJSON_free(authParams); +} + +static void VerifyDeviceDevLvl(AuthManager *auth) +{ + if (auth->side == CLIENT_SIDE_FLAG) { + StartAuth(auth, NULL, true, true); + } else { + StartAuth(auth, NULL, true, false); + } +} + +void HandleReceiveDeviceId(AuthManager *auth, uint8_t *data) +{ + if (auth == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return; + } + if (AuthUnpackDeviceInfo(auth, data) != SOFTBUS_OK) { + LOG_ERR("AuthUnpackDeviceInfo failed"); + HandleAuthFail(auth); + return; + } + if (auth->side == SERVER_SIDE_FLAG) { + if (AuthSyncDeviceUuid(auth) != SOFTBUS_OK) { + HandleAuthFail(auth); + } + return; + } + if (auth->status == AUTH_PASSED) { + LOG_INFO("auth pass, no need to call verify again"); + return; + } + VerifyDeviceDevLvl(auth); +} + +static void ReceiveCloseAck(uint32_t connectionId) +{ + LOG_INFO("auth receive close connection ack"); + AuthSendCloseAck(connectionId); + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_authClientHead) { + AuthManager *auth = LIST_ENTRY(item, AuthManager, node); + if (auth->connectionId == connectionId) { + EventRemove(auth->authId); + return; + } + } +} + +void AuthHandlePeerSyncDeviceInfo(AuthManager *auth, uint8_t *data, uint32_t len) +{ + if (auth == NULL || data == NULL || len == 0 || len > AUTH_MAX_DATA_LEN) { + LOG_ERR("invalid parameter"); + return; + } + if (AuthIsSeqInKeyList((int32_t)(auth->authId)) == false || + auth->status == IN_SYNC_PROGRESS) { + LOG_INFO("auth saved encrypted data first"); + if (auth->encryptDevData != NULL) { + LOG_WARN("encrypted data is not null"); + SoftBusFree(auth->encryptDevData); + auth->encryptDevData = NULL; + } + auth->encryptDevData = (uint8_t *)SoftBusMalloc(len); + if (auth->encryptDevData == NULL) { + LOG_ERR("SoftBusMalloc failed"); + HandleAuthFail(auth); + return; + } + (void)memset_s(auth->encryptDevData, len, 0, len); + if (memcpy_s(auth->encryptDevData, len, data, len) != EOK) { + LOG_ERR("memcpy_s failed"); + HandleAuthFail(auth); + return; + } + auth->encryptLen = len; + return; + } + auth->cb->onRecvSyncDeviceInfo(auth->authId, auth->side, auth->peerUuid, data, len); + auth->status = AUTH_PASSED; + if (auth->option.type == CONNECT_TCP) { + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_authClientHead) { + AuthManager *authList = LIST_ENTRY(item, AuthManager, node); + if (authList == auth) { + EventRemove(auth->authId); + return; + } + } + } +} + +static int32_t ServerAuthInit(AuthManager *auth, int64_t authId, uint64_t connectionId) +{ + auth->cb = GetDefaultAuthCallback(); + if (auth->cb == NULL) { + LOG_ERR("GetDefaultAuthCallback failed"); + return SOFTBUS_ERR; + } + if (AuthVerifyInit() != SOFTBUS_OK) { + LOG_ERR("AuthVerifyInit failed"); + return SOFTBUS_ERR; + } + + auth->side = SERVER_SIDE_FLAG; + auth->status = WAIT_CONNECTION_ESTABLISHED; + auth->authId = authId; + auth->connectionId = connectionId; + auth->softbusVersion = SOFT_BUS_NEW_V1; + if (g_hichainGaInstance == NULL || g_hichainGmInstance == NULL) { + LOG_ERR("need to AuthVerifyInit!"); + return SOFTBUS_ERR; + } + auth->hichain = g_hichainGaInstance; + ConnectionInfo connInfo; + if (memset_s(&connInfo, sizeof(ConnectOption), 0, sizeof(ConnectOption)) != EOK) { + LOG_ERR("memset_s connInfo fail!"); + } + if (ConnGetConnectionInfo(connectionId, &connInfo) != SOFTBUS_OK) { + LOG_ERR("auth ConnGetConnectionInfo failed"); + return SOFTBUS_ERR; + } + ConnectOption option; + (void)memset_s(&option, sizeof(ConnectOption), 0, sizeof(ConnectOption)); + if (AuthConvertConnInfo(&option, &connInfo) != SOFTBUS_OK) { + LOG_ERR("AuthConvertConnInfo failed"); + return SOFTBUS_ERR; + } + auth->option = option; + ListNodeInsert(&g_authServerHead, &auth->node); + return SOFTBUS_OK; +} + +static int32_t AnalysisData(char *data, int len, AuthDataInfo *info) +{ + if (len < (int32_t)sizeof(AuthDataInfo)) { + return SOFTBUS_ERR; + } + info->type = *(uint32_t *)data; + data += sizeof(uint32_t); + info->module = *(int32_t *)data; + data += sizeof(int32_t); + info->authId = *(int64_t *)data; + data += sizeof(int64_t); + info->flag = *(int32_t *)data; + data += sizeof(int32_t); + info->dataLen = *(uint32_t *)data; + return SOFTBUS_OK; +} + +static AuthManager *CreateServerAuth(uint32_t connectionId, AuthDataInfo *authDataInfo) +{ + AuthManager *auth = NULL; + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return NULL; + } + auth = (AuthManager *)SoftBusMalloc(sizeof(AuthManager)); + if (auth == NULL) { + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("SoftBusMalloc failed"); + return NULL; + } + (void)memset_s(auth, sizeof(AuthManager), 0, sizeof(AuthManager)); + if (ServerAuthInit(auth, authDataInfo->authId, connectionId) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("ServerAuthInit failed"); + SoftBusFree(auth); + return NULL; + } + if (EventInLooper(auth->authId) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_authLock); + LOG_ERR("auth EventInLooper failed"); + DeleteAuth(auth); + return NULL; + } + (void)pthread_mutex_unlock(&g_authLock); + LOG_INFO("auth as server side"); + return auth; +} + +static void HandleReceiveData(uint32_t connectionId, AuthDataInfo *authDataInfo, AuthSideFlag side, uint8_t *recvData) +{ + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId(authDataInfo->authId, side); + if (auth == NULL && authDataInfo->type != DATA_TYPE_CLOSE_ACK) { + if (authDataInfo->type == DATA_TYPE_DEVICE_ID && side == SERVER_SIDE_FLAG) { + auth = CreateServerAuth(connectionId, authDataInfo); + if (auth == NULL) { + LOG_ERR("CreateServerAuth failed"); + return; + } + } else { + LOG_ERR("cannot find auth"); + return; + } + } + LOG_INFO("auth data type is %u", authDataInfo->type); + switch (authDataInfo->type) { + case DATA_TYPE_DEVICE_ID: { + HandleReceiveDeviceId(auth, recvData); + break; + } + case DATA_TYPE_AUTH: { + HandleReceiveAuthData(auth, authDataInfo->module, recvData, authDataInfo->dataLen); + break; + } + case DATA_TYPE_SYNC: { + AuthHandlePeerSyncDeviceInfo(auth, recvData, authDataInfo->dataLen); + break; + } + case DATA_TYPE_CLOSE_ACK: { + ReceiveCloseAck(connectionId); + break; + } + default: { + LOG_ERR("unknown data type"); + break; + } + } +} + +void AuthOnDataReceived(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int len) +{ + if (data == NULL || moduleId != MODULE_DEVICE_AUTH) { + LOG_ERR("invalid parameter"); + return; + } + LOG_INFO("auth receive data, connectionId is %u, moduleId is %d, seq is %lld", connectionId, moduleId, seq); + AuthDataInfo authDataInfo = {0}; + uint8_t *recvData = NULL; + AuthSideFlag side; + side = AuthGetSideByRemoteSeq(seq); + if (AnalysisData(data, len, &authDataInfo) != SOFTBUS_OK) { + LOG_ERR("AnalysisData failed"); + return; + } + recvData = (uint8_t *)data + sizeof(AuthDataInfo); + HandleReceiveData(connectionId, &authDataInfo, side, recvData); +} + +static void AuthOnSessionKeyReturned(int64_t authId, const uint8_t *sessionKey, uint32_t sessionKeyLen) +{ + if (sessionKey == NULL) { + LOG_ERR("invalid parameter"); + return; + } + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId(authId, false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId(authId, true); + if (auth == NULL) { + LOG_ERR("no match auth found"); + return; + } + } + LOG_INFO("auth get session key succ, authId is %lld", authId); + NecessaryDevInfo devInfo = {0}; + if (AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &devInfo.deviceKeyLen, &auth->option) != SOFTBUS_OK) { + LOG_ERR("auth get device key failed"); + return; + } + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + devInfo.type = auth->option.type; + devInfo.side = auth->side; + devInfo.seq = (int32_t)((uint64_t)authId & LOW_32_BIT); + AuthSetLocalSessionKey(&devInfo, auth->peerUdid, sessionKey, sessionKeyLen); + auth->status = IN_SYNC_PROGRESS; + (void)pthread_mutex_unlock(&g_authLock); + auth->cb->onDeviceVerifyPass(authId, &auth->option, auth->peerVersion); +} + +static void AuthOnError(int64_t authId, int operationCode, int errorCode, const char *errorReturn) +{ + (void)operationCode; + if (errorReturn == NULL) { + LOG_ERR("invalid parameter"); + return; + } + LOG_ERR("HiChain auth failed, errorCode is %d, errorReturn is %s", errorCode, errorReturn); + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId(authId, false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId(authId, true); + if (auth == NULL) { + LOG_ERR("no match auth found, AuthPostData failed"); + return; + } + } + HandleAuthFail(auth); +} + +static char *AuthOnRequest(int64_t authReqId, int authForm, const char *reqParams) +{ + (void)authReqId; + (void)authForm; + (void)reqParams; + return NULL; +} + +static void AuthOnFinish(int64_t authId, int operationCode, const char *returnData) +{ + (void)authId; + (void)operationCode; + (void)returnData; +} + +static void AuthOnConnected(uint32_t connectionId, const ConnectionInfo *info) +{ + (void)connectionId; + (void)info; +} + +static void AuthOnDisConnect(uint32_t connectionId, const ConnectionInfo *info) +{ + (void)connectionId; + (void)info; +} + +static void AuthOnDeviceNotTrusted(const char *peerUdid) +{ + AuthManager *auth = NULL; + auth = GetAuthByPeerUdid(peerUdid); + if (auth == NULL) { + LOG_ERR("GetAuthByPeerUdid failed"); + return; + } + auth->cb->onDeviceNotTrusted(peerUdid); +} + +static int32_t HichainServiceInit(void) +{ + if (InitDeviceAuthService() != 0) { + LOG_ERR("auth InitDeviceAuthService failed"); + return SOFTBUS_ERR; + } + g_hichainGaInstance = GetGaInstance(); + if (g_hichainGaInstance == NULL) { + LOG_ERR("auth GetGaInstance failed"); + return SOFTBUS_ERR; + } + g_hichainGmInstance = GetGmInstance(); + if (g_hichainGmInstance == NULL) { + LOG_ERR("auth GetGmInstance failed"); + return SOFTBUS_ERR; + } + (void)memset_s(&g_hichainCallback, sizeof(DeviceAuthCallback), 0, sizeof(DeviceAuthCallback)); + g_hichainCallback.onTransmit = AuthOnTransmit; + g_hichainCallback.onSessionKeyReturned = AuthOnSessionKeyReturned; + g_hichainCallback.onFinish = AuthOnFinish; + g_hichainCallback.onError = AuthOnError; + g_hichainCallback.onRequest = AuthOnRequest; + + (void)memset_s(&g_hichainListener, sizeof(DataChangeListener), 0, sizeof(DataChangeListener)); + g_hichainListener.onDeviceNotTrusted = AuthOnDeviceNotTrusted; + if (g_hichainGmInstance->regDataChangeListener(AUTH_APPID, &g_hichainListener) != 0) { + LOG_ERR("auth RegDataChangeListener failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void AuthTimeout(SoftBusMessage *msg) +{ + if (msg == NULL) { + LOG_ERR("invalid parameter"); + return; + } + LOG_ERR("auth process timeout, authId = %lld", (int64_t)(msg->arg1)); + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId((int64_t)(msg->arg1), false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId((int64_t)(msg->arg1), true); + if (auth == NULL) { + LOG_ERR("no match auth found"); + return; + } + } + HandleAuthFail(auth); +} + +int32_t AuthVerifyInit(void) +{ + if (HichainServiceInit() != SOFTBUS_OK) { + LOG_ERR("HichainServiceInit failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t AuthVerifyDeinit(void) +{ + DestroyDeviceAuthService(); + return SOFTBUS_OK; +} + +static int32_t AuthCallbackInit(uint32_t moduleNum) +{ + if (g_verifyCallback != NULL) { + SoftBusFree(g_verifyCallback); + g_verifyCallback = NULL; + } + g_verifyCallback = (VerifyCallback *)SoftBusMalloc(sizeof(VerifyCallback) * moduleNum); + if (g_verifyCallback == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return SOFTBUS_ERR; + } + (void)memset_s(g_verifyCallback, sizeof(VerifyCallback) * moduleNum, 0, sizeof(VerifyCallback) * moduleNum); + return SOFTBUS_OK; +} + +int32_t AuthRegCallback(AuthModuleId moduleId, VerifyCallback *cb) +{ + if (cb == NULL || cb->onDeviceVerifyPass == NULL || cb->onDeviceVerifyFail == NULL || + cb->onRecvSyncDeviceInfo == NULL || cb->onDeviceNotTrusted == NULL || moduleId >= MODULE_NUM) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + if (g_verifyCallback == NULL) { + int32_t ret = AuthCallbackInit(MODULE_NUM); + if (ret != SOFTBUS_OK) { + LOG_ERR("AuthCallbackInit failed"); + return ret; + } + } + g_verifyCallback[moduleId].onDeviceVerifyPass = cb->onDeviceVerifyPass; + g_verifyCallback[moduleId].onDeviceVerifyFail = cb->onDeviceVerifyFail; + g_verifyCallback[moduleId].onRecvSyncDeviceInfo = cb->onRecvSyncDeviceInfo; + g_verifyCallback[moduleId].onDeviceNotTrusted = cb->onDeviceNotTrusted; + return SOFTBUS_OK; +} + +static int32_t RegisterConnCallback(ConnectCallback *connCb, ConnectResult *connResult) +{ + connCb->OnConnected = AuthOnConnected; + connCb->OnDisconnected = AuthOnDisConnect; + connCb->OnDataReceived = AuthOnDataReceived; + if (ConnSetConnectCallback(MODULE_DEVICE_AUTH, connCb) != SOFTBUS_OK) { + LOG_ERR("auth ConnSetConnectCallback failed"); + return SOFTBUS_ERR; + } + connResult->OnConnectSuccessed = AuthOnConnectSuccessful; + connResult->OnConnectFailed = AuthOnConnectFailed; + return SOFTBUS_OK; +} + +static void AuthListInit(void) +{ + ListInit(&g_authClientHead); + ListInit(&g_authServerHead); + AuthSessionKeyListInit(); +} + +static void AuthLooperInit(void) +{ + g_authHandler.name = "auth_handler"; + g_authHandler.HandleMessage = AuthTimeout; + g_authHandler.looper = GetLooper(LOOP_TYPE_DEFAULT); +} + +int32_t AuthHandleLeaveLNN(int64_t authId) +{ + AuthManager *auth = NULL; + auth = AuthGetManagerByAuthId(authId, false); + if (auth == NULL) { + auth = AuthGetManagerByAuthId(authId, true); + if (auth == NULL) { + LOG_ERR("no match auth found, AuthHandleLeaveLNN failed"); + return SOFTBUS_ERR; + } + } + LOG_INFO("auth handle leave LNN, authId is %lld", authId); + char deviceKey[MAX_DEVICE_KEY_LEN] = {0}; + uint32_t deviceKeyLen = 0; + if (AuthGetDeviceKey(deviceKey, MAX_DEVICE_KEY_LEN, &deviceKeyLen, &auth->option) != SOFTBUS_OK) { + LOG_ERR("get device key failed"); + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&g_authLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + AuthClearSessionKeyByDeviceInfo(auth->option.type, deviceKey, deviceKeyLen); + (void)pthread_mutex_unlock(&g_authLock); + if (auth->option.type == CONNECT_TCP) { + AuthCloseTcpFd(auth->fd); + } + DeleteAuth(auth); + return SOFTBUS_OK; +} + +int32_t AuthGetUuidByOption(const ConnectOption *option, char *buf, uint32_t bufLen) +{ + AuthManager *auth = NULL; + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_authClientHead) { + auth = LIST_ENTRY(item, AuthManager, node); + if ((option->type == CONNECT_TCP && strncmp(auth->option.info.ipOption.ip, option->info.ipOption.ip, + strlen(auth->option.info.ipOption.ip)) == 0) || (option->type == CONNECT_BR && + strncmp(auth->option.info.brOption.brMac, option->info.brOption.brMac, BT_MAC_LEN) == 0)) { + if (memcpy_s(buf, bufLen, auth->peerUuid, strlen(auth->peerUuid)) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; + } + } + LIST_FOR_EACH_SAFE(item, tmp, &g_authServerHead) { + auth = LIST_ENTRY(item, AuthManager, node); + if ((option->type == CONNECT_TCP && strncmp(auth->option.info.ipOption.ip, option->info.ipOption.ip, + strlen(auth->option.info.ipOption.ip)) == 0) || (option->type == CONNECT_BR && + strncmp(auth->option.info.brOption.brMac, option->info.brOption.brMac, BT_MAC_LEN) == 0)) { + if (memcpy_s(buf, bufLen, auth->peerUuid, strlen(auth->peerUuid)) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; + } + } + LOG_ERR("auth get uuid by option failed"); + return SOFTBUS_ERR; +} + +static void ClearAuthManager(void) +{ + AuthManager *auth = NULL; + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_authClientHead) { + auth = LIST_ENTRY(item, AuthManager, node); + ListDelete(&auth->node); + if (auth->encryptDevData != NULL) { + SoftBusFree(auth->encryptDevData); + auth->encryptDevData = NULL; + } + if (auth->option.type == CONNECT_TCP) { + AuthCloseTcpFd(auth->fd); + } + EventRemove(auth->authId); + SoftBusFree(auth); + auth = NULL; + } + LIST_FOR_EACH_SAFE(item, tmp, &g_authServerHead) { + auth = LIST_ENTRY(item, AuthManager, node); + ListDelete(&auth->node); + if (auth->encryptDevData != NULL) { + SoftBusFree(auth->encryptDevData); + auth->encryptDevData = NULL; + } + if (auth->option.type == CONNECT_TCP) { + AuthCloseTcpFd(auth->fd); + } + EventRemove(auth->authId); + SoftBusFree(auth); + auth = NULL; + } + ListInit(&g_authClientHead); + ListInit(&g_authServerHead); + LOG_INFO("clear auth manager finish"); +} + +int32_t AuthDeinit(void) +{ + if (g_isAuthInit == false) { + return SOFTBUS_OK; + } + if (g_verifyCallback != NULL) { + SoftBusFree(g_verifyCallback); + g_verifyCallback = NULL; + } + ClearAuthManager(); + AuthClearAllSessionKey(); + pthread_mutex_destroy(&g_authLock); + g_isAuthInit = false; + LOG_INFO("auth deinit succ!"); + return SOFTBUS_OK; +} + +int32_t AuthInit(void) +{ + if (g_isAuthInit == true) { + return SOFTBUS_OK; + } + if (AuthCallbackInit(MODULE_NUM) != SOFTBUS_OK) { + LOG_ERR("AuthCallbackInit failed"); + return SOFTBUS_ERR; + } + AuthListInit(); + if (RegisterConnCallback(&g_connCallback, &g_connResult) != SOFTBUS_OK) { + LOG_ERR("RegisterConnCallback failed"); + (void)AuthDeinit(); + return SOFTBUS_ERR; + } + AuthLooperInit(); + UniqueIdInit(); + if (pthread_mutex_init(&g_authLock, NULL) != 0) { + LOG_ERR("mutex init fail!"); + (void)AuthDeinit(); + return SOFTBUS_ERR; + } + g_isAuthInit = true; + LOG_INFO("auth init succ!"); + return SOFTBUS_OK; +} + +#ifdef __cplusplus +} +#endif diff --git a/core/authentication/src/auth_sessionkey.c b/core/authentication/src/auth_sessionkey.c new file mode 100644 index 000000000..2d93c610f --- /dev/null +++ b/core/authentication/src/auth_sessionkey.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_sessionkey.h" + +#include + +#include "auth_common.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static ListNode g_sessionKeyListHead; + +void AuthSessionKeyListInit(void) +{ + ListInit(&g_sessionKeyListHead); +} + +void AuthSetLocalSessionKey(const NecessaryDevInfo *devInfo, const char *peerUdid, + const uint8_t *sessionKey, uint32_t sessionKeyLen) +{ + uint32_t listSize = 0; + if (devInfo == NULL || peerUdid == NULL || sessionKey == NULL) { + LOG_ERR("invalid parameter"); + return; + } + SessionKeyList *sessionKeyList = NULL; + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_sessionKeyListHead) { + listSize++; + } + if (listSize == MAX_KEY_LIST_SIZE) { + item = GET_LIST_TAIL(&g_sessionKeyListHead); + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + (void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH); + ListDelete(&sessionKeyList->node); + SoftBusFree(sessionKeyList); + sessionKeyList = NULL; + } + sessionKeyList = (SessionKeyList *)SoftBusMalloc(sizeof(SessionKeyList)); + if (sessionKeyList == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return; + } + (void)memset_s(sessionKeyList, sizeof(SessionKeyList), 0, sizeof(SessionKeyList)); + sessionKeyList->type = devInfo->type; + sessionKeyList->side = devInfo->side; + sessionKeyList->seq = devInfo->seq; + if (memcpy_s(sessionKeyList->peerUdid, UDID_BUF_LEN, peerUdid, strlen(peerUdid)) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(sessionKeyList); + return; + } + if (memcpy_s(sessionKeyList->deviceKey, MAX_DEVICE_KEY_LEN, devInfo->deviceKey, devInfo->deviceKeyLen) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(sessionKeyList); + return; + } + sessionKeyList->deviceKeyLen = devInfo->deviceKeyLen; + if (memcpy_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, sessionKey, sessionKeyLen) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(sessionKeyList); + return; + } + sessionKeyList->sessionKeyLen = sessionKeyLen; + ListNodeInsert(&g_sessionKeyListHead, &sessionKeyList->node); +} + +bool AuthIsDeviceVerified(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen) +{ + if (deviceKey == NULL) { + LOG_ERR("invalid parameter"); + return false; + } + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + LOG_WARN("no session key in memory, need to verify device"); + return false; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + if (sessionKeyList->type == type && strncmp(sessionKeyList->deviceKey, deviceKey, deviceKeyLen) == 0) { + return true; + } + } + return false; +} + +bool AuthIsSeqInKeyList(int32_t seq) +{ + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + LOG_WARN("no session key in memory"); + return false; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + if (sessionKeyList->seq == seq) { + return true; + } + } + return false; +} + +static SessionKeyList *AuthGetLastSessionKey(const NecessaryDevInfo *devInfo) +{ + if (devInfo == NULL) { + LOG_ERR("invalid parameter"); + return NULL; + } + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + LOG_ERR("no session key in memory"); + return NULL; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + if (sessionKeyList->type == devInfo->type && + strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) { + LOG_INFO("get last session key succ"); + return sessionKeyList; + } + } + LOG_ERR("auth get last session key failed"); + return NULL; +} + +static SessionKeyList *GetSessionKeyByDevinfo(const NecessaryDevInfo *devInfo) +{ + if (devInfo == NULL) { + LOG_ERR("invalid parameter"); + return NULL; + } + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + LOG_ERR("no session key in memory"); + return NULL; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + if (sessionKeyList->type == devInfo->type && + sessionKeyList->side == devInfo->side && + sessionKeyList->seq == devInfo->seq && + strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) { + LOG_INFO("get session key seccessfully."); + return sessionKeyList; + } + } + LOG_ERR("auth cannot find session key by seq"); + return NULL; +} + +int32_t AuthEncrypt(const ConnectOption *option, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf) +{ + if (option == NULL || side == NULL || data == NULL || + outBuf == NULL || outBuf->bufLen < (len + ENCRYPT_OVER_HEAD_LEN)) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + int32_t ret; + SessionKeyList *sessionKeyList = NULL; + NecessaryDevInfo devInfo = {0}; + uint32_t outLen; + + devInfo.type = option->type; + ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option); + if (ret != SOFTBUS_OK) { + LOG_ERR("AuthGetDeviceKey failed"); + return SOFTBUS_ENCRYPT_ERR; + } + sessionKeyList = AuthGetLastSessionKey(&devInfo); + if (sessionKeyList == NULL) { + LOG_ERR("AuthGetLastSessionKey failed"); + return SOFTBUS_ENCRYPT_ERR; + } + *side = sessionKeyList->side; + // add seq first + if (memcpy_s(outBuf->buf, sizeof(int32_t), &sessionKeyList->seq, sizeof(int32_t)) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ENCRYPT_ERR; + } + AesGcmCipherKey cipherKey = {0}; + cipherKey.keyLen = SESSION_KEY_LENGTH; + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ENCRYPT_ERR; + } + if (SoftBusEncryptDataWithSeq(&cipherKey, data, len, outBuf->buf + MESSAGE_INDEX_LEN, + &outLen, sessionKeyList->seq) != SOFTBUS_OK) { + LOG_ERR("SoftBusEncryptDataWithSeq failed"); + return SOFTBUS_ENCRYPT_ERR; + } + outBuf->outLen = outLen + MESSAGE_INDEX_LEN; + return SOFTBUS_OK; +} + +int32_t AuthDecrypt(const ConnectOption *option, AuthSideFlag side, uint8_t *data, uint32_t len, OutBuf *outBuf) +{ + if (option == NULL || data == NULL || outBuf == NULL || outBuf->bufLen < (len - ENCRYPT_OVER_HEAD_LEN)) { + LOG_ERR("invalid parameter"); + return SOFTBUS_INVALID_PARAM; + } + SessionKeyList *sessionKeyList = NULL; + NecessaryDevInfo devInfo = {0}; + devInfo.type = option->type; + + int32_t ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option); + if (ret != SOFTBUS_OK) { + LOG_ERR("AuthGetDeviceKey failed"); + return SOFTBUS_ENCRYPT_ERR; + } + int32_t seq; + if (memcpy_s(&seq, sizeof(int32_t), data, sizeof(int32_t)) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ENCRYPT_ERR; + } + devInfo.seq = seq; + data += sizeof(int32_t); + len -= sizeof(int32_t); + devInfo.side = side; + sessionKeyList = GetSessionKeyByDevinfo(&devInfo); + if (sessionKeyList == NULL) { + LOG_ERR("GetSessionKeyByDevinfo failed"); + return SOFTBUS_ENCRYPT_ERR; + } + + AesGcmCipherKey cipherKey = {0}; + cipherKey.keyLen = SESSION_KEY_LENGTH; + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ENCRYPT_ERR; + } + if (SoftBusDecryptDataWithSeq(&cipherKey, data, len, outBuf->buf, + &outBuf->outLen, sessionKeyList->seq) != SOFTBUS_OK) { + LOG_ERR("SoftBusDecryptDataWithSeq failed"); + return SOFTBUS_ENCRYPT_ERR; + } + return SOFTBUS_OK; +} + +uint32_t AuthGetEncryptHeadLen(void) +{ + return ENCRYPT_OVER_HEAD_LEN; +} + +void AuthClearSessionKeyByDeviceInfo(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen) +{ + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + return; + } + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + if (sessionKeyList->type == type && strncmp(sessionKeyList->deviceKey, deviceKey, deviceKeyLen) == 0) { + (void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH); + ListDelete(&sessionKeyList->node); + SoftBusFree(sessionKeyList); + sessionKeyList = NULL; + } + } +} + +void AuthClearAllSessionKey(void) +{ + SessionKeyList *sessionKeyList = NULL; + if (IsListEmpty(&g_sessionKeyListHead) == true) { + return; + } + ListNode *item = NULL; + ListNode *tmp = NULL; + LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) { + sessionKeyList = LIST_ENTRY(item, SessionKeyList, node); + (void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH); + ListDelete(&sessionKeyList->node); + SoftBusFree(sessionKeyList); + sessionKeyList = NULL; + } + ListInit(&g_sessionKeyListHead); +} + +#ifdef __cplusplus +} +#endif diff --git a/core/authentication/src/auth_socket.c b/core/authentication/src/auth_socket.c new file mode 100644 index 000000000..f1066d7db --- /dev/null +++ b/core/authentication/src/auth_socket.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "auth_socket.h" + +#include + +#include "auth_connection.h" +#include "bus_center_manager.h" +#include "softbus_base_listener.h" +#include "softbus_conn_manager.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_tcp_socket.h" + +#define AUTH_DEFAULT_PORT (-1) + +#ifdef __cplusplus +extern "C" { +#endif + +static SoftbusBaseListener g_ethListener = {0}; + +int32_t HandleIpVerifyDevice(AuthManager *auth, const ConnectOption *option) +{ + if (auth == NULL || option == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_ERR; + } + char localIp[IP_MAX_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, IP_MAX_LEN) != SOFTBUS_OK) { + LOG_ERR("auth get local ip failed"); + return SOFTBUS_ERR; + } + int fd = OpenTcpClientSocket(option->info.ipOption.ip, localIp, option->info.ipOption.port); + if (fd < 0) { + LOG_ERR("auth OpenTcpClientSocket failed"); + return SOFTBUS_ERR; + } + auth->fd = fd; + if (AddTrigger(AUTH, fd, RW_TRIGGER) != SOFTBUS_OK) { + LOG_ERR("auth AddTrigger failed"); + return SOFTBUS_ERR; + } + if (AuthSyncDeviceUuid(auth) != SOFTBUS_OK) { + LOG_ERR("AuthSyncDeviceUuid failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void AuthIpOnDataReceived(int32_t fd, const ConnPktHead *head, char *data, int len) +{ + if (head == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return; + } + AuthManager *auth = NULL; + auth = AuthGetManagerByFd(fd); + if (auth == NULL || auth->authId != head->seq) { + LOG_ERR("ip get auth failed"); + return; + } + LOG_INFO("auth ip data module is %d", head->module); + switch (head->module) { + case MODULE_TRUST_ENGINE: { + HandleReceiveDeviceId(auth, (uint8_t *)data); + break; + } + case MODULE_AUTH_SDK: { + HandleReceiveAuthData(auth, head->module, (uint8_t *)data, head->len); + break; + } + case MODULE_AUTH_CONNECTION: { + AuthHandlePeerSyncDeviceInfo(auth, (uint8_t *)data, head->len); + break; + } + default: { + LOG_ERR("unknown data type"); + break; + } + } +} + +static int32_t AuthOnDataEvent(int32_t events, int32_t fd) +{ + if (events != SOFTBUS_SOCKET_IN) { + return SOFTBUS_ERR; + } + ConnPktHead *head = NULL; + char *ipData = NULL; + uint32_t headSize = sizeof(ConnPktHead); + + char *data = (char *)SoftBusMalloc(AUTH_MAX_DATA_LEN); + if (data == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return SOFTBUS_ERR; + } + ssize_t len = RecvTcpData(fd, data, AUTH_MAX_DATA_LEN, 0); + if (len < (int32_t)headSize) { + if (len == -1) { + LOG_ERR("RecvTcpData failed, DelTrigger"); + (void)DelTrigger(AUTH, fd, RW_TRIGGER); + } + LOG_ERR("auth recv data len not correct, len %d", len); + SoftBusFree(data); + return SOFTBUS_ERR; + } + LOG_INFO("AuthOnDataEvent len is %d", len); + head = (ConnPktHead *)data; + LOG_INFO("auth recv eth data, head.len is %d, module = %d, flag = %d, seq = %lld", + head->len, head->module, head->flag, head->seq); + ipData = data + headSize; + AuthIpOnDataReceived(fd, head, ipData, head->len); + SoftBusFree(data); + return SOFTBUS_OK; +} + +static int32_t AuthOnConnectEvent(int32_t events, int32_t cfd, const char *ip) +{ + (void)events; + (void)ip; + (void)cfd; + LOG_INFO("in auth AuthOnConnectEvent"); + return SOFTBUS_OK; +} + +int32_t AuthSocketSendData(AuthManager *auth, const AuthDataHead *head, const uint8_t *data, uint32_t len) +{ + if (auth == NULL || head == NULL || data == NULL) { + LOG_ERR("invalid parameter"); + return SOFTBUS_ERR; + } + ConnPktHead ethHead; + uint32_t postDataLen; + char *connPostData = NULL; + ethHead.magic = MAGIC_NUMBER; + ethHead.module = head->module; + ethHead.seq = auth->authId; + ethHead.flag = auth->side; + ethHead.len = len; + postDataLen = sizeof(ConnPktHead) + len; + char *buf = (char *)SoftBusMalloc(postDataLen); + if (buf == NULL) { + LOG_ERR("SoftBusMalloc failed"); + return SOFTBUS_ERR; + } + connPostData = buf; + if (memcpy_s(buf, sizeof(ConnPktHead), ðHead, sizeof(ConnPktHead)) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(connPostData); + return SOFTBUS_ERR; + } + buf += sizeof(ConnPktHead); + if (memcpy_s(buf, len, data, len) != EOK) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(connPostData); + return SOFTBUS_ERR; + } + LOG_INFO("auth start post eth data, authId is %lld, moduleId is %d, len is %u", + auth->authId, head->module, len); + ssize_t byte = SendTcpData(auth->fd, connPostData, postDataLen, 0); + if (byte != (ssize_t)postDataLen) { + LOG_ERR("SendTcpData failed"); + SoftBusFree(connPostData); + return SOFTBUS_ERR; + } + SoftBusFree(connPostData); + return SOFTBUS_OK; +} + +int32_t OpenAuthServer(void) +{ + int32_t localPort; + g_ethListener.onConnectEvent = AuthOnConnectEvent; + g_ethListener.onDataEvent = AuthOnDataEvent; + if (SetSoftbusBaseListener(AUTH, &g_ethListener) != SOFTBUS_OK) { + LOG_ERR("auth SetSoftbusBaseListener failed"); + return AUTH_ERROR_CODE; + } + char localIp[IP_MAX_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, IP_MAX_LEN) != SOFTBUS_OK) { + LOG_ERR("auth LnnGetLocalStrInfo failed"); + return AUTH_ERROR_CODE; + } + localPort = StartBaseListener(AUTH, localIp, 0, SERVER_MODE); + if (localPort <= 0) { + LOG_ERR("auth StartBaseListener failed!"); + return AUTH_ERROR_CODE; + } + return localPort; +} + +void AuthCloseTcpFd(int32_t fd) +{ + (void)DelTrigger(AUTH, fd, RW_TRIGGER); + CloseTcpFd(fd); +} + +void CloseAuthServer(void) +{ + LOG_INFO("close auth listener"); + if (StopBaseListener(AUTH) != SOFTBUS_OK) { + LOG_ERR("auth StopBaseListener failed"); + } + DestroyBaseListener(AUTH); +} + +#ifdef __cplusplus +} +#endif diff --git a/core/bus_center/BUILD.gn b/core/bus_center/BUILD.gn new file mode 100755 index 000000000..b05f554e8 --- /dev/null +++ b/core/bus_center/BUILD.gn @@ -0,0 +1,132 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_bus_center") { + sources = [ + "ipc/mini_system/lnn_bus_center_ipc.c", + "lnn/lane_hub/lane_manager/src/lnn_lane_info.c", + "lnn/lane_hub/lane_manager/src/lnn_lane_manager.c", + "lnn/lane_hub/lane_manager/src/lnn_smart_communication.c", + "lnn/net_builder/src/lnn_net_builder.c", + "lnn/net_builder/src/lnn_network_id.c", + "lnn/net_builder/src/lnn_state_machine.c", + "lnn/net_ledger/common/src/lnn_device_info.c", + "lnn/net_ledger/common/src/lnn_map.c", + "lnn/net_ledger/common/src/lnn_net_capability.c", + "lnn/net_ledger/common/src/lnn_node_info.c", + "lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c", + "lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c", + "lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c", + "lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c", + "service/src/bus_center_event.c", + "service/src/bus_center_manager.c", + "utils/src/lnn_connection_addr_utils.c", + ] + + include_dirs = [ + "interface", + "ipc/include", + "lnn/lane_hub/lane_manager/include", + "lnn/net_builder/include", + "lnn/net_ledger/common/include", + "lnn/net_ledger/distributed_ledger/include", + "lnn/net_ledger/local_ledger/include", + "lnn/net_ledger/sync_ledger/include", + "service/include", + "utils/include", + "$dsoftbus_root_path/core/adapter/bus_center/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/interfaces/kits/transport", + "//third_party/cJSON", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + cflags = [ + "-Wall", + "-Werror", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + } +} else { + shared_library("softbus_bus_center") { + sources = [ + "ipc/mini_system/lnn_bus_center_ipc.c", + "lnn/lane_hub/lane_manager/src/lnn_lane_info.c", + "lnn/lane_hub/lane_manager/src/lnn_lane_manager.c", + "lnn/lane_hub/lane_manager/src/lnn_smart_communication.c", + "lnn/net_builder/src/lnn_net_builder.c", + "lnn/net_builder/src/lnn_network_id.c", + "lnn/net_builder/src/lnn_state_machine.c", + "lnn/net_ledger/common/src/lnn_device_info.c", + "lnn/net_ledger/common/src/lnn_map.c", + "lnn/net_ledger/common/src/lnn_net_capability.c", + "lnn/net_ledger/common/src/lnn_node_info.c", + "lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c", + "lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c", + "lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c", + "lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c", + "service/src/bus_center_event.c", + "service/src/bus_center_manager.c", + "utils/src/lnn_connection_addr_utils.c", + ] + + include_dirs = [ + "interface", + "ipc/include", + "lnn/lane_hub/lane_manager/include", + "lnn/net_builder/include", + "lnn/net_ledger/common/include", + "lnn/net_ledger/distributed_ledger/include", + "lnn/net_ledger/local_ledger/include", + "lnn/net_ledger/sync_ledger/include", + "service/include", + "utils/include", + "$dsoftbus_root_path/core/adapter/bus_center/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/interfaces/kits/transport", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + ] + + cflags = [ + "-Wall", + "-fPIC", + ] + } +} diff --git a/core/bus_center/interface/bus_center_info_key.h b/core/bus_center/interface/bus_center_info_key.h new file mode 100644 index 000000000..7cfec67da --- /dev/null +++ b/core/bus_center/interface/bus_center_info_key.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUS_CENTER_INFO_KEY_H +#define BUS_CENTER_INFO_KEY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_TYPE_BUF_LEN 17 +#define NET_IF_NAME_LEN 20 +#define IP_MAX_LEN 46 +#define ID_MAX_LEN 72 +#define VERSION_MAX_LEN 16 +#define MAC_LEN 18 + +typedef enum { + STRING_KEY_BEGIN = 0, + STRING_KEY_HICE_VERSION = STRING_KEY_BEGIN, + STRING_KEY_DEV_UDID, + STRING_KEY_NETWORKID, + STRING_KEY_UUID, + STRING_KEY_DEV_TYPE, + STRING_KEY_DEV_NAME, + STRING_KEY_BT_MAC, + STRING_KEY_WLAN_IP, + STRING_KEY_NET_IF_NAME, + STRING_KEY_END, + NUM_KEY_BEGIN = 100, + NUM_KEY_SESSION_PORT = NUM_KEY_BEGIN, + NUM_KEY_AUTH_PORT, + NUM_KEY_PROXY_PORT, + NUM_KEY_NET_CAP, + NUM_KEY_DEV_TYPE_ID, + NUM_KEY_END, +} InfoKey; + +#ifdef __cplusplus +} +#endif +#endif // BUS_CENTER_INFO_KEY_H \ No newline at end of file diff --git a/core/bus_center/interface/bus_center_manager.h b/core/bus_center/interface/bus_center_manager.h new file mode 100644 index 000000000..5471f1dce --- /dev/null +++ b/core/bus_center/interface/bus_center_manager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUS_CENTER_MANAGER_H +#define BUS_CENTER_MANAGER_H + +#include + +#include "bus_center_info_key.h" +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LnnGetRemoteStrInfo(const char *netWorkId, InfoKey key, char *info, uint32_t len); +int32_t LnnGetRemoteNumInfo(const char *netWorkId, InfoKey key, int32_t *info); +int32_t LnnSetLocalStrInfo(InfoKey key, const char *info); +int32_t LnnSetLocalNumInfo(InfoKey key, int32_t info); +int32_t LnnGetLocalStrInfo(InfoKey key, char *info, uint32_t len); +int32_t LnnGetLocalNumInfo(InfoKey key, int32_t *info); + +int32_t LnnServerJoin(ConnectionAddr *addr); +int32_t LnnServerLeave(const char *networkId); + +int32_t LnnGetAllOnlineNodeInfo(NodeBasicInfo **info, int32_t *infoNum); +int32_t LnnGetLocalDeviceInfo(NodeBasicInfo *info); +int32_t LnnGetNodeKeyInfo(const char *networkId, int key, uint8_t *info, int32_t infoLen); + +int32_t LnnGetNetworkIdByUuid(const char *uuid, char *buf, uint32_t len); +#ifdef __cplusplus +} +#endif +#endif // BUS_CENTER_MANAGER_H \ No newline at end of file diff --git a/core/bus_center/ipc/include/lnn_bus_center_ipc.h b/core/bus_center/ipc/include/lnn_bus_center_ipc.h new file mode 100755 index 000000000..6107815ec --- /dev/null +++ b/core/bus_center/ipc/include/lnn_bus_center_ipc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_BUS_CENTER_IPC_H +#define LNN_BUS_CENTER_IPC_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen); +int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId); +int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum); +int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen); +int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len); + +int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode); +int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode); +int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen); +int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type); + +#ifdef __cplusplus +} +#endif +#endif /* LNN_L2_BUS_CENTER_IPC_H */ \ No newline at end of file diff --git a/core/bus_center/ipc/mini_system/lnn_bus_center_ipc.c b/core/bus_center/ipc/mini_system/lnn_bus_center_ipc.c new file mode 100755 index 000000000..2e959cb00 --- /dev/null +++ b/core/bus_center/ipc/mini_system/lnn_bus_center_ipc.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_bus_center_ipc.h" + +#include +#include + +#include "bus_center_manager.h" +#include "softbus_interface.h" + +int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + (void)pkgName; + (void)addrTypeLen; + return LnnServerJoin((ConnectionAddr *)addr); +} + +int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId) +{ + (void)pkgName; + return LnnServerLeave(networkId); +} + +int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) +{ + (void)pkgName; + (void)infoTypeLen; + return LnnGetAllOnlineNodeInfo((NodeBasicInfo **)info, infoNum); +} + +int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + (void)pkgName; + (void)infoTypeLen; + return LnnGetLocalDeviceInfo((NodeBasicInfo *)info); +} + +int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len) +{ + (void)pkgName; + return LnnGetNodeKeyInfo(networkId, key, buf, len); +} + +int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode) +{ + return GetClientProvideInterface()->onJoinLNNResult(NULL, addr, addrTypeLen, networkId, retCode); +} + +int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode) +{ + return GetClientProvideInterface()->onLeaveLNNResult(NULL, networkId, retCode); +} + +int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen) +{ + return GetClientProvideInterface()->onNodeOnlineStateChanged(isOnline, info, infoTypeLen); +} + +int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + return GetClientProvideInterface()->onNodeBasicInfoChanged(info, infoTypeLen, type); +} \ No newline at end of file diff --git a/core/bus_center/ipc/standard_system/lnn_bus_center_ipc.cpp b/core/bus_center/ipc/standard_system/lnn_bus_center_ipc.cpp new file mode 100755 index 000000000..6a3a02750 --- /dev/null +++ b/core/bus_center/ipc/standard_system/lnn_bus_center_ipc.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_bus_center_ipc.h" + +#include +#include +#include +#include + +#include "bus_center_manager.h" +#include "lnn_connection_addr_utils.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_permission.h" + +struct JoinLnnRequestInfo { + char pkgName[PKG_NAME_SIZE_MAX]; + ConnectionAddr addr; +}; + +struct LeaveLnnRequestInfo { + char pkgName[PKG_NAME_SIZE_MAX]; + char networkId[NETWORK_ID_BUF_LEN]; +}; + +static std::mutex g_lock; +static std::vector g_joinLNNRequestInfo; +static std::vector g_leaveLNNRequestInfo; + +static bool IsRepeatJoinLNNRequest(const char *pkgName, const ConnectionAddr *addr) +{ + std::vector::iterator iter; + for (iter = g_joinLNNRequestInfo.begin(); iter != g_joinLNNRequestInfo.end(); ++iter) { + if (strncmp(pkgName, (*iter)->pkgName, strlen(pkgName)) != 0) { + continue; + } + if (LnnIsSameConnectionAddr(addr, &(*iter)->addr)) { + return true; + } + } + return false; +} + +static int32_t AddJoinLNNInfo(const char *pkgName, const ConnectionAddr *addr) +{ + JoinLnnRequestInfo *info = new JoinLnnRequestInfo(); + if (strncpy_s(info->pkgName, PKG_NAME_SIZE_MAX, pkgName, strlen(pkgName)) != EOK) { + LOG_ERR("copy pkgName fail"); + delete info; + return SOFTBUS_ERR; + } + info->addr = *addr; + g_joinLNNRequestInfo.push_back(info); + return SOFTBUS_OK; +} + +static bool IsRepeatLeaveLNNRequest(const char *pkgName, const char *networkId) +{ + std::vector::iterator iter; + for (iter = g_leaveLNNRequestInfo.begin(); iter != g_leaveLNNRequestInfo.end(); ++iter) { + if (strncmp(pkgName, (*iter)->pkgName, strlen(pkgName)) != 0) { + continue; + } + if (strncmp(networkId, (*iter)->networkId, strlen(networkId)) == 0) { + return true; + } + } + return false; +} + +static int32_t AddLeaveLNNInfo(const char *pkgName, const char *networkId) +{ + LeaveLnnRequestInfo *info = new LeaveLnnRequestInfo(); + if (strncpy_s(info->pkgName, PKG_NAME_SIZE_MAX, pkgName, strlen(pkgName)) != EOK) { + LOG_ERR("copy pkgName fail"); + delete info; + return SOFTBUS_ERR; + } + if (strncpy_s(info->networkId, NETWORK_ID_BUF_LEN, networkId, strlen(networkId)) != EOK) { + LOG_ERR("copy networkId fail"); + delete info; + return SOFTBUS_ERR; + } + g_leaveLNNRequestInfo.push_back(info); + return SOFTBUS_OK; +} + +int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + if (CheckBusCenterPermission(pkgName) != true) { + LOG_ERR("ServerJoinLNN no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + ConnectionAddr *connAddr = (ConnectionAddr *)addr; + + (void)addrTypeLen; + if (pkgName == nullptr || connAddr == nullptr) { + LOG_ERR("parameters are nullptr!\n"); + return SOFTBUS_ERR; + } + std::lock_guard autoLock(g_lock); + if (IsRepeatJoinLNNRequest(pkgName, connAddr)) { + LOG_ERR("repeat join lnn request from: %s", pkgName); + return SOFTBUS_ERR; + } + int32_t ret = LnnServerJoin(connAddr); + if (ret == SOFTBUS_OK) { + ret = AddJoinLNNInfo(pkgName, connAddr); + } + return ret; +} + +int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId) +{ + if (CheckBusCenterPermission(pkgName) != true) { + LOG_ERR("ServerLeaveLNN no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + if (pkgName == nullptr || networkId == nullptr) { + LOG_ERR("parameters are nullptr!\n"); + return SOFTBUS_ERR; + } + std::lock_guard autoLock(g_lock); + if (IsRepeatLeaveLNNRequest(pkgName, networkId)) { + LOG_ERR("repeat leave lnn request from: %s", pkgName); + return SOFTBUS_ERR; + } + int32_t ret = LnnServerLeave(networkId); + if (ret == SOFTBUS_OK) { + ret = AddLeaveLNNInfo(pkgName, networkId); + } + return ret; +} + +int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) +{ + if (CheckBusCenterPermission(pkgName) != true) { + LOG_ERR("ServerGetAllOnlineNodeInfo no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + (void)infoTypeLen; + return LnnGetAllOnlineNodeInfo((NodeBasicInfo **)info, infoNum); +} + +int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + if (CheckBusCenterPermission(pkgName) != true) { + LOG_ERR("ServerGetLocalDeviceInfo no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + (void)infoTypeLen; + return LnnGetLocalDeviceInfo((NodeBasicInfo *)info); +} + +int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len) +{ + if (CheckBusCenterPermission(pkgName) != true) { + LOG_ERR("ServerGetNodeKeyInfo no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + return LnnGetNodeKeyInfo(networkId, key, buf, len); +} + +int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode) +{ + if (addr == nullptr) { + return SOFTBUS_INVALID_PARAM; + } + ConnectionAddr *connAddr = (ConnectionAddr *)addr; + std::lock_guard autoLock(g_lock); + std::vector::iterator iter, iter2; + for (iter = g_joinLNNRequestInfo.begin(); iter != g_joinLNNRequestInfo.end();) { + if (!LnnIsSameConnectionAddr(connAddr, &(*iter)->addr)) { + ++iter; + continue; + } + GetClientProvideInterface()->onJoinLNNResult((*iter)->pkgName, addr, addrTypeLen, networkId, retCode); + iter2 = iter; + iter = g_joinLNNRequestInfo.erase(iter); + delete *iter2; + } + return SOFTBUS_OK; +} + +int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode) +{ + if (networkId == nullptr) { + return SOFTBUS_INVALID_PARAM; + } + std::lock_guard autoLock(g_lock); + std::vector::iterator iter, iter2; + for (iter = g_leaveLNNRequestInfo.begin(); iter != g_leaveLNNRequestInfo.end();) { + if (strncmp(networkId, (*iter)->networkId, strlen(networkId))) { + ++iter; + continue; + } + GetClientProvideInterface()->onLeaveLNNResult((*iter)->pkgName, networkId, retCode); + iter2 = iter; + iter = g_leaveLNNRequestInfo.erase(iter); + delete *iter2; + } + return SOFTBUS_OK; +} + +int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen) +{ + return GetClientProvideInterface()->onNodeOnlineStateChanged(isOnline, info, infoTypeLen); +} + +int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + return GetClientProvideInterface()->onNodeBasicInfoChanged(info, infoTypeLen, type); +} \ No newline at end of file diff --git a/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_info.h b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_info.h new file mode 100644 index 000000000..e5de930f2 --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_info.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_LANE_INFO_H +#define LNN_LANE_INFO_H + +#include +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LNN_REQUEST_MAX_LANE_NUM 1 +/* Link type */ +typedef enum { + LNN_LINK_TYPE_WLAN_5G = 0x0, + LNN_LINK_TYPE_WLAN_2P4G, + LNN_LINK_TYPE_BR, + LNN_LINK_TYPE_BUTT, +} LnnLaneLinkType; + +typedef struct { + bool isProxy; + ConnectionAddr conOption; +} LnnLaneInfo; + +typedef enum { + LNN_MESSAGE_LANE = 1, + LNN_BYTES_LANE, + LNN_FILE_LANE, + LNN_STREAM_LANE, + LNN_LANE_PROPERTY_BUTT, +} LnnLaneProperty; + +ConnectionAddrType LnnGetLaneType(int32_t laneId); +void LnnReleaseLane(int32_t laneId); +const LnnLaneInfo *LnnGetConnection(int32_t laneId); +bool LnnUpdateLaneRemoteInfo(const char *netWorkId, LnnLaneLinkType type, bool mode); +void LnnLanesInit(void); + +#ifdef __cplusplus +} +#endif +#endif /* LNN_LANE_INFO_H */ \ No newline at end of file diff --git a/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_manager.h b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_manager.h new file mode 100644 index 000000000..10df64914 --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_lane_manager.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_LANE_MANAGER_H +#define LNN_LANE_MANAGER_H + +#include +#include "lnn_lane_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct LnnLanesObject LnnLanesObject; +LnnLanesObject *LnnRequestLanesObject(const char *netWorkId, LnnLaneProperty prop, uint32_t laneNum); +void LnnReleaseLanesObject(LnnLanesObject *lanesObject); + +uint32_t LnnGetLaneNum(LnnLanesObject *lanesObject); +int32_t LnnGetLaneId(LnnLanesObject *lanesObject, uint32_t num); + +#ifdef __cplusplus +} +#endif +#endif /* LNN_LANE_MANAGER_H */ \ No newline at end of file diff --git a/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_smart_communication.h b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_smart_communication.h new file mode 100644 index 000000000..61624f827 --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/include/lnn_smart_communication.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_SMART_COMMUNICATION_H +#define LNN_SMART_COMMUNICATION_H + +#include +#include "lnn_lane_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LnnGetRightLane(const char *netWorkId, LnnLaneProperty prop); + +#ifdef __cplusplus +} +#endif +#endif /* LNN_SMART_COMMUNICATION_H */ \ No newline at end of file diff --git a/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_info.c b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_info.c new file mode 100644 index 000000000..e937b370e --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_info.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_lane_info.h" + +#include +#include +#include + +#include "bus_center_info_key.h" +#include "bus_center_manager.h" +#include "softbus_log.h" + +typedef struct { + LnnLaneInfo laneInfo; + int32_t laneId; + bool isUse; + pthread_mutex_t lock; +} LaneInfoImpl; + +static LaneInfoImpl g_lanes[LNN_LINK_TYPE_BUTT]; +void LnnLanesInit(void) +{ + uint32_t firstLaneId = LNN_LINK_TYPE_WLAN_5G; + for (uint32_t i = firstLaneId; i < LNN_LINK_TYPE_BUTT; i++) { + g_lanes[i].laneId = firstLaneId++; + (void)pthread_mutex_init(&g_lanes[i].lock, NULL); + } +} + +static bool IsValidLaneId(int32_t laneId) +{ + if (laneId < LNN_LINK_TYPE_WLAN_5G || laneId >= LNN_LINK_TYPE_BUTT) { + LOG_ERR("param error. laneId = %d", laneId); + return false; + } + if (pthread_mutex_lock(&g_lanes[laneId].lock) != 0) { + LOG_ERR("lock failed"); + return false; + } + if (!g_lanes[laneId].isUse) { + LOG_ERR("The laneId cannot be used. laneId: %d.", laneId); + (void)pthread_mutex_unlock(&g_lanes[laneId].lock); + return false; + } + (void)pthread_mutex_unlock(&g_lanes[laneId].lock); + return true; +} + +void LnnReleaseLane(int32_t laneId) +{ + if (laneId < LNN_LINK_TYPE_WLAN_5G || laneId >= LNN_LINK_TYPE_BUTT) { + return; + } + if (pthread_mutex_lock(&g_lanes[laneId].lock) != 0) { + LOG_ERR("lock failed"); + return; + } + g_lanes[laneId].isUse = false; + (void)pthread_mutex_unlock(&g_lanes[laneId].lock); +} + +ConnectionAddrType LnnGetLaneType(int32_t laneId) +{ + if (!IsValidLaneId(laneId)) { + return CONNECTION_ADDR_MAX; + } + if (laneId == LNN_LINK_TYPE_WLAN_5G || laneId == LNN_LINK_TYPE_WLAN_2P4G) { + return CONNECTION_ADDR_WLAN; + } + return laneId; +} + +const LnnLaneInfo *LnnGetConnection(int32_t laneId) +{ + if (!IsValidLaneId(laneId)) { + return NULL; + } + return &g_lanes[laneId].laneInfo; +} + +static bool SetPeerIPInfo(const char *netWorkId, LnnLaneLinkType type, bool mode) +{ + int32_t ret; + int32_t port; + ret = LnnGetRemoteStrInfo(netWorkId, STRING_KEY_WLAN_IP, + g_lanes[type].laneInfo.conOption.info.ip.ip, IP_STR_MAX_LEN); + if (ret < 0 || strncmp(g_lanes[type].laneInfo.conOption.info.ip.ip, "127.0.0.1", strlen("127.0.0.1")) == 0) { + LOG_ERR("LnnGetRemoteStrInfo error."); + return false; + } + if (mode) { + ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_PROXY_PORT, &port); + } else { + ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_AUTH_PORT, &port); + } + if (ret < 0) { + LOG_ERR("LnnGetRemoteNumInfo error."); + return false; + } + g_lanes[type].laneInfo.conOption.type = CONNECTION_ADDR_WLAN; + g_lanes[type].laneInfo.conOption.info.ip.port = (uint16_t)port; + g_lanes[type].laneInfo.isProxy = mode; + return true; +} + +static bool SetPeerMacInfo(const char *netWorkId, LnnLaneLinkType type, bool mode) +{ + int32_t ret; + ret = LnnGetRemoteStrInfo(netWorkId, STRING_KEY_BT_MAC, g_lanes[type].laneInfo.conOption.info.br.brMac, BT_MAC_LEN); + if (ret < 0) { + LOG_ERR("LnnGetRemoteStrInfo error."); + return false; + } + if (type == LNN_LINK_TYPE_BR) { + g_lanes[type].laneInfo.conOption.type = CONNECTION_ADDR_BR; + g_lanes[type].laneInfo.isProxy = mode; + } + return true; +} + +bool LnnUpdateLaneRemoteInfo(const char *netWorkId, LnnLaneLinkType type, bool mode) +{ + if (netWorkId == NULL || type >= LNN_LINK_TYPE_BUTT || type < LNN_LINK_TYPE_WLAN_5G) { + LOG_ERR("param error. type = %d", type); + return false; + } + if (!g_lanes[type].isUse) { + if (pthread_mutex_lock(&g_lanes[type].lock) != 0) { + LOG_ERR("lock failed"); + return false; + } + if (g_lanes[type].isUse) { + (void)pthread_mutex_unlock(&g_lanes[type].lock); + return true; + } + } + + bool ret = false; + switch (type) { + case LNN_LINK_TYPE_WLAN_5G: + case LNN_LINK_TYPE_WLAN_2P4G: // the WLAN_5G and the WLAN_2P4G is same process. + ret = SetPeerIPInfo(netWorkId, type, mode); + break; + case LNN_LINK_TYPE_BR: + ret = SetPeerMacInfo(netWorkId, type, true); + break; + default: + break; + } + g_lanes[type].isUse = true; + (void)pthread_mutex_unlock(&g_lanes[type].lock); + return ret; +} diff --git a/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_manager.c b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_manager.c new file mode 100644 index 000000000..0749dae1c --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_manager.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_lane_manager.h" + +#include + +#include "lnn_smart_communication.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +struct LnnLanesObject { + LnnLaneProperty prop; + uint32_t laneNum; + int32_t laneId[0]; +}; + +LnnLanesObject *LnnRequestLanesObject(const char *netWorkId, LnnLaneProperty prop, uint32_t laneNum) +{ + if (prop < LNN_MESSAGE_LANE || prop >= LNN_LANE_PROPERTY_BUTT || netWorkId == NULL || + laneNum == 0 || laneNum > LNN_REQUEST_MAX_LANE_NUM) { + LOG_ERR("param error, prop = %d, laneNum = %u", prop, laneNum); + return NULL; + } + uint32_t memLen = sizeof(LnnLanesObject) + sizeof(int32_t) * laneNum; + LnnLanesObject *lanesObject = (LnnLanesObject *)SoftBusMalloc(memLen); + if (lanesObject == NULL) { + LOG_ERR("SoftBusMalloc error."); + return NULL; + } + (void)memset_s(lanesObject, memLen, 0, memLen); + lanesObject->prop = prop; + lanesObject->laneNum = laneNum; + + for (uint32_t i = 0; i < laneNum; i++) { + int32_t laneId = LnnGetRightLane(netWorkId, prop); + if (laneId < 0) { + LOG_ERR("LnnGetRightLane error. laneId = %d", laneId); + SoftBusFree(lanesObject); + return NULL; + } + lanesObject->laneId[i] = laneId; + } + return lanesObject; +} + +void LnnReleaseLanesObject(LnnLanesObject *lanesObject) +{ + if (lanesObject == NULL) { + return; + } + for (uint32_t i = 0; i < lanesObject->laneNum; i++) { + LnnReleaseLane(lanesObject->laneId[i]); + } + SoftBusFree(lanesObject); +} + +int32_t LnnGetLaneId(LnnLanesObject *lanesObject, uint32_t num) +{ + if (lanesObject == NULL || num >= lanesObject->laneNum) { + LOG_ERR("param error. num = %u", num); + return SOFTBUS_ERR; + } + return lanesObject->laneId[num]; +} + +uint32_t LnnGetLaneNum(LnnLanesObject *lanesObject) +{ + if (lanesObject == NULL) { + LOG_ERR("param error"); + return SOFTBUS_ERR; + } + return lanesObject->laneNum; +} \ No newline at end of file diff --git a/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_smart_communication.c b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_smart_communication.c new file mode 100644 index 000000000..404a30ede --- /dev/null +++ b/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_smart_communication.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_smart_communication.h" + +#include "bus_center_info_key.h" +#include "bus_center_manager.h" +#include "lnn_lane_info.h" +#include "lnn_net_capability.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +static int32_t GetLaneOf5GWlan(const char *netWorkId, LnnLaneProperty prop); +static int32_t GetLaneOf2P4GWlan(const char *netWorkId, LnnLaneProperty prop); +static int32_t GetLaneOfBR(const char *netWorkId, LnnLaneProperty prop); +typedef int32_t (*GetLaneByType)(const char *netWorkId, LnnLaneProperty prop); + +typedef struct { + uint8_t preferredLinkNum; + GetLaneByType getLaneByType[LNN_LINK_TYPE_BUTT]; +} SmartLaneMapEntry; + +SmartLaneMapEntry g_smartLaneMap[LNN_LANE_PROPERTY_BUTT] = { + [LNN_MESSAGE_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3 + [LNN_BYTES_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3 + [LNN_FILE_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3 + [LNN_STREAM_LANE] = {2, {GetLaneOf5GWlan, GetLaneOf2P4GWlan}}, // the preferredLinkNum is 2 +}; + +int32_t LnnGetRightLane(const char *netWorkId, LnnLaneProperty prop) +{ + if (prop < LNN_MESSAGE_LANE || prop >= LNN_LANE_PROPERTY_BUTT || netWorkId == NULL) { + LOG_ERR("param error. prop = %d", prop); + return SOFTBUS_ERR; + } + int32_t lane = SOFTBUS_ERR; + for (uint8_t i = 0; i < g_smartLaneMap[prop].preferredLinkNum; i++) { + lane = g_smartLaneMap[prop].getLaneByType[i](netWorkId, prop); + if (lane >= 0) { + return lane; + } + } + return lane; +} + +static bool IsProxyPort(LnnLaneProperty prop, LnnLaneLinkType type) +{ + if (prop == LNN_MESSAGE_LANE && + (type == LNN_LINK_TYPE_WLAN_5G || type == LNN_LINK_TYPE_WLAN_2P4G || type == LNN_LINK_TYPE_BR)) { + return true; + } + return false; +} + +static bool GetNumInfo(const char *netWorkId, int32_t *local, int32_t *remote) +{ + int32_t ret; + ret = LnnGetLocalNumInfo(NUM_KEY_NET_CAP, local); + if (ret < 0 || *local < 0) { + LOG_ERR("LnnGetLocalNumInfo error. ret = %d, local = %d", ret, *local); + return false; + } + ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_NET_CAP, remote); + if (ret < 0 || *remote < 0) { + LOG_ERR("LnnGetRemoteNumInfo error. ret = %d, remote = %d", ret, *remote); + return false; + } + return true; +} + +static int32_t GetLaneOf5GWlan(const char* netWorkId, LnnLaneProperty prop) +{ + int32_t local, remote; + if (!GetNumInfo(netWorkId, &local, &remote)) { + LOG_ERR("GetNumInfo error."); + return SOFTBUS_ERR; + } + + if (((local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH))) && + ((remote & (1 << BIT_WIFI_5G)) || (remote & (1 << BIT_ETH)))) { + if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_WLAN_5G, IsProxyPort(prop, LNN_LINK_TYPE_WLAN_5G))) { + return LNN_LINK_TYPE_WLAN_5G; // the LNN_LINK_TYPE_WLAN_5G is laneID. + } + } + LOG_INFO("Can't support WIFI WLAN 5G."); + return SOFTBUS_ERR; +} + +static int32_t GetLaneOf2P4GWlan(const char* netWorkId, LnnLaneProperty prop) +{ + int32_t local, remote; + if (!GetNumInfo(netWorkId, &local, &remote)) { + LOG_ERR("GetLaneOf2P4GWlan error."); + return SOFTBUS_ERR; + } + + if (((local & (1 << BIT_WIFI_24G)) || (local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH))) && + ((remote & (1 << BIT_WIFI_24G)) || (remote & (1 << BIT_WIFI_5G)) || (remote & (1 << BIT_ETH)))) { + if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_WLAN_2P4G, IsProxyPort(prop, LNN_LINK_TYPE_WLAN_2P4G))) { + return LNN_LINK_TYPE_WLAN_2P4G; + } + } + LOG_INFO("Can't support WIFI WLAN 2P4G."); + return SOFTBUS_ERR; +} + +static int32_t GetLaneOfBR(const char *netWorkId, LnnLaneProperty prop) +{ + int32_t local, remote; + + if (!GetNumInfo(netWorkId, &local, &remote)) { + LOG_ERR("GetLaneOfBR error."); + return SOFTBUS_ERR; + } + + if ((local & (1 << BIT_BR)) && (remote & (1 << BIT_BR))) { + if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_BR, IsProxyPort(prop, LNN_LINK_TYPE_BR))) { + return LNN_LINK_TYPE_BR; + } + } + LOG_INFO("Can't support BR."); + return SOFTBUS_ERR; +} diff --git a/core/bus_center/lnn/net_builder/include/lnn_conn_type_hook.h b/core/bus_center/lnn/net_builder/include/lnn_conn_type_hook.h new file mode 100644 index 000000000..40ea3bbfe --- /dev/null +++ b/core/bus_center/lnn/net_builder/include/lnn_conn_type_hook.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_CONN_TYPE_HOOK_H +#define LNN_CONN_TYPE_HOOK_H + +#include +#include "lnn_state_machine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + NETWORK_TYPE_ACTIVE, + NETWORK_TYPE_SELF +} NetworkType; + +#define JOIN_DISCOVERY_TIMEOUT_LEN (60 * 1000UL) + +typedef struct { + int32_t (*preprocess)(const ConnectionAddr *addr, FsmStateMachine *fsm, NetworkType type); + void (*shutdown)(const ConnectionAddr *addr); +} ConnTypeHook; + +void LnnInitIpHook(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/bus_center/lnn/net_builder/include/lnn_net_builder.h b/core/bus_center/lnn/net_builder/include/lnn_net_builder.h new file mode 100644 index 000000000..31fc88ceb --- /dev/null +++ b/core/bus_center/lnn/net_builder/include/lnn_net_builder.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_NET_BUILDER_H +#define LNN_NET_BUILDER_H + +#include + +#include "lnn_sync_ledger_item_info.h" +#include "lnn_conn_type_hook.h" +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + NODE_TYPE_C, + NODE_TYPE_L +} NodeType; + +typedef enum { + FSM_MSG_TYPE_JOIN_LNN, + FSM_MSG_TYPE_DISCOVERY_TIMEOUT, + FSM_MSG_TYPE_AUTH_DONE, + FSM_MSG_TYPE_SYNC_DEVICE_INFO, + FSM_MSG_TYPE_SYNC_DEVICE_INFO_DONE, + FSM_MSG_TYPE_EST_HEART_BEAT, + FSM_MSG_TYPE_LEAVE_LNN, + FSM_MSG_TYPE_NOT_TRUSTED, + FSM_MSG_TYPE_PEER_INFO_CHANGE, + FSM_MSG_TYPE_JOIN_LNN_TIMEOUT, + FSM_MSG_TYPE_SYNC_OFFLINE_DONE, + FSM_MSG_TYPE_SEND_OFFLINE_MESSAGE, + FSM_MSG_TYPE_LEAVE_LNN_TIMEOUT, +} StateMessageType; + +int32_t LnnInitNetBuilder(void); +void LnnDeinitNetBuilder(void); + +int32_t LnnRegisterConnTypeHook(ConnectionAddrType type, const ConnTypeHook *hook); +int32_t LnnNotifyPeerDevInfoChanged(const char *udid, SyncItemInfo *info); +int32_t LnnNotifySyncOfflineFinish(void); +int32_t LnnNotifySendOfflineMessage(int32_t id); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/core/bus_center/lnn/net_builder/include/lnn_network_id.h b/core/bus_center/lnn/net_builder/include/lnn_network_id.h new file mode 100644 index 000000000..17c0ee145 --- /dev/null +++ b/core/bus_center/lnn/net_builder/include/lnn_network_id.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_NETWORK_ID_H +#define LNN_NETWORK_ID_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LnnGenLocalNetworkId(char *networkId, int32_t len); +int32_t LnnGenLocalUuid(char *uuid, int32_t len); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/core/bus_center/lnn/net_builder/include/lnn_state_machine.h b/core/bus_center/lnn/net_builder/include/lnn_state_machine.h new file mode 100644 index 000000000..14d5a0116 --- /dev/null +++ b/core/bus_center/lnn/net_builder/include/lnn_state_machine.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_STATE_MACHINE_H +#define LNN_STATE_MACHINE_H + +#include + +#include "common_list.h" +#include "message_handler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FSM_FLAG_RUNNING 0x1 + +typedef void (*StateEnterFunc)(void); +typedef void (*StateExitFunc)(void); +typedef bool (*StateProcessFunc)(int32_t msgType, void *para); + +typedef struct { + ListNode list; + StateEnterFunc enter; + StateProcessFunc process; + StateExitFunc exit; +} FsmState; + +struct tagFsmStateMachine; + +typedef void (*FsmDinitCallback)(struct tagFsmStateMachine *fsm); + +typedef struct tagFsmStateMachine { + FsmState *curState; + uint32_t flag; + + ListNode stateList; + SoftBusLooper *looper; + SoftBusHandler handler; + + FsmDinitCallback deinitCallback; +} FsmStateMachine; + +int32_t LnnFsmInit(FsmStateMachine *fsm, char *name, FsmDinitCallback cb); +int32_t LnnFsmDeinit(FsmStateMachine *fsm); + +int32_t LnnFsmAddState(FsmStateMachine *fsm, FsmState *state); + +int32_t LnnFsmStart(FsmStateMachine *fsm, FsmState *initialState); +int32_t LnnFsmStop(FsmStateMachine *fsm); + +int32_t LnnFsmPostMessage(FsmStateMachine *fsm, int32_t msgType, void *data); +int32_t LnnFsmPostMessageDelay(FsmStateMachine *fsm, int32_t msgType, + void *data, uint64_t delayMillis); +int32_t LnnFsmRemoveMessage(FsmStateMachine *fsm, int32_t msgType); + +int32_t LnnFsmTransactState(FsmStateMachine *fsm, FsmState *state); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/bus_center/lnn/net_builder/ip/ip_hook.c b/core/bus_center/lnn/net_builder/ip/ip_hook.c new file mode 100644 index 000000000..13862780f --- /dev/null +++ b/core/bus_center/lnn/net_builder/ip/ip_hook.c @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "auth_socket.h" +#include "bus_center_manager.h" +#include "disc_interface.h" +#include "lnn_connect_info.h" +#include "lnn_net_builder.h" +#include "lnn_state_machine.h" +#include "softbus_conn_interface.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "trans_tcp_direct_listener.h" + +#define WLAN_IF_NAME_PRE "wlan" +#define ETH_IF_NAME_PRE "eth" +#define IF_COUNT_MAX 16 +#define LNN_DISC_CAPABILITY "ddmpCapability" +#define LNN_PUBLISH_ID 0 +#define LNN_SUBSCRIBE_ID 0 +#define IP_DEFAULT_PORT 0 + +typedef struct { + FsmStateMachine *fsm; + ConnectionAddrType type; +} IpHookStatus; + +typedef struct { + char *ifName; + uint32_t ifNameLen; +} IfInfo; + +static IpHookStatus g_status = { + .fsm = NULL, + .type = CONNECTION_ADDR_WLAN, +}; + +static int32_t GetNetworkIfList(int32_t fd, struct ifconf *conf, struct ifreq *buf, uint32_t len) +{ + if (fd < 0 || conf == NULL || buf == NULL) { + LOG_ERR("fail: parameter error!"); + return SOFTBUS_INVALID_PARAM; + } + conf->ifc_len = len; + conf->ifc_buf = (char *)buf; + if (ioctl(fd, SIOCGIFCONF, (char*)conf) < 0) { + LOG_ERR("ioctl fail, errno = %d", errno); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t GetNetworkIfIp(int32_t fd, struct ifreq *req, char *ip, uint32_t len) +{ + if (fd < 0 || req == NULL || ip == NULL) { + LOG_ERR("fail: parameter error!"); + return SOFTBUS_INVALID_PARAM; + } + + if (ioctl(fd, SIOCGIFFLAGS, (char*)req) < 0) { + LOG_ERR("ioctl SIOCGIFFLAGS fail, errno = %d", errno); + return SOFTBUS_ERR; + } + if (!((uint16_t)req->ifr_flags & IFF_UP)) { + LOG_ERR("interface is not up"); + return SOFTBUS_ERR; + } + + /* get IP of this interface */ + if (ioctl(fd, SIOCGIFADDR, (char*)req) < 0) { + LOG_ERR("ioctl SIOCGIFADDR fail, errno = %d", errno); + return SOFTBUS_ERR; + } + + if (strcpy_s(ip, len, inet_ntoa(((struct sockaddr_in *)&(req->ifr_addr))->sin_addr)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static char *GetIfNamePre(ConnectionAddrType type) +{ + if (type == CONNECTION_ADDR_WLAN) { + return WLAN_IF_NAME_PRE; + } else if (type == CONNECTION_ADDR_ETH) { + return ETH_IF_NAME_PRE; + } else { + LOG_ERR("type = %d, error!", type); + return NULL; + } +} + +static int32_t GetLocalIp(char *ip, uint32_t len, IfInfo *info, ConnectionAddrType type) +{ + LOG_INFO("type = %d", type); + if (ip == NULL || len < IP_MAX_LEN || info == NULL || info->ifName == NULL) { + LOG_ERR("fail : para error!"); + return SOFTBUS_INVALID_PARAM; + } + char *pre = GetIfNamePre(type); + if (pre == NULL) { + return SOFTBUS_INVALID_PARAM; + } + uint32_t preLen = strlen(pre); + int32_t fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + return SOFTBUS_ERR; + } + struct ifreq req[IF_COUNT_MAX]; + struct ifconf conf; + int32_t ret = GetNetworkIfList(fd, &conf, req, sizeof(req)); + if (ret != SOFTBUS_OK) { + LOG_ERR("GetNetworkIfList fail!"); + close(fd); + return SOFTBUS_ERR; + } + int32_t num = conf.ifc_len / sizeof(struct ifreq); + ret = SOFTBUS_ERR; + LOG_INFO("network interface num = %d", num); + for (int32_t i = 0; (i < num) && (i < IF_COUNT_MAX); i++) { + LOG_INFO("network interface name is %s", req[i].ifr_name); + if (strlen(req[i].ifr_name) < preLen) { + continue; + } + if (memcmp(pre, req[i].ifr_name, preLen) == 0) { + if (GetNetworkIfIp(fd, &req[i], ip, len) == SOFTBUS_OK) { + (void)strncpy_s(info->ifName, info->ifNameLen, req[i].ifr_name, strlen(req[i].ifr_name)); + LOG_INFO("GetNetworkIfIp ok!"); + ret = SOFTBUS_OK; + } + break; + } + } + close(fd); + return ret; +} + +static void DeviceFound(const DeviceInfo *device) +{ + ConnectionAddr *para = NULL; + if (device == NULL) { + LOG_ERR("DeviceFound error!"); + return; + } + LOG_INFO("DeviceFound! type = %d", g_status.type); + para = (ConnectionAddr *)SoftBusCalloc(sizeof(ConnectionAddr)); + if (para == NULL) { + LOG_ERR("malloc init message fail"); + return; + } + para->type = g_status.type; + para->info.ip.port = device->addr[0].port; + if (strncpy_s(para->info.ip.ip, IP_STR_MAX_LEN, device->addr[0].addr, strlen(device->addr[0].addr)) != EOK) { + LOG_ERR("STR ERROR!"); + SoftBusFree(para); + return; + } + + if (g_status.fsm != NULL) { + LOG_INFO("PostMessageToFsm!"); + (void)LnnFsmRemoveMessage(g_status.fsm, FSM_MSG_TYPE_DISCOVERY_TIMEOUT); + if (LnnFsmPostMessage(g_status.fsm, FSM_MSG_TYPE_JOIN_LNN, para) != SOFTBUS_OK) { + LOG_ERR("LnnFsmPostMessage FSM_MSG_TYPE_JOIN_LNN error!"); + SoftBusFree(para); + } + } else { + LOG_ERR("DeviceFound don't post to fsm!"); + SoftBusFree(para); + } + return; +} + +static DiscInnerCallback g_discCb = { + .OnDeviceFound = DeviceFound, +}; + +static int32_t EnableCoapDisc(void) +{ + LOG_INFO("EnableCoapDisc begin"); + int32_t ret = DiscSetDiscoverCallback(MODULE_LNN, &g_discCb); + if (ret != SOFTBUS_OK) { + LOG_ERR("DiscSetDiscoverCallback error!"); + return SOFTBUS_ERR; + } + PublishInnerInfo publishInfo = { + .publishId = LNN_PUBLISH_ID, + .medium = COAP, + .freq = HIGH, + .capability = LNN_DISC_CAPABILITY, + .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY, + .dataLen = strlen(LNN_DISC_CAPABILITY) + 1, + }; + LOG_INFO("DiscStartScan!"); + ret = DiscStartScan(MODULE_LNN, &publishInfo); + if (ret != SOFTBUS_OK) { + LOG_ERR("DiscStartScan fail!"); + return SOFTBUS_ERR; + } + + SubscribeInnerInfo subscribeInfo = { + .subscribeId = LNN_SUBSCRIBE_ID, + .medium = COAP, + .freq = HIGH, + .isSameAccount = false, + .isWakeRemote = false, + .capability = LNN_DISC_CAPABILITY, + .capabilityData = (unsigned char *)LNN_DISC_CAPABILITY, + .dataLen = strlen(LNN_DISC_CAPABILITY) + 1, + }; + LOG_INFO("DiscStartAdvertise!"); + ret = DiscStartAdvertise(MODULE_LNN, &subscribeInfo); + if (ret != SOFTBUS_OK) { + LOG_ERR("DiscStartAdvertise fail!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t UpdateLocalIp(ConnectionAddrType type) +{ + char ipAddr[IP_MAX_LEN] = {0}; + char ifName[NET_IF_NAME_LEN] = {0}; + IfInfo info = { + .ifName = ifName, + .ifNameLen = NET_IF_NAME_LEN, + }; + int32_t ret = GetLocalIp(ipAddr, IP_MAX_LEN, &info, type); + if (ret != SOFTBUS_OK) { + LOG_ERR("GetLocalIp error!"); + return SOFTBUS_ERR; + } + ret = LnnSetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr); + if (ret != SOFTBUS_OK) { + LOG_ERR("LnnSetLocalStrInfo error!"); + return SOFTBUS_ERR; + } + (void)LnnSetLocalStrInfo(STRING_KEY_NET_IF_NAME, ifName); + return SOFTBUS_OK; +} + +static int32_t UpdateProxyPort(void) +{ + LocalListenerInfo listenerInfo = {0}; + char ipAddr[IP_MAX_LEN] = {0}; + listenerInfo.type = CONNECT_TCP; + listenerInfo.info.ipListenerInfo.port = 0; + if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr, IP_MAX_LEN) != SOFTBUS_OK) { + LOG_ERR("LnnGetLocalStrInfo fail!"); + return SOFTBUS_ERR; + } + if (strncpy_s(listenerInfo.info.ipListenerInfo.ip, IP_LEN, ipAddr, strlen(ipAddr)) != EOK) { + LOG_ERR("fail:strncpy_s fail!"); + return SOFTBUS_MEM_ERR; + } + int32_t port = ConnStartLocalListening(&listenerInfo); + return LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, port); +} + +static int32_t UpdateSessionPort(void) +{ + char ipAddr[IP_MAX_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr, IP_MAX_LEN) != SOFTBUS_OK) { + LOG_ERR("LnnGetLocalStrInfo fail!"); + return SOFTBUS_ERR; + } + int32_t port = TransTdcStartSessionListener(ipAddr, 0); + return LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, port); +} + +static int32_t UpdateAuthPort(void) +{ + int32_t port = OpenAuthServer(); + return LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, port); +} + +static void CloseAuthPort(void) +{ + CloseAuthServer(); + (void)LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, IP_DEFAULT_PORT); + return; +} + +static void CloseSessionPort(void) +{ + TransTdcStopSessionListener(); + (void)LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, IP_DEFAULT_PORT); + return; +} + +static void CloseProxyPort(void) +{ + LocalListenerInfo listenerInfo = {0}; + listenerInfo.type = CONNECT_TCP; + if (ConnStopLocalListening(&listenerInfo) != SOFTBUS_OK) { + LOG_ERR("ConnStopLocalListening fail!"); + } + (void)LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, IP_DEFAULT_PORT); + return; +} + +static int32_t OpenIpLink(void) +{ + int32_t ret = UpdateAuthPort(); + if (ret != SOFTBUS_OK) { + LOG_ERR("UpdateSeesionPort fail!"); + return SOFTBUS_ERR; + } + ret = UpdateSessionPort(); + if (ret != SOFTBUS_OK) { + LOG_ERR("UpdateSeesionPort fail!"); + CloseAuthPort(); + return SOFTBUS_ERR; + } + ret = UpdateProxyPort(); + if (ret != SOFTBUS_OK) { + LOG_ERR("UpdateProxyPort fail!"); + CloseAuthPort(); + CloseSessionPort(); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void CloseIpLink(void) +{ + CloseAuthPort(); + CloseSessionPort(); + CloseProxyPort(); +} + +static void CloseCoapDisc(void) +{ + if (DiscUnpublish(MODULE_LNN, LNN_PUBLISH_ID) != SOFTBUS_OK) { + LOG_ERR("DiscUnpublish fail!"); + } + if (DiscStopAdvertise(MODULE_LNN, LNN_SUBSCRIBE_ID) != SOFTBUS_OK) { + LOG_ERR("DiscStopAdvertise fail!"); + } + return; +} + +static int32_t IpPreprocess(const ConnectionAddr *addr, FsmStateMachine *fsm, NetworkType networkType) +{ + if (addr == NULL || fsm == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_ERR; + } + ConnectionAddrType type = addr->type; + + if (UpdateLocalIp(type) != SOFTBUS_OK) { + LOG_ERR("UpdateLocalIp fail!"); + return SOFTBUS_ERR; + } + if (OpenIpLink() != SOFTBUS_OK) { + LOG_ERR("OpenIpLink fail!"); + return SOFTBUS_ERR; + } + if (networkType == NETWORK_TYPE_ACTIVE) { + ConnectionAddrType *para = (ConnectionAddrType *)SoftBusCalloc(sizeof(ConnectionAddrType)); + if (para == NULL) { + LOG_ERR("malloc init message fail"); + return SOFTBUS_ERR; + } + *para = type; + if (LnnFsmPostMessageDelay(fsm, FSM_MSG_TYPE_DISCOVERY_TIMEOUT, para, JOIN_DISCOVERY_TIMEOUT_LEN) + != SOFTBUS_OK) { + SoftBusFree(para); + return SOFTBUS_ERR; + } + } + if (EnableCoapDisc() != SOFTBUS_OK) { + LOG_ERR("EnableCoapDisc fail!"); + return SOFTBUS_ERR; + } + + LOG_INFO("IpPreprocess ok!"); + g_status.fsm = fsm; + g_status.type = type; + return SOFTBUS_OK; +} + +static void IpShutdown(const ConnectionAddr *addr) +{ + (void)addr; + (void)LnnSetLocalStrInfo(STRING_KEY_WLAN_IP, LOCAL_IP); + CloseIpLink(); + CloseCoapDisc(); + g_status.fsm = NULL; + return; +} + +static ConnTypeHook g_hook = { + .preprocess = IpPreprocess, + .shutdown = IpShutdown, +}; + +void LnnInitIpHook(void) +{ + LnnRegisterConnTypeHook(CONNECTION_ADDR_WLAN, &g_hook); + LnnRegisterConnTypeHook(CONNECTION_ADDR_ETH, &g_hook); + if (UpdateLocalIp(CONNECTION_ADDR_ETH) == SOFTBUS_OK) { + LOG_INFO("update eth ip success"); + return; + } + if (UpdateLocalIp(CONNECTION_ADDR_WLAN) == SOFTBUS_OK) { + LOG_INFO("update wlan ip success"); + } +} diff --git a/core/bus_center/lnn/net_builder/src/lnn_net_builder.c b/core/bus_center/lnn/net_builder/src/lnn_net_builder.c new file mode 100644 index 000000000..98a6dbe24 --- /dev/null +++ b/core/bus_center/lnn/net_builder/src/lnn_net_builder.c @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_net_builder.h" + +#include + +#include + +#include "auth_interface.h" +#include "bus_center_event.h" +#include "bus_center_manager.h" +#include "lnn_conn_type_hook.h" +#include "lnn_connection_addr_utils.h" +#include "lnn_distributed_net_ledger.h" +#include "lnn_exchange_ledger_info.h" +#include "lnn_network_id.h" +#include "lnn_state_machine.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#define STATE_AUTH_INDEX 0 +#define STATE_SYNC_DEVICE_INFO_INDEX 1 +#define STATE_OFFLINE_INDEX 2 +#define STATE_ONLINE_INDEX 3 +#define STATE_LEAVING_INDEX 4 +#define STATE_NUM_MAX (STATE_LEAVING_INDEX + 1) + + +#define CONN_INFO_FLAG_JOINING_ACTIVE 0x01 +#define CONN_INFO_FLAG_JOINING_PASSIVE 0x02 +#define CONN_INFO_FLAG_LEAVING_ACTIVE 0x04 +#define CONN_INFO_FLAG_LEAVING_PASSIVE 0x08 + +#define JOIN_LNN_TIMEOUT_LEN (15 * 1000UL) +#define LEAVE_LNN_TIMEOUT_LEN (5 * 1000UL) + +typedef struct { + ConnectionAddr addr; + NodeInfo *nodeInfo; + char peerNetworkId[NETWORK_ID_BUF_LEN]; + int64_t authId; + SoftBusVersion peerVersion; + uint32_t flag; +} ConnInfo; + +typedef struct { + NodeType nodeType; + FsmStateMachine fsm; + ConnInfo connInfo; + const ConnTypeHook *hook[CONNECTION_ADDR_MAX]; + bool isInit; +} NetBuilder; + +typedef struct { + bool isSuccess; + int64_t authId; + ConnectOption connOp; + SoftBusVersion peerVersion; +} AuthResultMsgPara; + +typedef struct { + int64_t authId; + AuthSideFlag side; + char uuid[UUID_BUF_LEN]; + uint8_t *data; + uint32_t len; +} RecvDeviceInfoMsgPara; + +typedef struct { + char udid[UDID_BUF_LEN]; + SyncItemInfo *info; +} RecvPeerInfoChangeMsgPara; + +static NetBuilder g_netBuilder; + +static void AuthStateEnter(void); +static bool AuthStateProcess(int32_t msgType, void *para); +static bool SyncDeviceInfoStateProcess(int32_t msgType, void *para); +static bool OfflineStateProcess(int32_t msgType, void *para); +static void OnlineStateEnter(void); +static bool OnlineStateProcess(int32_t msgType, void *para); +static void LeavingStateEnter(void); +static bool LeavingStateProcess(int32_t msgType, void *para); + +static FsmState g_states[STATE_NUM_MAX] = { + [STATE_AUTH_INDEX] = { + .enter = AuthStateEnter, + .process = AuthStateProcess, + .exit = NULL, + }, + [STATE_SYNC_DEVICE_INFO_INDEX] = { + .enter = NULL, + .process = SyncDeviceInfoStateProcess, + .exit = NULL, + }, + [STATE_OFFLINE_INDEX] = { + .enter = NULL, + .process = OfflineStateProcess, + .exit = NULL, + }, + [STATE_ONLINE_INDEX] = { + .enter = OnlineStateEnter, + .process = OnlineStateProcess, + .exit = NULL, + }, + [STATE_LEAVING_INDEX] = { + .enter = LeavingStateEnter, + .process = LeavingStateProcess, + .exit = NULL, + }, +}; + +void __attribute__ ((weak)) LnnInitIpHook(void) +{ +} +static bool ConvertAddrToOption(ConnectionAddr *addr, ConnectOption *option) +{ + if (addr->type == CONNECTION_ADDR_BR) { + option->type = CONNECT_BR; + if (strncpy_s(option->info.brOption.brMac, BT_MAC_LEN, addr->info.br.brMac, + strlen(addr->info.br.brMac)) != EOK) { + LOG_ERR("copy br mac to addr fail"); + return false; + } + return true; + } else if (addr->type == CONNECTION_ADDR_ETH || addr->type == CONNECTION_ADDR_WLAN) { + option->type = CONNECT_TCP; + if (strncpy_s(option->info.ipOption.ip, IP_LEN, addr->info.ip.ip, + strlen(addr->info.ip.ip)) != EOK) { + LOG_ERR("copy ip to addr fail"); + return false; + } + option->info.ipOption.port = addr->info.ip.port; + return true; + } + LOG_ERR("not supported type: %d", addr->type); + return false; +} + +static bool ConvertOptionToAddr(ConnectionAddr *addr, ConnectOption *option) +{ + if (option->type == CONNECT_BR) { + addr->type = CONNECTION_ADDR_BR; + if (strncpy_s(addr->info.br.brMac, BT_MAC_LEN, option->info.brOption.brMac, + strlen(option->info.brOption.brMac)) != EOK) { + LOG_ERR("copy br mac to addr fail"); + return false; + } + return true; + } + if (option->type == CONNECT_TCP) { + ConnectionAddr *temp = &g_netBuilder.connInfo.addr; + addr->type = temp->type; + if (strncpy_s(addr->info.ip.ip, IP_STR_MAX_LEN, option->info.ipOption.ip, + strlen(option->info.ipOption.ip)) != EOK) { + LOG_ERR("copy op ip to addr fail"); + return false; + } + return true; + } + LOG_ERR("not supported type: %d", option->type); + return false; +} + +static void FreeUnhandledMessage(int32_t msgType, void *para) +{ + RecvPeerInfoChangeMsgPara *peerInfo = NULL; + + LOG_INFO("free unhandled msg: %d", msgType); + if (msgType == FSM_MSG_TYPE_PEER_INFO_CHANGE) { + peerInfo = (RecvPeerInfoChangeMsgPara *)para; + if (peerInfo->info != NULL) { + LnnDeleteSyncItemInfo(peerInfo->info); + } + } + if (para != NULL) { + SoftBusFree(para); + } +} + +static void CompleteJoinLNN(const char *networkId, int32_t retCode) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + + LnnFsmRemoveMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_JOIN_LNN_TIMEOUT); + if (retCode == SOFTBUS_OK) { + if (strncpy_s(connInfo->peerNetworkId, NETWORK_ID_BUF_LEN, + networkId, strlen(networkId)) == EOK) { + LnnAddOnlineNode(connInfo->nodeInfo); + } else { + LOG_ERR("copy peer network id error"); + } + } else { + if (g_netBuilder.hook[connInfo->addr.type] != NULL && + g_netBuilder.hook[connInfo->addr.type]->shutdown != NULL) { + g_netBuilder.hook[connInfo->addr.type]->shutdown(&connInfo->addr); + } + (void)AuthHandleLeaveLNN(connInfo->authId); + } + if (connInfo->nodeInfo != NULL) { + SoftBusFree(connInfo->nodeInfo); + connInfo->nodeInfo = NULL; + } + if ((connInfo->flag & CONN_INFO_FLAG_JOINING_ACTIVE) != 0) { + LnnNotifyJoinResult(&connInfo->addr, networkId, retCode); + } + connInfo->flag &= ~CONN_INFO_FLAG_JOINING_ACTIVE; + connInfo->flag &= ~CONN_INFO_FLAG_JOINING_PASSIVE; +} + +static void CompleteLeaveLNN(const char *networkId, int32_t retCode) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + NodeInfo *info = NULL; + const char *udid = NULL; + ConnectOption option; + + if (retCode == SOFTBUS_OK) { + info = LnnGetNodeInfoById(networkId, CATEGORY_NETWORK_ID); + if (info != NULL) { + udid = LnnGetDeviceUdid(info); + LnnSetNodeOffline(udid); + // just remove node when peer device is not trusted + if ((connInfo->flag & CONN_INFO_FLAG_LEAVING_PASSIVE) != 0) { + LOG_INFO("remove node"); + LnnRemoveNode(udid); + } + } + } + if (g_netBuilder.hook[connInfo->addr.type] != NULL && + g_netBuilder.hook[connInfo->addr.type]->shutdown != NULL) { + g_netBuilder.hook[connInfo->addr.type]->shutdown(&connInfo->addr); + } + if (ConvertAddrToOption(&connInfo->addr, &option) == true) { + ConnDisconnectDeviceAllConn(&option); + } + if ((connInfo->flag & CONN_INFO_FLAG_LEAVING_ACTIVE) != 0) { + LnnNotifyLeaveResult(networkId, retCode); + } + connInfo->flag &= ~CONN_INFO_FLAG_LEAVING_ACTIVE; + connInfo->flag &= ~CONN_INFO_FLAG_LEAVING_PASSIVE; + (void)AuthHandleLeaveLNN(g_netBuilder.connInfo.authId); +} + +static void OnAuthPassed(int64_t authId, ConnectOption *option, SoftBusVersion peerVersion) +{ + if (option == NULL) { + LOG_ERR("OnAuthPassed option = null!"); + return; + } + AuthResultMsgPara *para = SoftBusCalloc(sizeof(*para)); + if (para == NULL) { + LOG_ERR("malloc auth result fail"); + return; + } + para->connOp = *option; + para->isSuccess = true; + para->authId = authId; + para->peerVersion = peerVersion; + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_AUTH_DONE, para); + LOG_INFO("auth passed: %lld", authId); +} + +static void OnAuthFailed(int64_t authId, ConnectOption *option) +{ + if (option == NULL) { + LOG_ERR("option = null!"); + return; + } + AuthResultMsgPara *para = SoftBusCalloc(sizeof(*para)); + if (para == NULL) { + LOG_ERR("malloc auth result fail"); + return; + } + para->connOp = *option; + para->isSuccess = false; + para->authId = authId; + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_AUTH_DONE, para); + LOG_INFO("auth failed: %lld", authId); +} + +static void OnRecvPeerDeviceInfo(int64_t authId, AuthSideFlag side, const char *peerUuid, uint8_t *data, uint32_t len) +{ + RecvDeviceInfoMsgPara *para = NULL; + + if (peerUuid == NULL || data == NULL) { + LOG_ERR("invalid para"); + return; + } + para = SoftBusCalloc(sizeof(*para) + len); + if (para == NULL) { + LOG_ERR("malloc device info para fail"); + return; + } + para->authId = authId; + para->side = side; + if (strncpy_s(para->uuid, UUID_BUF_LEN, peerUuid, strlen(peerUuid)) != EOK) { + LOG_ERR("copy uuid fail"); + SoftBusFree(para); + return; + } + para->data = (uint8_t *)para + sizeof(*para); + if (memcpy_s(para->data, len, data, len) != EOK) { + LOG_ERR("copy uuid fail"); + SoftBusFree(para); + return; + } + para->len = len; + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_SYNC_DEVICE_INFO_DONE, para); +} + +static void OnDeviceNotTrusted(const char *peerUdid) +{ + char *udid = NULL; + int32_t udidLen; + + if (peerUdid == NULL) { + return; + } + udidLen = strlen(peerUdid) + 1; + udid = (char *)SoftBusMalloc(udidLen); + if (udid == NULL) { + LOG_ERR("malloc udid fail"); + return; + } + if (strncpy_s(udid, udidLen, peerUdid, udidLen) != EOK) { + LOG_ERR("copy udid fail"); + SoftBusFree(udid); + return; + } + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_NOT_TRUSTED, udid); +} + +static VerifyCallback g_verifyCb = { + .onDeviceVerifyPass = OnAuthPassed, + .onDeviceVerifyFail = OnAuthFailed, + .onRecvSyncDeviceInfo = OnRecvPeerDeviceInfo, + .onDeviceNotTrusted = OnDeviceNotTrusted, +}; + +static int32_t InitNetBuilderStateMachine(void) +{ + int32_t rc, i; + + rc = LnnFsmInit(&g_netBuilder.fsm, "NetBuilderSm", NULL); + if (rc != SOFTBUS_OK) { + return rc; + } + for (i = 0; i < STATE_NUM_MAX; ++i) { + LnnFsmAddState(&g_netBuilder.fsm, &g_states[i]); + } + return SOFTBUS_OK; +} + +static void OnJoinLNNTimeout(void) +{ + LOG_ERR("join LNN timeout : auth time out!"); + CompleteJoinLNN(NULL, SOFTBUS_ERR); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); +} + +static void OnDiscoveryTimeOut(ConnectionAddrType *para) +{ + LOG_ERR("join LNN timeout : discovery time out!"); + if (para == NULL) { + LOG_ERR("join LNN timeout : para error!"); + return; + } + ConnectionAddr addr; + (void)memset_s(&addr, sizeof(ConnectionAddr), 0, sizeof(ConnectionAddr)); + addr.type = *para; + LnnNotifyJoinResult(&addr, NULL, SOFTBUS_ERR); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + if (g_netBuilder.hook[*para] != NULL && + g_netBuilder.hook[*para]->shutdown != NULL) { + g_netBuilder.hook[*para]->shutdown(NULL); + } + SoftBusFree(para); +} + +static void AuthStateEnter(void) +{ + char uuid[UUID_BUF_LEN]; + char networkId[NETWORK_ID_BUF_LEN]; + + LOG_INFO("auth state enter"); + if (LnnGenLocalNetworkId(networkId, NETWORK_ID_BUF_LEN) != SOFTBUS_OK || + LnnGenLocalUuid(uuid, UUID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("get local id fail"); + return; + } + LnnSetLocalStrInfo(STRING_KEY_UUID, uuid); + LnnSetLocalStrInfo(STRING_KEY_NETWORKID, networkId); + if (AuthRegCallback(LNN, &g_verifyCb) != SOFTBUS_OK) { + LOG_ERR("register auth cb fail"); + } +} + +static int32_t OnJoinLNNInAuth(ConnectionAddr *addr) +{ + int32_t rc; + ConnInfo *connInfo = &g_netBuilder.connInfo; + ConnectOption option; + + if (addr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (ConvertAddrToOption(addr, &option) == false) { + SoftBusFree(addr); + return SOFTBUS_ERR; + } + + if ((connInfo->flag & (CONN_INFO_FLAG_JOINING_ACTIVE | + CONN_INFO_FLAG_JOINING_PASSIVE)) != 0) { + if (LnnIsSameConnectionAddr(addr, &connInfo->addr) == true) { + LOG_INFO("addr is same, waiting..."); + SoftBusFree(addr); + return SOFTBUS_OK; + } + LOG_ERR("previous request is ongoing, reject it"); + LnnNotifyJoinResult(addr, NULL, SOFTBUS_ERR); + SoftBusFree(addr); + return SOFTBUS_OK; + } + LOG_INFO("begin a new join request"); + connInfo->addr = *addr; + connInfo->flag |= CONN_INFO_FLAG_JOINING_ACTIVE; + (void)AuthVerifyInit(); + LOG_INFO("hichain init ok...."); + rc = AuthVerifyDevice(LNN, &option); + if (rc != SOFTBUS_OK) { + CompleteJoinLNN(NULL, SOFTBUS_ERR); + (void)AuthVerifyDeinit(); + } else { + LnnFsmPostMessageDelay(&g_netBuilder.fsm, FSM_MSG_TYPE_JOIN_LNN_TIMEOUT, + NULL, JOIN_LNN_TIMEOUT_LEN); + } + SoftBusFree(addr); + LOG_INFO("rc = %d", rc); + return rc; +} + +static int32_t OnAuthDoneInAuth(AuthResultMsgPara *para) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + + if (para == NULL) { + LOG_ERR("unexpected null result"); + return SOFTBUS_INVALID_PARAM; + } + ConnectionAddr addr = {0}; + ConvertOptionToAddr(&addr, ¶->connOp); + LOG_INFO("auth done, authId = %lld", para->authId); + if ((connInfo->flag & CONN_INFO_FLAG_JOINING_ACTIVE) != 0) { + if (LnnIsSameConnectionAddr(&connInfo->addr, &addr) == false) { + LOG_ERR("unexpected auth done when joining"); + SoftBusFree(para); + return SOFTBUS_OK; + } + if (para->isSuccess) { + LOG_INFO("active auth success, transact to syn_device_info state"); + connInfo->authId = para->authId; + connInfo->peerVersion = para->peerVersion; + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_SYNC_DEVICE_INFO_INDEX); + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_SYNC_DEVICE_INFO, NULL); + } else { + LOG_ERR("auth failed"); + CompleteJoinLNN(NULL, SOFTBUS_ERR); + } + } else { + if (para->isSuccess) { + LOG_INFO("passive auth success, transact to syn_device_info state"); + connInfo->authId = para->authId; + connInfo->addr = addr; + connInfo->peerVersion = para->peerVersion; + connInfo->flag |= CONN_INFO_FLAG_JOINING_PASSIVE; + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_SYNC_DEVICE_INFO_INDEX); + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_SYNC_DEVICE_INFO, NULL); + LnnFsmPostMessageDelay(&g_netBuilder.fsm, FSM_MSG_TYPE_JOIN_LNN_TIMEOUT, + NULL, JOIN_LNN_TIMEOUT_LEN); + } else { + LOG_INFO("ignore failure auth result"); + } + } + (void)AuthVerifyDeinit(); + SoftBusFree(para); + return SOFTBUS_OK; +} + +static bool AuthStateProcess(int32_t msgType, void *para) +{ + LOG_INFO("auth process message: %d", msgType); + switch (msgType) { + case FSM_MSG_TYPE_JOIN_LNN: + OnJoinLNNInAuth((ConnectionAddr *)para); + break; + case FSM_MSG_TYPE_DISCOVERY_TIMEOUT: + OnDiscoveryTimeOut((ConnectionAddrType *)para); + break; + case FSM_MSG_TYPE_AUTH_DONE: + OnAuthDoneInAuth((AuthResultMsgPara *)para); + break; + case FSM_MSG_TYPE_LEAVE_LNN: + if (para != NULL) { + LnnNotifyLeaveResult((char *)para, SOFTBUS_ERR); + SoftBusFree(para); + } + break; + case FSM_MSG_TYPE_JOIN_LNN_TIMEOUT: + OnJoinLNNTimeout(); + break; + default: + FreeUnhandledMessage(msgType, para); + return false; + } + return true; +} + +static int32_t OnJoinLNNInSynInfo(ConnectionAddr *addr) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + int32_t rc = SOFTBUS_OK; + + if (addr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (LnnIsSameConnectionAddr(addr, &connInfo->addr) == false) { + LOG_ERR("previous request is ongoing, reject now request"); + LnnNotifyJoinResult(addr, NULL, false); + rc = SOFTBUS_ERR; + } else { + LOG_INFO("addr is same, waiting..."); + } + SoftBusFree(addr); + return rc; +} + +static int32_t OnSyncDeviceInfo(void) +{ + uint8_t *buf = NULL; + uint32_t bufSize; + int32_t rc; + ConnInfo *connInfo = &g_netBuilder.connInfo; + AuthDataHead head; + ConnectOption option; + + if (ConvertAddrToOption(&connInfo->addr, &option) == false) { + return SOFTBUS_ERR; + } + buf = LnnGetExchangeNodeInfo(&option, SOFT_BUS_NEW_V1, &bufSize, &head.flag); + if (buf == NULL) { + LOG_ERR("pack local device info fail"); + CompleteJoinLNN(NULL, SOFTBUS_ERR); + return SOFTBUS_ERR; + } + + head.dataType = DATA_TYPE_SYNC; + if (option.type == CONNECT_TCP) { + head.module = MODULE_AUTH_CONNECTION; + } else { + head.module = HICHAIN_SYNC; + } + + head.authId = connInfo->authId; + rc = AuthPostData(&head, buf, bufSize); + if (rc != SOFTBUS_OK) { + CompleteJoinLNN(NULL, SOFTBUS_ERR); + } + SoftBusFree(buf); + LOG_INFO("rc = %d", rc); + return rc; +} + +static DiscoveryType GetDiscoveryType(ConnectType type) +{ + if (type == CONNECT_TCP) { + return DISCOVERY_TYPE_WIFI; + } else if (type == CONNECT_BR) { + return DISCOVERY_TYPE_BR; + } else { + return DISCOVERY_TYPE_BLE; + } +} + +static bool ParsePeerNodeInfo(RecvDeviceInfoMsgPara *para, ConnInfo *connInfo) +{ + ParseBuf parseBuf; + int32_t rc = SOFTBUS_OK; + ConnectOption option; + do { + if (connInfo->nodeInfo == NULL) { + connInfo->nodeInfo = SoftBusCalloc(sizeof(NodeInfo)); + if (connInfo->nodeInfo == NULL) { + LOG_ERR("malloc node info fail"); + rc = SOFTBUS_MALLOC_ERR; + break; + } + } + if (ConvertAddrToOption(&connInfo->addr, &option) == false) { + rc = SOFTBUS_ERR; + break; + } + parseBuf.buf = para->data; + parseBuf.len = para->len; + if (LnnParsePeerNodeInfo(&option, connInfo->nodeInfo, + &parseBuf, para->side, connInfo->peerVersion) != SOFTBUS_OK) { + CompleteJoinLNN(NULL, SOFTBUS_ERR); + LOG_ERR("unpack peer device info fail"); + rc = SOFTBUS_ERR; + break; + } + connInfo->nodeInfo->discoveryType = 1 << (uint32_t)GetDiscoveryType(option.type); + connInfo->nodeInfo->authSeqNum = connInfo->authId; + if (strncpy_s(connInfo->nodeInfo->uuid, UUID_BUF_LEN, para->uuid, strlen(para->uuid)) != EOK) { + LOG_ERR("strncpy_s uuid failed"); + rc = SOFTBUS_ERR; + break; + } + if (option.type == CONNECT_TCP) { + if (strncpy_s(connInfo->nodeInfo->connectInfo.deviceIp, IP_MAX_LEN, connInfo->addr.info.ip.ip, + strlen(connInfo->addr.info.ip.ip)) != EOK) { + LOG_ERR("strncpy_s deviceIp failed"); + rc = SOFTBUS_ERR; + } + } + } while (false); + + if (rc != SOFTBUS_OK) { + SoftBusFree(connInfo->nodeInfo); + connInfo->nodeInfo = NULL; + return false; + } + return true; +} + +static int32_t OnSyncDeviceInfoDone(RecvDeviceInfoMsgPara *para) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + if (para == NULL) { + LOG_ERR("unexpected para"); + return SOFTBUS_ERR; + } + if (para->authId != connInfo->authId) { + LOG_INFO("unexpected authId:%lld, expected authId:%lld", para->authId, connInfo->authId); + SoftBusFree(para); + return SOFTBUS_ERR; + } + if (connInfo->peerVersion >= SOFT_BUS_NEW_V1) { + LOG_ERR("unexpected peer version: %d", connInfo->peerVersion); + CompleteJoinLNN(NULL, SOFTBUS_ERR); + SoftBusFree(para); + return SOFTBUS_ERR; + } + if (!ParsePeerNodeInfo(para, connInfo)) { + LOG_ERR("ParsePeerNodeInfo error"); + SoftBusFree(para); + return SOFTBUS_ERR; + } + SoftBusFree(para); + LOG_INFO("recv peer device info, transact to offline"); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_OFFLINE_INDEX); + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_EST_HEART_BEAT, NULL); + return SOFTBUS_OK; +} + +static int32_t OnDeviceNotTrustedInSynInfo(char *peerUdid) +{ + const char *udid = NULL; + + if (peerUdid == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_netBuilder.connInfo.nodeInfo != NULL) { + udid = LnnGetDeviceUdid(g_netBuilder.connInfo.nodeInfo); + if (udid != NULL && strcmp(peerUdid, udid) == 0) { + LOG_INFO("peer device is not trusted, complete join process"); + CompleteJoinLNN(NULL, SOFTBUS_ERR); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + } + } else { + LOG_INFO("ignore not trusted peer udid"); + } + SoftBusFree(peerUdid); + return SOFTBUS_OK; +} + +static bool SyncDeviceInfoStateProcess(int32_t msgType, void *para) +{ + LOG_INFO("sync device info process message: %d", msgType); + switch (msgType) { + case FSM_MSG_TYPE_JOIN_LNN: + OnJoinLNNInSynInfo((ConnectionAddr *)para); + break; + case FSM_MSG_TYPE_SYNC_DEVICE_INFO: + OnSyncDeviceInfo(); + break; + case FSM_MSG_TYPE_SYNC_DEVICE_INFO_DONE: + OnSyncDeviceInfoDone((RecvDeviceInfoMsgPara *)para); + break; + case FSM_MSG_TYPE_LEAVE_LNN: + if (para != NULL) { + LnnNotifyLeaveResult((char *)para, SOFTBUS_ERR); + SoftBusFree(para); + } + break; + case FSM_MSG_TYPE_NOT_TRUSTED: + OnDeviceNotTrustedInSynInfo((char *)para); + break; + case FSM_MSG_TYPE_JOIN_LNN_TIMEOUT: + OnJoinLNNTimeout(); + break; + default: + FreeUnhandledMessage(msgType, para); + return false; + } + return true; +} + +static void OnSetupHeartBeat(void) +{ + // don't support establish heart beat connection + LOG_INFO("no need setup hb, transact to online"); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_ONLINE_INDEX); +} + +static bool OfflineStateProcess(int32_t msgType, void *para) +{ + LOG_INFO("offline process message: %d", msgType); + switch (msgType) { + case FSM_MSG_TYPE_JOIN_LNN: + case FSM_MSG_TYPE_LEAVE_LNN: + case FSM_MSG_TYPE_NOT_TRUSTED: // JOIN LEAVE and NOT_TRUSTED is same process. + LnnFsmPostMessage(&g_netBuilder.fsm, msgType, para); + break; + case FSM_MSG_TYPE_EST_HEART_BEAT: + OnSetupHeartBeat(); + break; + case FSM_MSG_TYPE_JOIN_LNN_TIMEOUT: + OnJoinLNNTimeout(); + break; + default: + FreeUnhandledMessage(msgType, para); + return false; + } + return true; +} + +static void OnlineStateEnter(void) +{ + LOG_INFO("online state enter"); + CompleteJoinLNN(g_netBuilder.connInfo.nodeInfo->networkId, SOFTBUS_OK); +} + +static int32_t OnJoinLNNInOnline(ConnectionAddr *addr) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + int32_t rc = SOFTBUS_OK; + + if (addr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (LnnIsSameConnectionAddr(addr, &connInfo->addr) == true) { + LOG_INFO("request addr is already online"); + LnnNotifyJoinResult(addr, connInfo->peerNetworkId, 0); + rc = SOFTBUS_ERR; + } else { + LOG_INFO("previous is online, plz let it leave"); + LnnNotifyJoinResult(addr, NULL, SOFTBUS_ERR); + } + SoftBusFree(addr); + return rc; +} + +static bool IsNotNeedToCloseHb(ConnectionAddrType type) +{ + return ((type == CONNECTION_ADDR_BR) || (type == CONNECTION_ADDR_ETH) || (type == CONNECTION_ADDR_WLAN)); +} + +static int32_t OnLeaveLNNInOnline(char *networkId) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + int32_t rc = SOFTBUS_ERR; + + if (networkId == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (strcmp(networkId, connInfo->peerNetworkId) == 0) { + connInfo->flag |= CONN_INFO_FLAG_LEAVING_ACTIVE; + if (IsNotNeedToCloseHb(connInfo->addr.type)) { + LOG_INFO("no need close hb, transact to auth"); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_LEAVING_INDEX); + rc = SOFTBUS_OK; + } else { + LOG_ERR("not support connection type: %d", connInfo->addr.type); + CompleteLeaveLNN(networkId, SOFTBUS_ERR); + } + } else { + LOG_INFO("invalid leave lnn request, target device is in offline"); + LnnNotifyLeaveResult(networkId, SOFTBUS_ERR); + } + SoftBusFree(networkId); + return rc; +} + +static int32_t OnDeviceNotTrustedInOnline(char *peerUdid) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + NodeInfo *info = NULL; + + info = LnnGetNodeInfoById(peerUdid, CATEGORY_UDID); + if (info != NULL) { + LOG_INFO("device not trusted, transact auth"); + connInfo->flag |= CONN_INFO_FLAG_LEAVING_PASSIVE; + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_LEAVING_INDEX); + } else { + LOG_INFO("ignore not trusted peer uuid"); + } + SoftBusFree(peerUdid); + return SOFTBUS_OK; +} + +static int32_t OnPeerDevInfoChanged(RecvPeerInfoChangeMsgPara *para) +{ + int32_t rc = SOFTBUS_ERR; + + if (para == NULL || para->info == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (para->info->type == INFO_TYPE_DEVICE_NAME) { + LOG_INFO("peer device info changed."); + LnnSetDLDeviceInfoName(para->udid, (char *)para->info->buf); + rc = SOFTBUS_OK; + } else { + LOG_ERR("invalid peer dev info change type: %d", para->info->type); + } + LnnDeleteSyncItemInfo(para->info); + SoftBusFree(para); + return rc; +} + +static bool OnlineStateProcess(int32_t msgType, void *para) +{ + LOG_INFO("online process message: %d", msgType); + switch (msgType) { + case FSM_MSG_TYPE_JOIN_LNN: + OnJoinLNNInOnline((ConnectionAddr *)para); + break; + case FSM_MSG_TYPE_LEAVE_LNN: + OnLeaveLNNInOnline((char *)para); + break; + case FSM_MSG_TYPE_NOT_TRUSTED: + OnDeviceNotTrustedInOnline((char *)para); + break; + case FSM_MSG_TYPE_PEER_INFO_CHANGE: + OnPeerDevInfoChanged((RecvPeerInfoChangeMsgPara *)para); + break; + default: + FreeUnhandledMessage(msgType, para); + return false; + } + return true; +} + +static void LeavingStateEnter(void) +{ + int32_t rc; + ConnInfo *connInfo = &g_netBuilder.connInfo; + + LOG_INFO("leaving state enter"); + rc = LnnSyncLedgerItemInfo(connInfo->peerNetworkId, DISCOVERY_TYPE_BR, INFO_TYPE_OFFLINE); + if (rc == SOFTBUS_OK) { + LnnFsmPostMessageDelay(&g_netBuilder.fsm, FSM_MSG_TYPE_LEAVE_LNN_TIMEOUT, + NULL, LEAVE_LNN_TIMEOUT_LEN); + } else { + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + CompleteLeaveLNN(connInfo->peerNetworkId, SOFTBUS_OK); + } +} + +static void OnLeaveLNNInLeaving(char *networkId) +{ + ConnInfo *connInfo = &g_netBuilder.connInfo; + + if (networkId == NULL) { + LOG_ERR("param error"); + return; + } + + if (strcmp(networkId, connInfo->peerNetworkId) != 0) { + LOG_INFO("not compare network id"); + LnnNotifyLeaveResult(networkId, SOFTBUS_ERR); + } else { + LOG_INFO("already in leaving, wait result"); + } + SoftBusFree(networkId); +} + +static bool LeavingStateProcess(int32_t msgType, void *para) +{ + LOG_INFO("leaving process message: %d", msgType); + switch (msgType) { + case FSM_MSG_TYPE_JOIN_LNN: + if (para != NULL) { + LnnNotifyJoinResult((ConnectionAddr *)para, NULL, SOFTBUS_ERR); + SoftBusFree(para); + } + break; + case FSM_MSG_TYPE_LEAVE_LNN: + OnLeaveLNNInLeaving((char *)para); + break; + case FSM_MSG_TYPE_LEAVE_LNN_TIMEOUT: + CompleteLeaveLNN(g_netBuilder.connInfo.peerNetworkId, SOFTBUS_OK); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + break; + case FSM_MSG_TYPE_SYNC_OFFLINE_DONE: + LnnFsmRemoveMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_LEAVE_LNN_TIMEOUT); + CompleteLeaveLNN(g_netBuilder.connInfo.peerNetworkId, SOFTBUS_OK); + LnnFsmTransactState(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + break; + case FSM_MSG_TYPE_SEND_OFFLINE_MESSAGE: + if (para != NULL) { + LnnSendMessageToPeer(*(int32_t *)para); + SoftBusFree(para); + } + break; + default: + FreeUnhandledMessage(msgType, para); + return false; + } + return true; +} + +static int32_t ConnTypeDefaultHook(const ConnectionAddr *addr) +{ + ConnectionAddr *para = NULL; + para = (ConnectionAddr *)SoftBusCalloc(sizeof(ConnectionAddr)); + if (para == NULL) { + LOG_ERR("malloc init message fail"); + return SOFTBUS_MALLOC_ERR; + } + *para = *addr; + return LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_JOIN_LNN, para); +} + +int32_t LnnRegisterConnTypeHook(ConnectionAddrType type, const ConnTypeHook *hook) +{ + if (type < 0 || type >= CONNECTION_ADDR_MAX) { + LOG_ERR("fail : para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (g_netBuilder.hook[type] != NULL) { + LOG_INFO("type = %d, already add.", type); + } + g_netBuilder.hook[type] = hook; + return SOFTBUS_OK; +} + +int32_t LnnInitNetBuilder(void) +{ + int rc; + + if (g_netBuilder.isInit == true) { + return SOFTBUS_OK; + } + + rc = InitNetBuilderStateMachine(); + if (rc == SOFTBUS_OK) { + rc = LnnFsmStart(&g_netBuilder.fsm, g_states + STATE_AUTH_INDEX); + } + (void)memset_s(g_netBuilder.hook, sizeof(g_netBuilder.hook), 0, sizeof(g_netBuilder.hook)); + g_netBuilder.nodeType = NODE_TYPE_L; + g_netBuilder.isInit = true; + LnnInitIpHook(); + LOG_INFO("init net builder result: %d", rc); + return rc; +} + +void LnnDeinitNetBuilder(void) +{ + if (g_netBuilder.isInit == true) { + (void)LnnFsmStop(&g_netBuilder.fsm); + (void)LnnFsmDeinit(&g_netBuilder.fsm); + g_netBuilder.isInit = false; + } +} + +int32_t LnnNotifyPeerDevInfoChanged(const char *udid, SyncItemInfo *info) +{ + RecvPeerInfoChangeMsgPara *para = NULL; + + if (udid == NULL || info == NULL || info->buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (g_netBuilder.isInit == false) { + LOG_ERR("no init"); + return SOFTBUS_ERR; + } + para = SoftBusCalloc(sizeof(*para)); + if (para == NULL) { + LOG_ERR("malloc recv peer info change para fail"); + return SOFTBUS_MALLOC_ERR; + } + if (strncpy_s(para->udid, UDID_BUF_LEN, udid, strlen(udid)) != EOK) { + LOG_ERR("copy udid fail"); + SoftBusFree(para); + return SOFTBUS_ERR; + } + para->info = info; + LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_PEER_INFO_CHANGE, para); + return SOFTBUS_OK; +} + +static int32_t ConvertTypeToNetCap(ConnectionAddrType type, uint32_t *cap) +{ + if (cap == NULL) { + return SOFTBUS_ENCRYPT_ERR; + } + if (type == CONNECTION_ADDR_WLAN) { + (void)LnnSetNetCapability(cap, BIT_WIFI); + (void)LnnSetNetCapability(cap, BIT_WIFI_24G); + } else if (type == CONNECTION_ADDR_BR) { + (void)LnnSetNetCapability(cap, BIT_BR); + } else if (type == CONNECTION_ADDR_BLE) { + (void)LnnSetNetCapability(cap, BIT_BLE); + } else if (type == CONNECTION_ADDR_ETH) { + (void)LnnSetNetCapability(cap, BIT_ETH); + } else { + LOG_ERR("type not right: type = %d", type); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t LnnServerJoin(ConnectionAddr *addr) +{ + LOG_INFO("LnnServerJoin enter!"); + if (addr == NULL || addr->type < CONNECTION_ADDR_WLAN || addr->type > CONNECTION_ADDR_ETH) { + LOG_ERR("para error!"); + return SOFTBUS_ERR; + } + if (g_netBuilder.isInit == false) { + LOG_ERR("no init"); + return SOFTBUS_ERR; + } + + uint32_t cap = 0; + if (ConvertTypeToNetCap(addr->type, &cap) != SOFTBUS_OK) { + LOG_ERR("ConvertTypeToNetCap error!"); + return SOFTBUS_ERR; + } + if (LnnSetLocalNumInfo(NUM_KEY_NET_CAP, (int32_t)cap) != SOFTBUS_OK) { + LOG_ERR("LnnSetLocalNumInfo error!"); + return SOFTBUS_ERR; + } + + if (g_netBuilder.hook[addr->type] != NULL) { + LOG_INFO("LnnServerJoin enter hook"); + return g_netBuilder.hook[addr->type]->preprocess(addr, &g_netBuilder.fsm, NETWORK_TYPE_ACTIVE); + } + return ConnTypeDefaultHook(addr); +} + +int32_t LnnServerLeave(const char *networkId) +{ + char *para = NULL; + + if (networkId == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (g_netBuilder.isInit == false) { + LOG_ERR("no init"); + return SOFTBUS_ERR; + } + para = (char *)SoftBusCalloc(NETWORK_ID_BUF_LEN); + if (para == NULL) { + LOG_ERR("malloc init message fail"); + return SOFTBUS_MALLOC_ERR; + } + if (strncpy_s(para, NETWORK_ID_BUF_LEN, networkId, strlen(networkId)) != EOK) { + LOG_ERR("copy network id fail"); + SoftBusFree(para); + return SOFTBUS_ERR; + } + return LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_LEAVE_LNN, para); +} + +int32_t LnnNotifySyncOfflineFinish() +{ + if (g_netBuilder.isInit == false) { + LOG_ERR("no init"); + return SOFTBUS_ERR; + } + return LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_SYNC_OFFLINE_DONE, NULL); +} + +int32_t LnnNotifySendOfflineMessage(int32_t id) +{ + int32_t *para = NULL; + + if (g_netBuilder.isInit == false) { + LOG_ERR("no init"); + return SOFTBUS_ERR; + } + LOG_INFO("LnnNotifySendOfflineMessage enter!"); + para = (int32_t *)SoftBusCalloc(sizeof(int32_t)); + if (para == NULL) { + LOG_ERR("malloc id message fail"); + return SOFTBUS_MALLOC_ERR; + } + *para = id; + return LnnFsmPostMessage(&g_netBuilder.fsm, FSM_MSG_TYPE_SEND_OFFLINE_MESSAGE, para); +} diff --git a/core/bus_center/lnn/net_builder/src/lnn_network_id.c b/core/bus_center/lnn/net_builder/src/lnn_network_id.c new file mode 100644 index 000000000..42ae2b5ca --- /dev/null +++ b/core/bus_center/lnn/net_builder/src/lnn_network_id.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_network_id.h" + +#include +#include + +#include + +#include "bus_center_info_key.h" +#include "softbus_bus_center.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +static int32_t GenerateRandomId(char *id, int32_t len) +{ + uint32_t hexLen = len / HEXIFY_UNIT_LEN; + uint8_t *hexId = NULL; + + hexId = (uint8_t *)SoftBusMalloc(hexLen); + if (hexId == NULL) { + LOG_ERR("malloc fail"); + return SOFTBUS_MEM_ERR; + } + if (GenerateRandomArray(hexId, hexLen) != SOFTBUS_OK) { + // HUKS will ensure the id is global uniq + LOG_ERR("generate random array fail"); + SoftBusFree(hexId); + return SOFTBUS_ERR; + } + if (ConvertBytesToHexString(id, len, hexId, hexLen) != SOFTBUS_OK) { + LOG_ERR("convert bytes to hex string fail"); + SoftBusFree(hexId); + return SOFTBUS_ERR; + } + SoftBusFree(hexId); + return SOFTBUS_OK; +} + +int32_t LnnGenLocalNetworkId(char *networkId, int32_t len) +{ + if (networkId == NULL || len < NETWORK_ID_BUF_LEN) { + return SOFTBUS_INVALID_PARAM; + } + + if (GenerateRandomId(networkId, NETWORK_ID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("generate network id fail"); + return SOFTBUS_ERR; + } + networkId[len - 1] = '\0'; + return SOFTBUS_OK; +} + +int32_t LnnGenLocalUuid(char *uuid, int32_t len) +{ + static bool isGenerated = false; + static char localUuid[UUID_BUF_LEN] = {0}; + + if (uuid == NULL || len < UUID_BUF_LEN) { + return SOFTBUS_INVALID_PARAM; + } + + if (isGenerated == false) { + if (GenerateRandomId(localUuid, UUID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("generate network id fail"); + return SOFTBUS_ERR; + } + isGenerated = true; + } + if (strncpy_s(uuid, len, localUuid, UUID_BUF_LEN) != EOK) { + LOG_ERR("copy uuid id fail"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/bus_center/lnn/net_builder/src/lnn_state_machine.c b/core/bus_center/lnn/net_builder/src/lnn_state_machine.c new file mode 100644 index 000000000..2b6f5b140 --- /dev/null +++ b/core/bus_center/lnn/net_builder/src/lnn_state_machine.c @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_state_machine.h" + +#include + +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#define FSM_CTRL_MSG_START 0 +#define FSM_CTRL_MSG_CHANGE_STATE 1 +#define FSM_CTRL_MSG_DATA 2 +#define FSM_CTRL_MSG_STOP 3 +#define FSM_CTRL_MSG_DEINIT 4 + +typedef struct { + FsmStateMachine *fsm; + void *obj; +} FsmCtrlMsgObj; + +static bool IsDuplicateState(FsmStateMachine *fsm, FsmState *state) +{ + struct ListNode *item = NULL; + + LIST_FOR_EACH(item, &fsm->stateList) { + if (item == (struct ListNode *)state) { + return true; + } + } + return false; +} + +static void FreeFsmHandleMsg(SoftBusMessage *msg) +{ + if (msg != NULL) { + if (msg->obj != NULL) { + SoftBusFree(msg->obj); + } + SoftBusFree(msg); + } +} + +static void FreeFsmHandleMsgObj(FsmCtrlMsgObj *ctrlMsgObj) +{ + if (ctrlMsgObj == NULL) { + return; + } + if (ctrlMsgObj->obj != NULL) { + SoftBusFree(ctrlMsgObj->obj); + ctrlMsgObj->obj = NULL; + } +} + +static SoftBusMessage *CreateFsmHandleMsg(FsmStateMachine *fsm, + int32_t what, uint64_t arg1, uint64_t arg2, void *obj) +{ + SoftBusMessage *msg = NULL; + FsmCtrlMsgObj *ctrlMsgObj = NULL; + + msg = SoftBusCalloc(sizeof(*msg)); + if (msg == NULL) { + return NULL; + } + msg->what = what; + msg->arg1 = arg1; + msg->arg2 = arg2; + msg->handler = &fsm->handler; + msg->FreeMessage = FreeFsmHandleMsg; + + ctrlMsgObj = SoftBusMalloc(sizeof(*ctrlMsgObj)); + if (ctrlMsgObj == NULL) { + SoftBusFree(msg); + return NULL; + } + ctrlMsgObj->fsm = fsm; + ctrlMsgObj->obj = obj; + msg->obj = ctrlMsgObj; + return msg; +} + +static void ProcessStartMessage(SoftBusMessage *msg) +{ + FsmCtrlMsgObj *ctrlMsgObj = msg->obj; + FsmStateMachine *fsm = NULL; + FsmState *state = NULL; + + if (ctrlMsgObj == NULL) { + return; + } + fsm = ctrlMsgObj->fsm; + state = (FsmState *)ctrlMsgObj->obj; + if (fsm == NULL || state == NULL) { + return; + } + if (fsm->curState != NULL || (fsm->flag & FSM_FLAG_RUNNING) != 0) { + LOG_ERR("unexpected state"); + return; + } + if (IsDuplicateState(fsm, state) == true) { + fsm->curState = state; + if (fsm->curState->enter != NULL) { + fsm->curState->enter(); + } + fsm->flag |= FSM_FLAG_RUNNING; + } +} + +static void ProcessChangeStateMessage(SoftBusMessage *msg) +{ + FsmCtrlMsgObj *ctrlMsgObj = msg->obj; + FsmStateMachine *fsm = NULL; + FsmState *state = NULL; + + if (ctrlMsgObj == NULL) { + return; + } + fsm = ctrlMsgObj->fsm; + state = (FsmState *)ctrlMsgObj->obj; + if (fsm == NULL || state == NULL) { + return; + } + + if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) { + LOG_ERR("unexpected state"); + return; + } + + if (IsDuplicateState(fsm, state)) { + if (fsm->curState->exit != NULL) { + fsm->curState->exit(); + } + fsm->curState = state; + if (fsm->curState->enter != NULL) { + fsm->curState->enter(); + } + } +} + +static void ProcessDataMessage(SoftBusMessage *msg) +{ + FsmCtrlMsgObj *ctrlMsgObj = msg->obj; + FsmStateMachine *fsm = NULL; + + if (ctrlMsgObj == NULL) { + return; + } + fsm = ctrlMsgObj->fsm; + if (fsm == NULL) { + return; + } + if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) { + LOG_ERR("unexpected state"); + return; + } + if (fsm->curState->process != NULL) { + fsm->curState->process((int32_t)msg->arg1, ctrlMsgObj->obj); + } +} + +static void ProcessStopMessage(SoftBusMessage *msg) +{ + FsmCtrlMsgObj *ctrlMsgObj = msg->obj; + FsmStateMachine *fsm = NULL; + + if (ctrlMsgObj == NULL) { + return; + } + fsm = ctrlMsgObj->fsm; + if (fsm == NULL) { + return; + } + if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) { + LOG_ERR("unexpected state"); + return; + } + fsm->curState = NULL; + fsm->flag &= ~FSM_FLAG_RUNNING; +} + +static void ProcessDeinitMessage(SoftBusMessage *msg) +{ + FsmCtrlMsgObj *ctrlMsgObj = msg->obj; + FsmStateMachine *fsm = NULL; + + if (ctrlMsgObj == NULL) { + return; + } + fsm = ctrlMsgObj->fsm; + if (fsm == NULL) { + return; + } + if (fsm->deinitCallback != NULL) { + fsm->deinitCallback(fsm); + } +} + +static void FsmStateMsgHandler(SoftBusMessage *msg) +{ + if (msg == NULL) { + return; + } + + if (msg->what != FSM_CTRL_MSG_DATA) { + LOG_INFO("process fsm ctrl msg: %d", msg->what); + } + switch (msg->what) { + case FSM_CTRL_MSG_START: + ProcessStartMessage(msg); + break; + case FSM_CTRL_MSG_CHANGE_STATE: + ProcessChangeStateMessage(msg); + break; + case FSM_CTRL_MSG_DATA: + ProcessDataMessage(msg); + break; + case FSM_CTRL_MSG_STOP: + ProcessStopMessage(msg); + break; + case FSM_CTRL_MSG_DEINIT: + ProcessDeinitMessage(msg); + break; + default: + break; + } +} + +static int32_t PostMessageToFsm(FsmStateMachine *fsm, int32_t what, uint64_t arg1, uint64_t arg2, void *obj) +{ + SoftBusMessage *msg = NULL; + + msg = CreateFsmHandleMsg(fsm, what, arg1, arg2, obj); + if (msg == NULL) { + LOG_ERR("create fsm handle msg fail"); + return SOFTBUS_ERR; + } + fsm->looper->PostMessage(fsm->looper, msg); + return SOFTBUS_OK; +} + +/* remove message when return 0, else return 1 */ +static int32_t RemoveMessageFunc(const SoftBusMessage *msg, void *para) +{ + int32_t msgType; + + if (msg == NULL || para == NULL) { + return 1; + } + msgType = (int32_t)para; + if (msg->what == FSM_CTRL_MSG_DATA && (int32_t)msg->arg1 == msgType) { + LOG_INFO("remove fsm data message: %d", msgType); + FreeFsmHandleMsgObj((FsmCtrlMsgObj *)msg->obj); + return 0; + } + return 1; +} + +int32_t LnnFsmInit(FsmStateMachine *fsm, char *name, FsmDinitCallback cb) +{ + if (fsm == NULL || name == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + (void)memset_s(fsm, sizeof(*fsm), 0, sizeof(*fsm)); + ListInit(&fsm->stateList); + fsm->looper = GetLooper(LOOP_TYPE_DEFAULT); + if (fsm->looper == NULL) { + LOG_ERR("get looper fail"); + return SOFTBUS_ERR; + } + fsm->handler.name = name; + fsm->handler.HandleMessage = FsmStateMsgHandler; + fsm->handler.looper = fsm->looper; + fsm->deinitCallback = cb; + return SOFTBUS_OK; +} + +int32_t LnnFsmDeinit(FsmStateMachine *fsm) +{ + if (fsm == NULL || fsm->looper == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return PostMessageToFsm(fsm, FSM_CTRL_MSG_DEINIT, 0, 0, NULL); +} + +int32_t LnnFsmAddState(FsmStateMachine *fsm, FsmState *state) +{ + if (fsm == NULL || fsm->looper == NULL || state == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (IsDuplicateState(fsm, state)) { + LOG_ERR("already exist state"); + return SOFTBUS_ERR; + } + ListInit(&state->list); + ListAdd(&fsm->stateList, &state->list); + return SOFTBUS_OK; +} + +int32_t LnnFsmStart(FsmStateMachine *fsm, FsmState *initialState) +{ + if (fsm == NULL || fsm->looper == NULL || initialState == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return PostMessageToFsm(fsm, FSM_CTRL_MSG_START, 0, 0, initialState); +} + +int32_t LnnFsmStop(FsmStateMachine *fsm) +{ + if (fsm == NULL || fsm->looper == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return PostMessageToFsm(fsm, FSM_CTRL_MSG_STOP, 0, 0, NULL); +} + +int32_t LnnFsmPostMessage(FsmStateMachine *fsm, int32_t msgType, void *data) +{ + if (fsm == NULL || fsm->looper == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return PostMessageToFsm(fsm, FSM_CTRL_MSG_DATA, msgType, 0, data); +} + +int32_t LnnFsmPostMessageDelay(FsmStateMachine *fsm, int32_t msgType, + void *data, uint64_t delayMillis) +{ + SoftBusMessage *msg = NULL; + + if (fsm == NULL || fsm->looper == NULL) { + return SOFTBUS_INVALID_PARAM; + } + msg = CreateFsmHandleMsg(fsm, FSM_CTRL_MSG_DATA, msgType, 0, data); + if (msg == NULL) { + LOG_ERR("create fsm handle msg fail"); + return SOFTBUS_ERR; + } + fsm->looper->PostMessageDelay(fsm->looper, msg, delayMillis); + return SOFTBUS_OK; +} + +int32_t LnnFsmRemoveMessage(FsmStateMachine *fsm, int32_t msgType) +{ + if (fsm == NULL || fsm->looper == NULL) { + return SOFTBUS_INVALID_PARAM; + } + fsm->looper->RemoveMessageCustom(fsm->looper, &fsm->handler, + RemoveMessageFunc, (void *)msgType); + return SOFTBUS_OK; +} + +int32_t LnnFsmTransactState(FsmStateMachine *fsm, FsmState *state) +{ + if (fsm == NULL || fsm->looper == NULL || state == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return PostMessageToFsm(fsm, FSM_CTRL_MSG_CHANGE_STATE, 0, 0, state); +} diff --git a/core/bus_center/lnn/net_ledger/common/include/lnn_connect_info.h b/core/bus_center/lnn/net_ledger/common/include/lnn_connect_info.h new file mode 100644 index 000000000..3693e0581 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/include/lnn_connect_info.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_CONNECT_INFO_H +#define LNN_CONNECT_INFO_H + +#include + +#include "bus_center_info_key.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOCAL_IP "127.0.0.1" +#define DEFAULT_IP "" +#define DEFAULT_MAC "" + +typedef struct { + char netIfName[NET_IF_NAME_LEN]; + char deviceIp[IP_MAX_LEN]; + char macAddr[MAC_LEN]; + int authPort; + int proxyPort; + int sessionPort; +} ConnectInfo; + +#ifdef __cplusplus +} +#endif + +#endif // LNN_CONNECT_INFO_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/include/lnn_device_info.h b/core/bus_center/lnn/net_ledger/common/include/lnn_device_info.h new file mode 100644 index 000000000..a9eb007bd --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/include/lnn_device_info.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_DEVICE_INFO_H +#define LNN_DEVICE_INFO_H + +#include + +#include "bus_center_info_key.h" +#include "softbus_bus_center.h" +#include "bus_center_adapter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TYPE_UNKNOW_ID 0x00 +#define TYPE_PHONE_ID 0x0E +#define TYPE_PAD_ID 0x11 +#define TYPE_TV_ID 0x9C +#define TYPE_PC_ID 0x0C +#define TYPE_AUDIO_ID 0x0A +#define TYPE_CAR_ID 0x83 +#define TYPE_WATCH_ID 0x6D +#define TYPE_IPCAMERA_ID 0X08 + +typedef struct { + char deviceName[DEVICE_NAME_BUF_LEN]; + char deviceUdid[UDID_BUF_LEN]; + uint8_t deviceTypeId; +} DeviceBasicInfo; + +int32_t LnnSetDeviceName(DeviceBasicInfo *info, const char *name); +const char *LnnGetDeviceName(const DeviceBasicInfo *info); +int32_t LnnGetDeviceTypeId(const DeviceBasicInfo *info, uint8_t *typeId); +int32_t LnnConvertDeviceTypeToId(const char *deviceType, uint8_t *typeId); +char *LnnConvertIdToDeviceType(uint8_t typeId); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_DEVICE_INFO_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/include/lnn_map.h b/core/bus_center/lnn/net_ledger/common/include/lnn_map.h new file mode 100644 index 000000000..2eec87f51 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/include/lnn_map.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_MAP_H +#define LNN_MAP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * LNN map node struct + */ +typedef struct tagMapNode { + uint32_t hash; + uint32_t valueSize; + void *key; + void *value; + struct tagMapNode *next; +} MapNode; + +/** + * LNN map struct define. + */ +typedef struct { + MapNode **nodes; /* Map node bucket */ + uint32_t nodeSize; /* Map node count */ + uint32_t bucketSize; /* Map node bucket size */ +} Map; + +/** + * LNN map node struct + */ +typedef struct { + MapNode *node; /* Map node */ + uint32_t nodeNum; /* Map node */ + uint32_t bucketNum; /* Map node */ + Map *map; +} MapIterator; + +MapIterator *LnnMapInitIterator(Map *map); +bool LnnMapHasNext(MapIterator *it); +MapIterator *LnnMapNext(MapIterator *it); +void LnnMapDeinitIterator(MapIterator *it); + +/** + * Initialize map + * + * @param : map Map see details in type Map + */ +void LnnMapInit(Map *map); + +/** + * Delete map, free the map memory + * + * @param : map Map see details in type Map + */ +void LnnMapDelete(Map *map); + +/** + * Add map element + * + * @param : map Map see details in type Map + * key Map key + * value Map value + * valueSize Map value size + * @return : SOFTBUS_OK or other error + */ +int32_t LnnMapSet(Map *map, const char *key, const void *value, uint32_t valueSize); + +/** + * Get map value + * + * @param : map Map see details in type Map + * key Map key + * @return : Value of key or NULL + */ +void *LnnMapGet(const Map *map, const char *key); + +/** + * Erase map element + * + * @param : map Map see details in type Map + * key Map key + */ +int32_t LnnMapErase(Map *map, const char *key); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LNN_MAP_H */ \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/include/lnn_net_capability.h b/core/bus_center/lnn/net_ledger/common/include/lnn_net_capability.h new file mode 100644 index 000000000..2c8f5999d --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/include/lnn_net_capability.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_NET_CAPABILITY_H +#define LNN_NET_CAPABILITY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BIT_BLE = 0, + BIT_BR, + BIT_WIFI, + BIT_WIFI_P2P, + BIT_WIFI_24G, + BIT_WIFI_5G, + BIT_ETH, + BIT_COUNT, +} NetCapability; + +uint32_t LnnGetNetCapabilty(void); +int32_t LnnSetNetCapability(uint32_t *capability, NetCapability type); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_NET_CAPABILITY_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/include/lnn_node_info.h b/core/bus_center/lnn/net_ledger/common/include/lnn_node_info.h new file mode 100644 index 000000000..8d1ef5106 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/include/lnn_node_info.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_NODE_INFO_H +#define LNN_NODE_INFO_H + +#include +#include + +#include "lnn_connect_info.h" +#include "lnn_device_info.h" +#include "lnn_net_capability.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ROLE_UNKNOWN = 0, + ROLE_CONTROLLER, + ROLE_LEAF, +} ConnectRole; + +typedef enum { + STATUS_OFFLINE = 0, + STATUS_ONLINE, +} ConnectStatus; + +typedef enum { + DISCOVERY_TYPE_UNKNOWN = 0, + DISCOVERY_TYPE_WIFI, + DISCOVERY_TYPE_BLE, + DISCOVERY_TYPE_BR, + DISCOVERY_TYPE_P2P, + DISCOVERY_TYPE_COUNT, +} DiscoveryType; + +typedef struct { + char softBusVersion[VERSION_MAX_LEN]; + char versionType[VERSION_MAX_LEN]; // compatible nearby + char uuid[UUID_BUF_LEN]; // compatible nearby + char networkId[NETWORK_ID_BUF_LEN]; + char publicId[ID_MAX_LEN]; + char parentId[ID_MAX_LEN]; + uint32_t weight; + ConnectRole role; + ConnectStatus status; + uint32_t netCapacity; + uint32_t discoveryType; + int64_t authSeqNum; + DeviceBasicInfo deviceInfo; + ConnectInfo connectInfo; +} NodeInfo; + +const char *LnnGetDeviceUdid(const NodeInfo *info); +int32_t LnnSetDeviceUdid(NodeInfo *info, const char *udid); +bool LnnHasDiscoveryType(const NodeInfo *info, DiscoveryType type); +int32_t LnnSetDiscoveryType(NodeInfo *info, DiscoveryType type); +bool LnnIsNodeOnline(const NodeInfo *info); +void LnnSetNodeConnStatus(NodeInfo *info, ConnectStatus status); +const char *LnnGetBtMac(const NodeInfo *info); +void LnnSetBtMac(NodeInfo *info, const char *mac); +const char *LnnGetWiFiIp(const NodeInfo *info); +void LnnSetWiFiIp(NodeInfo *info, const char *ip); +const char *LnnGetNetIfName(const NodeInfo *info); +void LnnSetNetIfName(NodeInfo *info, const char *netIfName); +int32_t LnnGetAuthPort(const NodeInfo *info); +int32_t LnnSetAuthPort(NodeInfo *info, int32_t port); +int32_t LnnGetSessionPort(const NodeInfo *info); +int32_t LnnSetSessionPort(NodeInfo *info, int32_t port); +int32_t LnnGetProxyPort(const NodeInfo *info); +int32_t LnnSetProxyPort(NodeInfo *info, int32_t port); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_NODE_INFO_H diff --git a/core/bus_center/lnn/net_ledger/common/src/lnn_device_info.c b/core/bus_center/lnn/net_ledger/common/src/lnn_device_info.c new file mode 100644 index 000000000..107b9b782 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/src/lnn_device_info.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_device_info.h" + +#include +#include + +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" + +typedef struct { + char *type; + uint8_t id; +} TypeToId; + +static TypeToId g_typeToIdMap[] = { + {TYPE_UNKNOWN, TYPE_UNKNOW_ID}, + {TYPE_PHONE, TYPE_PHONE_ID}, + {TYPE_PAD, TYPE_PAD_ID}, + {TYPE_TV, TYPE_TV_ID}, + {TYPE_PC, TYPE_PC_ID}, + {TYPE_CAR, TYPE_CAR_ID}, + {TYPE_WATCH, TYPE_WATCH_ID}, + {TYPE_IPCAMERA, TYPE_IPCAMERA_ID}, +}; + +const char *LnnGetDeviceName(const DeviceBasicInfo *info) +{ + if (info == NULL) { + LOG_ERR("LnnGetDeviceName para error."); + return NULL; + } + return info->deviceName; +} + +int32_t LnnSetDeviceName(DeviceBasicInfo *info, const char *name) +{ + if (info == NULL || name == NULL || strlen(name) > DEVICE_NAME_BUF_LEN - 1) { + LOG_ERR("LnnSetDeviceName para error."); + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(info->deviceName, DEVICE_NAME_BUF_LEN, name, strlen(name)) != EOK) { + LOG_ERR("%s fail:strncpy_s fail!", __func__); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +int32_t LnnGetDeviceTypeId(const DeviceBasicInfo *info, uint8_t *typeId) +{ + if (info == NULL || typeId == NULL) { + LOG_ERR("LnnGetDeviceTypeId para error."); + return SOFTBUS_INVALID_PARAM; + } + *typeId = info->deviceTypeId; + return SOFTBUS_OK; +} + +int32_t LnnConvertDeviceTypeToId(const char *deviceType, uint8_t *typeId) +{ + if (deviceType == NULL || typeId == NULL) { + LOG_ERR("LnnConvertDeviceTypeToId para error."); + return SOFTBUS_INVALID_PARAM; + } + int count = sizeof(g_typeToIdMap) / sizeof(TypeToId); + for (int i = 0; i < count; i++) { + if (strcmp(g_typeToIdMap[i].type, deviceType) == 0) { + *typeId = g_typeToIdMap[i].id; + return SOFTBUS_OK; + } + } + *typeId = TYPE_UNKNOW_ID; + return SOFTBUS_ERR; +} + +char *LnnConvertIdToDeviceType(uint8_t typeId) +{ + int count = sizeof(g_typeToIdMap) / sizeof(TypeToId); + for (int i = 0; i < count; i++) { + if (g_typeToIdMap[i].id == typeId) { + return g_typeToIdMap[i].type; + } + } + LOG_ERR("typeId not exist"); + return NULL; +} diff --git a/core/bus_center/lnn/net_ledger/common/src/lnn_map.c b/core/bus_center/lnn/net_ledger/common/src/lnn_map.c new file mode 100644 index 000000000..19ab1c730 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/src/lnn_map.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_map.h" + +#include +#include + +#include + +#include "softbus_errcode.h" +#include "softbus_mem_interface.h" + +#define HDF_MIN_MAP_SIZE 8 +#define HDF_ENLARGE_FACTOR 2 +#define HDF_MAP_KEY_MAX_SIZE 1000 +#define HDF_MAP_VALUE_MAX_SIZE 1000 + +/* BKDR Hash */ +static uint32_t MapHash(const char *key) +{ + uint32_t hash = 0; + const uint32_t seed = 131; + if (key == NULL) { + return 0; + } + uint32_t len = strlen(key); + for (uint32_t i = 0; i < len; i++) { + hash = (hash * seed) + (*key++); + } + + return (hash & 0x7FFFFFFF); +} + +static uint32_t MapHashIdx(const Map *map, uint32_t hash) +{ + return (hash & (map->bucketSize - 1)); +} + +static void MapAddNode(Map *map, MapNode *node) +{ + uint32_t idx = MapHashIdx(map, node->hash); + node->next = map->nodes[idx]; + map->nodes[idx] = node; +} + +static int32_t MapResize(Map *map, uint32_t size) +{ + uint32_t bucketSize; + MapNode **nodes = NULL; + MapNode **tmp = NULL; + + nodes = (MapNode **)SoftBusCalloc(size * sizeof(*nodes)); + if (nodes == NULL) { + return SOFTBUS_MEM_ERR; + } + + tmp = map->nodes; + bucketSize = map->bucketSize; + map->nodes = nodes; + map->bucketSize = size; + + if (tmp != NULL) { + MapNode *node = NULL; + MapNode *next = NULL; + + /* remap node with new map size */ + for (uint32_t i = 0; i < bucketSize; i++) { + node = tmp[i]; + while (node != NULL) { + next = node->next; + MapAddNode(map, node); + node = next; + } + } + SoftBusFree(tmp); + } + return SOFTBUS_OK; +} + +static MapNode *MapCreateNode(const char *key, uint32_t hash, + const void *value, uint32_t valueSize) +{ + uint32_t keySize = strlen(key) + 1; + MapNode *node = (MapNode *)SoftBusCalloc(sizeof(*node) + keySize + valueSize); + if (node == NULL) { + return NULL; + } + + node->hash = hash; + node->key = (uint8_t *)node + sizeof(*node); + node->value = (uint8_t *)node + sizeof(*node) + keySize; + node->valueSize = valueSize; + if (memcpy_s(node->key, keySize, key, keySize) != EOK) { + SoftBusFree(node); + return NULL; + } + if (memcpy_s(node->value, node->valueSize, value, valueSize) != EOK) { + SoftBusFree(node); + return NULL; + } + return node; +} + +/** + * Add map element + * + * @param : map Map see details in type Map + * key Map key + * value Map value + * valueSize Map value size + * @return : SOFTBUS_OK or other error + */ +int32_t LnnMapSet(Map *map, const char *key, const void *value, uint32_t valueSize) +{ + MapNode *node = NULL; + + if (map == NULL || key == NULL || value == NULL || valueSize == 0) { + return SOFTBUS_INVALID_PARAM; + } + if (valueSize > HDF_MAP_KEY_MAX_SIZE || strlen(key) > HDF_MAP_VALUE_MAX_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + uint32_t hash = MapHash(key); + if (map->nodeSize > 0 && map->nodes != NULL) { + uint32_t idx = MapHashIdx(map, hash); + node = map->nodes[idx]; + while (node != NULL) { + if (node->hash != hash || node->key == NULL || strcmp(node->key, key) != 0) { + node = node->next; + continue; + } + + // size unmatch + if (node->value == NULL || node->valueSize != valueSize) { + return SOFTBUS_INVALID_PARAM; + } + // update k-v node + if (memcpy_s(node->value, node->valueSize, value, valueSize) != EOK) { + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; + } + } + // for decreasing map search conflict, enlarge bucket Size + if (map->nodeSize >= map->bucketSize) { + uint32_t size = (map->bucketSize < HDF_MIN_MAP_SIZE) ? HDF_MIN_MAP_SIZE : \ + (map->bucketSize << HDF_ENLARGE_FACTOR); + MapResize(map, size); + } + + node = MapCreateNode(key, hash, value, valueSize); + if (node == NULL) { + return SOFTBUS_INVALID_PARAM; + } + MapAddNode(map, node); + map->nodeSize++; + + return SOFTBUS_OK; +} + +/** + * Get map value api + * + * @param : map Map see details in type Map + * key Map key + * @return : value of key or NULL + */ +void* LnnMapGet(const Map *map, const char *key) +{ + if (map == NULL || key == NULL || map->nodeSize == 0 || map->nodes == NULL) { + return NULL; + } + + uint32_t hash = MapHash(key); + uint32_t idx = MapHashIdx(map, hash); + MapNode *node = map->nodes[idx]; + + while (node != NULL) { + if (node->hash == hash && node->key != NULL && !strcmp(node->key, key)) { + return node->value; + } + + node = node->next; + } + + return NULL; +} + +/** + * Erase map node + * + * @param : map Map see details in type Map + * key Map key + */ +int32_t LnnMapErase(Map *map, const char *key) +{ + if (map == NULL || key == NULL || map->nodeSize == 0 || map->nodes == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + uint32_t hash = MapHash(key); + uint32_t idx = MapHashIdx(map, hash); + MapNode *node = map->nodes[idx]; + MapNode *prev = node; + + while (node != NULL) { + if (node->hash == hash && node->key != NULL && !strcmp(node->key, key)) { + if (map->nodes[idx] == node) { + map->nodes[idx] = node->next; + } else { + prev->next = node->next; + } + SoftBusFree(node); + map->nodeSize--; + return SOFTBUS_OK; + } + prev = node; + node = node->next; + } + + return SOFTBUS_ERR; +} + +uint32_t MapGetSize(Map *map) +{ + return (map == NULL) ? 0 : map->nodeSize; +} +/** + * initialize map + * + * @param : map Map see details in type Map + */ +void LnnMapInit(Map *map) +{ + if (map == NULL) { + return; + } + + map->nodes = NULL; + map->nodeSize = 0; + map->bucketSize = 0; +} + +/** + * delete map, free the map memory + * + * @param : map Map see details in type Map + */ +void LnnMapDelete(Map *map) +{ + uint32_t i; + MapNode *node = NULL; + MapNode *next = NULL; + + if (map == NULL || map->nodes == NULL) { + return; + } + + for (i = 0; i < map->bucketSize; i++) { + node = map->nodes[i]; + while (node != NULL) { + next = node->next; + SoftBusFree(node); + node = next; + } + } + + SoftBusFree(map->nodes); + + map->nodes = NULL; + map->nodeSize = 0; + map->bucketSize = 0; +} + +/** + * init LNN map iterator + * + * @param : map Map see details in type Map + */ +MapIterator *LnnMapInitIterator(Map *map) +{ + MapIterator *it = NULL; + if (map == NULL) { + return NULL; + } + it = (MapIterator *)SoftBusCalloc(sizeof(MapIterator)); + if (it == NULL) { + return NULL; + } + it->node = NULL; + it->bucketNum = 0; + it->nodeNum = 0; + it->map = map; + return it; +} + +/** + * Have a next element + * + * @param : it Iterator see details in type Iterator + */ +bool LnnMapHasNext(MapIterator *it) +{ + return (it->nodeNum < it->map->nodeSize); +} + +/** + * Get next iterator API + * + * @param : it Iterator see details in type Iterator + */ +MapIterator *LnnMapNext(MapIterator *it) +{ + MapNode *node = NULL; + if (it == NULL) { + return NULL; + } + if (LnnMapHasNext(it)) { + if (it->node != NULL && it->node->next != NULL) { + it->nodeNum++; + it->node = it->node->next; + return it; + } + while (it->bucketNum < it->map->bucketSize) { + node = it->map->nodes[it->bucketNum]; + it->bucketNum++; + if (node != NULL) { + it->nodeNum++; + it->node = node; + return it; + } + } + } + return it; +} + +/** + * deinit iterator and free memory API + * + * @param : it Iterator see details in type Iterator + */ +void LnnMapDeinitIterator(MapIterator *it) +{ + if (it == NULL) { + return; + } + SoftBusFree(it); +} \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/src/lnn_net_capability.c b/core/bus_center/lnn/net_ledger/common/src/lnn_net_capability.c new file mode 100644 index 000000000..f3ef7fa6b --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/src/lnn_net_capability.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_net_capability.h" + +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" + +int32_t LnnSetNetCapability(uint32_t *capability, NetCapability type) +{ + if (capability == NULL || type >= BIT_COUNT) { + LOG_ERR("in para error!"); + return SOFTBUS_INVALID_PARAM; + } + *capability = (*capability) | (1 << (uint32_t)type); + return SOFTBUS_OK; +} + +uint32_t LnnGetNetCapabilty(void) +{ + uint32_t capability = 0; + capability = capability | (1 << BIT_BR); + return capability; +} \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/common/src/lnn_node_info.c b/core/bus_center/lnn/net_ledger/common/src/lnn_node_info.c new file mode 100644 index 000000000..e27d13001 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/common/src/lnn_node_info.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_node_info.h" + +#include + +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" + +bool LnnHasDiscoveryType(const NodeInfo *info, DiscoveryType type) +{ + if (info == NULL || type >= DISCOVERY_TYPE_COUNT) { + LOG_ERR("para error!"); + return false; + } + if (((uint32_t)info->discoveryType & (1 << (uint32_t)type)) != 0) { + return true; + } + return false; +} + +const char *LnnGetDeviceUdid(const NodeInfo *info) +{ + if (info == NULL) { + return NULL; + } + return info->deviceInfo.deviceUdid; +} + +int32_t LnnSetDeviceUdid(NodeInfo *info, const char *udid) +{ + if (info == NULL || udid == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(info->deviceInfo.deviceUdid, UDID_BUF_LEN, udid, strlen(udid)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +int32_t LnnSetDiscoveryType(NodeInfo *info, DiscoveryType type) +{ + if (info == NULL || type >= DISCOVERY_TYPE_COUNT) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + info->discoveryType = (uint32_t)info->discoveryType | (1 << (uint32_t)type); + return SOFTBUS_OK; +} + +bool LnnIsNodeOnline(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return false; + } + return (info->status == STATUS_ONLINE); +} + +void LnnSetNodeConnStatus(NodeInfo *info, ConnectStatus status) +{ + if (info == NULL) { + LOG_ERR("para error!!!"); + return; + } + info->status = status; +} + +const char *LnnGetBtMac(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return DEFAULT_MAC; + } + return info->connectInfo.macAddr; +} + +void LnnSetBtMac(NodeInfo *info, const char *mac) +{ + if (info == NULL || mac == NULL) { + LOG_ERR("PARA ERROR!"); + return; + } + if (strncpy_s(info->connectInfo.macAddr, MAC_LEN, mac, strlen(mac)) != EOK) { + LOG_ERR("str copy error!"); + } + return; +} + +const char *LnnGetNetIfName(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return DEFAULT_MAC; + } + return info->connectInfo.netIfName; +} + +void LnnSetNetIfName(NodeInfo *info, const char *netIfName) +{ + if (info == NULL || netIfName == NULL) { + LOG_ERR("PARA ERROR!"); + return; + } + if (strncpy_s(info->connectInfo.netIfName, NET_IF_NAME_LEN, netIfName, strlen(netIfName)) != EOK) { + LOG_ERR("str copy error!"); + } + return; +} + +const char *LnnGetWiFiIp(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("PARA error!"); + return DEFAULT_IP; + } + return info->connectInfo.deviceIp; +} + +void LnnSetWiFiIp(NodeInfo *info, const char *ip) +{ + if (info == NULL || ip == NULL) { + LOG_ERR("PARA ERROR!"); + return; + } + if (strncpy_s(info->connectInfo.deviceIp, IP_MAX_LEN, ip, strlen(ip)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + } + return; +} + +int32_t LnnGetAuthPort(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error"); + return SOFTBUS_INVALID_PARAM; + } + return info->connectInfo.authPort; +} + +int32_t LnnSetAuthPort(NodeInfo *info, int32_t port) +{ + if (info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + info->connectInfo.authPort = port; + return SOFTBUS_OK; +} + +int32_t LnnGetSessionPort(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + return info->connectInfo.sessionPort; +} + +int32_t LnnSetSessionPort(NodeInfo *info, int32_t port) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + info->connectInfo.sessionPort = port; + return SOFTBUS_OK; +} + +int32_t LnnGetProxyPort(const NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + return info->connectInfo.proxyPort; +} + +int32_t LnnSetProxyPort(NodeInfo *info, int32_t port) +{ + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_OK; + } + info->connectInfo.proxyPort = port; + return SOFTBUS_OK; +} diff --git a/core/bus_center/lnn/net_ledger/distributed_ledger/include/lnn_distributed_net_ledger.h b/core/bus_center/lnn/net_ledger/distributed_ledger/include/lnn_distributed_net_ledger.h new file mode 100644 index 000000000..dbdc6581a --- /dev/null +++ b/core/bus_center/lnn/net_ledger/distributed_ledger/include/lnn_distributed_net_ledger.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_DISTRIBUTED_NET_LEDGER_H +#define LNN_DISTRIBUTED_NET_LEDGER_H + +#include +#include + +#include "bus_center_info_key.h" +#include "lnn_node_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INT_TO_STR_SIZE 12 +#define INVALID_CONNECTION_CODE_VALUE -1 + +typedef struct { + InfoKey key; + int32_t (*getInfo)(const char *netWorkId, void *info, uint32_t len); +} DistributedLedgerKey; + +typedef enum { + CATEGORY_UDID, + CATEGORY_UUID, + CATEGORY_NETWORK_ID, +} IdCategory; + +int32_t LnnInitDistributedLedger(void); +void LnnDeinitDistributedLedger(void); +void LnnAddOnlineNode(NodeInfo *info); +void LnnSetNodeOffline(const char *udid); +void LnnRemoveNode(const char *udid); +NodeInfo *LnnGetNodeInfoById(const char *id, IdCategory type); +bool LnnSetDLDeviceInfoName(const char *udid, const char *name); +const char *LnnConvertDLidToUdid(const char *id, IdCategory type); +int32_t LnnGetDLStrInfo(const char *networkId, InfoKey key, char *info, uint32_t len); +int32_t LnnGetDLNumInfo(const char *networkId, InfoKey key, int32_t *info); +short LnnGetCnnCode(const char *uuid, DiscoveryType type); +int32_t LnnGetDistributedNodeInfo(NodeBasicInfo **info, int32_t *infoNum); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_DISTRIBUTED_NET_LEDGER_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c b/core/bus_center/lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c new file mode 100644 index 000000000..b66f9fa38 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c @@ -0,0 +1,945 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_distributed_net_ledger.h" + +#include +#include +#include + +#include + +#include "bus_center_event.h" +#include "lnn_map.h" +#include "softbus_bus_center.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +#define NUM_BUF_SIZE 4 +#define RETURN_IF_GET_NODE_VALID(networkId, buf, info) do { \ + if ((networkId) == NULL || (buf) == NULL) { \ + return SOFTBUS_INVALID_PARAM; \ + } \ + (info) = LnnGetNodeInfoById((networkId), (CATEGORY_NETWORK_ID)); \ + if ((info) == NULL) { \ + LOG_ERR("get node info fail."); \ + return SOFTBUS_ERR; \ + } \ + } while (0) \ + +typedef struct { + Map udidMap; + Map ipMap; + Map macMap; +} DoubleHashMap; + +typedef enum { + DL_INIT_UNKNOWN = 0, + DL_INIT_FAIL, + DL_INIT_SUCCESS, +} DistributedLedgerStatus; + +typedef struct { + Map connectionCode; +} ConnectionCode; + +typedef struct { + DoubleHashMap distributedInfo; + ConnectionCode cnnCode; + int countMax; + pthread_mutex_t lock; + DistributedLedgerStatus status; +} DistributedNetLedger; + +static DistributedNetLedger g_distributedNetLedger; + +static NodeInfo *GetNodeInfoFromMap(const DoubleHashMap *map, const char *id) +{ + if (map == NULL || id == NULL) { + LOG_ERR("para error!"); + return NULL; + } + NodeInfo *info = NULL; + if ((info = (NodeInfo *)LnnMapGet(&map->udidMap, id)) != NULL) { + return info; + } + if ((info = (NodeInfo *)LnnMapGet(&map->macMap, id)) != NULL) { + return info; + } + if ((info = (NodeInfo *)LnnMapGet(&map->ipMap, id)) != NULL) { + return info; + } + LOG_ERR("id not exist!"); + return NULL; +} + +static int32_t InitDistributedInfo(DoubleHashMap *map) +{ + if (map == NULL) { + LOG_ERR("fail:para error!"); + return SOFTBUS_INVALID_PARAM; + } + LnnMapInit(&map->udidMap); + LnnMapInit(&map->ipMap); + LnnMapInit(&map->macMap); + return SOFTBUS_OK; +} + +static void DeinitDistributedInfo(DoubleHashMap *map) +{ + if (map == NULL) { + LOG_ERR("fail: para error!"); + return; + } + LnnMapDelete(&map->udidMap); + LnnMapDelete(&map->ipMap); + LnnMapDelete(&map->macMap); +} + +static int32_t InitConnectionCode(ConnectionCode *cnnCode) +{ + if (cnnCode == NULL) { + LOG_ERR("fail: para error!"); + return SOFTBUS_INVALID_PARAM; + } + LnnMapInit(&cnnCode->connectionCode); + return SOFTBUS_OK; +} + +static void DeinitConnectionCode(ConnectionCode *cnnCode) +{ + if (cnnCode == NULL) { + LOG_ERR("fail: para error!"); + return; + } + LnnMapDelete(&cnnCode->connectionCode); + return; +} + +int32_t LnnInitDistributedLedger(void) +{ + if (g_distributedNetLedger.status == DL_INIT_SUCCESS) { + LOG_INFO("Distributed Ledger already init"); + return SOFTBUS_OK; + } + + if (InitDistributedInfo(&g_distributedNetLedger.distributedInfo) != SOFTBUS_OK) { + LOG_ERR("InitDistributedInfo ERROR!"); + g_distributedNetLedger.status = DL_INIT_FAIL; + return SOFTBUS_ERR; + } + + if (InitConnectionCode(&g_distributedNetLedger.cnnCode) != SOFTBUS_OK) { + LOG_ERR("InitConnectionCode ERROR!"); + g_distributedNetLedger.status = DL_INIT_FAIL; + return SOFTBUS_ERR; + } + + if (pthread_mutex_init(&g_distributedNetLedger.lock, NULL) != 0) { + g_distributedNetLedger.status = DL_INIT_FAIL; + return SOFTBUS_ERR; + } + g_distributedNetLedger.status = DL_INIT_SUCCESS; + return SOFTBUS_OK; +} + +void LnnDeinitDistributedLedger(void) +{ + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + g_distributedNetLedger.status = DL_INIT_UNKNOWN; + DeinitDistributedInfo(&g_distributedNetLedger.distributedInfo); + DeinitConnectionCode(&g_distributedNetLedger.cnnCode); + if (pthread_mutex_unlock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("unlock mutex fail!"); + } + pthread_mutex_destroy(&g_distributedNetLedger.lock); +} + +static void NewWifiDiscovered(const NodeInfo *oldInfo, NodeInfo *newInfo) +{ + const char *macAddr = NULL; + if (oldInfo == NULL || newInfo == NULL) { + LOG_ERR("para error!"); + return; + } + newInfo->discoveryType = newInfo->discoveryType | oldInfo->discoveryType; + macAddr = LnnGetBtMac(newInfo); + if (macAddr == NULL) { + LOG_ERR("LnnGetBtMac Fail!"); + return; + } + if (strcmp(macAddr, DEFAULT_MAC) == 0) { + LnnSetBtMac(newInfo, LnnGetBtMac(oldInfo)); + } +} + +static void NewBrBleDiscovered(const NodeInfo *oldInfo, NodeInfo *newInfo) +{ + const char *ipAddr = NULL; + if (oldInfo == NULL || newInfo == NULL) { + LOG_ERR("para error!"); + return; + } + newInfo->discoveryType = newInfo->discoveryType | oldInfo->discoveryType; + ipAddr = LnnGetWiFiIp(newInfo); + if (ipAddr == NULL) { + LOG_ERR("LnnGetWiFiIp Fail!"); + return; + } + if (strcmp(ipAddr, DEFAULT_IP) == 0) { + LnnSetWiFiIp(newInfo, LnnGetWiFiIp(oldInfo)); + } +} + +static int32_t ConvertNodeInfoToBasicInfo(const NodeInfo *info, NodeBasicInfo *basic) +{ + if (info == NULL || basic == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(basic->deviceName, DEVICE_NAME_BUF_LEN, info->deviceInfo.deviceName, + strlen(info->deviceInfo.deviceName)) != EOK) { + LOG_ERR("strncpy_s name error!"); + return SOFTBUS_MEM_ERR; + } + + if (strncpy_s(basic->networkId, NETWORK_ID_BUF_LEN, info->networkId, strlen(info->networkId)) != EOK) { + LOG_ERR("strncpy_s networkID error!"); + return SOFTBUS_MEM_ERR; + } + basic->deviceTypeId = info->deviceInfo.deviceTypeId; + return SOFTBUS_OK; +} + +static int32_t GetDLOnlineNodeNumLocked(int32_t *infoNum) +{ + NodeInfo *info = NULL; + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + MapIterator *it = LnnMapInitIterator(&map->udidMap); + + if (it == NULL) { + return SOFTBUS_ERR; + } + *infoNum = 0; + while (LnnMapHasNext(it)) { + it = LnnMapNext(it); + if (it == NULL) { + return SOFTBUS_ERR; + } + info = (NodeInfo *)it->node->value; + if (LnnIsNodeOnline(info)) { + (*infoNum)++; + } + } + LnnMapDeinitIterator(it); + return SOFTBUS_OK; +} + +static int32_t FillDLOnlineNodeInfoLocked(NodeBasicInfo **info, int32_t infoNum) +{ + NodeInfo *nodeInfo = NULL; + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + MapIterator *it = LnnMapInitIterator(&map->udidMap); + int32_t i = 0; + + if (it == NULL) { + LOG_ERR("it is null"); + return SOFTBUS_ERR; + } + while (LnnMapHasNext(it) && i < infoNum) { + it = LnnMapNext(it); + if (it == NULL) { + LnnMapDeinitIterator(it); + return SOFTBUS_ERR; + } + nodeInfo = (NodeInfo *)it->node->value; + if (LnnIsNodeOnline(nodeInfo)) { + ConvertNodeInfoToBasicInfo(nodeInfo, info[i++]); + } + } + LnnMapDeinitIterator(it); + return SOFTBUS_OK; +} + +static int32_t PostDeviceBasicInfoChanged(const NodeInfo *info, NodeBasicInfoType type) +{ + NodeBasicInfo basic; + if (memset_s(&basic, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)) != EOK) { + LOG_ERR("memset_s basic fail!"); + } + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (ConvertNodeInfoToBasicInfo(info, &basic) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + LnnNotifyBasicInfoChanged(&basic, type); + return SOFTBUS_OK; +} + +static int32_t PostOnline(NodeBasicInfo *basic) +{ + if (basic == NULL) { + return SOFTBUS_INVALID_PARAM; + } + LnnNotifyOnlineState(true, basic); + return SOFTBUS_OK; +} + +static int32_t PostOffline(NodeBasicInfo *basic) +{ + if (basic == NULL) { + return SOFTBUS_INVALID_PARAM; + } + LnnNotifyOnlineState(false, basic); + return SOFTBUS_OK; +} + +static int32_t PostToClient(const NodeInfo *info, ConnectStatus status) +{ + NodeBasicInfo basic; + if (memset_s(&basic, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)) != EOK) { + LOG_ERR("memset_s basic fail!"); + } + if (info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (ConvertNodeInfoToBasicInfo(info, &basic) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + if (status == STATUS_ONLINE) { + PostOnline(&basic); + } else if (status == STATUS_OFFLINE) { + PostOffline(&basic); + } else { + LOG_ERR("status error!"); + } + + return SOFTBUS_OK; +} + +static bool IsNetworkIdChanged(NodeInfo *newInfo, NodeInfo *oldInfo) +{ + if (newInfo == NULL || oldInfo == NULL) { + LOG_ERR("para error!"); + return false; + } + if (strcmp(newInfo->networkId, oldInfo->networkId) == 0) { + return false; + } + return true; +} + +void PostOnlineNodesToCb(const INodeStateCb *callBack) +{ + NodeInfo *info = NULL; + NodeBasicInfo basic; + if (memset_s(&basic, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)) != EOK) { + LOG_ERR("memset_s basic fail!"); + } + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + if (callBack->onNodeOnline == NULL) { + LOG_ERR("onNodeOnline IS null!"); + return; + } + MapIterator *it = LnnMapInitIterator(&map->udidMap); + if (it == NULL) { + return; + } + while (LnnMapHasNext(it)) { + it = LnnMapNext(it); + if (it == NULL) { + return; + } + info = (NodeInfo *)it->node->value; + if (LnnIsNodeOnline(info)) { + ConvertNodeInfoToBasicInfo(info, &basic); + callBack->onNodeOnline(&basic); + } + } + LnnMapDeinitIterator(it); +} + +NodeInfo *LnnGetNodeInfoById(const char *id, IdCategory type) +{ + NodeInfo *info = NULL; + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + if (id == NULL) { + LOG_ERR("para error"); + return info; + } + if (type == CATEGORY_UDID) { + return GetNodeInfoFromMap(map, id); + } + MapIterator *it = LnnMapInitIterator(&map->udidMap); + if (it == NULL) { + return info; + } + while (LnnMapHasNext(it)) { + it = LnnMapNext(it); + if (it == NULL) { + return info; + } + info = (NodeInfo *)it->node->value; + if (info == NULL) { + continue; + } + if (type == CATEGORY_NETWORK_ID) { + if (strcmp(info->networkId, id) == 0) { + LnnMapDeinitIterator(it); + return info; + } + } else if (type == CATEGORY_UUID) { + if (strcmp(info->uuid, id) == 0) { + LnnMapDeinitIterator(it); + return info; + } + } else { + LOG_ERR("type error"); + } + } + LnnMapDeinitIterator(it); + return NULL; +} + +static int32_t DlGetDeviceUuid(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + if (strncpy_s(buf, len, info->uuid, strlen(info->uuid)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetDeviceUdid(const char *networkId, void *buf, uint32_t len) +{ + const char *udid = NULL; + NodeInfo *info = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + udid = LnnGetDeviceUdid(info); + if (udid == NULL) { + LOG_ERR("get device udid fail"); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, udid, strlen(udid)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetNodeSoftBusVersion(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + if (strncpy_s(buf, len, info->softBusVersion, strlen(info->softBusVersion)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetDeviceType(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + char *deviceType = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + deviceType = LnnConvertIdToDeviceType(info->deviceInfo.deviceTypeId); + if (deviceType == NULL) { + LOG_ERR("deviceType fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, deviceType, strlen(deviceType)) != EOK) { + LOG_ERR("MEM COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetDeviceName(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + const char *deviceName = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + deviceName = LnnGetDeviceName(&info->deviceInfo); + if (deviceName == NULL) { + LOG_ERR("get device name fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, deviceName, strlen(deviceName)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetBtMac(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + const char *mac = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + mac = LnnGetBtMac(info); + if (mac == NULL) { + LOG_ERR("get bt mac fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, mac, strlen(mac)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetWlanIp(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + const char *ip = NULL; + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + ip = LnnGetWiFiIp(info); + if (ip == NULL) { + LOG_ERR("get wifi ip fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, ip, strlen(ip)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t DlGetAuthPort(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + if (len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + *((int32_t *)buf) = LnnGetAuthPort(info); + return SOFTBUS_OK; +} + +static int32_t DlGetSessionPort(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + if (len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + *((int32_t *)buf) = LnnGetSessionPort(info); + return SOFTBUS_OK; +} + +static int32_t DlGetProxyPort(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + if (len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + *((int32_t *)buf) = LnnGetProxyPort(info); + return SOFTBUS_OK; +} + +static int32_t DlGetNetCap(const char *networkId, void *buf, uint32_t len) +{ + NodeInfo *info = NULL; + if (len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + RETURN_IF_GET_NODE_VALID(networkId, buf, info); + *((int32_t *)buf) = info->netCapacity; + return SOFTBUS_OK; +} + +static DistributedLedgerKey g_dlKeyTable[] = { + {STRING_KEY_HICE_VERSION, DlGetNodeSoftBusVersion}, + {STRING_KEY_DEV_UDID, DlGetDeviceUdid}, + {STRING_KEY_UUID, DlGetDeviceUuid}, + {STRING_KEY_DEV_TYPE, DlGetDeviceType}, + {STRING_KEY_DEV_NAME, DlGetDeviceName}, + {STRING_KEY_BT_MAC, DlGetBtMac}, + {STRING_KEY_WLAN_IP, DlGetWlanIp}, + {NUM_KEY_SESSION_PORT, DlGetSessionPort}, + {NUM_KEY_AUTH_PORT, DlGetAuthPort}, + {NUM_KEY_PROXY_PORT, DlGetProxyPort}, + {NUM_KEY_NET_CAP, DlGetNetCap}, +}; + +static char *CreateCnnCodeKey(const char *uuid, DiscoveryType type) +{ + if (uuid == NULL || strlen(uuid) >= UUID_BUF_LEN) { + LOG_ERR("para error!"); + return NULL; + } + char *key = (char *)SoftBusCalloc(INT_TO_STR_SIZE + UUID_BUF_LEN); + if (key == NULL) { + LOG_ERR("SoftBusCalloc fail!"); + return NULL; + } + if (sprintf_s(key, INT_TO_STR_SIZE + UUID_BUF_LEN, "%d%s", type, uuid) == -1) { + LOG_ERR("type convert char error!"); + goto EXIT_FAIL; + } + return key; +EXIT_FAIL: + SoftBusFree(key); + return NULL; +} + +static void DestroyCnnCodeKey(char *key) +{ + if (key == NULL) { + return; + } + SoftBusFree(key); +} + + +static int32_t AddCnnCode(Map *cnnCode, const char *uuid, DiscoveryType type, int64_t authSeqNum) +{ + short seq = (short)authSeqNum; + char *key = CreateCnnCodeKey(uuid, type); + if (key == NULL) { + LOG_ERR("CreateCnnCodeKey error!"); + return SOFTBUS_ERR; + } + if (LnnMapSet(cnnCode, key, (void *)&seq, sizeof(short)) != SOFTBUS_OK) { + LOG_ERR("LnnMapSet error!"); + DestroyCnnCodeKey(key); + return SOFTBUS_ERR; + } + DestroyCnnCodeKey(key); + return SOFTBUS_OK; +} + +static void RemoveCnnCode(Map *cnnCode, const char *uuid, DiscoveryType type) +{ + char *key = CreateCnnCodeKey(uuid, type); + if (key == NULL) { + LOG_ERR("CreateCnnCodeKey error!"); + return; + } + if (LnnMapErase(cnnCode, key) != SOFTBUS_OK) { + LOG_ERR("LnnMapErase error!"); + } + DestroyCnnCodeKey(key); + return; +} + +short LnnGetCnnCode(const char *uuid, DiscoveryType type) +{ + char *key = CreateCnnCodeKey(uuid, type); + if (key == NULL) { + LOG_ERR("CreateCnnCodeKey error!"); + return INVALID_CONNECTION_CODE_VALUE; + } + short *ptr = (short *)LnnMapGet(&g_distributedNetLedger.cnnCode.connectionCode, key); + if (ptr == NULL) { + LOG_ERR(" KEY not exist."); + DestroyCnnCodeKey(key); + return INVALID_CONNECTION_CODE_VALUE; + } + DestroyCnnCodeKey(key); + return (*ptr); +} + +void LnnAddOnlineNode(NodeInfo *info) +{ + // judge map + const char *deviceId = NULL; + DoubleHashMap *map = NULL; + NodeInfo *oldInfo = NULL; + bool isOffline = true; + bool oldWifiFlag = false; + bool oldBrFlag = false; + bool oldBleFlag = false; + bool isChanged = false; + bool newWifiFlag = LnnHasDiscoveryType(info, DISCOVERY_TYPE_WIFI); + bool newBleBrFlag = LnnHasDiscoveryType(info, DISCOVERY_TYPE_BLE) + || LnnHasDiscoveryType(info, DISCOVERY_TYPE_BR); + if (LnnHasDiscoveryType(info, DISCOVERY_TYPE_BR)) { + LOG_INFO("DiscoveryType = BR."); + AddCnnCode(&g_distributedNetLedger.cnnCode.connectionCode, info->uuid, DISCOVERY_TYPE_BR, + info->authSeqNum); + } + + deviceId = LnnGetDeviceUdid(info); + map = &g_distributedNetLedger.distributedInfo; + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + oldInfo = (NodeInfo *)LnnMapGet(&map->udidMap, deviceId); + if (oldInfo != NULL && LnnIsNodeOnline(oldInfo)) { + LOG_INFO("addOnlineNode find online node"); + isOffline = false; + isChanged = IsNetworkIdChanged(info, oldInfo); + oldWifiFlag = LnnHasDiscoveryType(oldInfo, DISCOVERY_TYPE_WIFI); + oldBleFlag = LnnHasDiscoveryType(oldInfo, DISCOVERY_TYPE_BLE); + oldBrFlag = LnnHasDiscoveryType(oldInfo, DISCOVERY_TYPE_BR); + if ((oldBleFlag || oldBrFlag) && newWifiFlag) { + NewWifiDiscovered(oldInfo, info); + } else if (oldWifiFlag && newBleBrFlag) { + NewBrBleDiscovered(oldInfo, info); + } else { + LOG_ERR("flag error"); + } + } + LnnSetNodeConnStatus(info, STATUS_ONLINE); + LnnMapSet(&map->udidMap, deviceId, info, sizeof(NodeInfo)); + pthread_mutex_unlock(&g_distributedNetLedger.lock); + if (isOffline) { + PostToClient(info, STATUS_ONLINE); + } + if (isChanged) { + PostDeviceBasicInfoChanged(info, TYPE_NETWORK_ID); + } +} + +void LnnSetNodeOffline(const char *udid) +{ + NodeInfo *info = NULL; + NodeBasicInfo basic; + if (memset_s(&basic, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)) != EOK) { + LOG_ERR("memset_s basic fail!"); + } + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + info = (NodeInfo *)LnnMapGet(&map->udidMap, udid); + if (info == NULL) { + LOG_ERR("PARA ERROR!"); + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return; + } + if (LnnHasDiscoveryType(info, DISCOVERY_TYPE_BR)) { + RemoveCnnCode(&g_distributedNetLedger.cnnCode.connectionCode, info->uuid, DISCOVERY_TYPE_BR); + } + LnnSetNodeConnStatus(info, STATUS_OFFLINE); + if (ConvertNodeInfoToBasicInfo(info, &basic) != SOFTBUS_OK) { + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return; + } + pthread_mutex_unlock(&g_distributedNetLedger.lock); + if (PostOffline(&basic) != SOFTBUS_OK) { + LOG_ERR("post offline fail!"); + } +} + +void LnnRemoveNode(const char *udid) +{ + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + if (udid == NULL) { + return; + } + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + LnnMapErase(&map->udidMap, udid); + pthread_mutex_unlock(&g_distributedNetLedger.lock); +} + +const char *LnnConvertDLidToUdid(const char *id, IdCategory type) +{ + NodeInfo *info = NULL; + if (id == NULL) { + return NULL; + } + info = LnnGetNodeInfoById(id, type); + if (info == NULL) { + LOG_ERR("uuid not find node info."); + return NULL; + } + return LnnGetDeviceUdid(info); +} + +bool LnnSetDLDeviceInfoName(const char *udid, const char *name) +{ + DoubleHashMap *map = &g_distributedNetLedger.distributedInfo; + NodeInfo *info = NULL; + NodeBasicInfo basic; + if (memset_s(&basic, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)) != EOK) { + LOG_ERR("memset_s basic fail!"); + } + if (udid == NULL || name == NULL) { + LOG_ERR("para error!"); + return false; + } + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return false; + } + info = GetNodeInfoFromMap(map, udid); + if (info == NULL) { + LOG_ERR("udid not exist !"); + goto EXIT; + } + if (strcmp(LnnGetDeviceName(&info->deviceInfo), name) == 0) { + LOG_INFO("devicename not change!"); + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return true; + } + if (LnnSetDeviceName(&info->deviceInfo, name) != SOFTBUS_OK) { + LOG_ERR("set device name error!"); + goto EXIT; + } + if (ConvertNodeInfoToBasicInfo(info, &basic) != SOFTBUS_OK) { + goto EXIT; + } + pthread_mutex_unlock(&g_distributedNetLedger.lock); + LnnNotifyBasicInfoChanged(&basic, TYPE_DEVICE_NAME); + return true; +EXIT: + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return false; +} + +int32_t LnnGetDLStrInfo(const char *networkId, InfoKey key, char *info, uint32_t len) +{ + uint32_t i; + int32_t ret; + if (networkId == NULL || info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + if (key >= STRING_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_dlKeyTable) / sizeof(DistributedLedgerKey); i++) { + if (key == g_dlKeyTable[i].key) { + if (g_dlKeyTable[i].getInfo != NULL) { + ret = g_dlKeyTable[i].getInfo(networkId, (void *)info, len); + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return ret; + } + } + } + pthread_mutex_unlock(&g_distributedNetLedger.lock); + LOG_ERR("KEY NOT exist."); + return SOFTBUS_ERR; +} + +int32_t LnnGetDLNumInfo(const char *networkId, InfoKey key, int32_t *info) +{ + uint32_t i; + int32_t ret; + if (networkId == NULL || info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + if (key < NUM_KEY_BEGIN || key >= NUM_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_dlKeyTable) / sizeof(DistributedLedgerKey); i++) { + if (key == g_dlKeyTable[i].key) { + if (g_dlKeyTable[i].getInfo != NULL) { + ret = g_dlKeyTable[i].getInfo(networkId, (void *)info, NUM_BUF_SIZE); + pthread_mutex_unlock(&g_distributedNetLedger.lock); + return ret; + } + } + } + pthread_mutex_unlock(&g_distributedNetLedger.lock); + LOG_ERR("KEY NOT exist."); + return SOFTBUS_ERR; +} + +int32_t LnnGetDistributedNodeInfo(NodeBasicInfo **info, int32_t *infoNum) +{ + int ret = SOFTBUS_ERR; + + if (info == NULL || infoNum == NULL) { + LOG_ERR("key params are null"); + return ret; + } + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + } + do { + *info = NULL; + if (GetDLOnlineNodeNumLocked(infoNum) != SOFTBUS_OK) { + LOG_ERR("get online node num failed"); + break; + } + if (*infoNum == 0) { + ret = SOFTBUS_OK; + break; + } + *info = SoftBusMalloc((*infoNum) * sizeof(NodeBasicInfo)); + if (*info == NULL) { + LOG_ERR("malloc node info buffer failed"); + break; + } + if (FillDLOnlineNodeInfoLocked(info, *infoNum) != SOFTBUS_OK) { + LOG_ERR("fill online node num failed"); + break; + } + ret = SOFTBUS_OK; + } while (false); + if (ret != SOFTBUS_OK && (*info != NULL)) { + SoftBusFree(*info); + } + if (pthread_mutex_unlock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("unlock mutex fail!"); + } + return ret; +} + +int32_t LnnGetNetworkIdByUuid(const char *uuid, char *buf, uint32_t len) +{ + if (!IsValidString(uuid, ID_MAX_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&g_distributedNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + NodeInfo *nodeInfo = LnnGetNodeInfoById(uuid, CATEGORY_UUID); + if (nodeInfo == NULL) { + LOG_ERR("get info fail"); + (void)pthread_mutex_unlock(&g_distributedNetLedger.lock); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, nodeInfo->networkId, strlen(nodeInfo->networkId)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + (void)pthread_mutex_unlock(&g_distributedNetLedger.lock); + return SOFTBUS_MEM_ERR; + } + (void)pthread_mutex_unlock(&g_distributedNetLedger.lock); + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/local_ledger/include/lnn_local_net_ledger.h b/core/bus_center/lnn/net_ledger/local_ledger/include/lnn_local_net_ledger.h new file mode 100644 index 000000000..ebe00291f --- /dev/null +++ b/core/bus_center/lnn/net_ledger/local_ledger/include/lnn_local_net_ledger.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_LOCAL_NET_LEDGER_H +#define LNN_LOCAL_NET_LEDGER_H + +#include +#include + +#include "bus_center_info_key.h" +#include "lnn_device_info.h" +#include "lnn_node_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + LL_INIT_UNKNOWN = 0, + LL_INIT_FAIL, + LL_INIT_SUCCESS, +} LocalLedgerStatus; + +typedef struct { + InfoKey key; + int32_t maxLen; + int32_t (*getInfo)(void *info, uint32_t len); + int32_t (*setInfo)(const void *info); +} LocalLedgerKey; + +int32_t LnnInitLocalLedger(void); +void LnnDeinitLocalLedger(void); +const NodeInfo *LnnGetLocalNodeInfo(void); +int32_t LnnGetLocalLedgerStrInfo(InfoKey key, char *info, uint32_t len); +int32_t LnnGetLocalLedgerNumInfo(InfoKey key, int32_t *info); +int32_t LnnSetLocalLedgerStrInfo(InfoKey key, const char *info); +int32_t LnnSetLocalLedgerNumInfo(InfoKey key, int32_t info); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_LOCAL_NET_LEDGER_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c b/core/bus_center/lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c new file mode 100644 index 000000000..629eba63e --- /dev/null +++ b/core/bus_center/lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_local_net_ledger.h" + +#include +#include +#include + +#include + +#include "bus_center_adapter.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_utils.h" + +#define SOFTBUS_VERSION "hm.1.0.0" +#define VERSION_TYPE_LITE "LITE" +#define VERSION_TYPE_DEFAULT "" +#define NUM_BUF_SIZE 4 + +typedef struct { + NodeInfo localInfo; + pthread_mutex_t lock; + LocalLedgerStatus status; +} LocalNetLedger; + +static LocalNetLedger g_localNetLedger; + +static int32_t LlGetNodeSoftBusVersion(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(buf, len, info->softBusVersion, strlen(info->softBusVersion)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetDeviceUdid(void *buf, uint32_t len) +{ + const char *udid = NULL; + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + udid = LnnGetDeviceUdid(info); + if (udid == NULL) { + LOG_ERR("get device udid fail"); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, udid, strlen(udid)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetNetworkId(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(buf, len, info->networkId, strlen(info->networkId)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetUuid(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(buf, len, info->uuid, strlen(info->uuid)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t UpdateLocalDeviceUdid(const void *buf) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return LnnSetDeviceUdid(info, (char *)buf); +} + +static int32_t LlGetDeviceType(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + char *deviceType = NULL; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + deviceType = LnnConvertIdToDeviceType(info->deviceInfo.deviceTypeId); + if (deviceType == NULL) { + LOG_ERR("deviceType fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, deviceType, strlen(deviceType)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t UpdateLocalDeviceType(const void *buf) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + uint8_t typeId; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (LnnConvertDeviceTypeToId((char *)buf, &typeId) == SOFTBUS_OK) { + info->deviceInfo.deviceTypeId = typeId; + return SOFTBUS_OK; + } + LOG_ERR("set device type error."); + return SOFTBUS_ERR; +} + +static int32_t LlGetDeviceName(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + const char *deviceName = NULL; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + deviceName = LnnGetDeviceName(&info->deviceInfo); + if (deviceName == NULL) { + LOG_ERR("get device name fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, deviceName, strlen(deviceName)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + + +static int32_t LlGetBtMac(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + const char *mac = NULL; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + mac = LnnGetBtMac(info); + if (mac == NULL) { + LOG_ERR("get bt mac fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, mac, strlen(mac)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetWlanIp(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + const char *ip = NULL; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + ip = LnnGetWiFiIp(info); + if (ip == NULL) { + LOG_ERR("get wifi ip fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, ip, strlen(ip)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetNetIfName(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + const char *ifName = NULL; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + ifName = LnnGetNetIfName(info); + if (ifName == NULL) { + LOG_ERR("get bt mac fail."); + return SOFTBUS_ERR; + } + if (strncpy_s(buf, len, ifName, strlen(ifName)) != EOK) { + LOG_ERR("STR COPY ERROR!"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t LlGetAuthPort(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL || len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + *((int32_t *)buf) = LnnGetAuthPort(info); + return SOFTBUS_OK; +} + +static int32_t UpdateLocalAuthPort(const void *buf) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return LnnSetAuthPort(info, *(int *)buf); +} + +static int32_t LlGetSessionPort(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL || len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + *((int32_t *)buf) = LnnGetSessionPort(info); + return SOFTBUS_OK; +} + +static int32_t UpdateLocalSessionPort(const void *buf) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return LnnSetSessionPort(info, *(int *)buf); +} + +static int32_t LlGetProxyPort(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL || len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + *((int32_t *)buf) = LnnGetProxyPort(info); + return SOFTBUS_OK; +} + +static int32_t UpdateLocalProxyPort(const void *buf) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + return LnnSetProxyPort(info, *(int *)buf); +} + +static int32_t LlGetNetCap(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL || len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + *((int32_t *)buf) = info->netCapacity; + return SOFTBUS_OK; +} + +static int32_t LlGetDeviceTypeId(void *buf, uint32_t len) +{ + NodeInfo *info = &g_localNetLedger.localInfo; + if (buf == NULL || len != NUM_BUF_SIZE) { + return SOFTBUS_INVALID_PARAM; + } + *((int32_t *)buf) = info->deviceInfo.deviceTypeId; + return SOFTBUS_OK; +} + +static int32_t InitLocalDeviceInfo(DeviceBasicInfo *info) +{ + char devType[DEVICE_TYPE_BUF_LEN] = TYPE_UNKNOWN; + + if (info == NULL) { + LOG_ERR("fail:para error!"); + return SOFTBUS_INVALID_PARAM; + } + (void)memset_s(info, sizeof(DeviceBasicInfo), 0, sizeof(DeviceBasicInfo)); + + // get device info + if (GetCommonDevInfo(COMM_DEVICE_KEY_UDID, info->deviceUdid, UDID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("GetCommonDevInfo: COMM_DEVICE_KEY_UDID failed"); + return SOFTBUS_ERR; + } + if (GetCommonDevInfo(COMM_DEVICE_KEY_DEVNAME, info->deviceName, DEVICE_NAME_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("GetCommonDevInfo: COMM_DEVICE_KEY_DEVNAME failed"); + return SOFTBUS_ERR; + } + if (GetCommonDevInfo(COMM_DEVICE_KEY_DEVTYPE, devType, DEVICE_TYPE_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("GetCommonDevInfo: COMM_DEVICE_KEY_DEVTYPE failed"); + return SOFTBUS_ERR; + } + if (UpdateLocalDeviceType(devType) != SOFTBUS_OK) { + LOG_ERR("UpdateLocalDeviceType failed"); + } + return SOFTBUS_OK; +} + +static int32_t InitLocalVersionType(NodeInfo *info) +{ + if (info == NULL) { + LOG_ERR("fail:para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(info->versionType, VERSION_MAX_LEN, VERSION_TYPE_LITE, strlen(VERSION_TYPE_LITE)) != EOK) { + LOG_ERR("strncpy_s error"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t InitConnectInfo(ConnectInfo *info) +{ + if (info == NULL) { + LOG_ERR("fail:para error!"); + return SOFTBUS_INVALID_PARAM; + } + // get mac addr + return GetCommonDevInfo(COMM_DEVICE_KEY_BT_MAC, info->macAddr, MAC_LEN); +} + +static int32_t ModifyId(char *dstId, uint32_t dstLen, const char *sourceId) +{ + if (dstId == NULL || sourceId == NULL || strlen(sourceId) > dstLen - 1) { + LOG_ERR("id:para error!"); + return SOFTBUS_INVALID_PARAM; + } + if (strncpy_s(dstId, dstLen, sourceId, strlen(sourceId)) != EOK) { + LOG_ERR("strncpy_s error"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +const NodeInfo *LnnGetLocalNodeInfo(void) +{ + return &g_localNetLedger.localInfo; +} + +static int32_t UpdateLocalDeviceName(const void *name) +{ + return LnnSetDeviceName(&g_localNetLedger.localInfo.deviceInfo, (char *)name); +} + +static int32_t UpdateLocalNetworkId(const void *id) +{ + return ModifyId(g_localNetLedger.localInfo.networkId, NETWORK_ID_BUF_LEN, (char *)id); +} + +static int32_t UpdateLocalUuid(const void *id) +{ + return ModifyId(g_localNetLedger.localInfo.uuid, UUID_BUF_LEN, (char *)id); +} + +int32_t UpdateLocalParentId(const char *id) +{ + return ModifyId(g_localNetLedger.localInfo.parentId, ID_MAX_LEN, id); +} + +int32_t UpdateLocalPublicId(const char *id) +{ + return ModifyId(g_localNetLedger.localInfo.publicId, ID_MAX_LEN, id); +} + +int32_t UpdateLocalRole(ConnectRole role) +{ + g_localNetLedger.localInfo.role = role; + return SOFTBUS_OK; +} + +static int32_t UpdateLocalNetCapability(const void *capability) +{ + if (capability == NULL) { + return SOFTBUS_INVALID_PARAM; + } + g_localNetLedger.localInfo.netCapacity = *(int32_t *)capability; + return SOFTBUS_OK; +} + +int32_t UpdateLocalStatus(ConnectStatus status) +{ + g_localNetLedger.localInfo.status = status; + return SOFTBUS_OK; +} + +int32_t UpdateLocalWeight(uint32_t weight) +{ + g_localNetLedger.localInfo.weight = weight; + return SOFTBUS_OK; +} + +static int32_t UpdateLocalDeviceIp(const void *ip) +{ + if (ip == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + LnnSetWiFiIp(&g_localNetLedger.localInfo, ip); + return SOFTBUS_OK; +} + +static int32_t UpdateLocalBtMac(const void *mac) +{ + if (mac == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + LnnSetBtMac(&g_localNetLedger.localInfo, (char *)mac); + return SOFTBUS_OK; +} + +static int32_t UpdateLocalNetIfName(const void *netIfName) +{ + if (netIfName == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + LnnSetNetIfName(&g_localNetLedger.localInfo, (char *)netIfName); + return SOFTBUS_OK; +} + +static LocalLedgerKey g_localKeyTable[] = { + {STRING_KEY_HICE_VERSION, VERSION_MAX_LEN, LlGetNodeSoftBusVersion, NULL}, + {STRING_KEY_DEV_UDID, UDID_BUF_LEN, LlGetDeviceUdid, UpdateLocalDeviceUdid}, + {STRING_KEY_NETWORKID, NETWORK_ID_BUF_LEN, LlGetNetworkId, UpdateLocalNetworkId}, + {STRING_KEY_UUID, UUID_BUF_LEN, LlGetUuid, UpdateLocalUuid}, + {STRING_KEY_DEV_TYPE, DEVICE_TYPE_BUF_LEN, LlGetDeviceType, UpdateLocalDeviceType}, + {STRING_KEY_DEV_NAME, DEVICE_NAME_BUF_LEN, LlGetDeviceName, UpdateLocalDeviceName}, + {STRING_KEY_BT_MAC, MAC_LEN, LlGetBtMac, UpdateLocalBtMac}, + {STRING_KEY_WLAN_IP, IP_MAX_LEN, LlGetWlanIp, UpdateLocalDeviceIp}, + {STRING_KEY_NET_IF_NAME, NET_IF_NAME_LEN, LlGetNetIfName, UpdateLocalNetIfName}, + {NUM_KEY_SESSION_PORT, -1, LlGetSessionPort, UpdateLocalSessionPort}, + {NUM_KEY_AUTH_PORT, -1, LlGetAuthPort, UpdateLocalAuthPort}, + {NUM_KEY_PROXY_PORT, -1, LlGetProxyPort, UpdateLocalProxyPort}, + {NUM_KEY_NET_CAP, -1, LlGetNetCap, UpdateLocalNetCapability}, + {NUM_KEY_DEV_TYPE_ID, -1, LlGetDeviceTypeId, NULL}, +}; + +int32_t LnnGetLocalLedgerStrInfo(InfoKey key, char *info, uint32_t len) +{ + uint32_t i; + int32_t ret; + if (info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + if (key >= STRING_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_localNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_localKeyTable) / sizeof(LocalLedgerKey); i++) { + if (key == g_localKeyTable[i].key) { + if (g_localKeyTable[i].getInfo != NULL) { + ret = g_localKeyTable[i].getInfo((void *)info, len); + pthread_mutex_unlock(&g_localNetLedger.lock); + return ret; + } + } + } + pthread_mutex_unlock(&g_localNetLedger.lock); + LOG_ERR("KEY NOT exist."); + return SOFTBUS_ERR; +} + +int32_t LnnGetLocalLedgerNumInfo(InfoKey key, int32_t *info) +{ + uint32_t i; + int32_t ret; + if (info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + if (key < NUM_KEY_BEGIN || key >= NUM_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_localNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_localKeyTable) / sizeof(LocalLedgerKey); i++) { + if (key == g_localKeyTable[i].key) { + if (g_localKeyTable[i].getInfo != NULL) { + ret = g_localKeyTable[i].getInfo((void *)info, NUM_BUF_SIZE); + pthread_mutex_unlock(&g_localNetLedger.lock); + return ret; + } + } + } + pthread_mutex_unlock(&g_localNetLedger.lock); + LOG_ERR("KEY NOT exist."); + return SOFTBUS_ERR; +} + +static bool JudgeString(const char *info, int32_t len) +{ + return (len <= 0) ? false : IsValidString(info, len); +} + +int32_t LnnSetLocalLedgerStrInfo(InfoKey key, const char *info) +{ + uint32_t i; + int32_t ret; + if (info == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + if (key >= STRING_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_localNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_localKeyTable) / sizeof(LocalLedgerKey); i++) { + if (key == g_localKeyTable[i].key) { + if (g_localKeyTable[i].setInfo != NULL && JudgeString(info, g_localKeyTable[i].maxLen)) { + ret = g_localKeyTable[i].setInfo((void *)info); + pthread_mutex_unlock(&g_localNetLedger.lock); + return ret; + } + LOG_ERR("key=%d not support or info format error", key); + pthread_mutex_unlock(&g_localNetLedger.lock); + return SOFTBUS_INVALID_PARAM; + } + } + pthread_mutex_unlock(&g_localNetLedger.lock); + LOG_ERR("key not exist."); + return SOFTBUS_ERR; +} + +int32_t LnnSetLocalLedgerNumInfo(InfoKey key, int32_t info) +{ + uint32_t i; + int32_t ret; + if (key < NUM_KEY_BEGIN || key >= NUM_KEY_END) { + LOG_ERR("KEY error."); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_localNetLedger.lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + for (i = 0; i < sizeof(g_localKeyTable) / sizeof(LocalLedgerKey); i++) { + if (key == g_localKeyTable[i].key) { + if (g_localKeyTable[i].setInfo != NULL) { + ret = g_localKeyTable[i].setInfo((void *)&info); + pthread_mutex_unlock(&g_localNetLedger.lock); + return ret; + } + LOG_ERR("key=%d not support", key); + pthread_mutex_unlock(&g_localNetLedger.lock); + return SOFTBUS_ERR; + } + } + pthread_mutex_unlock(&g_localNetLedger.lock); + LOG_ERR("key not exist."); + return SOFTBUS_ERR; +} + +int32_t LnnInitLocalLedger() +{ + NodeInfo *nodeInfo = NULL; + if (g_localNetLedger.status == LL_INIT_SUCCESS) { + LOG_INFO("local net ledger already init."); + return SOFTBUS_OK; + } + g_localNetLedger.status = LL_INIT_UNKNOWN; + nodeInfo = &g_localNetLedger.localInfo; + (void)memset_s(nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo)); + if (strncpy_s(nodeInfo->softBusVersion, VERSION_MAX_LEN, SOFTBUS_VERSION, strlen(SOFTBUS_VERSION)) != EOK) { + LOG_ERR("fail:strncpy_s fail!"); + g_localNetLedger.status = LL_INIT_FAIL; + return SOFTBUS_MEM_ERR; + } + nodeInfo->netCapacity = LnnGetNetCapabilty(); + DeviceBasicInfo *deviceInfo = &nodeInfo->deviceInfo; + if (InitLocalDeviceInfo(deviceInfo) != SOFTBUS_OK) { + LOG_ERR("init local device info error!"); + goto EXIT; + } + if (InitLocalVersionType(nodeInfo) != SOFTBUS_OK) { + LOG_ERR("init local version type error!"); + goto EXIT; + } + if (InitConnectInfo(&nodeInfo->connectInfo) != SOFTBUS_OK) { + LOG_ERR("init local connect info error!"); + goto EXIT; + } + + if (pthread_mutex_init(&g_localNetLedger.lock, NULL) != 0) { + LOG_ERR("mutex init fail!"); + goto EXIT; + } + g_localNetLedger.status = LL_INIT_SUCCESS; + return SOFTBUS_OK; +EXIT: + g_localNetLedger.status = LL_INIT_FAIL; + return SOFTBUS_ERR; +} + +void LnnDeinitLocalLedger() +{ + if (g_localNetLedger.status == LL_INIT_SUCCESS) { + pthread_mutex_destroy(&g_localNetLedger.lock); + } + g_localNetLedger.status = LL_INIT_UNKNOWN; +} diff --git a/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_exchange_ledger_info.h b/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_exchange_ledger_info.h new file mode 100644 index 000000000..85cfa0816 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_exchange_ledger_info.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_EXCHANGE_LEDGER_INFO_H +#define LNN_EXCHANGE_LEDGER_INFO_H + +#include + +#include "auth_interface.h" +#include "lnn_node_info.h" +#include "softbus_json_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CODE "CODE" +#define DEVICE_NAME "DEVICE_NAME" +#define DEVICE_TYPE "DEVICE_TYPE" +#define DEVICE_UDID "DEVICE_UDID" +#define NETWORK_ID "NETWORK_ID" +#define VERSION_TYPE "VERSION_TYPE" +#define BT_MAC "BT_MAC" +#define BUS_MAX_VERSION "BUS_MAX_VERSION" +#define BUS_MIN_VERSION "BUS_MIN_VERSION" +#define AUTH_PORT "AUTH_PORT" +#define SESSION_PORT "SESSION_PORT" +#define PROXY_PORT "PROXY_PORT" +#define CONN_CAP "CONN_CAP" +#define SW_VERSION "SW_VERSION" + +#define CODE_VERIFY_IP 1 +#define CODE_VERIFY_BT 5 +#define BUS_V1 1 +#define BUS_V2 2 + +typedef enum { + AUTH_BT = 0, + AUTH_WIFI, + AUTH_MAX, +} AuthType; + +typedef struct { + ConnectType cnnType; + AuthType authType; +} ConvertType; + +typedef struct { + uint8_t *buf; + uint32_t len; +} ParseBuf; + +typedef struct { + AuthType type; + char* (*pack)(const NodeInfo *info, SoftBusVersion version); + int32_t (*unpack)(const cJSON* json, NodeInfo *info, SoftBusVersion version); +} ProcessLedgerInfo; + +uint8_t *LnnGetExchangeNodeInfo(ConnectOption *option, SoftBusVersion version, + uint32_t *outSize, AuthSideFlag *side); +int32_t LnnParsePeerNodeInfo(ConnectOption *option, NodeInfo *info, + const ParseBuf *bufInfo, AuthSideFlag side, SoftBusVersion version); + +#ifdef __cplusplus +} +#endif + +#endif // LNN_EXCHANGE_LEDGER_INFO_H \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_sync_ledger_item_info.h b/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_sync_ledger_item_info.h new file mode 100644 index 000000000..7e788cb5c --- /dev/null +++ b/core/bus_center/lnn/net_ledger/sync_ledger/include/lnn_sync_ledger_item_info.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_SYNC_LEDGER_ITEM_INFO_H +#define LNN_SYNC_LEDGER_ITEM_INFO_H + +#include +#include "lnn_distributed_net_ledger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + INFO_TYPE_CAPABILITY = 0, + INFO_TYPE_CONNECTION_INFO, + INFO_TYPE_DEVICE_NAME, + INFO_TYPE_BATTERY_INFO, + INFO_TYPE_SCREEN_STATUS, + INFO_TYPE_OFFLINE, + INFO_TYPE_P2P_INFO, + INFO_TYPE_COUNT, +} SyncItemType; + +typedef struct { + SyncItemType type; + uint8_t *(*get)(const char* networkId, DiscoveryType type, uint32_t *bufLen); + uint8_t *(*convert)(const uint8_t *msg, uint32_t len, uint32_t *outLen); +} ItemFunc; + +typedef struct { + SyncItemType type; + uint8_t *buf; + uint32_t bufLen; +} SyncItemInfo; + +int32_t LnnSyncLedgerItemInfo(const char *networkId, DiscoveryType discoveryType, SyncItemType itemType); +int32_t LnnInitSyncLedgerItem(void); +void LnnDeinitSyncLedgerItem(void); +void LnnDeleteSyncItemInfo(SyncItemInfo *info); +int32_t LnnSendMessageToPeer(int32_t channelId); +#ifdef __cplusplus +} +#endif +#endif // LNN_SYNC_LEDGER_ITEM_INFO_H diff --git a/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c b/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c new file mode 100644 index 000000000..3d3669d9c --- /dev/null +++ b/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_exchange_ledger_info.h" + +#include +#include + +#include "lnn_distributed_net_ledger.h" +#include "lnn_local_net_ledger.h" +#include "lnn_node_info.h" +#include "softbus_errcode.h" +#include "softbus_mem_interface.h" + +static int32_t PackCommon(cJSON *json, const NodeInfo *info, SoftBusVersion version) +{ + if (json == NULL || info == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + + if (version >= SOFT_BUS_NEW_V1) { + if (!AddStringToJsonObject(json, SW_VERSION, info->softBusVersion)) { + LOG_ERR("AddStringToJsonObject Fail."); + return SOFTBUS_ERR; + } + } + + if (!AddStringToJsonObject(json, DEVICE_NAME, LnnGetDeviceName(&info->deviceInfo)) || + !AddStringToJsonObject(json, DEVICE_TYPE, LnnConvertIdToDeviceType(info->deviceInfo.deviceTypeId)) || + !AddStringToJsonObject(json, DEVICE_UDID, LnnGetDeviceUdid(info)) || + !AddStringToJsonObject(json, NETWORK_ID, info->networkId) || + !AddStringToJsonObject(json, VERSION_TYPE, info->versionType) || + !AddNumberToJsonObject(json, CONN_CAP, info->netCapacity)) { + LOG_ERR("AddStringToJsonObject Fail."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void UnPackCommon(const cJSON* json, NodeInfo *info, SoftBusVersion version) +{ + char deviceType[DEVICE_TYPE_BUF_LEN] = {0}; + uint8_t typeId; + if (json == NULL || info == NULL) { + LOG_ERR("para error!"); + return; + } + + if (version >= SOFT_BUS_NEW_V1) { + (void)GetJsonObjectStringItem(json, SW_VERSION, info->softBusVersion, VERSION_MAX_LEN); + } + + (void)GetJsonObjectStringItem(json, DEVICE_NAME, info->deviceInfo.deviceName, DEVICE_NAME_BUF_LEN); + if (GetJsonObjectStringItem(json, DEVICE_TYPE, deviceType, DEVICE_TYPE_BUF_LEN)) { + if (LnnConvertDeviceTypeToId(deviceType, &typeId) == SOFTBUS_OK) { + info->deviceInfo.deviceTypeId = typeId; + } + } + (void)GetJsonObjectStringItem(json, DEVICE_UDID, info->deviceInfo.deviceUdid, UDID_BUF_LEN); + (void)GetJsonObjectStringItem(json, NETWORK_ID, info->networkId, NETWORK_ID_BUF_LEN); + (void)GetJsonObjectStringItem(json, VERSION_TYPE, info->versionType, VERSION_MAX_LEN); + (void)GetJsonObjectNumberItem(json, CONN_CAP, (int *)&info->netCapacity); + return; +} + +static char *PackBt(const NodeInfo *info, SoftBusVersion version) +{ + if (info == NULL) { + LOG_ERR("info para error!"); + return NULL; + } + LOG_INFO("PackBt enter!"); + cJSON* json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("create cjson object error!"); + return NULL; + } + + if (!AddNumberToJsonObject(json, CODE, CODE_VERIFY_BT) || + !AddStringToJsonObject(json, BT_MAC, LnnGetBtMac(info))) { + LOG_ERR("AddToJsonObject error!"); + cJSON_Delete(json); + return NULL; + } + + if (PackCommon(json, info, version) != SOFTBUS_OK) { + LOG_ERR("PackCommon error!"); + cJSON_Delete(json); + return NULL; + } + + char *data = cJSON_PrintUnformatted(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + } + cJSON_Delete(json); + return data; +} + +static int32_t UnPackBt(const cJSON *json, NodeInfo *info, SoftBusVersion version) +{ + if (info == NULL || json == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + (void)GetJsonObjectStringItem(json, BT_MAC, info->connectInfo.macAddr, MAC_LEN); + UnPackCommon(json, info, version); + return SOFTBUS_OK; +} + +static int32_t UnPackWifi(const cJSON* json, NodeInfo *info, SoftBusVersion version) +{ + if (info == NULL || json == NULL) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + (void)GetJsonObjectNumberItem(json, AUTH_PORT, &info->connectInfo.authPort); + (void)GetJsonObjectNumberItem(json, SESSION_PORT, &info->connectInfo.sessionPort); + (void)GetJsonObjectNumberItem(json, PROXY_PORT, &info->connectInfo.proxyPort); + UnPackCommon(json, info, version); + return SOFTBUS_OK; +} + +static char *PackWifi(const NodeInfo *info, SoftBusVersion version) +{ + if (info == NULL) { + LOG_ERR("info para error!"); + return NULL; + } + LOG_INFO("PackWifi enter!"); + cJSON* json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("create cjson object error!"); + return NULL; + } + + if (!AddNumberToJsonObject(json, CODE, CODE_VERIFY_IP) || + !AddNumberToJsonObject(json, BUS_MAX_VERSION, BUS_V2) || + !AddNumberToJsonObject(json, BUS_MIN_VERSION, BUS_V1) || + !AddNumberToJsonObject(json, AUTH_PORT, LnnGetAuthPort(info)) || + !AddNumberToJsonObject(json, SESSION_PORT, LnnGetSessionPort(info)) || + !AddNumberToJsonObject(json, PROXY_PORT, LnnGetProxyPort(info))) { + LOG_ERR("AddStringToJsonObject Fail."); + cJSON_Delete(json); + return NULL; + } + + if (PackCommon(json, info, version) != SOFTBUS_OK) { + LOG_ERR("PackCommon error!"); + cJSON_Delete(json); + return NULL; + } + + char *data = cJSON_PrintUnformatted(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted Failed!"); + } + cJSON_Delete(json); + return data; +} + +static ProcessLedgerInfo g_processFuncs[] = { + {AUTH_BT, PackBt, UnPackBt}, + {AUTH_WIFI, PackWifi, UnPackWifi}, +}; + +char *PackLedgerInfo(SoftBusVersion version, AuthType type) +{ + uint32_t i; + const NodeInfo *info = LnnGetLocalNodeInfo(); + if (info == NULL) { + LOG_ERR("info = null."); + return NULL; + } + for (i = 0; i < sizeof(g_processFuncs) / sizeof(ProcessLedgerInfo); i++) { + if (g_processFuncs[i].type == type) { + return g_processFuncs[i].pack(info, version); + } + } + return NULL; +} + +static int32_t UnPackLedgerInfo(const cJSON *json, NodeInfo *info, + SoftBusVersion version, AuthType type) +{ + uint32_t i; + if (info == NULL || json == NULL) { + LOG_ERR("para error."); + return SOFTBUS_INVALID_PARAM; + } + for (i = 0; i < sizeof(g_processFuncs) / sizeof(ProcessLedgerInfo); i++) { + if (g_processFuncs[i].type == type) { + return g_processFuncs[i].unpack(json, info, version); + } + } + return SOFTBUS_ERR; +} +static ConvertType g_convertTable[] = { + {CONNECT_BR, AUTH_BT}, + {CONNECT_BLE, AUTH_BT}, + {CONNECT_TCP, AUTH_WIFI}, +}; + +static AuthType ConvertCnnTypeToAuthType(ConnectType type) +{ + uint32_t i; + for (i = 0; i < sizeof(g_convertTable) / sizeof(ConvertType); i++) { + if (g_convertTable[i].cnnType == type) { + return g_convertTable[i].authType; + } + } + return AUTH_MAX; +} + +uint8_t *LnnGetExchangeNodeInfo(ConnectOption *option, SoftBusVersion version, + uint32_t *outSize, AuthSideFlag *side) +{ + char *data = NULL; + uint8_t *encryptData = NULL; + OutBuf buf = {0}; + AuthType authType; + uint32_t len; + + if (option == NULL || outSize == NULL || side == NULL) { + return NULL; + } + authType = ConvertCnnTypeToAuthType(option->type); + data = PackLedgerInfo(version, authType); + if (data == NULL) { + LOG_ERR("pack ledger info error!"); + return NULL; + } + len = strlen(data) + 1 + AuthGetEncryptHeadLen(); + encryptData = (uint8_t *)SoftBusCalloc(len); + if (encryptData == NULL) { + LOG_ERR("malloc error!"); + cJSON_free(data); + return NULL; + } + buf.buf = encryptData; + buf.bufLen = len; + if (AuthEncrypt(option, side, (uint8_t *)data, strlen(data) + 1, &buf) != SOFTBUS_OK) { + LOG_ERR("AuthEncrypt error."); + cJSON_free(data); + SoftBusFree(encryptData); + return NULL; + } + if (buf.outLen != len) { + LOG_ERR("outLen not right."); + } + *outSize = buf.outLen; + cJSON_free(data); + return encryptData; +} + +int32_t LnnParsePeerNodeInfo(ConnectOption *option, NodeInfo *info, + const ParseBuf *bufInfo, AuthSideFlag side, SoftBusVersion version) +{ + cJSON *json = NULL; + int ret = SOFTBUS_OK; + uint8_t *decryptData = NULL; + OutBuf buf = {0}; + AuthType authType; + if ((option == NULL) || (info == NULL) || (bufInfo == NULL) || (bufInfo->buf == NULL)) { + LOG_ERR("para error!"); + return SOFTBUS_INVALID_PARAM; + } + authType = ConvertCnnTypeToAuthType(option->type); + decryptData = (uint8_t *)SoftBusCalloc(bufInfo->len - AuthGetEncryptHeadLen() + 1); + if (decryptData == NULL) { + return SOFTBUS_MALLOC_ERR; + } + buf.buf = decryptData; + buf.bufLen = bufInfo->len - AuthGetEncryptHeadLen(); + + // Decrypt + if (AuthDecrypt(option, side, bufInfo->buf, bufInfo->len, &buf) != SOFTBUS_OK) { + SoftBusFree(decryptData); + return SOFTBUS_ERR; + } + json = cJSON_Parse((char *)decryptData); + SoftBusFree(decryptData); + decryptData = NULL; + if (json == NULL) { + LOG_ERR("CJSON PARSE error!"); + return SOFTBUS_PARSE_JSON_ERR; + } + if (UnPackLedgerInfo(json, info, version, authType) != SOFTBUS_OK) { + LOG_ERR("UnPackLedgerInfo error!"); + ret = SOFTBUS_ERR; + } + cJSON_Delete(json); + return ret; +} \ No newline at end of file diff --git a/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c b/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c new file mode 100644 index 000000000..3f19dd5d9 --- /dev/null +++ b/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_sync_ledger_item_info.h" + +#include +#include +#include +#include + +#include + +#include "lnn_distributed_net_ledger.h" +#include "lnn_local_net_ledger.h" +#include "lnn_map.h" +#include "lnn_net_builder.h" +#include "softbus_conn_interface.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_transmission_interface.h" + +#define MSG_HEAD_LEN 4 +#define MSG_MAX_COUNT 10 +#define MSG_OFFLINE_LEN 4 +#define ITEM_INFO_COUNT 10 +#define CHANNEL_NAME "com.huawei.hwddmp.service.DeviceInfoSynchronize" + +static uint8_t *GetDeviceNameMsg(const char *networkId, DiscoveryType discoveryType, uint32_t *bufLen); +static uint8_t *GetOfflineMsg(const char *networkId, DiscoveryType type, uint32_t *bufLen); +static uint8_t *ConvertToDeviceName(const uint8_t *msg, uint32_t len, uint32_t *outLen); +static void ReleaseMsgResources(int32_t channelId); + +static ItemFunc g_itemGetFunTable[] = { + {INFO_TYPE_DEVICE_NAME, GetDeviceNameMsg, ConvertToDeviceName}, + {INFO_TYPE_OFFLINE, GetOfflineMsg, NULL}, +}; +typedef enum { + SYNC_INIT_UNKNOWN = 0, + SYNC_INIT_FAIL, + SYNC_INIT_SUCCESS, +} SyncLedgerStatus; + +typedef struct { + Map idMap; + SyncLedgerStatus status; +} SyncLedgerItem; + +typedef struct { + char udid[UDID_BUF_LEN]; + SyncItemInfo *info[ITEM_INFO_COUNT]; +} SyncElement; + +static SyncLedgerItem g_syncLedgerItem; + +static int32_t AddNewElementToMap(const char *key, const char *udid, SyncItemInfo *itemInfo) +{ + if (key == NULL || udid == NULL) { + return SOFTBUS_INVALID_PARAM; // itemInfo may be null + } + + SyncElement temp; + if (memset_s(&temp, sizeof(SyncElement), 0, sizeof(SyncElement)) != EOK) { + LOG_ERR("memset_s temp fail!"); + } + if (strncpy_s(temp.udid, UDID_BUF_LEN, udid, strlen(udid)) != EOK) { + LOG_ERR("strncpy_s fail!"); + return SOFTBUS_ERR; + } + temp.info[0] = itemInfo; + if (LnnMapSet(&g_syncLedgerItem.idMap, key, (void *)&temp, sizeof(SyncElement)) != SOFTBUS_OK) { + LOG_ERR("LnnMapSet fail!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t ServerProccess(const char *key, const char *udid) +{ + int32_t ret; + + SyncElement *element = (SyncElement *)LnnMapGet(&g_syncLedgerItem.idMap, key); + if (element != NULL) { + LOG_ERR("server element should be null!"); + for (uint32_t i = 0; i < ITEM_INFO_COUNT; i++) { + if (element->info[i] != NULL) { + LnnDeleteSyncItemInfo(element->info[i]); + element->info[i] = NULL; + } + } + LnnMapErase(&g_syncLedgerItem.idMap, key); + } + ret = AddNewElementToMap(key, udid, NULL); + return ret; +} + +int32_t LnnSendMessageToPeer(int32_t channelId) +{ + char key[INT_TO_STR_SIZE] = {0}; + if (sprintf_s(key, INT_TO_STR_SIZE, "%d", channelId) == -1) { + LOG_ERR("int convert char error!"); + return SOFTBUS_ERR; + } + LOG_INFO("LnnSendMessageToPeer enter channelId =%d!", channelId); + SyncElement *element = (SyncElement *)LnnMapGet(&g_syncLedgerItem.idMap, key); + if (element == NULL) { + LOG_ERR("key not exist!"); + return SOFTBUS_ERR; + } + // send message to peer. + for (uint32_t i = 0; i < ITEM_INFO_COUNT; i++) { + if (element->info[i] != NULL) { + LOG_INFO("LnnSendMessageToPeer send data!"); + TransSendNetworkingMessage(channelId, (char *)element->info[i]->buf, + element->info[i]->bufLen, CONN_HIGH); + LnnDeleteSyncItemInfo(element->info[i]); + element->info[i] = NULL; + } + } + (void)LnnMapErase(&g_syncLedgerItem.idMap, key); + if (TransCloseNetWorkingChannel(channelId) != SOFTBUS_OK) { + LOG_ERR("TransCloseNetWorkingChannel error!"); + } + ReleaseMsgResources(channelId); + LnnNotifySyncOfflineFinish(); + return SOFTBUS_OK; +} + +static int32_t OnChannelOpened(int32_t id, const char *peerUuid, unsigned char isServer) +{ + if (peerUuid == NULL) { + return SOFTBUS_INVALID_PARAM; + } + LOG_INFO("OnChannelOpened enter!"); + char key[INT_TO_STR_SIZE] = {0}; + if (sprintf_s(key, INT_TO_STR_SIZE, "%d", id) == -1) { + LOG_ERR("int convert char error!"); + return SOFTBUS_ERR; + } + const char *peerUdid = LnnConvertDLidToUdid(peerUuid, CATEGORY_UUID); + if (peerUdid == NULL) { + LOG_ERR("peerUuid not be found."); + return SOFTBUS_ERR; + } + if (isServer == 0) { + if (LnnNotifySendOfflineMessage(id) != SOFTBUS_OK) { + if (TransCloseNetWorkingChannel(id) != SOFTBUS_OK) { + ReleaseMsgResources(id); + LnnNotifySyncOfflineFinish(); + } + } + return SOFTBUS_OK; + } + return ServerProccess(key, peerUdid); +} + +static void ReleaseMsgResources(int32_t channelId) +{ + char key[INT_TO_STR_SIZE] = {0}; + if (sprintf_s(key, INT_TO_STR_SIZE, "%d", channelId) == -1) { + LOG_ERR("int convert char error!"); + return; + } + SyncElement *element = (SyncElement *)LnnMapGet(&g_syncLedgerItem.idMap, key); + if (element != NULL) { + for (uint32_t i = 0; i < ITEM_INFO_COUNT; i++) { + if (element->info[i] != NULL) { + LnnDeleteSyncItemInfo(element->info[i]); + element->info[i] = NULL; + } + } + LnnMapErase(&g_syncLedgerItem.idMap, key); + } +} + +static void OnChannelOpenFailed(int32_t channelId, const char *uuid) +{ + (void)uuid; + LOG_INFO("open channel fail channelId = %d", channelId); + ReleaseMsgResources(channelId); + LnnNotifySyncOfflineFinish(); +} + +static void OnChannelClosed(int32_t channelId) +{ + ReleaseMsgResources(channelId); + LnnNotifySyncOfflineFinish(); +} + +static uint8_t *ConvertToDeviceName(const uint8_t *msg, uint32_t len, uint32_t *outLen) +{ + char *buf = NULL; + buf = SoftBusCalloc(len + 1); + if (buf == NULL) { + return NULL; + } + if (memcpy_s(buf, len, msg, len) != EOK) { + SoftBusFree(buf); + return NULL; + } + *outLen = len + 1; + return (uint8_t*)buf; +} + +static int32_t ConvertMsgToSyncItemInfo(const uint8_t *message, uint32_t len, SyncItemInfo *itemInfo) +{ + uint32_t i; + uint32_t outLen = 0; + if (itemInfo == NULL || message == NULL || len <= MSG_HEAD_LEN) { + return SOFTBUS_INVALID_PARAM; + } + itemInfo->type = (SyncItemType)(*(int32_t *)message); + itemInfo->buf = NULL; + itemInfo->bufLen = 0; + for (i = 0; i < sizeof(g_itemGetFunTable) / sizeof (ItemFunc); i++) { + if (itemInfo->type == g_itemGetFunTable[i].type && g_itemGetFunTable[i].convert != NULL) { + itemInfo->buf = g_itemGetFunTable[i].convert(message + MSG_HEAD_LEN, len - MSG_HEAD_LEN, &outLen); + if (itemInfo->buf != NULL) { + itemInfo->bufLen = outLen; + return SOFTBUS_OK; + } + LOG_ERR("convert fail!"); + return SOFTBUS_ERR; + } + } + LOG_ERR("type not support!"); + return SOFTBUS_ERR; +} + +static void OnMessageReceived(int32_t id, const char *message, uint32_t len) +{ + char *peerUdid = NULL; + SyncItemInfo *itemInfo = NULL; + char str[INT_TO_STR_SIZE] = {0}; + if (message == NULL || len <= MSG_HEAD_LEN) { + return; + } + if (sprintf_s(str, INT_TO_STR_SIZE, "%d", id) == -1) { + LOG_ERR("int convert char error!"); + return; + } + SyncElement *element = (SyncElement *)LnnMapGet(&g_syncLedgerItem.idMap, str); + if (element == NULL) { + return; + } + peerUdid = element->udid; + itemInfo = (SyncItemInfo *)SoftBusCalloc(sizeof(SyncItemInfo)); + if (itemInfo == NULL) { + return; + } + if (ConvertMsgToSyncItemInfo((uint8_t *)message, len, itemInfo) != SOFTBUS_OK) { + SoftBusFree(itemInfo); + return; + } + // Notify netbuild report name change + if (LnnNotifyPeerDevInfoChanged(peerUdid, itemInfo) != SOFTBUS_OK) { + LOG_ERR("NotifyPeerDevInfoChange error!"); + LnnDeleteSyncItemInfo(itemInfo); + } +} + +static int32_t Little2Big(int32_t little) +{ + uint32_t lit = (uint32_t)little; + return (((lit & 0xff) << 24) | ((lit & 0xff00) << 8) | ((lit & 0xff0000) >> 8) | ((lit >> 24) & 0xff)); +} + +static uint8_t *GetOfflineMsg(const char *networkId, DiscoveryType type, uint32_t *bufLen) +{ + if (networkId == NULL || type != DISCOVERY_TYPE_BR || bufLen == NULL) { + LOG_ERR("fail: para error!"); + return NULL; + } + *bufLen = 0; + const NodeInfo *info = LnnGetNodeInfoById(networkId, CATEGORY_NETWORK_ID); + if (info == NULL) { + LOG_ERR("fail: para error!"); + return NULL; + } + + if (!LnnHasDiscoveryType(info, type)) { + LOG_INFO("sync offline type error type = %d.", type); + return NULL; + } + short code = LnnGetCnnCode(info->uuid, type); + if (code == INVALID_CONNECTION_CODE_VALUE) { + LOG_ERR("uuid not exist!"); + return NULL; + } + int32_t infoType = INFO_TYPE_OFFLINE; + unsigned short shortType = (unsigned short)type; + int32_t combinedInt = ((unsigned short)code << 16) | (shortType & 0x7FFF); + combinedInt = Little2Big(combinedInt); + LOG_INFO("GetOfflineMsg, infoType = %d, combinedInt = %d", infoType, combinedInt); + uint8_t *msg = (uint8_t *)SoftBusCalloc(MSG_HEAD_LEN + MSG_OFFLINE_LEN); + if (msg == NULL) { + return NULL; + } + if (memcpy_s(msg, MSG_HEAD_LEN, &infoType, sizeof(int32_t)) != EOK) { + LOG_ERR("memcpy fail!"); + SoftBusFree(msg); + return NULL; + } + if (memcpy_s(msg + MSG_HEAD_LEN, MSG_OFFLINE_LEN, &combinedInt, sizeof(int)) != EOK) { + LOG_ERR("memcpy fail!"); + SoftBusFree(msg); + return NULL; + } + *bufLen = MSG_HEAD_LEN + MSG_OFFLINE_LEN; + return msg; +} + +static uint8_t *GetDeviceNameMsg(const char *networkId, DiscoveryType discoveryType, uint32_t *bufLen) +{ + uint8_t *msg = NULL; + const char *deviceName = NULL; + uint32_t len; + int32_t type = INFO_TYPE_DEVICE_NAME; + (void)networkId; + (void)discoveryType; + if (bufLen == NULL) { + LOG_ERR("fail: para error!"); + return NULL; + } + *bufLen = 0; + const NodeInfo *info = LnnGetLocalNodeInfo(); + if (info == NULL) { + return NULL; + } + deviceName = LnnGetDeviceName(&info->deviceInfo); + if (deviceName == NULL) { + return NULL; + } + len = strlen(deviceName) + MSG_HEAD_LEN; + msg = SoftBusCalloc(len); + if (msg == NULL) { + return NULL; + } + if (memcpy_s(msg, MSG_HEAD_LEN, &type, MSG_HEAD_LEN) != EOK) { + LOG_ERR("memcpy fail!"); + SoftBusFree(msg); + return NULL; + } + if (memcpy_s(msg + MSG_HEAD_LEN, len - MSG_HEAD_LEN, deviceName, strlen(deviceName)) != EOK) { + LOG_ERR("memcpy fail!"); + SoftBusFree(msg); + return NULL; + } + *bufLen = len; + return msg; +} + +static int32_t GetItemInfoMsg(const char *networkId, DiscoveryType discoveryType, SyncItemInfo *itemInfo) +{ + uint32_t i; + uint32_t outLen = 0; + if (networkId == NULL || itemInfo == NULL) { + LOG_ERR("fail:para error!"); + return SOFTBUS_INVALID_PARAM; + } + for (i = 0; i < sizeof(g_itemGetFunTable) / sizeof (ItemFunc); i++) { + if (itemInfo->type == g_itemGetFunTable[i].type && g_itemGetFunTable[i].get != NULL) { + itemInfo->buf = g_itemGetFunTable[i].get(networkId, discoveryType, &outLen); + if (itemInfo->buf != NULL) { + itemInfo->bufLen = outLen; + return SOFTBUS_OK; + } + LOG_ERR("type = %d get function error!", itemInfo->type); + return SOFTBUS_ERR; + } + } + LOG_ERR("type = %d, not support!", itemInfo->type); + return SOFTBUS_ERR; +} + +static int32_t SaveMsgToBuf(int32_t channelId, const char *udid, SyncItemInfo *itemInfo) +{ + if (channelId == INVALID_CHANNEL_ID || udid == NULL || itemInfo == NULL) { + LOG_ERR("fail: para error channelId =%d!", channelId); + return SOFTBUS_INVALID_PARAM; + } + int32_t ret = SOFTBUS_OK; + char key[INT_TO_STR_SIZE] = {0}; + if (sprintf_s(key, INT_TO_STR_SIZE, "%d", channelId) == -1) { + LOG_ERR("int convert char error!"); + return SOFTBUS_ERR; + } + SyncElement *element = (SyncElement *)LnnMapGet(&g_syncLedgerItem.idMap, key); + if (element == NULL) { + ret = AddNewElementToMap(key, udid, itemInfo); + goto EXIT; + } else { + for (uint32_t i = 0; i < ITEM_INFO_COUNT; i++) { + if (element->info[i] == NULL) { + element->info[i] = itemInfo; + goto EXIT; + } + } + LOG_ERR("sending buf already full and abandon the first buf!"); + element->info[0] = itemInfo; + goto EXIT; + } +EXIT: + return ret; +} + +static INetworkingListener g_nodeChangeListener = { + OnChannelOpened, + OnChannelOpenFailed, + OnChannelClosed, + OnMessageReceived, +}; + +int32_t LnnSyncLedgerItemInfo(const char *networkId, DiscoveryType discoveryType, SyncItemType itemType) +{ + if (networkId == NULL) { + LOG_ERR("fail: networkId = NULL"); + return SOFTBUS_INVALID_PARAM; + } + LOG_INFO("LnnSyncLedgerItemInfo enter!"); + const char *udid = LnnConvertDLidToUdid(networkId, CATEGORY_NETWORK_ID); + if (udid == NULL) { + LOG_ERR("fail : networkId not exist!"); + return SOFTBUS_INVALID_PARAM; + } + + SyncItemInfo *itemInfo = (SyncItemInfo *)SoftBusCalloc(sizeof(SyncItemInfo)); + if (itemInfo == NULL) { + LOG_ERR("fail: SoftBusCalloc fail!"); + return SOFTBUS_MALLOC_ERR; + } + itemInfo->type = itemType; + if (GetItemInfoMsg(networkId, discoveryType, itemInfo) != SOFTBUS_OK) { + SoftBusFree(itemInfo); + return SOFTBUS_ERR; + } + if (itemType == INFO_TYPE_OFFLINE) { + int type = *(int *)itemInfo->buf; + int seq = *(int *)(itemInfo->buf + MSG_HEAD_LEN); + LOG_INFO("INFO: type = %d, seq = %d", type, seq); + } + int32_t channelId = TransOpenNetWorkingChannel(CHANNEL_NAME, networkId); + LOG_INFO("OpenNetWorkingChannel channelId =%d!", channelId); + if (SaveMsgToBuf(channelId, udid, itemInfo) != SOFTBUS_OK) { + LOG_ERR("SaveMsgToBuf error!"); + LnnDeleteSyncItemInfo(itemInfo); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +void LnnDeleteSyncItemInfo(SyncItemInfo *info) +{ + if (info == NULL) { + return; + } + if (info->buf != NULL) { + SoftBusFree(info->buf); + } + SoftBusFree(info); +} + +int32_t LnnInitSyncLedgerItem(void) +{ + if (g_syncLedgerItem.status == SYNC_INIT_SUCCESS) { + LOG_INFO("LnnInitSyncLedgerItem already success!"); + return SOFTBUS_OK; + } + LnnMapInit(&g_syncLedgerItem.idMap); + if (TransRegisterNetworkingChannelListener(&g_nodeChangeListener) != SOFTBUS_OK) { + g_syncLedgerItem.status = SYNC_INIT_FAIL; + LOG_ERR("TransRegisterNetworkingChannelListener error!"); + return SOFTBUS_ERR; + } + g_syncLedgerItem.status = SYNC_INIT_SUCCESS; + LOG_INFO("LnnInitSyncLedgerItem INIT success!"); + return SOFTBUS_OK; +} + +void LnnDeinitSyncLedgerItem(void) +{ + LnnMapDelete(&g_syncLedgerItem.idMap); + g_syncLedgerItem.status = SYNC_INIT_UNKNOWN; +} \ No newline at end of file diff --git a/core/bus_center/service/include/bus_center_event.h b/core/bus_center/service/include/bus_center_event.h new file mode 100644 index 000000000..1eb080839 --- /dev/null +++ b/core/bus_center/service/include/bus_center_event.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUS_CENTER_EVENT_H +#define BUS_CENTER_EVENT_H + +#include +#include + +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void LnnNotifyJoinResult(ConnectionAddr *addr, + const char *networkId, int32_t retCode); +void LnnNotifyLeaveResult(const char *networkId, int32_t retCode); + +void LnnNotifyOnlineState(bool isOnline, NodeBasicInfo *info); +void LnnNotifyBasicInfoChanged(NodeBasicInfo *info, NodeBasicInfoType type); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/bus_center/service/src/bus_center_event.c b/core/bus_center/service/src/bus_center_event.c new file mode 100644 index 000000000..50b926c33 --- /dev/null +++ b/core/bus_center/service/src/bus_center_event.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bus_center_event.h" + +#include + +#include "lnn_bus_center_ipc.h" +#include "softbus_log.h" + +void LnnNotifyOnlineState(bool isOnline, NodeBasicInfo *info) +{ + if (info == NULL) { + LOG_ERR("para : info = null!"); + return; + } + LOG_INFO("notify node %s", (isOnline == true) ? "online" : "offline"); + LnnIpcNotifyOnlineState(isOnline, info, sizeof(NodeBasicInfo)); +} + +void LnnNotifyBasicInfoChanged(NodeBasicInfo *info, NodeBasicInfoType type) +{ + if (info == NULL) { + LOG_ERR("para : info = null!"); + return; + } + if (type == TYPE_DEVICE_NAME) { + LOG_INFO("notify peer device name changed %s", info->deviceName); + } + LnnIpcNotifyBasicInfoChanged(info, sizeof(NodeBasicInfo), type); +} + +void LnnNotifyJoinResult(ConnectionAddr *addr, const char *networkId, int32_t retCode) +{ + if (addr == NULL) { + LOG_ERR("para : addr or networkId = null!"); + return; + } + LOG_INFO("notify join LNN result :%d", retCode); + LnnIpcNotifyJoinResult(addr, sizeof(ConnectionAddr), networkId, retCode); +} + +void LnnNotifyLeaveResult(const char *networkId, int32_t retCode) +{ + if (networkId == NULL) { + LOG_ERR("para : networkId = null!"); + return; + } + LOG_INFO("notify leave LNN result %d", retCode); + LnnIpcNotifyLeaveResult(networkId, retCode); +} \ No newline at end of file diff --git a/core/bus_center/service/src/bus_center_manager.c b/core/bus_center/service/src/bus_center_manager.c new file mode 100644 index 000000000..c5b246ec5 --- /dev/null +++ b/core/bus_center/service/src/bus_center_manager.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bus_center_manager.h" + +#include +#include + +#include "lnn_distributed_net_ledger.h" +#include "lnn_exchange_ledger_info.h" +#include "lnn_lane_info.h" +#include "lnn_local_net_ledger.h" +#include "lnn_net_builder.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_utils.h" + +void __attribute__ ((weak)) LnnLanesInit(void) +{ +} + +int32_t BusCenterServerInit(void) +{ + if (LnnInitLocalLedger() != SOFTBUS_OK) { + LOG_ERR("init local net ledger fail!"); + return SOFTBUS_ERR; + } + if (LnnInitDistributedLedger() != SOFTBUS_OK) { + LOG_ERR("init distributed net ledger fail!"); + return SOFTBUS_ERR; + } + if (LnnInitSyncLedgerItem() != SOFTBUS_OK) { + LOG_ERR("init sync ledger item fail!"); + return SOFTBUS_ERR; + } + if (LnnInitNetBuilder() != SOFTBUS_OK) { + LOG_ERR("init net builder fail!"); + return SOFTBUS_ERR; + } + LnnLanesInit(); + LOG_INFO("bus center server init ok"); + return SOFTBUS_OK; +} + +void BusCenterServerDeinit(void) +{ + LnnDeinitLocalLedger(); + LnnDeinitDistributedLedger(); + LnnDeinitNetBuilder(); + LnnDeinitSyncLedgerItem(); + LOG_INFO("bus center server deinit"); +} + +int32_t LnnGetRemoteStrInfo(const char *networkId, InfoKey key, char *info, uint32_t len) +{ + if (!IsValidString(networkId, ID_MAX_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + return LnnGetDLStrInfo(networkId, key, info, len); +} + +int32_t LnnGetRemoteNumInfo(const char *networkId, InfoKey key, int32_t *info) +{ + if (!IsValidString(networkId, ID_MAX_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + return LnnGetDLNumInfo(networkId, key, info); +} + +int32_t LnnSetLocalStrInfo(InfoKey key, const char *info) +{ + return LnnSetLocalLedgerStrInfo(key, info); +} + +int32_t LnnSetLocalNumInfo(InfoKey key, int32_t info) +{ + return LnnSetLocalLedgerNumInfo(key, info); +} + +int32_t LnnGetLocalStrInfo(InfoKey key, char *info, uint32_t len) +{ + return LnnGetLocalLedgerStrInfo(key, info, len); +} + +int32_t LnnGetLocalNumInfo(InfoKey key, int32_t *info) +{ + return LnnGetLocalLedgerNumInfo(key, info); +} + +int32_t LnnGetAllOnlineNodeInfo(NodeBasicInfo **info, int32_t *infoNum) +{ + return LnnGetDistributedNodeInfo(info, infoNum); +} + +int32_t LnnGetLocalDeviceInfo(NodeBasicInfo *info) +{ + int32_t rc; + char type[DEVICE_TYPE_BUF_LEN] = {0}; + + if (info == NULL) { + LOG_ERR("info is null"); + return SOFTBUS_INVALID_PARAM; + } + rc = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_NAME, info->deviceName, DEVICE_NAME_BUF_LEN); + if (rc != SOFTBUS_OK) { + LOG_ERR("get local device info failed"); + return SOFTBUS_ERR; + } + rc = LnnGetLocalLedgerStrInfo(STRING_KEY_NETWORKID, info->networkId, NETWORK_ID_BUF_LEN); + if (rc != SOFTBUS_OK) { + LOG_ERR("get local network id info failed"); + return SOFTBUS_ERR; + } + rc = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_TYPE, type, DEVICE_TYPE_BUF_LEN); + if (rc != SOFTBUS_OK) { + LOG_ERR("get local device type failed"); + return SOFTBUS_ERR; + } + return LnnConvertDeviceTypeToId(type, &info->deviceTypeId); +} + +int32_t LnnGetNodeKeyInfo(const char *networkId, int key, uint8_t *info, int32_t infoLen) +{ + bool isLocalNetowrkId = false; + char localNetworkId[NETWORK_ID_BUF_LEN] = {0}; + if (networkId == NULL || info == NULL) { + LOG_ERR("params are null"); + return SOFTBUS_ERR; + } + if (LnnGetLocalStrInfo(STRING_KEY_NETWORKID, localNetworkId, NETWORK_ID_BUF_LEN) != SOFTBUS_OK) { + LOG_ERR("get local network id fail"); + return SOFTBUS_ERR; + } + if (strncmp(localNetworkId, networkId, NETWORK_ID_BUF_LEN) == 0) { + isLocalNetowrkId = true; + } + switch (key) { + case NODE_KEY_UDID: + if (isLocalNetowrkId) { + return LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, (char *)info, infoLen); + } else { + return LnnGetRemoteStrInfo(networkId, STRING_KEY_DEV_UDID, (char *)info, infoLen); + } + case NODE_KEY_UUID: + if (isLocalNetowrkId) { + return LnnGetLocalStrInfo(STRING_KEY_UUID, (char *)info, infoLen); + } else { + return LnnGetRemoteStrInfo(networkId, STRING_KEY_UUID, (char *)info, infoLen); + } + default: + LOG_ERR("invalid node key type: %d", key); + return SOFTBUS_ERR; + } +} diff --git a/core/bus_center/utils/include/lnn_connection_addr_utils.h b/core/bus_center/utils/include/lnn_connection_addr_utils.h new file mode 100644 index 000000000..b8dfb7345 --- /dev/null +++ b/core/bus_center/utils/include/lnn_connection_addr_utils.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LNN_CONNECTION_ADDR_UTILS_H +#define LNN_CONNECTION_ADDR_UTILS_H + +#include + +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool LnnIsSameConnectionAddr(const ConnectionAddr *addr1, const ConnectionAddr *addr2); + +#ifdef __cplusplus +} +#endif +#endif /* LNN_CONNECTION_ADDR_UTILS_H */ + diff --git a/core/bus_center/utils/src/lnn_connection_addr_utils.c b/core/bus_center/utils/src/lnn_connection_addr_utils.c new file mode 100644 index 000000000..db60c37b3 --- /dev/null +++ b/core/bus_center/utils/src/lnn_connection_addr_utils.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lnn_connection_addr_utils.h" + +#include + +bool LnnIsSameConnectionAddr(const ConnectionAddr *addr1, const ConnectionAddr *addr2) +{ + if (addr1->type != addr2->type) { + return false; + } + if (addr1->type == CONNECTION_ADDR_BR) { + return strncmp(addr1->info.br.brMac, addr2->info.br.brMac, BT_MAC_LEN) == 0; + } + if (addr1->type == CONNECTION_ADDR_BLE) { + return strncmp(addr1->info.ble.bleMac, addr2->info.ble.bleMac, BT_MAC_LEN) == 0; + } + if (addr1->type == CONNECTION_ADDR_WLAN || addr1->type == CONNECTION_ADDR_ETH) { + return true; + } + return false; +} diff --git a/core/common/BUILD.gn b/core/common/BUILD.gn new file mode 100755 index 000000000..50bbdacea --- /dev/null +++ b/core/common/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") + +lite_component("softbus_core_common") { + features = [ + "json_utils:json_utils", + "utils:softbus_utils", + "softbus_property:softbus_property", + "message_handler:message_handler", + "security:softbus_crypto", + ] +} diff --git a/core/common/include/common_list.h b/core/common/include/common_list.h new file mode 100644 index 000000000..a6cae4780 --- /dev/null +++ b/core/common/include/common_list.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_LIST_H +#define COMMON_LIST_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef struct ListNode { + struct ListNode *prev; /* Current node's pointer to the previous node */ + struct ListNode *next; /* Current node's pointer to the next node */ +} ListNode; + +/* list initialize */ +__attribute__((always_inline)) static inline void ListInit(ListNode *list) +{ + list->next = list; + list->prev = list; +} + +/* Get list head node */ +#define GET_LIST_HEAD(object) ((object)->next) + +/* Get list tail node */ +#define GET_LIST_TAIL(object) ((object)->prev) + +/* Insert a new node to list. */ +__attribute__((always_inline)) static inline void ListAdd(ListNode *list, ListNode *node) +{ + node->next = list->next; + node->prev = list; + list->next->prev = node; + list->next = node; +} + +/* Insert a node to the tail of a list. */ +__attribute__((always_inline)) static inline void ListTailInsert(ListNode *list, ListNode *node) +{ + ListAdd(list->prev, node); +} + +/* Insert a new node to list. */ +__attribute__((always_inline)) static inline void ListNodeInsert(ListNode *list, ListNode *node) +{ + ListAdd(list, node); +} + +/* Delete a specified node from list. */ +__attribute__((always_inline)) static inline void ListDelete(ListNode *node) +{ + if (node->next != 0 && node->prev != 0) { + node->next->prev = node->prev; + node->prev->next = node->next; + } + node->next = node; + node->prev = node; +} + +__attribute__((always_inline)) static inline bool IsListEmpty(const ListNode *node) +{ + return (bool)(node->next == node); +} + +/* + * @brief Obtain the pointer to a list in a structure + * + * @param type [IN] Structure name. + * @param member [IN] Member name of the list in the structure. + */ +#define OFF_SET_OF(type, member) ((size_t)&(((type *)0)->member)) + +#define CONTAINER_OF(ptr, type, member) \ + (type *)((char *)(ptr) - (char *) &((type *)0)->member) + +/* + * @brief Obtain the pointer to a structure that contains a list. + * @param item [IN] Current node's pointer to the next node. + * @param type [IN] Structure name. + * @param member [IN] Member name of the list in the structure. + */ +#define LIST_ENTRY(item, type, member) \ + ((type *)(void *)((char *)(item) - OFF_SET_OF(type, member))) \ + +/* Iterate over a list of given type. */ +#define LIST_FOR_EACH_ENTRY(item, list, type, member) \ + for ((item) = LIST_ENTRY((list)->next, type, member); \ + &(item)->member != (list); \ + (item) = LIST_ENTRY((item)->member.next, type, member)) + +/* Iterate over a list safe against removal of list entry. */ +#define LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, list, type, member) \ + for ((item) = LIST_ENTRY((list)->next, type, member), \ + (nextItem) = LIST_ENTRY((item)->member.next, type, member); \ + &((item)->member) != (list); \ + (item) = (nextItem), (nextItem) = LIST_ENTRY((item)->member.next, type, member)) + +__attribute__((always_inline)) static inline void ListDel(ListNode *prevNode, ListNode *nextNode) +{ + nextNode->prev = prevNode; + prevNode->next = nextNode; +} + +/* Delete node and initialize list */ +__attribute__((always_inline)) static inline void ListDelInit(ListNode *list) +{ + ListDel(list->prev, list->next); + ListInit(list); +} + +/* Iterate over a list. */ +#define LIST_FOR_EACH(item, list) \ + for ((item) = (list)->next; (item) != (list); (item) = (item)->next) + +/* Iterate over a list safe against removal of list entry. */ +#define LIST_FOR_EACH_SAFE(item, nextItem, list) \ + for ((item) = (list)->next, (nextItem) = (item)->next; (item) != (list); \ + (item) = (nextItem), (nextItem) = (item)->next) + +/* Initialize a list. */ +#define LIST_HEAD(list) ListNode list = { &(list), &(list) } + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* COMMON_LIST_H */ diff --git a/core/common/include/softbus.h b/core/common/include/softbus.h new file mode 100644 index 000000000..64234cdc5 --- /dev/null +++ b/core/common/include/softbus.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFT_BUS_H +#define SOFT_BUS_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +enum SoftBusEvent { + EVENT_SERVER_DEATH = 1, + EVENT_SERVER_RECOVERY = 2, + EVENT_BUTT +}; + +typedef int (*EventCallback)(void *arg, unsigned int argLen, void *userData); + +int RegisterEventCallback(enum SoftBusEvent event, EventCallback cb, void *userData); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* SOFT_BUS_H */ diff --git a/core/common/include/softbus_crypto.h b/core/common/include/softbus_crypto.h new file mode 100644 index 000000000..ddd0f1be2 --- /dev/null +++ b/core/common/include/softbus_crypto.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CRYPTO_H +#define SOFTBUS_CRYPTO_H + +#include +#include "softbus_def.h" + +#ifndef AES_GCM_H +#define AES_GCM_H + +#define HUKS_AES_GCM_KEY_LEN 256 +#define GCM_IV_LEN 12 +#define AAD_LEN 16 + +#define TAG_LEN 16 +#define OVERHEAD_LEN (GCM_IV_LEN + TAG_LEN) + +#define GCM_KEY_BITS_LEN_128 128 +#define GCM_KEY_BITS_LEN_256 256 +#define KEY_BITS_UNIT 8 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +typedef struct { + unsigned char *aad; + unsigned int aadLen; + const unsigned char *input; + unsigned int inputLen; + unsigned char **output; + unsigned int *outputLen; +} GcmInputParams; + +typedef struct { + unsigned int keyLen; + unsigned char key[SESSION_KEY_LENGTH]; + unsigned char iv[GCM_IV_LEN]; +} AesGcmCipherKey; + +int GenerateSessionKey(char* key, int len); + +int SoftBusEncryptData(AesGcmCipherKey *key, const unsigned char *input, unsigned int inLen, + unsigned char *encryptData, unsigned int *encryptLen); + +int SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *encryptData, unsigned int *encryptLen, int32_t seqNum); + +int SoftBusDecryptData(AesGcmCipherKey *key, const unsigned char *input, unsigned int inLen, + unsigned char *decryptData, unsigned int *decryptLen); + +int SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *encryptData, unsigned int *encryptLen, int32_t seqNum); + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_CRYPTO_H */ \ No newline at end of file diff --git a/core/common/include/softbus_def.h b/core/common/include/softbus_def.h new file mode 100755 index 000000000..43e3c9ec8 --- /dev/null +++ b/core/common/include/softbus_def.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SOFTBUS_DEF_H +#define SOFTBUS_DEF_H + +#include +#include "stdint.h" +#include "common_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define INVALID_SESSION_ID (-1) +#define INVALID_CHANNEL_ID (-1) + +#define PKG_NAME_SIZE_MAX 65 +#define SESSION_NAME_SIZE_MAX 65 +#define DEVICE_ID_SIZE_MAX 65 +#define GROUP_ID_SIZE_MAX 65 +#define AUTH_STATE_SIZE_MAX 65 + +#define MAX_DEV_INFO_VALUE_LEN 65 +#define MAX_CAPABILITY_LEN 33 +#define MAX_CAPABILITY_DATA_LEN 512 +#define MAX_PACKAGE_NAME_LEN 33 +#define MAX_DEV_INFO_COUNT 32 +#define MAX_PUBLISH_INFO_COUNT 32 +#define IP_LEN 46 +#define MAX_PEERS_NUM 32 +#define MAX_OPERATION_CODE_LEN 32 +#define SESSION_KEY_LENGTH 32 +#define DEVICE_KEY_LEN 16 + +#define MAX_SESSION_ID 16 +#define MAX_SESSION_SERVER_NUMBER 8 + +#ifdef SOFTBUS_WATCH +#define TRANS_BYTES_LENGTH_MAX (3 * 1024) +#else +#define TRANS_BYTES_LENGTH_MAX (4 * 1024) +#endif +#define TRANS_MESSAGE_LENGTH_MAX 1024 + +typedef struct { + pthread_mutex_t lock; + unsigned int cnt; + ListNode list; +} SoftBusList; + +typedef enum { + SEC_TYPE_UNKNOWN = 0, + SEC_TYPE_PLAINTEXT = 1, + SEC_TYPE_CIPHERTEXT = 2, +} SoftBusSecType; + +/* Timer type */ +enum { + TIMER_TYPE_ONCE, + TIMER_TYPE_PERIOD, + TIMER_TYPE_MAX, +}; + +struct CommonScvId { + unsigned int handle; + unsigned int token; + unsigned int cookie; + void *ipcCtx; + unsigned int cbId; +}; + +typedef enum { + TRANS_SESSION_BYTES = 0, + TRANS_SESSION_MESSAGE, +} SessionPktType; + +typedef enum { + CHANNEL_TYPE_TCP_DIRECT = 0, + CHANNEL_TYPE_PROXY, + CHANNEL_TYPE_FILE, + CHANNEL_TYPE_BUTT, +} ChannelType; + +typedef struct { + int32_t channelId; + int32_t channelType; + int32_t fd; + bool isServer; + bool isEnabled; + int32_t peerUid; + int32_t peerPid; + char *groupId; + uint32_t keyLen; + char *sessionKey; + char *peerSessionName; + char *peerDeviceId; +} ChannelInfo; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_DEF_H */ + diff --git a/core/common/include/softbus_errcode.h b/core/common/include/softbus_errcode.h new file mode 100755 index 000000000..67faa6105 --- /dev/null +++ b/core/common/include/softbus_errcode.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_ERROR_CODE_H +#define SOFTBUS_ERROR_CODE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +enum SoftBusErrNo { + SOFTBUS_PUBLIC_ERR_BASE = (-13000), + + SOFTBUS_FRAMEWORK_ERR_BASE = (-12000), + + SOFTBUS_TRANS_ERR_BASE = (-11000), + + SOFTBUS_TRANS_INVALID_SESSION_NAME, + SOFTBUS_TRANS_SESSION_REPEATED, + SOFTBUS_TRANS_SESSION_CNT_EXCEEDS_LIMIT, + SOFTBUS_TRANS_SESSIONSERVER_NOT_CREATED, + SOFTBUS_TRANS_SESSION_OPENING, + + SOFTBUS_TRANS_PROXY_PACKMSG_ERR, + SOFTBUS_TRANS_PROXY_SEND_CHANNELID_INVALID, + SOFTBUS_TRANS_PROXY_CHANNLE_STATUS_INVALID, + SOFTBUS_TRANS_PROXY_DEL_CHANNELID_INVALID, + SOFTBUS_TRANS_PROXY_SESS_ENCRYPT_ERR, + + SOFTBUS_AUTH_ERR_BASE = (-9000), + SOFTBUS_AUTH_VERIFIED, + SOFTBUS_AUTH_VERIFYING, + + SOFTBUS_NETWORK_ERR_BASE = (-7000), + + SOFTBUS_CONN_ERR_BASE = (-5000), + SOFTBUS_CONN_FAIL, + SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT, + SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT, + SOFTBUS_CONN_MANAGER_PKT_LEN_INVALID, + SOFTBUS_CONN_MANAGER_LIST_NOT_INIT, + SOFTBUS_CONNECTION_BASE, + SOFTBUS_CONNECTION_ERR_CLOSED, + SOFTBUS_CONNECTION_ERR_DRIVER_CONGEST, + SOFTBUS_CONNECTION_ERR_SOFTBUS_CONGEST, + SOFTBUS_CONNECTION_ERR_CONNID_INVALID, + SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL, + SOFTBUS_BRCONNECTION_POSTBYTES_ERROR, + SOFTBUS_BRCONNECTION_GETCONNINFO_ERROR, + SOFTBUS_BRCONNECTION_STRNCPY_ERROR, + SOFTBUS_BRCONNECTION_PACKJSON_ERROR, + SOFTBUS_BRCONNECTION_CONNECTDEVICE_MALLOCFAIL, + SOFTBUS_BRCONNECTION_CONNECTDEVICE_GETSOCKETIDFAIL, + SOFTBUS_BRCONNECTION_DISCONNECT_NOTFIND, + SOFTBUS_TCPCONNECTION_SOCKET_ERR, + + SOFTBUS_DISCOVER_ERR_BASE = (-3000), + + SOFTBUS_DISCOVER_NOT_INIT, + SOFTBUS_DISCOVER_INVALID_PKGNAME, + SOFTBUS_DISCOVER_SERVER_NO_PERMISSION, + SOFTBUS_DISCOVER_MANAGER_NOT_INIT, + SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE, + SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, + SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE, + SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL, + SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID, + SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM, + SOFTBUS_DISCOVER_MANAGER_INVALID_PARAM, + SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM, + SOFTBUS_DISCOVER_MANAGER_INVALID_PKGNAME, + SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE, + SOFTBUS_DISCOVER_COAP_NOT_INIT, + SOFTBUS_DISCOVER_COAP_INIT_FAIL, + SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL, + SOFTBUS_DISCOVER_COAP_CANCEL_CAP_FAIL, + SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL, + SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL, + SOFTBUS_DISCOVER_COAP_REGISTER_DEVICE_FAIL, + SOFTBUS_DISCOVER_COAP_START_PUBLISH_FAIL, + SOFTBUS_DISCOVER_COAP_STOP_PUBLISH_FAIL, + SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL, + SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL, + + SOFTBUS_COMMOM_ERR_BASE = (-1000), + SOFTBUS_TIMOUT, + SOFTBUS_INVALID_PARAM, + SOFTBUS_MEM_ERR, + SOFTBUS_NOT_IMPLEMENT, + SOFTBUS_NO_URI_QUERY_KEY, + SOFTBUS_NO_INIT, + SOFTBUS_PARSE_JSON_ERR, + SOFTBUS_PERMISSION_DENIED, + SOFTBUS_MALLOC_ERR, + SOFTBUS_ENCRYPT_ERR, + SOFTBUS_DECRYPT_ERR, + SOFTBUS_INVALID_SESS_OPCODE, + SOFTBUS_INVALID_NUM, + SOFTBUS_SERVER_NAME_REPEATED, + SOFTBUS_TCP_SOCKET_ERR, + SOFTBUS_LOCK_ERR, + SOFTBUS_GET_REMOTE_UUID_ERR, + SOFTBUS_NO_ENOUGH_DATA, + SOFTBUS_INVALID_DATA_HEAD, + SOFTBUS_INVALID_FD, + SOFTBUS_FILE_ERR, + + SOFTBUS_ERR = (-1), + SOFTBUS_OK = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_ERRCODE_H */ diff --git a/core/common/include/softbus_json_utils.h b/core/common/include/softbus_json_utils.h new file mode 100644 index 000000000..0271c0d44 --- /dev/null +++ b/core/common/include/softbus_json_utils.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SOFTBUS_JSON_UTILS_H +#define SOFTBUS_JSON_UTILS_H + +#include "cJSON.h" +#include "string.h" +#include "stdbool.h" +#include "softbus_log.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +bool GetJsonObjectStringItem(const cJSON *json, const char * const string, char *target, int targetLen); + +bool GetJsonObjectNumberItem(const cJSON *json, const char * const string, int *target); + +bool GetJsonObjectDoubleItem(const cJSON *json, const char * const string, double *target); + +bool GetJsonObjectBoolItem(const cJSON *json, const char * const string, bool *target); + +bool AddStringToJsonObject(cJSON *json, const char * const string, const char *value); + +bool AddNumberToJsonObject(cJSON *json, const char * const string, int num); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_JSON_UTILS_H */ \ No newline at end of file diff --git a/core/common/include/softbus_log.h b/core/common/include/softbus_log.h new file mode 100755 index 000000000..d93ecfc2d --- /dev/null +++ b/core/common/include/softbus_log.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_LOG_H +#define SOFTBUS_LOG_H + +#include +#include + +#ifndef SOFTBUS_DEBUG +#if defined(__LITEOS_M__) +#include "hiview_log.h" +#else +#include "hilog/log.h" +#endif +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifndef SOFTBUS_DEBUG +#if defined(__LITEOS_M__) + +#define LOG_DBG(fmt, ...) HILOG_DEBUG(HILOG_MODULE_SOFTBUS, fmt"\n", ##__VA_ARGS__); +#define LOG_INFO(fmt, ...) HILOG_INFO(HILOG_MODULE_SOFTBUS, fmt"\n", ##__VA_ARGS__); +#define LOG_WARN(fmt, ...) HILOG_WARN(HILOG_MODULE_SOFTBUS, fmt"\n", ##__VA_ARGS__); +#define LOG_ERR(fmt, ...) HILOG_ERROR(HILOG_MODULE_SOFTBUS, fmt"\n", ##__VA_ARGS__); +#else + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD0015C0 +#define LOG_TAG "dsoftbus_standard" + +#define LOG_DBG(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt"\n", ##__VA_ARGS__); +#define LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, fmt"\n", ##__VA_ARGS__); +#define LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, fmt"\n", ##__VA_ARGS__); +#define LOG_ERR(fmt, ...) HILOG_ERROR(LOG_CORE, fmt"\n", ##__VA_ARGS__); +#endif +#else +enum { + SOFTBUS_LOG_LEVEL_DEBUG = 0, + SOFTBUS_LOG_LEVEL_INFO, + SOFTBUS_LOG_LEVEL_WARNING, + SOFTBUS_LOG_LEVEL_ERROR +}; + +#define SOFTBUS_LOG_LEVEL SOFTBUS_LOG_LEVEL_INFO + +#define LOG_DBG(fmt, ...) do { \ + if (SOFTBUS_LOG_LEVEL_DEBUG >= SOFTBUS_LOG_LEVEL) { \ + printf("DEBUG:%s:%d " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ +} while (0) + +#define LOG_INFO(fmt, ...) do { \ + if (SOFTBUS_LOG_LEVEL_INFO >= SOFTBUS_LOG_LEVEL) { \ + printf("INFO:%s:%d " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ +} while (0) + +#define LOG_WARN(fmt, ...) do { \ + if (SOFTBUS_LOG_LEVEL_WARNING >= SOFTBUS_LOG_LEVEL) { \ + printf("WARN:%s:%d " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ +} while (0) + +#define LOG_ERR(fmt, ...) do { \ + if (SOFTBUS_LOG_LEVEL_ERROR >= SOFTBUS_LOG_LEVEL) { \ + printf("ERROR:%s:%d " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ +} while (0) +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* SOFTBUS_LOG_H */ diff --git a/core/common/include/softbus_permission.h b/core/common/include/softbus_permission.h new file mode 100755 index 000000000..a7070795c --- /dev/null +++ b/core/common/include/softbus_permission.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PERMISSION_H +#define SOFTBUS_PERMISSION_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define PERMISSION_JSON_FILE "/system/etc/communication/softbus/permission.json" + +#define ACTION_CREATE 0x1 +#define ACTION_OPEN 0x2 + +enum { + SYSTEM_APP = 0, + NATIVE_APP, + SELF_APP, + NORMAL_APP, + GRANTED_APP, +}; + +int32_t TransPermissionInit(const char *fileName); +void TransPermissionDeinit(void); +int32_t CheckTransPermission(const char *pkgName, const char *SessionName, uint32_t action); +bool CheckDiscPermission(const char *pkgName); +bool CheckBusCenterPermission(const char *pkgName); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* SOFTBUS_PERMISSION_H */ diff --git a/core/common/include/softbus_property.h b/core/common/include/softbus_property.h new file mode 100755 index 000000000..25d5e7ea3 --- /dev/null +++ b/core/common/include/softbus_property.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROPERTY_H +#define SOFTBUS_PROPERTY_H + +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +// softbus default defined value +#define MAX_BYTES_LENGTH (4 * 1024 * 1024) // Bytes max size 4M +#define MAX_MESSAGE_LENGTH (4 * 1024) // Message max size 4K +#define MAX_BUF_LENGTH (MAX_MESSAGE_LENGTH + 64) + +int GetPropertyString(const char *string, char *target, size_t targetLen); + +int GetPropertyInt(const char *string, int *target); + +int GetPropertyDouble(const char *string, double *target); + +int GetPropertyBool(const char *string, bool *target); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_PROPERTY_H */ diff --git a/core/common/include/softbus_type_def.h b/core/common/include/softbus_type_def.h new file mode 100644 index 000000000..62e3ec35b --- /dev/null +++ b/core/common/include/softbus_type_def.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_TYPE_DEF_H +#define SOFTBUS_TYPE_DEF_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* SOFTBUS_TYPE_DEF_H */ diff --git a/core/common/include/softbus_utils.h b/core/common/include/softbus_utils.h new file mode 100644 index 000000000..33b6b603d --- /dev/null +++ b/core/common/include/softbus_utils.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_UTILS_H +#define SOFTBUS_UTILS_H + +#include "softbus_def.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define HEXIFY_UNIT_LEN 2 +#define UN_HEXIFY_LEN(len) ((len) / HEXIFY_UNIT_LEN) +#define HEXIFY_LEN(len) ((len) * HEXIFY_UNIT_LEN + 1) +#define HEX_MAX_NUM 16 +#define DEC_MAX_NUM 10 +#define HEX_MAX_BIT_NUM 4 +#define MAX_QUERY_LEN 64 + +#define TIMER_TIMEOUT 1000 // 1s + +typedef void (*TimerFunCallback)(void); + +typedef enum { + SOFTBUS_CONN_TIMER_FUN, + SOFTBUS_AUTHEN_TIMER_FUN, + SOFTBUS_SESSION_TIMER_FUN, + SOFTBUS_PROXYCHANNEL_TIMER_FUN, + SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, + SOFTBUS_MAX_TIMER_FUN_NUM +} SoftBusTimerFunEnum; + +int32_t RegisterTimeoutCallback(int32_t timerFunId, TimerFunCallback callback); + +int32_t SoftBusTimerInit(void); + +void SoftBusTimerDeInit(void); +SoftBusList *CreateSoftBusList(void); + +void DestroySoftBusList(SoftBusList *list); + +int32_t GenerateRandomArray(unsigned char *randStr, uint32_t len); + +int32_t ConvertBytesToHexString(char *outBuf, uint32_t outBufLen, const unsigned char *inBuf, int32_t inLen); + +int32_t ConvertHexStringToBytes(unsigned char *outBuf, uint32_t outBufLen, const char *inBuf, int32_t inLen); + +int32_t GenerateRandomStr(char *str, uint32_t size); + +bool IsValidString(const char *input, uint32_t maxLen); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* SOFTBUS_UTILS_H */ \ No newline at end of file diff --git a/core/common/inner_communication/c/softbus_client_interface.c b/core/common/inner_communication/c/softbus_client_interface.c new file mode 100644 index 000000000..36e3e38a0 --- /dev/null +++ b/core/common/inner_communication/c/softbus_client_interface.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_interface.h" +#include + +#include "softbus_def.h" +#include "softbus_errcode.h" + +#if defined(__LITEOS_M__) +extern int TransOnChannelOpened(const char *pkgName, const char* sessionName, const ChannelInfo* channel); + +extern int TransOnChannelOpenFailed(const char *pkgName, int32_t channelId); + +extern int TransOnChannelClosed(const char *pkgName, int32_t channelId); + +extern int TransOnChannelMsgReceived(const char *pkgName, int32_t channelId, + const void *data, unsigned int len, int32_t type); + +extern int LnnOnJoinResult(void *addr, const char *networkId, int32_t retCode); + +extern int LnnOnLeaveResult(const char *networkId, int32_t retCode); + +extern int LnnOnNodeOnlineStateChanged(bool isOnline, void *info); + +extern int LnnOnNodeBasicInfoChanged(void *info, int32_t type); +#else +int __attribute__ ((weak)) TransOnChannelOpened(const char *sessionName, const ChannelInfo *channel) +{ + (void)sessionName; + (void)channel; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransOnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + (void)pkgName; + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransOnChannelClosed(const char *pkgName, int32_t channelId) +{ + (void)pkgName; + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransOnChannelMsgReceived(const char *pkgName, int32_t channelId, + const void *data, unsigned int len, int32_t type) +{ + (void)channelId; + (void)data; + (void)len; + (void)type; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) LnnOnJoinResult(void *addr, const char *networkId, int32_t retCode) +{ + (void)addr; + (void)networkId; + (void)retCode; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) LnnOnLeaveResult(const char *networkId, int32_t retCode) +{ + (void)networkId; + (void)retCode; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) LnnOnNodeOnlineStateChanged(bool isOnline, void *info) +{ + (void)isOnline; + (void)info; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) LnnOnNodeBasicInfoChanged(void *info, int32_t type) +{ + (void)info; + (void)type; + return SOFTBUS_NOT_IMPLEMENT; +} +#endif + +static int ClientOnJoinLNNResult(const char *pkgName, void *addr, uint32_t addrTypeLen, + const char *networkId, int32_t retCode) +{ + (void)pkgName; + (void)addrTypeLen; + return LnnOnJoinResult(addr, networkId, retCode); +} + +static int ClientOnLeaveLNNResult(const char *pkgName, const char *networkId, int32_t retCode) +{ + (void)pkgName; + return LnnOnLeaveResult(networkId, retCode); +} + +static int ClinetOnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) +{ + (void)infoTypeLen; + return LnnOnNodeOnlineStateChanged(isOnline, info); +} + +static int ClinetOnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + (void)infoTypeLen; + return LnnOnNodeBasicInfoChanged(info, type); +} + +static struct ClientProvideInterface g_clientProvideInterface = { + .onChannelOpened = TransOnChannelOpened, + .onChannelOpenFailed = TransOnChannelOpenFailed, + .onChannelClosed = TransOnChannelClosed, + .onChannelMsgReceived = TransOnChannelMsgReceived, + + .onJoinLNNResult = ClientOnJoinLNNResult, + .onLeaveLNNResult = ClientOnLeaveLNNResult, + .onNodeOnlineStateChanged = ClinetOnNodeOnlineStateChanged, + .onNodeBasicInfoChanged = ClinetOnNodeBasicInfoChanged, +}; + +struct ClientProvideInterface *GetClientProvideInterface(void) +{ + return &g_clientProvideInterface; +} + +int ClientProvideInterfaceInit(void) +{ + return SOFTBUS_OK; +} + +void *SoftBusGetIpcContext(void) +{ + return NULL; +} diff --git a/core/common/inner_communication/c/softbus_client_interface_impl.c b/core/common/inner_communication/c/softbus_client_interface_impl.c new file mode 100644 index 000000000..183da850e --- /dev/null +++ b/core/common/inner_communication/c/softbus_client_interface_impl.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_errcode.h" + +int ClientProvideInterfaceImplInit(const char *name) +{ + (void)name; + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/common/inner_communication/c/softbus_server_interface.c b/core/common/inner_communication/c/softbus_server_interface.c new file mode 100755 index 000000000..72aa34f7a --- /dev/null +++ b/core/common/inner_communication/c/softbus_server_interface.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_interface.h" + +#include "softbus_errcode.h" +#include "softbus_log.h" + +#if defined(__LITEOS_M__) +extern int TransCreateSessionServer(const char *pkgName, const char *sessionName); + +extern int TransRemoveSessionServer(const char *pkgName, const char *sessionName); + +extern int TransOpenSession(const char *mySessionName, + const char *peerSessionName, const char *peerDeviceId, const char *groupId, int flags); + +extern int TransCloseChannel(int32_t channelId); + +extern int TransSendMsg(int32_t channelId, const void *data, uint32_t len, int32_t msgType); + +extern int LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen); + +extern int LnnIpcServerLeave(const char *pkgName, const char *networkId); + +extern int LnnIpcGetAllOnlineNodeInfo(void **info, uint32_t infoTypeLen, int32_t *infoNum); + +extern int LnnIpcGetLocalDeviceInfo(void *info, uint32_t infoTypeLen); + +extern int LnnIpcGetNodeKeyInfo(const char *networkId, int key, unsigned char *buf, uint32_t len); + +#else +int __attribute__ ((weak)) TransCreateSessionServer(const char *pkgName, const char *sessionName) +{ + (void)pkgName; + (void)sessionName; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransRemoveSessionServer(const char *pkgName, const char *sessionName) +{ + (void)pkgName; + (void)sessionName; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransOpenSession(const char *mySessionName, + const char *peerSessionName, const char *peerDeviceId, const char *groupId, int flags) +{ + (void)mySessionName; + (void)peerSessionName; + (void)peerDeviceId; + (void)groupId; + (void)flags; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransCloseChannel(int32_t channelId) +{ + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) TransSendMsg(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + (void)channelId; + (void)data; + (void)len; + (void)msgType; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + (void)pkgName; + (void)addr; + (void)addrTypeLen; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) LnnIpcServerLeave(const char *pkgName, const char *networkId) +{ + (void)pkgName; + (void)networkId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) LnnIpcGetAllOnlineNodeInfo(void **info, + uint32_t infoTypeLen, int32_t *infoNum) +{ + (void)info; + (void)infoTypeLen; + (void)infoNum; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) LnnIpcGetLocalDeviceInfo(void *info, uint32_t infoTypeLen) +{ + (void)info; + (void)infoTypeLen; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) LnnIpcGetNodeKeyInfo(const char *networkId, + int key, unsigned char *buf, uint32_t len) +{ + (void)networkId; + (void)key; + (void)buf; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} +#endif + +static int32_t ServerIpcJoinLNN(void *addr, uint32_t addrTypeLen) +{ + return LnnIpcServerJoin(NULL, addr, addrTypeLen); +} + +static int32_t ServerIpcLeaveLNN(const char *networkId) +{ + return LnnIpcServerLeave(NULL, networkId); +} + +static struct ServerProvideInterface g_serverProvideInterface = { + .registerService = NULL, + .createSessionServer = TransCreateSessionServer, + .removeSessionServer = TransRemoveSessionServer, + .openSession = TransOpenSession, + .closeChannel = TransCloseChannel, + .sendMessage = TransSendMsg, + .joinLNN = ServerIpcJoinLNN, + .leaveLNN = ServerIpcLeaveLNN, + .getAllOnlineNodeInfo = LnnIpcGetAllOnlineNodeInfo, + .getLocalDeviceInfo = LnnIpcGetLocalDeviceInfo, + .getNodeKeyInfo = LnnIpcGetNodeKeyInfo, +}; + +int ServerProvideInterfaceInit(void) +{ + LOG_INFO("ServerProvideInterfaceInit"); + return SOFTBUS_OK; +} + +struct ServerProvideInterface *GetServerProvideInterface(void) +{ + return &g_serverProvideInterface; +} + +void *SoftBusGetClientProxy(void) +{ + return NULL; +} \ No newline at end of file diff --git a/core/common/inner_communication/c/softbus_server_interface_impl.c b/core/common/inner_communication/c/softbus_server_interface_impl.c new file mode 100755 index 000000000..76b721c18 --- /dev/null +++ b/core/common/inner_communication/c/softbus_server_interface_impl.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_errcode.h" + +int ServerProvideInterfaceImplInit(void) +{ + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/common/inner_communication/ipc/include/softbus_client_weak.h b/core/common/inner_communication/ipc/include/softbus_client_weak.h new file mode 100644 index 000000000..cf8da3bc5 --- /dev/null +++ b/core/common/inner_communication/ipc/include/softbus_client_weak.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_WEAK_H +#define SOFTBUS_CLIENT_WEAK_H + +#include "liteipc_adapter.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* Client Implement function */ +void __attribute__ ((weak)) ClientIpcOnChannelOpened(IpcIo *io); + +void __attribute__ ((weak)) ClientIpcOnChannelOpenFailed(IpcIo *io); + +void __attribute__ ((weak)) ClientIpcOnChannelClosed(IpcIo *io); + +void __attribute__ ((weak)) ClientIpcOnChannelMsgReceived(IpcIo *io); + +/* Client Invoke function */ +int __attribute__ ((weak)) ServerIpcPublishService(const char *pkgName, const void *info); + +int __attribute__ ((weak)) ServerIpcUnPublishService(const char *pkgName, int publishId); + +int __attribute__ ((weak)) ServerIpcCreateSessionServer(const char *pkgName, const char *sessionName); + +int __attribute__ ((weak)) ServerIpcRemoveSessionServer(const char *pkgName, const char *sessionName); + +int __attribute__ ((weak)) ServerIpcOpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int flags); + +int __attribute__ ((weak)) ServerIpcCloseChannel(int32_t channelId); + +int __attribute__ ((weak)) ServerIpcSendMessage(int32_t channelId, const void *data, unsigned int len); + +int __attribute__ ((weak)) ServerIpcCreateChannelServer(const char *pkgName); + +int __attribute__ ((weak)) ServerIpcRemoveChannelServer(const char *pkgName); + +int __attribute__ ((weak)) ServerIpcSendChannelMsg(const char *connectId, const unsigned char *sendData, + unsigned int len); + +int __attribute__ ((weak)) ServerIpcStartDiscovery(const char *pkgName, const void *info); + +int __attribute__ ((weak)) ServerIpcStopDiscovery(const char *pkgName, int subscribeId); + +int __attribute__ ((weak)) ServerIpcJoinLNN(void *addr); + +int __attribute__ ((weak)) ServerIpcLeaveLNN(const char *networkId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // SOFTBUS_CLIENT_INTERFACE_WEAK_H \ No newline at end of file diff --git a/core/common/inner_communication/ipc/include/softbus_server_weak.h b/core/common/inner_communication/ipc/include/softbus_server_weak.h new file mode 100644 index 000000000..fc0e3eeb0 --- /dev/null +++ b/core/common/inner_communication/ipc/include/softbus_server_weak.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_WEAK_H +#define SOFTBUS_SERVER_WEAK_H + +#include "liteipc_adapter.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* Server Implement function */ +int __attribute__ ((weak)) ServerPublishService(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerUnPublishService(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerCreateSessionServer(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerRemoveSessionServer(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerOpenSession(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerCloseSession(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerSendSessionMsg(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerCreateChannelServer(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerRemoveChannelServer(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerSendChannelMsg(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerStartDiscovery(void *origin, IpcIo *req, IpcIo *reply); + +int __attribute__ ((weak)) ServerStopDiscovery(void *origin, IpcIo *req, IpcIo *reply); + +/* Server Invoke function */ +int __attribute__((weak)) ClientIpcOnChannelOpened(const void *channel); + +int __attribute__((weak)) ClientIpcOnChannelClosed(int32_t channelId); + +int __attribute__((weak)) ClientIpcOnChannelMsgReiceived(int32_t channelId, const void *data, unsigned int len); + +int __attribute__((weak)) ClientIpcOnJoinLNNResult(void *addr, const char *networkId, int32_t retCode); + +int __attribute__((weak)) ClientIpcOnLeaveLNNResult(const char *networkId, int32_t retCode); + +int __attribute__((weak)) ClientIpcOnNodeOnlineStateChanged(bool isOnline, void *info); + +int __attribute__((weak)) ClientIpcOnNodeBasicInfoChanged(void *info, int32_t type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // SOFTBUS_SERVER_WEAK_H \ No newline at end of file diff --git a/core/common/inner_communication/ipc/softbus_client_interface.c b/core/common/inner_communication/ipc/softbus_client_interface.c new file mode 100644 index 000000000..9643b5026 --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_client_interface.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "iproxy_server.h" +#include "samgr_lite.h" +#include "securec.h" +#include "softbus_client_info_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_server_weak.h" + +static IpcContext *g_svcIpcCtx = NULL; + +static void ConvertSvcId(const struct CommonScvId *svcId, SvcIdentity *svc) +{ + if ((svcId == NULL) || (svc == NULL)) { + LOG_ERR("scvId is NULL, convert failed."); + return; + } + svc->handle = svcId->handle; + svc->token = svcId->token; + svc->cookie = svcId->cookie; +#ifdef __LINUX__ + svc->ipcContext = svcId->ipcCtx; +#endif +} + +static struct ClientProvideInterface g_clientProvideInterface = { + .onChannelOpened = ClientIpcOnChannelOpened, + .onChannelClosed = ClientIpcOnChannelClosed, + .onChannelMsgReceived = ClientIpcOnChannelMsgReiceived, + .onJoinLNNResult = ClientIpcOnJoinLNNResult, + .onLeaveLNNResult = ClientIpcOnLeaveLNNResult, + .onNodeOnlineStateChanged = ClientIpcOnNodeOnlineStateChanged, + .onNodeBasicInfoChanged = ClientIpcOnNodeBasicInfoChanged, +}; + +struct ClientProvideInterface *GetClientProvideInterface(void) +{ + return &g_clientProvideInterface; +} + +int ClientProvideInterfaceInit(void) +{ + g_svcIpcCtx = NULL; + return SOFTBUS_OK; +} + +void *SoftBusGetIpcContext(void) +{ + return g_svcIpcCtx; +} diff --git a/core/common/inner_communication/ipc/softbus_client_interface_impl.c b/core/common/inner_communication/ipc/softbus_client_interface_impl.c new file mode 100755 index 000000000..d5af0140f --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_client_interface_impl.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "iproxy_client.h" +#include "samgr_lite.h" +#include "securec.h" +#include "softbus_client_event_manager.h" +#include "softbus_client_frame_manager.h" +#include "softbus_client_weak.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_os_interface.h" + +#define WAIT_SERVER_READY_INTERVAL 100 +#define INVALID_CB_ID 0xFF + +static int RegisterServerDeathCb(void); +static unsigned int g_deathCbId = INVALID_CB_ID; +static SvcIdentity g_svcIdentity = {0}; + +struct SoftBusIpcClientCmd { + uint32_t code; + void (*func)(IpcIo *io); +}; + +static struct SoftBusIpcClientCmd g_softBusIpcClientCmdTbl[] = { + { CLIENT_ON_CHANNEL_OPENED, ClientIpcOnChannelOpened }, + { CLIENT_ON_CHANNEL_OPENFAILED, ClientIpcOnChannelOpenFailed }, + { CLIENT_ON_CHANNEL_CLOSED, ClientIpcOnChannelClosed }, + { CLIENT_ON_CHANNEL_MSGRECEIVED, ClientIpcOnChannelMsgReceived }, +}; + +static int ClientIpcInterfaceMsgHandle(const IpcContext *ctx, void *ipcMsg, IpcIo *io, void *arg) +{ + uint32_t code = 0; + (void)ctx; + (void)arg; + + if (ipcMsg == NULL || io == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + GetCode(ipcMsg, &code); + LOG_INFO("receive ipc transact code(%u)", code); + unsigned int num = sizeof(g_softBusIpcClientCmdTbl) / sizeof(struct SoftBusIpcClientCmd); + for (unsigned int i = 0; i < num; i++) { + if (code == g_softBusIpcClientCmdTbl[i].code) { + g_softBusIpcClientCmdTbl[i].func(io); + return SOFTBUS_OK; + } + } + + LOG_ERR("not support code(%u)", code); + return SOFTBUS_ERR; +} + +static int RegisterService(void) +{ + char clientName[PKG_NAME_SIZE_MAX] = {0}; + if (GetSoftBusClientName(clientName, sizeof(clientName)) != SOFTBUS_OK) { + LOG_ERR("get client name failed"); + return SOFTBUS_ERR; + } + + struct CommonScvId svcId = {0}; + if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie, &svcId.ipcCtx) != SOFTBUS_OK) { + LOG_ERR("get client identity failed"); + return SOFTBUS_ERR; + } + + while (GetServerProvideInterface()->registerService(clientName, &svcId) != SOFTBUS_OK) { + SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL); + continue; + } + + LOG_INFO("success"); + return SOFTBUS_OK; +} + +static void UnregisterServerDeathCb(void) +{ + UnregisterDeathCallback(g_svcIdentity, g_deathCbId); + g_deathCbId = INVALID_CB_ID; + g_svcIdentity.handle = 0; + g_svcIdentity.token = 0; + g_svcIdentity.cookie = 0; +} + +static void *DeathProcTask(void *arg) +{ + CLIENT_NotifyObserver(EVENT_SERVER_DEATH, NULL, 0); + + if (RegisterService() != SOFTBUS_OK) { + LOG_ERR("register service failed"); + return NULL; + } + + LOG_INFO("\n<< !!! SERVICE (%s) RECOVER !!! >>\n", SOFTBUS_SERVICE); + CLIENT_NotifyObserver(EVENT_SERVER_RECOVERY, NULL, 0); + UnregisterServerDeathCb(); + + if (RegisterServerDeathCb() != SOFTBUS_OK) { + LOG_ERR("reg server death cb failed"); + return NULL; + } + + return NULL; +} + +static int StartDeathProcTask(void) +{ + int ret; + pthread_t tid; + pthread_attr_t attr; + + ret = pthread_attr_init(&attr); + if (ret != 0) { + LOG_ERR("pthread_attr_init failed, ret[%d]", ret); + return SOFTBUS_ERR; + } + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (ret != 0) { + LOG_ERR("pthread set detached attr failed, ret[%d]", ret); + ret = SOFTBUS_ERR; + goto EXIT; + } + + ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); + if (ret != 0) { + LOG_ERR("pthread set sched failed, ret[%d]", ret); + ret = SOFTBUS_ERR; + goto EXIT; + } + + ret = pthread_create(&tid, &attr, DeathProcTask, NULL); + if (ret != 0) { + LOG_ERR("create DeathProcTask failed, ret[%d]", ret); + ret = SOFTBUS_ERR; + goto EXIT; + } + + return SOFTBUS_OK; +EXIT: + if (pthread_attr_destroy(&attr) != 0) { + LOG_ERR("destroy pthread attr failed, ret[%d]", ret); + ret = SOFTBUS_ERR; + } + + return ret; +} + +static int32_t DeathCallback(const IpcContext *ctx, void *ipcMsg, IpcIo *data, void *arg) +{ + (void)ctx; + (void)ipcMsg; + (void)data; + (void)arg; + + LOG_WARN("\n<< ATTENTION !!! >> SERVICE (%s) DEAD !!!\n", SOFTBUS_SERVICE); + + if (StartDeathProcTask() != SOFTBUS_OK) { + LOG_ERR("start death proc task failed"); + return SOFTBUS_ERR; + } else { + LOG_INFO("client start check softbus server..."); + } + + return SOFTBUS_OK; +} + +static int RegisterServerDeathCb(void) +{ + g_svcIdentity = SAMGR_GetRemoteIdentity(SOFTBUS_SERVICE, NULL); + g_deathCbId = INVALID_CB_ID; + if (RegisterDeathCallback(NULL, g_svcIdentity, DeathCallback, NULL, &g_deathCbId) != EC_SUCCESS) { + LOG_ERR("reg death callback failed"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int ClientProvideInterfaceImplInit(void) +{ + SvcIdentity clientIdentity = {0}; + int ret = RegisterIpcCallback(ClientIpcInterfaceMsgHandle, 0, IPC_WAIT_FOREVER, &clientIdentity, NULL); + if (ret != 0) { + LOG_ERR("register ipc cb failed"); + return SOFTBUS_ERR; + } +#ifdef __LINUX__ + SetClientIdentity(clientIdentity.handle, clientIdentity.token, clientIdentity.cookie, clientIdentity.ipcContext); +#else + SetClientIdentity(clientIdentity.handle, clientIdentity.token, clientIdentity.cookie, NULL); +#endif + + if (RegisterService() != SOFTBUS_OK) { + LOG_ERR("register service failed"); + return SOFTBUS_ERR; + } + + if (RegisterServerDeathCb() != SOFTBUS_OK) { + LOG_ERR("reg server death cb failed"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/common/inner_communication/ipc/softbus_client_weak.c b/core/common/inner_communication/ipc/softbus_client_weak.c new file mode 100644 index 000000000..a622a23ed --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_client_weak.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_weak.h" +#include "softbus_errcode.h" + +void __attribute__ ((weak)) ClientIpcOnChannelOpened(IpcIo *io) +{ + (void)io; +} + +void __attribute__ ((weak)) ClientIpcOnChannelOpenFailed(IpcIo *io) +{ + (void)io; +} + +void __attribute__ ((weak)) ClientIpcOnChannelClosed(IpcIo *io) +{ + (void)io; +} + +void __attribute__ ((weak)) ClientIpcOnChannelMsgReceived(IpcIo *io) +{ + (void)io; +} + +int __attribute__ ((weak)) ServerIpcPublishService(const char *pkgName, const void *info) +{ + (void)pkgName; + (void)info; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcUnPublishService(const char *pkgName, int publishId) +{ + (void)pkgName; + (void)publishId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcCreateSessionServer(const char *pkgName, const char *sessionName) +{ + (void)pkgName; + (void)sessionName; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcRemoveSessionServer(const char *pkgName, const char *sessionName) +{ + (void)pkgName; + (void)sessionName; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcOpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int flags) +{ + (void)mySessionName; + (void)peerSessionName; + (void)peerDeviceId; + (void)groupId; + (void)flags; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcCloseChannel(int32_t channelId) +{ + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcSendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + (void)channelId; + (void)data; + (void)len; + (void)msgType; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcStartDiscovery(const char *pkgName, const void *info) +{ + (void)pkgName; + (void)info; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcStopDiscovery(const char *pkgName, int subscribeId) +{ + (void)pkgName; + (void)subscribeId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcJoinLNN(void *addr) +{ + (void)addr; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__ ((weak)) ServerIpcLeaveLNN(const char *networkId) +{ + (void)networkId; + return SOFTBUS_NOT_IMPLEMENT; +} \ No newline at end of file diff --git a/core/common/inner_communication/ipc/softbus_server_interface.c b/core/common/inner_communication/ipc/softbus_server_interface.c new file mode 100644 index 000000000..193811ea2 --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_server_interface.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "iproxy_client.h" +#include "liteipc_adapter.h" +#include "samgr_lite.h" +#include "securec.h" +#include "softbus.h" +#include "softbus_client_weak.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_os_interface.h" + +#define WAIT_SERVER_READY_INTERVAL 200 + +static IClientProxy *g_clientProxy = NULL; + +static int ClientSimpleResultCb(IOwner owner, int code, IpcIo *reply) +{ + *(int *)owner = IpcIoPopInt32(reply); + LOG_INFO("retvalue:%d", *(int *)owner); + return EC_SUCCESS; +} + +static int ServerIpcRegisterService(const char *name, const struct CommonScvId *svcId) +{ + if ((svcId == NULL) || (name == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + char *data = SoftBusMalloc(MAX_SOFT_BUS_IPC_LEN); + if (data == NULL) { + LOG_ERR("malloc failed"); + return SOFTBUS_ERR; + } + (void)memset_s(data, MAX_SOFT_BUS_IPC_LEN, 0, MAX_SOFT_BUS_IPC_LEN); + + IpcIo request = {0}; + IpcIoInit(&request, data, MAX_SOFT_BUS_IPC_LEN, 1); + IpcIoPushString(&request, name); + + SvcIdentity svc = {0}; + svc.handle = svcId->handle; + svc.token = svcId->token; + svc.cookie = svcId->cookie; +#ifdef __LINUX__ + svc.ipcContext = svcId->ipcCtx; +#endif + IpcIoPushSvc(&request, &svc); + + int ret = SOFTBUS_ERR; + if (g_clientProxy->Invoke(g_clientProxy, MANAGE_REGISTER_SERVICE, &request, &ret, + ClientSimpleResultCb) != EC_SUCCESS) { + SoftBusFree(data); + LOG_INFO("Call back ret(%d)", ret); + return SOFTBUS_ERR; + } + + SoftBusFree(data); + return ret; +} + +static IClientProxy *GetClientProxy(void) +{ + IClientProxy *clientProxy = NULL; + IUnknown *iUnknown = NULL; + int ret; + + LOG_INFO("start get client proxy"); + while (clientProxy == NULL) { + iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(SOFTBUS_SERVICE); + if (iUnknown == NULL) { + SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL); + continue; + } + + ret = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&clientProxy); + if (ret != EC_SUCCESS || clientProxy == NULL) { + LOG_ERR("QueryInterface failed [%d]", ret); + SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL); + continue; + } + } + + LOG_INFO("get client proxy ok"); + return clientProxy; +} + +void __attribute__((weak)) HOS_SystemInit(void) +{ + SAMGR_Bootstrap(); + return; +} + +static struct ServerProvideInterface g_serverProvideInterface = { + .registerService = ServerIpcRegisterService, + .publishService = ServerIpcPublishService, + .unPublishService = ServerIpcUnPublishService, + .createSessionServer = ServerIpcCreateSessionServer, + .removeSessionServer = ServerIpcRemoveSessionServer, + .openSession = ServerIpcOpenSession, + .closeChannel = ServerIpcCloseChannel, + .sendMessage = ServerIpcSendMessage, + .startDiscovery = ServerIpcStartDiscovery, + .stopDiscovery = ServerIpcStopDiscovery, + .joinLNN = ServerIpcJoinLNN, + .leaveLNN = ServerIpcLeaveLNN, +}; + +int ServerProvideInterfaceInit(void) +{ + HOS_SystemInit(); + g_clientProxy = GetClientProxy(); + if (g_clientProxy == NULL) { + LOG_ERR("get ipc client proxy failed"); + return SOFTBUS_ERR; + } + LOG_INFO("ServerProvideInterfaceInit ok"); + return SOFTBUS_OK; +} + +struct ServerProvideInterface *GetServerProvideInterface(void) +{ + return &g_serverProvideInterface; +} + +void *SoftBusGetClientProxy(void) +{ + return g_clientProxy; +} \ No newline at end of file diff --git a/core/common/inner_communication/ipc/softbus_server_interface_impl.c b/core/common/inner_communication/ipc/softbus_server_interface_impl.c new file mode 100644 index 000000000..5fb05f692 --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_server_interface_impl.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "iproxy_server.h" +#include "samgr_lite.h" +#include "securec.h" +#include "softbus_client_info_manager.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_server_weak.h" + +#define STACK_SIZE 0x800 +#define QUEUE_SIZE 20 + +typedef struct { + INHERIT_SERVER_IPROXY; +} DefaultFeatureApi; + +typedef struct { + INHERIT_SERVICE; + INHERIT_IUNKNOWNENTRY(DefaultFeatureApi); + Identity identity; +} SoftbusSamgrService; + +static const char *GetName(Service *service) +{ + (void)service; + return SOFTBUS_SERVICE; +} + +static BOOL Initialize(Service *service, Identity identity) +{ + if (service == NULL) { + LOG_ERR("invalid param"); + return TRUE; + } + + SoftbusSamgrService *samgrService = (SoftbusSamgrService *)service; + samgrService->identity = identity; + return TRUE; +} + +static BOOL MessageHandle(Service *service, Request *msg) +{ + if (service == NULL || msg == NULL) { + LOG_ERR("invalid param"); + return TRUE; + } + return FALSE; +} + +static TaskConfig GetTaskConfig(Service *service) +{ + (void)service; + TaskConfig config = { LEVEL_HIGH, PRI_BELOW_NORMAL, STACK_SIZE, QUEUE_SIZE, SHARED_TASK }; + return config; +} + +static void ClientDeathCallback(const IpcContext *context, void *ipcMsg, IpcIo *data, void *arg) +{ + if (arg == NULL) { + LOG_ERR("package name is NULL."); + return; + } + struct CommonScvId svcId = {0}; + if (SERVER_GetIdentityByPkgName((const char *)arg, &svcId) != SOFTBUS_OK) { + LOG_ERR("not found client by package name."); + SoftBusFree(arg); + arg = NULL; + return; + } + SERVER_UnregisterService((const char *)arg); + SoftBusFree(arg); + arg = NULL; +#ifdef __LINUX__ + BinderRelease(svcId.ipcCtx, svcId.handle); +#endif + SvcIdentity sid = {0}; + sid.handle = svcId.handle; + sid.token = svcId.token; + sid.cookie = svcId.cookie; + UnregisterDeathCallback(sid, svcId.cbId); +} + +static int ServerRegisterService(void *origin, IpcIo *req, IpcIo *reply) +{ + size_t len = 0; + int ret = SOFTBUS_ERR; + struct CommonScvId svcId = {0}; + + uint8_t *name = IpcIoPopString(req, &len); + SvcIdentity *svc = IpcIoPopSvc(req); + if (name == NULL || svc == NULL || len == 0) { + LOG_ERR("get data fail"); + goto EXIT; + } + + svcId.handle = svc->handle; + svcId.token = svc->token; + svcId.cookie = svc->cookie; + SvcIdentity sid = *svc; +#ifdef __LINUX__ + svcId.ipcCtx = svc->ipcContext; + BinderAcquire(svcId.ipcCtx, svcId.handle); + SoftBusFree(svc); + svc = NULL; +#endif + char *pkgName = (char *)SoftBusMalloc(len + 1); + if (pkgName == NULL) { + LOG_ERR("softbus malloc failed!"); + goto EXIT; + } + if (strcpy_s(pkgName, len + 1, (const char *)name) != EOK) { + LOG_ERR("softbus strcpy_s failed!"); + SoftBusFree(pkgName); + goto EXIT; + } + uint32_t cbId = 0; + RegisterDeathCallback(NULL, sid, ClientDeathCallback, pkgName, &cbId); + svcId.cbId = cbId; + ret = SERVER_RegisterService((const char *)name, &svcId); +EXIT: + IpcIoPushInt32(reply, ret); + return SOFTBUS_OK; +} + +typedef struct { + enum SoftBusFuncId id; + int (*func)(void *origin, IpcIo *req, IpcIo *reply); +} ServerInvokeCmd; + +ServerInvokeCmd g_serverInvokeCmdTbl[] = { + { MANAGE_REGISTER_SERVICE, ServerRegisterService }, + { SERVER_PUBLISH_SERVICE, ServerPublishService }, + { SERVER_UNPUBLISH_SERVICE, ServerUnPublishService }, + { SERVER_CREATE_SESSION_SERVER, ServerCreateSessionServer }, + { SERVER_REMOVE_SESSION_SERVER, ServerRemoveSessionServer }, + { SERVER_OPEN_SESSION, ServerOpenSession }, + { SERVER_CLOSE_CHANNEL, ServerCloseSession }, + { SERVER_SESSION_SENDMSG, ServerSendSessionMsg }, + { SERVER_START_DISCOVERY, ServerStartDiscovery}, + { SERVER_STOP_DISCOVERY, ServerStopDiscovery}, +}; + +static int32_t Invoke(const IServerProxy *iProxy, int funcId, const void *origin, + const IpcIo *req, const IpcIo *reply) +{ + LOG_INFO("RECEIVE FUNCID:%d", funcId); + int tblSize = sizeof(g_serverInvokeCmdTbl) / sizeof(ServerInvokeCmd); + for (int i = 0; i < tblSize; i++) { + if (funcId == g_serverInvokeCmdTbl[i].id) { + return g_serverInvokeCmdTbl[i].func(origin, req, reply); + } + } + LOG_ERR("not support func[%d]", funcId); + return SOFTBUS_ERR; +} + +static SoftbusSamgrService g_samgrService = { + .GetName = GetName, + .Initialize = Initialize, + .MessageHandle = MessageHandle, + .GetTaskConfig = GetTaskConfig, + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = Invoke, + IPROXY_END, +}; + +void __attribute__((weak)) HOS_SystemInit(void) +{ + SAMGR_Bootstrap(); + return; +} + +int ServerProvideInterfaceImplInit(void) +{ + HOS_SystemInit(); + return SOFTBUS_OK; +} + +static void Init(void) +{ + SAMGR_GetInstance()->RegisterService((Service *)&g_samgrService); + SAMGR_GetInstance()->RegisterDefaultFeatureApi(SOFTBUS_SERVICE, GET_IUNKNOWN(g_samgrService)); + LOG_INFO("Init success %s", SOFTBUS_SERVICE); +} +SYSEX_SERVICE_INIT(Init); \ No newline at end of file diff --git a/core/common/inner_communication/ipc/softbus_server_weak.c b/core/common/inner_communication/ipc/softbus_server_weak.c new file mode 100644 index 000000000..13141f259 --- /dev/null +++ b/core/common/inner_communication/ipc/softbus_server_weak.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_weak.h" +#include "softbus_errcode.h" + +int __attribute__ ((weak)) ServerPublishService(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerUnPublishService(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerCreateSessionServer(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerRemoveSessionServer(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerOpenSession(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerCloseSession(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerSendSessionMsg(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerCreateChannelServer(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerRemoveChannelServer(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerSendChannelMsg(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerStartDiscovery(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__ ((weak)) ServerStopDiscovery(void *origin, IpcIo *req, IpcIo *reply) +{ + (void)origin; + (void)req; + (void)reply; + IpcIoPushInt32(reply, (int32_t)SOFTBUS_NOT_IMPLEMENT); + return SOFTBUS_OK; +} + +int __attribute__((weak)) ClientIpcOnChannelOpened(const void *channel) +{ + (void)channel; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnChannelClosed(int64_t channelId) +{ + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnChannelMsgReiceived(int64_t channelId, const void *data, unsigned int len) +{ + (void)channelId; + (void)data; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnJoinLNNResult(void *addr, + const char *networkId, int32_t retCode) +{ + (void)addr; + (void)networkId; + (void)retCode; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnLeaveLNNResult(const char *networkId, int32_t retCode) +{ + (void)networkId; + (void)retCode; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnNodeOnlineStateChanged(bool isOnline, void *info) +{ + (void)isOnline; + (void)info; + return SOFTBUS_NOT_IMPLEMENT; +} + +int __attribute__((weak)) ClientIpcOnNodeBasicInfoChanged(void *info, int32_t type) +{ + (void)info; + (void)type; + return SOFTBUS_NOT_IMPLEMENT; +} \ No newline at end of file diff --git a/core/common/inner_communication/softbus_interface.h b/core/common/inner_communication/softbus_interface.h new file mode 100755 index 000000000..0251c27e9 --- /dev/null +++ b/core/common/inner_communication/softbus_interface.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_INTERFACE_H +#define SOFTBUS_INTERFACE_H + +#include "softbus.h" +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_SOFT_BUS_IPC_LEN 512 +#define MAC_SOFT_BUS_IPC_LEN_EX 1024 +#define SOFTBUS_SERVICE "softbus_service" + +enum SoftBusFuncId { + MANAGE_REGISTER_SERVICE = 0, + + SERVER_PUBLISH_SERVICE = 128, + SERVER_UNPUBLISH_SERVICE, + + SERVER_CREATE_SESSION_SERVER, + SERVER_REMOVE_SESSION_SERVER, + SERVER_OPEN_SESSION, + SERVER_CLOSE_CHANNEL, + SERVER_SESSION_SENDMSG, + + SERVER_START_DISCOVERY, + SERVER_STOP_DISCOVERY, + + SERVER_JOIN_LNN, + SERVER_LEAVE_LNN, + SERVER_GET_ALL_ONLINE_NODE_INFO, + SERVER_GET_LOCAL_DEVICE_INFO, + SERVER_GET_NODE_KEY_INFO, + + CLIENT_ON_CHANNEL_OPENED = 256, + CLIENT_ON_CHANNEL_OPENFAILED, + CLIENT_ON_CHANNEL_CLOSED, + CLIENT_ON_CHANNEL_MSGRECEIVED, + + CLIENT_DISCOVERY_SUCC, + CLIENT_DISCOVERY_FAIL, + CLIENT_DISCOVERY_DEVICE_FOUND, + CLIENT_PUBLISH_SUCC, + CLIENT_PUBLISH_FAIL, + + CLIENT_ON_JOIN_RESULT, + CLIENT_ON_LEAVE_RESULT, + CLIENT_ON_NODE_ONLINE_STATE_CHANGED, + CLIENT_ON_NODE_BASIC_INFO_CHANGED, +}; + +struct ServerProvideInterface { + int (*registerService)(const char *clientPkgName, const void *svcId); + + int (*publishService)(const char *pkgName, const void *info); + int (*unPublishService)(const char *pkgName, int publishId); + + int (*startDiscovery)(const char *pkgName, const void *info); + int (*stopDiscovery)(const char *pkgName, int subscribeId); + + int (*createSessionServer)(const char *pkgName, const char *sessionName); + int (*removeSessionServer)(const char *pkgName, const char *sessionName); + int32_t (*openSession)(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int flags); + int (*closeChannel)(int32_t channelId); + int (*sendMessage)(int32_t channelId, const void *data, uint32_t len, int32_t msgType); + + int (*joinLNN)(void *addr, uint32_t addrTypeLen); + int (*leaveLNN)(const char *networkId); + int (*getAllOnlineNodeInfo)(void **info, uint32_t infoTypeLen, int32_t *infoNum); + int (*getLocalDeviceInfo)(void *info, uint32_t infoTypeLen); + int (*getNodeKeyInfo)(const char *networkId, int key, unsigned char *buf, uint32_t len); +}; + +struct ClientProvideInterface { + int (*onDeviceFound)(const char *pkgName, const void *device); + int (*onDiscoverFailed)(const char *pkgName, int subscribeId, int failReason); + int (*onDiscoverySuccess)(const char *pkgName, int subscribeId); + int (*onPublishSuccess)(const char *pkgName, int publishId); + int (*onPublishFail)(const char *pkgName, int publishId, int reason); + + int (*onChannelOpened)(const char *pkgName, const char *sessionName, const ChannelInfo *channel); + int (*onChannelOpenFailed)(const char *pkgName, int32_t channelId); + int (*onChannelClosed)(const char *pkgName, int32_t channelId); + int (*onChannelMsgReceived)(const char *pkgName, int32_t channelId, const void *data, unsigned int len, + int32_t type); + + int (*openChannel)(const char *udid, const char *pkgName, const char *requestId, const char *connectId); + int (*closeChannel)(const char *connectId); + int (*sendChannelMsg)(const char *connectId, const void *data, unsigned int len); + + int (*onJoinLNNResult)(const char *pkgName, void *addr, uint32_t addrTypeLen, + const char *networkId, int32_t retCode); + int (*onLeaveLNNResult)(const char *pkgName, const char *networkId, int32_t retCode); + int (*onNodeOnlineStateChanged)(bool isOnline, void *info, uint32_t infoTypeLen); + int (*onNodeBasicInfoChanged)(void *info, uint32_t infoTypeLen, int32_t type); +}; + +int ClientProvideInterfaceInit(void); +struct ClientProvideInterface *GetClientProvideInterface(void); +int ClientProvideInterfaceImplInit(void); +void ClientDeathProcTask(void); + +int ServerProvideInterfaceInit(void); +struct ServerProvideInterface *GetServerProvideInterface(void); +int ServerProvideInterfaceImplInit(void); + +void *SoftBusGetClientProxy(void); +void *SoftBusGetIpcContext(void); + +#ifdef __cplusplus +} +#endif +#endif /* SOFTBUS_INTERFACE_H */ \ No newline at end of file diff --git a/core/common/json_utils/BUILD.gn b/core/common/json_utils/BUILD.gn new file mode 100755 index 000000000..e76cda94b --- /dev/null +++ b/core/common/json_utils/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("json_utils") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ "-Wall" ] + sources = [ "softbus_json_utils.c" ] + } +} else { + shared_library("json_utils") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + ] + cflags = [ "-Wall" ] + sources = [ "softbus_json_utils.c" ] + public_deps = [ + "//build/lite/config/component/cJSON:cjson_shared", + "//third_party/bounds_checking_function:libsec_shared", + ] + } +} diff --git a/core/common/json_utils/softbus_json_utils.c b/core/common/json_utils/softbus_json_utils.c new file mode 100644 index 000000000..79c0e44c1 --- /dev/null +++ b/core/common/json_utils/softbus_json_utils.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_json_utils.h" + +#include +#include + +bool GetJsonObjectStringItem(const cJSON *json, const char * const string, char *target, int targetLen) +{ + if (json == NULL || string == NULL || target == NULL || targetLen < 0) { + return false; + } + cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string); + if (item == NULL || !cJSON_IsString(item)) { + LOG_ERR("Cannot find or invalid [%s]", string); + return false; + } + int length = strlen(item->valuestring); + if (length >= targetLen) { + LOG_ERR("the length [%d] is to long for [%s]", length, string); + return false; + } + int ret = strcpy_s(target, targetLen, item->valuestring); + if (ret != 0) { + LOG_ERR("strcpy error %d\n", ret); + return false; + } + return true; +} + +bool GetJsonObjectNumberItem(const cJSON *json, const char * const string, int *target) +{ + if (json == NULL || string == NULL || target == NULL) { + return false; + } + cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string); + if (item == NULL || !cJSON_IsNumber(item) || (item->valuedouble < 0)) { + LOG_ERR("Cannot find or invalid [%s]", string); + return false; + } + *target = (int)item->valuedouble; + return true; +} + +bool GetJsonObjectDoubleItem(const cJSON *json, const char * const string, double *target) +{ + if (json == NULL || string == NULL || target == NULL) { + return false; + } + cJSON* item = cJSON_GetObjectItemCaseSensitive(json, string); + if (item == NULL || !cJSON_IsNumber(item)) { + LOG_ERR("Cannot find or invalid [%s]", string); + return false; + } + *target = item->valuedouble; + return true; +} + +bool GetJsonObjectBoolItem(const cJSON *json, const char * const string, bool *target) +{ + if (json == NULL || string == NULL || target == NULL) { + return false; + } + cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string); + if (item == NULL || !cJSON_IsBool(item)) { + LOG_ERR("Cannot find or invalid [%s]", string); + return false; + } + *target = (bool)item->valueint; + return true; +} + +bool AddStringToJsonObject(cJSON *json, const char * const string, const char *value) +{ + if (value == NULL || json == NULL || string == NULL) { + return false; + } + cJSON *item = cJSON_CreateString(value); + if (item == NULL) { + LOG_ERR("Cannot create cJSON string object [%s]", string); + return false; + } + if (!cJSON_AddItemToObject(json, string, item)) { + cJSON_Delete(item); + return false; + } + return true; +} + +bool AddNumberToJsonObject(cJSON *json, const char * const string, int num) +{ + if (json == NULL || string == NULL) { + return false; + } + cJSON *item = cJSON_CreateNumber(num); + if (item == NULL) { + LOG_ERR("Cannot create cJSON number object [%s]", string); + return false; + } + if (!cJSON_AddItemToObject(json, string, item)) { + cJSON_Delete(item); + return false; + } + return true; +} \ No newline at end of file diff --git a/core/common/message_handler/BUILD.gn b/core/common/message_handler/BUILD.gn new file mode 100755 index 000000000..05fd9d4a7 --- /dev/null +++ b/core/common/message_handler/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("message_handler") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libc/musl/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ "message_handler.c" ] + } +} else { + static_library("message_handler") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//third_party/bounds_checking_function/include", + ] + sources = [ "message_handler.c" ] + + deps = [] + } +} diff --git a/core/common/message_handler/include/message_handler.h b/core/common/message_handler/include/message_handler.h new file mode 100755 index 000000000..176ecec72 --- /dev/null +++ b/core/common/message_handler/include/message_handler.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MESSAGE_HANDLER_H +#define MESSAGE_HANDLER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SoftBusMessage SoftBusMessage; +typedef struct SoftBusHandler SoftBusHandler; +typedef struct SoftBusLooperContext SoftBusLooperContext; +typedef struct SoftBusLooper SoftBusLooper; + +struct SoftBusLooper { + SoftBusLooperContext *context; + void (*PostMessage)(const SoftBusLooper *looper, SoftBusMessage *msg); + void (*PostMessageDelay)(const SoftBusLooper *looper, SoftBusMessage *msg, uint64_t delayMillis); + void (*RemoveMessage)(const SoftBusLooper *looper, const SoftBusHandler *handler, int32_t what); + // customFunc, when match, return 0 + void (*RemoveMessageCustom)(const SoftBusLooper *looper, const SoftBusHandler *handler, + int (*)(const SoftBusMessage*, void*), void *args); +}; + +struct SoftBusHandler { + char *name; + SoftBusLooper *looper; + void (*HandleMessage)(SoftBusMessage *msg); +}; + +struct SoftBusMessage { + int32_t what; + uint64_t arg1; + uint64_t arg2; + int64_t time; + void *obj; + SoftBusHandler *handler; + void (*FreeMessage)(SoftBusMessage *msg); +}; + +SoftBusMessage *MallocMessage(void); + +void FreeMessage(SoftBusMessage *msg); + +enum LooperType { + LOOP_TYPE_DEFAULT = 1, + LOOP_TYPE_BR_SEND, + LOOP_TYPE_BR_RECV +}; + +SoftBusLooper *GetLooper(int looper); + +int LooperInit(void); + +void LooperDeinit(void); + +void DumpLooper(const SoftBusLooper *looper); + +SoftBusLooper *CreateNewLooper(const char *name); + +void DestroyLooper(SoftBusLooper *looper); + +#ifdef __cplusplus +} +#endif + +#endif /* MESSAGE_HANDLER_H */ diff --git a/core/common/message_handler/message_handler.c b/core/common/message_handler/message_handler.c new file mode 100755 index 000000000..043e4d473 --- /dev/null +++ b/core/common/message_handler/message_handler.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "message_handler.h" + +#include +#include + +#include "common_list.h" +#include "pthread.h" +#include "securec.h" +#include "softbus_def.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_type_def.h" +#include "unistd.h" + +#define LOOP_NAME_LEN 16 +#define TIME_THOUSANDS_MULTIPLIER 1000LL + +static int8_t g_isNeedDestroy = 0; +static int8_t g_isThreadStarted = 0; + +typedef struct { + SoftBusMessage *msg; + ListNode node; +} SoftBusMessageNode; + +struct SoftBusLooperContext { + ListNode msgHead; + char name[LOOP_NAME_LEN]; + volatile unsigned char stop; // destroys looper, stop =1, and running =0 + volatile unsigned char running; + SoftBusMessage *currentMsg; + unsigned int msgSize; + pthread_mutex_t lock; + pthread_mutexattr_t attr; + pthread_cond_t cond; + pthread_cond_t condRunning; +}; + +static uint64_t UptimeMicros(void) +{ + struct timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + gettimeofday(&t, NULL); + uint64_t when = ((uint64_t)(t.tv_sec)) * TIME_THOUSANDS_MULTIPLIER * TIME_THOUSANDS_MULTIPLIER + + (uint64_t)t.tv_usec; + return when; +} + +static void FreeSoftBusMsg(SoftBusMessage *msg) +{ + if (msg->FreeMessage == NULL) { + SoftBusFree(msg); + } else { + msg->FreeMessage(msg); + } +} + +SoftBusMessage *MallocMessage(void) +{ + SoftBusMessage *msg = (SoftBusMessage *)SoftBusMalloc(sizeof(SoftBusMessage)); + if (msg == NULL) { + LOG_INFO("malloc SoftBusMessage failed"); + return NULL; + } + (void)memset_s(msg, sizeof(SoftBusMessage), 0, sizeof(SoftBusMessage)); + return msg; +} + +void FreeMessage(SoftBusMessage *msg) +{ + if (msg != NULL) { + FreeSoftBusMsg(msg); + } +} + +static void *LoopTask(void *arg) +{ + SoftBusLooper *looper = arg; + SoftBusLooperContext *context = looper->context; + + LOG_INFO("LoopTask[%s] running", context->name); + + if (pthread_mutex_lock(&context->lock) != 0) { + LOG_ERR("lock failed"); + return NULL; + } + context->running = 1; + g_isThreadStarted = 1; + (void)pthread_mutex_unlock(&context->lock); + + for (;;) { + if (pthread_mutex_lock(&context->lock) != 0) { + LOG_ERR("lock failed"); + return NULL; + } + // wait + if (context->stop == 1) { + LOG_INFO("LoopTask[%s], stop ==1", context->name); + (void)pthread_mutex_unlock(&context->lock); + break; + } + + if (g_isNeedDestroy == 1) { + (void)pthread_mutex_unlock(&context->lock); + break; + } + + if (IsListEmpty(&context->msgHead)) { + LOG_INFO("LoopTask[%s] wait msg list empty", context->name); + pthread_cond_wait(&context->cond, &context->lock); + (void)pthread_mutex_unlock(&context->lock); + continue; + } + + uint64_t now = UptimeMicros(); + ListNode *item = context->msgHead.next; + SoftBusMessage *msg = NULL; + SoftBusMessageNode *itemNode = CONTAINER_OF(item, SoftBusMessageNode, node); + uint64_t time = itemNode->msg->time; + if (now >= time) { + msg = itemNode->msg; + ListDelete(item); + SoftBusFree(itemNode); + context->msgSize--; + LOG_INFO("LoopTask[%s], get message. handle=%s,what=%d,msgSize=%u", + context->name, msg->handler->name, msg->what, context->msgSize); + } else { + uint64_t diff = time - now; + struct timespec tv; + tv.tv_sec = diff / TIME_THOUSANDS_MULTIPLIER / TIME_THOUSANDS_MULTIPLIER; + tv.tv_nsec = diff % (TIME_THOUSANDS_MULTIPLIER * TIME_THOUSANDS_MULTIPLIER) * TIME_THOUSANDS_MULTIPLIER; + pthread_cond_timedwait(&context->cond, &context->lock, &tv); + } + + if (msg == NULL) { + (void)pthread_mutex_unlock(&context->lock); + continue; + } + context->currentMsg = msg; + (void)pthread_mutex_unlock(&context->lock); + LOG_INFO("LoopTask[%s], HandleMessage message. handle=%s,what=%d", + context->name, msg->handler->name, msg->what); + + if (msg->handler->HandleMessage != NULL) { + msg->handler->HandleMessage(msg); + } + LOG_INFO("LoopTask[%s], after HandleMessage message. handle=%s,what=%d", + context->name, msg->handler->name, msg->what); + (void)pthread_mutex_lock(&context->lock); + FreeSoftBusMsg(msg); + context->currentMsg = NULL; + (void)pthread_mutex_unlock(&context->lock); + } + (void)pthread_mutex_lock(&context->lock); + context->running = 0; + LOG_INFO("LoopTask[%s], running =0", context->name); + pthread_cond_broadcast(&context->cond); + pthread_cond_broadcast(&context->condRunning); + (void)pthread_mutex_unlock(&context->lock); + if (g_isNeedDestroy == 1) { + LooperDeinit(); + } + return NULL; +} + +static int StartNewLooperThread(SoftBusLooper *looper) +{ +#define MAINLOOP_STACK_SIZE 5120 + pthread_t tid; + pthread_attr_t threadAttr; + + pthread_attr_init(&threadAttr); + pthread_attr_setstacksize(&threadAttr, MAINLOOP_STACK_SIZE); + if (pthread_create(&tid, &threadAttr, LoopTask, looper) != 0) { + LOG_ERR("create DeathProcTask failed"); + return -1; + } + + LOG_INFO("loop thread creating %s id %d", looper->context->name, (int)tid); + return 0; +} + +static void DumpLooperLocked(const SoftBusLooperContext *context) +{ + int i = 0; + ListNode *item = NULL; + LIST_FOR_EACH(item, &context->msgHead) { + SoftBusMessageNode *itemNode = LIST_ENTRY(item, SoftBusMessageNode, node); + SoftBusMessage *msg = itemNode->msg; + LOG_DBG("DumpLooper. i=%d,handler=%s,what =%d,arg1=%llu arg2=%llu, time=%lld", + i, msg->handler->name, msg->what, msg->arg1, msg->arg2, msg->time); + i++; + } +} + +void DumpLooper(const SoftBusLooper *looper) +{ + if (looper == NULL) { + return; + } + SoftBusLooperContext *context = looper->context; + if (pthread_mutex_lock(&context->lock) != 0) { + LOG_ERR("lock failed"); + return; + } + DumpLooperLocked(context); + (void)pthread_mutex_unlock(&context->lock); +} + +static void PostMessageAtTime(const SoftBusLooper *looper, SoftBusMessage *msgPost) +{ + LOG_INFO("[%s]PostMessageAtTime what =%d time=%lld us", looper->context->name, msgPost->what, msgPost->time); + if (msgPost->handler == NULL) { + FreeSoftBusMsg(msgPost); + LOG_ERR("[%s]PostMessageAtTime. msg handler is null", looper->context->name); + return; + } + SoftBusMessageNode *newNode = (SoftBusMessageNode *)SoftBusMalloc(sizeof(SoftBusMessageNode)); + if (newNode == NULL) { + FreeSoftBusMsg(msgPost); + return; + } + ListInit(&newNode->node); + newNode->msg = msgPost; + SoftBusLooperContext *context = looper->context; + if (pthread_mutex_lock(&context->lock) != 0) { + SoftBusFree(newNode); + FreeSoftBusMsg(msgPost); + LOG_ERR("lock failed"); + return; + } + if (context->stop == 1) { + SoftBusFree(newNode); + FreeSoftBusMsg(msgPost); + (void)pthread_mutex_unlock(&context->lock); + LOG_ERR("[%s]PostMessageAtTime. running=%d,stop=%d", context->name, context->running, context->stop); + return; + } + ListNode *item = NULL; + ListNode *nextItem = NULL; + bool insert = false; + LIST_FOR_EACH_SAFE(item, nextItem, &context->msgHead) { + SoftBusMessageNode *itemNode = LIST_ENTRY(item, SoftBusMessageNode, node); + SoftBusMessage *msg = itemNode->msg; + if (msg->time > msgPost->time) { + ListTailInsert(item, &(newNode->node)); + insert = true; + break; + } + } + if (!insert) { + ListTailInsert(&(context->msgHead), &(newNode->node)); + } + context->msgSize++; + LOG_INFO("[%s]PostMessageAtTime. insert", context->name); + DumpLooperLocked(context); + + pthread_cond_broadcast(&context->cond); + (void)pthread_mutex_unlock(&context->lock); +} + +static void LooperPostMessage(const SoftBusLooper *looper, SoftBusMessage *msg) +{ + msg->time = UptimeMicros(); + PostMessageAtTime(looper, msg); +} + +static void LooperPostMessageDelay(const SoftBusLooper *looper, SoftBusMessage *msg, uint64_t delayMillis) +{ + msg->time = UptimeMicros() + delayMillis * TIME_THOUSANDS_MULTIPLIER; + PostMessageAtTime(looper, msg); +} + +static int WhatRemoveFunc(const SoftBusMessage *msg, void *args) +{ + int32_t what = (int32_t)(intptr_t)args; + if (msg->what == what) { + return 0; + } + return 1; +} + +static void LoopRemoveMessageCustom(const SoftBusLooper *looper, const SoftBusHandler *handler, + int (*customFunc)(const SoftBusMessage*, void*), void *args) +{ + SoftBusLooperContext *context = looper->context; + if (pthread_mutex_lock(&context->lock) != 0) { + LOG_ERR("lock failed"); + return; + } + if (context->running == 0 || context->stop == 1) { + (void)pthread_mutex_unlock(&context->lock); + return; + } + ListNode *item = NULL; + ListNode *nextItem = NULL; + LIST_FOR_EACH_SAFE(item, nextItem, &context->msgHead) { + SoftBusMessageNode *itemNode = LIST_ENTRY(item, SoftBusMessageNode, node); + SoftBusMessage *msg = itemNode->msg; + if (msg->handler == handler && customFunc(msg, args) == 0) { + LOG_INFO("[%s]LooperRemoveMessage. handler=%s, what =%d", + context->name, handler->name, msg->what); + FreeSoftBusMsg(msg); + ListDelete(&itemNode->node); + SoftBusFree(itemNode); + context->msgSize--; + } + } + (void)pthread_mutex_unlock(&context->lock); +} + +static void LooperRemoveMessage(const SoftBusLooper *looper, const SoftBusHandler *handler, int what) +{ + LoopRemoveMessageCustom(looper, handler, WhatRemoveFunc, (void*)(intptr_t)what); +} + +SoftBusLooper *CreateNewLooper(const char *name) +{ + SoftBusLooper *looper = (SoftBusLooper *)SoftBusCalloc(sizeof(SoftBusLooper)); + if (looper == NULL) { + return NULL; + } + + SoftBusLooperContext *context = SoftBusCalloc(sizeof(SoftBusLooperContext)); + if (context == NULL) { + SoftBusFree(looper); + return NULL; + } + + if (memcpy_s(context->name, sizeof(context->name), name, strlen(name)) != EOK) { + SoftBusFree(looper); + SoftBusFree(context); + return NULL; + } + ListInit(&context->msgHead); + // init context + + pthread_mutex_init(&context->lock, NULL); + pthread_cond_init(&context->cond, NULL); + pthread_cond_init(&context->condRunning, NULL); + + // init looper + looper->context = context; + looper->PostMessage = LooperPostMessage; + looper->PostMessageDelay = LooperPostMessageDelay; + looper->RemoveMessage = LooperRemoveMessage; + looper->RemoveMessageCustom = LoopRemoveMessageCustom; + int ret = StartNewLooperThread(looper); + if (ret != 0) { + SoftBusFree(looper); + SoftBusFree(context); + return NULL; + } + + LOG_INFO("[%s]wait looper start ok", context->name); + return looper; +} + +struct LoopConfigItem { + int type; + SoftBusLooper *looper; +}; + +static struct LoopConfigItem g_loopConfig[] = { + {LOOP_TYPE_DEFAULT, NULL}, + {LOOP_TYPE_BR_SEND, NULL}, + {LOOP_TYPE_BR_RECV, NULL} +}; + +SoftBusLooper *GetLooper(int type) +{ + int len = sizeof(g_loopConfig) / sizeof(struct LoopConfigItem); + for (int i = 0; i < len; i++) { + if (g_loopConfig[i].type == type) { + return g_loopConfig[i].looper; + } + } + return NULL; +} + +static void SetLooper(int type, SoftBusLooper *looper) +{ + int len = sizeof(g_loopConfig) / sizeof(struct LoopConfigItem); + for (int i = 0; i < len; i++) { + if (g_loopConfig[i].type == type) { + g_loopConfig[i].looper = looper; + } + } +} + +static void ReleaseLooper(const SoftBusLooper *looper) +{ + int len = sizeof(g_loopConfig) / sizeof(struct LoopConfigItem); + for (int i = 0; i < len; i++) { + if (g_loopConfig[i].looper == looper) { + g_loopConfig[i].looper = NULL; + return; + } + } +} + +void DestroyLooper(SoftBusLooper *looper) +{ + if (looper == NULL) { + return; + } + + SoftBusLooperContext *context = looper->context; + if (context != NULL) { + (void)pthread_mutex_lock(&context->lock); + + LOG_INFO("[%s]set stop = 1", context->name); + context->stop = 1; + + pthread_cond_broadcast(&context->cond); + (void)pthread_mutex_unlock(&context->lock); + while (1) { + (void)pthread_mutex_lock(&context->lock); + LOG_INFO("[%s] get running = %d", context->name, context->running); + if (context->running == 0) { + (void)pthread_mutex_unlock(&context->lock); + break; + } + pthread_cond_wait(&context->condRunning, &context->lock); + (void)pthread_mutex_unlock(&context->lock); + } + // release msg + ListNode *item = NULL; + ListNode *nextItem = NULL; + LIST_FOR_EACH_SAFE(item, nextItem, &context->msgHead) { + SoftBusMessageNode *itemNode = LIST_ENTRY(item, SoftBusMessageNode, node); + SoftBusMessage *msg = itemNode->msg; + FreeSoftBusMsg(msg); + ListDelete(&itemNode->node); + SoftBusFree(itemNode); + } + LOG_INFO("[%s] destroy", context->name); + // destroy looper + pthread_cond_destroy(&context->cond); + pthread_cond_destroy(&context->condRunning); + pthread_mutex_destroy(&context->lock); + SoftBusFree(context); + looper->context = NULL; + } + ReleaseLooper(looper); + SoftBusFree(looper); +} + +int LooperInit(void) +{ + SoftBusLooper *looper = CreateNewLooper("Loop-default"); + if (!looper) { + LOG_ERR("init looper fail."); + return -1; + } + SetLooper(LOOP_TYPE_DEFAULT, looper); + LOG_INFO("init looper success."); + return 0; +} + +void LooperDeinit(void) +{ + int len = sizeof(g_loopConfig) / sizeof(struct LoopConfigItem); + for (int i = 0; i < len; i++) { + if (g_loopConfig[i].looper == NULL) { + continue; + } + (void)pthread_mutex_lock(&(g_loopConfig[i].looper->context->lock)); + if (g_isThreadStarted == 0) { + g_isNeedDestroy = 1; + (void)pthread_mutex_unlock(&(g_loopConfig[i].looper->context->lock)); + return; + } + (void)pthread_mutex_unlock(&(g_loopConfig[i].looper->context->lock)); + DestroyLooper(g_loopConfig[i].looper); + } +} diff --git a/core/common/security/BUILD.gn b/core/common/security/BUILD.gn new file mode 100755 index 000000000..d58cf129a --- /dev/null +++ b/core/common/security/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_crypto") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "//third_party/bounds_checking_function/include", + "//third_party/mbedtls/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ "-Wall" ] + sources = [ "mbedtls/softbus_crypto.c" ] + } +} else { + shared_library("softbus_crypto") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "//third_party/bounds_checking_function/include", + "//third_party/mbedtls/include", + ] + cflags = [ "-Wall" ] + sources = [ "mbedtls/softbus_crypto.c" ] + public_deps = [ + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/mbedtls:mbedtls_shared", + ] + } +} diff --git a/core/common/security/mbedtls/softbus_crypto.c b/core/common/security/mbedtls/softbus_crypto.c new file mode 100644 index 000000000..6deb35966 --- /dev/null +++ b/core/common/security/mbedtls/softbus_crypto.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "softbus_crypto.h" + +#include + +#include "mbedtls/gcm.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_utils.h" + +static int MbedAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText, + unsigned int plainTextSize, unsigned char *cipherText, unsigned int cipherTextLen) +{ + if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL || + (cipherTextLen < plainTextSize + OVERHEAD_LEN)) { + LOG_ERR("Encrypt invalid para\n"); + return SOFTBUS_INVALID_PARAM; + } + + int ret; + unsigned char tagBuf[TAG_LEN] = {0}; + mbedtls_gcm_context aesContext; + mbedtls_gcm_init(&aesContext); + + ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherkey->key, cipherkey->keyLen * KEY_BITS_UNIT); + if (ret != 0) { + mbedtls_gcm_free(&aesContext); + return SOFTBUS_ENCRYPT_ERR; + } + + ret = mbedtls_gcm_crypt_and_tag(&aesContext, MBEDTLS_GCM_ENCRYPT, plainTextSize, cipherkey->iv, + GCM_IV_LEN, NULL, 0, plainText, cipherText + GCM_IV_LEN, TAG_LEN, tagBuf); + if (ret != 0) { + mbedtls_gcm_free(&aesContext); + return SOFTBUS_ENCRYPT_ERR; + } + + if (memcpy_s(cipherText, cipherTextLen, cipherkey->iv, GCM_IV_LEN) != 0) { + mbedtls_gcm_free(&aesContext); + return SOFTBUS_ENCRYPT_ERR; + } + + if (memcpy_s(cipherText + GCM_IV_LEN + plainTextSize, cipherTextLen - GCM_IV_LEN - plainTextSize, + tagBuf, TAG_LEN) != 0) { + mbedtls_gcm_free(&aesContext); + return SOFTBUS_ENCRYPT_ERR; + } + + mbedtls_gcm_free(&aesContext); + return (plainTextSize + OVERHEAD_LEN); +} + +static int MbedAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText, + unsigned int cipherTextSize, unsigned char *plain, unsigned int plainLen) +{ + if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL || + (plainLen < cipherTextSize - OVERHEAD_LEN)) { + LOG_ERR("Decrypt invalid para\n"); + return SOFTBUS_INVALID_PARAM; + } + + mbedtls_gcm_context aesContext; + mbedtls_gcm_init(&aesContext); + int ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherkey->key, + cipherkey->keyLen * KEY_BITS_UNIT); + if (ret != 0) { + LOG_ERR("Decrypt mbedtls_gcm_setkey fail\n"); + mbedtls_gcm_free(&aesContext); + return SOFTBUS_DECRYPT_ERR; + } + + int actualPlainLen = cipherTextSize - OVERHEAD_LEN; + ret = mbedtls_gcm_auth_decrypt(&aesContext, cipherTextSize - OVERHEAD_LEN, cipherkey->iv, + GCM_IV_LEN, NULL, 0, cipherText + actualPlainLen + GCM_IV_LEN, TAG_LEN, cipherText + GCM_IV_LEN, plain); + if (ret != 0) { + LOG_ERR("[TRANS] Decrypt mbedtls_gcm_auth_decrypt fail\n"); + mbedtls_gcm_free(&aesContext); + return SOFTBUS_DECRYPT_ERR; + } + + mbedtls_gcm_free(&aesContext); + return actualPlainLen; +} + +int GenerateSessionKey(char *key, int len) +{ + if (GenerateRandomArray((unsigned char*)key, len) != SOFTBUS_OK) { + LOG_ERR("generate sessionKey error."); + return SOFTBUS_ENCRYPT_ERR; + } + return SOFTBUS_OK; +} + +int SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *encryptData, unsigned int *encryptLen) +{ + if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (GenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) { + LOG_ERR("generate random iv error."); + return SOFTBUS_ENCRYPT_ERR; + } + unsigned int outLen = inLen + OVERHEAD_LEN; + int result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen); + if (result <= 0) { + return SOFTBUS_ENCRYPT_ERR; + } + *encryptLen = result; + return SOFTBUS_OK; +} + +int SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *encryptData, unsigned int *encryptLen, int32_t seqNum) +{ + if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (GenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) { + LOG_ERR("generate random iv error."); + return SOFTBUS_ENCRYPT_ERR; + } + if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) { + return SOFTBUS_ENCRYPT_ERR; + } + unsigned int outLen = inLen + OVERHEAD_LEN; + int result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen); + if (result <= 0) { + return SOFTBUS_ENCRYPT_ERR; + } + *encryptLen = result; + return SOFTBUS_OK; +} + +int SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *decryptData, unsigned int *decryptLen) +{ + if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) { + LOG_ERR("copy iv failed."); + return SOFTBUS_ENCRYPT_ERR; + } + unsigned int outLen = inLen - OVERHEAD_LEN; + int result = MbedAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen); + if (result <= 0) { + return SOFTBUS_ENCRYPT_ERR; + } + *decryptLen = result; + return SOFTBUS_OK; +} + +int SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, unsigned int inLen, + unsigned char *decryptData, unsigned int *decryptLen, int32_t seqNum) +{ + return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen); +} diff --git a/core/common/security/permission/BUILD.gn b/core/common/security/permission/BUILD.gn new file mode 100755 index 000000000..68de950ef --- /dev/null +++ b/core/common/security/permission/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +ohos_prebuilt_etc("softbus_permission") { + source = "permission.json" + install_enable = true + relative_install_dir = "communication/softbus" + part_name = "dsoftbus_standard" +} diff --git a/core/common/security/permission/common/permission_entry.c b/core/common/security/permission/common/permission_entry.c new file mode 100755 index 000000000..29030b5d3 --- /dev/null +++ b/core/common/security/permission/common/permission_entry.c @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "permission_entry.h" + +#include +#include + +#include "cJSON.h" +#include "common_list.h" +#include "permission_utils.h" +#include "regex.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_mem_interface.h" +#include "softbus_os_interface.h" +#include "softbus_permission.h" +#include "softbus_utils.h" + +#define ENFORCING 1 + +#define PERMISSION_JSON_LEN 10000 +#define TEMP_STR_MAX_LEN 128 + +/* permission entry key */ +#define SESSION_NAME_STR "SESSION_NAME" +#define REGEXP_STR "REGEXP" +#define DEVID_STR "DEVID" +#define SEC_LEVEL_STR "SEV_LEVEL" +#define APP_INFO_STR "APP_INFO" + +/* app info key */ +#define APP_INFO_TYPE_STR "TYPE" +#define APP_INFO_PKG_NAME_STR "PKG_NAME" +#define APP_INFO_ACTION_STR "ACTIONS" +#define APP_INFO_UID_STR "UID" + +/* permission entry regexp value */ +#define TRUE_STR "true" +#define FALSE_STR "false" + +/* permission entry sec level value */ +#define PUBLIC_STR "public" +#define PRIVATE_STR "private" + +/* permission entry devid value */ +#define UDID_STR "UDID" +#define UUID_STR "UUID" +#define NETWORK_ID_STR "NETWORKID" + +/* app info type value */ +#define SYSTEM_APP_STR "system_app" +#define NATIVE_APP_STR "native_app" +#define SELF_APP_STR "self_app" +#define NORMAL_APP_STR "normal_app" +#define GRANTED_APP_STR "granted_app" + +/* app info actions value */ +#define OPEN_ACTIONS_STR "open" +#define CREATE_ACTIONS_STR "create" +#define ACTIONS_SPLIT "," + +#define DBINDER_SERVICE_NAME "DBinderService" +#define DBINDER_BUS_NAME_PREFIX "DBinder" + +typedef struct { + const char *key; + int32_t value; +} PeMap; + +static SoftBusList *g_permissionEntryList = NULL; +static char g_permissonJson[PERMISSION_JSON_LEN]; + +static PeMap g_peMap[] = { + {SYSTEM_APP_STR, SYSTEM_APP}, + {NATIVE_APP_STR, NATIVE_APP}, + {SELF_APP_STR, SELF_APP}, + {NORMAL_APP_STR, NORMAL_APP}, + {GRANTED_APP_STR, GRANTED_APP}, + {UDID_STR, UDID}, + {UUID_STR, UUID}, + {NETWORK_ID_STR, NETWORKID}, + {PRIVATE_STR, LEVEL_PRIVATE}, + {PUBLIC_STR, LEVEL_PUBLIC}, + {TRUE_STR, 1}, + {FALSE_STR, 0}, +}; + +static int32_t ReadConfigJson(const char* permissionFile) +{ + if (SoftBusReadFile(permissionFile, g_permissonJson, PERMISSION_JSON_LEN) != SOFTBUS_OK) { + LOG_ERR("ReadConfigJson failed."); + return SOFTBUS_FILE_ERR; + } + return SOFTBUS_OK; +} + +static int32_t GetPeMapValue(const char *string) +{ + int32_t mapSize = sizeof(g_peMap) / sizeof(PeMap); + int index; + for (index = 0; index < mapSize; index++) { + if (strcmp(string, g_peMap[index].key) == 0) { + return g_peMap[index].value; + } + } + return UNKNOWN_VALUE; +} + +static bool StrIsEmpty(const char *string) +{ + if (string == NULL || strlen(string) == 0) { + return true; + } + return false; +} + +static bool StrStartWith(const char *string, const char *target) +{ + if (string == NULL || target == NULL) { + return false; + } + int32_t stringLen = strlen(string); + int32_t targetLen = strlen(target); + if (stringLen == 0 || targetLen == 0 || stringLen < targetLen) { + return false; + } + for (int index = 0; index < targetLen; index++) { + if (string[index] != target[index]) { + return false; + } + } + return true; +} + +static SoftBusAppInfo *ProcessAppInfo(cJSON *object) +{ + if (object == NULL) { + return NULL; + } + + SoftBusAppInfo *appInfo = (SoftBusAppInfo *)SoftBusCalloc(sizeof(SoftBusAppInfo)); + if (appInfo == NULL) { + return NULL; + } + ListInit(&appInfo->node); + appInfo->type = UNKNOWN_VALUE; + appInfo->uid = UNKNOWN_VALUE; + appInfo->pid = UNKNOWN_VALUE; + appInfo->actions = 0; + + char mapKey[TEMP_STR_MAX_LEN]; + char *actionStr = NULL; + if (!GetJsonObjectStringItem(object, APP_INFO_PKG_NAME_STR, appInfo->pkgName, PKG_NAME_SIZE_MAX)) { + LOG_INFO("appInfo has no pkgname"); + } + if (GetJsonObjectStringItem(object, APP_INFO_TYPE_STR, mapKey, TEMP_STR_MAX_LEN)) { + appInfo->type = GetPeMapValue(mapKey); + if (appInfo->type == UNKNOWN_VALUE) { + goto EXIT; + } + } else { + goto EXIT; + } + if (GetJsonObjectStringItem(object, APP_INFO_UID_STR, mapKey, TEMP_STR_MAX_LEN)) { + appInfo->uid = atoi(mapKey); + } + if (GetJsonObjectStringItem(object, APP_INFO_ACTION_STR, mapKey, TEMP_STR_MAX_LEN)) { + char *nextToken = NULL; + actionStr = strtok_s(mapKey, ACTIONS_SPLIT, &nextToken); + while (actionStr != NULL) { + if (strcmp(actionStr, "open") == 0) { + appInfo->actions |= ACTION_OPEN; + } else if (strcmp(actionStr, "create") == 0) { + appInfo->actions |= ACTION_CREATE; + } + actionStr = strtok_s(NULL, ACTIONS_SPLIT, &nextToken); + } + } + if (appInfo->actions == 0) { + goto EXIT; + } + return appInfo; +EXIT: + SoftBusFree(appInfo); + return NULL; +} + +static SoftBusPermissionEntry *ProcessPermissionEntry(cJSON *object) +{ + if (object == NULL) { + return NULL; + } + + SoftBusPermissionEntry *permissionEntry = (SoftBusPermissionEntry *)SoftBusCalloc(sizeof(SoftBusPermissionEntry)); + if (permissionEntry == NULL) { + return NULL; + } + ListInit(&permissionEntry->node); + ListInit(&permissionEntry->appInfo); + permissionEntry->regexp = false; + permissionEntry->devId = UNKNOWN_VALUE; + permissionEntry->secLevel = UNKNOWN_VALUE; + + char mapKey[TEMP_STR_MAX_LEN]; + int appInfoSize; + int appInfoIndex; + if (!GetJsonObjectStringItem(object, SESSION_NAME_STR, permissionEntry->sessionName, SESSION_NAME_SIZE_MAX)) { + goto EXIT; + } + if (GetJsonObjectStringItem(object, REGEXP_STR, mapKey, TEMP_STR_MAX_LEN)) { + permissionEntry->regexp = GetPeMapValue(mapKey); + } + if (GetJsonObjectStringItem(object, DEVID_STR, mapKey, TEMP_STR_MAX_LEN)) { + permissionEntry->devId = GetPeMapValue(mapKey); + } + if (GetJsonObjectStringItem(object, SEC_LEVEL_STR, mapKey, TEMP_STR_MAX_LEN)) { + permissionEntry->secLevel = GetPeMapValue(mapKey); + } + cJSON *appInfoArray = cJSON_GetObjectItem(object, APP_INFO_STR); + if (appInfoArray != NULL) { + appInfoSize = cJSON_GetArraySize(appInfoArray); + for (appInfoIndex = 0; appInfoIndex < appInfoSize; appInfoIndex++) { + SoftBusAppInfo *appInfo = ProcessAppInfo(cJSON_GetArrayItem(appInfoArray, appInfoIndex)); + if (appInfo != NULL) { + ListNodeInsert(&permissionEntry->appInfo, &appInfo->node); + } + } + } + return permissionEntry; + +EXIT: + SoftBusFree(permissionEntry); + return NULL; +} + +static int32_t CompareString(const char *src, const char *dest, bool regexp) +{ + if (src == NULL || dest == NULL) { + return SOFTBUS_PERMISSION_DENIED; + } + if (regexp) { + regex_t regComp; + if (regcomp(®Comp, src, REG_EXTENDED | REG_NOSUB) != 0) { + LOG_ERR("regcomp failed"); + return SOFTBUS_PERMISSION_DENIED; + } + if (regexec(®Comp, dest, 0, NULL, 0) == 0) { + LOG_INFO("src:%s dest:%s", src, dest); + return SOFTBUS_OK; + } + } else { + if (strcmp(src, dest) == 0) { + LOG_INFO("src:%s dest:%s", src, dest); + return SOFTBUS_OK; + } + } + return SOFTBUS_PERMISSION_DENIED; +} + +static int32_t GetPermType(const SoftBusAppInfo *appInfo, const SoftBusPermissionItem *pItem) +{ + if (appInfo == NULL || pItem == NULL) { + return SOFTBUS_INVALID_PARAM; + } + switch (appInfo->type) { + case NATIVE_APP: + /* same as system app */ + case SYSTEM_APP: + if (pItem->permType == SYSTEM_APP || + pItem->permType == NATIVE_APP) { + return pItem->permType; + } + break; + case GRANTED_APP: + if (pItem->actions == ACTION_CREATE) { + if (pItem->permType == SYSTEM_APP || + pItem->permType == NATIVE_APP || + pItem->permType == NORMAL_APP) { + return pItem->permType; + } + } else if (pItem->actions == ACTION_OPEN) { + if (pItem->permType == GRANTED_APP) { + return appInfo->type; + } + } + break; + case NORMAL_APP: + if (pItem->permType == SYSTEM_APP || + pItem->permType == NATIVE_APP || + pItem->permType == NORMAL_APP) { + return pItem->permType; + } + break; + case SELF_APP: + if (pItem->permType == SELF_APP) { + return SELF_APP; + } + break; + default: + return SOFTBUS_PERMISSION_DENIED; + } + return SOFTBUS_PERMISSION_DENIED; +} + +static int32_t CheckPermissionAppInfo(const SoftBusPermissionEntry *pe, + const SoftBusPermissionItem *pItem) +{ + if (pe == NULL || pItem == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pItem->actions == 0) { + return SOFTBUS_PERMISSION_DENIED; + } + int32_t permType; + SoftBusAppInfo *appInfo = NULL; + LIST_FOR_EACH_ENTRY(appInfo, &pe->appInfo, SoftBusAppInfo, node) { + if ((appInfo->actions & pItem->actions) != pItem->actions) { + continue; + } + permType = GetPermType(appInfo, pItem); + if (permType < 0) { + continue; + } + if ((appInfo->uid >= 0) && (appInfo->uid != pItem->uid)) { + continue; + } + if ((appInfo->pid >= 0) && (appInfo->pid != pItem->pid)) { + continue; + } + if (!StrIsEmpty(appInfo->pkgName)) { + if ((CompareString(appInfo->pkgName, pItem->pkgName, false) != SOFTBUS_OK) && + !StrIsEmpty(pItem->pkgName)) { + continue; + } + if (appInfo->type == SYSTEM_APP || appInfo->type == NORMAL_APP) { + return permType; + } + } + return permType; + } + return SOFTBUS_PERMISSION_DENIED; +} + +static bool CheckDBinder(const char *sessionName) +{ + if (StrIsEmpty(sessionName)) { + return false; + } + if (strcmp(DBINDER_SERVICE_NAME, sessionName) == 0) { + return true; + } + if (StrStartWith(sessionName, DBINDER_BUS_NAME_PREFIX)) { + return true; + } + return false; +} + +int32_t LoadPermissionJson(const char *fileName) +{ + int ret = ReadConfigJson(fileName); + if (ret != SOFTBUS_OK) { + return ret; + } + if (g_permissionEntryList == NULL) { + g_permissionEntryList = CreateSoftBusList(); + if (g_permissionEntryList == NULL) { + return SOFTBUS_MALLOC_ERR; + } + } + cJSON *jsonArray = cJSON_Parse(g_permissonJson); + if (jsonArray == NULL) { + LOG_ERR("parse %s failed.", fileName); + return SOFTBUS_PARSE_JSON_ERR; + } + int itemNum = cJSON_GetArraySize(jsonArray); + if (itemNum <= 0) { + cJSON_Delete(jsonArray); + return SOFTBUS_PARSE_JSON_ERR; + } + int index; + SoftBusPermissionEntry *pe = NULL; + for (index = 0; index < itemNum; index++) { + cJSON *permissionEntryObeject = cJSON_GetArrayItem(jsonArray, index); + pe = ProcessPermissionEntry(permissionEntryObeject); + if (pe != NULL) { + ListNodeInsert(&g_permissionEntryList->list, &pe->node); + g_permissionEntryList->cnt++; + } + } + cJSON_Delete(jsonArray); + return SOFTBUS_OK; +} + +void ClearAppInfo(const ListNode *appInfo) +{ + if (appInfo == NULL) { + return; + } + while (!IsListEmpty(appInfo)) { + SoftBusAppInfo *item = LIST_ENTRY(appInfo->next, SoftBusAppInfo, node); + ListDelete(&item->node); + SoftBusFree(item); + } +} + +void DeinitPermissionJson(void) +{ + if (g_permissionEntryList == NULL) { + return; + } + pthread_mutex_lock(&g_permissionEntryList->lock); + while (!IsListEmpty(&g_permissionEntryList->list)) { + SoftBusPermissionEntry *item = LIST_ENTRY((&g_permissionEntryList->list)->next, SoftBusPermissionEntry, node); + ClearAppInfo(&item->appInfo); + ListDelete(&item->node); + SoftBusFree(item); + } + pthread_mutex_unlock(&g_permissionEntryList->lock); + DestroySoftBusList(g_permissionEntryList); +} + +SoftBusPermissionItem *CreatePermissionItem(int32_t permType, int32_t uid, int32_t pid, + const char *pkgName, uint32_t actions) +{ + SoftBusPermissionItem *pItem = SoftBusCalloc(sizeof(SoftBusPermissionItem)); + if (pItem == NULL) { + return NULL; + } + pItem->permType = permType; + pItem->uid = uid; + pItem->pid = pid; + pItem->pkgName = (char *)pkgName; + pItem->actions = actions; + return pItem; +} + +int32_t CheckPermissionEntry(const char *sessionName, const SoftBusPermissionItem *pItem) +{ + if (sessionName == NULL || pItem == NULL || g_permissionEntryList == NULL) { + return SOFTBUS_INVALID_PARAM; + } + int permType; + SoftBusPermissionEntry *pe = NULL; + (void)pthread_mutex_lock(&g_permissionEntryList->lock); + LIST_FOR_EACH_ENTRY(pe, &g_permissionEntryList->list, SoftBusPermissionEntry, node) { + if (CompareString(pe->sessionName, sessionName, pe->regexp) == SOFTBUS_OK) { + if (CheckDBinder(sessionName)) { + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return GRANTED_APP; + } + permType = CheckPermissionAppInfo(pe, pItem); + if (permType < 0) { + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType; + } + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return permType; + } + } + if (pItem->permType != NORMAL_APP) { + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType; + } + if (pItem->actions == ACTION_CREATE) { + if (IsValidPkgName(pItem->uid, pItem->pkgName) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType; + } + if (!StrStartWith(sessionName, pItem->pkgName)) { + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType; + } + } + (void)pthread_mutex_unlock(&g_permissionEntryList->lock); + return SOFTBUS_PERMISSION_DENIED; +} \ No newline at end of file diff --git a/core/common/security/permission/include/permission_entry.h b/core/common/security/permission/include/permission_entry.h new file mode 100755 index 000000000..ea12e52bb --- /dev/null +++ b/core/common/security/permission/include/permission_entry.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERMISSION_ENTRY_H +#define PERMISSION_ENTRY_H + +#include "softbus_def.h" +#include "softbus_permission.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define UNKNOWN_VALUE (-1) + +typedef enum { + UDID = 0, + UUID, + NETWORKID, +} DevId; + +typedef enum { + LEVEL_PRIVATE = 0, + LEVEL_PUBLIC, +} SecurityLevel; + +typedef struct { + int32_t permType; + int32_t uid; + int32_t pid; + char *pkgName; + uint32_t actions; +} SoftBusPermissionItem; + +typedef struct { + ListNode node; + int32_t type; + char pkgName[PKG_NAME_SIZE_MAX]; + uint32_t actions; + int32_t uid; + int32_t pid; +} SoftBusAppInfo; + +typedef struct { + ListNode node; + char sessionName[SESSION_NAME_SIZE_MAX]; + int32_t devId; + bool regexp; + int32_t secLevel; + ListNode appInfo; +} SoftBusPermissionEntry; + +int32_t LoadPermissionJson(const char *fileName); +void DeinitPermissionJson(void); +int32_t CheckPermissionEntry(const char *sessionName, const SoftBusPermissionItem *pItem); +int32_t IsValidPkgName(int32_t uid, const char *pkgName); +SoftBusPermissionItem *CreatePermissionItem(int32_t permType, int32_t uid, int32_t pid, + const char *pkgName, uint32_t actions); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* PERMISSION_ENTRY_H */ diff --git a/core/common/security/permission/include/permission_utils.h b/core/common/security/permission/include/permission_utils.h new file mode 100755 index 000000000..6e4b4b268 --- /dev/null +++ b/core/common/security/permission/include/permission_utils.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERMISSION_UTILS_H +#define PERMISSION_UTILS_H + +#include "stdint.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +int32_t IsValidPkgName(int32_t uid, const char *pkgName); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* PERMISSION_UTILS_H */ diff --git a/core/common/security/permission/mini_system/softbus_permission.c b/core/common/security/permission/mini_system/softbus_permission.c new file mode 100755 index 000000000..9d13fbc45 --- /dev/null +++ b/core/common/security/permission/mini_system/softbus_permission.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_errcode.h" +#include "softbus_permission.h" + +int32_t TransPermissionInit(void) +{ + return SOFTBUS_OK; +} + +void TransPermissionDeinit(void) +{} + +int32_t CheckTransPermission(const char *pkgName, const char *sessionName, uint32_t action) +{ + (void)pkgName; + (void)sessionName; + (void)action; + return SOFTBUS_OK; +} + +bool CheckDiscPermission(const char *pkgName) +{ + (void)pkgName; + return SOFTBUS_OK; +} + +bool CheckBusCenterPermission(const char *pkgName) +{ + (void)pkgName; + return true; +} \ No newline at end of file diff --git a/core/common/security/permission/permission.json b/core/common/security/permission/permission.json new file mode 100755 index 000000000..1f760a5db --- /dev/null +++ b/core/common/security/permission/permission.json @@ -0,0 +1,14 @@ +[ + { + "SESSION_NAME": "DistributedFileService.*", + "REGEXP": "true", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "native_app", + "UID": "1000", + "ACTIONS": "create,open" + } + ] + } +] diff --git a/core/common/security/permission/small_system/softbus_permission.c b/core/common/security/permission/small_system/softbus_permission.c new file mode 100755 index 000000000..9d13fbc45 --- /dev/null +++ b/core/common/security/permission/small_system/softbus_permission.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_errcode.h" +#include "softbus_permission.h" + +int32_t TransPermissionInit(void) +{ + return SOFTBUS_OK; +} + +void TransPermissionDeinit(void) +{} + +int32_t CheckTransPermission(const char *pkgName, const char *sessionName, uint32_t action) +{ + (void)pkgName; + (void)sessionName; + (void)action; + return SOFTBUS_OK; +} + +bool CheckDiscPermission(const char *pkgName) +{ + (void)pkgName; + return SOFTBUS_OK; +} + +bool CheckBusCenterPermission(const char *pkgName) +{ + (void)pkgName; + return true; +} \ No newline at end of file diff --git a/core/common/security/permission/standard_system/permission_utils.cpp b/core/common/security/permission/standard_system/permission_utils.cpp new file mode 100755 index 000000000..a2f8cd2fe --- /dev/null +++ b/core/common/security/permission/standard_system/permission_utils.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "permission_utils.h" + +#include "bundle_mgr_interface.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "sys_mgr_client.h" +#include "system_ability_definition.h" + +using namespace OHOS::AppExecFwk; + +extern "C" int32_t IsValidPkgName(int32_t uid, const char *pkgName) +{ + if (pkgName == NULL) { + return SOFTBUS_ERR; + } + auto bundleObj = + OHOS::DelayedSingleton::GetInstance()->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (bundleObj == nullptr) { + LOG_ERR("failed to get bundle manager service"); + return SOFTBUS_ERR; + } + OHOS::sptr bmgr = OHOS::iface_cast(bundleObj); + std::string bundleName; +#ifndef PERMISSION_TEST + bmgr->GetBundleNameForUid(uid, bundleName); + printf("BundleName: %s\n", bundleName.c_str()); + if (std::string(pkgName) != bundleName) { + return SOFTBUS_ERR; + } +#endif + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/common/security/permission/standard_system/softbus_permission.cpp b/core/common/security/permission/standard_system/softbus_permission.cpp new file mode 100755 index 000000000..62d92c089 --- /dev/null +++ b/core/common/security/permission/standard_system/softbus_permission.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_permission.h" + +#include +#include + +#include "bundle_mgr_interface.h" +#include "ipc_skeleton.h" +#include "permission/permission.h" +#include "permission/permission_kit.h" +#include "permission_entry.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "sys_mgr_client.h" +#include "system_ability_definition.h" + +using namespace OHOS::AppExecFwk; +using namespace OHOS::Security::Permission; + +namespace { + const std::string SYSTEM_APP_PERMISSION = "com.huawei.permission.MANAGE_DISTRIBUTED_PERMISSION"; + const std::string DANGER_APP_PERMISSION = "ohos.permission.DISTRIBUTED_DATASYNC"; + const std::string BIND_DISCOVER_SERVICE = "com.huawei.hwddmp.permission.BIND_DISCOVER_SERVICE"; + const int32_t SYSTEM_UID = 1000; + const int32_t SHELL_UID = 2000; + const int32_t INVALID_UID = -1; + const int32_t FIRST_APPLICATION_UID = 10000; + const int32_t MULTE_USER_RADIX = 100000; + +#ifdef PERMISSION_TEST + const int32_t TEST_UID = 1000; + const int32_t TEST_PID = 1; +#endif + + int32_t CheckSystemPermission(const std::string &pkgName, const std::string &permission) + { + auto bundleObj = + OHOS::DelayedSingleton::GetInstance()->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (bundleObj == nullptr) { + LOG_ERR("failed to get bundle manager service"); + return SOFTBUS_ERR; + } + OHOS::sptr bmgr = OHOS::iface_cast(bundleObj); + return bmgr->CheckPermission(std::string(pkgName), std::string(permission)); + } + + int32_t GetPermType(int32_t callingUid, int32_t callingPid, const char *pkgName) + { + std::string pkg; + if (pkgName != nullptr) { + pkg = std::string(pkgName); + } + if (callingUid == SHELL_UID) { + return SOFTBUS_PERMISSION_DENIED; + } + if (callingUid == static_cast(getuid()) && + callingPid == static_cast(getpid())) { + return SELF_APP; + } + int32_t ret = CheckSystemPermission(pkg, SYSTEM_APP_PERMISSION); + if (ret == PERMISSION_GRANTED) { + LOG_INFO("system app"); + return SYSTEM_APP; + } + ret = CheckSystemPermission(pkg, DANGER_APP_PERMISSION); + if (ret == PERMISSION_GRANTED) { + LOG_INFO("normal app"); + return NORMAL_APP; + } + if (callingUid > INVALID_UID && callingUid < FIRST_APPLICATION_UID && callingUid != SHELL_UID) { + LOG_INFO("native app"); + return NATIVE_APP; + } + return SOFTBUS_PERMISSION_DENIED; + } +} + +int32_t TransPermissionInit(const char *fileName) +{ + if (fileName == nullptr) { + return SOFTBUS_PERMISSION_DENIED; + } + return LoadPermissionJson(fileName); +} + +void TransPermissionDeinit(void) +{ + DeinitPermissionJson(); +} + +int32_t CheckTransPermission(const char *sessionName, const char *pkgName, uint32_t actions) +{ + int32_t ret; +#ifdef PERMISSION_TEST + int32_t callingUid = TEST_UID; + int32_t callingPid = TEST_PID; +#else + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); + int32_t callingPid = OHOS::IPCSkeleton::GetCallingPid(); +#endif + int32_t permType = GetPermType(callingUid, callingPid, pkgName); + if (permType < 0) { + return permType; + } + if (sessionName == nullptr && pkgName == nullptr) { + return permType; + } + if (sessionName == nullptr && pkgName != nullptr) { + if (IsValidPkgName(callingUid, pkgName) == SOFTBUS_OK) { + return permType; + } + return SOFTBUS_PERMISSION_DENIED; + } + SoftBusPermissionItem *pItem = CreatePermissionItem(permType, callingUid, callingPid, pkgName, actions); + if (pItem == nullptr) { + return SOFTBUS_MALLOC_ERR; + } + ret = CheckPermissionEntry(sessionName, pItem); + SoftBusFree(pItem); + return ret; +} + +bool CheckDiscPermission(const char *pkgName) +{ + std::string pkg; + if (pkgName != nullptr) { + pkg = std::string(pkgName); + } else { + return false; + } +#ifdef PERMISSION_TEST + int32_t callingUid = TEST_UID; +#else + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); +#endif + if (callingUid == SYSTEM_UID || callingUid % MULTE_USER_RADIX == SYSTEM_UID) { + return true; + } + if (CheckSystemPermission(pkg, BIND_DISCOVER_SERVICE) == PERMISSION_GRANTED) { + return true; + } + return false; +} + +bool CheckBusCenterPermission(const char *pkgName) +{ + std::string pkg; + if (pkgName != nullptr) { + pkg = std::string(pkgName); + } else { + return false; + } + +#ifdef PERMISSION_TEST + int32_t callingUid = TEST_UID; +#else + int32_t callingUid = OHOS::IPCSkeleton::GetCallingUid(); +#endif + if (callingUid == SYSTEM_UID || callingUid % MULTE_USER_RADIX == SYSTEM_UID) { + return true; + } + if (CheckSystemPermission(pkg, SYSTEM_APP_PERMISSION) == PERMISSION_GRANTED) { + return true; + } + if (CheckSystemPermission(pkg, DANGER_APP_PERMISSION) == PERMISSION_GRANTED) { + return true; + } + return false; +} \ No newline at end of file diff --git a/core/common/security/sequence_verification/BUILD.gn b/core/common/security/sequence_verification/BUILD.gn new file mode 100755 index 000000000..3d3ee7b81 --- /dev/null +++ b/core/common/security/sequence_verification/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_seq_verification") { + sources = [ "src/softbus_sequence_verification.c" ] + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-std=c99", + ] + } +} else { + shared_library("softbus_seq_verification") { + sources = [ "src/softbus_sequence_verification.c" ] + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-std=c99", + ] + } +} diff --git a/core/common/security/sequence_verification/include/softbus_sequence_verification.h b/core/common/security/sequence_verification/include/softbus_sequence_verification.h new file mode 100644 index 000000000..688ebfed5 --- /dev/null +++ b/core/common/security/sequence_verification/include/softbus_sequence_verification.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SEQUENCE_VERIFICATION_H +#define SOFTBUS_SEQUENCE_VERIFICATION_H + +#include +#include +#include "softbus_def.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* when receive seq < minSeq, the package is duplicated. + when receive seq == minSeq, update minSeq. + when minSeq < receive seq < maxSeq, Check whether duplicate package exist, record the package in bitmap. + when receive seq >= maxSeq, update maxSeq, record the package in bitmap. +*/ +typedef struct { + int32_t maxSeq; + int32_t minSeq; + uint64_t recvBitmap; +} SeqVerifyInfo; + +/* When the received package is an ACK packet, this function does not need to be called for verification. */ +bool IsPassSeqCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // !SOFTBUS_SEQUENCE_VERIFICATION_H diff --git a/core/common/security/sequence_verification/src/softbus_sequence_verification.c b/core/common/security/sequence_verification/src/softbus_sequence_verification.c new file mode 100644 index 000000000..6b6067f21 --- /dev/null +++ b/core/common/security/sequence_verification/src/softbus_sequence_verification.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_sequence_verification.h" +#include "softbus_log.h" + +#define MAX_SEQ_BIAS 60 + +static bool IsDifferentSign(int32_t seqA, int32_t seqB) +{ + if ((seqA >= 0 && seqB >= 0) || (seqA < 0 && seqB < 0)) { + return false; + } + return true; +} + +static bool IsPassDuplicateCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + uint32_t offset = seqVerifyInfo->maxSeq - recvSeq; + int32_t isRepeat = seqVerifyInfo->recvBitmap & (0x1UL << offset); + if (isRepeat) { + LOG_INFO("duplicated package seq[%d].", recvSeq); + return false; + } + seqVerifyInfo->recvBitmap |= (0x1UL << offset); + return true; +} + +static bool IsPassOverMaxCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + /* consider flip */ + if (recvSeq - seqVerifyInfo->maxSeq < 0) { + return false; + } + + if (recvSeq - seqVerifyInfo->minSeq >= MAX_SEQ_BIAS) { + LOG_ERR("seq bias reach max[%d].", MAX_SEQ_BIAS); + return false; + } + uint32_t seqOffset = recvSeq - seqVerifyInfo->maxSeq + 1; + seqVerifyInfo->maxSeq = ++recvSeq; + seqVerifyInfo->recvBitmap = seqVerifyInfo->recvBitmap << seqOffset; + /* 1: represent the penultimate bit of recvBitmap is 1. */ + seqVerifyInfo->recvBitmap |= (0x1UL << 1); + return true; +} + +static bool IsPassAllRangeCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + if (recvSeq == seqVerifyInfo->minSeq) { + seqVerifyInfo->minSeq = ++recvSeq; + return true; + } + + if (recvSeq > seqVerifyInfo->minSeq) { + if (recvSeq < seqVerifyInfo->maxSeq) { + return IsPassDuplicateCheck(seqVerifyInfo, recvSeq); + } + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + return false; +} + +static bool IsPassNormalCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + /* normal case */ + if (recvSeq == seqVerifyInfo->minSeq) { + seqVerifyInfo->minSeq = recvSeq + 1; + seqVerifyInfo->maxSeq = recvSeq + 1; + return true; + } + /* first disorder package, recvSeq and minSeq/maxSeq are same signs. */ + if (!IsDifferentSign(recvSeq, seqVerifyInfo->minSeq)) { + if (recvSeq > seqVerifyInfo->maxSeq) { + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + return false; + } + /* first disorder package, recvSeq and minSeq/maxSeq are different signs. */ + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); +} + +static bool IsPassNoflipDisorderCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + if (seqVerifyInfo->minSeq >= 0) { + if (recvSeq >= 0) { + return IsPassAllRangeCheck(seqVerifyInfo, recvSeq); + } + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + if (seqVerifyInfo->maxSeq < 0) { + if (recvSeq < 0) { + return IsPassAllRangeCheck(seqVerifyInfo, recvSeq); + } + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + /* can not reach here. */ + return false; +} + +static bool IsPassFlipPositiveCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + if (recvSeq >= 0) { + if (recvSeq < seqVerifyInfo->maxSeq) { + return IsPassDuplicateCheck(seqVerifyInfo, recvSeq); + } + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + if (recvSeq < 0) { + if (recvSeq == seqVerifyInfo->minSeq) { + seqVerifyInfo->minSeq = ++recvSeq; + return true; + } + if (recvSeq > seqVerifyInfo->minSeq) { + return IsPassDuplicateCheck(seqVerifyInfo, recvSeq); + } + return false; + } + /* can not reach here. */ + return false; +} + +static bool IsPassFlipNegativeCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + if (recvSeq >= 0) { + if (recvSeq == seqVerifyInfo->minSeq) { + seqVerifyInfo->minSeq = ++recvSeq; + return true; + } + if (recvSeq > seqVerifyInfo->minSeq) { + return IsPassDuplicateCheck(seqVerifyInfo, recvSeq); + } + return false; + } + if (recvSeq < 0) { + if (recvSeq < seqVerifyInfo->maxSeq) { + return IsPassDuplicateCheck(seqVerifyInfo, recvSeq); + } + return IsPassOverMaxCheck(seqVerifyInfo, recvSeq); + } + /* can not reach here. */ + return false; +} + +bool IsPassSeqCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq) +{ + if (seqVerifyInfo == NULL) { + LOG_ERR("invalid param."); + return false; + } + bool isDifferentSign = IsDifferentSign(seqVerifyInfo->minSeq, seqVerifyInfo->maxSeq); + if (seqVerifyInfo->minSeq == seqVerifyInfo->maxSeq) { + return IsPassNormalCheck(seqVerifyInfo, recvSeq); + } + if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && !isDifferentSign) { + return IsPassNoflipDisorderCheck(seqVerifyInfo, recvSeq); + } + if ((seqVerifyInfo->minSeq > seqVerifyInfo->maxSeq) && isDifferentSign) { + return IsPassFlipNegativeCheck(seqVerifyInfo, recvSeq); + } + if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && isDifferentSign) { + return IsPassFlipPositiveCheck(seqVerifyInfo, recvSeq); + } + /* can not reach here. */ + return false; +} diff --git a/core/common/softbus_property/BUILD.gn b/core/common/softbus_property/BUILD.gn new file mode 100755 index 000000000..f180158e4 --- /dev/null +++ b/core/common/softbus_property/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_property") { + sources = [ "src/softbus_property.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "include", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + } +} else { + shared_library("softbus_property") { + cflags = [ "-Wall" ] + sources = [ "src/softbus_property.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "include", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + public_deps = [ + "$dsoftbus_root_path/core/common/json_utils:json_utils", + "//build/lite/config/component/cJSON:cjson_shared", + "//third_party/bounds_checking_function:libsec_shared", + ] + } +} diff --git a/core/common/softbus_property/include/softbus_config.h b/core/common/softbus_property/include/softbus_config.h new file mode 100644 index 000000000..e74742a1d --- /dev/null +++ b/core/common/softbus_property/include/softbus_config.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CONFIG_H +#define SOFTBUS_CONFIG_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +static const char* SOFTBUS_CONFIG = +"{\ +\"MAX_BYTES_LENGTH\" : 4194304,\ +\"MAX_MESSAGE_LENGTH\" : 4096,\ +\"CONN_BR_MAX_DATA_LENGTH\" : 4096,\ +\"CONN_RFCOM_SEND_MAX_LEN\" : 990,\ +\"CONN_BR_RECEIVE_MAX_LEN\" : 10,\ +\"CONN_TCP_MAX_LENGTH\" : 3072,\ +\"CONN_TCP_MAX_CONN_NUM\" : 30,\ +\"CONN_TCP_TIME_OUT\" : 100,\ +\"MAX_NODE_STATE_CB_CNT\" : 10\ +}"; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif // SOFTBUS_CONFIG_H \ No newline at end of file diff --git a/core/common/softbus_property/src/softbus_property.c b/core/common/softbus_property/src/softbus_property.c new file mode 100755 index 000000000..fe61ab26b --- /dev/null +++ b/core/common/softbus_property/src/softbus_property.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_property.h" + +#include "softbus_config.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" + +static cJSON *GetConfigText() +{ + cJSON *config = cJSON_Parse(SOFTBUS_CONFIG); + if (config == NULL) { + LOG_ERR("json parse failed. %s\n", cJSON_GetErrorPtr()); + return NULL; + } + return config; +} + +int GetPropertyString(const char *string, char *target, size_t targetLen) +{ + if (string == NULL || target == NULL || targetLen == 0) { + LOG_ERR("Invalid param."); + return SOFTBUS_INVALID_PARAM; + } + cJSON *config = GetConfigText(); + if (config == NULL) { + LOG_ERR("Get config text failed."); + return SOFTBUS_PARSE_JSON_ERR; + } + bool res = GetJsonObjectStringItem(config, string, target, targetLen); + cJSON_Delete(config); + if (!res) { + LOG_ERR("Get config item with %s failed.", string); + return SOFTBUS_PARSE_JSON_ERR; + } + return SOFTBUS_OK; +} + +int GetPropertyInt(const char *string, int *target) +{ + if (string == NULL || target == NULL) { + LOG_ERR("Invalid param."); + return SOFTBUS_INVALID_PARAM; + } + cJSON *config = GetConfigText(); + if (config == NULL) { + LOG_ERR("Get config text failed."); + return SOFTBUS_PARSE_JSON_ERR; + } + bool res = GetJsonObjectNumberItem(config, string, target); + cJSON_Delete(config); + if (!res) { + LOG_ERR("Get config item with %s failed.", string); + return SOFTBUS_PARSE_JSON_ERR; + } + return SOFTBUS_OK; +} + +int GetPropertyDouble(const char *string, double *target) +{ + if (string == NULL || target == NULL) { + LOG_ERR("Invalid param."); + return SOFTBUS_INVALID_PARAM; + } + cJSON *config = GetConfigText(); + if (config == NULL) { + LOG_ERR("Get config text failed."); + return SOFTBUS_PARSE_JSON_ERR; + } + bool res = GetJsonObjectDoubleItem(config, string, target); + cJSON_Delete(config); + if (!res) { + LOG_ERR("Get config item with %s failed.", string); + return SOFTBUS_PARSE_JSON_ERR; + } + return SOFTBUS_OK; +} + +int GetPropertyBool(const char *string, bool *target) +{ + if (string == NULL || target == NULL) { + LOG_ERR("Invalid param."); + return SOFTBUS_INVALID_PARAM; + } + cJSON *config = GetConfigText(); + if (config == NULL) { + LOG_ERR("Get config text failed."); + return SOFTBUS_PARSE_JSON_ERR; + } + bool res = GetJsonObjectBoolItem(config, string, target); + cJSON_Delete(config); + if (!res) { + LOG_ERR("Get config item with %s failed.", string); + return SOFTBUS_PARSE_JSON_ERR; + } + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/common/utils/BUILD.gn b/core/common/utils/BUILD.gn new file mode 100755 index 000000000..876c7c6c6 --- /dev/null +++ b/core/common/utils/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_utils") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//third_party/bounds_checking_function/include", + "//third_party/mbedtls/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ "-Wall" ] + sources = [ "softbus_utils.c" ] + } +} else { + shared_library("softbus_utils") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//third_party/bounds_checking_function/include", + "//third_party/mbedtls/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ "-Wall" ] + sources = [ "softbus_utils.c" ] + public_deps = [ + "$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel", + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/mbedtls:mbedtls_shared", + ] + } +} diff --git a/core/common/utils/softbus_utils.c b/core/common/utils/softbus_utils.c new file mode 100755 index 000000000..614f84c36 --- /dev/null +++ b/core/common/utils/softbus_utils.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_utils.h" + +#include "pthread.h" + +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/entropy.h" +#include "securec.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_os_interface.h" +#include "softbus_type_def.h" + +#ifndef MBEDTLS_CTR_DRBG_C +#define MBEDTLS_CTR_DRBG_C +#endif + +#ifndef MBEDTLS_ENTROPY_C +#define MBEDTLS_ENTROPY_C +#endif +static pthread_mutex_t g_randomLock = PTHREAD_MUTEX_INITIALIZER; +static void *g_timerId = NULL; +static TimerFunCallback g_timerFunList[SOFTBUS_MAX_TIMER_FUN_NUM] = {0}; + +SoftBusList *CreateSoftBusList(void) +{ + SoftBusList *list = (SoftBusList *)SoftBusMalloc(sizeof(SoftBusList)); + if (list == NULL) { + LOG_ERR("malloc failed"); + return NULL; + } + (void)memset_s(list, sizeof(SoftBusList), 0, sizeof(SoftBusList)); + + if (pthread_mutex_init(&list->lock, NULL) != 0) { + LOG_ERR("init lock failed"); + SoftBusFree(list); + return NULL; + } + + ListInit(&list->list); + return list; +} + +void DestroySoftBusList(SoftBusList *list) +{ + ListDelInit(&list->list); + pthread_mutex_destroy(&list->lock); + SoftBusFree(list); + return; +} + +int32_t RegisterTimeoutCallback(int32_t timerFunId, TimerFunCallback callback) +{ + if (callback == NULL || timerFunId >= SOFTBUS_MAX_TIMER_FUN_NUM || + timerFunId < SOFTBUS_CONN_TIMER_FUN) { + return SOFTBUS_ERR; + } + + if (g_timerFunList[timerFunId] != NULL) { + return SOFTBUS_OK; + } + + g_timerFunList[timerFunId] = callback; + return SOFTBUS_OK; +} + +static void HandleTimeoutFun(void) +{ + int32_t i; + for (i = 0; i < SOFTBUS_MAX_TIMER_FUN_NUM; i++) { + if (g_timerFunList[i] != NULL) { + g_timerFunList[i](); + } + } +} + +int32_t SoftBusTimerInit(void) +{ + if (g_timerId != NULL) { + return SOFTBUS_OK; + } + g_timerId = SoftBusCreateTimer(&g_timerId, (void *)HandleTimeoutFun, TIMER_TYPE_PERIOD); + if (SoftBusStartTimer(g_timerId, TIMER_TIMEOUT) != SOFTBUS_OK) { + LOG_ERR("start timer failed."); + (void)SoftBusDeleteTimer(g_timerId); + g_timerId = NULL; + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +void SoftBusTimerDeInit(void) +{ + if (g_timerId != NULL) { + (void)SoftBusDeleteTimer(g_timerId); + g_timerId = NULL; + } +} + +int32_t GenerateRandomArray(unsigned char *randStr, uint32_t len) +{ + if (randStr == NULL || len == 0) { + return SOFTBUS_INVALID_PARAM; + } + mbedtls_entropy_context *entropy = (mbedtls_entropy_context *)SoftBusCalloc(sizeof(mbedtls_entropy_context)); + if (entropy == NULL) { + return SOFTBUS_MALLOC_ERR; + } + mbedtls_ctr_drbg_context *ctrDrbg = SoftBusCalloc(sizeof(mbedtls_ctr_drbg_context)); + if (ctrDrbg == NULL) { + SoftBusFree(entropy); + return SOFTBUS_MALLOC_ERR; + } + + if (pthread_mutex_lock(&g_randomLock) != 0) { + LOG_ERR("lock mutex failed"); + SoftBusFree(ctrDrbg); + SoftBusFree(entropy); + return SOFTBUS_ERR; + } + mbedtls_ctr_drbg_init(ctrDrbg); + mbedtls_entropy_init(entropy); + int ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy, NULL, 0); + if (ret != 0) { + pthread_mutex_unlock(&g_randomLock); + LOG_ERR("gen random seed error, ret[%d]", ret); + SoftBusFree(ctrDrbg); + SoftBusFree(entropy); + return SOFTBUS_ERR; + } + ret = mbedtls_ctr_drbg_random(ctrDrbg, randStr, len); + if (ret != 0) { + pthread_mutex_unlock(&g_randomLock); + SoftBusFree(ctrDrbg); + SoftBusFree(entropy); + LOG_ERR("gen random error, ret[%d]", ret); + return SOFTBUS_ERR; + } + pthread_mutex_unlock(&g_randomLock); + SoftBusFree(ctrDrbg); + SoftBusFree(entropy); + return SOFTBUS_OK; +} + +int32_t ConvertHexStringToBytes(unsigned char *outBuf, uint32_t outBufLen, const char *inBuf, int32_t inLen) +{ + (void)outBufLen; + + if ((outBuf == NULL) || (inBuf == NULL) || (inLen % HEXIFY_UNIT_LEN != 0)) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + uint32_t outLen = UN_HEXIFY_LEN(inLen); + uint32_t i = 0; + while (i < outLen) { + unsigned char c = *inBuf++; + if ((c >= '0') && (c <= '9')) { + c -= '0'; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a' - DEC_MAX_NUM; + } else if ((c >= 'A') && (c <= 'F')) { + c -= 'A' - DEC_MAX_NUM; + } else { + LOG_ERR("HexToString Error! %c", c); + return SOFTBUS_ERR; + } + + unsigned char c2 = *inBuf++; + if ((c2 >= '0') && (c2 <= '9')) { + c2 -= '0'; + } else if ((c2 >= 'a') && (c2 <= 'f')) { + c2 -= 'a' - DEC_MAX_NUM; + } else if ((c2 >= 'A') && (c2 <= 'F')) { + c2 -= 'A' - DEC_MAX_NUM; + } else { + LOG_ERR("HexToString Error! %c2", c2); + return SOFTBUS_ERR; + } + + *outBuf++ = (c << HEX_MAX_BIT_NUM) | c2; + i++; + } + return SOFTBUS_OK; +} + +int32_t ConvertBytesToHexString(char *outBuf, uint32_t outBufLen, const unsigned char *inBuf, int32_t inLen) +{ + if ((outBuf == NULL) || (inBuf == NULL) || (outBufLen < (uint32_t)HEXIFY_LEN(inLen))) { + return SOFTBUS_ERR; + } + + while (inLen > 0) { + unsigned char h = *inBuf / HEX_MAX_NUM; + unsigned char l = *inBuf % HEX_MAX_NUM; + + if (h < DEC_MAX_NUM) { + *outBuf++ = '0' + h; + } else { + *outBuf++ = 'a' + h - DEC_MAX_NUM; + } + + if (l < DEC_MAX_NUM) { + *outBuf++ = '0' + l; + } else { + *outBuf++ = 'a' + l - DEC_MAX_NUM; + } + + ++inBuf; + inLen--; + } + return SOFTBUS_OK; +} + +int32_t GenerateRandomStr(char *str, uint32_t len) +{ + if ((str == NULL) || (len < HEXIFY_UNIT_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + uint32_t hexLen = len / HEXIFY_UNIT_LEN; + unsigned char *hexAuthId = (unsigned char *)SoftBusMalloc(hexLen); + if (hexAuthId == NULL) { + return SOFTBUS_MEM_ERR; + } + (void)memset_s(hexAuthId, hexLen, 0, hexLen); + + if (GenerateRandomArray(hexAuthId, hexLen) != SOFTBUS_OK) { + SoftBusFree(hexAuthId); + return SOFTBUS_ERR; + } + + if (ConvertBytesToHexString(str, len, hexAuthId, hexLen) != SOFTBUS_OK) { + SoftBusFree(hexAuthId); + return SOFTBUS_ERR; + } + + SoftBusFree(hexAuthId); + return SOFTBUS_OK; +} + +bool IsValidString(const char *input, uint32_t maxLen) +{ + if (input == NULL) { + return false; + } + + uint32_t len = strlen(input); + if ((len == 0) || (len >= maxLen)) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/core/connection/BUILD.gn b/core/connection/BUILD.gn new file mode 100644 index 000000000..91e79c9d7 --- /dev/null +++ b/core/connection/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") + +lite_component("softbus_connection") { + features = [ "manager:conn_manager" ] +} diff --git a/core/connection/br/BUILD.gn b/core/connection/br/BUILD.gn new file mode 100644 index 000000000..238253d1d --- /dev/null +++ b/core/connection/br/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +static_library("br_connection") { + sources = [ "br_connection.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/adapter/br/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/connection/interface", + "//third_party/cJSON", + ] + deps = [ "$dsoftbus_root_path/core/adapter/br/mock:br_adapter" ] +} diff --git a/core/connection/br/br_connection.c b/core/connection/br/br_connection.c new file mode 100644 index 000000000..59bddcf0b --- /dev/null +++ b/core/connection/br/br_connection.c @@ -0,0 +1,1664 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "cJSON.h" +#include "cmsis_os2.h" +#include "common_list.h" +#include "message_handler.h" +#include "ohos_types.h" +#include "securec.h" +#include "softbus_conn_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_property.h" +#include "softbus_type_def.h" +#include "stdbool.h" +#include "string.h" +#include "time.h" +#include "unistd.h" +#include "wrapper_br_interface.h" + +#define KEY_METHOD "KEY_METHOD" +#define KEY_DELTA "KEY_DELTA" +#define KEY_REFERENCE_NUM "KEY_REFERENCE_NUM" +#define GET_PROPERTY_LENGTH "CONN_BR_MAX_DATA_LENGTH" +#define GET_SEND_MESSAGE_PEER_LEN "CONN_RFCOM_SEND_MAX_LEN" +#define BR_SENDQUEQUE_MAXNUM "CONN_BR_RECEIVE_MAX_LEN" +#define METHOD_NOTIFY_REQUEST 1 +#define METHOD_NOTIFY_RESPONSE 2 +#define METHOD_SHUT_DOWN 3 +#define DISCONN_DELAY_TIME 200 +#define MAGIC_NUMBER 0xBABEFACE +#define TIMEOUT_DISCONNECT 1000 +#define CONNECT_REF_INCRESE 1 +#define CONNECT_REF_DECRESE (-1) +#define BR_CONNECT_TEST 1588 +#define BR_CLIENT_TYPE 0 +#define BR_MAC_PRINT 17 +#define BR_SERVICE_TYPE 1 +#define BT_RFCOM_CONGEST_ON 0 +#define BT_RFCOM_CONGEST_OFF 1 +#define BR_NOTIFY_REQUESTID 1 +#define BR_NOTIFY_REQUESTID_DISCONNECT 2 +#define BR_STATE_RECAVER 5 +#define BR_CONNECT_TASK 10 +#define BR_SEND_THREAD_STACK 3072 +#define BR_RECE_THREAD_STACK 4096 +#define MAX_BR_SIZE (32*1024) +#define MAX_BR_PEER_SIZE (3*1024) +#define INVALID_LENGTH (-1) +#define PRIORITY_HIGH 64 +#define PRIORITY_MID 8 +#define PRIORITY_LOW 1 +#define PRIORITY_DAF 1 +#define INVALID_VALUE (-1) +#define MAX_BR_SENDQUEQUE_SIZE (10*10) +#define BT_ADDR_LEN_RFCOM 6 + +typedef struct { + ListNode node; + int32_t requestId; + ConnectResult callback; +} RequestInfo; + +typedef struct { + ListNode node; + uint32_t connectionId; + int32_t socketFd; + int32_t sideType; + char mac[BT_MAC_LEN]; + int32_t connectQueueState; + int32_t state; + int32_t refCount; + int32_t refCountRemote; + char *recvBuf; + int32_t recvPos; + int32_t conGestState; + ListNode requestList; + pthread_mutex_t lock; + pthread_cond_t congestCond; +} BrConnectionInfo; + +typedef struct { + ListNode node; + uint32_t connectionId; + int32_t pid; + int32_t priority; + uint32_t dataLen; + int32_t sendPos; + char *data; +} SendItemStruct; + +typedef struct { + ListNode node; + int32_t pid; + int32_t itemCount; +} DataPidQueueStruct; + +typedef struct { + ListNode sendList; + ListNode pidList; + pthread_mutex_t lock; + pthread_cond_t cond; + SoftBusHandler *handler; +} DataQueueStruct; + +typedef struct { + ListNode node; + uint32_t connectionId; + int32_t module; + long seqNum; + int32_t flag; + uint32_t dataLen; + uint8_t *data; +} ReceiveItemStruct; + +typedef struct { + ListNode recvList; + pthread_mutex_t lock; + pthread_cond_t cond; + SoftBusHandler *handler; +} RecvQueueStruct; + +enum BRConnectionState { + BR_CONNECTION_STATE_CONNECTING = 0, + BR_CONNECTION_STATE_CONNECTED, + BR_CONNECTION_STATE_CLOSING, + BR_CONNECTION_STATE_CLOSED +}; + +static void ClientOnEvent(int32_t type, int32_t socketFd, int32_t value); + +static void ClientOnDataReceived(int32_t socketFd, const char *buf, int32_t len); + +static void ServerOnEvent(int32_t type, int32_t socketFd, int32_t value); + +static void ServerOnDataReceived(int32_t socketFd, const char *buf, int32_t len); + +static bool GetJsonObjectNumberItem(const cJSON *json, const char * const string, int *target); + +static bool AddNumberToJsonObject(cJSON *obj, const char * const string, int32_t num); + +static int32_t ConnectDevice(const ConnectOption *option, uint32_t requestId, const ConnectResult *result); + +static int32_t PostBytes(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag); + +static int32_t DisconnectDevice(uint32_t connectionId); + +static int32_t DisconnectDeviceNow(const ConnectOption *option); + +static int32_t GetConnectionInfo(uint32_t connectionId, ConnectionInfo *info); + +static int32_t StartLocalListening(const LocalListenerInfo *info); + +static int32_t StopLocalListening(const LocalListenerInfo *info); + +static void ClientOnBrDisconnect(int32_t socketFd, int32_t value); + +static void ClearSendItemByConnId(uint32_t connectionId); + +static void ClearReceiveQueueByConnId(uint32_t connectionId); + +static int32_t ConvertBtMacToBinary(char *strMac, int32_t strMacLen, + const uint8_t *binMac, int32_t binMacLen) +{ + int32_t ret; + + if (strMac == NULL || strMacLen < BT_MAC_LEN || binMac == NULL || binMacLen < BT_ADDR_LEN) { + return SOFTBUS_INVALID_PARAM; + } + ret = sscanf_s(strMac, "%02x:%02x:%02x:%02x:%02x:%02x", + &binMac[0], &binMac[1], &binMac[2], &binMac[3], &binMac[4], &binMac[5]); + if (ret < 0) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t ConvertBtMacToStr(char *strMac, int32_t strMacLen, + const uint8_t *binMac, int32_t binMacLen) +{ + int32_t ret; + + if (strMac == NULL || strMacLen < BT_MAC_LEN || binMac == NULL || binMacLen < BT_ADDR_LEN) { + return SOFTBUS_INVALID_PARAM; + } + ret = snprintf_s(strMac, strMacLen, strMacLen - 1, "%02x:%02x:%02x:%02x:%02x:%02x", + binMac[0], binMac[1], binMac[2], binMac[3], binMac[4], binMac[5]); + if (ret < 0) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static SppSocketEventCallback g_sppSocketClientCallback = { + .OnEvent = ClientOnEvent, + .OnDataReceived = ClientOnDataReceived +}; + + +static SppSocketEventCallback g_sppSocketServiceCallback = { + .OnEvent = ServerOnEvent, + .OnDataReceived = ServerOnDataReceived +}; + +static ConnectFuncInterface g_brInterface = { + .ConnectDevice = ConnectDevice, + .PostBytes = PostBytes, + .DisconnectDevice = DisconnectDevice, + .DisconnectDeviceNow = DisconnectDeviceNow, + .GetConnectionInfo = GetConnectionInfo, + .StartLocalListening = StartLocalListening, + .StopLocalListening = StopLocalListening +}; + +static pthread_mutex_t g_connectionLock; +static const uint8_t UUID[BT_UUID_LEN] = { + 0x8c, 0xe2, 0x55, 0xc0, 0x20, 0x0a, 0x11, 0xe0, + 0xac, 0x64, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 +}; + +static LIST_HEAD(g_conection_list); +static DataQueueStruct g_dataQueue; +static RecvQueueStruct g_recvQueue; +static SppSocketDriver *g_sppDriver = NULL; +static ConnectCallback *g_connectCallback = NULL; + +static int16_t g_nextConnectionId = 0; +static int32_t g_brBuffSize; +static int32_t g_brSendPeerLen; +static int32_t g_brSendQueueMaxLen; +static int32_t AllocNewConnectionIdLocked() +{ + g_nextConnectionId++; + int32_t tempId; + while (1) { + tempId = (CONNECT_BR << CONNECT_TYPE_SHIFT) + g_nextConnectionId; + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == tempId) { + g_nextConnectionId++; + continue; + } + } + break; + } + return tempId; +} + +static int32_t GetConnectionInfo(uint32_t connectionId, ConnectionInfo *info) +{ + int32_t result = SOFTBUS_ERR; + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connectionId) { + info->isAvailable = 1; + info->isServer = itemNode->sideType; + info->type = CONNECT_BR; + if (strncpy_s(info->info.brInfo.brMac, BT_MAC_LEN, + itemNode->mac, sizeof(itemNode->mac)) != EOK) { + LOG_ERR("GetConnInfo scpy error"); + (void)pthread_mutex_unlock(&g_connectionLock); + return SOFTBUS_BRCONNECTION_GETCONNINFO_ERROR; + } + result = SOFTBUS_OK; + break; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + return result; +} + +static BrConnectionInfo *GetConnectionRef(uint32_t connID) +{ + BrConnectionInfo *result = NULL; + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connID) { + result = itemNode; + break; + } + } + return result; +} + +static void ReleaseConnection(BrConnectionInfo *conn) +{ + LOG_INFO("ReleaseConnection node + %u", conn->connectionId); + ListNode *item = NULL; + ListNode *nextItem = NULL; + LIST_FOR_EACH_SAFE(item, nextItem, &conn->requestList) { + RequestInfo *requestInfo = LIST_ENTRY(item, RequestInfo, node); + ListDelete(&(requestInfo->node)); + SoftBusFree(requestInfo); + } + pthread_cond_destroy(&conn->congestCond); + pthread_mutex_destroy(&conn->lock); + SoftBusFree(conn->recvBuf); + SoftBusFree(conn); +} + +static void ReleaseConnectionRef(BrConnectionInfo *conn) +{ + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + ListDelete(&conn->node); + ReleaseConnection(conn); + (void)pthread_mutex_unlock(&g_connectionLock); +} + +static int AddNumToJson(cJSON *json, int32_t requestOrResponse, int32_t delta, int32_t count) +{ + if (requestOrResponse == METHOD_NOTIFY_REQUEST) { + if (!AddNumberToJsonObject(json, KEY_METHOD, METHOD_NOTIFY_REQUEST) || + !AddNumberToJsonObject(json, KEY_DELTA, delta) || + !AddNumberToJsonObject(json, KEY_REFERENCE_NUM, count)) { + return SOFTBUS_BRCONNECTION_PACKJSON_ERROR; + } + } else { + if (!AddNumberToJsonObject(json, KEY_METHOD, METHOD_NOTIFY_RESPONSE) || + !AddNumberToJsonObject(json, KEY_REFERENCE_NUM, count)) { + return SOFTBUS_BRCONNECTION_PACKJSON_ERROR; + } + } + return SOFTBUS_OK; +} + +static void SendRefMessage(int32_t delta, int32_t connectionId, int32_t count, int32_t requestOrResponse) +{ + cJSON *json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("Cannot create cJSON object"); + return; + } + if (AddNumToJson(json, requestOrResponse, delta, count) != SOFTBUS_OK) { + cJSON_Delete(json); + LOG_ERR("Cannot AddNumToJson"); + return; + } + + char *data = cJSON_PrintUnformatted(json); + cJSON_Delete(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + return; + } + + int32_t headSize = sizeof(ConnPktHead); + int32_t dataLen = strlen(data) + 1 + headSize; + char *buf = (char *)SoftBusCalloc(dataLen); + if (buf == NULL) { + cJSON_free(data); + return; + } + ConnPktHead head; + head.magic = MAGIC_NUMBER; + head.module = MODULE_CONNECTION; + head.seq = 1; + head.flag = 0; + head.len = strlen(data) + 1; + + if (memcpy_s(buf, dataLen, (void *)&head, headSize)) { + cJSON_free(data); + LOG_ERR("memcpy_s head error"); + cJSON_free(data); + SoftBusFree(buf); + return; + } + if (memcpy_s(buf + headSize, dataLen - headSize, data, strlen(data) + 1)) { + cJSON_free(data); + LOG_ERR("memcpy_s data error"); + cJSON_free(data); + SoftBusFree(buf); + return; + } + (void)PostBytes(connectionId, buf, dataLen, 0, 0); + cJSON_free(data); + return; +} + +static void PackRequest(int32_t delta, int32_t connectionId) +{ + LOG_INFO("[onNotifyRequest: delta=%d, connectionIds=%u", delta, connectionId); + ListNode *item = NULL; + BrConnectionInfo *targetNode = NULL; + int refCount; + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connectionId) { + itemNode->refCount += delta; + refCount = itemNode->refCount; + targetNode = itemNode; + break; + } + } + if (targetNode == NULL) { + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + (void)pthread_mutex_unlock(&g_connectionLock); + + SendRefMessage(delta, connectionId, refCount, METHOD_NOTIFY_REQUEST); +} + +static void OnPackResponse(int32_t delta, int32_t peerRef, int32_t connectionId) +{ + LOG_INFO("[onNotifyRequest: delta=%d, RemoteRef=%d, connectionIds=%u", delta, peerRef, connectionId); + ListNode *item = NULL; + BrConnectionInfo *targetNode = NULL; + int myRefCount; + int mySocketFd; + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connectionId) { + targetNode = itemNode; + targetNode->refCount += delta; + myRefCount = targetNode->refCount; + mySocketFd = targetNode->socketFd; + break; + } + } + if (targetNode == NULL) { + LOG_INFO("Not find OnPackResponse device"); + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + (void)pthread_mutex_unlock(&g_connectionLock); + LOG_INFO("[onPackRequest: myRefCount=%d]", myRefCount); + if (peerRef > 0) { + LOG_INFO("[remote device Ref is > 0, do not reply]"); + return; + } + if (myRefCount <= 0) { + LOG_INFO("[local device Ref <= 0, close connection now]"); + g_sppDriver->CloseClient(mySocketFd); + return; + } + SendRefMessage(delta, connectionId, myRefCount, METHOD_NOTIFY_RESPONSE); +} + +static int32_t HasDiffMacDeviceExit(const ConnectOption *option) +{ + if (IsListEmpty(&g_conection_list)) { + LOG_INFO("[g_conection_list is empty, allow to connect device.]"); + return 0; + } + ListNode *item = NULL; + int32_t res; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (memcmp(itemNode->mac, option->info.brOption.brMac, sizeof(itemNode->mac)) == 0 && + itemNode->sideType == BR_CLIENT_TYPE) { + res = SOFTBUS_OK; + } else { + res = SOFTBUS_ERR; + break; + } + } + LOG_INFO("[check HasDiffMacDeviceExit, return value is %d", res); + return res; +} + +static void ReleaseBrconnectionNode(BrConnectionInfo *newConnectionInfo) +{ + if (newConnectionInfo == NULL) { + return; + } + + LOG_ERR("[ReleaseBrconnectionNode"); + pthread_cond_destroy(&newConnectionInfo->congestCond); + pthread_mutex_destroy(&newConnectionInfo->lock); + pthread_mutex_destroy(&newConnectionInfo->lock); + if (newConnectionInfo->recvBuf != NULL) { + SoftBusFree(newConnectionInfo->recvBuf); + } + RequestInfo *requestInfo = NULL; + ListNode *item = NULL; + ListNode *itemNext = NULL; + if (IsListEmpty(&newConnectionInfo->requestList) != true) { + LIST_FOR_EACH_SAFE(item, itemNext, &newConnectionInfo->requestList) { + requestInfo = LIST_ENTRY(item, RequestInfo, node); + ListDelete(&requestInfo->node); + SoftBusFree(requestInfo); + } + } + SoftBusFree(newConnectionInfo); + return; +} + +static BrConnectionInfo* CreateBrconnectionNode(int clientFlag) +{ + BrConnectionInfo *newConnectionInfo = SoftBusCalloc(sizeof(BrConnectionInfo)); + if (newConnectionInfo == NULL) { + LOG_ERR("[ConnectDeviceFristTime malloc fail.]"); + return NULL; + } + newConnectionInfo->recvBuf = SoftBusCalloc(g_brBuffSize); + if (newConnectionInfo->recvBuf == NULL) { + LOG_ERR("[SoftBusMalloc recvBuf fail]"); + SoftBusFree(newConnectionInfo); + return NULL; + } + ListInit(&newConnectionInfo->node); + ListInit(&newConnectionInfo->requestList); + pthread_mutex_init(&newConnectionInfo->lock, NULL); + newConnectionInfo->connectionId = AllocNewConnectionIdLocked(); + newConnectionInfo->recvPos = 0; + newConnectionInfo->conGestState = BT_RFCOM_CONGEST_OFF; + pthread_cond_init(&newConnectionInfo->congestCond, NULL); + newConnectionInfo->refCount = 1; + return newConnectionInfo; +} + +static int32_t ConnectDeviceFristTime(const ConnectOption *option, uint32_t requestId, const ConnectResult *result) +{ + BrConnectionInfo *newConnectionInfo = CreateBrconnectionNode(true); + if (newConnectionInfo == NULL) { + LOG_ERR("[client node create fail]"); + return SOFTBUS_ERR; + } + RequestInfo *requestInfo = SoftBusCalloc(sizeof(RequestInfo)); + if (requestInfo == NULL) { + ReleaseBrconnectionNode(newConnectionInfo); + return NULL; + } + ListInit(&requestInfo->node); + ListAdd(&newConnectionInfo->requestList, &requestInfo->node); + strncpy_s(newConnectionInfo->mac, sizeof(newConnectionInfo->mac), + option->info.brOption.brMac, BT_MAC_LEN); + // init lock + + requestInfo->requestId = requestId; + (void)memcpy_s(&requestInfo->callback, sizeof(requestInfo->callback), result, sizeof(*result)); + newConnectionInfo->state = BR_CONNECTION_STATE_CONNECTING; + newConnectionInfo->sideType = BR_CLIENT_TYPE; + int32_t socketFd = SOFTBUS_ERR; + uint8_t btAddr[BT_ADDR_LEN]; + + if (ConvertBtMacToBinary(newConnectionInfo->mac, BT_MAC_LEN, btAddr, BT_ADDR_LEN) != SOFTBUS_OK) { + LOG_ERR("convert bt mac to binary fail.]"); + ReleaseBrconnectionNode(newConnectionInfo); + return SOFTBUS_ERR; + } + if (g_sppDriver != NULL) { + socketFd = g_sppDriver->OpenSppClient(btAddr, UUID, 0); + } + if (socketFd == SOFTBUS_ERR) { + ReleaseBrconnectionNode(newConnectionInfo); + return SOFTBUS_BRCONNECTION_CONNECTDEVICE_GETSOCKETIDFAIL; + } + newConnectionInfo->socketFd = socketFd; + LOG_INFO("[new connection %d,socket=%d", newConnectionInfo->connectionId, socketFd); + ListAdd(&g_conection_list, &newConnectionInfo->node); + int32_t ret = g_sppDriver->Connect(socketFd, &g_sppSocketClientCallback); + return ret; +} + +static void ConnectDeviceExit(const BrConnectionInfo *itemNode, uint32_t requestId, const ConnectResult *result) +{ + LOG_INFO("[already find mac in g_conection_list]"); + ConnectionInfo connectionInfo; + connectionInfo.isAvailable = 1; + connectionInfo.isServer = itemNode->sideType; + connectionInfo.type = CONNECT_BR; + strncpy_s(connectionInfo.info.brInfo.brMac, BT_MAC_LEN, + itemNode->mac, sizeof(itemNode->mac)); + int connectionId = itemNode->connectionId; + + (void)pthread_mutex_unlock(&g_connectionLock); + if (result->OnConnectSuccessed != NULL) { + result->OnConnectSuccessed( + requestId, connectionId, &connectionInfo); + } + + (void)PackRequest(CONNECT_REF_INCRESE, connectionId); +} + +int32_t ConnectDevice(const ConnectOption *option, uint32_t requestId, const ConnectResult *result) +{ + int32_t ret = SOFTBUS_OK; + LOG_INFO("[ConnectDevice]"); + if (HasDiffMacDeviceExit(option) != SOFTBUS_OK) { + LOG_INFO("[g_conection_list has diff mac device, mini system not support.]"); + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + ListNode *item = NULL; + BrConnectionInfo *targetConnectionInfo = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (strncmp(itemNode->mac, option->info.brOption.brMac, BT_MAC_LEN) == 0) { + targetConnectionInfo = itemNode; + if (itemNode->state == BR_CONNECTION_STATE_CONNECTED) { + ConnectDeviceExit(itemNode, requestId, result); + return SOFTBUS_OK; + } else if (itemNode->state == BR_CONNECTION_STATE_CONNECTING) { + RequestInfo *requestInfo = SoftBusMalloc(sizeof(RequestInfo)); + if (requestInfo == NULL) { + (void)pthread_mutex_unlock(&g_connectionLock); + LOG_INFO("[ConnectDevice fail and state is BR_CONNECTION_STATE_CONNECTING.]"); + return SOFTBUS_ERR; + } + (void)memset_s(requestInfo, sizeof(RequestInfo), 0, sizeof(RequestInfo)); + ListInit(&requestInfo->node); + requestInfo->requestId = requestId; + (void)memcpy_s(&requestInfo->callback, sizeof(requestInfo->callback), result, sizeof(*result)); + ListAdd(&itemNode->requestList, &requestInfo->node); + ret = SOFTBUS_OK; + } else if (itemNode->state == BR_CONNECTION_STATE_CLOSING) { + result->OnConnectFailed(requestId, 0); + ret = SOFTBUS_OK; + } + } + } + if (targetConnectionInfo == NULL) { + LOG_INFO("[targetConnectionInfo == NULL]"); + ret = ConnectDeviceFristTime(option, requestId, result); + } + (void)pthread_mutex_unlock(&g_connectionLock); + return ret; +} + +static void DeviceConnectPackRequest(int32_t value, int32_t connectionId) +{ + while (--value > 0) { + (void)PackRequest(CONNECT_REF_INCRESE, connectionId); + } +} + +void RfcomCongestEvent(int32_t socketFd, int32_t value) +{ + ListNode *item = NULL; + BrConnectionInfo *itemNode = NULL; + + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + LIST_FOR_EACH(item, &g_conection_list) { + itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->socketFd == socketFd) { + itemNode->conGestState = value; + if (value == BT_RFCOM_CONGEST_OFF) { + if (pthread_mutex_lock(&itemNode->lock) != 0) { + (void)pthread_mutex_unlock(&g_connectionLock); + LOG_ERR("lock itemNode failed"); + return; + } + pthread_cond_broadcast(&itemNode->congestCond); + (void)pthread_mutex_unlock(&itemNode->lock); + } + break; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); +} + +static void ClientOnBrConnect(int32_t socketFd) +{ + ListNode notifyList; + ListInit(¬ifyList); + ListNode *britem = NULL; + ListNode *item = NULL; + ListNode *itemNext = NULL; + RequestInfo *requestInfo = NULL; + ConnectionInfo connectionInfo; + (void)pthread_mutex_lock(&g_connectionLock); + int32_t connectionId = 0; + int32_t packRequestFlag = 0; + LIST_FOR_EACH(britem, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(britem, BrConnectionInfo, node); + if (itemNode->socketFd == socketFd) { + connectionInfo.isAvailable = 1; + connectionInfo.isServer = itemNode->sideType; + connectionInfo.type = CONNECT_BR; + strncpy_s(connectionInfo.info.brInfo.brMac, BT_MAC_LEN, + itemNode->mac, sizeof(itemNode->mac)); + connectionId = itemNode->connectionId; + itemNode->state = BR_CONNECTION_STATE_CONNECTED; + LIST_FOR_EACH_SAFE(item, itemNext, &itemNode->requestList) { + requestInfo = LIST_ENTRY(item, RequestInfo, node); + LOG_INFO("[ClientOnEvent] requestId=%d, connectionId=%u", + requestInfo->requestId, itemNode->connectionId); + ListDelete(&requestInfo->node); + ListAdd(¬ifyList, &requestInfo->node); + packRequestFlag++; + } + break; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + if (connectionId != 0) { + DeviceConnectPackRequest(packRequestFlag, connectionId); + LIST_FOR_EACH_SAFE(item, itemNext, ¬ifyList) { + requestInfo = LIST_ENTRY(item, RequestInfo, node); + if (requestInfo->callback.OnConnectSuccessed != NULL) { + requestInfo->callback.OnConnectSuccessed( + requestInfo->requestId, connectionId, &connectionInfo); + } + ListDelete(&requestInfo->node); + SoftBusFree(requestInfo); + } + } +} + +static void ClientOnEvent(int32_t type, int32_t socketFd, int32_t value) +{ + LOG_INFO("[ClientOnEvent] type=%d, socketFd=%d", type, socketFd); + if (type == SPP_EVENT_TYPE_CONNECTED) { + ClientOnBrConnect(socketFd); + } else if (type == SPP_EVENT_TYPE_DISCONNECTED) { + ClientOnBrDisconnect(socketFd, value); + } else if (type == SPP_EVENT_TYPE_CONGEST) { + RfcomCongestEvent(socketFd, value); + } +} + +static int32_t InitConnectionInfo(ConnectionInfo *connectionInfo, const BrConnectionInfo *itemNode) +{ + (*connectionInfo).isAvailable = 0; + (*connectionInfo).isServer = itemNode->sideType; + (*connectionInfo).type = CONNECT_BR; + if (strncpy_s((*connectionInfo).info.brInfo.brMac, BT_MAC_LEN, + itemNode->mac, sizeof(itemNode->mac)) != EOK) { + LOG_ERR("InitConnInfo scpy error"); + return SOFTBUS_BRCONNECTION_STRNCPY_ERROR; + } + return SOFTBUS_OK; +} + +static void FreeCongestEvent(BrConnectionInfo *itemNode) +{ + itemNode->conGestState = BT_RFCOM_CONGEST_OFF; + if (pthread_mutex_lock(&itemNode->lock) != 0) { + LOG_ERR("FreeCongestEvent mutex failed"); + return; + } + pthread_cond_broadcast(&itemNode->congestCond); + (void)pthread_mutex_unlock(&itemNode->lock); +} + +static void NotifyDisconnect(const ListNode *notifyList, int32_t connectionId, + ConnectionInfo connectionInfo, int32_t value) +{ + ListNode *item = NULL; + ListNode *itemNext = NULL; + if (IsListEmpty(notifyList) != true) { + LIST_FOR_EACH_SAFE(item, itemNext, notifyList) { + RequestInfo *requestInfo = LIST_ENTRY(item, RequestInfo, node); + if (requestInfo->callback.OnConnectFailed != NULL) { + LOG_INFO("[ClientOnEvent] disconn connectionId=%d", connectionId); + requestInfo->callback.OnConnectFailed(requestInfo->requestId, value); + } + ListDelete(&requestInfo->node); + SoftBusFree(requestInfo); + } + } + + if (g_connectCallback != NULL) { + LOG_INFO("[ClientOnEvent] disconn connectionId=%d", connectionId); + g_connectCallback->OnDisconnected(connectionId, &connectionInfo); + } +} + +static void ClientOnBrDisconnect(int32_t socketFd, int32_t value) +{ + ListNode *britem = NULL; + ListNode *item = NULL; + ListNode *itemNext = NULL; + int32_t connectionId = -1; + ListNode notifyList; + ListInit(¬ifyList); + ConnectionInfo connectionInfo; + BrConnectionInfo *brNode = NULL; + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("ClientOnBrDisconnect mutex failed"); + return; + } + LIST_FOR_EACH(britem, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(britem, BrConnectionInfo, node); + if (itemNode->socketFd == socketFd) { + brNode = itemNode; + itemNode->state = BR_CONNECTION_STATE_CLOSED; + FreeCongestEvent(itemNode); + if (InitConnectionInfo(&connectionInfo, itemNode) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + connectionId = itemNode->connectionId; + LIST_FOR_EACH_SAFE(item, itemNext, &itemNode->requestList) { + RequestInfo *requestInfo = LIST_ENTRY(item, RequestInfo, node); + ListDelete(&requestInfo->node); + ListAdd(¬ifyList, &requestInfo->node); + } + break; + } + } + ClearSendItemByConnId(connectionId); + ClearReceiveQueueByConnId(connectionId); + ReleaseConnectionRef(brNode); + (void)pthread_mutex_unlock(&g_connectionLock); + if (connectionId != -1) { + NotifyDisconnect(¬ifyList, connectionId, connectionInfo, value); + } +} + +static int32_t ReceivedHeadCheck(const ConnPktHead *head, BrConnectionInfo *conn) +{ + if (head->magic != 0xBABEFACE) { + LOG_ERR("[ClientOnDataReceived] magic error 0x%x", head->magic); + conn->recvPos = 0; + return SOFTBUS_ERR; + } + + if (head->len > (g_brBuffSize - sizeof(ConnPktHead))) { + LOG_ERR("[ClientOnDataReceived]data too large . module=%d,seq=%lld, datalen=%d", + head->module, head->seq, head->len); + conn->recvPos = 0; + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t ReceivedError(ReceiveItemStruct *recvItem, char *dataCopy, + const char *bufHead, const ConnPktHead *head, int32_t sendToManagerLen) +{ + if (recvItem == NULL) { + LOG_ERR("malloc recvItem fail"); + if (dataCopy != NULL) { + SoftBusFree(dataCopy); + } + return SOFTBUS_ERR; + } + if (dataCopy == NULL) { + LOG_ERR("malloc dataCopy fail"); + SoftBusFree(recvItem); + return SOFTBUS_ERR; + } + if (memcpy_s(dataCopy, sendToManagerLen, + bufHead, head->len + sizeof(ConnPktHead)) != EOK) { + LOG_ERR("ReceivedError memcpy_s failed"); + SoftBusFree(dataCopy); + SoftBusFree(recvItem); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + + +static void InitRecvItemAndInsert(ReceiveItemStruct *recvItem, int32_t connectionId, + const ConnPktHead *head, int32_t sendToManagerLen, const char *dataCopy) +{ + recvItem->connectionId = connectionId; + recvItem->module = head->module; + recvItem->seqNum = head->seq; + recvItem->flag = head->flag; + recvItem->dataLen = sendToManagerLen; + recvItem->data = (uint8_t*)dataCopy; + if (pthread_mutex_lock(&g_recvQueue.lock) != 0) { + LOG_ERR("InitRecvItemAndInsert mutex failed"); + return; + } + if (recvItem->module == MODULE_DEVICE_AUTH) { + ListAdd(&g_recvQueue.recvList, &recvItem->node); + } else { + ListTailInsert(&g_recvQueue.recvList, &recvItem->node); + } + LOG_INFO("[ClientOnDataReceived] connectionId=%d", connectionId); + pthread_cond_signal(&g_recvQueue.cond); + (void)pthread_mutex_unlock(&g_recvQueue.lock); +} + +static void ClientOnDataReceived(int32_t socketFd, const char *buf, int32_t len) +{ + LOG_INFO("[ClientOnDataReceived] socketFd=%d,len=%d", socketFd, len); + BrConnectionInfo *conn = NULL; + (void)pthread_mutex_lock(&g_connectionLock); + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->socketFd == socketFd) { + conn = itemNode; + break; + } + } + + if (conn == NULL) { + (void)pthread_mutex_unlock(&g_connectionLock); + LOG_ERR("[ClientOnDataReceived] not found socket=%d", socketFd); + return; + } + + char *bufHead = (char*)buf; + int32_t bufLen = len; + bool isCopy = false; + if (conn->recvPos != 0) { + LOG_DBG("[ClientOnDataReceived] recvPos=%d", conn->recvPos); + (void)memcpy_s(conn->recvBuf + conn->recvPos, g_brBuffSize - conn->recvPos, buf, len); + conn->recvPos += len; + isCopy = true; + bufHead = conn->recvBuf; + bufLen = conn->recvPos; + } + // recv head + if (bufLen < sizeof(ConnPktHead)) { + if (!isCopy) { + (void)memcpy_s(conn->recvBuf + conn->recvPos, g_brBuffSize - conn->recvPos, buf, len); + conn->recvPos += len; + isCopy = true; + } + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + + ConnPktHead *head = (ConnPktHead *)bufHead; + if (ReceivedHeadCheck(head, conn) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + + if (head->len > (bufLen - sizeof(ConnPktHead))) { + LOG_ERR("[ClientOnDataReceived] socket=%d , continue to recv", socketFd); + if (!isCopy) { + (void)memcpy_s(conn->recvBuf + conn->recvPos, g_brBuffSize - conn->recvPos, buf, len); + conn->recvPos += len; + isCopy = true; + } + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + bool headtogether = false; + int32_t sendToManagerLen = bufLen; + if (head->len < (bufLen - sizeof(ConnPktHead))) { + headtogether = true; + sendToManagerLen = head->len + sizeof(ConnPktHead); + } + if (g_connectCallback != NULL) { + LOG_ERR("[ClientOnDataReceived] socket=%d , ready to insert", socketFd); + ReceiveItemStruct *recvItem = SoftBusMalloc(sizeof(ReceiveItemStruct)); + if (recvItem == NULL) { + LOG_ERR("malloc failed"); + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + char *dataCopy = SoftBusMalloc(sendToManagerLen); + if (dataCopy == NULL) { + LOG_ERR("malloc failed"); + SoftBusFree(recvItem); + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + if (ReceivedError(recvItem, dataCopy, bufHead, head, sendToManagerLen) != SOFTBUS_OK) { + conn->recvPos = 0; + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + InitRecvItemAndInsert(recvItem, conn->connectionId, head, sendToManagerLen, dataCopy); + } + if (headtogether == false) { + conn->recvPos = 0; + } else { + if (memmove_s(conn->recvBuf, g_brBuffSize, + conn->recvBuf + sendToManagerLen, bufLen - sendToManagerLen) != EOK) { + LOG_ERR("memmove_s failed"); + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + conn->recvPos = bufLen - sendToManagerLen; + } + (void)pthread_mutex_unlock(&g_connectionLock); +} + +static int32_t NotifyServerConn(int connectionId, const BrConnectionInfo *conn) +{ + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + ConnectionInfo connectionInfo; + connectionInfo.isAvailable = 1; + connectionInfo.isServer = conn->sideType; + connectionInfo.type = CONNECT_BR; + if (strncpy_s(connectionInfo.info.brInfo.brMac, + BT_MAC_LEN, conn->mac, sizeof(conn->mac)) != EOK) { + LOG_ERR("NotifyServerConn scpy error"); + (void)pthread_mutex_unlock(&g_connectionLock); + return SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&g_connectionLock); + g_connectCallback->OnConnected(connectionId, &connectionInfo); + return SOFTBUS_OK; +} + +static void ServerOnBrConnect(int32_t type, int32_t socketFd, int32_t value) +{ + LOG_INFO("[new connection, socket = %d", value); + (void)pthread_mutex_lock(&g_connectionLock); + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (value == itemNode->socketFd) { + LOG_INFO("Serviceconnection exit, socketFd=%d", socketFd); + (void)pthread_mutex_unlock(&g_connectionLock); + return; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + BrConnectionInfo *newConnectionInfo = CreateBrconnectionNode(false); + if (newConnectionInfo == NULL) { + LOG_ERR("[service node create fail]"); + g_sppDriver->CloseClient(value); + return; + } + RequestInfo *requestInfo = SoftBusCalloc(sizeof(RequestInfo)); + if (requestInfo == NULL) { + ReleaseBrconnectionNode(newConnectionInfo); + g_sppDriver->CloseClient(value); + return; + } + ListInit(&requestInfo->node); + ListAdd(&newConnectionInfo->requestList, &requestInfo->node); + BluetoothRemoteDevice* info = NULL; + g_sppDriver->GetRemoteDeviceInfo(value, info); + if (info == NULL) { + return; + } + if (ConvertBtMacToStr(newConnectionInfo->mac, BT_MAC_LEN, (uint8_t *)info->mac, BT_ADDR_LEN_RFCOM) != SOFTBUS_OK) { + LOG_ERR("convert bt mac to str fail"); + ReleaseBrconnectionNode(newConnectionInfo); + g_sppDriver->CloseClient(value); + return; + } + newConnectionInfo->socketFd = value; + newConnectionInfo->state = BR_CONNECTION_STATE_CONNECTED; + newConnectionInfo->sideType = BR_SERVICE_TYPE; + int connectionId = newConnectionInfo->connectionId; + ListAdd(&g_conection_list, &newConnectionInfo->node); + if (NotifyServerConn(connectionId, newConnectionInfo) != SOFTBUS_OK) { + ReleaseBrconnectionNode(newConnectionInfo); + g_sppDriver->CloseClient(value); + } + return; +} + +static void ServerOnBrDisconnect(int32_t socketFd, int32_t value) +{ + ClientOnBrDisconnect(socketFd, value); +} + +static void ServerOnDataReceived(int32_t socketFd, const char *buf, int32_t len) +{ + ClientOnDataReceived(socketFd, buf, len); +} + +static void ServerOnEvent(int32_t type, int32_t socketFd, int32_t value) +{ + LOG_INFO("[ClientOnEvent] socketFd=%d", socketFd); + if (type == SPP_EVENT_TYPE_CONNECTED) { + ServerOnBrConnect(type, socketFd, value); + } else if (type == SPP_EVENT_TYPE_DISCONNECTED) { + ServerOnBrDisconnect(socketFd, value); + } +} + +static int32_t GetPriority(int32_t flag) +{ + int priority; + switch (flag) { + case CONN_HIGH: { + priority = PRIORITY_HIGH; + break; + } + case CONN_MIDDLE: { + priority = PRIORITY_MID; + break; + } + case CONN_LOW: { + priority = PRIORITY_LOW; + break; + } + default: + priority = PRIORITY_DAF; + break; + } + return priority; +} + +static int32_t CheckSendQueueLength(void) +{ + int totalSendNum = 0; + ListNode *sendItemNode = NULL; + if (pthread_mutex_lock(&g_dataQueue.lock) != 0) { + LOG_ERR("CheckSendQueueLength mutex failed"); + return SOFTBUS_ERR; + } + LIST_FOR_EACH(sendItemNode, &g_dataQueue.sendList) { + totalSendNum++; + } + (void)pthread_mutex_unlock(&g_dataQueue.lock); + if (totalSendNum > g_brSendQueueMaxLen) { + return SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL; + } + return SOFTBUS_OK; +} + +static DataPidQueueStruct *CreatNewPidNode(int pid) +{ + DataPidQueueStruct *pidQueue = SoftBusCalloc(sizeof(DataPidQueueStruct)); + if (pidQueue == NULL) { + LOG_ERR("PostBytes CreatNewPidNode fail"); + return NULL; + } + ListInit(&pidQueue->node); + pidQueue->pid = pid; + ListTailInsert(&g_dataQueue.pidList, &pidQueue->node); + return pidQueue; +} + +static int32_t CreateNewSendItem(int pid, int flag, int connectionId, int len, const char *data) +{ + SendItemStruct *sendItem = SoftBusCalloc(sizeof(SendItemStruct)); + if (sendItem == NULL) { + LOG_ERR("PostBytes CreateNewSendItem fail"); + return SOFTBUS_ERR; + } + ListInit(&sendItem->node); + sendItem->pid = pid; + sendItem->priority = GetPriority(flag); + sendItem->connectionId = connectionId; + sendItem->dataLen = len; + sendItem->data = (char*)data; + + ListNode *item = NULL; + ListNode *nextItem = NULL; + SendItemStruct *sendItemInsert = NULL; + int lastInsertFlag = false; + LIST_FOR_EACH_SAFE(item, nextItem, &g_dataQueue.sendList) { + sendItemInsert = LIST_ENTRY(item, SendItemStruct, node); + if (sendItemInsert->pid == pid && sendItemInsert->priority < sendItem->priority) { + LOG_INFO("SendItem ListAdd"); + ListNode *sendItemNode = item->prev; + ListAdd(sendItemNode, &sendItem->node); + lastInsertFlag = true; + break; + } + } + if (lastInsertFlag != true) { + LOG_INFO("SendItem ListTailInsert"); + ListTailInsert(&g_dataQueue.sendList, &sendItem->node); + } + return SOFTBUS_OK; +} + +static int32_t PostBytes(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag) +{ + LOG_INFO("PostBytes connectionId=%u,pid=%d,len=%d flag=%d", connectionId, pid, len, flag); + (void)pthread_mutex_lock(&g_connectionLock); + if (CheckSendQueueLength() != SOFTBUS_OK) { + SoftBusFree((void*)data); + (void)pthread_mutex_unlock(&g_connectionLock); + return SOFTBUS_CONNECTION_ERR_SENDQUEUE_FULL; + } + BrConnectionInfo *conn = GetConnectionRef(connectionId); + if (conn == NULL) { + LOG_INFO("PostBytes connectionId=%u not found", connectionId); + SoftBusFree((void*)data); + (void)pthread_mutex_unlock(&g_connectionLock); + return SOFTBUS_BRCONNECTION_POSTBYTES_ERROR; + } + + (void)pthread_mutex_lock(&g_dataQueue.lock); + DataPidQueueStruct *pidQueue = NULL; + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_dataQueue.pidList) { + DataPidQueueStruct *itemNode = LIST_ENTRY(item, DataPidQueueStruct, node); + if (itemNode->pid == pid) { + pidQueue = itemNode; + break; + } + } + if (pidQueue == NULL) { + pidQueue = CreatNewPidNode(pid); + if (pidQueue == NULL) { + (void)pthread_mutex_unlock(&g_connectionLock); + SoftBusFree((void*)data); + (void)pthread_mutex_unlock(&g_dataQueue.lock); + return SOFTBUS_BRCONNECTION_POSTBYTES_ERROR; + } + } + + pidQueue->itemCount++; + LOG_INFO("PostBytes pidQueue count=%d", pidQueue->itemCount); + if (CreateNewSendItem(pid, flag, connectionId, len, data) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&g_connectionLock); + SoftBusFree((void*)data); + SoftBusFree(pidQueue); + (void)pthread_mutex_unlock(&g_dataQueue.lock); + return SOFTBUS_BRCONNECTION_POSTBYTES_ERROR; + } + + (void)pthread_mutex_unlock(&g_connectionLock); + pthread_cond_broadcast(&g_dataQueue.cond); + (void)pthread_mutex_unlock(&g_dataQueue.lock); + return SOFTBUS_OK; +} + + +static void FreeSendItem(SendItemStruct *sendItem) +{ + LOG_INFO("FreeSendItem"); + if (sendItem == NULL) { + return; + } + if (sendItem->data != NULL) { + SoftBusFree(sendItem->data); + } + SoftBusFree(sendItem); +} + + +static void ClearDataPidByPid(int32_t pid) +{ + ListNode *item = NULL; + ListNode *nextItem = NULL; + LIST_FOR_EACH_SAFE(item, nextItem, &g_dataQueue.pidList) { + DataPidQueueStruct *itemNode = LIST_ENTRY(item, DataPidQueueStruct, node); + if (itemNode->pid == pid) { + ListDelete(item); + SoftBusFree(itemNode); + } + } +} + +static void ClearSendItemByConnId(uint32_t connectionId) +{ + if (pthread_mutex_lock(&g_dataQueue.lock) != 0) { + LOG_ERR("ClearSendItemByConnId mutex failed"); + return; + } + ListNode *sendItemNode = NULL; + ListNode *nextItem = NULL; + SendItemStruct *sendItem = NULL; + LIST_FOR_EACH_SAFE(sendItemNode, nextItem, &g_dataQueue.sendList) { + sendItem = LIST_ENTRY(sendItemNode, SendItemStruct, node); + if (sendItem->connectionId == connectionId) { + ClearDataPidByPid(sendItem->pid); + ListDelete(sendItemNode); + FreeSendItem(sendItem); + } + } + (void)pthread_mutex_unlock(&g_dataQueue.lock); +} + +static int32_t SendData(SendItemStruct *sendItem) +{ + BrConnectionInfo *brConnInfo = NULL; + LOG_INFO("SendData"); + (void)pthread_mutex_lock(&g_connectionLock); + ListNode *item = NULL; + int32_t socketFd = -1; + LIST_FOR_EACH(item, &g_conection_list) { + brConnInfo = LIST_ENTRY(item, BrConnectionInfo, node); + if (brConnInfo->connectionId == sendItem->connectionId) { + socketFd = brConnInfo->socketFd; + } + } + + if (socketFd == -1) { + (void)pthread_mutex_unlock(&g_connectionLock); + return SOFTBUS_ERR; + } + int32_t writeRet = -1; + int freeLock = false; + + int32_t templen = sendItem->dataLen; + char *sendData = sendItem->data; + while (templen > 0) { + (void)pthread_mutex_lock(&brConnInfo->lock); + while (brConnInfo->conGestState == BT_RFCOM_CONGEST_ON && + brConnInfo->state == BR_CONNECTION_STATE_CONNECTED) { + LOG_INFO("wait congest"); + (void)pthread_mutex_unlock(&g_connectionLock); + freeLock = true; + pthread_cond_wait(&brConnInfo->congestCond, &brConnInfo->lock); + LOG_INFO("free congest"); + break; + } + (void)pthread_mutex_unlock(&brConnInfo->lock); + + int32_t sendlenth = templen; + if (sendlenth > g_brSendPeerLen) { + sendlenth = g_brSendPeerLen; + } + writeRet = g_sppDriver->Write(socketFd, sendItem->data, sendlenth); + sendItem->data += sendlenth; + templen -= sendlenth; + } + sendItem->data = sendData; + if (freeLock != true) { + (void)pthread_mutex_unlock(&g_connectionLock); + } + return writeRet; +} + +void *SendHandlerLoop(const void *arg) +{ + while (1) { + (void)pthread_mutex_lock(&g_dataQueue.lock); + if (IsListEmpty(&g_dataQueue.sendList)) { + LOG_INFO("SendHandlerLoop empty"); + pthread_cond_wait(&g_dataQueue.cond, &g_dataQueue.lock); + LOG_INFO("start SendHandlerLoop"); + (void)pthread_mutex_unlock(&g_dataQueue.lock); + continue; + } + ListNode *item = NULL; + int32_t sendPid = 0; + LIST_FOR_EACH(item, &g_dataQueue.pidList) { + DataPidQueueStruct *itemNode = LIST_ENTRY(item, DataPidQueueStruct, node); + ListDelete(item); + itemNode->itemCount--; + sendPid = itemNode->pid; + if (itemNode->itemCount == 0) { + SoftBusFree(itemNode); + } else { + ListTailInsert(&g_dataQueue.pidList, &itemNode->node); + } + break; + } + + ListNode *sendItemNode = NULL; + SendItemStruct *sendItem = NULL; + LIST_FOR_EACH(sendItemNode, &g_dataQueue.sendList) { + sendItem = LIST_ENTRY(sendItemNode, SendItemStruct, node); + if (sendItem->pid == sendPid) { + ListDelete(sendItemNode); + break; + } + } + if (sendItem == NULL) { + LOG_ERR("SendItem fail"); + continue; + } + (void)pthread_mutex_unlock(&g_dataQueue.lock); + if (SendData(sendItem) != SOFTBUS_OK) { + LOG_INFO("SendItem fail"); + } + FreeSendItem(sendItem); + } +} + +static void RecvConnectedComd(uint32_t connectionId, const cJSON *data) +{ + int32_t keyMethod = 0; + int32_t keyDelta = 0; + int32_t keyRefernceNum = 0; + LOG_INFO("RecvConnectedComd ID=%u", connectionId); + + if (!GetJsonObjectNumberItem(data, KEY_METHOD, &keyMethod)) { + return; + } + if (keyMethod == METHOD_NOTIFY_REQUEST) { + if (!GetJsonObjectNumberItem(data, KEY_METHOD, &keyMethod) || + !GetJsonObjectNumberItem(data, KEY_DELTA, &keyDelta) || + !GetJsonObjectNumberItem(data, KEY_REFERENCE_NUM, &keyRefernceNum)) { + LOG_INFO("REQUEST fail"); + return; + } + OnPackResponse(keyDelta, keyRefernceNum, connectionId); + } + if (keyMethod == METHOD_NOTIFY_RESPONSE) { + LOG_INFO("NOTIFY_RESPONSE"); + if (!GetJsonObjectNumberItem(data, KEY_METHOD, &keyMethod) || + !GetJsonObjectNumberItem(data, KEY_REFERENCE_NUM, &keyRefernceNum)) { + LOG_INFO("RESPONSE fail"); + return; + } + (void)pthread_mutex_lock(&g_connectionLock); + ListNode *item = NULL; + LIST_FOR_EACH(item, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connectionId) { + if (itemNode->state == BR_CONNECTION_STATE_CLOSING) { + LOG_INFO("NOTIFY_CHANGE"); + itemNode->state = BR_CONNECTION_STATE_CONNECTED; + } + break; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + } +} + +void *RecvHandlerLoop(const void *arg) +{ + while (1) { + (void)pthread_mutex_lock(&g_recvQueue.lock); + if (IsListEmpty(&g_recvQueue.recvList)) { + LOG_INFO("RecvHandlerLoop empty"); + pthread_cond_wait(&g_recvQueue.cond, &g_recvQueue.lock); + LOG_INFO("Recv recvQueueCond"); + (void)pthread_mutex_unlock(&g_recvQueue.lock); + continue; + } + + ListNode *recvItemNode = NULL; + ReceiveItemStruct *recvItem = NULL; + LIST_FOR_EACH(recvItemNode, &g_recvQueue.recvList) { + recvItem = LIST_ENTRY(recvItemNode, ReceiveItemStruct, node); + ListDelete(recvItemNode); + break; + } + (void)pthread_mutex_unlock(&g_recvQueue.lock); + LOG_INFO("RecvHandlerLoop OnDataReceived"); + if (recvItem->module == MODULE_CONNECTION) { + cJSON *data = NULL; + data = cJSON_Parse((char *)(recvItem->data + sizeof(ConnPktHead))); + if (data == NULL) { + SoftBusFree(recvItem->data); + SoftBusFree(recvItem); + LOG_ERR("[receive data invalid]"); + continue; + } + RecvConnectedComd(recvItem->connectionId, (const cJSON*)data); + cJSON_Delete(data); + } else { + if (g_connectCallback != NULL) { + g_connectCallback->OnDataReceived(recvItem->connectionId, (ConnModule)recvItem->module, recvItem->seqNum, + (char*)recvItem->data, recvItem->dataLen); + } + } + SoftBusFree(recvItem->data); + SoftBusFree(recvItem); + } +} + +static void ClearReceiveQueueByConnId(uint32_t connectionId) +{ + if (pthread_mutex_lock(&g_recvQueue.lock) != 0) { + LOG_ERR("ClearReceiveQueueByConnId mutex failed"); + return; + } + ListNode *recvItemNode = NULL; + ListNode *nextItem = NULL; + ReceiveItemStruct *recvItem = NULL; + LIST_FOR_EACH_SAFE(recvItemNode, nextItem, &g_recvQueue.recvList) { + recvItem = LIST_ENTRY(recvItemNode, ReceiveItemStruct, node); + if (recvItem->connectionId == connectionId) { + ListDelete(recvItemNode); + SoftBusFree(recvItem->data); + SoftBusFree(recvItem); + } + } + (void)pthread_mutex_unlock(&g_recvQueue.lock); +} + +static int32_t DisconnectDevice(uint32_t connectionId) +{ + LOG_INFO("[DisconnectDevice]"); + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("DisconnectDevice mutex failed"); + return SOFTBUS_ERR; + } + ListNode *item = NULL; + ListNode *nextItem = NULL; + int getConnectionId = -1; + LIST_FOR_EACH_SAFE(item, nextItem, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (itemNode->connectionId == connectionId) { + getConnectionId = itemNode->connectionId; + break; + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + if (getConnectionId == -1) { + return SOFTBUS_BRCONNECTION_DISCONNECT_NOTFIND; + } + (void)PackRequest(CONNECT_REF_DECRESE, getConnectionId); + LOG_INFO("[DisconnectDevice over]"); + return SOFTBUS_OK; +} + +static int32_t DisconnectDeviceNow(const ConnectOption *option) +{ + int32_t ret = (int32_t)SOFTBUS_ERR; + LOG_INFO("[DisconnectDeviceByOption]"); + if (option == NULL || option->type != CONNECT_BR) { + LOG_ERR("option check fail"); + return ret; + } + if (pthread_mutex_lock(&g_connectionLock) != 0) { + LOG_ERR("DisconnectDevice mutex failed"); + return ret; + } + ListNode *item = NULL; + ListNode *nextItem = NULL; + ConnectionInfo connectionInfo; + LIST_FOR_EACH_SAFE(item, nextItem, &g_conection_list) { + BrConnectionInfo *itemNode = LIST_ENTRY(item, BrConnectionInfo, node); + if (memcmp(itemNode->mac, option->info.brOption.brMac, sizeof(itemNode->mac)) == 0) { + if (!IsListEmpty(&g_dataQueue.sendList)) { + osDelay(DISCONN_DELAY_TIME); + } + ret = g_sppDriver->CloseClient(itemNode->socketFd); + } + } + (void)pthread_mutex_unlock(&g_connectionLock); + return ret; +} + +static void InitDataQueue(DataQueueStruct *dataQueue) +{ + ListInit(&dataQueue->sendList); + ListInit(&dataQueue->pidList); + pthread_mutex_init(&dataQueue->lock, NULL); + pthread_cond_init(&dataQueue->cond, NULL); + + pthread_t tid; + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + pthread_attr_setstacksize(&threadAttr, BR_SEND_THREAD_STACK); + if (pthread_create(&tid, &threadAttr, SendHandlerLoop, NULL) != 0) { + LOG_ERR("create DeathProcTask failed"); + } +} + +static void InitRecvQueue(RecvQueueStruct *recvQueue) +{ + ListInit(&recvQueue->recvList); + pthread_mutex_init(&recvQueue->lock, NULL); + pthread_cond_init(&recvQueue->cond, NULL); + + pthread_t tid; + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + pthread_attr_setstacksize(&threadAttr, BR_RECE_THREAD_STACK); + if (pthread_create(&tid, &threadAttr, RecvHandlerLoop, NULL) != 0) { + LOG_ERR("create DeathProcTask failed"); + } +} + +static int32_t StartLocalListening(const LocalListenerInfo *info) +{ + if (g_sppDriver == NULL) { + return SOFTBUS_ERR; + } + int32_t socketId = g_sppDriver->OpenSppServer(NULL, UUID, 0); + g_sppDriver->Accept(socketId, (const SppSocketEventCallback*)&g_sppSocketServiceCallback); + return SOFTBUS_OK; +} + +static int32_t StopLocalListening(const LocalListenerInfo *info) +{ + if (g_sppDriver == NULL) { + return SOFTBUS_ERR; + } + g_sppDriver->CloseServer(0); + return SOFTBUS_OK; +} + +static int32_t InitProperty() +{ + g_brBuffSize = INVALID_LENGTH; + g_brSendPeerLen = INVALID_LENGTH; + GetPropertyInt(GET_PROPERTY_LENGTH, &g_brBuffSize); + GetPropertyInt(GET_SEND_MESSAGE_PEER_LEN, &g_brSendPeerLen); + GetPropertyInt(BR_SENDQUEQUE_MAXNUM, &g_brSendQueueMaxLen); + if (g_brBuffSize == INVALID_LENGTH || g_brBuffSize > MAX_BR_SIZE) { + LOG_ERR("Cannot get brBuffSize"); + return SOFTBUS_ERR; + } + if (g_brSendPeerLen == INVALID_LENGTH || g_brSendPeerLen > MAX_BR_PEER_SIZE) { + LOG_ERR("Cannot get brSendPeerLen"); + return SOFTBUS_ERR; + } + if (g_brSendQueueMaxLen == SOFTBUS_ERR || g_brSendQueueMaxLen > MAX_BR_PEER_SIZE) { + LOG_ERR("Cannot get brSendQueueMaxLen"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +ConnectFuncInterface *ConnInitBr(const ConnectCallback *callback) +{ + LOG_INFO("[InitBR]"); + if (InitProperty() != SOFTBUS_OK) { + return NULL; + } + pthread_mutex_init(&g_connectionLock, NULL); + InitDataQueue(&g_dataQueue); + InitRecvQueue(&g_recvQueue); + g_connectCallback = (ConnectCallback*)callback; + g_sppDriver = InitSppSocketDriver(); + if (g_sppDriver != NULL) { + g_sppDriver->Init(g_sppDriver); + } + return &g_brInterface; +} + +static bool GetJsonObjectNumberItem(const cJSON *json, const char * const string, int *target) +{ + cJSON *item = cJSON_GetObjectItemCaseSensitive(json, string); + if (item == NULL || !cJSON_IsNumber(item) || (item->valuedouble < 0)) { + LOG_ERR("Cannot find or invalid [%s]", string); + return false; + } + *target = (int)item->valuedouble; + return true; +} + +static bool AddNumberToJsonObject(cJSON *obj, const char * const string, int32_t num) +{ + if (obj == NULL || string == NULL) { + LOG_ERR("AddNumberToJsonObject fail"); + return false; + } + cJSON *item = cJSON_CreateNumber(num); + if (item == NULL) { + LOG_ERR("Cannot create cJSON number object [%s]", string); + return false; + } + if (!cJSON_AddItemToObject(obj, string, item)) { + cJSON_Delete(item); + return false; + } + return true; +} diff --git a/core/connection/common/BUILD.gn b/core/connection/common/BUILD.gn new file mode 100755 index 000000000..d70a67b97 --- /dev/null +++ b/core/connection/common/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("conn_common") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "src/softbus_base_listener.c", + "src/softbus_tcp_socket.c", + "src/softbus_thread_pool.c", + ] + } +} else { + shared_library("conn_common") { + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/adapter/kernel/include", + "//third_party/bounds_checking_function/include", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "src/softbus_base_listener.c", + "src/softbus_tcp_socket.c", + "src/softbus_thread_pool.c", + ] + deps = [] + } +} diff --git a/core/connection/common/include/softbus_thread_pool.h b/core/connection/common/include/softbus_thread_pool.h new file mode 100644 index 000000000..9b4160c57 --- /dev/null +++ b/core/connection/common/include/softbus_thread_pool.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef THREAD_POOL_H +#define THREAD_POOL_H + +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +typedef enum { + ONCE = 0, + PERSISTENT = 1, +} JobMode; + +struct Job { + int32_t (*callbackFunction)(void *arg); + void *arg; + struct Job *next; + JobMode jobMode; + pthread_mutex_t mutex; + uintptr_t handle; + bool runnable; +}; + +typedef struct Job Job; + +typedef struct { + int32_t threadNum; + int32_t queueMaxNum; + Job *head; + Job *tail; + pthread_t *pthreads; + pthread_mutex_t mutex; + pthread_cond_t queueEmpty; + pthread_cond_t queueNotEmpty; + pthread_cond_t queueNotFull; + int32_t queueCurNum; + int32_t queueClose; + int32_t poolClose; +} ThreadPool; + +ThreadPool* ThreadPoolInit(int32_t threadNum, int32_t queueMaxNum); + +int32_t ThreadPoolAddJob(ThreadPool *pool, int32_t (*callbackFunction)(void *arg), + void *arg, JobMode jobMode, uintptr_t handle); + +int32_t ThreadPoolRemoveJob(ThreadPool *pool, uintptr_t handle); + +int32_t ThreadPoolDestroy(ThreadPool *pool); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* THREAD_POOL_H */ \ No newline at end of file diff --git a/core/connection/common/src/softbus_base_listener.c b/core/connection/common/src/softbus_base_listener.c new file mode 100755 index 000000000..d27b1f9de --- /dev/null +++ b/core/connection/common/src/softbus_base_listener.c @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_base_listener.h" + +#include +#include +#include +#include +#include + +#include "common_list.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_tcp_socket.h" +#include "softbus_thread_pool.h" +#include "softbus_utils.h" + +#define MAX_LISTEN_EVENTS 1024 +#define TIMEOUT 500 +#define DEFAULT_BACKLOG 4 + +#define CLIENT_THREADNUM 1 +#define CLIENT_QUEUE_NUM 10 + +#define SERVER_THREADNUM 1 +#define SERVER_QUEUE_NUM 10 + +typedef enum { + LISTENER_IDLE, + LISTENER_PREPARED, + LISTENER_RUNNING, + LISTENER_ERROR, +} ListenerStatus; + +typedef struct { + ListNode node; + int32_t fd; +} FdNode; + +typedef struct { + ListNode node; + fd_set readSet; + fd_set writeSet; + fd_set exceptSet; + struct timeval tv; + int32_t listenFd; + char ip[IP_LEN]; + int32_t listenPort; + int32_t fdCount; + int32_t maxFd; + ModeType modeType; + ListenerStatus status; +} SoftbusBaseListenerInfo; + +typedef struct { + ListenerModule module; + SoftbusBaseListener *listener; + SoftbusBaseListenerInfo *info; + pthread_mutex_t lock; +} SoftbusListenerNode; + +static SoftbusListenerNode g_listenerList[UNUSE_BUTT]; +static ThreadPool *g_clientPool = NULL; +static ThreadPool *g_serverPool = NULL; + +static int32_t InitListenFd(ListenerModule module, const char *ip, int32_t port); +static int32_t OnEvent(ListenerModule module, int32_t fd, uint32_t events); +static void ProcessData(ListenerModule module, fd_set *readSet, + fd_set *writeSet, fd_set *exceptSet); +static int32_t PrepareBaseListener(ListenerModule module, ModeType modeType); +static int32_t CheckModule(ListenerModule module); + +static int32_t FdCopy(const fd_set *dest, const fd_set *src) +{ + return memcpy_s((void *)dest, sizeof(fd_set), (void *)src, sizeof(fd_set)); +} + +static int32_t MaxFd(int32_t fd1, int32_t fd2) +{ + return (fd1 > fd2) ? fd1 : fd2; +} + +static int32_t CheckModule(ListenerModule module) +{ + if (module >= UNUSE_BUTT || module < PROXY) { + LOG_ERR("Invalid listener module."); + return SOFTBUS_INVALID_PARAM; + } + return SOFTBUS_OK; +} + +static int32_t CheckTrigger(TriggerType triggerType) +{ + if (triggerType < READ_TRIGGER || triggerType > RW_TRIGGER) { + LOG_ERR("Invalid listener trigger type."); + return SOFTBUS_INVALID_PARAM; + } + return SOFTBUS_OK; +} + +static void ClearListenerFdList(const ListNode *cfdList) +{ + FdNode *item = NULL; + while (!IsListEmpty(cfdList)) { + item = LIST_ENTRY(cfdList->next, FdNode, node); + ListDelete(&item->node); + SoftBusFree(item); + } +} + +static int32_t InitListenFd(ListenerModule module, const char *ip, int32_t port) +{ + if (CheckModule(module) != SOFTBUS_OK || ip == NULL || port < 0) { + return SOFTBUS_INVALID_PARAM; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + return SOFTBUS_ERR; + } + int32_t rc = OpenTcpServerSocket(ip, port); + if (rc < 0) { + LOG_ERR("OpenTcpServer failed, rc=%d errno=%d", rc, errno); + return SOFTBUS_TCP_SOCKET_ERR; + } + listenerInfo->listenFd = rc; + rc = listen(listenerInfo->listenFd, DEFAULT_BACKLOG); + if (rc != 0) { + LOG_ERR("listen failed, rc=%d errno=%d", rc, errno); + ResetBaseListener(module); + return SOFTBUS_TCP_SOCKET_ERR; + } + listenerInfo->fdCount = 1; + listenerInfo->listenPort = GetTcpSockPort(listenerInfo->listenFd); + if (memcpy_s(listenerInfo->ip, IP_LEN, ip, IP_LEN) != EOK) { + LOG_ERR("Copy ip failed"); + ResetBaseListener(module); + return SOFTBUS_MEM_ERR; + } + if (listenerInfo->listenPort < 0) { + LOG_ERR("GetSockPort failed, listenPort_=%d", listenerInfo->listenPort); + ResetBaseListener(module); + return SOFTBUS_ERR; + } + FD_SET(listenerInfo->listenFd, &listenerInfo->readSet); + listenerInfo->maxFd = MaxFd(listenerInfo->listenFd, listenerInfo->maxFd); + return SOFTBUS_OK; +} + +void ResetBaseListener(ListenerModule module) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return; + } + if (listenerInfo->listenFd >= 0) { + TcpShutDown(listenerInfo->listenFd); + } + listenerInfo->listenFd = -1; + listenerInfo->listenPort = -1; + FD_ZERO(&listenerInfo->readSet); + FD_ZERO(&listenerInfo->writeSet); + FD_ZERO(&listenerInfo->exceptSet); + listenerInfo->status = LISTENER_IDLE; + listenerInfo->modeType = UNSET_MODE; + listenerInfo->fdCount = 0; + listenerInfo->maxFd = 0; + ClearListenerFdList(&listenerInfo->node); + pthread_mutex_unlock(&g_listenerList[module].lock); +} + +void ResetBaseListenerSet(ListenerModule module) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return; + } + FD_ZERO(&listenerInfo->readSet); + FD_ZERO(&listenerInfo->writeSet); + FD_ZERO(&listenerInfo->exceptSet); + ClearListenerFdList(&listenerInfo->node); + listenerInfo->fdCount = 0; + pthread_mutex_unlock(&g_listenerList[module].lock); +} + +static int32_t OnEvent(ListenerModule module, int32_t fd, uint32_t events) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + SoftbusBaseListener *listener = g_listenerList[module].listener; + if (listenerInfo == NULL || listener == NULL) { + return SOFTBUS_ERR; + } + if (fd == listenerInfo->listenFd) { + struct sockaddr_in addr; + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + LOG_ERR("memset failed"); + return SOFTBUS_ERR; + } + socklen_t addrLen = sizeof(addr); + int32_t cfd = TEMP_FAILURE_RETRY(accept(fd, (struct sockaddr *)&addr, &addrLen)); + if (cfd < 0) { + LOG_ERR("accept failed, cfd=%d, errno=%d", cfd, errno); + return SOFTBUS_TCP_SOCKET_ERR; + } + char ip[IP_LEN] = {0}; + inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip)); + if (listener->onConnectEvent != NULL) { + listener->onConnectEvent(events, cfd, ip); + } else { + LOG_ERR("Please set onConnectEvent callback"); + } + } else { + if (listener->onDataEvent != NULL) { + listener->onDataEvent(events, fd); + } else { + LOG_ERR("Please set onDataEvent callback"); + } + } + return SOFTBUS_OK; +} + +static void ProcessData(ListenerModule module, fd_set *readSet, + fd_set *writeSet, fd_set *exceptSet) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + return; + } + FdNode *item = NULL; + if ((listenerInfo->listenFd > 0) && FD_ISSET(listenerInfo->listenFd, readSet)) { + OnEvent(module, listenerInfo->listenFd, SOFTBUS_SOCKET_IN); + return; + } + LIST_FOR_EACH_ENTRY(item, &listenerInfo->node, FdNode, node) { + if (FD_ISSET(item->fd, readSet)) { + OnEvent(module, item->fd, SOFTBUS_SOCKET_IN); + return; + } + } + LIST_FOR_EACH_ENTRY(item, &listenerInfo->node, FdNode, node) { + if (FD_ISSET(item->fd, writeSet)) { + OnEvent(module, item->fd, SOFTBUS_SOCKET_OUT); + return; + } + } + LIST_FOR_EACH_ENTRY(item, &listenerInfo->node, FdNode, node) { + if (FD_ISSET(item->fd, exceptSet)) { + OnEvent(module, item->fd, SOFTBUS_SOCKET_EXCEPTION); + return; + } + } +} + +static int32_t SetSelect(ListenerModule module, fd_set *readSet, fd_set *writeSet, fd_set *exceptSet) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + return SOFTBUS_ERR; + } + FdNode *item = NULL; + listenerInfo->maxFd = listenerInfo->listenFd; + FD_ZERO(readSet); + FD_ZERO(writeSet); + FD_ZERO(exceptSet); + if (listenerInfo->listenFd > 0) { + FD_SET(listenerInfo->listenFd, readSet); + } + LIST_FOR_EACH_ENTRY(item, &listenerInfo->node, FdNode, node) { + listenerInfo->maxFd = MaxFd(item->fd, listenerInfo->maxFd); + } + if (FdCopy(readSet, &listenerInfo->readSet) != EOK) { + goto EXIT; + } + if (FdCopy(writeSet, &listenerInfo->writeSet) != EOK) { + goto EXIT; + } + if (FdCopy(exceptSet, &listenerInfo->exceptSet) != EOK) { + goto EXIT; + } + return SOFTBUS_OK; + +EXIT: + FD_ZERO(readSet); + FD_ZERO(writeSet); + FD_ZERO(exceptSet); + return SOFTBUS_MEM_ERR; +} + +static int32_t SelectThread(const SoftbusListenerNode *node) +{ + if (node == NULL) { + return SOFTBUS_INVALID_PARAM; + } + ListenerModule module = node->module; + if (CheckModule(node->module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL || listenerInfo->status != LISTENER_RUNNING) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + fd_set readSet; + fd_set writeSet; + fd_set exceptSet; + if (SetSelect(module, &readSet, &writeSet, &exceptSet) != SOFTBUS_OK) { + LOG_ERR("select failed with invalid listener"); + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + int32_t nEvents = select(listenerInfo->maxFd + 1, &readSet, &writeSet, + &exceptSet, &listenerInfo->tv); + if (nEvents < 0) { + LOG_ERR("select failed, errno=%d", errno); + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_TCP_SOCKET_ERR; + } else if (nEvents == 0) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; + } else { + ProcessData(module, &readSet, &writeSet, &exceptSet); + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; + } +} + +static int32_t StartThread(ListenerModule module, ModeType modeType) +{ + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + return SOFTBUS_ERR; + } + listenerInfo->modeType = modeType; + listenerInfo->status = LISTENER_RUNNING; + if (modeType == SERVER_MODE) { + return ThreadPoolAddJob(g_serverPool, (int(*)(void *))SelectThread, + &g_listenerList[module], PERSISTENT, (uintptr_t)module); + } else if (modeType == CLIENT_MODE) { + return ThreadPoolAddJob(g_clientPool, (int(*)(void *))SelectThread, + &g_listenerList[module], PERSISTENT, (uintptr_t)module); + } else { + return SOFTBUS_INVALID_PARAM; + } +} + +static int32_t PrepareBaseListener(ListenerModule module, ModeType modeType) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + return SOFTBUS_ERR; + } + + if (modeType == SERVER_MODE) { + if (g_serverPool == NULL) { + g_serverPool = ThreadPoolInit(SERVER_THREADNUM, SERVER_QUEUE_NUM); + if (g_serverPool == NULL) { + return SOFTBUS_MALLOC_ERR; + } + } + } else { + if (g_clientPool == NULL) { + g_clientPool = ThreadPoolInit(CLIENT_THREADNUM, CLIENT_QUEUE_NUM); + if (g_clientPool == NULL) { + return SOFTBUS_MALLOC_ERR; + } + } + } + if (StartThread(module, modeType) != SOFTBUS_OK) { + LOG_ERR("StartThread failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static SoftbusBaseListenerInfo *CreateNewListenerInfo(void) +{ + SoftbusBaseListenerInfo *listenerInfo = (SoftbusBaseListenerInfo *)SoftBusCalloc(sizeof(SoftbusBaseListenerInfo)); + if (listenerInfo == NULL) { + LOG_ERR("Malloc error"); + return NULL; + } + listenerInfo->tv.tv_sec = 0; + listenerInfo->tv.tv_usec = TIMEOUT; + listenerInfo->maxFd = 0; + listenerInfo->modeType = UNSET_MODE; + listenerInfo->fdCount = 0; + listenerInfo->listenFd = -1; + listenerInfo->listenPort = -1; + listenerInfo->status = LISTENER_IDLE; + ListInit(&listenerInfo->node); + FD_ZERO(&listenerInfo->readSet); + FD_ZERO(&listenerInfo->writeSet); + FD_ZERO(&listenerInfo->exceptSet); + return listenerInfo; +} + +int32_t StartBaseClient(ListenerModule module) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + g_listenerList[module].module = module; + if (g_listenerList[module].listener == NULL) { + LOG_ERR("BaseListener not set, start failed."); + return SOFTBUS_ERR; + } + if (g_listenerList[module].info == NULL) { + g_listenerList[module].info = CreateNewListenerInfo(); + if (g_listenerList[module].info == NULL) { + LOG_ERR("malloc listenerInfo err"); + return SOFTBUS_MALLOC_ERR; + } + pthread_mutexattr_t mutexAttr; + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&g_listenerList[module].lock, &mutexAttr); + } + if (g_listenerList[module].info->status != LISTENER_IDLE) { + LOG_ERR("listener is not in idle status."); + return SOFTBUS_ERR; + } + g_listenerList[module].info->status = LISTENER_PREPARED; + return PrepareBaseListener(module, CLIENT_MODE); +} + +int32_t StartBaseListener(ListenerModule module, const char *ip, int32_t port, ModeType modeType) +{ + if (CheckModule(module) != SOFTBUS_OK || port < 0 || ip == NULL) { + return SOFTBUS_INVALID_PARAM; + } + int32_t ret; + g_listenerList[module].module = module; + if (g_listenerList[module].listener == NULL) { + LOG_ERR("BaseListener not set, start failed."); + return SOFTBUS_ERR; + } + if (g_listenerList[module].info == NULL) { + g_listenerList[module].info = CreateNewListenerInfo(); + if (g_listenerList[module].info == NULL) { + LOG_ERR("malloc listenerInfo err"); + return SOFTBUS_MALLOC_ERR; + } + pthread_mutexattr_t mutexAttr; + pthread_mutexattr_init(&mutexAttr); + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&g_listenerList[module].lock, &mutexAttr); + } + if (g_listenerList[module].info->status != LISTENER_IDLE) { + LOG_ERR("listener is not in idle status."); + return SOFTBUS_ERR; + } + ret = InitListenFd(module, ip, port); + if (ret != SOFTBUS_OK) { + LOG_ERR("InitListenFd failed"); + return ret; + } + g_listenerList[module].info->status = LISTENER_PREPARED; + ret = PrepareBaseListener(module, modeType); + if (ret != SOFTBUS_OK) { + return ret; + } + return g_listenerList[module].info->listenPort; +} + +int32_t GetSoftbusBaseListener(ListenerModule module, SoftbusBaseListener *listener) +{ + if (CheckModule(module) != SOFTBUS_OK || listener == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (g_listenerList[module].listener != NULL) { + if (memcpy_s(listener, sizeof(SoftbusBaseListener), g_listenerList[module].listener, + sizeof(SoftbusBaseListener)) != EOK) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_MEM_ERR; + } + } else { + SoftBusFree(listener); + } + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; +} + +int32_t SetSoftbusBaseListener(ListenerModule module, const SoftbusBaseListener *listener) +{ + if (CheckModule(module) != SOFTBUS_OK || listener == NULL || + listener->onConnectEvent == NULL || listener->onDataEvent == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (g_listenerList[module].listener == NULL) { + g_listenerList[module].listener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener)); + if (g_listenerList[module].listener == NULL) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_MALLOC_ERR; + } + } + if (memcpy_s(g_listenerList[module].listener, sizeof(SoftbusBaseListener), + listener, sizeof(SoftbusBaseListener)) != EOK) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_MEM_ERR; + } + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; +} + +int32_t StopBaseListener(ListenerModule module) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info; + if (listenerInfo == NULL) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + if (listenerInfo->status != LISTENER_RUNNING) { + listenerInfo->status = LISTENER_IDLE; + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; + } + listenerInfo->status = LISTENER_IDLE; + if (listenerInfo->listenFd > 0) { + TcpShutDown(listenerInfo->listenFd); + } + pthread_mutex_unlock(&g_listenerList[module].lock); + + if (listenerInfo->modeType == SERVER_MODE) { + return ThreadPoolRemoveJob(g_serverPool, (uintptr_t)module); + } else if (listenerInfo->modeType == CLIENT_MODE) { + return ThreadPoolRemoveJob(g_clientPool, (uintptr_t)module); + } else { + LOG_ERR("No such thread pool type."); + return SOFTBUS_INVALID_PARAM; + } +} + +void DestroyBaseListener(ListenerModule module) +{ + if (CheckModule(module) != SOFTBUS_OK) { + return; + } + ResetBaseListener(module); + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return; + } + SoftBusFree(g_listenerList[module].info); + SoftBusFree(g_listenerList[module].listener); + g_listenerList[module].info = NULL; + g_listenerList[module].listener = NULL; + pthread_mutex_unlock(&g_listenerList[module].lock); +} + +static int32_t OnAddTrigger(fd_set *set, int32_t fd) +{ + if (FD_ISSET(fd, set)) { + LOG_ERR("fd already in set"); + return SOFTBUS_ERR; + } + FD_SET(fd, set); + return SOFTBUS_OK; +} + +static int32_t OnDelTrigger(fd_set *set, int32_t fd) +{ + if (!FD_ISSET(fd, set)) { + LOG_ERR("fd not in set"); + return SOFTBUS_ERR; + } + FD_CLR(fd, set); + return SOFTBUS_OK; +} + +static int32_t AddTriggerToSet(SoftbusBaseListenerInfo *info, int32_t fd, TriggerType triggerType) +{ + int32_t ret; + switch (triggerType) { + case READ_TRIGGER: + ret = OnAddTrigger(&info->readSet, fd); + break; + case WRITE_TRIGGER: + ret = OnAddTrigger(&info->writeSet, fd); + break; + case EXCEPT_TRIGGER: + ret = OnAddTrigger(&info->exceptSet, fd); + break; + case RW_TRIGGER: + ret = OnAddTrigger(&info->readSet, fd); + if (ret != SOFTBUS_OK) { + break; + } + ret = OnAddTrigger(&info->writeSet, fd); + break; + default: + ret = SOFTBUS_INVALID_PARAM; + LOG_ERR("Invalid trigger type"); + break; + } + + return ret; +} + +static int32_t DelTriggerFromSet(SoftbusBaseListenerInfo *info, int32_t fd, TriggerType triggerType) +{ + int32_t ret; + switch (triggerType) { + case READ_TRIGGER: + ret = OnDelTrigger(&info->readSet, fd); + break; + case WRITE_TRIGGER: + ret = OnDelTrigger(&info->writeSet, fd); + break; + case EXCEPT_TRIGGER: + ret = OnDelTrigger(&info->exceptSet, fd); + break; + case RW_TRIGGER: + ret = OnDelTrigger(&info->readSet, fd); + if (ret != SOFTBUS_OK) { + break; + } + ret = OnDelTrigger(&info->writeSet, fd); + break; + default: + ret = SOFTBUS_INVALID_PARAM; + LOG_ERR("Invalid trigger type"); + break; + } + + return ret; +} + +static bool CheckFdIsExist(SoftbusBaseListenerInfo *info, int32_t fd) +{ + FdNode *item = NULL; + LIST_FOR_EACH_ENTRY(item, &info->node, FdNode, node) { + if (item->fd == fd) { + return true; + } + } + return false; +} + +static int32_t AddNewFdNode(SoftbusBaseListenerInfo *info, int32_t fd) +{ + FdNode *newNode = (FdNode *)SoftBusCalloc(sizeof(FdNode)); + if (newNode == NULL) { + return SOFTBUS_MALLOC_ERR; + } + newNode->fd = fd; + ListInit(&newNode->node); + ListNodeInsert(&info->node, &newNode->node); + info->fdCount++; + return SOFTBUS_OK; +} + +static void DelFdNode(SoftbusBaseListenerInfo *info, int32_t fd) +{ + FdNode *item = NULL; + LIST_FOR_EACH_ENTRY(item, &info->node, FdNode, node) { + if (item->fd == fd) { + ListDelete(&item->node); + SoftBusFree(item); + info->fdCount--; + return; + } + } +} + +int32_t AddTrigger(ListenerModule module, int32_t fd, TriggerType triggerType) +{ + if (CheckModule(module) != SOFTBUS_OK || fd < 0 || CheckTrigger(triggerType) != SOFTBUS_OK) { + LOG_ERR("Invalid AddTrigger Param"); + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + SoftbusBaseListenerInfo *info = g_listenerList[module].info; + if (info == NULL || info->fdCount > MAX_LISTEN_EVENTS) { + LOG_ERR("Cannot AddTrigger any more"); + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + + if (AddTriggerToSet(info, fd, triggerType) != SOFTBUS_OK) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + + if (CheckFdIsExist(info, fd)) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; + } + + if (AddNewFdNode(info, fd) != SOFTBUS_OK) { + (void)DelTriggerFromSet(info, fd, triggerType); + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_OK; +} + +int32_t DelTrigger(ListenerModule module, int32_t fd, TriggerType triggerType) +{ + if (CheckModule(module) != SOFTBUS_OK || fd < 0 || CheckTrigger(triggerType)) { + LOG_ERR("Invalid AddTrigger Param"); + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&g_listenerList[module].lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + SoftbusBaseListenerInfo *info = g_listenerList[module].info; + if (info == NULL) { + pthread_mutex_unlock(&g_listenerList[module].lock); + return SOFTBUS_ERR; + } + + if (DelTriggerFromSet(info, fd, triggerType) != SOFTBUS_OK) { + LOG_ERR("del trigger fail: fd = %d, trigger = %d", fd, triggerType); + } + + if (!FD_ISSET(fd, &info->writeSet) && !FD_ISSET(fd, &info->readSet) && !FD_ISSET(fd, &info->exceptSet)) { + DelFdNode(info, fd); + } + + pthread_mutex_unlock(&g_listenerList[module].lock); + LOG_INFO("DelTrigger fd:%d success, current fdcount:%d", fd, info->fdCount); + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/connection/common/src/softbus_tcp_socket.c b/core/connection/common/src/softbus_tcp_socket.c new file mode 100755 index 000000000..c5d9eb933 --- /dev/null +++ b/core/connection/common/src/softbus_tcp_socket.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_tcp_socket.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" + +#define SEND_BUF_SIZE 0x200000 // 2M +#define RECV_BUF_SIZE 0x100000 // 1M +#define USER_TIMEOUT_MS 5000 // 5000us + +#ifndef __LITEOS_M__ +static int SetReusePort(int fd, int on) +{ + int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); + if (rc != 0) { + LOG_ERR("set SO_REUSEPORT"); + return -1; + } + return 0; +} +#endif + +static int SetReuseAddr(int fd, int on) +{ + int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (rc != 0) { + LOG_ERR("set SO_REUSEADDR"); + return -1; + } + return 0; +} + +static int SetNoDelay(int fd, int on) +{ + int rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); + if (rc != 0) { + LOG_ERR("set SO_REUSEADDR"); + return -1; + } + return 0; +} + +static void SetServerOption(int fd) +{ + (void)SetReuseAddr(fd, 1); + (void)SetNoDelay(fd, 1); +#ifndef __LITEOS_M__ + (void)SetReusePort(fd, 1); +#endif +} + +static void SetClientOption(int fd) +{ + SetReuseAddr(fd, 1); + SetNoDelay(fd, 1); +#ifndef __LITEOS_M__ + SetReusePort(fd, 1); +#endif +} + +static int WaitEvent(int fd, short events, int timeout) +{ + if (fd < 0) { + LOG_ERR("%s:%d:fd=%d invalid params", __func__, __LINE__, fd); + return -1; + } + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = timeout; + int rc = 0; + switch (events) { + case SOFTBUS_SOCKET_OUT: { + fd_set writeSet; + FD_ZERO(&writeSet); + FD_SET(fd, &writeSet); + rc = TEMP_FAILURE_RETRY(select(fd + 1, NULL, &writeSet, NULL, &tv)); + if (rc < 0) { + break; + } + if (!FD_ISSET(fd, &writeSet)) { + rc = 0; + } + break; + } + case SOFTBUS_SOCKET_IN: { + fd_set readSet; + FD_ZERO(&readSet); + FD_SET(fd, &readSet); + rc = TEMP_FAILURE_RETRY(select(fd + 1, &readSet, NULL, NULL, &tv)); + if (rc < 0) { + break; + } + if (!FD_ISSET(fd, &readSet)) { + rc = 0; + } + break; + } + default: + break; + } + return rc; +} + +static int BindLocalIP(int fd, const char *localIP, uint16_t port) +{ + struct sockaddr_in addr; + + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + LOG_ERR("memset failed"); + } + + addr.sin_family = AF_INET; + int rc = inet_pton(AF_INET, localIP, &addr.sin_addr); + if (rc <= 0) { + LOG_ERR("inet_pton rc=%d", rc); + return SOFTBUS_ERR; + } + addr.sin_port = htons(port); + + errno = 0; + rc = TEMP_FAILURE_RETRY(bind(fd, (struct sockaddr *)&addr, sizeof(addr))); + if (rc < 0) { + LOG_ERR("bind fd=%d,rc=%d", fd, rc); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int OpenTcpServerSocket(const char *ip, int port) +{ + if (ip == NULL || port < 0) { + return -1; + } + errno = 0; + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + LOG_ERR("fd=%d", fd); + return -1; + } + SetServerOption(fd); + int ret = BindLocalIP(fd, ip, port); + if (ret != SOFTBUS_OK) { + LOG_ERR("BindLocalIP ret=%d", ret); + TcpShutDown(fd); + return -1; + } + return fd; +} + +int OpenTcpClientSocket(const char *peerIp, const char *myIp, int port) +{ + if ((peerIp == NULL) || (port <= 0)) { + return -1; + } + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + LOG_ERR("%s:%d:fd=%d", __func__, __LINE__, fd); + return -1; + } + + SetClientOption(fd); + if (myIp != NULL) { + int ret = BindLocalIP(fd, myIp, 0); + if (ret != SOFTBUS_OK) { + LOG_ERR("BindLocalIP ret=%d", ret); + TcpShutDown(fd); + return -1; + } + } + struct sockaddr_in addr; + if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) { + LOG_ERR("memset failed"); + } + addr.sin_family = AF_INET; + inet_pton(AF_INET, peerIp, &addr.sin_addr); + addr.sin_port = htons(port); + errno = 0; + int rc = TEMP_FAILURE_RETRY(connect(fd, (struct sockaddr *)&addr, sizeof(addr))); + if ((rc == -1) && (errno != EINPROGRESS)) { + LOG_ERR("fd=%d,connect rc=%d, errno=%d", fd, rc, errno); + TcpShutDown(fd); + return -1; + } + return fd; +} + +int GetTcpSockPort(int fd) +{ + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + + int rc = getsockname(fd, (struct sockaddr *)&addr, &addrLen); + if (rc != 0) { + LOG_ERR("fd=%d,getsockname rc=%d", fd, rc); + return rc; + } + return ntohs(addr.sin_port); +} + +ssize_t SendTcpData(int fd, const char *buf, size_t len, int timeout) +{ + if (fd < 0 || buf == NULL || len == 0) { + LOG_ERR("fd=%d invalid params", fd); + return -1; + } + + if (timeout == 0) { + timeout = USER_TIMEOUT_MS; + } + + int err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, USER_TIMEOUT_MS); + if (err <= 0) { + return err; + } + ssize_t bytes = 0; + while (1) { + errno = 0; + ssize_t rc = TEMP_FAILURE_RETRY(send(fd, &buf[bytes], len - bytes, 0)); + if ((rc == -1) && (errno == EAGAIN)) { + continue; + } else if (rc <= 0) { + if (bytes == 0) { + bytes = -1; + } + break; + } + bytes += rc; + if (bytes == (ssize_t)(len)) { + break; + } + + err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, timeout); + if (err == 0) { + continue; + } else if (err < 0) { + if (bytes == 0) { + bytes = err; + } + break; + } + } + return bytes; +} + +static ssize_t OnRecvData(int fd, char *buf, size_t len, int timeout, int flags) +{ + if (fd < 0 || buf == NULL || len == 0) { + LOG_ERR("fd=%d invalid params", fd); + return -1; + } + + if (timeout != 0) { + int err = WaitEvent(fd, SOFTBUS_SOCKET_IN, timeout); + if (err < 0) { + return err; + } + } + + errno = 0; + ssize_t rc = TEMP_FAILURE_RETRY(recv(fd, buf, len, flags)); + if ((rc == -1) && (errno == EAGAIN)) { + rc = 0; + } else if (rc <= 0) { + rc = -1; + } + return rc; +} + +ssize_t RecvTcpData(int fd, char *buf, size_t len, int timeout) +{ + return OnRecvData(fd, buf, len, timeout, 0); +} + +void CloseTcpFd(int fd) +{ + if (fd >= 0) { + LOG_INFO("close fd=%d", fd); + close(fd); + } +} + +void TcpShutDown(int fd) +{ + if (fd >= 0) { + LOG_INFO("shutdown fd=%d", fd); + shutdown(fd, SHUT_RDWR); + close(fd); + } +} + +int32_t SetTcpKeepAlive(int32_t fd, int32_t seconds) +{ +#define KEEP_ALIVE_COUNT 5 + if (fd < 0) { + LOG_ERR("SetTcpKeepAlive invalid param"); + return -1; + } + + int32_t rc; + int32_t enable; + if (seconds > 0) { + enable = 1; + rc = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &seconds, sizeof(seconds)); + if (rc != 0) { + LOG_ERR("set TCP_KEEPIDLE"); + return -1; + } + + int32_t keepAliveCnt = KEEP_ALIVE_COUNT; + rc = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepAliveCnt, sizeof(keepAliveCnt)); + if (rc != 0) { + LOG_ERR("set TCP_KEEPCNT"); + return -1; + } + + int32_t keepAliveIntvl = 1; + rc = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepAliveIntvl, sizeof(keepAliveIntvl)); + if (rc != 0) { + LOG_ERR("set TCP_KEEPINTVL"); + return -1; + } + } else { + enable = 0; + } + + rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + if (rc != 0) { + LOG_ERR("set SO_KEEPALIVE"); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/core/connection/common/src/softbus_thread_pool.c b/core/connection/common/src/softbus_thread_pool.c new file mode 100755 index 000000000..950b341e5 --- /dev/null +++ b/core/connection/common/src/softbus_thread_pool.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_thread_pool.h" + +#include +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#ifndef MIN_STACK_SIZE +#define MIN_STACK_SIZE 0x2000 +#define THREAD_PRIORITY 20 +#endif + +typedef void *(*Runnable)(void *argv); +typedef struct ThreadAttr ThreadAttr; + +struct ThreadAttr { + const char *name; + uint32_t stackSize; + uint8_t priority; +}; + +static int32_t CreateThread(Runnable run, void *argv, const ThreadAttr *attr, uint32_t *threadId); +static ThreadPool* CreateThreadPool(int32_t threadNum, int32_t queueMaxNum); +static void JobCheck(ThreadPool *pool, Job *job); +static void ThreadPoolWorker(void *arg); + +static int32_t CreateThread(Runnable run, void *argv, const ThreadAttr *attr, uint32_t *threadId) +{ + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + pthread_attr_setstacksize(&threadAttr, (attr->stackSize | MIN_STACK_SIZE)); + struct sched_param sched = {attr->priority}; + pthread_attr_setschedparam(&threadAttr, &sched); + pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE); + int32_t errCode = pthread_create((pthread_t *)threadId, &threadAttr, run, argv); + return errCode; +} + +static ThreadPool* CreateThreadPool(int32_t threadNum, int32_t queueMaxNum) +{ + if (threadNum <= 0 || queueMaxNum <= 0) { + LOG_ERR("Invalid para."); + return NULL; + } + ThreadPool *pool = (ThreadPool *)SoftBusCalloc(sizeof(ThreadPool)); + if (pool == NULL) { + LOG_ERR("Failed to malloc ThreadPool"); + return NULL; + } + pool->threadNum = threadNum; + pool->queueMaxNum = queueMaxNum; + pool->queueCurNum = 0; + pool->head = NULL; + pool->tail = NULL; + if (pthread_mutex_init(&(pool->mutex), NULL)) { + SoftBusFree(pool); + LOG_ERR("Failed to init mutex"); + return NULL; + } + if (pthread_cond_init(&(pool->queueEmpty), NULL)) { + SoftBusFree(pool); + LOG_ERR("Failed to init cond queueEmpty"); + return NULL; + } + if (pthread_cond_init(&(pool->queueNotEmpty), NULL)) { + SoftBusFree(pool); + LOG_ERR("Failed to init cond queueNotEmpty"); + return NULL; + } + if (pthread_cond_init(&(pool->queueNotFull), NULL)) { + SoftBusFree(pool); + LOG_ERR("Failed to init cond queueNotFull"); + return NULL; + } + return pool; +} + +ThreadPool *ThreadPoolInit(int32_t threadNum, int32_t queueMaxNum) +{ + if (threadNum <= 0 || queueMaxNum <= 0) { + LOG_ERR("Invalid para."); + return NULL; + } + ThreadPool *pool = CreateThreadPool(threadNum, queueMaxNum); + if (pool == NULL) { + LOG_ERR("Failed to create thread pool"); + return NULL; + } + + pool->pthreads = (pthread_t *)SoftBusCalloc(sizeof(pthread_t) * threadNum); + if (pool->pthreads == NULL) { + SoftBusFree(pool); + LOG_ERR("Failed to malloc pthreads"); + return NULL; + } + pool->queueClose = 0; + pool->poolClose = 0; + if (pthread_mutex_lock(&(pool->mutex)) != 0) { + LOG_ERR("lock failed"); + goto EXIT; + } + int32_t countSuccess = 0; + for (int32_t i = 0; i < pool->threadNum; ++i) { + ThreadAttr attr = {"ThreadPoolWorker", 0, THREAD_PRIORITY}; + if (CreateThread((Runnable)ThreadPoolWorker, (void *)pool, &attr, (uint32_t *)&(pool->pthreads[i])) != 0) { + LOG_ERR("create pthreads no. [%d] failed\n", i); + pool->pthreads[i] = (pthread_t)0; + } else { + ++countSuccess; + } + } + if (countSuccess < pool->threadNum) { + LOG_ERR("Failed to create %d threads", pool->threadNum - countSuccess); + } + if (countSuccess == 0) { + pthread_mutex_unlock(&pool->mutex); + goto EXIT; + } + pthread_mutex_unlock(&(pool->mutex)); + return pool; + +EXIT: + pthread_mutex_destroy(&pool->mutex); + pthread_cond_destroy(&pool->queueEmpty); + pthread_cond_destroy(&pool->queueNotEmpty); + pthread_cond_destroy(&pool->queueNotFull); + SoftBusFree(pool->pthreads); + SoftBusFree(pool); + return NULL; +} + +static void JobCheck(ThreadPool *pool, Job *job) +{ + if (pool->queueClose || pool->poolClose) { + job->runnable = false; + LOG_INFO("Threadpool starts to close..."); + } + if (job->jobMode == PERSISTENT && job->runnable == true) { + pool->queueCurNum++; + pool->tail->next = job; + pool->tail = job; + } + if (pool->queueCurNum == 0) { + pool->head = pool->tail = NULL; + } else { + pool->head = job->next; + } + if (pool->tail != NULL) { + pool->tail->next = NULL; + } +} + +static void ThreadPoolWorker(void *arg) +{ + if (arg == NULL) { + return; + } + ThreadPool *pool = (ThreadPool *)arg; + Job *job = NULL; + while (1) { + if (pthread_mutex_lock(&(pool->mutex)) != 0) { + LOG_ERR("lock failed"); + return; + } + while ((pool->queueCurNum == 0) && !pool->poolClose) { + pthread_cond_wait(&(pool->queueNotEmpty), &(pool->mutex)); + } + if (pool->poolClose || pool->queueCurNum <= 0) { + pthread_mutex_unlock(&(pool->mutex)); + break; + } + pool->queueCurNum--; + job = pool->head; + if (pthread_mutex_lock(&(job->mutex)) != 0) { + LOG_ERR("lock failed"); + pthread_mutex_unlock(&(pool->mutex)); + return; + } + JobCheck(pool, job); + if (pool->queueCurNum == 0) { + pthread_cond_signal(&(pool->queueEmpty)); + } + if (pool->queueCurNum == pool->queueMaxNum - 1) { + pthread_cond_broadcast(&(pool->queueNotFull)); + } + pthread_mutex_unlock(&(pool->mutex)); + if (job->runnable) { + (void)(*(job->callbackFunction))(job->arg); + } + if (job->jobMode == ONCE || job->runnable == false) { + pthread_mutex_unlock(&(job->mutex)); + pthread_mutex_destroy(&(job->mutex)); + SoftBusFree(job); + job = NULL; + } + if (job != NULL) { + pthread_mutex_unlock(&(job->mutex)); + } + } +} + +static int32_t CheckThreadPoolAddReady(ThreadPool *pool, int32_t (*callbackFunction)(void *arg)) +{ + if (pool == NULL || callbackFunction == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(pool->mutex)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (pool->queueCurNum == pool->queueMaxNum) { + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_ERR; + } + while ((pool->queueCurNum == pool->queueMaxNum) && !(pool->queueClose || pool->poolClose)) { + pthread_cond_wait(&(pool->queueNotFull), &(pool->mutex)); + } + if (pool->queueClose || pool->poolClose) { + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t ThreadPoolAddJob(ThreadPool *pool, int32_t (*callbackFunction)(void *arg), void *arg, + JobMode jobMode, uintptr_t handle) +{ + int32_t ret = CheckThreadPoolAddReady(pool, callbackFunction); + if (ret != SOFTBUS_OK) { + return ret; + } + Job* job = pool->head; + while (job != NULL) { + if (job->handle == handle && job->runnable == true) { + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_INVALID_PARAM; + } + job = job->next; + } + job = (Job *)SoftBusCalloc(sizeof(Job)); + if (job == NULL) { + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_MALLOC_ERR; + } + job->callbackFunction = callbackFunction; + job->arg = arg; + job->jobMode = jobMode; + job->handle = handle; + job->runnable = true; + job->next = NULL; + if (pthread_mutex_init(&(job->mutex), NULL)) { + SoftBusFree(job); + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_ERR; + } + if (pool->head == NULL) { + pool->head = pool->tail = job; + pthread_cond_broadcast(&(pool->queueNotEmpty)); + } else { + pool->tail->next = job; + pool->tail = job; + } + pool->queueCurNum++; + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_OK; +} + +int32_t ThreadPoolRemoveJob(ThreadPool *pool, uintptr_t handle) +{ + if (pool == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(pool->mutex)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + Job* job = pool->head; + while (job != NULL) { + if (job->handle == handle && job->jobMode == PERSISTENT && job->runnable == true) { + break; + } + job = job->next; + } + if (job != NULL && job->runnable == true && job->jobMode == PERSISTENT) { + if (pthread_mutex_lock(&(job->mutex)) != 0) { + LOG_ERR("lock failed"); + pthread_mutex_unlock(&(job->mutex)); + return SOFTBUS_LOCK_ERR; + } + job->runnable = false; + pthread_mutex_unlock(&(job->mutex)); + } + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_OK; +} + +int32_t ThreadPoolDestroy(ThreadPool *pool) +{ + if (pool == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(pool->mutex)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (pool->queueClose || pool->poolClose) { + pthread_mutex_unlock(&(pool->mutex)); + return SOFTBUS_OK; + } + pool->queueClose = 1; + while (pool->queueCurNum != 0) { + pthread_cond_wait(&(pool->queueEmpty), &(pool->mutex)); + } + pool->poolClose = 1; + pthread_mutex_unlock(&(pool->mutex)); + pthread_cond_broadcast(&(pool->queueNotEmpty)); + pthread_cond_broadcast(&(pool->queueNotFull)); + for (int32_t i = 0; i < pool->threadNum; ++i) { + if (pool->pthreads != NULL) { + pthread_join(pool->pthreads[i], NULL); + } + } + pthread_mutex_destroy(&(pool->mutex)); + pthread_cond_destroy(&(pool->queueEmpty)); + pthread_cond_destroy(&(pool->queueNotEmpty)); + pthread_cond_destroy(&(pool->queueNotFull)); + SoftBusFree(pool->pthreads); + Job* job = NULL; + while (pool->head != NULL) { + job = pool->head; + pool->head = job->next; + SoftBusFree(job); + } + SoftBusFree(pool); + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/core/connection/interface/softbus_base_listener.h b/core/connection/interface/softbus_base_listener.h new file mode 100644 index 000000000..e1cf7b866 --- /dev/null +++ b/core/connection/interface/softbus_base_listener.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_BASE_LISTENER_H +#define SOFTBUS_BASE_LISTENER_H + +#include + +#include "common_list.h" +#include "softbus_def.h" +#include "softbus_utils.h" +#include "sys/select.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum { + READ_TRIGGER, + WRITE_TRIGGER, + EXCEPT_TRIGGER, + RW_TRIGGER, +} TriggerType; + +typedef enum { + UNSET_MODE, + CLIENT_MODE, + SERVER_MODE, +} ModeType; + +typedef enum { + PROXY = 0, + AUTH, + DIRECT_CHANNEL_CLIENT, + DIRECT_CHANNEL_SERVER, + UNUSE_BUTT, +} ListenerModule; + +typedef struct { + int32_t (*onConnectEvent)(int32_t events, int32_t cfd, const char *ip); + int32_t (*onDataEvent)(int32_t events, int32_t fd); +} SoftbusBaseListener; + +int32_t GetSoftbusBaseListener(ListenerModule module, SoftbusBaseListener *listener); +int32_t SetSoftbusBaseListener(ListenerModule module, const SoftbusBaseListener *listener); +int32_t StartBaseClient(ListenerModule module); +int32_t StartBaseListener(ListenerModule module, const char *ip, int32_t port, ModeType modeType); +int32_t StopBaseListener(ListenerModule module); +void ResetBaseListener(ListenerModule module); +void ResetBaseListenerSet(ListenerModule module); +void DestroyBaseListener(ListenerModule module); + +int32_t AddTrigger(ListenerModule module, int32_t fd, TriggerType triggerType); +int32_t DelTrigger(ListenerModule module, int32_t fd, TriggerType triggerType); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* SOFTBUS_BASE_LISTENER_H */ \ No newline at end of file diff --git a/core/connection/interface/softbus_conn_interface.h b/core/connection/interface/softbus_conn_interface.h new file mode 100755 index 000000000..9f4414f57 --- /dev/null +++ b/core/connection/interface/softbus_conn_interface.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CONN_INTERFACE_H +#define SOFTBUS_CONN_INTERFACE_H +#include +#include "softbus_common.h" +#include "softbus_def.h" + +#define DEV_ID_HASH_LEN 32 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +typedef enum { + MODULE_TRUST_ENGINE = 1, + MODULE_HICHAIN = 2, + MODULE_AUTH_SDK = 3, + MODULE_AUTH_CONNECTION = 5, + MODULE_MESSAGE_SERVICE = 8, + MODULE_BLUETOOTH_MANAGER = 9, + MODULE_CONNECTION = 11, + MODULE_DIRECT_CHANNEL = 12, + MODULE_PROXY_CHANNEL = 13, + MODULE_DEVICE_AUTH = 14, + MODULE_P2P_LINK = 15, + MODULE_PKG_VERIFY = 20, + MODULE_BLE_NET = 100, + MODULE_BLE_CONN = 101 +} ConnModule; + +typedef enum { + CONNECT_TCP = 1, + CONNECT_BR, + CONNECT_BLE, + CONNECT_TYPE_MAX +} ConnectType; + +typedef struct { + int32_t isAvailable; + int32_t isServer; + ConnectType type; + union { + struct BrInfo { + char brMac[BT_MAC_LEN]; + } brInfo; + struct BleInfo { + char bleMac[BT_MAC_LEN]; + char deviceIdHash[DEV_ID_HASH_LEN]; + } bleInfo; + struct IpInfo { + char ip[IP_LEN]; + int32_t port; + int32_t fd; + } ipInfo; + } info; +} ConnectionInfo; + +typedef struct { + void (*OnConnected)(uint32_t connectionId, const ConnectionInfo *info); + void (*OnDisconnected)(uint32_t connectionId, const ConnectionInfo *info); + void (*OnDataReceived)(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len); +} ConnectCallback; + +typedef enum { + CONN_DEFAULT = 0, + CONN_LOW, + CONN_MIDDLE, + CONN_HIGH +} SendPriority; + +typedef struct { + int32_t module; // ConnModule + int64_t seq; + int32_t flag; // SendPriority + int32_t pid; + int32_t len; + char *buf; +} ConnPostData; + +typedef struct { + void (*OnConnectSuccessed)(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info); + void (*OnConnectFailed)(uint32_t requestId, int32_t reason); +} ConnectResult; + +typedef struct { + ConnectType type; + union { + struct BrOption { + char brMac[BT_MAC_LEN]; + } brOption; + struct BleOption { + char bleMac[BT_MAC_LEN]; + char deviceIdHash[DEV_ID_HASH_LEN]; + } bleOption; + struct IpOption { + char ip[IP_LEN]; + int32_t port; + } ipOption; + } info; +} ConnectOption; + +typedef struct { + ConnectType type; + union { + struct IpListenerInfo { + char ip[IP_LEN]; + int32_t port; + } ipListenerInfo; + } info; +} LocalListenerInfo; + +uint32_t ConnGetHeadSize(void); + +int32_t ConnServerInit(void); + +int32_t ConnSetConnectCallback(ConnModule moduleId, const ConnectCallback *callback); + +void ConnUnSetConnectCallback(ConnModule moduleId); + +int32_t ConnPostBytes(uint32_t connectionId, ConnPostData *data); + +int32_t ConnTypeIsSupport(ConnectType type); + +int32_t ConnGetConnectionInfo(uint32_t connectionId, ConnectionInfo *info); + +uint32_t ConnGetNewRequestId(ConnModule moduleId); + +int32_t ConnConnectDevice(const ConnectOption *option, uint32_t requestId, const ConnectResult *result); + +int32_t ConnDisconnectDevice(uint32_t connectionId); + +int32_t ConnDisconnectDeviceAllConn(const ConnectOption *option); + +int32_t ConnStopLocalListening(const LocalListenerInfo *info); + +int32_t ConnStartLocalListening(const LocalListenerInfo *info); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/core/connection/interface/softbus_tcp_socket.h b/core/connection/interface/softbus_tcp_socket.h new file mode 100644 index 000000000..67a83ca4c --- /dev/null +++ b/core/connection/interface/softbus_tcp_socket.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_TCP_SOCKET_H +#define SOFTBUS_TCP_SOCKET_H + +#include +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(expression) \ +( \ + __extension__ \ + ( \ + { \ + long int __result; \ + do __result = (long int) (expression); \ + while ((__result == -1L) && (errno == EINTR)); \ + __result; \ + } \ + ) \ +) +#endif + +enum { + SOFTBUS_SOCKET_OUT, // writable + SOFTBUS_SOCKET_IN, // readable + SOFTBUS_SOCKET_EXCEPTION, // exception +}; + +int32_t OpenTcpServerSocket(const char *ip, int32_t port); +int32_t OpenTcpClientSocket(const char *peerIp, const char *myIp, int32_t port); +int32_t GetTcpSockPort(int32_t fd); +ssize_t SendTcpData(int32_t fd, const char *buf, size_t len, int32_t timeout); +ssize_t RecvTcpData(int32_t fd, char *buf, size_t len, int32_t timeout); +void CloseTcpFd(int32_t fd); +void TcpShutDown(int32_t fd); +int32_t SetTcpKeepAlive(int32_t fd, int32_t seconds); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // SOFTBUS_TCP_SOCKET_H diff --git a/core/connection/manager/BUILD.gn b/core/connection/manager/BUILD.gn new file mode 100755 index 000000000..7ccaea196 --- /dev/null +++ b/core/connection/manager/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("conn_manager") { + sources = [ + "softbus_conn_manager.c", + "softbus_conn_manager_weak.c", + ] + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/interfaces/kits/common", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + } +} else { + shared_library("conn_manager") { + sources = [ "softbus_conn_manager.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/interfaces/kits/common", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + deps = [ "$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel" ] + } +} diff --git a/core/connection/manager/softbus_conn_manager.c b/core/connection/manager/softbus_conn_manager.c new file mode 100755 index 000000000..a1afd8ea2 --- /dev/null +++ b/core/connection/manager/softbus_conn_manager.c @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_conn_manager.h" + +#include + +#include "common_list.h" +#include "softbus_conn_interface.h" +#include "softbus_conn_manager_weak.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +ConnectFuncInterface *g_connManager[CONNECT_TYPE_MAX] = {0}; +static SoftBusList *g_listenerList = NULL; +static bool g_isInited = false; + +typedef struct TagConnListenerNode { + ListNode node; + ConnModule moduleId; + ConnectCallback callback; +} ConnListenerNode; + +static int32_t ModuleCheck(ConnModule moduleId) +{ + ConnModule id[] = { + MODULE_TRUST_ENGINE, MODULE_HICHAIN, MODULE_AUTH_SDK, MODULE_AUTH_CONNECTION, MODULE_MESSAGE_SERVICE, + MODULE_BLUETOOTH_MANAGER, MODULE_CONNECTION, MODULE_DIRECT_CHANNEL, MODULE_PROXY_CHANNEL, + MODULE_DEVICE_AUTH, MODULE_P2P_LINK, MODULE_PKG_VERIFY, MODULE_BLE_NET, + MODULE_BLE_CONN + }; + int32_t i; + int32_t idNum = sizeof(id) / sizeof(ConnModule); + + for (i = 0; i < idNum; i++) { + if (moduleId == id[i]) { + return SOFTBUS_OK; + } + } + LOG_ERR("check module fail %d", moduleId); + return SOFTBUS_ERR; +} + +static int32_t ConnTypeCheck(ConnectType type) +{ + if (type >= CONNECT_TYPE_MAX) { + LOG_ERR("type is over max %d", type); + return SOFTBUS_ERR; + } + + if (g_connManager[type] == NULL) { + LOG_ERR("type is %d", type); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t GetAllListener(ConnListenerNode **node) +{ + ConnListenerNode *listenerNode = NULL; + int32_t cnt = 0; + + if (g_listenerList == NULL) { + LOG_ERR("listener list is null"); + return cnt; + } + + if (g_listenerList->cnt == 0) { + LOG_ERR("listener cnt is null"); + return cnt; + } + + if (pthread_mutex_lock(&g_listenerList->lock) != 0) { + LOG_ERR("lock mutex failed"); + return 0; + } + *node = SoftBusCalloc(g_listenerList->cnt * sizeof(ConnListenerNode)); + if (*node == NULL) { + (void)pthread_mutex_unlock(&g_listenerList->lock); + return cnt; + } + LIST_FOR_EACH_ENTRY(listenerNode, &g_listenerList->list, ConnListenerNode, node) { + if (memcpy_s(*node + cnt, sizeof(ConnListenerNode), listenerNode, sizeof(ConnListenerNode)) != EOK) { + LOG_ERR("mem error"); + } + cnt++; + } + (void)pthread_mutex_unlock(&g_listenerList->lock); + return cnt; +} + +static int32_t GetListenerByModuleId(ConnModule moduleId, ConnListenerNode *node) +{ + ConnListenerNode *listenerNode = NULL; + + if (g_listenerList == NULL) { + return SOFTBUS_ERR; + } + int ret = SOFTBUS_OK; + if (pthread_mutex_lock(&g_listenerList->lock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + LIST_FOR_EACH_ENTRY(listenerNode, &g_listenerList->list, ConnListenerNode, node) { + if (listenerNode->moduleId == moduleId) { + if (memcpy_s(node, sizeof(ConnListenerNode), listenerNode, sizeof(ConnListenerNode)) != EOK) { + ret = SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&g_listenerList->lock); + return ret; + } + } + (void)pthread_mutex_unlock(&g_listenerList->lock); + return SOFTBUS_ERR; +} + +static int32_t AddListener(ConnModule moduleId, const ConnectCallback *callback) +{ + ConnListenerNode *item = NULL; + ConnListenerNode *listNode = NULL; + + if (g_listenerList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_listenerList->lock) != 0) { + LOG_ERR("lock mutex failed"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(listNode, &g_listenerList->list, ConnListenerNode, node) { + if (listNode->moduleId == moduleId) { + (void)pthread_mutex_unlock(&g_listenerList->lock); + return SOFTBUS_ERR; + } + } + + item = (ConnListenerNode *)SoftBusCalloc(sizeof(ConnListenerNode)); + if (item == NULL) { + LOG_ERR("malloc fail"); + (void)pthread_mutex_unlock(&g_listenerList->lock); + return SOFTBUS_ERR; + } + + item->moduleId = moduleId; + if (memcpy_s(&(item->callback), sizeof(ConnectCallback), callback, sizeof(ConnectCallback)) != 0) { + SoftBusFree(item); + (void)pthread_mutex_unlock(&g_listenerList->lock); + return SOFTBUS_ERR; + } + ListAdd(&(g_listenerList->list), &(item->node)); + g_listenerList->cnt++; + (void)pthread_mutex_unlock(&g_listenerList->lock); + return SOFTBUS_OK; +} + +static void DelListener(ConnModule moduleId) +{ + ConnListenerNode *removeNode = NULL; + if (g_listenerList == NULL) { + LOG_ERR("listenerList is null"); + return; + } + + if (pthread_mutex_lock(&g_listenerList->lock) != 0) { + LOG_ERR("lock mutex failed"); + return; + } + + LIST_FOR_EACH_ENTRY(removeNode, &g_listenerList->list, ConnListenerNode, node) { + if (removeNode->moduleId == moduleId) { + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_listenerList->cnt--; + break; + } + } + (void)pthread_mutex_unlock(&g_listenerList->lock); + return; +} + +uint32_t ConnGetHeadSize() +{ + return sizeof(ConnPktHead); +} + +uint32_t ConnGetNewRequestId(ConnModule moduleId) +{ +#define REQID_MAX 1000000 + (void)moduleId; + static uint32_t reqId = 1; + reqId++; + reqId = reqId % REQID_MAX + 1; + return reqId; +} + +void ConnManagerRecvData(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len) +{ + ConnListenerNode listener; + int32_t ret; + char* pkt = NULL; + int32_t pktLen; + + if (data == NULL) { + return; + } + + if (len <= (int32_t)sizeof(ConnPktHead)) { + LOG_ERR("len %d \r\n", len); + return; + } + + ret = GetListenerByModuleId(moduleId, &listener); + if (ret == SOFTBUS_ERR) { + LOG_ERR("GetListenerByModuleId fail moduleId %d \r\n", moduleId); + return; + } + + pktLen = len - sizeof(ConnPktHead); + pkt = data + sizeof(ConnPktHead); + listener.callback.OnDataReceived(connectionId, moduleId, seq, pkt, pktLen); + return; +} + +void ConnManagerConnected(uint32_t connectionId, const ConnectionInfo *info) +{ + int32_t i, num; + ConnListenerNode *node = NULL; + ConnListenerNode *listener = NULL; + + num = GetAllListener(&node); + if (num == 0 || node == NULL) { + LOG_ERR("get node fail connId %u", connectionId); + return; + } + for (i = 0; i < num; i++) { + listener = node + i; + listener->callback.OnConnected(connectionId, info); + } + SoftBusFree(node); + return; +} + +void ConnManagerDisconnected(uint32_t connectionId, const ConnectionInfo *info) +{ + int32_t i, num; + ConnListenerNode *node = NULL; + ConnListenerNode *listener = NULL; + + num = GetAllListener(&node); + if (num == 0 || node == NULL) { + return; + } + for (i = 0; i < num; i++) { + listener = node + i; + listener->callback.OnDisconnected(connectionId, info); + } + SoftBusFree(node); + return; +} + +int32_t ConnSetConnectCallback(ConnModule moduleId, const ConnectCallback *callback) +{ + if (ModuleCheck(moduleId) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + if (callback == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if ((callback->OnConnected == NULL) || + (callback->OnDisconnected == NULL) || + (callback->OnDataReceived == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + return AddListener(moduleId, callback); +} + +void ConnUnSetConnectCallback(ConnModule moduleId) +{ + DelListener(moduleId); + return; +} + +int32_t ConnTypeIsSupport(ConnectType type) +{ + return ConnTypeCheck(type); +} + +int32_t ConnConnectDevice(const ConnectOption *info, uint32_t requestId, const ConnectResult *result) +{ + if (info == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (ConnTypeCheck(info->type) != SOFTBUS_OK) { + LOG_ERR("connect type is err %d", info->type); + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[info->type]->ConnectDevice == NULL) { + return SOFTBUS_ERR; + } + + return g_connManager[info->type]->ConnectDevice(info, requestId, result); +} + +int32_t ConnPostBytes(uint32_t connectionId, ConnPostData *data) +{ + uint32_t type; + ConnPktHead *head = NULL; + + if (data == NULL || data->buf == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (data->len <= (int32_t)sizeof(ConnPktHead)) { + SoftBusFree(data->buf); + return SOFTBUS_CONN_MANAGER_PKT_LEN_INVALID; + } + + type = (connectionId >> CONNECT_TYPE_SHIFT); + if (ConnTypeCheck((ConnectType)type) != SOFTBUS_OK) { + LOG_ERR("connectionId type is err %d", type); + SoftBusFree(data->buf); + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[type]->PostBytes == NULL) { + SoftBusFree(data->buf); + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + + head = (ConnPktHead *)data->buf; + head->magic = MAGIC_NUMBER; + head->flag = data->flag; + head->module = data->module; + head->len = data->len - sizeof(ConnPktHead); + head->seq = data->seq; + + return g_connManager[type]->PostBytes(connectionId, data->buf, data->len, data->pid, data->flag); +} + +int32_t ConnDisconnectDevice(uint32_t connectionId) +{ + uint32_t type = (connectionId >> CONNECT_TYPE_SHIFT); + if (ConnTypeCheck((ConnectType)type) != SOFTBUS_OK) { + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[type]->DisconnectDevice == NULL) { + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + return g_connManager[type]->DisconnectDevice(connectionId); +} + +int32_t ConnDisconnectDeviceAllConn(const ConnectOption *option) +{ + if (option == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (ConnTypeCheck(option->type) != SOFTBUS_OK) { + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[option->type]->DisconnectDeviceNow == NULL) { + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + return g_connManager[option->type]->DisconnectDeviceNow(option); +} + +int32_t ConnGetConnectionInfo(uint32_t connectionId, ConnectionInfo *info) +{ + uint32_t type = (connectionId >> CONNECT_TYPE_SHIFT); + if (ConnTypeCheck((ConnectType)type) != SOFTBUS_OK) { + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[type]->GetConnectionInfo == NULL) { + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + + return g_connManager[type]->GetConnectionInfo(connectionId, info); +} + +int32_t ConnStartLocalListening(const LocalListenerInfo *info) +{ + if (info == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (ConnTypeCheck(info->type) != SOFTBUS_OK) { + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[info->type]->StartLocalListening == NULL) { + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + + return g_connManager[info->type]->StartLocalListening(info); +} + +int32_t ConnStopLocalListening(const LocalListenerInfo *info) +{ + if (info == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (ConnTypeCheck(info->type) != SOFTBUS_OK) { + return SOFTBUS_CONN_MANAGER_TYPE_NOT_SUPPORT; + } + + if (g_connManager[info->type]->StopLocalListening == NULL) { + return SOFTBUS_CONN_MANAGER_OP_NOT_SUPPORT; + } + + return g_connManager[info->type]->StopLocalListening(info); +} + +ConnectCallback g_connManagerCb = {0}; + +int32_t ConnServerInit(void) +{ + ConnectFuncInterface *connectObj = NULL; + + if (g_isInited) { + return SOFTBUS_ERR; + } + + g_connManagerCb.OnConnected = ConnManagerConnected; + g_connManagerCb.OnDisconnected = ConnManagerDisconnected; + g_connManagerCb.OnDataReceived = ConnManagerRecvData; + + connectObj = ConnInitTcp(&g_connManagerCb); + if (connectObj != NULL) { + g_connManager[CONNECT_TCP] = connectObj; + LOG_INFO("init tcp ok \r\n"); + } + + connectObj = ConnInitBr(&g_connManagerCb); + if (connectObj != NULL) { + g_connManager[CONNECT_BR] = connectObj; + LOG_INFO("init br ok \r\n"); + } + + connectObj = ConnInitBle(&g_connManagerCb); + if (connectObj != NULL) { + g_connManager[CONNECT_BLE] = connectObj; + LOG_INFO("init ble ok \r\n"); + } + + if (g_listenerList == NULL) { + g_listenerList = CreateSoftBusList(); + if (g_listenerList == NULL) { + LOG_ERR("create list fail \r\n"); + return SOFTBUS_ERR; + } + } + + g_isInited = true; + LOG_INFO("connect manager init success. \r\n"); + return SOFTBUS_OK; +} + +void ConnServerDeinit(void) +{ + if (!g_isInited) { + return; + } + + ConnListenerNode *item = NULL; + if (g_listenerList != NULL) { + while (!IsListEmpty(&g_listenerList->list)) { + item = LIST_ENTRY(&(g_listenerList->list.next), ConnListenerNode, node); + ListDelete(&item->node); + SoftBusFree(item); + } + DestroySoftBusList(g_listenerList); + g_listenerList = NULL; + } + + g_isInited = false; +} + diff --git a/core/connection/manager/softbus_conn_manager.h b/core/connection/manager/softbus_conn_manager.h new file mode 100755 index 000000000..638e0ac0f --- /dev/null +++ b/core/connection/manager/softbus_conn_manager.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CONN_MANAGER_H +#define SOFTBUS_CONN_MANAGER_H + +#include "softbus_conn_interface.h" + +#define CONNECT_TYPE_SHIFT 16 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef struct { + int32_t (*ConnectDevice)(const ConnectOption *option, uint32_t requestId, const ConnectResult *result); + int32_t (*PostBytes)(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag); + int32_t (*DisconnectDevice)(uint32_t connectionId); + int32_t (*DisconnectDeviceNow)(const ConnectOption *option); + int32_t (*GetConnectionInfo)(uint32_t connectionId, ConnectionInfo *info); + int32_t (*StartLocalListening)(const LocalListenerInfo *info); + int32_t (*StopLocalListening)(const LocalListenerInfo *info); +} ConnectFuncInterface; + +#define MAGIC_NUMBER 0xBABEFACE +typedef struct { + int32_t magic; + int32_t module; + int64_t seq; + int32_t flag; + int32_t len; +} ConnPktHead; + +ConnectFuncInterface *ConnInitBr(const ConnectCallback *callback); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/core/connection/manager/softbus_conn_manager_weak.c b/core/connection/manager/softbus_conn_manager_weak.c new file mode 100755 index 000000000..f72a795d1 --- /dev/null +++ b/core/connection/manager/softbus_conn_manager_weak.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_conn_manager_weak.h" + +ConnectFuncInterface __attribute__ ((weak)) *ConnInitBr(const ConnectCallback *callback) +{ + (void)callback; + return NULL; +} + +ConnectFuncInterface __attribute__ ((weak)) *ConnInitBle(const ConnectCallback *callback) +{ + (void)callback; + return NULL; +} + +ConnectFuncInterface __attribute__ ((weak)) *ConnInitTcp(const ConnectCallback *callback) +{ + (void)callback; + return NULL; +} \ No newline at end of file diff --git a/core/connection/manager/softbus_conn_manager_weak.h b/core/connection/manager/softbus_conn_manager_weak.h new file mode 100755 index 000000000..bdf67c5ab --- /dev/null +++ b/core/connection/manager/softbus_conn_manager_weak.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CONN_MANAGER_WEAK_H +#define SOFTBUS_CONN_MANAGER_WEAK_H + +#include "softbus_conn_interface.h" +#include "softbus_conn_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +ConnectFuncInterface __attribute__ ((weak)) *ConnInitBr(const ConnectCallback *callback); +ConnectFuncInterface __attribute__ ((weak)) *ConnInitBle(const ConnectCallback *callback); +ConnectFuncInterface __attribute__ ((weak)) *ConnInitTcp(const ConnectCallback *callback); + +#ifdef __cplusplus +} +#endif + +#endif // SOFTBUS_CONN_MANAGER_WEAK_H + diff --git a/core/connection/tcp/BUILD.gn b/core/connection/tcp/BUILD.gn new file mode 100755 index 000000000..b70c370a0 --- /dev/null +++ b/core/connection/tcp/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("tcp_connection") { + sources = [ "src/softbus_tcp_connect_manager.c" ] + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/interfaces/kits/common", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + deps = [ "$dsoftbus_root_path/core/connection/common:conn_common" ] + } +} else { + shared_library("tcp_connection") { + sources = [ "src/softbus_tcp_connect_manager.c" ] + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/interfaces/kits/common", + "//third_party/bounds_checking_function/include", + ] + deps = [ + "$dsoftbus_root_path/core/common/softbus_property:softbus_property", + "$dsoftbus_root_path/core/connection/common:conn_common", + ] + } +} diff --git a/core/connection/tcp/include/softbus_tcp_connect_manager.h b/core/connection/tcp/include/softbus_tcp_connect_manager.h new file mode 100644 index 000000000..c7f9d6a36 --- /dev/null +++ b/core/connection/tcp/include/softbus_tcp_connect_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_TCP_CONNECT_MANAGER_H +#define SOFTBUS_TCP_CONNECT_MANAGER_H + +#include +#include + +#include "common_list.h" +#include "softbus_conn_interface.h" +#include "softbus_conn_manager.h" +#include "softbus_base_listener.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +uint32_t CalTcpConnectionId(int32_t fd); + +int32_t TcpGetConnNum(void); + +int32_t TcpConnectDevice(const ConnectOption *option, uint32_t requestId, const ConnectResult *result); + +int32_t TcpDisconnectDevice(uint32_t connectionId); + +int32_t TcpDisconnectDeviceNow(const ConnectOption *option); + +int32_t TcpPostBytes(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag); + +int32_t TcpGetConnectionInfo(uint32_t connectionId, ConnectionInfo *Info); + +int32_t TcpStartListening(const LocalListenerInfo *info); + +int32_t TcpStopListening(const LocalListenerInfo *info); + +ConnectFuncInterface *ConnInitTcp(const ConnectCallback *callback); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/core/connection/tcp/src/softbus_tcp_connect_manager.c b/core/connection/tcp/src/softbus_tcp_connect_manager.c new file mode 100755 index 000000000..8e234a725 --- /dev/null +++ b/core/connection/tcp/src/softbus_tcp_connect_manager.c @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_tcp_connect_manager.h" + +#include +#include +#include +#include + +#include "securec.h" +#include "softbus_base_listener.h" +#include "softbus_conn_interface.h" +#include "softbus_conn_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_property.h" +#include "softbus_tcp_socket.h" +#include "softbus_type_def.h" +#include "softbus_utils.h" + +#define GET_TCP_MAX_CONN_NUM "CONN_TCP_MAX_CONN_NUM" +#define GET_TCP_MAX_LENGTH "CONN_TCP_MAX_LENGTH" +#define GET_TCP_TIME_OUT "CONN_TCP_TIME_OUT" +#define INVALID_DATA (-1) + +static int32_t g_tcpMaxConnNum; +static int32_t g_tcpTimeOut; +static int32_t g_tcpMaxLen; +static char g_localIp[IP_LEN]; + +typedef struct TcpConnInfoNode { + ListNode node; + uint32_t connectionId; + ConnectionInfo info; +} TcpConnInfoNode; + +static SoftBusList *g_tcpConnInfoList = NULL; +static SoftbusBaseListener *g_tcpListener = NULL; +static const ConnectCallback *g_tcpConnCallback; + +static int32_t AddTcpConnInfo(TcpConnInfoNode *item); +static int32_t DelTcpConnInfo(uint32_t connectionId, ConnectionInfo *info); +static void DelAllConnInfo(void); +static int32_t TcpOnConnectEvent(int32_t events, int32_t cfd, const char *ip); +static int32_t TcpOnDataEvent(int32_t events, int32_t fd); + +int32_t TcpGetConnNum(void) +{ + if (g_tcpConnInfoList == NULL) { + return 0; + } + return g_tcpConnInfoList->cnt; +} + +int32_t AddTcpConnInfo(TcpConnInfoNode *item) +{ + if (item == NULL || g_tcpConnInfoList == NULL) { + return SOFTBUS_INVALID_PARAM; + } + TcpConnInfoNode *temp = NULL; + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if ((int32_t)g_tcpConnInfoList->cnt >= g_tcpMaxConnNum) { + LOG_ERR("Tcp out of max conn num."); + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_ERR; + } + LIST_FOR_EACH_ENTRY(temp, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + if (temp->connectionId == item->connectionId) { + LOG_ERR("ConnectionId:%08x ready in ConnectionInfoList.", item->connectionId); + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_ERR; + } + } + ListInit(&item->node); + ListAdd(&g_tcpConnInfoList->list, &item->node); + g_tcpConnInfoList->cnt++; + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_OK; +} + +int32_t DelTcpConnInfo(uint32_t connectionId, ConnectionInfo *info) +{ + if (g_tcpConnInfoList == NULL) { + return SOFTBUS_ERR; + } + TcpConnInfoNode *item = NULL; + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + if (item->connectionId == connectionId) { + if (info != NULL) { + if (memcpy_s((void *)info, sizeof(ConnectionInfo), (void *)&item->info, + sizeof(ConnectionInfo)) != EOK) { + LOG_ERR("memcpy_s failed."); + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_MEM_ERR; + } + } + TcpShutDown(item->info.info.ipInfo.fd); + ListDelete(&item->node); + SoftBusFree(item); + g_tcpConnInfoList->cnt--; + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + LOG_ERR("DelTcpConnInfo failed. ConnectionId:%08x not found.", connectionId); + return SOFTBUS_OK; +} + +int32_t TcpOnConnectEvent(int32_t events, int32_t cfd, const char *ip) +{ + if (events == SOFTBUS_SOCKET_EXCEPTION) { + LOG_ERR("Exception occurred"); + return SOFTBUS_ERR; + } + if (cfd < 0 || ip == NULL || g_tcpListener == NULL) { + return SOFTBUS_INVALID_PARAM; + } + TcpConnInfoNode *tcpConnInfoNode = (TcpConnInfoNode *)SoftBusCalloc(sizeof(TcpConnInfoNode)); + if (tcpConnInfoNode == NULL) { + LOG_ERR("OnConnectEvent malloc TcpConnInfoNode"); + return SOFTBUS_MALLOC_ERR; + } + + tcpConnInfoNode->connectionId = CalTcpConnectionId(cfd); + tcpConnInfoNode->info.isAvailable = true; + tcpConnInfoNode->info.isServer = true; + tcpConnInfoNode->info.type = CONNECT_TCP; + if (strcpy_s(tcpConnInfoNode->info.info.ipInfo.ip, IP_LEN, ip) != EOK) { + goto EXIT; + } + tcpConnInfoNode->info.info.ipInfo.port = GetTcpSockPort(cfd); + tcpConnInfoNode->info.info.ipInfo.fd = cfd; + if (AddTrigger(PROXY, cfd, RW_TRIGGER) != SOFTBUS_OK) { + goto EXIT; + } + if (AddTcpConnInfo(tcpConnInfoNode) != SOFTBUS_OK) { + goto EXIT; + } + g_tcpConnCallback->OnConnected(tcpConnInfoNode->connectionId, &tcpConnInfoNode->info); + return SOFTBUS_OK; + +EXIT: + SoftBusFree(tcpConnInfoNode); + (void)DelTrigger(PROXY, cfd, RW_TRIGGER); + TcpShutDown(cfd); + return SOFTBUS_ERR; +} + +static char *RecvData(const ConnPktHead *head, int32_t fd, int32_t len) +{ + uint32_t headSize = sizeof(ConnPktHead); + ssize_t recvLen; + if (len > g_tcpMaxLen) { + LOG_ERR("Tcp recv data out of max data length, shutdown"); + return NULL; + } + char *data = (char *)SoftBusCalloc(headSize + len); + if (data == NULL) { + LOG_ERR("Tcp recv data malloc err"); + return NULL; + } + if (memcpy_s(data, headSize, head, headSize) != EOK) { + LOG_ERR("Tcp recv data copy head failed"); + goto EXIT; + } + recvLen = RecvTcpData(fd, data + headSize, len, g_tcpTimeOut); + if (recvLen != len) { + LOG_ERR("receiveData: error occurred!"); + goto EXIT; + } + return data; +EXIT: + SoftBusFree(data); + return NULL; +} + +int32_t TcpOnDataEvent(int32_t events, int32_t fd) +{ + if (g_tcpListener == NULL || events != SOFTBUS_SOCKET_IN) { + return SOFTBUS_ERR; + } + uint32_t connectionId = CalTcpConnectionId(fd); + ConnPktHead head; + uint32_t headSize = sizeof(ConnPktHead); + ssize_t bytes = RecvTcpData(fd, (char *)&head, headSize, g_tcpTimeOut); + if (bytes <= 0) { + LOG_INFO("TcpOnDataEvent Disconnect fd:%d", fd); + (void)DelTrigger(PROXY, fd, RW_TRIGGER); + ConnectionInfo *info = SoftBusCalloc(sizeof(ConnectionInfo)); + if (DelTcpConnInfo(connectionId, info) == SOFTBUS_OK) { + g_tcpConnCallback->OnDisconnected(connectionId, info); + } + SoftBusFree(info); + return SOFTBUS_OK; + } else if (bytes != (ssize_t)headSize) { + LOG_ERR("Recv Head failed."); + return SOFTBUS_ERR; + } + char *data = RecvData(&head, fd, head.len); + if (data == NULL) { + (void)DelTrigger(PROXY, fd, RW_TRIGGER); + DelTcpConnInfo(connectionId, NULL); + return SOFTBUS_ERR; + } + g_tcpConnCallback->OnDataReceived(connectionId, head.module, head.seq, data, headSize + head.len); + SoftBusFree(data); + return SOFTBUS_OK; +} + +static void DelAllConnInfo(void) +{ + if (g_tcpConnInfoList == NULL) { + return; + } + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return; + } + TcpConnInfoNode *item = NULL; + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + (void)DelTrigger(PROXY, item->info.info.ipInfo.fd, RW_TRIGGER); + } + while (1) { + if (IsListEmpty(&g_tcpConnInfoList->list)) { + break; + } + item = LIST_ENTRY((&g_tcpConnInfoList->list)->next, TcpConnInfoNode, node); + ListDelete(&item->node); + TcpShutDown(item->info.info.ipInfo.fd); + SoftBusFree(item); + g_tcpConnInfoList->cnt--; + } + ListInit(&g_tcpConnInfoList->list); + pthread_mutex_unlock(&g_tcpConnInfoList->lock); +} + +uint32_t CalTcpConnectionId(int32_t fd) +{ + uint32_t connectType = (uint32_t)CONNECT_TCP; + uint32_t connectionId = ((uint32_t)fd & 0xffff) | (connectType << CONNECT_TYPE_SHIFT); + return connectionId; +} + +int32_t TcpConnectDevice(const ConnectOption *option, uint32_t requestId, const ConnectResult *result) +{ + if (result == NULL || + result->OnConnectFailed == NULL || + result->OnConnectSuccessed == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (option == NULL || option->type != CONNECT_TCP) { + result->OnConnectFailed(requestId, SOFTBUS_INVALID_PARAM); + return SOFTBUS_INVALID_PARAM; + } + TcpConnInfoNode *tcpConnInfoNode = (TcpConnInfoNode *)SoftBusCalloc(sizeof(TcpConnInfoNode)); + if (tcpConnInfoNode == NULL) { + LOG_ERR("malloc TcpConnInfoNode failed"); + result->OnConnectFailed(requestId, SOFTBUS_MALLOC_ERR); + return SOFTBUS_MALLOC_ERR; + } + + int32_t fd = OpenTcpClientSocket(option->info.ipOption.ip, "0.0.0.0", (uint16_t)option->info.ipOption.port); + if (fd < 0) { + LOG_ERR("OpenTcpClient failed."); + SoftBusFree(tcpConnInfoNode); + result->OnConnectFailed(requestId, SOFTBUS_ERR); + return SOFTBUS_TCPCONNECTION_SOCKET_ERR; + } + if (AddTrigger(PROXY, fd, RW_TRIGGER) != SOFTBUS_OK) { + TcpShutDown(fd); + SoftBusFree(tcpConnInfoNode); + result->OnConnectFailed(requestId, SOFTBUS_ERR); + return SOFTBUS_ERR; + } + + uint32_t connectionId = CalTcpConnectionId(fd); + tcpConnInfoNode->connectionId = connectionId; + tcpConnInfoNode->info.isAvailable = true; + tcpConnInfoNode->info.isServer = false; + tcpConnInfoNode->info.type = CONNECT_TCP; + tcpConnInfoNode->info.info.ipInfo.port = option->info.ipOption.port; + tcpConnInfoNode->info.info.ipInfo.fd = fd; + if (strcpy_s(tcpConnInfoNode->info.info.ipInfo.ip, IP_LEN, option->info.ipOption.ip) != EOK || + AddTcpConnInfo(tcpConnInfoNode) != SOFTBUS_OK) { + (void)DelTrigger(PROXY, fd, RW_TRIGGER); + TcpShutDown(fd); + SoftBusFree(tcpConnInfoNode); + result->OnConnectFailed(requestId, SOFTBUS_ERR); + return SOFTBUS_ERR; + } + result->OnConnectSuccessed(requestId, tcpConnInfoNode->connectionId, &tcpConnInfoNode->info); + return SOFTBUS_OK; +} + +int32_t TcpDisconnectDevice(uint32_t connectionId) +{ + ConnectionInfo info; + if (TcpGetConnectionInfo(connectionId, &info) != SOFTBUS_OK || !info.isAvailable) { + return SOFTBUS_ERR; + } + (void)DelTrigger(PROXY, info.info.ipInfo.fd, RW_TRIGGER); + return DelTcpConnInfo(connectionId, NULL); +} + +int32_t TcpDisconnectDeviceNow(const ConnectOption *option) +{ + if (g_tcpConnInfoList == NULL) { + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + TcpConnInfoNode *item = NULL; + TcpConnInfoNode *itemPrev = NULL; + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + if (strcmp(option->info.ipOption.ip, item->info.info.ipInfo.ip) == 0) { + (void)DelTrigger(PROXY, item->info.info.ipInfo.fd, RW_TRIGGER); + } + } + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + itemPrev = (TcpConnInfoNode *)LIST_ENTRY(item, TcpConnInfoNode, node)->node.prev; + if (strcmp(option->info.ipOption.ip, item->info.info.ipInfo.ip) == 0) { + TcpShutDown(item->info.info.ipInfo.fd); + ListDelete(&item->node); + SoftBusFree(item); + g_tcpConnInfoList->cnt--; + item = itemPrev; + } + } + if (g_tcpConnInfoList->cnt == 0) { + ListInit(&g_tcpConnInfoList->list); + } + pthread_mutex_unlock(&g_tcpConnInfoList->lock); + return SOFTBUS_OK; +} + +int32_t TcpPostBytes(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag) +{ + (void)pid; + TcpConnInfoNode *item = NULL; + if (g_tcpConnInfoList == NULL) { + return SOFTBUS_ERR; + } + if (data == NULL || len <= 0) { + return SOFTBUS_INVALID_PARAM; + } + int32_t fd = -1; + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + if (item->connectionId == connectionId) { + fd = item->info.info.ipInfo.fd; + break; + } + } + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + if (fd == -1) { + LOG_ERR("TcpPostBytes failed, connectionId:%08x not found.", connectionId); + return SOFTBUS_ERR; + } + int32_t bytes = SendTcpData(fd, data, len, flag); + if (bytes != len) { + return SOFTBUS_TCPCONNECTION_SOCKET_ERR; + } + return SOFTBUS_OK; +} + +int32_t TcpGetConnectionInfo(uint32_t connectionId, ConnectionInfo *info) +{ + if (g_tcpConnInfoList == NULL) { + return SOFTBUS_ERR; + } + if (info == NULL) { + LOG_ERR("info is NULL."); + return SOFTBUS_INVALID_PARAM; + } + TcpConnInfoNode *item = NULL; + if (pthread_mutex_lock(&g_tcpConnInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + LIST_FOR_EACH_ENTRY(item, &g_tcpConnInfoList->list, TcpConnInfoNode, node) { + if (item->connectionId == connectionId) { + int32_t ret = memcpy_s(info, sizeof(ConnectionInfo), &item->info, sizeof(ConnectionInfo)); + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + if (ret != EOK) { + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; + } + } + info->isAvailable = false; + (void)pthread_mutex_unlock(&g_tcpConnInfoList->lock); + LOG_ERR("ConnectionId:%08x is not exists.", connectionId); + return SOFTBUS_ERR; +} + +int32_t TcpStartListening(const LocalListenerInfo *info) +{ + if (info == NULL || info->type != CONNECT_TCP) { + return SOFTBUS_INVALID_PARAM; + } + if (g_tcpListener == NULL) { + g_tcpListener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener)); + if (g_tcpListener == NULL) { + LOG_ERR("malloc tcp listener failed"); + return SOFTBUS_MALLOC_ERR; + } + g_tcpListener->onConnectEvent = TcpOnConnectEvent; + g_tcpListener->onDataEvent = TcpOnDataEvent; + } + int32_t rc = SetSoftbusBaseListener(PROXY, g_tcpListener); + if (rc != SOFTBUS_OK) { + LOG_ERR("Set BaseListener Failed."); + return rc; + } + if (strcpy_s(g_localIp, IP_LEN, info->info.ipListenerInfo.ip) != EOK) { + LOG_ERR("Get local ip addr failed."); + return SOFTBUS_MEM_ERR; + } + + rc = StartBaseListener(PROXY, g_localIp, info->info.ipListenerInfo.port, SERVER_MODE); + return rc; +} + +int32_t TcpStopListening(const LocalListenerInfo *info) +{ + if (info == NULL || g_tcpListener == NULL) { + return SOFTBUS_INVALID_PARAM; + } + int32_t ret = StopBaseListener(PROXY); + if (ret != SOFTBUS_OK) { + return ret; + } + DelAllConnInfo(); + DestroyBaseListener(PROXY); + g_tcpListener = NULL; + return SOFTBUS_OK; +} + +static int32_t InitProperty() +{ + g_tcpMaxConnNum = INVALID_DATA; + g_tcpTimeOut = INVALID_DATA; + g_tcpMaxLen = INVALID_DATA; + GetPropertyInt(GET_TCP_MAX_CONN_NUM, &g_tcpMaxConnNum); + GetPropertyInt(GET_TCP_MAX_LENGTH, &g_tcpMaxLen); + GetPropertyInt(GET_TCP_TIME_OUT, &g_tcpTimeOut); + if (g_tcpMaxConnNum == INVALID_DATA || g_tcpTimeOut == INVALID_DATA || + g_tcpMaxLen == INVALID_DATA) { + LOG_ERR("Cannot get brBuffSize"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +ConnectFuncInterface *ConnInitTcp(const ConnectCallback *callback) +{ + if (callback == NULL) { + LOG_ERR("ConnectCallback is NULL."); + return NULL; + } + if (InitProperty() != SOFTBUS_OK) { + LOG_ERR("Can not InitProperty"); + return NULL; + } + ConnectFuncInterface *interface = SoftBusCalloc(sizeof(ConnectFuncInterface)); + if (interface == NULL) { + LOG_ERR("InitTcp failed."); + return NULL; + } + interface->ConnectDevice = TcpConnectDevice; + interface->DisconnectDevice = TcpDisconnectDevice; + interface->DisconnectDeviceNow = TcpDisconnectDeviceNow; + interface->PostBytes = TcpPostBytes; + interface->GetConnectionInfo = TcpGetConnectionInfo; + interface->StartLocalListening = TcpStartListening; + interface->StopLocalListening = TcpStopListening; + g_tcpConnCallback = callback; + + if (g_tcpConnInfoList == NULL) { + g_tcpConnInfoList = CreateSoftBusList(); + if (g_tcpConnInfoList == NULL) { + LOG_ERR("Create tcpConnInfoList failed."); + SoftBusFree(interface); + return NULL; + } + g_tcpConnInfoList->cnt = 0; + } + if (g_tcpListener == NULL) { + g_tcpListener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener)); + if (g_tcpListener == NULL) { + SoftBusFree(interface); + DestroySoftBusList(g_tcpConnInfoList); + g_tcpConnInfoList = NULL; + return NULL; + } + } + g_tcpListener->onConnectEvent = TcpOnConnectEvent; + g_tcpListener->onDataEvent = TcpOnDataEvent; + return interface; +} \ No newline at end of file diff --git a/core/discovery/BUILD.gn b/core/discovery/BUILD.gn new file mode 100755 index 000000000..323070044 --- /dev/null +++ b/core/discovery/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") + +lite_component("softbus_discovery") { + features = [ + "manager:disc_manager", + "coap:disc_coap_module", + ] +} diff --git a/core/discovery/coap/BUILD.gn b/core/discovery/coap/BUILD.gn new file mode 100755 index 000000000..12714359e --- /dev/null +++ b/core/discovery/coap/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +shared_library("disc_coap_module") { + sources = [ + "src/disc_coap.c", + "src/disc_nstackx_adapter.c", + ] + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/discovery/interface", + "$dsoftbus_root_path/core/discovery/manager/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/components/dfinder/include", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-std=c99", + ] + ldflags = [ + "-lnstackx_ctrl", + "-lnstackx_util", + ] + deps = [ + "$dsoftbus_root_path/components/dfinder:dfinder", + "$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel", + "$dsoftbus_root_path/core/bus_center:softbus_bus_center", + "$dsoftbus_root_path/core/common/json_utils:json_utils", + "//third_party/bounds_checking_function:libsec_shared", + ] +} diff --git a/core/discovery/coap/include/disc_coap.h b/core/discovery/coap/include/disc_coap.h new file mode 100755 index 000000000..8c2936ea2 --- /dev/null +++ b/core/discovery/coap/include/disc_coap.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISC_COAP_H +#define DISC_COAP_H + +#include "disc_manager.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +DiscoveryFuncInterface *DiscCoapInit(DiscInnerCallback *discInnerCb); +void DiscCoapDeinit(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // !DISC_COAP_H diff --git a/core/discovery/coap/include/disc_nstackx_adapter.h b/core/discovery/coap/include/disc_nstackx_adapter.h new file mode 100755 index 000000000..87633aafc --- /dev/null +++ b/core/discovery/coap/include/disc_nstackx_adapter.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISC_NSTACKX_ADAPTER_H +#define DISC_NSTACKX_ADAPTER_H + +#include +#include "disc_manager.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum { + INVALID_MODE = -1, + ACTIVE_PUBLISH = 0, + ACTIVE_DISCOVERY, +} DiscCoapMode; + +int32_t DiscNstackxInit(void); +void DiscNstackxDeinit(void); + +int32_t DiscCoapRegisterCb(const DiscInnerCallback *discCoapCb); +int32_t DiscCoapRegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); +int32_t DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]); +int32_t DiscCoapRegisterServiceData(const unsigned char *serviceData, uint32_t dataLen); +int32_t DiscCoapStartDiscovery(DiscCoapMode); +int32_t DiscCoapStopDiscovery(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // !DISC_NSTACKX_ADAPTER_H diff --git a/core/discovery/coap/src/disc_coap.c b/core/discovery/coap/src/disc_coap.c new file mode 100755 index 000000000..30c7faa5f --- /dev/null +++ b/core/discovery/coap/src/disc_coap.c @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "disc_coap.h" + +#include +#include "disc_nstackx_adapter.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#define INT32_MAX_BIT_NUM 32 +#define MAX_CAP_NUM (CAPABILITY_NUM * INT32_MAX_BIT_NUM) +#define MAX_SERVICE_DATA 64 + +typedef struct { + uint32_t allCap[CAPABILITY_NUM]; + int16_t capCount[MAX_CAP_NUM]; + bool isUpdate; + bool isEmpty; + pthread_mutex_t lock; +} DiscCoapInfo; + +static DiscCoapInfo *g_publishMgr = NULL; +static DiscCoapInfo *g_subscribeMgr = NULL; + +static int32_t RegisterAllCapBitmap(uint32_t capBitmapNum, const uint32_t inCapBitmap[], DiscCoapInfo *info, + uint32_t count) +{ + if (info == NULL || capBitmapNum == 0 || capBitmapNum > CAPABILITY_NUM || count > MAX_CAP_NUM) { + LOG_ERR("invalid param."); + return SOFTBUS_INVALID_PARAM; + } + + info->isUpdate = false; + for (uint32_t i = 0; i < capBitmapNum; i++) { + LOG_INFO("register input bitmap = [%u].", inCapBitmap[i]); + for (uint32_t pos = 0; pos < count; pos++) { + if (((inCapBitmap[i] >> (pos % INT32_MAX_BIT_NUM)) & 0x1) == 0) { + continue; + } + if ((info->capCount)[pos] == 0) { + (info->allCap)[i] |= (0x1 << (pos % INT32_MAX_BIT_NUM)); + info->isUpdate = true; + } + (info->capCount)[pos]++; + } + LOG_INFO("register all cap bitmap = [%u].", (info->allCap)[i]); + } + return SOFTBUS_OK; +} + +static int32_t UnregisterAllCapBitmap(uint32_t capBitmapNum, const uint32_t inCapBitmap[], DiscCoapInfo *info, + uint32_t count) +{ + if (info == NULL || capBitmapNum == 0 || capBitmapNum > CAPABILITY_NUM || count > MAX_CAP_NUM) { + LOG_ERR("invalid param."); + return SOFTBUS_INVALID_PARAM; + } + + info->isEmpty = true; + info->isUpdate = false; + for (uint32_t i = 0; i < capBitmapNum; i++) { + LOG_INFO("unregister input bitmap = [%u].", inCapBitmap[i]); + for (uint32_t pos = 0; pos < count; pos++) { + if (((inCapBitmap[i] >> (pos % INT32_MAX_BIT_NUM)) & 0x1) == 0) { + continue; + } + (info->capCount)[pos]--; + if ((info->capCount)[pos] <= 0) { + (info->allCap)[i] &= (~(0x1 << (pos % INT32_MAX_BIT_NUM))); + (info->capCount)[pos] = 0; + info->isUpdate = true; + } + } + if ((info->allCap)[i] != 0) { + info->isEmpty = false; + } + LOG_INFO("register all cap bitmap = [%u].", (info->allCap)[i]); + } + return SOFTBUS_OK; +} + +static int32_t CoapPublish(const PublishOption *option) +{ + if (option == NULL || g_publishMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(g_publishMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (RegisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_publishMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("merge publish capability failed."); + return SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL; + } + if (g_publishMgr->isUpdate) { + if (DiscCoapRegisterCapability(CAPABILITY_NUM, g_publishMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register all capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL; + } + } + if (DiscCoapRegisterServiceData(option->capabilityData, option->dataLen) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register service data to dfinder failed."); + return SOFTBUS_ERR; + } + if (DiscCoapStartDiscovery(ACTIVE_PUBLISH) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("coap start publish failed."); + return SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL; + } + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_INFO("coap publish service."); + return SOFTBUS_OK; +} + +static int32_t CoapUnPublish(const PublishOption *option) +{ + if (option == NULL || g_publishMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&(g_publishMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (UnregisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_publishMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("cancel a publish capability failed."); + return SOFTBUS_DISCOVER_COAP_CANCEL_CAP_FAIL; + } + if (g_publishMgr->isUpdate) { + if (DiscCoapRegisterCapability(CAPABILITY_NUM, g_publishMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register all capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL; + } + } + if (DiscCoapRegisterServiceData(option->capabilityData, option->dataLen) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register service data to dfinder failed."); + return SOFTBUS_ERR; + } + if (g_publishMgr->isEmpty) { + if (DiscCoapStopDiscovery() != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("coap unpublish failed."); + return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL; + } + } + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_INFO("coap unpublish service."); + return SOFTBUS_OK; +} + +static int32_t CoapStartScan(const PublishOption *option) +{ + if (option == NULL || g_publishMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(g_publishMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (RegisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_publishMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("merge publish capability failed."); + return SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL; + } + if (g_publishMgr->isUpdate) { + if (DiscCoapRegisterCapability(CAPABILITY_NUM, g_publishMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register all capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL; + } + } + if (DiscCoapRegisterServiceData(option->capabilityData, option->dataLen) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register service data to dfinder failed."); + return SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_INFO("coap start passive publish."); + return SOFTBUS_OK; +} + +static int32_t CoapStoptScan(const PublishOption *option) +{ + if (option == NULL || g_publishMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (pthread_mutex_lock(&(g_publishMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (UnregisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_publishMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("merge publish capability failed."); + return SOFTBUS_DISCOVER_COAP_CANCEL_CAP_FAIL; + } + if (g_publishMgr->isUpdate) { + if (DiscCoapRegisterCapability(CAPABILITY_NUM, g_publishMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register all capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL; + } + } + if (DiscCoapRegisterServiceData(option->capabilityData, option->dataLen) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_ERR("register service data to dfinder failed."); + return SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&(g_publishMgr->lock)); + LOG_INFO("coap stop passive publish."); + return SOFTBUS_OK; +} + +static int32_t CoapSubscribe(const SubscribeOption *option) +{ + if (option == NULL || g_subscribeMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&(g_subscribeMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (RegisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_subscribeMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("merge discovery capability failed."); + return SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL; + } + if (g_subscribeMgr->isUpdate) { + if (DiscCoapSetFilterCapability(CAPABILITY_NUM, g_subscribeMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("set all filter capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL; + } + } + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_INFO("coap start passive discovery."); + return SOFTBUS_OK; +} + +static int32_t CoapUnsubscribe(const SubscribeOption *option) +{ + if (option == NULL || g_subscribeMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&(g_subscribeMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (UnregisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_subscribeMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("merge discovery capability failed."); + return SOFTBUS_DISCOVER_COAP_CANCEL_CAP_FAIL; + } + if (g_subscribeMgr->isUpdate) { + if (DiscCoapSetFilterCapability(CAPABILITY_NUM, g_subscribeMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("set all filter capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL; + } + } + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_INFO("coap stop passive discovery."); + return SOFTBUS_OK; +} + +static int32_t CoapStartAdvertise(const SubscribeOption *option) +{ + if (option == NULL || g_subscribeMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&(g_subscribeMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (RegisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_subscribeMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("merge discovery capability failed."); + return SOFTBUS_DISCOVER_COAP_MERGE_CAP_FAIL; + } + if (g_subscribeMgr->isUpdate) { + if (DiscCoapSetFilterCapability(CAPABILITY_NUM, g_subscribeMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("set all filter capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL; + } + } + if (DiscCoapStopDiscovery() != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("coap stop discovery failed."); + return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL; + } + if (DiscCoapStartDiscovery(ACTIVE_DISCOVERY) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("coap start advertise failed."); + return SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL; + } + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_INFO("coap start active discovery."); + return SOFTBUS_OK; +} + +static int32_t CoapStopAdvertise(const SubscribeOption *option) +{ + if (option == NULL || g_subscribeMgr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&(g_subscribeMgr->lock)) != 0) { + LOG_ERR("pthread mutex lock failed."); + return SOFTBUS_LOCK_ERR; + } + if (UnregisterAllCapBitmap(CAPABILITY_NUM, option->capabilityBitmap, g_subscribeMgr, MAX_CAP_NUM) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("cancel a discovery capability failed."); + return SOFTBUS_DISCOVER_COAP_CANCEL_CAP_FAIL; + } + if (g_subscribeMgr->isUpdate) { + if (DiscCoapSetFilterCapability(CAPABILITY_NUM, g_subscribeMgr->allCap) != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("set all filter capability to dfinder failed."); + return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL; + } + } + if (g_subscribeMgr->isEmpty) { + if (DiscCoapStopDiscovery() != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_ERR("coap stop advertise failed."); + return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL; + } + } + (void)pthread_mutex_unlock(&(g_subscribeMgr->lock)); + LOG_INFO("coap stop active discovery."); + return SOFTBUS_OK; +} + +static DiscoveryFuncInterface g_discCoapFuncInterface = { + .Publish = CoapPublish, + .StartScan = CoapStartScan, + .Unpublish = CoapUnPublish, + .StopScan = CoapStoptScan, + .StartAdvertise = CoapStartAdvertise, + .Subscribe = CoapSubscribe, + .StopAdvertise = CoapStopAdvertise, + .Unsubscribe = CoapUnsubscribe +}; + +static DiscCoapInfo *NewDiscCoapInfo() +{ + DiscCoapInfo *coapInfo = (DiscCoapInfo*)SoftBusCalloc(sizeof(DiscCoapInfo)); + if (coapInfo == NULL) { + return NULL; + } + if (pthread_mutex_init(&(coapInfo->lock), NULL) != 0) { + SoftBusFree(coapInfo); + return NULL; + } + return coapInfo; +} + +static void DeleteDiscCoapInfo(DiscCoapInfo *coapInfo) +{ + if (coapInfo == NULL) { + return; + } + (void)pthread_mutex_destroy(&(coapInfo->lock)); + SoftBusFree(coapInfo); +} + +static void DeinitCoapManager() +{ + DeleteDiscCoapInfo(g_publishMgr); + g_publishMgr = NULL; + DeleteDiscCoapInfo(g_subscribeMgr); + g_subscribeMgr = NULL; +} + +static int32_t InitCoapManager() +{ + if (g_publishMgr == NULL) { + g_publishMgr = NewDiscCoapInfo(); + } + if (g_subscribeMgr == NULL) { + g_subscribeMgr = NewDiscCoapInfo(); + } + if (g_publishMgr == NULL || g_subscribeMgr == NULL) { + DeinitCoapManager(); + return SOFTBUS_DISCOVER_COAP_INIT_FAIL; + } + return SOFTBUS_OK; +} + +DiscoveryFuncInterface *DiscCoapInit(DiscInnerCallback *discInnerCb) +{ + if (InitCoapManager() != SOFTBUS_OK) { + LOG_ERR("coap manager init failed."); + return NULL; + } + if (DiscNstackxInit() != SOFTBUS_OK) { + LOG_ERR("dfinder init failed."); + DeinitCoapManager(); + return NULL; + } + if (DiscCoapRegisterCb(discInnerCb) != SOFTBUS_OK) { + LOG_ERR("register coap callback to dfinder failed."); + DiscCoapDeinit(); + return NULL; + } + LOG_INFO("coap discovery init success."); + return &g_discCoapFuncInterface; +} + +void DiscCoapDeinit(void) +{ + DeinitCoapManager(); + DiscNstackxDeinit(); +} \ No newline at end of file diff --git a/core/discovery/coap/src/disc_nstackx_adapter.c b/core/discovery/coap/src/disc_nstackx_adapter.c new file mode 100755 index 000000000..9f5f97dab --- /dev/null +++ b/core/discovery/coap/src/disc_nstackx_adapter.c @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "disc_nstackx_adapter.h" + +#include +#include +#include "bus_center_manager.h" +#include "nstackx.h" +#include "securec.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +#define JSON_WLAN_IP "wifiIpAddr" +#define JSON_HW_ACCOUNT "hwAccountHashVal" +#define JSON_SERVICE_DATA "serviceData" +#define SERVICE_DATA_PORT "port" +#define DEVICE_UDID "UDID" +#define AUTH_PORT_LEN 6 + +static NSTACKX_LocalDeviceInfo *g_localDeviceInfo = NULL; +static DiscInnerCallback *g_discCoapInnerCb = NULL; +static char *g_capabilityData = NULL; + +static void ParseWifiIpAddr(const cJSON *data, DeviceInfo *device) +{ + if (!GetJsonObjectStringItem(data, JSON_WLAN_IP, device->addr[0].addr, sizeof(device->addr[0].addr))) { + LOG_ERR("parse wifi ip address failed."); + return; + } +} + +static void ParseHwAccountHash(const cJSON *data, DeviceInfo *device) +{ + if (!GetJsonObjectStringItem(data, JSON_HW_ACCOUNT, device->hwAccountHash, sizeof(device->hwAccountHash))) { + LOG_ERR("parse hw account hash value failed."); + return; + } +} + +static void ParseItemDataFromServiceData(char *serviceData, const char *key, char *targetStr, int32_t len) +{ + const char *itemDelimit = ","; + const char *keyStr = NULL; + char *valueStr = NULL; + char *itemStr = NULL; + char *saveItemPtr = NULL; + itemStr = strtok_s(serviceData, itemDelimit, &saveItemPtr); + while (itemStr != NULL) { + valueStr = strchr(itemStr, ':'); + if (valueStr == NULL) { + continue; + } + *valueStr = '\0'; + valueStr++; + keyStr = itemStr; + if (!strcmp(keyStr, key)) { + if (strcpy_s(targetStr, len, valueStr) != EOK) { + LOG_ERR("strpcy_s failed."); + break; + } + return; + } + itemStr = strtok_s(NULL, itemDelimit, &saveItemPtr); + } + LOG_INFO("not find key in service data."); + return; +} + +static void ParseServiceData(const cJSON *data, DeviceInfo *device) +{ + char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN] = {0}; + if (!GetJsonObjectStringItem(data, JSON_SERVICE_DATA, serviceData, sizeof(serviceData))) { + LOG_ERR("parse service data failed."); + return; + } + char port[AUTH_PORT_LEN] = {0}; + ParseItemDataFromServiceData(serviceData, SERVICE_DATA_PORT, port, sizeof(port)); + int authPort = atoi(port); + if (authPort == 0) { + LOG_ERR("not find auth port."); + return; + } + device->addr[0].port = authPort; +} + +static int32_t ParseReservedInfo(const NSTACKX_DeviceInfo *nstackxDevice, DeviceInfo *device) +{ + cJSON *reserveInfo = cJSON_Parse(nstackxDevice->reservedInfo); + if (reserveInfo == NULL) { + LOG_ERR("parse reserve data failed."); + return SOFTBUS_PARSE_JSON_ERR; + } + + ParseWifiIpAddr(reserveInfo, device); + ParseHwAccountHash(reserveInfo, device); + ParseServiceData(reserveInfo, device); + cJSON_Delete(reserveInfo); + return SOFTBUS_OK; +} + +static int32_t ParseDeviceUdid(const NSTACKX_DeviceInfo *nstackxDevice, DeviceInfo *device) +{ + cJSON *deviceId = cJSON_Parse(nstackxDevice->deviceId); + if (deviceId == NULL) { + LOG_ERR("parse device id failed."); + return SOFTBUS_ERR; + } + if (!GetJsonObjectStringItem(deviceId, DEVICE_UDID, device->devId, sizeof(device->devId))) { + cJSON_Delete(deviceId); + LOG_ERR("parse udid from remote failed."); + return SOFTBUS_ERR; + } + cJSON_Delete(deviceId); + return SOFTBUS_OK; +} + +static void OnDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount) +{ + if (deviceCount == 0) { + return; + } + + for (uint32_t i = 0; i < deviceCount; i++) { + const NSTACKX_DeviceInfo *nstackxDeviceInfo = deviceList + i; + if (nstackxDeviceInfo == NULL) { + return; + } + if (((nstackxDeviceInfo->update) & 0x1) == 0) { + LOG_INFO("duplicate device is not reported."); + continue; + } + DeviceInfo discDeviceInfo; + (void)memset_s(&discDeviceInfo, sizeof(DeviceInfo), 0, sizeof(DeviceInfo)); + if (memcpy_s(discDeviceInfo.devName, sizeof(discDeviceInfo.devName), + nstackxDeviceInfo->deviceName, sizeof(nstackxDeviceInfo->deviceName)) != EOK || + memcpy_s(discDeviceInfo.capabilityBitmap, sizeof(discDeviceInfo.capabilityBitmap), + nstackxDeviceInfo->capabilityBitmap, sizeof(nstackxDeviceInfo->capabilityBitmap))) { + LOG_ERR("memcpy_s failed."); + return; + } + discDeviceInfo.addrNum = 1; + discDeviceInfo.devType = nstackxDeviceInfo->deviceType; + discDeviceInfo.capabilityBitmapNum = nstackxDeviceInfo->capabilityBitmapNum; + discDeviceInfo.addr[0].type = CONNECT_ADDR_WLAN; + if (ParseDeviceUdid(nstackxDeviceInfo, &discDeviceInfo) != SOFTBUS_OK) { + LOG_ERR("parse device udid failed."); + return; + } + if (ParseReservedInfo(nstackxDeviceInfo, &discDeviceInfo) != SOFTBUS_OK) { + LOG_ERR("parse reserve information failed."); + return; + } + if (g_discCoapInnerCb != NULL) { + g_discCoapInnerCb->OnDeviceFound(&discDeviceInfo); + } + } +} + +static NSTACKX_Parameter g_nstackxCallBack = { + .onDeviceListChanged = OnDeviceFound, + .onDeviceFound = NULL, + .onMsgReceived = NULL, + .onDFinderMsgReceived = NULL +}; + +int32_t DiscCoapRegisterCb(const DiscInnerCallback *discCoapCb) +{ + if (discCoapCb == NULL || g_discCoapInnerCb == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (memcpy_s(g_discCoapInnerCb, sizeof(DiscInnerCallback), discCoapCb, sizeof(DiscInnerCallback)) != EOK) { + LOG_ERR("memcpy_s failed."); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +int32_t DiscCoapRegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + if (capabilityBitmapNum == 0) { + return SOFTBUS_INVALID_PARAM; + } + + if (NSTACKX_RegisterCapability(capabilityBitmapNum, capabilityBitmap) != 0) { + return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL; + } + return SOFTBUS_OK; +} + +int32_t DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]) +{ + if (capabilityBitmapNum == 0) { + return SOFTBUS_INVALID_PARAM; + } + + if (NSTACKX_SetFilterCapability(capabilityBitmapNum, capabilityBitmap) != SOFTBUS_OK) { + return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL; + } + return SOFTBUS_OK; +} + +int32_t DiscCoapRegisterServiceData(const unsigned char *serviceData, uint32_t dataLen) +{ + (void)serviceData; + (void)dataLen; + if (g_capabilityData == NULL) { + return SOFTBUS_DISCOVER_COAP_INIT_FAIL; + } + + int32_t authPort = 0; + if (LnnGetLocalNumInfo(NUM_KEY_AUTH_PORT, &authPort) != SOFTBUS_OK) { + LOG_ERR("get auth port from lnn failed."); + return SOFTBUS_ERR; + } + (void)memset_s(g_capabilityData, NSTACKX_MAX_SERVICE_DATA_LEN, 0, NSTACKX_MAX_SERVICE_DATA_LEN); + int32_t ret = sprintf_s(g_capabilityData, NSTACKX_MAX_SERVICE_DATA_LEN, "port:%d,", authPort); + if (ret == -1) { + return SOFTBUS_ERR; + } + if (NSTACKX_RegisterServiceData(g_capabilityData) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t DiscCoapStartDiscovery(DiscCoapMode mode) +{ + if (mode < ACTIVE_PUBLISH || mode > ACTIVE_DISCOVERY) { + LOG_ERR("invalid param."); + return SOFTBUS_INVALID_PARAM; + } + + switch (mode) { + case ACTIVE_PUBLISH: + if (NSTACKX_StartDeviceFindAn(PUBLISH_MODE_PROACTIVE) != SOFTBUS_OK) { + return SOFTBUS_DISCOVER_COAP_START_PUBLISH_FAIL; + } + break; + case ACTIVE_DISCOVERY: + if (NSTACKX_StartDeviceFind() != SOFTBUS_OK) { + return SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL; + } + break; + default: + LOG_ERR("unsupport coap mode."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t DiscCoapStopDiscovery(void) +{ + if (NSTACKX_StopDeviceFind() != SOFTBUS_OK) { + return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL; + } + + return SOFTBUS_OK; +} + +static char *GetDeviceId() +{ + char *formatString = NULL; + char udid[UDID_BUF_LEN] = {0}; + if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, sizeof(udid)) != SOFTBUS_OK) { + LOG_ERR("get udid failed."); + return NULL; + } + cJSON *deviceId = cJSON_CreateObject(); + if (deviceId == NULL) { + LOG_ERR("crate json object failed."); + return NULL; + } + if (!AddStringToJsonObject(deviceId, DEVICE_UDID, udid)) { + LOG_ERR("add udid to device id json object failed."); + goto GET_DEVICE_ID_END; + } + formatString = cJSON_PrintUnformatted(deviceId); + if (formatString == NULL) { + LOG_ERR("format device id json object failed."); + } + +GET_DEVICE_ID_END: + cJSON_Delete(deviceId); + return formatString; +} + +static int32_t SetLocalDeviceInfo() +{ + if (g_localDeviceInfo == NULL) { + return SOFTBUS_DISCOVER_COAP_NOT_INIT; + } + + char *deviceIdStr = GetDeviceId(); + if (deviceIdStr == NULL) { + LOG_ERR("get device id string failed."); + return SOFTBUS_ERR; + } + if (memcpy_s(g_localDeviceInfo->deviceId, sizeof(g_localDeviceInfo->deviceId), deviceIdStr, strlen(deviceIdStr))) { + cJSON_free(deviceIdStr); + LOG_ERR("memcpy_s failed."); + return SOFTBUS_ERR; + } + cJSON_free(deviceIdStr); + int32_t deviceType = 0; + if (LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, &deviceType) != SOFTBUS_OK) { + LOG_ERR("get local device type failed."); + return SOFTBUS_ERR; + } + g_localDeviceInfo->deviceType = (uint8_t)deviceType; + if (LnnGetLocalStrInfo(STRING_KEY_DEV_NAME, g_localDeviceInfo->name, + sizeof(g_localDeviceInfo->name)) != SOFTBUS_OK || + LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, g_localDeviceInfo->networkIpAddr, + sizeof(g_localDeviceInfo->networkIpAddr)) != SOFTBUS_OK || + LnnGetLocalStrInfo(STRING_KEY_HICE_VERSION, g_localDeviceInfo->version, + sizeof(g_localDeviceInfo->version)) != SOFTBUS_OK || + LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, g_localDeviceInfo->networkName, + sizeof(g_localDeviceInfo->networkName)) != SOFTBUS_OK) { + LOG_ERR("get local device info from lnn failed."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static void DeinitLocalInfo() +{ + if (g_localDeviceInfo != NULL) { + SoftBusFree(g_localDeviceInfo); + g_localDeviceInfo = NULL; + } + + if (g_capabilityData != NULL) { + SoftBusFree(g_capabilityData); + g_capabilityData = NULL; + } + + if (g_discCoapInnerCb != NULL) { + SoftBusFree(g_discCoapInnerCb); + g_discCoapInnerCb = NULL; + } +} + +static int32_t InitLocalInfo() +{ + if (g_localDeviceInfo == NULL) { + g_localDeviceInfo = (NSTACKX_LocalDeviceInfo*)SoftBusCalloc(sizeof(NSTACKX_LocalDeviceInfo)); + if (g_localDeviceInfo == NULL) { + return SOFTBUS_MEM_ERR; + } + } + if (SetLocalDeviceInfo() != SOFTBUS_OK) { + DeinitLocalInfo(); + return SOFTBUS_ERR; + } + if (g_capabilityData == NULL) { + g_capabilityData = (char*)SoftBusCalloc(NSTACKX_MAX_SERVICE_DATA_LEN); + if (g_capabilityData == NULL) { + DeinitLocalInfo(); + return SOFTBUS_MEM_ERR; + } + } + if (g_discCoapInnerCb == NULL) { + g_discCoapInnerCb = (DiscInnerCallback*)SoftBusCalloc(sizeof(DiscInnerCallback)); + if (g_discCoapInnerCb == NULL) { + DeinitLocalInfo(); + return SOFTBUS_MEM_ERR; + } + } + return SOFTBUS_OK; +} + +int32_t DiscNstackxInit(void) +{ + if (InitLocalInfo() != SOFTBUS_OK) { + return SOFTBUS_DISCOVER_COAP_INIT_FAIL; + } + if (NSTACKX_Init(&g_nstackxCallBack) != SOFTBUS_OK) { + DeinitLocalInfo(); + return SOFTBUS_DISCOVER_COAP_INIT_FAIL; + } + if (NSTACKX_RegisterDevice(g_localDeviceInfo) != SOFTBUS_OK) { + DiscNstackxDeinit(); + return SOFTBUS_DISCOVER_COAP_REGISTER_DEVICE_FAIL; + } + return SOFTBUS_OK; +} + +void DiscNstackxDeinit(void) +{ + NSTACKX_Deinit(); + DeinitLocalInfo(); +} \ No newline at end of file diff --git a/core/discovery/interface/disc_interface.h b/core/discovery/interface/disc_interface.h new file mode 100755 index 000000000..30e24c707 --- /dev/null +++ b/core/discovery/interface/disc_interface.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISC_MANAGER_INTERFACE_H +#define DISC_MANAGER_INTERFACE_H + +#include "discovery_service.h" +#include "stdint.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** + * @ingroup softbus_disc_manager + * Inner Module. + * + */ +typedef enum { + MODULE_MIN = 1, + MODULE_LNN = MODULE_MIN, + MODULE_CONN = 2, + MODULE_MAX = MODULE_CONN +} DiscModule; + +/** + * @ingroup softbus_disc_manager + * Inner publish info. + * + */ +typedef struct { + int publishId; + ExchanageMedium medium; + ExchangeFreq freq; + const char *capability; + unsigned char *capabilityData; + unsigned int dataLen; +} PublishInnerInfo; + +/** + * @ingroup softbus_disc_manager + * Inner subscribe info. + * + */ +typedef struct { + int subscribeId; + ExchanageMedium medium; + ExchangeFreq freq; + bool isSameAccount; + bool isWakeRemote; + const char *capability; + unsigned char *capabilityData; + unsigned int dataLen; +} SubscribeInnerInfo; + +/** + * @ingroup softbus_disc_manager + * Inner Callback. + * + */ +typedef struct { + void (*OnDeviceFound)(const DeviceInfo *device); +} DiscInnerCallback; + +/** + * @ingroup softbus_disc_manager + * @brief softbus discovery manager init + * + * @retval #SOFTBUS_ERR Create Softbus list failed. + * @retval #SOFTBUS_OK Manager is Successfully inited + * + */ +int32_t DiscMgrInit(void); + +/** + * @ingroup softbus_disc_manager + * @brief softbus discovery manager deinit + * + */ +void DiscMgrDeinit(void); + +/** + * @ingroup softbus_disc_manager + * @brief Subscribe inner callback update. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param initParam [IN] Type #DiscInnerCallback * update the callback of the module. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or cb. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_LOCK_ERR Mutex lock failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_PARAM Module not found. + * @retval #SOFTBUS_OK Subscribe inner callback update successfully. + * + */ +int32_t DiscSetDiscoverCallback(DiscModule moduleId, const DiscInnerCallback *cb); + +/** + * @ingroup softbus_disc_manager + * @brief Active publish. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param info [IN] Type #PublishInnerInfo * publish information. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE InfoNode create failed. + * @retval #SOFTBUS_MEM_ERR Memcpy failed. + * @retval #SOFTBUS_LOCK_ERR Mutex lock failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM Duplicate info. + * @retval #SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE ItemNode create failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Active publish successfully. + * + */ +int32_t DiscPublish(DiscModule moduleId, const PublishInnerInfo *info); + +/** + * @ingroup softbus_disc_manager + * @brief Passive publish. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param info [IN] Type #PublishInnerInfo * publish information. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE InfoNode create failed. + * @retval #SOFTBUS_MEM_ERR Memcpy failed. + * @retval #SOFTBUS_LOCK_ERR Mutex lock failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM Duplicate info. + * @retval #SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE ItemNode create failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Passive publish successfully. + * + */ +int32_t DiscStartScan(DiscModule moduleId, const PublishInnerInfo *info); + +/** + * @ingroup softbus_disc_manager + * @brief Stop publish. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param publishId [IN] Type #int32_t the publish ID which will be stopped. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE InfoNode delete failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Stop publish successfully. + * + */ +int32_t DiscUnpublish(DiscModule moduleId, int32_t publishId); + +/** + * @ingroup softbus_disc_manager + * @brief Active discover. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param info [IN] Type #SubscribeInnerInfo * discover information. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE InfoNode create failed. + * @retval #SOFTBUS_MEM_ERR Memcpy failed. + * @retval #SOFTBUS_LOCK_ERR Mutex lock failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM Duplicate info. + * @retval #SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE ItemNode create failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Active discover successfully. + * + */ +int32_t DiscStartAdvertise(DiscModule moduleId, const SubscribeInnerInfo *info); + +/** + * @ingroup softbus_disc_manager + * @brief Passive discover. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param info [IN] Type #SubscribeInnerInfo * discover information. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE InfoNode create failed. + * @retval #SOFTBUS_MEM_ERR Memcpy failed. + * @retval #SOFTBUS_LOCK_ERR Mutex lock failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM Duplicate info. + * @retval #SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE ItemNode create failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Passive discover successfully. + * + */ +int32_t DiscSubscribe(DiscModule moduleId, const SubscribeInnerInfo *info); + +/** + * @ingroup softbus_disc_manager + * @brief Stop discover. + * + * @param moduleId [IN] Type #DiscModule module ID. + * @param subscribeId [IN] Type #int32_t the discover ID which will be stopped. + * + * @retval #SOFTBUS_INVALID_PARAM Invalid moduleId or info parameter. + * @retval #SOFTBUS_DISCOVER_MANAGER_NOT_INIT Discovery manager is not initialised. + * @retval #SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE Module to string failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE InfoNode delete failed. + * @retval #SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL InnerFunction failed. + * @retval #SOFTBUS_OK Stop discover successfully. + * + */ +int32_t DiscStopAdvertise(DiscModule moduleId, int32_t subscribeId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* DISC_MANAGER_INTERFACE_H */ \ No newline at end of file diff --git a/core/discovery/manager/BUILD.gn b/core/discovery/manager/BUILD.gn new file mode 100755 index 000000000..374181e77 --- /dev/null +++ b/core/discovery/manager/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +shared_library("disc_manager") { + sources = [ "src/disc_manager.c" ] + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/core/discovery/interface", + "$dsoftbus_root_path/core/discovery/coap/include", + "$dsoftbus_root_path/core/discovery/manager/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-std=c99", + ] + ldflags = [ + "-lnstackx_ctrl", + "-lnstackx_util", + ] + deps = [ + "$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel", + "$dsoftbus_root_path/core/common/utils:softbus_utils", + "${dsoftbus_root_path}/core/discovery/coap:disc_coap_module", + "//third_party/bounds_checking_function:libsec_shared", + ] +} diff --git a/core/discovery/manager/include/disc_manager.h b/core/discovery/manager/include/disc_manager.h new file mode 100755 index 000000000..82daccaa3 --- /dev/null +++ b/core/discovery/manager/include/disc_manager.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISC_MANAGER_H +#define DISC_MANAGER_H + +#include "disc_interface.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define CAPABILITY_NUM 1 +#define CAPABILITY_MAX_BITNUM 7 + +typedef struct { + int32_t freq; + uint32_t capabilityBitmap[CAPABILITY_NUM]; + unsigned char *capabilityData; + uint32_t dataLen; +} PublishOption; + +typedef struct { + int32_t freq; + bool isSameAccount; + bool isWakeRemote; + uint32_t capabilityBitmap[CAPABILITY_NUM]; + unsigned char *capabilityData; + uint32_t dataLen; +} SubscribeOption; + +typedef struct { + int32_t (*Publish)(const PublishOption *option); + int32_t (*StartScan)(const PublishOption *option); + int32_t (*Unpublish)(const PublishOption *option); + int32_t (*StopScan)(const PublishOption *option); + int32_t (*StartAdvertise)(const SubscribeOption *option); + int32_t (*Subscribe)(const SubscribeOption *option); + int32_t (*Unsubscribe)(const SubscribeOption *option); + int32_t (*StopAdvertise)(const SubscribeOption *option); +} DiscoveryFuncInterface; + +typedef struct { + void (*OnServerPublishSuccess)(const char *packageName, int32_t publishId); + void (*OnServerPublishFail)(const char *packageName, int32_t publishId, PublishFailReason reason); +} IServerPublishCallback; + +typedef struct { + void (*OnServerDeviceFound)(const char *packageName, const DeviceInfo *device); + void (*OnServerDiscoverFailed)(const char *packageName, int32_t subscribeId, DiscoveryFailReason failReason); + void (*OnServerDiscoverySuccess)(const char *packageName, int32_t subscribeId); +} IServerDiscoveryCallback; + +void DiscOnDeviceFound(const DeviceInfo *device); +int32_t DiscPublishService(const char *packageName, const PublishInfo *info, const IServerPublishCallback *cb); +int32_t DiscUnPublishService(const char *packageName, int32_t publishId); +int32_t DiscStartDiscovery(const char *packageName, const SubscribeInfo *info, const IServerDiscoveryCallback *cb); +int32_t DiscStopDiscovery(const char *packageName, int32_t subscribeId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* DISC_MANAGER_H */ \ No newline at end of file diff --git a/core/discovery/manager/src/disc_manager.c b/core/discovery/manager/src/disc_manager.c new file mode 100755 index 000000000..96656097f --- /dev/null +++ b/core/discovery/manager/src/disc_manager.c @@ -0,0 +1,1251 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "disc_manager.h" +#include "common_list.h" +#include "disc_coap.h" +#include "securec.h" +#include "softbus.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +#define DISCOVERY_CB_LEN (sizeof(IServerDiscoveryCallback)) +#define PUBLISH_CB_LEN (sizeof(IServerPublishCallback)) + +static bool g_isInited = false; +static SoftBusList *g_publishInfoList = NULL; +static SoftBusList *g_discoveryInfoList = NULL; +static DiscInnerCallback g_discMgrMediumCb = { DiscOnDeviceFound }; +static DiscoveryFuncInterface *g_discCoapInterface = NULL; +static DiscoveryFuncInterface *g_discBleInterface = NULL; +static ListNode g_capabilityList[CAPABILITY_MAX_BITNUM]; +static const char *g_discModuleMap[] = { + "MODULE_LNN", + "MODULE_CONN", +}; + +typedef enum { + MIN_SERVICE = 0, + PUBLISH_SERVICE = MIN_SERVICE, + PUBLISH_INNER_SERVICE = 1, + SUBSCRIBE_SERVICE = 2, + SUBSCRIBE_INNER_SERVICE = 3, + MAX_SERVICE = SUBSCRIBE_INNER_SERVICE, +} ServiceType; + +typedef enum { + PUBLISH_FUNC = 0, + UNPUBLISH_FUNC = 1, + STARTDISCOVERTY_FUNC = 2, + STOPDISCOVERY_FUNC = 3 +} InterfaceFuncType; + +typedef union { + PublishOption publishOption; + SubscribeOption subscribeOption; +} InnerOption; + +typedef union { + IServerPublishCallback publishCb; + IServerDiscoveryCallback subscribeCb; + DiscInnerCallback innerCb; +} InnerCallback; + +typedef struct { + ListNode node; + char packageName[PKG_NAME_SIZE_MAX]; + InnerCallback callback; + uint32_t infoNum; + ListNode InfoList; +} DiscItem; + +typedef struct { + ListNode node; + int32_t id; + DiscoverMode mode; + ExchanageMedium medium; + InnerOption option; + ListNode capNode; + DiscItem *item; +} DiscInfo; + +void __attribute__ ((weak)) DiscBleDeinit(void) +{ + return; +} + +DiscoveryFuncInterface __attribute__ ((weak)) *DiscBleInit(DiscInnerCallback *bleCb) +{ + (void)bleCb; + return NULL; +} + +static void BitmapSet(uint32_t *bitMap, const uint32_t pos) +{ + if (bitMap == NULL || pos > CAPABILITY_MAX_BITNUM) { + return; + } + *bitMap |= 1U << pos; +} + +static bool IsBitmapSet(uint32_t *bitMap, const uint32_t pos) +{ + if (bitMap == NULL || pos > CAPABILITY_MAX_BITNUM) { + return false; + } + bool flag = ((1U << pos) & (*bitMap)) ? true : false; + return flag; +} + +static int32_t DiscInterfaceProcess(const InnerOption *option, const DiscoveryFuncInterface *interface, + const DiscoverMode mode, InterfaceFuncType type) +{ + if (interface == NULL) { + return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL; + } + + switch (type) { + case PUBLISH_FUNC: + return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Publish(&(option->publishOption))) : + (interface->StartScan(&(option->publishOption)))); + case UNPUBLISH_FUNC: + return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Unpublish(&(option->publishOption))) : + (interface->StopScan(&(option->publishOption)))); + case STARTDISCOVERTY_FUNC: + return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StartAdvertise(&(option->subscribeOption))) : + (interface->Subscribe(&(option->subscribeOption)))); + case STOPDISCOVERY_FUNC: + return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StopAdvertise(&(option->subscribeOption))) : + (interface->Unsubscribe(&(option->subscribeOption)))); + default: + return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL; + } +} + +static int32_t DiscInterfaceByMedium(const DiscInfo *info, const InterfaceFuncType type) +{ + switch (info->medium) { + case BLE: + return DiscInterfaceProcess(&(info->option), g_discBleInterface, info->mode, type); + case COAP: + return DiscInterfaceProcess(&(info->option), g_discCoapInterface, info->mode, type); + case AUTO: { + int32_t ret1 = DiscInterfaceProcess(&(info->option), g_discBleInterface, info->mode, type); + int32_t ret2 = DiscInterfaceProcess(&(info->option), g_discCoapInterface, info->mode, type); + if ((ret1 == SOFTBUS_OK) || (ret2 == SOFTBUS_OK)) { + return SOFTBUS_OK; + } + return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL; + } + default: + return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL; + } +} + +static int32_t CapabilityStringToBimap(const char *capability) +{ + for (int32_t i = 0; i < CAPABILITY_MAX_BITNUM; i++) { + if (strcmp(capability, g_capabilityMap[i].capability) == 0) { + return g_capabilityMap[i].bitmap; + } + } + return SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID; +} + +static void AddInfoToCapability(DiscInfo *info, const ServiceType type) +{ + if ((type != SUBSCRIBE_SERVICE) && (type != SUBSCRIBE_INNER_SERVICE)) { + return; + } + + uint32_t tmp; + for (tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) { + if (IsBitmapSet(&(info->option.subscribeOption.capabilityBitmap[0]), tmp) == true) { + break; + } + } + + if (type == SUBSCRIBE_INNER_SERVICE) { + ListNodeInsert(&(g_capabilityList[tmp]), &(info->capNode)); + } + + if (type == SUBSCRIBE_SERVICE) { + ListTailInsert(&(g_capabilityList[tmp]), &(info->capNode)); + } + + return; +} + +static void DeleteInfoFromCapability(DiscInfo *info, const ServiceType type) +{ + if ((type != SUBSCRIBE_SERVICE) && (type != SUBSCRIBE_INNER_SERVICE)) { + return; + } + ListDelete(&(info->capNode)); + return; +} + +static void ReleaseInfoNodeMem(DiscInfo *info, const ServiceType type) +{ + if ((type < MIN_SERVICE) || (type > MAX_SERVICE)) { + LOG_ERR("type erro"); + return; + } + if ((type == PUBLISH_SERVICE) || (type == PUBLISH_INNER_SERVICE)) { + SoftBusFree(info->option.publishOption.capabilityData); + } + + if ((type == SUBSCRIBE_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) { + SoftBusFree(info->option.subscribeOption.capabilityData); + } + SoftBusFree(info); + return; +} + +static void InnerDeviceFound(const DiscInfo *infoNode, const DeviceInfo *device) +{ + uint32_t tmp; + bool isInnerInfo = false; + for (tmp = 0; tmp < MODULE_MAX; tmp++) { + if (strcmp(infoNode->item->packageName, g_discModuleMap[tmp]) != 0) { + continue; + } + isInnerInfo = true; + } + if (isInnerInfo == false) { + infoNode->item->callback.subscribeCb.OnServerDeviceFound(infoNode->item->packageName, device); + return; + } + if (infoNode->item->callback.innerCb.OnDeviceFound == NULL) { + LOG_ERR("OnDeviceFound not regist"); + return; + } + infoNode->item->callback.innerCb.OnDeviceFound(device); +} + +void DiscOnDeviceFound(const DeviceInfo *device) +{ + uint32_t tmp; + DiscInfo *infoNode = NULL; + for (tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) { + if (IsBitmapSet((uint32_t *)&(device->capabilityBitmap[0]), tmp) == false) { + continue; + } + LIST_FOR_EACH_ENTRY(infoNode, &(g_capabilityList[tmp]), DiscInfo, capNode) { + LOG_INFO("find callback:id = %d", infoNode->id); + InnerDeviceFound(infoNode, device); + } + } + return; +} + +static int32_t UpdateItemCallback(DiscItem *item, const InnerCallback *cb, const ServiceType type) +{ + if ((type != PUBLISH_SERVICE) && (type != SUBSCRIBE_SERVICE)) { + return SOFTBUS_OK; + } + + if ((type == PUBLISH_SERVICE) && + (memcpy_s(&(item->callback.publishCb), PUBLISH_CB_LEN, cb, PUBLISH_CB_LEN) != EOK)) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_MEM_ERR; + } + if ((type == SUBSCRIBE_SERVICE) && + (memcpy_s(&(item->callback.subscribeCb), DISCOVERY_CB_LEN, cb, DISCOVERY_CB_LEN) != EOK)) { + LOG_ERR("memcpy_s failed"); + return SOFTBUS_MEM_ERR; + } + return SOFTBUS_OK; +} + +static int32_t PublishInfoCheck(const char *packageName, const PublishInfo *info) +{ + if (strlen(packageName) >= PKG_NAME_SIZE_MAX) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->mode != DISCOVER_MODE_PASSIVE) && (info->mode != DISCOVER_MODE_ACTIVE)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->medium < AUTO) || (info->medium > COAP)) { + return SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static int32_t PublishInnerInfoCheck(const PublishInnerInfo *info) +{ + if ((info->medium < AUTO) || (info->medium > COAP)) { + return SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static int32_t SubscribeInfoCheck(const char *packageName, const SubscribeInfo *info) +{ + if (strlen(packageName) >= PKG_NAME_SIZE_MAX) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->mode != DISCOVER_MODE_PASSIVE) && (info->mode != DISCOVER_MODE_ACTIVE)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->medium < AUTO) || (info->medium > COAP)) { + return SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static int32_t SubscribeInnerInfoCheck(const SubscribeInnerInfo *info) +{ + if ((info->medium < AUTO) || (info->medium > COAP)) { + return SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static DiscItem *CreateNewItem(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb, + const ServiceType type) +{ + if ((type < MIN_SERVICE) || (type > MAX_SERVICE)) { + LOG_ERR("type erro"); + return NULL; + } + DiscItem *itemNode = (DiscItem *)SoftBusCalloc(sizeof(DiscItem)); + if (itemNode == NULL) { + LOG_ERR("calloc itemNode failed"); + return NULL; + } + itemNode->infoNum = 0; + if ((type == PUBLISH_INNER_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) { + ListNodeInsert(&(serviceList->list), &(itemNode->node)); + } + + if ((type == PUBLISH_SERVICE) || (type == SUBSCRIBE_SERVICE)) { + ListTailInsert(&(serviceList->list), &(itemNode->node)); + } + if ((type == PUBLISH_SERVICE) && + ((memcpy_s(&(itemNode->callback.publishCb), PUBLISH_CB_LEN, cb, PUBLISH_CB_LEN) != EOK) || + (memcpy_s(itemNode->packageName, PKG_NAME_SIZE_MAX, packageName, PKG_NAME_SIZE_MAX) != EOK))) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(itemNode); + return NULL; + } + if ((type == SUBSCRIBE_SERVICE) && + ((memcpy_s(&(itemNode->callback.subscribeCb), DISCOVERY_CB_LEN, cb, DISCOVERY_CB_LEN) != EOK) || + (memcpy_s(itemNode->packageName, PKG_NAME_SIZE_MAX, packageName, PKG_NAME_SIZE_MAX) != EOK))) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(itemNode); + return NULL; + } + if (((type == PUBLISH_INNER_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) && + (memcpy_s(itemNode->packageName, PKG_NAME_SIZE_MAX, packageName, PKG_NAME_SIZE_MAX) != EOK)) { + LOG_ERR("memcpy_s failed"); + SoftBusFree(itemNode); + return NULL; + } + if (type == SUBSCRIBE_INNER_SERVICE) { + itemNode->callback.innerCb.OnDeviceFound = cb->innerCb.OnDeviceFound; + } + serviceList->cnt++; + ListInit(&(itemNode->InfoList)); + return itemNode; +} + +static DiscInfo *CreateNewPublishInfoNode(const PublishInfo *info) +{ + int32_t ret; + DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo)); + if (infoNode == NULL) { + LOG_ERR("calloc infoNode failed"); + return NULL; + } + ListInit(&(infoNode->node)); + ListInit(&(infoNode->capNode)); + infoNode->item = NULL; + infoNode->id = info->publishId; + infoNode->medium = info->medium; + infoNode->mode = info->mode; + infoNode->option.publishOption.freq = info->freq; + infoNode->option.publishOption.dataLen = info->dataLen; + infoNode->option.publishOption.capabilityData = + (unsigned char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN * sizeof(unsigned char)); + if (infoNode->option.publishOption.capabilityData == NULL) { + LOG_ERR("calloc capabilityData failed"); + SoftBusFree(infoNode); + return NULL; + } + if ((info->dataLen != 0) && (memcpy_s(infoNode->option.publishOption.capabilityData, MAX_CAPABILITYDATA_LEN, + info->capabilityData, info->dataLen) != EOK)) { + LOG_ERR("memcpy_s fail"); + ReleaseInfoNodeMem(infoNode, PUBLISH_SERVICE); + return NULL; + } + ret = CapabilityStringToBimap(info->capability); + if (ret < 0) { + LOG_ERR("capability not found"); + ReleaseInfoNodeMem(infoNode, PUBLISH_SERVICE); + return NULL; + } + BitmapSet(&(infoNode->option.publishOption.capabilityBitmap[0]), ret); + return infoNode; +} + +static DiscInfo *CreateNewSubscribeInfoNode(const SubscribeInfo *info) +{ + int32_t ret; + DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo)); + if (infoNode == NULL) { + LOG_ERR("calloc infoNode failed"); + return NULL; + } + ListInit(&(infoNode->node)); + ListInit(&(infoNode->capNode)); + infoNode->item = NULL; + infoNode->id = info->subscribeId; + infoNode->medium = info->medium; + infoNode->mode = info->mode; + infoNode->option.subscribeOption.freq = info->freq; + infoNode->option.subscribeOption.dataLen = info->dataLen; + infoNode->option.subscribeOption.isSameAccount = info->isSameAccount; + infoNode->option.subscribeOption.isWakeRemote = info->isWakeRemote; + infoNode->option.subscribeOption.capabilityData = + (unsigned char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN * sizeof(unsigned char)); + if (infoNode->option.subscribeOption.capabilityData == NULL) { + LOG_ERR("calloc capabilityData failed"); + SoftBusFree(infoNode); + return NULL; + } + if ((info->dataLen != 0) && (memcpy_s(infoNode->option.subscribeOption.capabilityData, MAX_CAPABILITYDATA_LEN, + info->capabilityData, info->dataLen) != EOK)) { + LOG_ERR("memcpy_s fail"); + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_SERVICE); + return NULL; + } + ret = CapabilityStringToBimap(info->capability); + if (ret < 0) { + LOG_ERR("capability not found"); + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_SERVICE); + return NULL; + } + BitmapSet(&(infoNode->option.subscribeOption.capabilityBitmap[0]), ret); + return infoNode; +} + +static DiscInfo *CreateNewPublishInnerInfoNode(const PublishInnerInfo *info, const DiscoverMode mode) +{ + int32_t ret; + DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo)); + if (infoNode == NULL) { + LOG_ERR("calloc infoNode failed"); + return NULL; + } + ListInit(&(infoNode->node)); + ListInit(&(infoNode->capNode)); + infoNode->item = NULL; + infoNode->id = info->publishId; + infoNode->medium = info->medium; + infoNode->mode = mode; + infoNode->option.publishOption.freq = info->freq; + infoNode->option.publishOption.dataLen = info->dataLen; + infoNode->option.publishOption.capabilityData = + (unsigned char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN * sizeof(unsigned char)); + if (infoNode->option.publishOption.capabilityData == NULL) { + LOG_ERR("calloc capabilityData failed"); + SoftBusFree(infoNode); + return NULL; + } + if ((info->dataLen != 0) && (memcpy_s(infoNode->option.publishOption.capabilityData, MAX_CAPABILITYDATA_LEN, + info->capabilityData, info->dataLen) != EOK)) { + LOG_ERR("memcpy_s fail"); + ReleaseInfoNodeMem(infoNode, PUBLISH_SERVICE); + return NULL; + } + ret = CapabilityStringToBimap(info->capability); + if (ret < 0) { + LOG_ERR("capability not found"); + ReleaseInfoNodeMem(infoNode, PUBLISH_SERVICE); + return NULL; + } + BitmapSet(&(infoNode->option.publishOption.capabilityBitmap[0]), ret); + return infoNode; +} + +static DiscInfo *CreateNewSubscribeInnerInfoNode(const SubscribeInnerInfo *info, const DiscoverMode mode) +{ + int32_t ret; + DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo)); + if (infoNode == NULL) { + LOG_ERR("calloc infoNode failed"); + return NULL; + } + ListInit(&(infoNode->node)); + ListInit(&(infoNode->capNode)); + infoNode->item = NULL; + infoNode->id = info->subscribeId; + infoNode->medium = info->medium; + infoNode->mode = mode; + infoNode->option.subscribeOption.freq = info->freq; + infoNode->option.subscribeOption.dataLen = info->dataLen; + infoNode->option.subscribeOption.isSameAccount = info->isSameAccount; + infoNode->option.subscribeOption.isWakeRemote = info->isWakeRemote; + infoNode->option.subscribeOption.capabilityData = + (unsigned char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN * sizeof(unsigned char)); + if (infoNode->option.subscribeOption.capabilityData == NULL) { + LOG_ERR("calloc capabilityData failed"); + SoftBusFree(infoNode); + return NULL; + } + if ((info->dataLen != 0) && (memcpy_s(infoNode->option.subscribeOption.capabilityData, MAX_CAPABILITYDATA_LEN, + info->capabilityData, info->dataLen) != EOK)) { + LOG_ERR("memcpy_s fail"); + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_SERVICE); + return NULL; + } + ret = CapabilityStringToBimap(info->capability); + if (ret < 0) { + LOG_ERR("capability not found"); + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_SERVICE); + return NULL; + } + BitmapSet(&(infoNode->option.subscribeOption.capabilityBitmap[0]), ret); + return infoNode; +} + +static int32_t AddInfoToList(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb, + DiscInfo *info, const ServiceType type) +{ + bool isPackageNameExist = false; + DiscItem *itemNode = NULL; + DiscInfo *infoNode = NULL; + + if (pthread_mutex_lock(&(serviceList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + + LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) { + if (strcmp(itemNode->packageName, packageName) != 0) { + continue; + } + LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) { + if (infoNode->id == info->id) { + LOG_INFO("id already exsisted"); + (void)pthread_mutex_unlock(&(serviceList->lock)); + return SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM; + } + } + if (UpdateItemCallback(itemNode, cb, type) != SOFTBUS_OK) { + LOG_ERR("update item fail"); + (void)pthread_mutex_unlock(&(serviceList->lock)); + return SOFTBUS_MEM_ERR; + } + isPackageNameExist = true; + itemNode->infoNum++; + info->item = itemNode; + ListTailInsert(&(itemNode->InfoList), &(info->node)); + AddInfoToCapability(info, type); + break; + } + + if (isPackageNameExist == false) { + itemNode = CreateNewItem(serviceList, packageName, cb, type); + if (itemNode == NULL) { + LOG_ERR("itemNode create failed"); + (void)pthread_mutex_unlock(&(serviceList->lock)); + return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE; + } + itemNode->infoNum++; + info->item = itemNode; + ListTailInsert(&(itemNode->InfoList), &(info->node)); + AddInfoToCapability(info, type); + } + (void)pthread_mutex_unlock(&(serviceList->lock)); + return SOFTBUS_OK; +} + +static DiscInfo *DeleteInfoFromList(SoftBusList *serviceList, const char *packageName, const int32_t id, + const ServiceType type) +{ + if (pthread_mutex_lock(&(serviceList->lock)) != 0) { + LOG_ERR("lock failed"); + return NULL; + } + + bool isIdExist = false; + DiscItem *itemNode = NULL; + DiscInfo *infoNode = NULL; + + LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) { + if (strcmp(itemNode->packageName, packageName) != 0) { + continue; + } + LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) { + if (infoNode->id != id) { + continue; + } + isIdExist = true; + itemNode->infoNum--; + DeleteInfoFromCapability(infoNode, type); + ListDelete(&(infoNode->node)); + if (itemNode->infoNum == 0) { + serviceList->cnt--; + ListDelete(&(itemNode->node)); + SoftBusFree(itemNode); + } + break; + } + break; + } + (void)pthread_mutex_unlock(&(serviceList->lock)); + if (isIdExist == false) { + LOG_INFO("can not find publishId"); + return NULL; + } + return infoNode; +} + +static int32_t InnerPublishService(const char *packageName, DiscInfo *info, const IServerPublishCallback *cb, + const ServiceType type) +{ + int32_t ret; + InnerCallback callback; + + if ((cb != NULL) && + (memcpy_s(&(callback.publishCb), PUBLISH_CB_LEN, cb, PUBLISH_CB_LEN) != EOK)) { + LOG_ERR("memcpy_s erro"); + return SOFTBUS_MEM_ERR; + } + + ret = AddInfoToList(g_publishInfoList, packageName, &callback, info, type); + if (ret != SOFTBUS_OK) { + LOG_ERR("add list fail"); + return ret; + } + ret = DiscInterfaceByMedium(info, PUBLISH_FUNC); + if (ret != SOFTBUS_OK) { + LOG_ERR("interface fail"); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t InnerUnPublishService(const char *packageName, int32_t publishId, const ServiceType type) +{ + DiscInfo *infoNode = DeleteInfoFromList(g_publishInfoList, packageName, publishId, type); + if (infoNode == NULL) { + LOG_ERR("delete list fail"); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE; + } + + int32_t ret = DiscInterfaceByMedium(infoNode, UNPUBLISH_FUNC); + if (ret != SOFTBUS_OK) { + LOG_ERR("interface fail"); + return ret; + } + ReleaseInfoNodeMem(infoNode, type); + return SOFTBUS_OK; +} + +static int32_t InnerStartDiscovery(const char *packageName, DiscInfo *info, const IServerDiscoveryCallback *cb, + const ServiceType type) +{ + int32_t ret; + InnerCallback callback; + + if ((cb != NULL) && + (memcpy_s(&(callback.subscribeCb), DISCOVERY_CB_LEN, cb, DISCOVERY_CB_LEN) != EOK)) { + LOG_ERR("memcpy_s erro"); + return SOFTBUS_MEM_ERR; + } + + if (type == SUBSCRIBE_INNER_SERVICE) { + callback.innerCb.OnDeviceFound = NULL; + } + + ret = AddInfoToList(g_discoveryInfoList, packageName, &callback, info, type); + if (ret != SOFTBUS_OK) { + LOG_ERR("add list fail"); + return ret; + } + + ret = DiscInterfaceByMedium(info, STARTDISCOVERTY_FUNC); + if (ret != SOFTBUS_OK) { + LOG_ERR("interface fail"); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t InnerStopDiscovery(const char *packageName, int32_t subscribeId, const ServiceType type) +{ + DiscInfo *infoNode = DeleteInfoFromList(g_discoveryInfoList, packageName, subscribeId, type); + if (infoNode == NULL) { + LOG_ERR("delete list fail"); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE; + } + + int32_t ret = DiscInterfaceByMedium(infoNode, STOPDISCOVERY_FUNC); + if (ret != SOFTBUS_OK) { + LOG_ERR("interface erro"); + return ret; + } + ReleaseInfoNodeMem(infoNode, type); + return SOFTBUS_OK; +} + +static char *ModuleIdToPackageName(DiscModule moduleId) +{ + char *packageName = (char *)SoftBusCalloc(PKG_NAME_SIZE_MAX * sizeof(char)); + if (packageName == NULL) { + LOG_ERR("calloc fail"); + return NULL; + } + int32_t ret = memcpy_s(packageName, PKG_NAME_SIZE_MAX, g_discModuleMap[(moduleId - 1)], PKG_NAME_SIZE_MAX); + if (ret != EOK) { + SoftBusFree(packageName); + LOG_ERR("memcpy_s fail"); + return NULL; + } + return packageName; +} + +static int32_t InnerSetDiscoverCallback(const char *packageName, const DiscInnerCallback *cb) +{ + if (pthread_mutex_lock(&(g_discoveryInfoList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + + bool isIdExist = false; + DiscItem *itemNode = NULL; + InnerCallback callback; + LIST_FOR_EACH_ENTRY(itemNode, &(g_discoveryInfoList->list), DiscItem, node) { + if (strcmp(itemNode->packageName, packageName) != 0) { + continue; + } + itemNode->callback.innerCb.OnDeviceFound = cb->OnDeviceFound; + isIdExist = true; + break; + } + if (isIdExist == false) { + callback.innerCb.OnDeviceFound = cb->OnDeviceFound; + itemNode = CreateNewItem(g_discoveryInfoList, packageName, &callback, SUBSCRIBE_INNER_SERVICE); + if (itemNode == NULL) { + LOG_ERR("itemNode create failed"); + (void)pthread_mutex_unlock(&(g_discoveryInfoList->lock)); + return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE; + } + } + (void)pthread_mutex_unlock(&(g_discoveryInfoList->lock)); + return SOFTBUS_OK; +} + +int32_t DiscSetDiscoverCallback(DiscModule moduleId, const DiscInnerCallback *cb) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX) || (cb == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE; + } + + int32_t ret = InnerSetDiscoverCallback(packageName, cb); + if (ret != SOFTBUS_OK) { + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscPublish(DiscModule moduleId, const PublishInnerInfo *info) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX) || (info == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (PublishInnerInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE; + } + + DiscInfo *infoNode = CreateNewPublishInnerInfoNode(info, DISCOVER_MODE_ACTIVE); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + SoftBusFree(packageName); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + } + + int32_t ret = InnerPublishService(packageName, infoNode, NULL, PUBLISH_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + SoftBusFree(packageName); + ReleaseInfoNodeMem(infoNode, PUBLISH_INNER_SERVICE); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscStartScan(DiscModule moduleId, const PublishInnerInfo *info) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX) || (info == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (PublishInnerInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE; + } + + DiscInfo *infoNode = CreateNewPublishInnerInfoNode(info, DISCOVER_MODE_PASSIVE); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + SoftBusFree(packageName); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + } + + int32_t ret = InnerPublishService(packageName, infoNode, NULL, PUBLISH_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + ReleaseInfoNodeMem(infoNode, PUBLISH_INNER_SERVICE); + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscUnpublish(DiscModule moduleId, int32_t publishId) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE; + } + + int32_t ret = InnerUnPublishService(packageName, publishId, PUBLISH_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscStartAdvertise(DiscModule moduleId, const SubscribeInnerInfo *info) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX) || (info == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (SubscribeInnerInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_MODULE; + } + + DiscInfo *infoNode = CreateNewSubscribeInnerInfoNode(info, DISCOVER_MODE_ACTIVE); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + SoftBusFree(packageName); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + } + + int32_t ret = InnerStartDiscovery(packageName, infoNode, NULL, SUBSCRIBE_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_INNER_SERVICE); + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscSubscribe(DiscModule moduleId, const SubscribeInnerInfo *info) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX) || (info == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (SubscribeInnerInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_PKGNAME; + } + + DiscInfo *infoNode = CreateNewSubscribeInnerInfoNode(info, DISCOVER_MODE_PASSIVE); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + SoftBusFree(packageName); + return SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + } + + int32_t ret = InnerStartDiscovery(packageName, infoNode, NULL, SUBSCRIBE_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_INNER_SERVICE); + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscStopAdvertise(DiscModule moduleId, int32_t subscribeId) +{ + if ((moduleId < MODULE_MIN) || (moduleId > MODULE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + char *packageName = ModuleIdToPackageName(moduleId); + if (packageName == NULL) { + LOG_ERR("packageName get fail"); + return SOFTBUS_DISCOVER_MANAGER_INVALID_PKGNAME; + } + int32_t ret = InnerStopDiscovery(packageName, subscribeId, SUBSCRIBE_INNER_SERVICE); + if (ret != SOFTBUS_OK) { + SoftBusFree(packageName); + return ret; + } + SoftBusFree(packageName); + return SOFTBUS_OK; +} + +int32_t DiscPublishService(const char *packageName, const PublishInfo *info, const IServerPublishCallback *cb) +{ + int32_t ret; + + if ((packageName == NULL) || (info == NULL) || (cb == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + ret = PublishInfoCheck(packageName, info); + if (ret != SOFTBUS_OK) { + goto EXIT; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + ret = SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + goto EXIT; + } + + DiscInfo *infoNode = CreateNewPublishInfoNode(info); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + ret = SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + goto EXIT; + } + + ret = InnerPublishService(packageName, infoNode, cb, PUBLISH_SERVICE); + if (ret != SOFTBUS_OK) { + ReleaseInfoNodeMem(infoNode, PUBLISH_SERVICE); + goto EXIT; + } + cb->OnServerPublishSuccess(packageName, info->publishId); + return SOFTBUS_OK; +EXIT: + if (ret == SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM) { + cb->OnServerPublishFail(packageName, info->publishId, PUBLISH_FAIL_REASON_NOT_SUPPORT_MEDIUM); + return ret; + } + cb->OnServerPublishFail(packageName, info->publishId, PUBLISH_FAIL_REASON_INTERNAL); + return ret; +} + +int32_t DiscUnPublishService(const char *packageName, int32_t publishId) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + int32_t ret = InnerUnPublishService(packageName, publishId, PUBLISH_SERVICE); + if (ret != SOFTBUS_OK) { + return ret; + } + return SOFTBUS_OK; +} + +int32_t DiscStartDiscovery(const char *packageName, const SubscribeInfo *info, const IServerDiscoveryCallback *cb) +{ + int32_t ret; + + if ((packageName == NULL) || (info == NULL) || (cb == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + ret = SubscribeInfoCheck(packageName, info); + if (ret != SOFTBUS_OK) { + goto EXIT; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + ret = SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + goto EXIT; + } + + DiscInfo *infoNode = CreateNewSubscribeInfoNode(info); + if (infoNode == NULL) { + LOG_ERR("infoNode create failed"); + ret = SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE; + goto EXIT; + } + + ret = InnerStartDiscovery(packageName, infoNode, cb, SUBSCRIBE_SERVICE); + if (ret != SOFTBUS_OK) { + ReleaseInfoNodeMem(infoNode, SUBSCRIBE_SERVICE); + goto EXIT; + } + cb->OnServerDiscoverySuccess(packageName, info->subscribeId); + return SOFTBUS_OK; +EXIT: + if (ret == SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM) { + cb->OnServerDiscoverFailed(packageName, info->subscribeId, DISCOVERY_FAIL_REASON_NOT_SUPPORT_MEDIUM); + return ret; + } + cb->OnServerDiscoverFailed(packageName, info->subscribeId, DISCOVERY_FAIL_REASON_INTERNAL); + return ret; +} + +int32_t DiscStopDiscovery(const char *packageName, int32_t subscribeId) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_MANAGER_NOT_INIT; + } + + int32_t ret = InnerStopDiscovery(packageName, subscribeId, SUBSCRIBE_SERVICE); + if (ret != SOFTBUS_OK) { + return ret; + } + return SOFTBUS_OK; +} + +int32_t DiscMgrInit(void) +{ + if (g_isInited) { + return SOFTBUS_OK; + } + + g_discCoapInterface = DiscCoapInit(&g_discMgrMediumCb); + g_discBleInterface = DiscBleInit(&g_discMgrMediumCb); + if ((g_discCoapInterface == NULL) && (g_discBleInterface == NULL)) { + LOG_ERR("medium init all fail"); + return SOFTBUS_ERR; + } + + g_publishInfoList = CreateSoftBusList(); + g_discoveryInfoList = CreateSoftBusList(); + if ((g_publishInfoList == NULL) || (g_discoveryInfoList == NULL)) { + LOG_ERR("init service info list fail"); + return SOFTBUS_ERR; + } + + for (int32_t i = 0; i < CAPABILITY_MAX_BITNUM; i++) { + ListInit(&g_capabilityList[i]); + } + + g_isInited = true; + LOG_INFO("init success"); + return SOFTBUS_OK; +} + +static void DiscMgrInfoListDeinit(SoftBusList *itemList, const ServiceType type) +{ + DiscItem *itemNode = NULL; + DiscItem *itemNodeNext = NULL; + DiscInfo *infoNode = NULL; + DiscInfo *infoNodeNext = NULL; + + if (pthread_mutex_lock(&(itemList->lock)) != 0) { + LOG_ERR("lock failed"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(itemNode, itemNodeNext, &(itemList->list), DiscItem, node) { + LIST_FOR_EACH_ENTRY_SAFE(infoNode, infoNodeNext, &(itemNode->InfoList), DiscInfo, node) { + ListDelete(&(infoNode->node)); + DeleteInfoFromCapability(infoNode, type); + ReleaseInfoNodeMem(infoNode, type); + } + itemList->cnt--; + ListDelete(&(itemNode->node)); + SoftBusFree(itemNode); + } + (void)pthread_mutex_unlock(&(itemList->lock)); + DestroySoftBusList(itemList); +} + +void DiscMgrDeinit(void) +{ + if (g_isInited == false) { + return; + } + DiscMgrInfoListDeinit(g_publishInfoList, PUBLISH_SERVICE); + DiscMgrInfoListDeinit(g_discoveryInfoList, SUBSCRIBE_SERVICE); + g_publishInfoList = NULL; + g_discoveryInfoList = NULL; + g_discCoapInterface = NULL; + g_discBleInterface = NULL; + DiscCoapDeinit(); + DiscBleDeinit(); + g_isInited = false; +} diff --git a/core/discovery/service/include/softbus_disc_server.h b/core/discovery/service/include/softbus_disc_server.h new file mode 100755 index 000000000..ff8edd7f9 --- /dev/null +++ b/core/discovery/service/include/softbus_disc_server.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_DISC_SERVER_H +#define SOFTBUS_DISC_SERVER_H + +#include "disc_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int32_t DiscIpcPublishService(const char *packageName, const PublishInfo *info); +int32_t DiscIpcUnPublishService(const char *packageName, int32_t publishId); +int32_t DiscIpcStartDiscovery(const char *packageName, const SubscribeInfo *info); +int32_t DiscIpcStopDiscovery(const char *packageName, int32_t subscribeId); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SOFTBUS_DISC_SERVER_H */ diff --git a/core/discovery/service/src/softbus_disc_server.c b/core/discovery/service/src/softbus_disc_server.c new file mode 100755 index 000000000..7a610b202 --- /dev/null +++ b/core/discovery/service/src/softbus_disc_server.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_disc_server.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_permission.h" +#include "softbus_server_frame.h" + +int32_t DiscServerInit(void) +{ + int32_t ret = DiscMgrInit(); + if (ret != SOFTBUS_OK) { + LOG_ERR("DiscServerInit failed"); + return ret; + } + return SOFTBUS_OK; +} + +void DiscServerDeinit(void) +{ + DiscMgrDeinit(); +} + +int32_t DiscIpcPublishService(const char *packageName, const PublishInfo *info) +{ + if (CheckDiscPermission(packageName) != true) { + LOG_ERR("ServerPublishService no permission!"); + return SOFTBUS_DISCOVER_SERVER_NO_PERMISSION; + } + IServerPublishCallback callback; + callback.OnServerPublishSuccess = (void *)(GetClientProvideInterface()->onPublishSuccess); + callback.OnServerPublishFail = (void *)(GetClientProvideInterface()->onPublishFail); + int32_t ret = DiscPublishService(packageName, info, &callback); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerPublishService failed"); + return ret; + } + LOG_INFO("ServerPublishService success!"); + return SOFTBUS_OK; +} + +int32_t DiscIpcUnPublishService(const char *packageName, int32_t publishId) +{ + if (CheckDiscPermission(packageName) != true) { + LOG_ERR("ServerUnPublishService no permission!"); + return SOFTBUS_DISCOVER_SERVER_NO_PERMISSION; + } + int32_t ret = DiscUnPublishService(packageName, publishId); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerUnPublishService failed"); + return ret; + } + LOG_INFO("ServerUnPublishService success!"); + return SOFTBUS_OK; +} + +int32_t DiscIpcStartDiscovery(const char *packageName, const SubscribeInfo *info) +{ + if (CheckDiscPermission(packageName) != true) { + LOG_ERR("ServerStartDiscovery no permission!"); + return SOFTBUS_DISCOVER_SERVER_NO_PERMISSION; + } + IServerDiscoveryCallback callback; + callback.OnServerDeviceFound = (void *)(GetClientProvideInterface()->onDeviceFound); + callback.OnServerDiscoverySuccess = (void *)(GetClientProvideInterface()->onDiscoverySuccess); + callback.OnServerDiscoverFailed = (void *)(GetClientProvideInterface()->onDiscoverFailed); + int32_t ret = DiscStartDiscovery(packageName, info, &callback); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerStartDiscovery failed"); + return ret; + } + LOG_INFO("ServerStartDiscovery success!"); + return SOFTBUS_OK; +} + +int32_t DiscIpcStopDiscovery(const char *packageName, int32_t subscribeId) +{ + if (CheckDiscPermission(packageName) != true) { + LOG_ERR("ServerStopDiscovery no permission!"); + return SOFTBUS_DISCOVER_SERVER_NO_PERMISSION; + } + int32_t ret = DiscStopDiscovery(packageName, subscribeId); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerStopDiscovery failed"); + return ret; + } + LOG_INFO("ServerStopDiscovery success!"); + return SOFTBUS_OK; +} diff --git a/core/frame/lite/BUILD.gn b/core/frame/lite/BUILD.gn new file mode 100755 index 000000000..6d34cba2c --- /dev/null +++ b/core/frame/lite/BUILD.gn @@ -0,0 +1,78 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_server_frame") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/sdk/bus_center/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + sources = [ + "$dsoftbus_root_path/core/common/inner_communication/c/softbus_client_interface.c", + "$dsoftbus_root_path/core/common/inner_communication/c/softbus_server_interface_impl.c", + "src/softbus_server_frame.c", + "src/softbus_server_frame_weak.c", + ] + } +} else { + shared_library("softbus_server_frame") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/inner_communication/ipc/include", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/sdk/bus_center/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "//utils/native/lite/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + sources = [ + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_client_interface.c", + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_server_interface_impl.c", + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_server_weak.c", + "src/softbus_client_info_manager.c", + "src/softbus_server_frame.c", + "src/softbus_server_frame_weak.c", + ] + + deps = [ + "$dsoftbus_root_path/core/adapter/kernel:softbus_adapter_kernel", + "$dsoftbus_root_path/core/common/message_handler:message_handler", + "$dsoftbus_root_path/core/common/utils:softbus_utils", + "//foundation/communication/ipc_lite:liteipc", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + ] + } +} diff --git a/core/frame/lite/include/softbus_client_info_manager.h b/core/frame/lite/include/softbus_client_info_manager.h new file mode 100644 index 000000000..e185cfa6d --- /dev/null +++ b/core/frame/lite/include/softbus_client_info_manager.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_INFO_MANAGER_H +#define SOFTBUS_CLIENT_INFO_MANAGER_H + +#include +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + SoftBusList *clientInfoList; +} SoftBusClientMgr; + +SoftBusClientMgr *SERVER_InitClient(void); + +int SERVER_RegisterService(const char *name, const struct CommonScvId *svcId); + +int SERVER_GetIdentityByPkgName(const char *name, struct CommonScvId *svcId); + +int SERVER_UnregisterService(const char *name); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/core/frame/lite/include/softbus_server_frame.h b/core/frame/lite/include/softbus_server_frame.h new file mode 100644 index 000000000..1c3b75208 --- /dev/null +++ b/core/frame/lite/include/softbus_server_frame.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_FRAME_H +#define SOFTBUS_SERVER_FRAME_H + +#ifdef __cplusplus +extern "C" { +#endif + +void InitSoftBusServer(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/frame/lite/include/softbus_server_frame_weak.h b/core/frame/lite/include/softbus_server_frame_weak.h new file mode 100755 index 000000000..db0998c66 --- /dev/null +++ b/core/frame/lite/include/softbus_server_frame_weak.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_FRAME_WEAK_H +#define SOFTBUS_SERVER_FRAME_WEAK_H + +#ifdef __cplusplus +extern "C" { +#endif + +int __attribute__ ((weak)) BusCenterServerInit(void); +void __attribute__ ((weak)) BusCenterServerDeinit(void); + +int __attribute__ ((weak)) TransServerInit(void); +void __attribute__ ((weak)) TransServerDeinit(void); + +int __attribute__ ((weak)) AuthInit(void); +void __attribute__ ((weak)) AuthDeinit(void); + +int __attribute__ ((weak)) ConnServerInit(void); +void __attribute__ ((weak)) ConnServerDeinit(void); + +int __attribute__ ((weak)) DiscServerInit(void); +void __attribute__ ((weak)) DiscServerDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif // SOFTBUS_SERVER_FRAME_WEAK_H + diff --git a/core/frame/lite/src/softbus_client_info_manager.c b/core/frame/lite/src/softbus_client_info_manager.c new file mode 100755 index 000000000..3615aa070 --- /dev/null +++ b/core/frame/lite/src/softbus_client_info_manager.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_info_manager.h" + +#include "securec.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +typedef struct { + ListNode node; + char name[PKG_NAME_SIZE_MAX]; /* softbus client name */ + unsigned int handle; /* use for small system device */ + unsigned int token; /* use for small system device */ + unsigned int cookie; /* use for small system device */ + void *ipcCtx; /* use for small system device */ +} SoftBusClientInfoNode; + +static SoftBusList *g_clientInfoList = NULL; + +static SoftBusList *SERVER_InitClientInfoManager(void) +{ + if (g_clientInfoList != NULL) { + LOG_INFO("has inited"); + return g_clientInfoList; + } + + g_clientInfoList = CreateSoftBusList(); + if (g_clientInfoList == NULL) { + LOG_ERR("init service info list failed"); + return NULL; + } + + if (pthread_mutex_init(&g_clientInfoList->lock, NULL) != 0) { + SoftBusFree(g_clientInfoList); + g_clientInfoList = NULL; + return NULL; + } + + ListInit(&g_clientInfoList->list); + return g_clientInfoList; +} + +SoftBusClientMgr *SERVER_InitClient(void) +{ + SoftBusClientMgr *clientMgr = (SoftBusClientMgr *)SoftBusMalloc(sizeof(SoftBusClientMgr)); + if (clientMgr == NULL) { + LOG_ERR("malloc client mgr failed"); + return NULL; + } + + clientMgr->clientInfoList = SERVER_InitClientInfoManager(); + if (clientMgr->clientInfoList == NULL) { + LOG_ERR("init client mgr failed"); + SoftBusFree(clientMgr); + return NULL; + } + + LOG_INFO("init success"); + return clientMgr; +} + +int SERVER_RegisterService(const char *name, const struct CommonScvId *svcId) +{ + if (name == NULL || svcId == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + LOG_INFO("new client register:%s", name); + + if (g_clientInfoList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + SoftBusClientInfoNode *clientInfo = (SoftBusClientInfoNode *)SoftBusMalloc(sizeof(SoftBusClientInfoNode)); + if (clientInfo == NULL) { + LOG_ERR("malloc failed"); + return SOFTBUS_ERR; + } + (void)memset_s(clientInfo, sizeof(SoftBusClientInfoNode), 0, sizeof(SoftBusClientInfoNode)); + + if (strcpy_s(clientInfo->name, sizeof(clientInfo->name), name) != EOK) { + LOG_ERR("strcpy failed"); + SoftBusFree(clientInfo); + return SOFTBUS_ERR; + } + + clientInfo->handle = svcId->handle; + clientInfo->token = svcId->token; + clientInfo->cookie = svcId->cookie; + clientInfo->ipcCtx = svcId->ipcCtx; + ListInit(&clientInfo->node); + + if (pthread_mutex_lock(&g_clientInfoList->lock) != 0) { + LOG_ERR("lock failed"); + SoftBusFree(clientInfo); + return SOFTBUS_ERR; + } + + ListAdd(&(g_clientInfoList->list), &(clientInfo->node)); + g_clientInfoList->cnt++; + + (void)pthread_mutex_unlock(&g_clientInfoList->lock); + return SOFTBUS_OK; +} + +int SERVER_GetIdentityByPkgName(const char *name, struct CommonScvId *svcId) +{ + if (name == NULL || svcId == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + if (g_clientInfoList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_clientInfoList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + SoftBusClientInfoNode *clientInfo = NULL; + LIST_FOR_EACH_ENTRY(clientInfo, &g_clientInfoList->list, SoftBusClientInfoNode, node) { + if (strcmp(clientInfo->name, name) == 0) { + svcId->handle = clientInfo->handle; + svcId->token = clientInfo->token; + svcId->cookie = clientInfo->cookie; + svcId->ipcCtx = clientInfo->ipcCtx; + (void)pthread_mutex_unlock(&g_clientInfoList->lock); + return SOFTBUS_OK; + } + } + + LOG_ERR("not found"); + (void)pthread_mutex_unlock(&g_clientInfoList->lock); + return SOFTBUS_ERR; +} + +int SERVER_UnregisterService(const char *name) +{ + return SOFTBUS_OK; +} diff --git a/core/frame/lite/src/softbus_server_frame.c b/core/frame/lite/src/softbus_server_frame.c new file mode 100644 index 000000000..fc9743505 --- /dev/null +++ b/core/frame/lite/src/softbus_server_frame.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_frame.h" + +#include "message_handler.h" +#include "ohos_init.h" +#include "pthread.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_server_frame_weak.h" + +static void ServerModuleDeinit(void) +{ + DiscServerDeinit(); + ConnServerDeinit(); + TransServerDeinit(); + BusCenterServerDeinit(); + AuthDeinit(); + SoftBusTimerDeInit(); + LooperDeinit(); +} + +void InitSoftBusServer(void) +{ + if (SoftBusTimerInit() == SOFTBUS_ERR) { + return; + } + + if (LooperInit() == -1) { + return; + } + + ClientProvideInterfaceInit(); + ServerProvideInterfaceImplInit(); + + if (ConnServerInit() == SOFTBUS_ERR) { + LOG_ERR("softbus conn server init failed."); + goto ERR_EXIT; + } + + if (TransServerInit() == SOFTBUS_ERR) { + LOG_ERR("softbus trans server init failed."); + goto ERR_EXIT; + } + + if (AuthInit() == SOFTBUS_ERR) { + LOG_ERR("softbus auth init failed."); + goto ERR_EXIT; + } + + if (BusCenterServerInit() == SOFTBUS_ERR) { + LOG_ERR("softbus buscenter server init failed."); + goto ERR_EXIT; + } + + if (DiscServerInit() == SOFTBUS_ERR) { + LOG_ERR("softbus disc server init failed."); + goto ERR_EXIT; + } + + LOG_INFO("softbus framework init success."); + return; + +ERR_EXIT: + ServerModuleDeinit(); + LOG_ERR("softbus framework init failed."); + return; +} + +#if defined(__LITEOS_M__) +// 4 stand for pri +SYS_SERVICE_INIT_PRI(InitSoftBusServer, 4); +#endif diff --git a/core/frame/lite/src/softbus_server_frame_weak.c b/core/frame/lite/src/softbus_server_frame_weak.c new file mode 100755 index 000000000..4e1bbed81 --- /dev/null +++ b/core/frame/lite/src/softbus_server_frame_weak.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_frame_weak.h" +#include "softbus_errcode.h" + +int __attribute__ ((weak)) BusCenterServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) BusCenterServerDeinit(void) +{ +} + +int __attribute__ ((weak)) TransServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) TransServerDeinit(void) +{ +} + +int __attribute__ ((weak)) AuthInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) AuthDeinit(void) +{ +} + +int __attribute__ ((weak)) ConnServerInit(void) +{ + return SOFTBUS_OK; +} +void __attribute__ ((weak)) ConnServerDeinit(void) +{ +} + +int __attribute__ ((weak)) DiscServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) DiscServerDeinit(void) +{ +} + diff --git a/core/frame/lite/src/softbus_server_main.c b/core/frame/lite/src/softbus_server_main.c new file mode 100644 index 000000000..f16987039 --- /dev/null +++ b/core/frame/lite/src/softbus_server_main.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_frame.h" +#include + +int main() +{ + InitSoftBusServer(); + while (1) { + pause(); + } + return 0; +} diff --git a/core/frame/standard/client/BUILD.gn b/core/frame/standard/client/BUILD.gn new file mode 100755 index 000000000..1b7638763 --- /dev/null +++ b/core/frame/standard/client/BUILD.gn @@ -0,0 +1,230 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +config("softbus_proxy_config") { + include_dirs = [ + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/sdk/transmission/session/cpp/include", + ] +} + +commonInclude = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/frame/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/include", + "$dsoftbus_root_path/core/common/softbus_property/include", + "$dsoftbus_root_path/core/common/security/sequence_verification/include", + + "$dsoftbus_root_path/sdk/transmission/session/include/", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/sdk/bus_center/include", + + "$dsoftbus_root_path/sdk/transmission/session/cpp/src", + + "//third_party/cJSON", + "//third_party/mbedtls/include", + "//third_party/mbedtls/include/mbedtls/", + "//third_party/bounds_checking_function/include", +] + +commonSrc = [ + "$dsoftbus_root_path/core/common/json_utils/softbus_json_utils.c", + "$dsoftbus_root_path/core/common/utils/softbus_utils.c", + "$dsoftbus_root_path/core/common/message_handler/message_handler.c", + "$dsoftbus_root_path/core/common/security/mbedtls/softbus_crypto.c", + "$dsoftbus_root_path/core/common/softbus_property/src/softbus_property.c", + "$dsoftbus_root_path/core/common/security/sequence_verification/src/softbus_sequence_verification.c", +] + +sdkFrameInclude = [ + "$dsoftbus_root_path/sdk/frame/include", + "$dsoftbus_root_path/sdk/discovery/include", + + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/core/transmission/pending_packet/include", +] + +sdkFrameSrc = [ + "$dsoftbus_root_path/sdk/frame/softbus_client_event_manager.c", + "$dsoftbus_root_path/sdk/frame/softbus_client_frame_manager.c", +] + +sdkBusCenterInclude = [ "$dsoftbus_root_path/sdk/bus_center/include" ] + +sdkBusCenterSrc = + [ "$dsoftbus_root_path/sdk/bus_center/src/client_bus_center.c" ] + +sdkDiscoveryInclude = [ "$dsoftbus_root_path/sdk/discovery/include" ] + +sdkDiscoverySrc = + [ "$dsoftbus_root_path/sdk/discovery/src/client_disc_manager.c" ] + +sdkBusTransmissionInclude = [ + "$dsoftbus_root_path/sdk/transmission/session/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/common/include", + + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/transmission/pending_packet/include", + "$dsoftbus_root_path/core/connection/common/include", +] + +sdkBusTransmissionSrc = [ + "$dsoftbus_root_path/sdk/transmission/session/src/client_trans_message_service.c", + "$dsoftbus_root_path/sdk/transmission/session/src/client_trans_session_callback.c", + "$dsoftbus_root_path/sdk/transmission/session/src/client_trans_session_manager.c", + "$dsoftbus_root_path/sdk/transmission/session/src/client_trans_session_service.c", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback.c", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager.c", + "$dsoftbus_root_path/sdk/transmission/trans_channel/proxy/src/client_trans_proxy_manager.c", + + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_listener.c", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_manager.c", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_message.c", + + "$dsoftbus_root_path/core/connection/common/src/softbus_base_listener.c", + "$dsoftbus_root_path/core/connection/common/src/softbus_tcp_socket.c", + "$dsoftbus_root_path/core/connection/common/src/softbus_thread_pool.c", + "$dsoftbus_root_path/core/transmission/pending_packet/src/trans_pending_pkt.c", + + "$dsoftbus_root_path/sdk/transmission/session/cpp/src/session_callback_mock.cpp", + "$dsoftbus_root_path/sdk/transmission/session/cpp/src/session_impl.cpp", + "$dsoftbus_root_path/sdk/transmission/session/cpp/src/session_mock.cpp", + "$dsoftbus_root_path/sdk/transmission/session/cpp/src/session_service_impl.cpp" +] + +clientStubSrc = [ + "$dsoftbus_root_path/core/frame/standard/client/src/softbus_client_stub.cpp", +] + +clientProxyInclude = [ + "//utils/native/base/include", + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", +] + +clientProxySrc = [ + "$dsoftbus_root_path/core/frame/standard/client/src/if_softbus_client.cpp", + "$dsoftbus_root_path/core/frame/standard/client/src/softbus_client_proxy.cpp", +] + +serverProxyInclude = [ + "$dsoftbus_root_path/core/frame/standard/server/include", + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/sdk/frame/include", + "//utils/system/safwk/native/include", +] + +serverProxySrc = [ + "$dsoftbus_root_path/core/frame/standard/server/src/if_softbus_server.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server_proxy.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_interface_server.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_client_death_recipient.cpp", +] + +coreAdapterInclude = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/adapter/bus_center/include", +] + +coreAdapterSrc = [ + "$dsoftbus_root_path/core/adapter/kernel/liteos_a/softbus_mem_interface.c", + "$dsoftbus_root_path/core/adapter/kernel/liteos_a/softbus_os_interface.c", + "$dsoftbus_root_path/core/adapter/bus_center/platform/bus_center_adapter_weak.c", +] + +sdkInclude = [ + "$dsoftbus_root_path/sdk/frame/include", + "$dsoftbus_root_path/sdk/transmission/session/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/interfaces/kits", + "//third_party/bounds_checking_function/include", + "$dsoftbus_root_path/core/adapter/kernel/include", +] + +ohos_shared_library("softbus_client") { + sources = sdkFrameSrc + sources += sdkBusCenterSrc + sources += sdkBusTransmissionSrc + sources += clientStubSrc + sources += commonSrc + sources += clientProxySrc + sources += serverProxySrc + sources += coreAdapterSrc + sources += sdkDiscoverySrc + + include_dirs = sdkFrameInclude + include_dirs += sdkBusCenterInclude + include_dirs += sdkBusTransmissionInclude + include_dirs += commonInclude + include_dirs += clientProxyInclude + include_dirs += serverProxyInclude + include_dirs += coreAdapterInclude + include_dirs += sdkDiscoveryInclude + include_dirs += sdkInclude + + cflags = [ + "-Wall", + "-Werror", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + + public_configs = [ ":softbus_proxy_config" ] + + if (is_standard_system) { + defines = [ "STANDARD_SYSTEM_ENABLE" ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + ] + + deps = [ + "$dsoftbus_root_path/components/mbedtls:mbedtls_shared", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + "//utils/native/base:utils", + ] + part_name = "dsoftbus_standard" + } + subsystem_name = "communication" +} diff --git a/core/frame/standard/client/include/if_softbus_client.h b/core/frame/standard/client/include/if_softbus_client.h new file mode 100644 index 000000000..9635f6c48 --- /dev/null +++ b/core/frame/standard/client/include/if_softbus_client.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_INNERKITS_SOFTBUS_CLIENT_H_ +#define INTERFACES_INNERKITS_SOFTBUS_CLIENT_H_ + +#include "iremote_broker.h" +#include "iremote_object.h" +#include "iremote_proxy.h" + +namespace OHOS { +class ISoftBusClient : public IRemoteBroker { +public: + virtual ~ISoftBusClient() = default; + + virtual void OnDeviceFound(const void *device) = 0; + virtual void OnDiscoverFailed(int subscribeId, int failReason) = 0; + virtual void OnDiscoverySuccess(int subscribeId) = 0; + virtual void OnPublishSuccess(int publishId) = 0; + virtual void OnPublishFail(int publishId, int reason) = 0; + virtual int32_t OnChannelOpened(const char *pkgName, const char *sessionName, const void *channel) = 0; + virtual int32_t OnChannelOpenFailed(const char *pkgName, int32_t channelId) = 0; + virtual int32_t OnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, uint32_t len, + int32_t type) = 0; + virtual int32_t OnChannelClosed(const char *pkgName, int32_t channelId) = 0; + virtual int32_t OnJoinLNNResult(void *addr, uint32_t addrTypeLen, const char *networkId, int retCode) = 0; + virtual int32_t OnLeaveLNNResult(const char *networkId, int retCode) = 0; + virtual int32_t OnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) = 0; + virtual int32_t OnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) = 0; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISoftBusClient"); +}; +} // namespace OHOS + +#endif // !defined(INTERFACES_INNERKITS_SOFTBUS_CLIENT_H_ ) diff --git a/core/frame/standard/client/include/softbus_client_proxy.h b/core/frame/standard/client/include/softbus_client_proxy.h new file mode 100644 index 000000000..153f31c56 --- /dev/null +++ b/core/frame/standard/client/include/softbus_client_proxy.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef INTERFACES_INNERKITS_SOFTBUS_CLIENT_PROXY_H_ +#define INTERFACES_INNERKITS_SOFTBUS_CLIENT_PROXY_H_ + +#include "if_softbus_client.h" + +namespace OHOS { +class SoftBusClientProxy : public IRemoteProxy { +public: + explicit SoftBusClientProxy(const sptr &impl) + : IRemoteProxy(impl) {} + virtual ~SoftBusClientProxy() = default; + + void OnDeviceFound(const void *device) override; + void OnDiscoverFailed(int subscribeId, int failReason) override; + void OnDiscoverySuccess(int subscribeId) override; + void OnPublishSuccess(int publishId) override; + void OnPublishFail(int publishId, int reason) override; + int32_t OnChannelOpened(const char *pkgName, const char *sessionName, const void *channel) override; + int32_t OnChannelOpenFailed(const char *pkgName, int32_t channelId) override; + int32_t OnChannelClosed(const char *pkgName, int32_t channelId) override; + int32_t OnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, uint32_t len, + int32_t type) override; + + int32_t OnJoinLNNResult(void *addr, uint32_t addrTypeLen, const char *networkId, int retCode) override; + int32_t OnLeaveLNNResult(const char *networkId, int retCode) override; + int32_t OnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) override; + int32_t OnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace OHOS + +#endif // !defined(INTERFACES_INNERKITS_SOFTBUS_CLIENT_PROXY_H_) diff --git a/core/frame/standard/client/include/softbus_client_stub.h b/core/frame/standard/client/include/softbus_client_stub.h new file mode 100644 index 000000000..9146018c3 --- /dev/null +++ b/core/frame/standard/client/include/softbus_client_stub.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_STUB_H_ +#define SOFTBUS_CLIENT_STUB_H_ + +#include +#include "if_softbus_client.h" +#include "iremote_object.h" +#include "iremote_stub.h" + +namespace OHOS { +class SoftBusClientStub : public IRemoteStub { +public: + SoftBusClientStub(); + virtual ~SoftBusClientStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + void OnDeviceFound(const void *device) override; + void OnDiscoverFailed(int subscribeId, int failReason) override; + void OnDiscoverySuccess(int subscribeId) override; + void OnPublishSuccess(int publishId) override; + void OnPublishFail(int publishId, int reason) override; + int32_t OnChannelOpened(const char *pkgName, const char *sessionName, const void *info) override; + int32_t OnChannelOpenFailed(const char *pkgName, int32_t channelId) override; + int32_t OnChannelClosed(const char *pkgName, int32_t channelId) override; + int32_t OnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, uint32_t len, + int32_t type) override; + int32_t OnJoinLNNResult(void *addr, uint32_t addrTypeLen, const char *networkId, int retCode) override; + int32_t OnLeaveLNNResult(const char *networkId, int retCode) override; + int32_t OnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) override; + int32_t OnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) override; + +private: + int32_t OnDeviceFoundInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDiscoverFailedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnDiscoverySuccessInner(MessageParcel &data, MessageParcel &reply); + int32_t OnPublishSuccessInner(MessageParcel &data, MessageParcel &reply); + int32_t OnPublishFailInner(MessageParcel &data, MessageParcel &reply); + int32_t OnChannelOpenedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnChannelOpenFailedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnChannelClosedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnChannelMsgReceivedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnJoinLNNResultInner(MessageParcel &data, MessageParcel &reply); + int32_t OnLeaveLNNResultInner(MessageParcel &data, MessageParcel &reply); + int32_t OnNodeOnlineStateChangedInner(MessageParcel &data, MessageParcel &reply); + int32_t OnNodeBasicInfoChangedInner(MessageParcel &data, MessageParcel &reply); + + using SoftBusClientStubFunc = + int32_t (SoftBusClientStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} // namespace OHOS + +#endif // SOFTBUS_CLIENT_STUB_H_ \ No newline at end of file diff --git a/core/frame/standard/client/src/if_softbus_client.cpp b/core/frame/standard/client/src/if_softbus_client.cpp new file mode 100644 index 000000000..1d14a58fb --- /dev/null +++ b/core/frame/standard/client/src/if_softbus_client.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace OHOS { +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/client/src/softbus_client_proxy.cpp b/core/frame/standard/client/src/softbus_client_proxy.cpp new file mode 100755 index 000000000..58bc4db76 --- /dev/null +++ b/core/frame/standard/client/src/softbus_client_proxy.cpp @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_proxy.h" + +#include "discovery_service.h" +#include "message_parcel.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" + +namespace OHOS { +int32_t SoftBusClientProxy::OnChannelOpened(const char *pkgName, const char *sessionName, const void *info) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + + ChannelInfo *channel = (ChannelInfo *)info; + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + + if (!data.WriteCString(sessionName)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channel->channelId)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channel->channelType)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteFileDescriptor(channel->fd)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteBool(channel->isServer)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteBool(channel->isEnabled)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channel->peerUid)) { + LOG_ERR("write peerUid failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channel->peerPid)) { + LOG_ERR("write peerPid failed"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(channel->groupId)) { + LOG_ERR("write addr failed"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(channel->keyLen)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(channel->sessionKey, channel->keyLen)) { + LOG_ERR("write addr failed"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(channel->peerSessionName)) { + LOG_ERR("write addr failed"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(channel->peerDeviceId)) { + LOG_ERR("write addr failed"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_CHANNEL_OPENED, data, reply, option) != 0) { + LOG_ERR("OnChannelOpened send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnChannelOpened read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channelId)) { + LOG_ERR("write channel id failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_CHANNEL_OPENFAILED, data, reply, option) != 0) { + LOG_ERR("OnChannelOpenFailed send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnChannelOpenFailed read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnChannelClosed(const char *pkgName, int32_t channelId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channelId)) { + LOG_ERR("write channel id failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_CHANNEL_CLOSED, data, reply, option) != 0) { + LOG_ERR("OnChannelClosed send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnChannelClosed read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *dataInfo, + uint32_t len, int32_t type) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("write pkgName failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(channelId)) { + LOG_ERR("write channel id failed"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(len)) { + LOG_ERR("write data len failed"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(dataInfo, len)) { + LOG_ERR("write (dataInfo, len) failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(type)) { + LOG_ERR("write data type failed"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_CHANNEL_MSGRECEIVED, data, reply, option) != 0) { + LOG_ERR("OnChannelMsgReceived send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnChannelMsgReceived read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +void SoftBusClientProxy::OnDeviceFound(const void *device) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return; + } + + DeviceInfo *deviceInfo = (DeviceInfo *)device; + MessageParcel data; + data.WriteBuffer(deviceInfo, sizeof(DeviceInfo)); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(CLIENT_DISCOVERY_DEVICE_FOUND, data, reply, option); + if (err != 0) { + LOG_ERR("OnDeviceFound send request failed"); + return; + } +} + +void SoftBusClientProxy::OnDiscoverFailed(int subscribeId, int failReason) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return; + } + + MessageParcel data; + data.WriteInt32(subscribeId); + data.WriteInt32(failReason); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(CLIENT_DISCOVERY_FAIL, data, reply, option); + if (err != 0) { + LOG_ERR("OnDiscoverFailed send request failed"); + return; + } +} + +void SoftBusClientProxy::OnDiscoverySuccess(int subscribeId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return; + } + + MessageParcel data; + data.WriteInt32(subscribeId); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(CLIENT_DISCOVERY_SUCC, data, reply, option); + if (err != 0) { + LOG_ERR("OnDiscoverySuccess send request failed"); + return; + } +} + +void SoftBusClientProxy::OnPublishSuccess(int publishId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return; + } + + MessageParcel data; + data.WriteInt32(publishId); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(CLIENT_PUBLISH_SUCC, data, reply, option); + if (err != 0) { + LOG_ERR("OnPublishSuccess send request failed"); + return; + } +} + +void SoftBusClientProxy::OnPublishFail(int publishId, int reason) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return; + } + + MessageParcel data; + data.WriteInt32(publishId); + data.WriteInt32(reason); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(CLIENT_PUBLISH_FAIL, data, reply, option); + if (err != 0) { + LOG_ERR("OnPublishFail send request failed"); + return; + } +} + +int32_t SoftBusClientProxy::OnJoinLNNResult(void *addr, uint32_t addrTypeLen, const char *networkId, int retCode) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + if (addr == nullptr || (retCode == 0 && networkId == nullptr)) { + LOG_ERR("invalid parameters"); + return SOFTBUS_ERR; + } + MessageParcel data; + if (!data.WriteUint32(addrTypeLen)) { + LOG_ERR("write addr type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(addr, addrTypeLen)) { + LOG_ERR("write addr failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(retCode)) { + LOG_ERR("write retCode failed"); + return SOFTBUS_ERR; + } + if (retCode == 0 && !data.WriteCString(networkId)) { + LOG_ERR("write networkId failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_JOIN_RESULT, data, reply, option) != 0) { + LOG_ERR("OnJoinLNNResult send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("SoftbusLeaveLNN read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnLeaveLNNResult(const char *networkId, int retCode) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + if (networkId == nullptr) { + LOG_ERR("invalid parameters"); + return SOFTBUS_ERR; + } + MessageParcel data; + if (!data.WriteCString(networkId)) { + LOG_ERR("write networkId failed"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(retCode)) { + LOG_ERR("write retCode failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_LEAVE_RESULT, data, reply, option) != 0) { + LOG_ERR("OnLeaveLNNResult send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnLeaveLNNResult read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + if (info == nullptr) { + LOG_ERR("invalid parameters"); + return SOFTBUS_ERR; + } + MessageParcel data; + if (!data.WriteBool(isOnline)) { + LOG_ERR("write online state failed"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(infoTypeLen)) { + LOG_ERR("write info type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(info, infoTypeLen)) { + LOG_ERR("write node info failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_NODE_ONLINE_STATE_CHANGED, data, reply, option) != 0) { + LOG_ERR("OnNodeOnlineStateChanged send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnNodeOnlineStateChanged read serverRet failed"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusClientProxy::OnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr"); + return SOFTBUS_ERR; + } + if (info == nullptr) { + LOG_ERR("invalid parameters"); + return SOFTBUS_ERR; + } + MessageParcel data; + LOG_ERR("OnNodeBasicInfoChanged type: %d", type); + if (!data.WriteInt32(type)) { + LOG_ERR("write type failed"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(infoTypeLen)) { + LOG_ERR("write info type length failed"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(info, infoTypeLen)) { + LOG_ERR("write node info failed"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(CLIENT_ON_NODE_BASIC_INFO_CHANGED, data, reply, option) != 0) { + LOG_ERR("OnNodeBasicInfoChanged send request failed"); + return SOFTBUS_ERR; + } + int32_t serverRet; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("OnNodeBasicInfoChanged read serverRet failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/client/src/softbus_client_stub.cpp b/core/frame/standard/client/src/softbus_client_stub.cpp new file mode 100755 index 000000000..39e748b10 --- /dev/null +++ b/core/frame/standard/client/src/softbus_client_stub.cpp @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_stub.h" + +#include "discovery_service.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "message_parcel.h" +#include "securec.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" + +extern "C" void __attribute__ ((weak)) DiscClientOnDeviceFound(const DeviceInfo *device) +{ + (void)device; + LOG_INFO("client DiscOnDeviceFound Weak!\n"); +} + +extern "C" void __attribute__ ((weak)) DiscClientOnDiscoverySuccess(int32_t subscribeId) +{ + (void)subscribeId; + LOG_INFO("client DiscOnDiscoverySuccess Weak!\n"); +} + +extern "C" void __attribute__ ((weak)) DiscClientOnDiscoverFailed(int32_t subscribeId, DiscoveryFailReason failReason) +{ + (void)subscribeId; + (void)failReason; + LOG_INFO("client DiscOnDiscoverFailed Weak!\n"); +} + +extern "C" void __attribute__ ((weak)) DiscClientOnPublishSuccess(int32_t publishId) +{ + (void)publishId; + LOG_INFO("client DiscOnPublishSuccess Weak!\n"); +} + +extern "C" void __attribute__ ((weak)) DiscClientOnPublishFail(int32_t publishId, PublishFailReason reason) +{ + (void)publishId; + (void)reason; + LOG_INFO("client DiscOnPublishFail Weak!\n"); +} + +extern "C" int __attribute__ ((weak)) TransOnChannelOpened(const char *pkgName, const char *sessionName, + const ChannelInfo *channel) +{ + LOG_INFO("client TransOnChannelOpened Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransOnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + LOG_INFO("client TransOnChannelOpenFailed Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransOnChannelClosed(const char *pkgName, int32_t channelId) +{ + LOG_INFO("client TransOnChannelClosed Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransOnChannelMsgReceived(const char *pkgName, int32_t channelId, + const void *data, uint32_t len, int32_t type) +{ + LOG_INFO("client TransOnChannelMsgReceived Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) LnnOnJoinResult(void *addr, const char *networkId, int retCode); +extern "C" int __attribute__ ((weak)) LnnOnLeaveResult(const char *networkId, int retCode); +extern "C" int __attribute__ ((weak)) LnnOnNodeOnlineStateChanged(bool isOnline, void *info); +extern "C" int __attribute__ ((weak)) LnnOnNodeBasicInfoChanged(void *info, int32_t type); + +namespace OHOS { +SoftBusClientStub::SoftBusClientStub() +{ + memberFuncMap_[CLIENT_DISCOVERY_DEVICE_FOUND] = + &SoftBusClientStub::OnDeviceFoundInner; + memberFuncMap_[CLIENT_DISCOVERY_SUCC] = + &SoftBusClientStub::OnDiscoverySuccessInner; + memberFuncMap_[CLIENT_DISCOVERY_FAIL] = + &SoftBusClientStub::OnDiscoverFailedInner; + memberFuncMap_[CLIENT_PUBLISH_SUCC] = + &SoftBusClientStub::OnPublishSuccessInner; + memberFuncMap_[CLIENT_PUBLISH_FAIL] = + &SoftBusClientStub::OnPublishFailInner; + memberFuncMap_[CLIENT_ON_CHANNEL_OPENED] = + &SoftBusClientStub::OnChannelOpenedInner; + memberFuncMap_[CLIENT_ON_CHANNEL_OPENFAILED] = + &SoftBusClientStub::OnChannelOpenFailedInner; + memberFuncMap_[CLIENT_ON_CHANNEL_CLOSED] = + &SoftBusClientStub::OnChannelClosedInner; + memberFuncMap_[CLIENT_ON_CHANNEL_MSGRECEIVED] = + &SoftBusClientStub::OnChannelMsgReceivedInner; + memberFuncMap_[CLIENT_ON_JOIN_RESULT] = + &SoftBusClientStub::OnJoinLNNResultInner; + memberFuncMap_[CLIENT_ON_LEAVE_RESULT] = + &SoftBusClientStub::OnLeaveLNNResultInner; + memberFuncMap_[CLIENT_ON_NODE_ONLINE_STATE_CHANGED] = + &SoftBusClientStub::OnNodeOnlineStateChangedInner; + memberFuncMap_[CLIENT_ON_NODE_BASIC_INFO_CHANGED] = + &SoftBusClientStub::OnNodeBasicInfoChangedInner; +} + +int32_t SoftBusClientStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + LOG_INFO("SoftBusClientStub::OnReceived, code = %u", code); + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + return (this->*memberFunc)(data, reply); + } + } + LOG_INFO("SoftBusClientStub: default case, need check."); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t SoftBusClientStub::OnDeviceFoundInner(MessageParcel &data, MessageParcel &reply) +{ + const unsigned char *info = data.ReadBuffer(sizeof(DeviceInfo)); + if (info == NULL) { + return SOFTBUS_ERR; + } + DeviceInfo deviceInfo; + if (memcpy_s(&deviceInfo, sizeof(DeviceInfo), info, sizeof(DeviceInfo)) != EOK) { + return SOFTBUS_ERR; + } + OnDeviceFound(&deviceInfo); + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnDiscoverFailedInner(MessageParcel &data, MessageParcel &reply) +{ + int subscribeId = data.ReadInt32(); + int failReason = data.ReadInt32(); + OnDiscoverFailed(subscribeId, failReason); + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnDiscoverySuccessInner(MessageParcel &data, MessageParcel &reply) +{ + int subscribeId = data.ReadInt32(); + OnDiscoverySuccess(subscribeId); + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnPublishSuccessInner(MessageParcel &data, MessageParcel &reply) +{ + int publishId = data.ReadInt32(); + OnPublishSuccess(publishId); + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnPublishFailInner(MessageParcel &data, MessageParcel &reply) +{ + int publishId = data.ReadInt32(); + int failReason = data.ReadInt32(); + OnPublishFail(publishId, failReason); + return SOFTBUS_OK; +} + +void SoftBusClientStub::OnDeviceFound(const void *device) +{ + DiscClientOnDeviceFound((DeviceInfo *)device); +} + +void SoftBusClientStub::OnDiscoverFailed(int subscribeId, int failReason) +{ + DiscClientOnDiscoverFailed(subscribeId, (DiscoveryFailReason)failReason); +} + +void SoftBusClientStub::OnDiscoverySuccess(int subscribeId) +{ + DiscClientOnDiscoverySuccess(subscribeId); +} + +void SoftBusClientStub::OnPublishSuccess(int publishId) +{ + DiscClientOnPublishSuccess(publishId); +} + +void SoftBusClientStub::OnPublishFail(int publishId, int reason) +{ + DiscClientOnPublishFail(publishId, (PublishFailReason)reason); +} + +int32_t SoftBusClientStub::OnChannelOpened(const char *pkgName, const char *sessionName, const void *info) +{ + return TransOnChannelOpened(pkgName, sessionName, (ChannelInfo *)info); +} + +int32_t SoftBusClientStub::OnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + return TransOnChannelOpenFailed(pkgName, channelId); +} + +int32_t SoftBusClientStub::OnChannelClosed(const char *pkgName, int32_t channelId) +{ + return TransOnChannelClosed(pkgName, channelId); +} + +int32_t SoftBusClientStub::OnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, + uint32_t len, int32_t type) +{ + return TransOnChannelMsgReceived(pkgName, channelId, data, len, type); +} + +int32_t SoftBusClientStub::OnChannelOpenedInner(MessageParcel &data, MessageParcel &reply) +{ + const char *pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("OnChannelOpenedInner read pkgName failed!"); + return SOFTBUS_ERR; + } + const char *sessionName = data.ReadCString(); + if (sessionName == nullptr) { + LOG_ERR("OnChannelOpenedInner read pkgName failed!"); + return SOFTBUS_ERR; + } + + ChannelInfo channel = {0}; + if (!data.ReadInt32(channel.channelId)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadInt32(channel.channelType)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + channel.fd = data.ReadFileDescriptor(); + if (!data.ReadBool(channel.isServer)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadBool(channel.isEnabled)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadInt32(channel.peerUid)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadInt32(channel.peerPid)) { + LOG_ERR("OnChannelOpenedInner read retCode failed!"); + return SOFTBUS_ERR; + } + channel.groupId = (char *)data.ReadCString(); + if (channel.groupId == nullptr) { + LOG_ERR("OnChannelOpenedInner read addr failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadUint32(channel.keyLen)) { + LOG_ERR("OnChannelOpenedInner len failed!"); + return SOFTBUS_ERR; + } + channel.sessionKey = (char *)data.ReadRawData(channel.keyLen); + if (channel.sessionKey == nullptr) { + LOG_ERR("OnChannelOpenedInner read addr failed!"); + return SOFTBUS_ERR; + } + channel.peerSessionName = (char *)data.ReadCString(); + if (channel.peerSessionName == nullptr) { + LOG_ERR("OnChannelOpenedInner read addr failed!"); + return SOFTBUS_ERR; + } + channel.peerDeviceId = (char *)data.ReadCString(); + if (channel.peerDeviceId == nullptr) { + LOG_ERR("OnChannelOpenedInner read addr failed!"); + return SOFTBUS_ERR; + } + + int ret = OnChannelOpened(pkgName, sessionName, &channel); + bool res = reply.WriteInt32(ret); + if (!res) { + LOG_ERR("OnChannelOpenedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnChannelOpenFailedInner(MessageParcel &data, MessageParcel &reply) +{ + const char* pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("OnChannelOpenedInner read pkgName failed!"); + return SOFTBUS_ERR; + } + + int32_t channelId; + if (!data.ReadInt32(channelId)) { + LOG_ERR("OnChannelOpenFailedInner read channel id failed!"); + return SOFTBUS_ERR; + } + + int ret = OnChannelOpenFailed(pkgName, channelId); + bool res = reply.WriteInt32(ret); + if (!res) { + LOG_ERR("OnChannelOpenFailedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnChannelClosedInner(MessageParcel &data, MessageParcel &reply) +{ + const char* pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("OnChannelOpenedInner read pkgName failed!"); + return SOFTBUS_ERR; + } + + int32_t channelId; + if (!data.ReadInt32(channelId)) { + LOG_ERR("OnChannelClosedInner read channel id failed!"); + return SOFTBUS_ERR; + } + + int ret = OnChannelClosed(pkgName, channelId); + bool res = reply.WriteInt32(ret); + if (!res) { + LOG_ERR("OnChannelClosedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnChannelMsgReceivedInner(MessageParcel &data, MessageParcel &reply) +{ + const char* pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("OnChannelMsgReceivedInner read pkgName failed!"); + return SOFTBUS_ERR; + } + + int32_t channelId; + if (!data.ReadInt32(channelId)) { + LOG_ERR("OnChannelMsgReceivedInner read channel id failed!"); + return SOFTBUS_ERR; + } + uint32_t len; + if (!data.ReadUint32(len)) { + LOG_ERR("OnChannelMsgReceivedInner read data len failed!"); + return SOFTBUS_ERR; + } + char *dataInfo = (char *)data.ReadRawData(len); + if (dataInfo == nullptr) { + LOG_ERR("OnChannelOpenedInner read dataInfo failed!"); + return SOFTBUS_ERR; + } + int32_t type; + if (!data.ReadInt32(type)) { + LOG_ERR("OnChannelMsgReceivedInner read type failed!"); + return SOFTBUS_ERR; + } + int ret = OnChannelMsgReceived(pkgName, channelId, dataInfo, len, type); + bool res = reply.WriteInt32(ret); + if (!res) { + LOG_ERR("OnChannelMsgReceivedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnJoinLNNResultInner(MessageParcel &data, MessageParcel &reply) +{ + uint32_t addrTypeLen; + if (!data.ReadUint32(addrTypeLen)) { + LOG_ERR("OnJoinLNNResultInner read addr type length failed!"); + return SOFTBUS_ERR; + } + void *addr = (void *)data.ReadRawData(addrTypeLen); + if (addr == nullptr) { + LOG_ERR("OnJoinLNNResultInner read addr failed!"); + return SOFTBUS_ERR; + } + int32_t retCode; + if (!data.ReadInt32(retCode)) { + LOG_ERR("OnJoinLNNResultInner read retCode failed!"); + return SOFTBUS_ERR; + } + const char *networkId = nullptr; + if (retCode == 0) { + networkId = data.ReadCString(); + if (networkId == nullptr) { + LOG_ERR("OnJoinLNNResultInner read networkId failed!"); + return SOFTBUS_ERR; + } + } + int32_t retReply = OnJoinLNNResult(addr, addrTypeLen, networkId, retCode); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("OnJoinLNNResultInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnLeaveLNNResultInner(MessageParcel &data, MessageParcel &reply) +{ + const char *networkId = data.ReadCString(); + if (networkId == nullptr) { + LOG_ERR("OnLeaveLNNResultInner read networkId failed!"); + return SOFTBUS_ERR; + } + int32_t retCode; + if (!data.ReadInt32(retCode)) { + LOG_ERR("OnLeaveLNNResultInner read retCode failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = OnLeaveLNNResult(networkId, retCode); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("OnLeaveLNNResultInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnNodeOnlineStateChangedInner(MessageParcel &data, MessageParcel &reply) +{ + bool isOnline = false; + if (!data.ReadBool(isOnline)) { + LOG_ERR("OnNodeOnlineStateChangedInner read online state failed!"); + return SOFTBUS_ERR; + } + uint32_t infoTypeLen; + if (!data.ReadUint32(infoTypeLen)) { + LOG_ERR("OnNodeOnlineStateChangedInner read info type length failed!"); + return SOFTBUS_ERR; + } + void *info = (void *)data.ReadRawData(infoTypeLen); + if (info == nullptr) { + LOG_ERR("OnNodeOnlineStateChangedInner read basic info failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = OnNodeOnlineStateChanged(isOnline, info, infoTypeLen); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("OnNodeOnlineStateChangedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnNodeBasicInfoChangedInner(MessageParcel &data, MessageParcel &reply) +{ + int32_t type; + if (!data.ReadInt32(type)) { + LOG_ERR("OnNodeBasicInfoChangedInner read type failed!"); + return SOFTBUS_ERR; + } + LOG_ERR("OnNodeBasicInfoChangedInner type %d", type); + uint32_t infoTypeLen; + if (!data.ReadUint32(infoTypeLen)) { + LOG_ERR("OnNodeBasicInfoChangedInner read info type length failed!"); + return SOFTBUS_ERR; + } + void *info = (void *)data.ReadRawData(infoTypeLen); + if (info == nullptr) { + LOG_ERR("OnNodeBasicInfoChangedInner read basic info failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = OnNodeBasicInfoChanged(info, infoTypeLen, type); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("OnNodeBasicInfoChangedInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusClientStub::OnJoinLNNResult(void *addr, uint32_t addrTypeLen, const char *networkId, int retCode) +{ + (void)addrTypeLen; + return LnnOnJoinResult(addr, networkId, retCode); +} + +int32_t SoftBusClientStub::OnLeaveLNNResult(const char *networkId, int retCode) +{ + return LnnOnLeaveResult(networkId, retCode); +} + +int32_t SoftBusClientStub::OnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) +{ + (void)infoTypeLen; + return LnnOnNodeOnlineStateChanged(isOnline, info); +} + +int32_t SoftBusClientStub::OnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + (void)infoTypeLen; + return LnnOnNodeBasicInfoChanged(info, type); +} +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/sa_profile/4700.xml b/core/frame/standard/sa_profile/4700.xml new file mode 100644 index 000000000..fda7d3461 --- /dev/null +++ b/core/frame/standard/sa_profile/4700.xml @@ -0,0 +1,24 @@ + + + + softbus_server + + 4700 + libsoftbus_server.z.so + true + false + 1 + + \ No newline at end of file diff --git a/core/frame/standard/sa_profile/BUILD.gn b/core/frame/standard/sa_profile/BUILD.gn new file mode 100755 index 000000000..d1d89c147 --- /dev/null +++ b/core/frame/standard/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("softbus_sa_profile") { + sources = [ "4700.xml" ] + + part_name = "dsoftbus_standard" +} diff --git a/core/frame/standard/server/BUILD.gn b/core/frame/standard/server/BUILD.gn new file mode 100644 index 000000000..905a7fe5a --- /dev/null +++ b/core/frame/standard/server/BUILD.gn @@ -0,0 +1,339 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +config("softbus_proxy_config") { + include_dirs = [ "$dsoftbus_root_path/core/frame/standard/server/include" ] +} + +config("softbus_private_config") { + include_dirs = [ + "//utils/native/base/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/core/common/message_handler/include", + ] +} + +group("etc") { + deps = [ ":softbus_server.rc" ] +} + +ohos_prebuilt_etc("softbus_server.rc") { + relative_install_dir = "init" + source = + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server.rc" + part_name = "dsoftbus_standard" + subsystem_name = "communication" +} + +coreConnectionInclude = [ + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/core/connection/tcp/include", +] + +coreConnectionSrc = [ + "$dsoftbus_root_path/core/connection/common/src/softbus_base_listener.c", + "$dsoftbus_root_path/core/connection/common/src/softbus_tcp_socket.c", + "$dsoftbus_root_path/core/connection/common/src/softbus_thread_pool.c", + "$dsoftbus_root_path/core/connection/manager/softbus_conn_manager.c", + "$dsoftbus_root_path/core/connection/manager/softbus_conn_manager_weak.c", + "$dsoftbus_root_path/core/connection/tcp/src/softbus_tcp_connect_manager.c", +] + +coreCommonInclude = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/frame/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/include", + "$dsoftbus_root_path/core/common/security/permission/include", + "$dsoftbus_root_path/core/common/softbus_property/include", + + "$dsoftbus_root_path/sdk/transmission/session/include/", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/sdk/bus_center/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/core/common/security/sequence_verification/include", + + "//third_party/cJSON", + "//third_party/mbedtls/include", + "//third_party/mbedtls/include/mbedtls/", + "//third_party/bounds_checking_function/include", + + "//foundation/appexecfwk/standard/kits/appkit/native/app/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/bundlemgr/", + "//utils/system/safwk/native/include", + "//foundation/aafwk/standard/interfaces/innerkits/want/include", +] + +coreCommonSrc = [ + "$dsoftbus_root_path/core/common/json_utils/softbus_json_utils.c", + "$dsoftbus_root_path/core/common/utils/softbus_utils.c", + "$dsoftbus_root_path/core/common/message_handler/message_handler.c", + "$dsoftbus_root_path/core/common/security/mbedtls/softbus_crypto.c", + "$dsoftbus_root_path/core/common/security/permission/common/permission_entry.c", + "$dsoftbus_root_path/core/common/security/permission/standard_system/permission_utils.cpp", + "$dsoftbus_root_path/core/common/security/permission/standard_system/softbus_permission.cpp", + "$dsoftbus_root_path/core/common/softbus_property/src/softbus_property.c", + "$dsoftbus_root_path/core/common/security/sequence_verification/src/softbus_sequence_verification.c", + "$dsoftbus_root_path/core/transmission/common/softbus_message_open_channel.c", +] + +coreBuscenterInclude = [ + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/distributed_ledger/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/local_ledger/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/sync_ledger/include", + "$dsoftbus_root_path/core/bus_center/ipc/include", + "$dsoftbus_root_path/core/bus_center/service/include", + "$dsoftbus_root_path/core/bus_center/utils/include", +] + +coreBuscenterSrc = [ + "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_info.c", + "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_lane_manager.c", + "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/src/lnn_smart_communication.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/ip/ip_hook.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/src/lnn_net_builder.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/src/lnn_network_id.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/src/lnn_state_machine.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/src/lnn_device_info.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/src/lnn_map.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/src/lnn_net_capability.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/src/lnn_node_info.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c", + "$dsoftbus_root_path/core/bus_center/ipc/standard_system/lnn_bus_center_ipc.cpp", + "$dsoftbus_root_path/core/bus_center/service/src/bus_center_event.c", + "$dsoftbus_root_path/core/bus_center/service/src/bus_center_manager.c", + "$dsoftbus_root_path/core/bus_center/utils/src/lnn_connection_addr_utils.c", +] + +coreAuthenticationInclude = [ + "$dsoftbus_root_path/core/authentication/include", + "$dsoftbus_root_path/core/authentication/interface", + + "//base/security/deviceauth/interfaces/innerkits", +] + +coreAuthenticationSrc = [ + "$dsoftbus_root_path/core/authentication/src/auth_common.c", + "$dsoftbus_root_path/core/authentication/src/auth_connection.c", + "$dsoftbus_root_path/core/authentication/src/auth_manager.c", + "$dsoftbus_root_path/core/authentication/src/auth_sessionkey.c", + "$dsoftbus_root_path/core/authentication/src/auth_socket.c", +] + +coreTransmissionInclude = [ + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + + "$dsoftbus_root_path/core/transmission/pending_packet/include", +] + +coreDiscoveryInclude = [ + "$dsoftbus_root_path/core/discovery/manager/include", + "$dsoftbus_root_path/core/discovery/coap/include", + "$dsoftbus_root_path/core/discovery/interface", + "$dsoftbus_root_path/core/discovery/service/include", +] + +coreTransmissionSrc = [ + "$dsoftbus_root_path/core/transmission/session/src/trans_session_manager.c", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/src/trans_channel_manager.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_control.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_listener.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_manager.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_message.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_network.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_session.c", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/src/softbus_proxychannel_transceiver.c", + + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_listener.c", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_manager.c", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_message.c", + + "$dsoftbus_root_path/core/transmission/pending_packet/src/trans_pending_pkt.c", +] + +coreAdapterInclude = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/adapter/bus_center/include", +] + +coreAdapterSrc = [ + "$dsoftbus_root_path/core/adapter/kernel/liteos_a/softbus_mem_interface.c", + "$dsoftbus_root_path/core/adapter/kernel/liteos_a/softbus_os_interface.c", + "$dsoftbus_root_path/core/adapter/bus_center/platform/bus_center_adapter_weak.c", +] + +coreDiscoverySrc = [ + "$dsoftbus_root_path/core/discovery/manager/src/disc_manager.c", + "$dsoftbus_root_path/core/discovery/coap/src/disc_coap.c", + "$dsoftbus_root_path/core/discovery/coap/src/disc_nstackx_adapter.c", + "$dsoftbus_root_path/core/discovery/service/src/softbus_disc_server.c", +] + +serverStubSrc = [ + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_interface_client.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server_stub.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server_death_recipient.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server_frame.c", +] + +serverProxyInclude = [ + "$dsoftbus_root_path/core/frame/standard/server/include", + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/sdk/frame/include", + "//utils/system/safwk/native/include", +] + +serverProxySrc = [ + "$dsoftbus_root_path/core/frame/standard/server/src/if_softbus_server.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_server_proxy.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_interface_server.cpp", + "$dsoftbus_root_path/core/frame/standard/server/src/softbus_client_death_recipient.cpp", +] + +clientProxyInclude = [ + "//utils/native/base/include", + "$dsoftbus_root_path/core/frame/standard/client/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", +] + +clientProxySrc = [ + "$dsoftbus_root_path/core/frame/standard/client/src/if_softbus_client.cpp", + "$dsoftbus_root_path/core/frame/standard/client/src/softbus_client_proxy.cpp", +] + +clientStubInclude = [ "$dsoftbus_root_path/core/frame/standard/client/include" ] + +clientStubSrc = [ + "$dsoftbus_root_path/core/frame/standard/client/src/softbus_client_stub.cpp", +] + +sdkFrameInclude = [ + "$dsoftbus_root_path/sdk/frame/include", + "$dsoftbus_root_path/sdk/discovery/include", + + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/core/transmission/pending_packet/include", +] + +sdkFrameSrc = [ + "$dsoftbus_root_path/sdk/frame/softbus_client_event_manager.c", + "$dsoftbus_root_path/sdk/frame/softbus_client_frame_manager.c", +] + +sdkDiscoveryInclude = [ "$dsoftbus_root_path/sdk/discovery/include" ] + +sdkDiscoverySrc = + [ "$dsoftbus_root_path/sdk/discovery/src/client_disc_manager.c" ] + +ohos_shared_library("softbus_server") { + sources = coreConnectionSrc + sources += coreCommonSrc + sources += coreBuscenterSrc + sources += coreAuthenticationSrc + sources += coreTransmissionSrc + sources += coreAdapterSrc + sources += coreDiscoverySrc + sources += serverStubSrc + sources += serverProxySrc + sources += clientProxySrc + sources += clientStubSrc + sources += sdkFrameSrc + sources += sdkDiscoverySrc + + include_dirs = coreConnectionInclude + include_dirs += coreCommonInclude + include_dirs += coreBuscenterInclude + include_dirs += coreAuthenticationInclude + include_dirs += coreTransmissionInclude + include_dirs += coreAdapterInclude + include_dirs += coreDiscoveryInclude + include_dirs += serverProxyInclude + include_dirs += clientProxyInclude + include_dirs += clientStubInclude + include_dirs += sdkFrameInclude + include_dirs += sdkDiscoveryInclude + + cflags = [ + "-Wall", + "-Werror", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + configs = [ ":softbus_private_config" ] + public_configs = [ ":softbus_proxy_config" ] + + if (is_standard_system) { + defines = [ "STANDARD_SYSTEM_ENABLE" ] + external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_core", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "permission_standard:libpermissionsdk_standard", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + deps = [ + ":softbus_server.rc", + "$dsoftbus_root_path/components/mbedtls:mbedtls_shared", + "$dsoftbus_root_path/components/nstackx/nstackx_ctrl:nstackx_ctrl", + "//base/security/deviceauth/services:deviceauth_sdk", + "//foundation/appexecfwk/standard/kits:appkit_native", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + "//utils/native/base:utils", + ] + part_name = "dsoftbus_standard" + } + subsystem_name = "communication" +} diff --git a/core/frame/standard/server/include/if_softbus_server.h b/core/frame/standard/server/include/if_softbus_server.h new file mode 100755 index 000000000..edab701c3 --- /dev/null +++ b/core/frame/standard/server/include/if_softbus_server.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_INNERKITS_SOFTBUS_SERVER_H_ +#define INTERFACES_INNERKITS_SOFTBUS_SERVER_H_ + +#include "iremote_broker.h" +#include "iremote_object.h" +#include "iremote_proxy.h" + +namespace OHOS { +class ISoftBusServer : public IRemoteBroker { +public: + virtual ~ISoftBusServer() = default; + + virtual int32_t StartDiscovery(const char *pkgName, const void *info) = 0; + virtual int32_t StopDiscovery(const char *pkgName, int subscribeId) = 0; + virtual int32_t PublishService(const char *pkgName, const void *info) = 0; + virtual int32_t UnPublishService(const char *pkgName, int publishId) = 0; + virtual int32_t SoftbusRegisterService(const char *clientPkgName, const sptr &object) = 0; + + virtual int32_t CreateSessionServer(const char *pkgName, const char *sessionName) = 0; + virtual int32_t RemoveSessionServer(const char *pkgName, const char *sessionName) = 0; + virtual int32_t OpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) = 0; + virtual int32_t CloseChannel(int32_t channelId) = 0; + virtual int32_t SendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) = 0; + + virtual int32_t JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) = 0; + virtual int32_t LeaveLNN(const char *pkgName, const char *networkId) = 0; + virtual int32_t GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) = 0; + virtual int32_t GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) = 0; + virtual int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, + uint32_t len) = 0; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISoftBusServer"); +}; +} // namespace OHOS + +#endif // !defined(INTERFACES_INNERKITS_SOFTBUS_SERVER_H_ ) \ No newline at end of file diff --git a/core/frame/standard/server/include/softbus_client_death_recipient.h b/core/frame/standard/server/include/softbus_client_death_recipient.h new file mode 100755 index 000000000..019073c4b --- /dev/null +++ b/core/frame/standard/server/include/softbus_client_death_recipient.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_DEATH_RECIPIENT_H +#define SOFTBUS_CLIENT_DEATH_RECIPIENT_H + +#include "iremote_object.h" + +namespace OHOS { +class SoftBusClientDeathRecipient : public IRemoteObject::DeathRecipient { +public: + SoftBusClientDeathRecipient() = default; + virtual ~SoftBusClientDeathRecipient() = default; + void OnRemoteDied(const wptr &remote) override; +}; +} // namespace OHOS + +#endif // SOFTBUS_CLIENT_DEATH_RECIPIENT_H diff --git a/core/frame/standard/server/include/softbus_server.h b/core/frame/standard/server/include/softbus_server.h new file mode 100755 index 000000000..53def4a01 --- /dev/null +++ b/core/frame/standard/server/include/softbus_server.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_H_ +#define SOFTBUS_SERVER_H_ + +#include "system_ability.h" + +#include +#include +#include "softbus_client_proxy.h" +#include "softbus_server_death_recipient.h" +#include "softbus_server_stub.h" + +namespace OHOS { +class SoftBusServer : public SystemAbility, public SoftBusServerStub { + DECLARE_SYSTEM_ABILITY(SoftBusServer); + +public: + SoftBusServer(int32_t saId, bool runOnCreate); + ~SoftBusServer() = default; + + int32_t StartDiscovery(const char *pkgName, const void *info) override; + int32_t StopDiscovery(const char *pkgName, int subscribeId) override; + int32_t PublishService(const char *pkgName, const void *info) override; + int32_t UnPublishService(const char *pkgName, int publishId) override; + int32_t SoftbusRegisterService(const char *clientPkgName, const sptr &object) override; + + int32_t CreateSessionServer(const char *pkgName, const char *sessionName) override; + int32_t RemoveSessionServer(const char *pkgName, const char *sessionName) override; + int32_t OpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) override; + int32_t CloseChannel(int32_t channelId) override; + int32_t SendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) override; + + int32_t JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) override; + int32_t LeaveLNN(const char *pkgName, const char *networkId) override; + int32_t GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) override; + int32_t GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) override; + int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, + uint32_t len) override; + + static sptr GetInstance(); + sptr GetSoftbusClientProxy(const char *pkgName); + int32_t SoftbusRemoveService(const sptr &object); + void GetSoftbusClientProxyMap(std::map> &softbusClientMap); + +protected: + void OnStart() override; + void OnStop() override; + DISALLOW_COPY_AND_MOVE(SoftBusServer); + +private: + std::recursive_mutex clientObjectMapLock_; + static std::map> clientObjectMap_; + static std::mutex instanceLock_; + static sptr instance_; + sptr abilityDeath_; +}; +} // namespace OHOS + +#endif // SOFTBUS_SERVER_H_ diff --git a/core/frame/standard/server/include/softbus_server_death_recipient.h b/core/frame/standard/server/include/softbus_server_death_recipient.h new file mode 100755 index 000000000..a264bdafa --- /dev/null +++ b/core/frame/standard/server/include/softbus_server_death_recipient.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_DEATH_RECIPIENT_H +#define SOFTBUS_SERVER_DEATH_RECIPIENT_H + +#include "iremote_object.h" + +namespace OHOS { +class SoftBusDeathRecipient : public IRemoteObject::DeathRecipient { +public: + SoftBusDeathRecipient() = default; + virtual ~SoftBusDeathRecipient() = default; + void OnRemoteDied(const wptr &remote) override; +}; +} // namespace OHOS + +#endif // SOFTBUS_SERVER_DEATH_RECIPIENT_H diff --git a/core/frame/standard/server/include/softbus_server_frame.h b/core/frame/standard/server/include/softbus_server_frame.h new file mode 100755 index 000000000..7e88be401 --- /dev/null +++ b/core/frame/standard/server/include/softbus_server_frame.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_FRAME_H +#define SOFTBUS_SERVER_FRAME_H + +#ifdef __cplusplus +extern "C" { +#endif + +int DiscServerInit(void); +void DiscServerDeinit(void); + +int ConnServerInit(void); +void ConnServerDeinit(void); + +int TransServerInit(void); +void TransServerDeinit(void); + +int BusCenterServerInit(void); +void BusCenterServerDeinit(void); + +int AuthInit(void); +void AuthDeinit(void); + +void InitSoftBusServer(); + +#ifdef __cplusplus +} +#endif + +#endif // SOFTBUS_SERVER_FRAME_H diff --git a/core/frame/standard/server/include/softbus_server_proxy.h b/core/frame/standard/server/include/softbus_server_proxy.h new file mode 100755 index 000000000..1163bc5c5 --- /dev/null +++ b/core/frame/standard/server/include/softbus_server_proxy.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef INTERFACES_INNERKITS_SOFTBUS_SERVER_PROXY_H_ +#define INTERFACES_INNERKITS_SOFTBUS_SERVER_PROXY_H_ + +#include "if_softbus_server.h" +#include + +namespace OHOS { +class SoftBusServerProxy : public IRemoteProxy { +public: + explicit SoftBusServerProxy(const sptr &impl) + : IRemoteProxy(impl) {} + virtual ~SoftBusServerProxy() = default; + + int32_t StartDiscovery(const char *pkgName, const void *info) override; + int32_t StopDiscovery(const char *pkgName, int subscribeId) override; + int32_t PublishService(const char *pkgName, const void *info) override; + int32_t UnPublishService(const char *pkgName, int publishId) override; + int32_t SoftbusRegisterService(const char *clientPkgName, const sptr &object) override; + + int32_t CreateSessionServer(const char *pkgName, const char *sessionName) override; + int32_t RemoveSessionServer(const char *pkgName, const char *sessionName) override; + int32_t OpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) override; + int32_t CloseChannel(int32_t channelId) override; + int32_t SendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) override; + + int32_t JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) override; + int32_t LeaveLNN(const char *pkgName, const char *networkId) override; + int32_t GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) override; + int32_t GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) override; + int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, + uint32_t len) override; + +private: + static inline BrokerDelegator delegator_; + static sptr clientCallbackStub_; + static std::mutex instanceLock; + + static sptr GetRemoteInstance(); +}; +} // namespace OHOS + +#endif // !defined(INTERFACES_INNERKITS_SOFTBUS_SERVER_PROXY_H_) diff --git a/core/frame/standard/server/include/softbus_server_stub.h b/core/frame/standard/server/include/softbus_server_stub.h new file mode 100755 index 000000000..7caeec71b --- /dev/null +++ b/core/frame/standard/server/include/softbus_server_stub.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SERVER_STUB_H_ +#define SOFTBUS_SERVER_STUB_H_ + +#include +#include "if_softbus_server.h" +#include "iremote_object.h" +#include "iremote_stub.h" + +namespace OHOS { +class SoftBusServerStub : public IRemoteStub { +public: + SoftBusServerStub(); + virtual ~SoftBusServerStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t StartDiscoveryInner(MessageParcel &data, MessageParcel &reply); + int32_t StopDiscoveryInner(MessageParcel &data, MessageParcel &reply); + int32_t PublishServiceInner(MessageParcel &data, MessageParcel &reply); + int32_t UnPublishServiceInner(MessageParcel &data, MessageParcel &reply); + int32_t SoftbusRegisterServiceInner(MessageParcel &data, MessageParcel &reply); + + int32_t CreateSessionServerInner(MessageParcel &data, MessageParcel &reply); + int32_t RemoveSessionServerInner(MessageParcel &data, MessageParcel &reply); + int32_t OpenSessionInner(MessageParcel &data, MessageParcel &reply); + int32_t CloseChannelInner(MessageParcel &data, MessageParcel &reply); + int32_t SendMessageInner(MessageParcel &data, MessageParcel &reply); + + int32_t JoinLNNInner(MessageParcel &data, MessageParcel &reply); + int32_t LeaveLNNInner(MessageParcel &data, MessageParcel &reply); + int32_t GetAllOnlineNodeInfoInner(MessageParcel &data, MessageParcel &reply); + int32_t GetLocalDeviceInfoInner(MessageParcel &data, MessageParcel &reply); + int32_t GetNodeKeyInfoInner(MessageParcel &data, MessageParcel &reply); + + using SoftBusServerStubFunc = + int32_t (SoftBusServerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map memberFuncMap_; +}; +} // namespace OHOS + +#endif // SOFTBUS_SERVER_STUB_H_ \ No newline at end of file diff --git a/core/frame/standard/server/src/if_softbus_server.cpp b/core/frame/standard/server/src/if_softbus_server.cpp new file mode 100644 index 000000000..1d14a58fb --- /dev/null +++ b/core/frame/standard/server/src/if_softbus_server.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace OHOS { +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/server/src/softbus_client_death_recipient.cpp b/core/frame/standard/server/src/softbus_client_death_recipient.cpp new file mode 100755 index 000000000..0eaf28255 --- /dev/null +++ b/core/frame/standard/server/src/softbus_client_death_recipient.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_death_recipient.h" + +#include "softbus_interface.h" +#include "softbus_log.h" + +namespace OHOS { +void SoftBusClientDeathRecipient::OnRemoteDied(const wptr &remote) +{ + LOG_INFO("server died, try to publish again"); + ClientDeathProcTask(); +} +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/server/src/softbus_interface_client.cpp b/core/frame/standard/server/src/softbus_interface_client.cpp new file mode 100755 index 000000000..e5be8db93 --- /dev/null +++ b/core/frame/standard/server/src/softbus_interface_client.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_interface.h" + +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_permission.h" +#include "softbus_server.h" +#include "system_ability_definition.h" + +using namespace OHOS; + +static sptr GetClientProxy(const char *pkgName) +{ + sptr softbusServer = SoftBusServer::GetInstance(); + if (softbusServer == nullptr) { + LOG_ERR("softbusServer is nullptr!\n"); + return nullptr; + } + sptr clientProxy = softbusServer->GetSoftbusClientProxy(pkgName); + return clientProxy; +} + +static int ClientIpcOnDeviceFound(const char *pkgName, const void *device) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnDeviceFound(device); + return SOFTBUS_OK; +} + +static int ClientIpcOnDiscoverFailed(const char *pkgName, int subscribeId, int failReason) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnDiscoverFailed(subscribeId, failReason); + return SOFTBUS_OK; +} + +static int ClientIpcOnDiscoverySuccess(const char *pkgName, int subscribeId) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnDiscoverySuccess(subscribeId); + return SOFTBUS_OK; +} + +static int ClientIpcOnPublishSuccess(const char *pkgName, int publishId) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnPublishSuccess(publishId); + return SOFTBUS_OK; +} + +static int ClientIpcOnPublishFail(const char *pkgName, int publishId, int reason) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnPublishFail(publishId, reason); + return SOFTBUS_OK; +} + +static int ClientIpcOnChannelOpened(const char *pkgName, const char *sessionName, const ChannelInfo *channel) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnChannelOpened(pkgName, sessionName, channel); + return SOFTBUS_OK; +} + +static int ClientIpcOnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnChannelOpenFailed(pkgName, channelId); + return SOFTBUS_OK; +} + +static int ClientIpcOnChannelClosed(const char *pkgName, int32_t channelId) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnChannelClosed(pkgName, channelId); + return SOFTBUS_OK; +} + +static int ClientIpcOnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, + uint32_t len, int32_t type) +{ + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + clientProxy->OnChannelMsgReceived(pkgName, channelId, data, len, type); + return SOFTBUS_OK; +} + +static int ClientOnJoinLNNResult(const char *pkgName, void *addr, uint32_t addrTypeLen, + const char *networkId, int32_t retCode) +{ + if (pkgName == nullptr) { + LOG_ERR("pkgName is null"); + return SOFTBUS_ERR; + } + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + return clientProxy->OnJoinLNNResult(addr, addrTypeLen, networkId, retCode); +} + +static int ClientOnLeaveLNNResult(const char *pkgName, const char *networkId, int32_t retCode) +{ + if (pkgName == nullptr) { + LOG_ERR("pkgName is null"); + return SOFTBUS_ERR; + } + sptr clientProxy = GetClientProxy(pkgName); + if (clientProxy == nullptr) { + LOG_ERR("softbus client proxy is nullptr!\n"); + return SOFTBUS_ERR; + } + return clientProxy->OnLeaveLNNResult(networkId, retCode); +} + +static int ClinetOnNodeOnlineStateChanged(bool isOnline, void *info, uint32_t infoTypeLen) +{ + sptr softbusServer = SoftBusServer::GetInstance(); + if (softbusServer == nullptr) { + LOG_ERR("softbusServer is nullptr!\n"); + return SOFTBUS_ERR; + } + std::map> proxyMap; + softbusServer->GetSoftbusClientProxyMap(proxyMap); + for (auto proxy : proxyMap) { + if (!CheckBusCenterPermission(proxy.first.c_str())) { + continue; + } + proxy.second->OnNodeOnlineStateChanged(isOnline, info, infoTypeLen); + } + return SOFTBUS_OK; +} + +static int ClinetOnNodeBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type) +{ + sptr softbusServer = SoftBusServer::GetInstance(); + if (softbusServer == nullptr) { + LOG_ERR("softbusServer is nullptr!\n"); + return SOFTBUS_ERR; + } + std::map> proxyMap; + softbusServer->GetSoftbusClientProxyMap(proxyMap); + for (auto proxy : proxyMap) { + if (!CheckBusCenterPermission(proxy.first.c_str())) { + continue; + } + proxy.second->OnNodeBasicInfoChanged(info, infoTypeLen, type); + } + return SOFTBUS_OK; +} + +static struct ClientProvideInterface g_clientProvideInterface = { + .onDeviceFound = ClientIpcOnDeviceFound, + .onDiscoverySuccess = ClientIpcOnDiscoverySuccess, + .onDiscoverFailed = ClientIpcOnDiscoverFailed, + .onPublishSuccess = ClientIpcOnPublishSuccess, + .onPublishFail = ClientIpcOnPublishFail, + .onChannelOpened = ClientIpcOnChannelOpened, + .onChannelOpenFailed = ClientIpcOnChannelOpenFailed, + .onChannelClosed = ClientIpcOnChannelClosed, + .onChannelMsgReceived = ClientIpcOnChannelMsgReceived, + .onJoinLNNResult = ClientOnJoinLNNResult, + .onLeaveLNNResult = ClientOnLeaveLNNResult, + .onNodeOnlineStateChanged = ClinetOnNodeOnlineStateChanged, + .onNodeBasicInfoChanged = ClinetOnNodeBasicInfoChanged, +}; + +struct ClientProvideInterface *GetClientProvideInterface(void) +{ + return &g_clientProvideInterface; +} \ No newline at end of file diff --git a/core/frame/standard/server/src/softbus_interface_server.cpp b/core/frame/standard/server/src/softbus_interface_server.cpp new file mode 100755 index 000000000..914a21287 --- /dev/null +++ b/core/frame/standard/server/src/softbus_interface_server.cpp @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_interface.h" + +#include +#include +#include "if_softbus_server.h" +#include "ipc_skeleton.h" +#include "softbus_client_death_recipient.h" +#include "softbus_client_frame_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "system_ability_definition.h" + +using namespace OHOS; + +namespace { +sptr g_serverProxy = nullptr; +sptr g_clientDeath = nullptr; +std::mutex g_mutex; +uint32_t g_waitServerInterval = 2; +uint32_t g_getSystemAbilityId = 2; +} + +static int ServerIpcStartDiscovery(const char *pkgName, const void *info) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + int ret = g_serverProxy->StartDiscovery(pkgName, info); + return ret; +} + +static int ServerIpcStopDiscovery(const char *pkgName, int subscribeId) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + int ret = g_serverProxy->StopDiscovery(pkgName, subscribeId); + return ret; +} + +static int ServerIpcPublishService(const char *pkgName, const void *info) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + int ret = g_serverProxy->PublishService(pkgName, info); + return ret; +} + +static int ServerIpcUnPublishService(const char *pkgName, int publishId) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + int ret = g_serverProxy->UnPublishService(pkgName, publishId); + return ret; +} + +static int ServerIpcRegisterService(const char *name, const void *info) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + int ret = g_serverProxy->SoftbusRegisterService(name, nullptr); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcRegisterService failed!\n"); + return ret; + } + LOG_INFO("softbus server register service success!\n"); + return SOFTBUS_OK; +} + +static int ServerIpcCreateSessionServer(const char *pkgName, const char *sessionName) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + if ((pkgName == nullptr) || (sessionName == nullptr)) { + return SOFTBUS_ERR; + } + + int ret = g_serverProxy->CreateSessionServer(pkgName, sessionName); + if (ret != SOFTBUS_OK) { + LOG_ERR("CreateSessionServer failed!\n"); + return ret; + } + LOG_INFO("softbus server create session server success!\n"); + return SOFTBUS_OK; +} + +static int ServerIpcRemoveSessionServer(const char *pkgName, const char *sessionName) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + if ((pkgName == nullptr) || (sessionName == nullptr)) { + return SOFTBUS_ERR; + } + + int ret = g_serverProxy->RemoveSessionServer(pkgName, sessionName); + if (ret != SOFTBUS_OK) { + LOG_ERR("RemoveSessionServer failed!\n"); + return ret; + } + LOG_INFO("softbus server remove session server success!\n"); + return SOFTBUS_OK; +} + +static int ServerIpcOpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + if ((mySessionName == nullptr) || (peerSessionName == nullptr) || + (peerDeviceId == nullptr) || (groupId == nullptr)) { + return SOFTBUS_ERR; + } + + int channelId = g_serverProxy->OpenSession(mySessionName, peerSessionName, peerDeviceId, groupId, flags); + if (channelId < SOFTBUS_OK) { + LOG_ERR("OpenSession failed!\n"); + return SOFTBUS_ERR; + } + LOG_INFO("softbus server open session success!\n"); + return channelId; +} + +static int ServerIpcSendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("softbus server g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + + int ret = g_serverProxy->SendMessage(channelId, data, len, msgType); + if (ret != SOFTBUS_OK) { + LOG_ERR("OpenSession failed!\n"); + return ret; + } + LOG_INFO("softbus server open session success!\n"); + return SOFTBUS_OK; +} + +static int ServerIpcJoinLNN(void *addr, unsigned int addrTypeLen) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("ServerIpcJoinLNN g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + char clientName[PKG_NAME_SIZE_MAX]; + int ret = GetSoftBusClientName(clientName, PKG_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + LOG_ERR("SoftbusJoinLNN get client name failed!"); + return ret; + } + ret = g_serverProxy->JoinLNN(clientName, addr, addrTypeLen); + if (ret != 0) { + LOG_ERR("ServerIpcJoinLNN failed!\n"); + return ret; + } + return ret; +} + +static int ServerIpcLeaveLNN(const char *networkId) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("ServerIpcLeaveLNN g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + char clientName[PKG_NAME_SIZE_MAX]; + int ret = GetSoftBusClientName(clientName, PKG_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcLeaveLNN get client name failed!"); + return ret; + } + ret = g_serverProxy->LeaveLNN(clientName, networkId); + if (ret != 0) { + LOG_ERR("ServerIpcLeaveLNN failed!\n"); + return ret; + } + return ret; +} + +static int ServerIpcGetAllOnlineNodeInfo(void **info, uint32_t infoTypeLen, int32_t *infoNum) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("ServerIpcGetAllOnlineNodeInfo g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + char clientName[PKG_NAME_SIZE_MAX]; + int ret = GetSoftBusClientName(clientName, PKG_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetAllOnlineNodeInfo get client name failed!"); + return ret; + } + ret = g_serverProxy->GetAllOnlineNodeInfo(clientName, info, infoTypeLen, infoNum); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetAllOnlineNodeInfo get all online info failed!\n"); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t ServerIpcGetLocalDeviceInfo(void *info, uint32_t infoTypeLen) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("ServerIpcGetLocalDeviceInfo g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + char clientName[PKG_NAME_SIZE_MAX]; + int ret = GetSoftBusClientName(clientName, PKG_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetLocalDeviceInfo get client name failed!"); + return ret; + } + ret = g_serverProxy->GetLocalDeviceInfo(clientName, info, infoTypeLen); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetLocalDeviceInfo get local device info failed!\n"); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t ServerIpcGetNodeKeyInfo(const char *networkId, int key, unsigned char *buf, uint32_t len) +{ + if (g_serverProxy == nullptr) { + LOG_ERR("ServerIpcGetNodeKeyInfo g_serverProxy is nullptr!\n"); + return SOFTBUS_ERR; + } + char clientName[PKG_NAME_SIZE_MAX]; + int ret = GetSoftBusClientName(clientName, PKG_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetNodeKeyInfo get client name failed!"); + return ret; + } + + ret = g_serverProxy->GetNodeKeyInfo(clientName, networkId, key, buf, len); + if (ret != SOFTBUS_OK) { + LOG_ERR("ServerIpcGetNodeKeyInfo get node key info failed!\n"); + return ret; + } + return SOFTBUS_OK; +} + +static struct ServerProvideInterface g_serverProvideInterface = { + .startDiscovery = ServerIpcStartDiscovery, + .createSessionServer = ServerIpcCreateSessionServer, + .removeSessionServer = ServerIpcRemoveSessionServer, + .openSession = ServerIpcOpenSession, + .sendMessage = ServerIpcSendMessage, + .stopDiscovery = ServerIpcStopDiscovery, + .publishService = ServerIpcPublishService, + .unPublishService = ServerIpcUnPublishService, + .joinLNN = ServerIpcJoinLNN, + .leaveLNN = ServerIpcLeaveLNN, + .getAllOnlineNodeInfo = ServerIpcGetAllOnlineNodeInfo, + .getLocalDeviceInfo = ServerIpcGetLocalDeviceInfo, + .getNodeKeyInfo = ServerIpcGetNodeKeyInfo, +}; + +static sptr GetSystemAbility() +{ + MessageParcel data; + data.WriteInt32(SOFTBUS_SERVER_SA_ID); + MessageParcel reply; + MessageOption option; + sptr samgr = IPCSkeleton::GetContextObject(); + int32_t err = samgr->SendRequest(g_getSystemAbilityId, data, reply, option); + if (err != 0) { + LOG_ERR("Get GetSystemAbility failed!\n"); + return nullptr; + } + return reply.ReadRemoteObject(); +} + +int ServerProvideInterfaceInit(void) +{ + if (g_serverProxy == nullptr) { + std::lock_guard lock(g_mutex); + if (g_serverProxy == nullptr) { + sptr object = GetSystemAbility(); + g_serverProxy = iface_cast(object); + if (g_serverProxy == nullptr || g_serverProxy->AsObject() == nullptr) { + LOG_ERR("Get remote softbus object failed!\n"); + return SOFTBUS_ERR; + } + g_clientDeath = sptr(new (std::nothrow) SoftBusClientDeathRecipient()); + if (g_clientDeath == nullptr) { + LOG_ERR("DeathRecipient object is nullptr\n"); + return SOFTBUS_ERR; + } + if (!g_serverProxy->AsObject()->AddDeathRecipient(g_clientDeath)) { + LOG_ERR("AddDeathRecipient failed\n"); + return SOFTBUS_ERR; + } + } + } + return SOFTBUS_OK; +} + +struct ServerProvideInterface *GetServerProvideInterface(void) +{ + return &g_serverProvideInterface; +} + +int ClientProvideInterfaceImplInit(void) +{ + char clientName[PKG_NAME_SIZE_MAX] = {0}; + int ret = GetSoftBusClientName(clientName, sizeof(clientName)); + if (ret != SOFTBUS_OK) { + LOG_ERR("get client name failed"); + return ret; + } + ret = ServerIpcRegisterService(clientName, nullptr); + if (ret != SOFTBUS_OK) { + LOG_ERR("server register service failed!\n"); + return ret; + } + return SOFTBUS_OK; +} + +void ClientDeathProcTask(void) +{ + { + std::lock_guard lock(g_mutex); + if (g_serverProxy->AsObject() != nullptr && g_clientDeath != nullptr) { + g_serverProxy->AsObject()->RemoveDeathRecipient(g_clientDeath); + } + g_serverProxy = nullptr; + } + + while (g_serverProxy == nullptr) { + sleep(g_waitServerInterval); + ServerProvideInterfaceInit(); + if (g_serverProxy != nullptr) { + break; + } + } + ClientProvideInterfaceImplInit(); +} diff --git a/core/frame/standard/server/src/softbus_server.cpp b/core/frame/standard/server/src/softbus_server.cpp new file mode 100755 index 000000000..0442e3abf --- /dev/null +++ b/core/frame/standard/server/src/softbus_server.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server.h" + +#include "softbus_disc_server.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_server_frame.h" +#include "system_ability_definition.h" + +extern "C" int __attribute__ ((weak)) DiscIpcPublishService(const char *packageName, const PublishInfo *info) +{ + LOG_INFO("DiscIpcPublishService Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) DiscIpcUnPublishService(const char *packageName, int publishId) +{ + LOG_INFO("DiscIpcUnPublishService Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) DiscIpcStartDiscovery(const char *packageName, const SubscribeInfo *info) +{ + LOG_INFO("DiscIpcStartDiscovery Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) DiscIpcStopDiscovery(const char *packageName, int subscribeId) +{ + LOG_INFO("DiscIpcStopDiscovery Weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransCreateSessionServer(const char *pkgName, const char *sessionName) +{ + LOG_INFO("TransCreateSessionServer!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransRemoveSessionServer(const char *pkgName, const char *sessionName) +{ + LOG_INFO("TransRemoveSessionServer!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransOpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) +{ + LOG_INFO("TransOpenSession!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransCloseChannel(int32_t channelId) +{ + LOG_INFO("TransCloseChannel!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) TransSendMsg(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + LOG_INFO("TransCloseChannel!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + LOG_INFO("LnnIpcServerJoin weak!\n"); + return SOFTBUS_OK; +} + +extern "C" int __attribute__ ((weak)) LnnIpcServerLeave(const char *pkgName, const char *networkId) +{ + LOG_INFO("LnnIpcServerLeave weak!\n"); + return SOFTBUS_NOT_IMPLEMENT; +} + +extern "C" int __attribute__ ((weak)) LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, + uint32_t infoTypeLen, int *infoNum) +{ + LOG_INFO("LnnIpcGetAllOnlineNodeInfo weak!\n"); + return SOFTBUS_NOT_IMPLEMENT; +} + +extern "C" int __attribute__ ((weak)) LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + LOG_INFO("LnnIpcGetLocalDeviceInfo weak!\n"); + return SOFTBUS_NOT_IMPLEMENT; +} + +extern "C" int __attribute__ ((weak)) GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + LOG_INFO("LnnIpcGetLocalDeviceInfo weak!\n"); + return SOFTBUS_NOT_IMPLEMENT; +} + +extern "C" int __attribute__ ((weak)) LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, + int key, unsigned char *buf, uint32_t len) +{ + LOG_INFO("LnnIpcGetNodeKeyInfo weak!\n"); + return SOFTBUS_NOT_IMPLEMENT; +} + +namespace OHOS { +REGISTER_SYSTEM_ABILITY_BY_ID(SoftBusServer, SOFTBUS_SERVER_SA_ID, true); +std::mutex SoftBusServer::instanceLock_; +sptr SoftBusServer::instance_; +std::map> SoftBusServer::clientObjectMap_; + +SoftBusServer::SoftBusServer(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +{ +} + +sptr SoftBusServer::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new (std::nothrow) SoftBusServer(SOFTBUS_SERVER_SA_ID, true); + } + } + return instance_; +} + +int32_t SoftBusServer::StartDiscovery(const char *pkgName, const void *info) +{ + int32_t ret = DiscIpcStartDiscovery(pkgName, (SubscribeInfo *)info); + return ret; +} + +int32_t SoftBusServer::StopDiscovery(const char *pkgName, int subscribeId) +{ + int32_t ret = DiscIpcStopDiscovery(pkgName, subscribeId); + return ret; +} + +int32_t SoftBusServer::PublishService(const char *pkgName, const void *info) +{ + int32_t ret = DiscIpcPublishService(pkgName, (PublishInfo *)info); + return ret; +} + +int32_t SoftBusServer::UnPublishService(const char *pkgName, int publishId) +{ + int32_t ret = DiscIpcUnPublishService(pkgName, publishId); + return ret; +} + +sptr SoftBusServer::GetSoftbusClientProxy(const char *pkgName) +{ + std::lock_guard autoLock(clientObjectMapLock_); + auto iter = clientObjectMap_.find(pkgName); + if (iter != clientObjectMap_.end()) { + sptr clientProxy = iface_cast(iter->second); + if (clientProxy != nullptr) { + return clientProxy; + } + } + LOG_ERR("GetSoftbusClientProxy client proxy is nullptr\n"); + return nullptr; +} + +void SoftBusServer::GetSoftbusClientProxyMap(std::map> &softbusClientMap) +{ + std::lock_guard autoLock(clientObjectMapLock_); + for (auto iter = clientObjectMap_.begin(); iter != clientObjectMap_.end(); ++iter) { + sptr clientProxy = iface_cast(iter->second); + softbusClientMap.insert(std::pair>(iter->first, clientProxy)); + } +} + +int32_t SoftBusServer::SoftbusRegisterService(const char *clientPkgName, const sptr &object) +{ + if (object == nullptr) { + LOG_ERR("RegisterService object is nullptr\n"); + return SOFTBUS_ERR; + } + std::lock_guard autoLock(clientObjectMapLock_); + clientObjectMap_.insert(std::pair>(clientPkgName, object)); + + abilityDeath_ = sptr(new (std::nothrow) SoftBusDeathRecipient()); + if (abilityDeath_ == nullptr) { + LOG_ERR("DeathRecipient object is nullptr\n"); + return SOFTBUS_ERR; + } + bool ret = object->AddDeathRecipient(abilityDeath_); + if (!ret) { + LOG_ERR("AddDeathRecipient failed\n"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServer::SoftbusRemoveService(const sptr &object) +{ + if (object == nullptr) { + LOG_ERR("RemoveService object is nullptr\n"); + return SOFTBUS_ERR; + } + std::lock_guard autoLock(clientObjectMapLock_); + for (auto iter = clientObjectMap_.begin(); iter != clientObjectMap_.end(); ++iter) { + if (iter->second == object) { + (void)clientObjectMap_.erase(iter); + if (abilityDeath_ != nullptr) { + object->RemoveDeathRecipient(abilityDeath_); + } + LOG_INFO("softbus client removed, size : %u", clientObjectMap_.size()); + break; + } + } + return SOFTBUS_OK; +} + +int32_t SoftBusServer::CreateSessionServer(const char *pkgName, const char *sessionName) +{ + return TransCreateSessionServer(pkgName, sessionName); +} + +int32_t SoftBusServer::RemoveSessionServer(const char *pkgName, const char *sessionName) +{ + return TransRemoveSessionServer(pkgName, sessionName); +} + +int32_t SoftBusServer::OpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) +{ + return TransOpenSession(mySessionName, peerSessionName, peerDeviceId, groupId, flags); +} + +int32_t SoftBusServer::CloseChannel(int32_t channelId) +{ + return TransCloseChannel(channelId); +} + +int32_t SoftBusServer::SendMessage(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + return TransSendMsg(channelId, data, len, msgType); +} + +int32_t SoftBusServer::JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + return LnnIpcServerJoin(pkgName, addr, addrTypeLen); +} + +int32_t SoftBusServer::LeaveLNN(const char *pkgName, const char *networkId) +{ + return LnnIpcServerLeave(pkgName, networkId); +} + +int32_t SoftBusServer::GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum) +{ + return LnnIpcGetAllOnlineNodeInfo(pkgName, info, infoTypeLen, infoNum); +} + +int32_t SoftBusServer::GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + return LnnIpcGetLocalDeviceInfo(pkgName, info, infoTypeLen); +} + +int32_t SoftBusServer::GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, + uint32_t len) +{ + return LnnIpcGetNodeKeyInfo(pkgName, networkId, key, buf, len); +} + +void SoftBusServer::OnStart() +{ + LOG_INFO("SoftBusServer OnStart called!\n"); + if (!Publish(this)) { + LOG_ERR("SoftBusServer publish failed!\n"); + } + InitSoftBusServer(); +} + +void SoftBusServer::OnStop() +{ + if (!clientObjectMap_.empty()) { + std::lock_guard autoLock(clientObjectMapLock_); + clientObjectMap_.clear(); + } +} +} // namespace OHOS diff --git a/core/frame/standard/server/src/softbus_server.rc b/core/frame/standard/server/src/softbus_server.rc new file mode 100644 index 000000000..2d5c9e333 --- /dev/null +++ b/core/frame/standard/server/src/softbus_server.rc @@ -0,0 +1,21 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +on post-fs-data + start softbus_server + +service softbus_server /system/bin/sa_main /system/profile/softbus_server.xml + class z_core + user system + group system shell + seclabel u:r:softbus_server:s0 diff --git a/core/frame/standard/server/src/softbus_server_death_recipient.cpp b/core/frame/standard/server/src/softbus_server_death_recipient.cpp new file mode 100755 index 000000000..29c4b9844 --- /dev/null +++ b/core/frame/standard/server/src/softbus_server_death_recipient.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_death_recipient.h" + +#include "softbus_log.h" +#include "softbus_server.h" + +namespace OHOS { +void SoftBusDeathRecipient::OnRemoteDied(const wptr &remote) +{ + LOG_INFO("service died, remove the proxy object"); + SoftBusServer::GetInstance()->SoftbusRemoveService(remote.promote()); + LOG_INFO("recv death notice success"); +} +} // namespace OHOS \ No newline at end of file diff --git a/core/frame/standard/server/src/softbus_server_frame.c b/core/frame/standard/server/src/softbus_server_frame.c new file mode 100755 index 000000000..cfebcdb73 --- /dev/null +++ b/core/frame/standard/server/src/softbus_server_frame.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_frame.h" + +#include "message_handler.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_utils.h" + +int __attribute__ ((weak)) BusCenterServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) BusCenterServerDeinit(void) +{ +} + +int __attribute__ ((weak)) TransServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) TransServerDeinit(void) +{ +} + +int __attribute__ ((weak)) AuthInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) AuthDeinit(void) +{ +} + +int __attribute__ ((weak)) ConnServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) ConnServerDeinit(void) +{ +} + +int __attribute__ ((weak)) DiscServerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) DiscServerDeinit(void) +{ +} + +static void ServerModuleDeinit(void) +{ + DiscServerDeinit(); + ConnServerDeinit(); + TransServerDeinit(); + BusCenterServerDeinit(); + AuthDeinit(); + SoftBusTimerDeInit(); + LooperDeinit(); +} + +void InitSoftBusServer(void) +{ + if (SoftBusTimerInit() != SOFTBUS_OK) { + return; + } + + if (LooperInit() != SOFTBUS_OK) { + return; + } + + if (ConnServerInit() != SOFTBUS_OK) { + LOG_ERR("softbus conn server init failed."); + goto ERR_EXIT; + } + + if (TransServerInit() != SOFTBUS_OK) { + LOG_ERR("softbus trans server init failed."); + goto ERR_EXIT; + } + + if (AuthInit() != SOFTBUS_OK) { + LOG_ERR("softbus auth init failed."); + goto ERR_EXIT; + } + + if (BusCenterServerInit() != SOFTBUS_OK) { + LOG_ERR("softbus buscenter server init failed."); + goto ERR_EXIT; + } + + if (DiscServerInit() != SOFTBUS_OK) { + LOG_ERR("softbus disc server init failed."); + goto ERR_EXIT; + } + + return; + +ERR_EXIT: + ServerModuleDeinit(); + LOG_ERR("softbus server framework init failed."); + return; +} \ No newline at end of file diff --git a/core/frame/standard/server/src/softbus_server_proxy.cpp b/core/frame/standard/server/src/softbus_server_proxy.cpp new file mode 100755 index 000000000..0a7fc8381 --- /dev/null +++ b/core/frame/standard/server/src/softbus_server_proxy.cpp @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_proxy.h" + +#include + +#include "discovery_service.h" +#include "message_parcel.h" +#include "softbus_client_stub.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +namespace OHOS { +sptr SoftBusServerProxy::clientCallbackStub_; +std::mutex SoftBusServerProxy::instanceLock; + +sptr SoftBusServerProxy::GetRemoteInstance() +{ + if (clientCallbackStub_ == nullptr) { + std::lock_guard autoLock(instanceLock); + if (clientCallbackStub_ == nullptr) { + clientCallbackStub_ = sptr(new (std::nothrow) SoftBusClientStub()); + } + } + return clientCallbackStub_; +} + +int32_t SoftBusServerProxy::StartDiscovery(const char *pkgName, const void *info) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + SubscribeInfo *subInfo = (SubscribeInfo *)info; + + data.WriteCString(pkgName); + data.WriteInt32(subInfo->subscribeId); + data.WriteInt32(subInfo->mode); + data.WriteInt32(subInfo->medium); + data.WriteInt32(subInfo->freq); + data.WriteBool(subInfo->isSameAccount); + data.WriteBool(subInfo->isWakeRemote); + data.WriteCString(subInfo->capability); + data.WriteCString((char *)subInfo->capabilityData); + data.WriteUint32(subInfo->dataLen); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(SERVER_START_DISCOVERY, data, reply, option); + if (err != 0) { + LOG_ERR("StartDiscovery send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + int32_t ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("StartDiscovery read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::StopDiscovery(const char *pkgName, int subscribeId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + + data.WriteCString(pkgName); + data.WriteInt32(subscribeId); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(SERVER_STOP_DISCOVERY, data, reply, option); + LOG_ERR("StopDiscovery send request ret = %d!", err); + if (err != 0) { + LOG_ERR("StopDiscovery send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + int32_t ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("StopDiscovery read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::PublishService(const char *pkgName, const void *info) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + PublishInfo *pubInfo = (PublishInfo *)info; + + data.WriteCString(pkgName); + data.WriteInt32(pubInfo->publishId); + data.WriteInt32(pubInfo->mode); + data.WriteInt32(pubInfo->medium); + data.WriteInt32(pubInfo->freq); + data.WriteCString(pubInfo->capability); + data.WriteCString((char *)pubInfo->capabilityData); + data.WriteUint32(pubInfo->dataLen); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(SERVER_PUBLISH_SERVICE, data, reply, option); + LOG_ERR("PublishService send request ret = %d!", err); + if (err != 0) { + LOG_ERR("PublishService send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + int32_t ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("PublishService read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::UnPublishService(const char *pkgName, int publishId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + + data.WriteCString(pkgName); + data.WriteInt32(publishId); + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(SERVER_UNPUBLISH_SERVICE, data, reply, option); + LOG_ERR("UnPublishService send request ret = %d!", err); + if (err != 0) { + LOG_ERR("UnPublishService send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + int32_t ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("UnPublishService read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::SoftbusRegisterService(const char *clientPkgName, const sptr& object) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + int ret = data.WriteRemoteObject(SoftBusServerProxy::GetRemoteInstance()); + if (!ret) { + LOG_ERR("SoftbusRegisterService write remote object failed!"); + return SOFTBUS_ERR; + } + ret = data.WriteCString(clientPkgName); + if (!ret) { + LOG_ERR("SoftbusRegisterService write clientPkgName failed!"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(MANAGE_REGISTER_SERVICE, data, reply, option); + if (err != 0) { + LOG_ERR("SoftbusRegisterService send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("SoftbusRegisterService read serverRet failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerProxy::CreateSessionServer(const char *pkgName, const char *sessionName) +{ + if (pkgName == nullptr || sessionName == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("CreateSessionServer write pkg name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(sessionName)) { + LOG_ERR("CreateSessionServer write session name failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_CREATE_SESSION_SERVER, data, reply, option) != 0) { + LOG_ERR("CreateSessionServer send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("CreateSessionServer read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::RemoveSessionServer(const char *pkgName, const char *sessionName) +{ + if (pkgName == nullptr || sessionName == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("RemoveSessionServer write pkg name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(sessionName)) { + LOG_ERR("RemoveSessionServer session name failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_REMOVE_SESSION_SERVER, data, reply, option) != 0) { + LOG_ERR("RemoveSessionServer send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("RemoveSessionServer read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::OpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) +{ + if (mySessionName == nullptr || peerSessionName == nullptr || peerDeviceId == nullptr || groupId == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(mySessionName)) { + LOG_ERR("OpenSession write my session name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(peerSessionName)) { + LOG_ERR("OpenSession write peer session name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(peerDeviceId)) { + LOG_ERR("OpenSession write addr type length failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(groupId)) { + LOG_ERR("OpenSession write addr type length failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(flags)) { + LOG_ERR("OpenSession write addr type length failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_OPEN_SESSION, data, reply, option) != 0) { + LOG_ERR("OpenSession send request failed!"); + return SOFTBUS_ERR; + } + int32_t channelId = 0; + if (!reply.ReadInt32(channelId)) { + LOG_ERR("OpenSession read channelId failed!"); + return SOFTBUS_ERR; + } + return channelId; +} + +int32_t SoftBusServerProxy::CloseChannel(int32_t channelId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + MessageParcel data; + if (!data.WriteInt32(channelId)) { + LOG_ERR("CloseChannel write channel id failed!"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_CLOSE_CHANNEL, data, reply, option) != 0) { + LOG_ERR("CloseChannel send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("CloseChannel read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::SendMessage(int32_t channelId, const void *dataInfo, uint32_t len, int32_t msgType) +{ + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + MessageParcel data; + if (!data.WriteInt32(channelId)) { + LOG_ERR("SendMessage write channel id failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(len)) { + LOG_ERR("SendMessage write dataInfo len failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(dataInfo, len)) { + LOG_ERR("SendMessage write dataInfo failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(msgType)) { + LOG_ERR("SendMessage msgType failed!"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_SESSION_SENDMSG, data, reply, option) != 0) { + LOG_ERR("SendMessage send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("SendMessage read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::JoinLNN(const char *pkgName, void *addr, uint32_t addrTypeLen) +{ + if (pkgName == nullptr || addr == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + if (!data.WriteCString(pkgName)) { + LOG_ERR("JoinLNN write client name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(addrTypeLen)) { + LOG_ERR("JoinLNN write addr type length failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteRawData(addr, addrTypeLen)) { + LOG_ERR("JoinLNN write addr failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_JOIN_LNN, data, reply, option) != 0) { + LOG_ERR("JoinLNN send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + if (!reply.ReadInt32(serverRet)) { + LOG_ERR("JoinLNN read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::LeaveLNN(const char *pkgName, const char *networkId) +{ + if (pkgName == nullptr || networkId == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + int32_t ret = data.WriteCString(pkgName); + if (!ret) { + LOG_ERR("LeaveLNN write client name failed!"); + return SOFTBUS_ERR; + } + ret = data.WriteCString(networkId); + if (!ret) { + LOG_ERR("LeaveLNN write networkId failed!"); + return SOFTBUS_ERR; + } + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(SERVER_LEAVE_LNN, data, reply, option); + if (err != 0) { + LOG_ERR("LeaveLNN send request failed!"); + return SOFTBUS_ERR; + } + int32_t serverRet = 0; + ret = reply.ReadInt32(serverRet); + if (!ret) { + LOG_ERR("LeaveLNN read serverRet failed!"); + return SOFTBUS_ERR; + } + return serverRet; +} + +int32_t SoftBusServerProxy::GetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, + int32_t *infoNum) +{ + if (info == nullptr || infoNum == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + int32_t ret = data.WriteCString(pkgName); + if (!ret) { + LOG_ERR("GetAllOnlineNodeInfo write client name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(infoTypeLen)) { + LOG_ERR("GetAllOnlineNodeInfo write info type length failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_GET_ALL_ONLINE_NODE_INFO, data, reply, option) != 0) { + LOG_ERR("GetAllOnlineNodeInfo send request failed!"); + return SOFTBUS_ERR; + } + if (!reply.ReadInt32(*infoNum)) { + LOG_ERR("GetAllOnlineNodeInfo read infoNum failed!"); + return SOFTBUS_ERR; + } + int32_t infoSize = (*infoNum) * (int32_t)infoTypeLen; + *info = nullptr; + if (infoSize > 0) { + void *nodeInfo = (void *)reply.ReadRawData(infoSize); + if (nodeInfo == nullptr) { + LOG_ERR("GetAllOnlineNodeInfo read node info failed!"); + return SOFTBUS_ERR; + } + *info = SoftBusMalloc(infoSize); + if (*info == nullptr) { + LOG_ERR("GetAllOnlineNodeInfo malloc failed!"); + return SOFTBUS_ERR; + } + if (memcpy_s(*info, infoSize, nodeInfo, infoSize) != EOK) { + LOG_ERR("GetAllOnlineNodeInfo copy node info failed!"); + SoftBusFree(*info); + return SOFTBUS_ERR; + } + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerProxy::GetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen) +{ + if (info == nullptr) { + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + int32_t ret = data.WriteCString(pkgName); + if (!ret) { + LOG_ERR("GetLocalDeviceInfo write client name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteUint32(infoTypeLen)) { + LOG_ERR("GetLocalDeviceInfo write info type length failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_GET_LOCAL_DEVICE_INFO, data, reply, option) != 0) { + LOG_ERR("GetLocalDeviceInfo send request failed!"); + return SOFTBUS_ERR; + } + void *nodeInfo = (void *)reply.ReadRawData(infoTypeLen); + if (nodeInfo == nullptr) { + LOG_ERR("GetLocalDeviceInfo read node info failed!"); + return SOFTBUS_ERR; + } + if (memcpy_s(info, infoTypeLen, nodeInfo, infoTypeLen) != EOK) { + LOG_ERR("GetLocalDeviceInfo copy node info failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerProxy::GetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, + uint32_t len) +{ + if (networkId == nullptr || buf == nullptr) { + LOG_ERR("params are nullptr!"); + return SOFTBUS_ERR; + } + sptr remote = Remote(); + if (remote == nullptr) { + LOG_ERR("remote is nullptr!"); + return SOFTBUS_ERR; + } + + MessageParcel data; + int32_t ret = data.WriteCString(pkgName); + if (!ret) { + LOG_ERR("GetNodeKeyInfo write client name failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteCString(networkId)) { + LOG_ERR("GetNodeKeyInfo write networkId failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(key)) { + LOG_ERR("GetNodeKeyInfo write key failed!"); + return SOFTBUS_ERR; + } + if (!data.WriteInt32(len)) { + LOG_ERR("GetNodeKeyInfo write buf len failed!"); + return SOFTBUS_ERR; + } + MessageParcel reply; + MessageOption option; + if (remote->SendRequest(SERVER_GET_NODE_KEY_INFO, data, reply, option) != 0) { + LOG_ERR("GetNodeKeyInfo send request failed!"); + return SOFTBUS_ERR; + } + void *retBuf = (void *)reply.ReadRawData(len); + if (retBuf == nullptr) { + LOG_ERR("GetNodeKeyInfo read retBuf failed!"); + return SOFTBUS_ERR; + } + if (memcpy_s(buf, len, retBuf, len) != EOK) { + LOG_ERR("GetNodeKeyInfo copy node key info failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} +} // namespace OHOS diff --git a/core/frame/standard/server/src/softbus_server_stub.cpp b/core/frame/standard/server/src/softbus_server_stub.cpp new file mode 100755 index 000000000..0e4c19d0b --- /dev/null +++ b/core/frame/standard/server/src/softbus_server_stub.cpp @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_server_stub.h" + +#include "discovery_service.h" +#include "ipc_skeleton.h" +#include "ipc_types.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_server.h" + +namespace OHOS { +SoftBusServerStub::SoftBusServerStub() +{ + memberFuncMap_[SERVER_START_DISCOVERY] = + &SoftBusServerStub::StartDiscoveryInner; + memberFuncMap_[SERVER_STOP_DISCOVERY] = + &SoftBusServerStub::StopDiscoveryInner; + memberFuncMap_[SERVER_PUBLISH_SERVICE] = + &SoftBusServerStub::PublishServiceInner; + memberFuncMap_[SERVER_UNPUBLISH_SERVICE] = + &SoftBusServerStub::UnPublishServiceInner; + memberFuncMap_[MANAGE_REGISTER_SERVICE] = + &SoftBusServerStub::SoftbusRegisterServiceInner; + memberFuncMap_[SERVER_CREATE_SESSION_SERVER] = + &SoftBusServerStub::CreateSessionServerInner; + memberFuncMap_[SERVER_REMOVE_SESSION_SERVER] = + &SoftBusServerStub::RemoveSessionServerInner; + memberFuncMap_[SERVER_OPEN_SESSION] = + &SoftBusServerStub::OpenSessionInner; + memberFuncMap_[SERVER_CLOSE_CHANNEL] = + &SoftBusServerStub::CloseChannelInner; + memberFuncMap_[SERVER_SESSION_SENDMSG] = + &SoftBusServerStub::SendMessageInner; + memberFuncMap_[SERVER_JOIN_LNN] = + &SoftBusServerStub::JoinLNNInner; + memberFuncMap_[SERVER_LEAVE_LNN] = + &SoftBusServerStub::LeaveLNNInner; + memberFuncMap_[SERVER_GET_ALL_ONLINE_NODE_INFO] = + &SoftBusServerStub::GetAllOnlineNodeInfoInner; + memberFuncMap_[SERVER_GET_LOCAL_DEVICE_INFO] = + &SoftBusServerStub::GetLocalDeviceInfoInner; + memberFuncMap_[SERVER_GET_NODE_KEY_INFO] = + &SoftBusServerStub::GetNodeKeyInfoInner; +} + +int32_t SoftBusServerStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + LOG_INFO("SoftBusServerStub::OnReceived, code = %u", code); + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + return (this->*memberFunc)(data, reply); + } + } + LOG_INFO("SoftBusServerStub:: default case, need check."); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t SoftBusServerStub::StartDiscoveryInner(MessageParcel &data, MessageParcel &reply) +{ + SubscribeInfo subInfo; + const char *pkgName = data.ReadCString(); + subInfo.subscribeId = data.ReadInt32(); + subInfo.mode = (DiscoverMode)data.ReadInt32(); + subInfo.medium = (ExchanageMedium)data.ReadInt32(); + subInfo.freq = (ExchangeFreq)data.ReadInt32(); + subInfo.isSameAccount = data.ReadBool(); + subInfo.isWakeRemote = data.ReadBool(); + subInfo.capability = data.ReadCString(); + subInfo.capabilityData = (unsigned char *)data.ReadCString(); + subInfo.dataLen = data.ReadUint32(); + int32_t retReply = StartDiscovery(pkgName, &subInfo); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("StartDiscoveryInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::StopDiscoveryInner(MessageParcel &data, MessageParcel &reply) +{ + const char *pkgName = data.ReadCString(); + int32_t subscribeId = data.ReadInt32(); + LOG_INFO("StopDiscoveryInner %s, %d!\n", pkgName, subscribeId); + int32_t retReply = StopDiscovery(pkgName, subscribeId); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("StopDiscoveryInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::PublishServiceInner(MessageParcel &data, MessageParcel &reply) +{ + PublishInfo pubInfo; + const char *pkgName = data.ReadCString(); + pubInfo.publishId = data.ReadInt32(); + pubInfo.mode = (DiscoverMode)data.ReadInt32(); + pubInfo.medium = (ExchanageMedium)data.ReadInt32(); + pubInfo.freq = (ExchangeFreq)data.ReadInt32(); + pubInfo.capability = data.ReadCString(); + pubInfo.capabilityData = (unsigned char *)data.ReadCString(); + pubInfo.dataLen = data.ReadUint32(); + int32_t retReply = PublishService(pkgName, &pubInfo); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("PublishServiceInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::UnPublishServiceInner(MessageParcel &data, MessageParcel &reply) +{ + const char *pkgName = data.ReadCString(); + int32_t publishId = data.ReadInt32(); + int32_t retReply = UnPublishService(pkgName, publishId); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("UnPublishServiceInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::SoftbusRegisterServiceInner(MessageParcel &data, MessageParcel &reply) +{ + auto remote = data.ReadRemoteObject(); + if (remote == nullptr) { + LOG_ERR("SoftbusRegisterServiceInner read systemAbilityId failed!"); + return SOFTBUS_ERR; + } + const char *pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("SoftbusRegisterServiceInner read pkgName failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = SoftbusRegisterService(pkgName, remote); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("SoftbusRegisterServiceInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::CreateSessionServerInner(MessageParcel &data, MessageParcel &reply) +{ + const char *pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("CreateSessionServerInner read pkgName failed!"); + return SOFTBUS_ERR; + } + const char *sessionName = data.ReadCString(); + if (sessionName == nullptr) { + LOG_ERR("CreateSessionServerInner read sessionName failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = CreateSessionServer(pkgName, sessionName); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("CreateSessionServerInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::RemoveSessionServerInner(MessageParcel &data, MessageParcel &reply) +{ + const char *pkgName = data.ReadCString(); + if (pkgName == nullptr) { + LOG_ERR("RemoveSessionServerInner read pkgName failed!"); + return SOFTBUS_ERR; + } + const char *sessionName = data.ReadCString(); + if (sessionName == nullptr) { + LOG_ERR("RemoveSessionServerInner read sessionName failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = RemoveSessionServer(pkgName, sessionName); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("RemoveSessionServerInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::OpenSessionInner(MessageParcel &data, MessageParcel &reply) +{ + const char *mySessionName = data.ReadCString(); + if (mySessionName == nullptr) { + LOG_ERR("OpenSessionInner read my session name failed!"); + return SOFTBUS_ERR; + } + const char *peerSessionName = data.ReadCString(); + if (peerSessionName == nullptr) { + LOG_ERR("OpenSessionInner read peer session name failed!"); + return SOFTBUS_ERR; + } + const char *peerDeviceId = data.ReadCString(); + if (peerDeviceId == nullptr) { + LOG_ERR("OpenSessionInner read peeer deviceid failed!"); + return SOFTBUS_ERR; + } + const char *groupId = data.ReadCString(); + if (groupId == nullptr) { + LOG_ERR("OpenSessionInner read group id failed!"); + return SOFTBUS_ERR; + } + int32_t flags; + if (!data.ReadInt32(flags)) { + LOG_ERR("OpenSessionInner read flags failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = OpenSession(mySessionName, peerSessionName, peerDeviceId, groupId, flags); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("OpenSessionInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::CloseChannelInner(MessageParcel &data, MessageParcel &reply) +{ + int32_t channelId; + if (!data.ReadInt32(channelId)) { + LOG_ERR("CloseChannelInner read channel Id failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = CloseChannel(channelId); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("CloseChannelInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::SendMessageInner(MessageParcel &data, MessageParcel &reply) +{ + int32_t channelId; + if (!data.ReadInt32(channelId)) { + LOG_ERR("SendMessage read channel Id failed!"); + return SOFTBUS_ERR; + } + uint32_t len; + if (!data.ReadUint32(len)) { + LOG_ERR("SendMessage dataInfo len failed!"); + return SOFTBUS_ERR; + } + void *dataInfo = (void *)data.ReadRawData(len); + if (dataInfo == nullptr) { + LOG_ERR("SendMessage read dataInfo failed!"); + return SOFTBUS_ERR; + } + int32_t msgType; + if (!data.ReadInt32(msgType)) { + LOG_ERR("SendMessage message type failed!"); + return SOFTBUS_ERR; + } + + int32_t retReply = SendMessage(channelId, dataInfo, len, msgType); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("SendMessage write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::JoinLNNInner(MessageParcel &data, MessageParcel &reply) +{ + const char *clientName = data.ReadCString(); + if (clientName == nullptr) { + LOG_ERR("SoftbusJoinLNNInner read clientName failed!"); + return SOFTBUS_ERR; + } + uint32_t addrTypeLen; + if (!data.ReadUint32(addrTypeLen)) { + LOG_ERR("SoftbusJoinLNNInner read addr type length failed!"); + return SOFTBUS_ERR; + } + void *addr = (void *)data.ReadRawData(addrTypeLen); + if (addr == nullptr) { + LOG_ERR("SoftbusJoinLNNInner read addr failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = JoinLNN(clientName, addr, addrTypeLen); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("SoftbusJoinLNNInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::LeaveLNNInner(MessageParcel &data, MessageParcel &reply) +{ + const char *clientName = data.ReadCString(); + if (clientName == nullptr) { + LOG_ERR("SoftbusLeaveLNNInner read clientName failed!"); + return SOFTBUS_ERR; + } + const char *networkId = data.ReadCString(); + if (networkId == nullptr) { + LOG_ERR("SoftbusLeaveLNNInner read networkId failed!"); + return SOFTBUS_ERR; + } + int32_t retReply = LeaveLNN(clientName, networkId); + if (!reply.WriteInt32(retReply)) { + LOG_ERR("SoftbusJoinLNNInner write reply failed!"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::GetAllOnlineNodeInfoInner(MessageParcel &data, MessageParcel &reply) +{ + void *nodeInfo = nullptr; + int32_t infoNum; + uint32_t infoTypeLen; + const char *clientName = data.ReadCString(); + if (clientName == nullptr) { + LOG_ERR("GetAllOnlineNodeInfoInner read clientName failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadUint32(infoTypeLen)) { + LOG_ERR("GetAllOnlineNodeInfoInner read info type length failed"); + return SOFTBUS_ERR; + } + if (GetAllOnlineNodeInfo(clientName, &nodeInfo, infoTypeLen, &infoNum) != SOFTBUS_OK) { + LOG_ERR("GetAllOnlineNodeInfoInner get info failed"); + return SOFTBUS_ERR; + } + if (infoNum < 0 || (infoNum > 0 && nodeInfo == nullptr)) { + LOG_ERR("GetAllOnlineNodeInfoInner node info is invalid"); + return SOFTBUS_ERR; + } + if (!reply.WriteInt32(infoNum)) { + LOG_ERR("GetAllOnlineNodeInfoInner write infoNum failed!"); + if (nodeInfo != nullptr) { + SoftBusFree(nodeInfo); + } + return SOFTBUS_ERR; + } + int32_t ret = SOFTBUS_OK; + if (infoNum > 0) { + if (!reply.WriteRawData(nodeInfo, infoTypeLen * infoNum)) { + LOG_ERR("GetAllOnlineNodeInfoInner write node info failed!"); + ret = SOFTBUS_ERR; + } + SoftBusFree(nodeInfo); + } + return ret; +} + +int32_t SoftBusServerStub::GetLocalDeviceInfoInner(MessageParcel &data, MessageParcel &reply) +{ + void *nodeInfo = nullptr; + uint32_t infoTypeLen; + const char *clientName = data.ReadCString(); + if (clientName == nullptr) { + LOG_ERR("GetLocalDeviceInfoInner read clientName failed!"); + return SOFTBUS_ERR; + } + if (!data.ReadUint32(infoTypeLen)) { + LOG_ERR("GetLocalDeviceInfoInner read info type length failed"); + return SOFTBUS_ERR; + } + nodeInfo = SoftBusCalloc(infoTypeLen); + if (nodeInfo == nullptr) { + LOG_ERR("GetLocalDeviceInfoInner malloc info type length failed"); + return SOFTBUS_ERR; + } + if (GetLocalDeviceInfo(clientName, nodeInfo, infoTypeLen) != SOFTBUS_OK) { + LOG_ERR("GetLocalDeviceInfoInner get local info failed"); + SoftBusFree(nodeInfo); + return SOFTBUS_ERR; + } + if (!reply.WriteRawData(nodeInfo, infoTypeLen)) { + LOG_ERR("GetLocalDeviceInfoInner write node info failed!"); + SoftBusFree(nodeInfo); + return SOFTBUS_ERR; + } + SoftBusFree(nodeInfo); + return SOFTBUS_OK; +} + +int32_t SoftBusServerStub::GetNodeKeyInfoInner(MessageParcel &data, MessageParcel &reply) +{ + const char *clientName = data.ReadCString(); + if (clientName == nullptr) { + LOG_ERR("GetNodeKeyInfoInner read clientName failed!"); + return SOFTBUS_ERR; + } + const char *networkId = data.ReadCString(); + if (networkId == nullptr) { + LOG_ERR("GetNodeKeyInfoInner read networkId failed!"); + return SOFTBUS_ERR; + } + int32_t key; + if (!data.ReadInt32(key)) { + LOG_ERR("GetNodeKeyInfoInner read key failed!"); + return SOFTBUS_ERR; + } + int32_t len; + if (!data.ReadInt32(len)) { + LOG_ERR("GetNodeKeyInfoInner read len failed!"); + return SOFTBUS_ERR; + } + void *buf = SoftBusMalloc(len); + if (buf == nullptr) { + LOG_ERR("GetNodeKeyInfoInner malloc buffer failed!"); + return SOFTBUS_ERR; + } + if (GetNodeKeyInfo(clientName, networkId, key, (unsigned char *)buf, len) != SOFTBUS_OK) { + LOG_ERR("GetNodeKeyInfoInner get key info failed!"); + SoftBusFree(buf); + return SOFTBUS_ERR; + } + if (!reply.WriteRawData(buf, len)) { + LOG_ERR("GetNodeKeyInfoInner write key info failed!"); + SoftBusFree(buf); + return SOFTBUS_ERR; + } + SoftBusFree(buf); + return SOFTBUS_OK; +} +} // namespace OHOS \ No newline at end of file diff --git a/core/transmission/BUILD.gn b/core/transmission/BUILD.gn new file mode 100755 index 000000000..bb6b5511c --- /dev/null +++ b/core/transmission/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_component("softbus_server_transmission") { + features = [ + "session:softbus_server_session", + "trans_channel:softbus_server_trans_channel", + ] +} diff --git a/core/transmission/common/BUILD.gn b/core/transmission/common/BUILD.gn new file mode 100755 index 000000000..1cabb313b --- /dev/null +++ b/core/transmission/common/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_library("transmission_common") { + target_type = "static_library" + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/common/include", + "//third_party/cJSON", + "//third_party/mbedtls/include/mbedtls/", + + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct", + "$dsoftbus_root_path/core/adapter/kernel/include", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ "softbus_message_open_channel.c" ] +} diff --git a/core/transmission/common/include/softbus_app_info.h b/core/transmission/common/include/softbus_app_info.h new file mode 100755 index 000000000..04410dd31 --- /dev/null +++ b/core/transmission/common/include/softbus_app_info.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_APP_INFO_H +#define SOFTBUS_APP_INFO_H + +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + API_UNKNOWN = 0, + API_V1 = 1, + API_V2 = 2, +} ApiVersion; + +typedef enum { + APP_TYPE_NOT_CARE, + APP_TYPE_NORMAL, + APP_TYPE_AUTH, + APP_TYPE_INNER +} AppType; +typedef enum { + WIFI_STA = 1, + WIFI_P2P = 2, +} RouteType; + +typedef enum { + UDP_CONN_TYPE_INVALID = -1, + UDP_CONN_TYPE_WIFI = 0, + UDP_CONN_TYPE_P2P = 1, +} UdpConnType; + +typedef enum { + TYPE_INVALID_CHANNEL = -1, + TYPE_UDP_CHANNEL_OPEN = 1, + TYPE_UDP_CHANNEL_CLOSE = 2, +} UdpChannelType; + +typedef enum { + BUSINESS_TYPE_MESSAGE = 1, + BUSINESS_TYPE_BYTE = 2, + BUSINESS_TYPE_FILE = 3, + BUSINESS_TYPE_STREAM = 4, +} BusinessType; + +typedef struct { + ApiVersion apiVersion; + char deviceId[DEVICE_ID_SIZE_MAX]; + char pkgName[PKG_NAME_SIZE_MAX]; + char sessionName[SESSION_NAME_SIZE_MAX]; + int uid; + int pid; + char authState[AUTH_STATE_SIZE_MAX]; + char ip[IP_LEN]; + int port; + int32_t channelId; +} AppInfoData; + +typedef struct { + char groupId[GROUP_ID_SIZE_MAX]; + char sessionKey[SESSION_KEY_LENGTH]; + RouteType routeType; + BusinessType businessType; + UdpConnType udpConnType; + UdpChannelType udpChannelType; + int fd; + AppType appType; + AppInfoData myData; + AppInfoData peerData; +} AppInfo; + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // SOFTBUS_APP_INFO_H \ No newline at end of file diff --git a/core/transmission/common/include/softbus_message_open_channel.h b/core/transmission/common/include/softbus_message_open_channel.h new file mode 100755 index 000000000..cec107ccb --- /dev/null +++ b/core/transmission/common/include/softbus_message_open_channel.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_MESSAGE_OPEN_CHANNEL +#define SOFTBUS_MESSAGE_OPEN_CHANNEL + +#include "cJSON.h" +#include "softbus_app_info.h" + +#define CODE "CODE" +#define ERR_CODE "ERR_CODE" +#define ERR_DESC "ERR_DESC" +#define API_VERSION "API_VERSION" +#define DEVICE_ID "DEVICE_ID" +#define BUS_NAME "BUS_NAME" +#define GROUP_ID "GROUP_ID" +#define UID "UID" +#define PID "PID" +#define SESSION_KEY "SESSION_KEY" +#define PKG_NAME "PKG_NAME" +#define CLIENT_BUS_NAME "CLIENT_BUS_NAME" +#define AUTH_STATE "AUTH_STATE" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + CODE_OPEN_CHANNEL = 1, +} MessageCode; + +char *PackRequest(const AppInfo *appInfo); + +int UnpackRequest(const cJSON *msg, AppInfo *appInfo); + +char *PackReply(const AppInfo *appInfo); + +int UnpackReply(const cJSON *msg, AppInfo *appInfo); + +char *PackError(int errCode, const char *errDesc); +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // SOFTBUS_MESSAGE_OPEN_CHANNEL diff --git a/core/transmission/common/softbus_message_open_channel.c b/core/transmission/common/softbus_message_open_channel.c new file mode 100755 index 000000000..6cf565bbc --- /dev/null +++ b/core/transmission/common/softbus_message_open_channel.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_message_open_channel.h" + +#include + +#include "base64.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" + +#define BASE64KEY 45 // Base64 encrypt SessionKey length + +char *PackError(int errCode, const char *errDesc) +{ + if (errDesc == NULL) { + LOG_ERR("invalid param"); + return NULL; + } + cJSON *json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("Cannot create cJSON object"); + return NULL; + } + if (!AddNumberToJsonObject(json, CODE, CODE_OPEN_CHANNEL) || + !AddNumberToJsonObject(json, ERR_CODE, errCode) || + !AddStringToJsonObject(json, ERR_DESC, errDesc)) { + cJSON_Delete(json); + LOG_ERR("add to cJSON object failed"); + return NULL; + } + char *data = cJSON_PrintUnformatted(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + } + cJSON_Delete(json); + return data; +} + +char *PackRequest(const AppInfo *appInfo) +{ + if (appInfo == NULL) { + LOG_ERR("invalid param"); + return NULL; + } + + cJSON *json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("Cannot create cJSON object"); + return NULL; + } + unsigned char encodeSessionKey[BASE64KEY] = {0}; + size_t keyLen = 0; + int ret = mbedtls_base64_encode(encodeSessionKey, BASE64KEY, &keyLen, (unsigned char*)appInfo->sessionKey, + SESSION_KEY_LENGTH); + if (ret != 0) { + cJSON_Delete(json); + return NULL; + } + if (!AddNumberToJsonObject(json, CODE, CODE_OPEN_CHANNEL) || + !AddNumberToJsonObject(json, API_VERSION, appInfo->myData.apiVersion) || + !AddStringToJsonObject(json, BUS_NAME, appInfo->peerData.sessionName) || + !AddStringToJsonObject(json, GROUP_ID, appInfo->groupId) || + !AddNumberToJsonObject(json, UID, appInfo->myData.uid) || + !AddNumberToJsonObject(json, PID, appInfo->myData.pid) || + !AddStringToJsonObject(json, SESSION_KEY, (char*)encodeSessionKey)) { + cJSON_Delete(json); + return NULL; + } + char *authState = (char*)appInfo->myData.authState; + if (appInfo->myData.apiVersion != API_V1) { + if (!AddStringToJsonObject(json, PKG_NAME, appInfo->myData.pkgName) || + !AddStringToJsonObject(json, CLIENT_BUS_NAME, appInfo->myData.sessionName) || + !AddStringToJsonObject(json, AUTH_STATE, authState)) { + cJSON_Delete(json); + return NULL; + } + } + char *data = cJSON_PrintUnformatted(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + } + cJSON_Delete(json); + return data; +} + +int UnpackRequest(const cJSON *msg, AppInfo *appInfo) +{ + if (msg == NULL || appInfo == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + int apiVersion = API_V1; + (void)GetJsonObjectNumberItem(msg, API_VERSION, &apiVersion); + char sessionKey[BASE64KEY] = {0}; + if (!GetJsonObjectStringItem(msg, BUS_NAME, (appInfo->myData.sessionName), SESSION_NAME_SIZE_MAX) || + !GetJsonObjectStringItem(msg, GROUP_ID, (appInfo->groupId), GROUP_ID_SIZE_MAX) || + !GetJsonObjectStringItem(msg, SESSION_KEY, sessionKey, sizeof(sessionKey))) { + LOG_ERR("Failed to get BUS_NAME"); + return SOFTBUS_ERR; + } + appInfo->peerData.apiVersion = apiVersion; + appInfo->peerData.uid = -1; + appInfo->peerData.pid = -1; + (void)GetJsonObjectNumberItem(msg, UID, &appInfo->peerData.uid); + (void)GetJsonObjectNumberItem(msg, PID, &appInfo->peerData.pid); + + size_t len = 0; + int ret = mbedtls_base64_decode((unsigned char *)appInfo->sessionKey, SESSION_KEY_LENGTH, + &len, (unsigned char *)sessionKey, strlen(sessionKey)); + (void)memset_s(sessionKey, sizeof(sessionKey), 0, sizeof(sessionKey)); + if (len != SESSION_KEY_LENGTH) { + LOG_ERR("Failed to decode sessionKey %d, len %d", ret, len); + return SOFTBUS_ERR; + } + if (apiVersion == API_V1) { + return SOFTBUS_OK; + } + + if (!GetJsonObjectStringItem(msg, PKG_NAME, (appInfo->peerData.pkgName), PKG_NAME_SIZE_MAX) || + !GetJsonObjectStringItem(msg, CLIENT_BUS_NAME, (appInfo->peerData.sessionName), SESSION_NAME_SIZE_MAX) || + !GetJsonObjectStringItem(msg, AUTH_STATE, (appInfo->peerData.authState), AUTH_STATE_SIZE_MAX)) { + LOG_ERR("Failed to get pkgName"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +char *PackReply(const AppInfo *appInfo) +{ + if (appInfo == NULL) { + LOG_ERR("invalid param"); + return NULL; + } + cJSON *json = cJSON_CreateObject(); + if (json == NULL) { + LOG_ERR("Cannot create cJSON object"); + return NULL; + } + if (!AddNumberToJsonObject(json, CODE, CODE_OPEN_CHANNEL) || + !AddNumberToJsonObject(json, API_VERSION, appInfo->myData.apiVersion) || + !AddStringToJsonObject(json, DEVICE_ID, appInfo->myData.deviceId) || + !AddNumberToJsonObject(json, UID, appInfo->myData.uid) || + !AddNumberToJsonObject(json, PID, appInfo->myData.pid)) { + LOG_ERR("Failed to add items"); + cJSON_Delete(json); + return NULL; + } + if (appInfo->myData.apiVersion != API_V1) { + char *authState = (char*)appInfo->myData.authState; + if (!AddStringToJsonObject(json, PKG_NAME, appInfo->myData.pkgName) || + !AddStringToJsonObject(json, AUTH_STATE, authState)) { + LOG_ERR("Failed to add pkgName or authState"); + cJSON_Delete(json); + return NULL; + } + } + char *data = cJSON_PrintUnformatted(json); + if (data == NULL) { + LOG_ERR("cJSON_PrintUnformatted failed"); + } + cJSON_Delete(json); + return data; +} + +int UnpackReply(const cJSON *msg, AppInfo *appInfo) +{ + if (msg == NULL || appInfo == NULL) { + LOG_ERR("Invalid param"); + return SOFTBUS_ERR; + } + + char deviceId[DEVICE_ID_SIZE_MAX] = {0}; + if (!GetJsonObjectStringItem(msg, DEVICE_ID, deviceId, DEVICE_ID_SIZE_MAX)) { + LOG_ERR("Failed to get deviceId"); + return SOFTBUS_ERR; + } + if (strcmp(deviceId, appInfo->peerData.deviceId) != 0) { + LOG_ERR("Invalid deviceId"); + return SOFTBUS_ERR; + } + + int apiVersion = API_V1; + (void)GetJsonObjectNumberItem(msg, API_VERSION, &apiVersion); + appInfo->peerData.apiVersion = apiVersion; + appInfo->peerData.uid = -1; + appInfo->peerData.pid = -1; + (void)GetJsonObjectNumberItem(msg, UID, &appInfo->peerData.uid); + (void)GetJsonObjectNumberItem(msg, PID, &appInfo->peerData.pid); + + if (apiVersion != API_V1) { + if (!GetJsonObjectStringItem(msg, PKG_NAME, (appInfo->peerData.pkgName), PKG_NAME_SIZE_MAX) || + !GetJsonObjectStringItem(msg, AUTH_STATE, (appInfo->peerData.authState), AUTH_STATE_SIZE_MAX)) { + LOG_ERR("Failed to get pkgName or authState"); + return SOFTBUS_ERR; + } + } + + return SOFTBUS_OK; +} diff --git a/core/transmission/interface/softbus_transmission_interface.h b/core/transmission/interface/softbus_transmission_interface.h new file mode 100644 index 000000000..560277e08 --- /dev/null +++ b/core/transmission/interface/softbus_transmission_interface.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_TRANSMISSION_H +#define SOFTBUS_TRANSMISSION_H + +#include +#include "softbus_def.h" + +typedef struct { + int (*onChannelOpened)(int32_t channelId, const char *uuid, unsigned char isServer); // compatible nearby + void (*onChannelOpenFailed)(int32_t channelId, const char *uuid); + void (*onChannelClosed)(int32_t channelId); + void (*onMessageReceived)(int32_t channelId, const char *data, unsigned int len); +} INetworkingListener; + +int TransOpenNetWorkingChannel(const char *sessionName, const char *peerNetworkId); + +int TransCloseNetWorkingChannel(int32_t channelId); + +int TransSendNetworkingMessage(int32_t channelId, const char *data, int dataLen, int priority); + +int TransRegisterNetworkingChannelListener(const INetworkingListener *listener); + + +#endif diff --git a/core/transmission/pending_packet/BUILD.gn b/core/transmission/pending_packet/BUILD.gn new file mode 100755 index 000000000..a8d438632 --- /dev/null +++ b/core/transmission/pending_packet/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_library("trans_pending") { + target_type = "static_library" + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + "$dsoftbus_root_path/core/adapter/kernel/include", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ "src/trans_pending_pkt.c" ] +} diff --git a/core/transmission/pending_packet/include/trans_pending_pkt.h b/core/transmission/pending_packet/include/trans_pending_pkt.h new file mode 100755 index 000000000..88710e7ae --- /dev/null +++ b/core/transmission/pending_packet/include/trans_pending_pkt.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TRANS_PENDING_PKT_H +#define TRANS_PENDING_PKT_H + +#include +#include + +#include "common_list.h" +#include "softbus_def.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +enum { + PENDING_TYPE_PROXY = 0, + PENDING_TYPE_DIRECT, + PENDING_TYPE_BUTT, +}; + +typedef struct { + ListNode node; + pthread_cond_t cond; + pthread_mutex_t lock; + int32_t channelId; + int32_t seq; + bool setFlag; + bool destroyFlag; +} PendingPktInfo; + +int32_t PendingInit(int type); +void PendingDeinit(int type); +int32_t AddPendingPacket(int32_t channelId, int32_t seqNum, int type); +int32_t SetPendingPacket(int32_t channelId, int32_t seqNum, int type); +int32_t DelPendingPacket(int32_t channelId, int32_t seqNum, int type); +int32_t DelPendingPacketById(int32_t channelId, int type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // TRANS_PENDING_PKT_H + diff --git a/core/transmission/pending_packet/src/trans_pending_pkt.c b/core/transmission/pending_packet/src/trans_pending_pkt.c new file mode 100755 index 000000000..46e4e9399 --- /dev/null +++ b/core/transmission/pending_packet/src/trans_pending_pkt.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_pending_pkt.h" + +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" +#include "time.h" +#include "unistd.h" + +#define TIME_OUT 2 +#define USECTONSEC 1000 + +static SoftBusList *g_pendingList[PENDING_TYPE_BUTT] = {NULL, NULL}; + +int32_t PendingInit(int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return SOFTBUS_ERR; + } + + g_pendingList[type] = CreateSoftBusList(); + if (g_pendingList[type] == NULL) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +void PendingDeinit(int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return; + } + + if (g_pendingList[type] != NULL) { + DestroySoftBusList(g_pendingList[type]); + g_pendingList[type] = NULL; + } + LOG_INFO("PendigPackManagerDeinit init ok"); +} + +int32_t AddPendingPacket(int32_t channelId, int32_t seqNum, int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return SOFTBUS_ERR; + } + + PendingPktInfo *item; + SoftBusList *pendingList = g_pendingList[type]; + if (pendingList == NULL) { + return SOFTBUS_ERR; + } + + pthread_mutex_lock(&pendingList->lock); + LIST_FOR_EACH_ENTRY(item, &pendingList->list, PendingPktInfo, node) { + if (item->seq == seqNum && item->channelId == channelId) { + LOG_ERR("PendingPacket already Created"); + pthread_mutex_unlock(&pendingList->lock); + return SOFTBUS_ERR; + } + } + item = (PendingPktInfo *)SoftBusMalloc(sizeof(PendingPktInfo)); + if (item == NULL) { + LOG_ERR("Malloc error"); + pthread_mutex_unlock(&pendingList->lock); + return SOFTBUS_ERR; + } + + pthread_mutex_init(&item->lock, NULL); + pthread_cond_init(&item->cond, NULL); + item->channelId = channelId; + item->seq = seqNum; + item->setFlag = false; + item->destroyFlag = false; + + ListAdd(&pendingList->list, &item->node); + pendingList->cnt++; + pthread_mutex_unlock(&pendingList->lock); + + pthread_mutex_lock(&item->lock); + struct timespec outtime; + struct timeval now; + gettimeofday(&now, NULL); + outtime.tv_sec = now.tv_sec + TIME_OUT; + outtime.tv_nsec = now.tv_usec * USECTONSEC; + pthread_cond_timedwait(&item->cond, &item->lock, &outtime); + + if (item->destroyFlag == true) { + pthread_mutex_unlock(&item->lock); + return SOFTBUS_ERR; + } + if (item->setFlag != true) { + pthread_mutex_unlock(&item->lock); + return SOFTBUS_TIMOUT; + } + pthread_mutex_unlock(&item->lock); + return SOFTBUS_OK; +} + +int32_t SetPendingPacket(int32_t channelId, int32_t seqNum, int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return SOFTBUS_ERR; + } + + SoftBusList *pendingList = g_pendingList[type]; + if (pendingList == NULL) { + return SOFTBUS_ERR; + } + + PendingPktInfo *item = NULL; + pthread_mutex_lock(&pendingList->lock); + LIST_FOR_EACH_ENTRY(item, &pendingList->list, PendingPktInfo, node) { + if (item->seq == seqNum && item->channelId == channelId) { + break; + } + } + pthread_mutex_unlock(&pendingList->lock); + + if (item != NULL && item->seq == seqNum && item->channelId == channelId) { + pthread_mutex_lock(&item->lock); + item->setFlag = true; + pthread_cond_signal(&item->cond); + pthread_mutex_unlock(&item->lock); + return SOFTBUS_OK; + } + return SOFTBUS_ERR; +} + +int32_t DelPendingPacket(int32_t channelId, int32_t seqNum, int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return SOFTBUS_ERR; + } + + SoftBusList *pendingList = g_pendingList[type]; + if (pendingList == NULL) { + return SOFTBUS_ERR; + } + + PendingPktInfo *item = NULL; + PendingPktInfo *next = NULL; + pthread_mutex_lock(&pendingList->lock); + LIST_FOR_EACH_ENTRY_SAFE(item, next, &pendingList->list, PendingPktInfo, node) { + if (item->seq == seqNum && item->channelId == channelId) { + ListDelete(&item->node); + pthread_mutex_destroy(&item->lock); + pthread_cond_destroy(&item->cond); + SoftBusFree(item); + pendingList->cnt--; + pthread_mutex_unlock(&pendingList->lock); + return SOFTBUS_OK; + } + } + pthread_mutex_unlock(&pendingList->lock); + return SOFTBUS_ERR; +} + +int32_t DelPendingPacketById(int32_t channelId, int type) +{ + if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) { + return SOFTBUS_ERR; + } + + SoftBusList *pendingList = g_pendingList[type]; + if (pendingList == NULL) { + return SOFTBUS_ERR; + } + + PendingPktInfo *item = NULL; + PendingPktInfo *next = NULL; + pthread_mutex_lock(&pendingList->lock); + LIST_FOR_EACH_ENTRY_SAFE(item, next, &pendingList->list, PendingPktInfo, node) { + if (item->channelId == channelId) { + ListDelete(&item->node); + pthread_mutex_lock(&item->lock); + item->destroyFlag = true; + pthread_cond_signal(&item->cond); + pthread_mutex_unlock(&item->lock); + + pthread_mutex_destroy(&item->lock); + pthread_cond_destroy(&item->cond); + SoftBusFree(item); + pendingList->cnt--; + break; + } + } + pthread_mutex_unlock(&pendingList->lock); + return SOFTBUS_OK; +} diff --git a/core/transmission/session/BUILD.gn b/core/transmission/session/BUILD.gn new file mode 100755 index 000000000..da2e16d8f --- /dev/null +++ b/core/transmission/session/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_server_session") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/sdk/transmission/session/include/", + "$dsoftbus_root_path/core/common/frame/include", + "$dsoftbus_root_path/interfaces/kits", + "//third_party/cJSON", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ "src/trans_session_manager.c" ] + deps = [ "//build/lite/config/component/cJSON:cjson_static" ] + } +} else { + shared_library("softbus_server_session") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/sdk/transmission/session/include/", + "$dsoftbus_root_path/core/common/frame/include", + "$dsoftbus_root_path/interfaces/kits", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + ] + sources = [ "src/trans_session_manager.c" ] + deps = [] + } +} diff --git a/core/transmission/session/include/trans_session_manager.h b/core/transmission/session/include/trans_session_manager.h new file mode 100644 index 000000000..cc6297a46 --- /dev/null +++ b/core/transmission/session/include/trans_session_manager.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TRANS_SESSION_MANAGER_H +#define TRANS_SESSION_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransCreateSessionServer(const char *pkgName, const char *sessionName); + +int32_t TransRemoveSessionServer(const char *pkgName, const char *sessionName); + +int32_t TransOpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int flags); + +int32_t TransGetPkgNameBySessionName(const char *sessionName, char *pkgName, uint16_t len); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/transmission/session/src/trans_session_manager.c b/core/transmission/session/src/trans_session_manager.c new file mode 100755 index 000000000..f2724e489 --- /dev/null +++ b/core/transmission/session/src/trans_session_manager.c @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_session_manager.h" + +#include "securec.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_permission.h" +#include "softbus_utils.h" +#include "trans_channel_manager.h" + +#define MAX_SESSION_SERVER_NUM 32 + +typedef struct { + ListNode node; + SoftBusSecType type; + char pkgName[PKG_NAME_SIZE_MAX]; + char sessionName[SESSION_NAME_SIZE_MAX]; +} SessionServer; + +static SoftBusList *g_sessionServerList = NULL; +static bool g_transSessionInitFlag = false; + +int TransServerInit(void) +{ + if (g_transSessionInitFlag) { + return SOFTBUS_OK; + } + g_sessionServerList = CreateSoftBusList(); + if (g_sessionServerList == NULL) { + return SOFTBUS_ERR; + } + g_transSessionInitFlag = true; + + if (TransPermissionInit(PERMISSION_JSON_FILE) != SOFTBUS_OK) { + LOG_ERR("Init trans permission failed"); + return SOFTBUS_ERR; + } + if (TransChannelInit() != SOFTBUS_OK) { + LOG_ERR("TransChannelInit failed"); + return SOFTBUS_ERR; + } + LOG_INFO("trans session server list init succ"); + return SOFTBUS_OK; +} + +void TransServerDeinit(void) +{ + if (g_transSessionInitFlag == false) { + return; + } + if (g_sessionServerList != NULL) { + DestroySoftBusList(g_sessionServerList); + g_sessionServerList = NULL; + } + g_transSessionInitFlag = false; + TransChannelDeinit(); + TransPermissionDeinit(); +} + +static bool TransSessionServerIsExist(const char *sessionName) +{ + if (sessionName == NULL) { + return false; + } + if (g_sessionServerList == NULL) { + LOG_INFO("not init"); + return false; + } + + SessionServer *pos = NULL; + SessionServer *tmp = NULL; + if (pthread_mutex_lock(&g_sessionServerList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return false; + } + LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) { + if (strcmp(pos->sessionName, sessionName) == 0) { + LOG_INFO("session server [%s] is exist", sessionName); + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return true; + } + } + + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return false; +} + +static int32_t TransSessionServerAddItem(SessionServer *newNode) +{ + if (newNode == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (g_sessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_NO_INIT; + } + + if (pthread_mutex_lock(&g_sessionServerList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + if (g_sessionServerList->cnt >= MAX_SESSION_SERVER_NUM) { + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return SOFTBUS_INVALID_NUM; + } + SessionServer *pos = NULL; + SessionServer *tmp = NULL; + LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) { + if (strcmp(pos->sessionName, newNode->sessionName) == 0) { + LOG_INFO("session server [%s] is exist", newNode->sessionName); + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return SOFTBUS_SERVER_NAME_REPEATED; + } + } + + ListAdd(&(g_sessionServerList->list), &(newNode->node)); + g_sessionServerList->cnt++; + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + + return SOFTBUS_OK; +} + +static int32_t TransSessionServerDelItem(const char *sessionName) +{ + if (sessionName == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (g_sessionServerList == NULL) { + return SOFTBUS_ERR; + } + + bool isFind = false; + SessionServer *pos = NULL; + SessionServer *tmp = NULL; + if (pthread_mutex_lock(&g_sessionServerList->lock) != 0) { + return SOFTBUS_ERR; + } + LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) { + if (strcmp(pos->sessionName, sessionName) == 0) { + isFind = true; + break; + } + } + if (isFind) { + ListDelete(&pos->node); + g_sessionServerList->cnt--; + LOG_INFO("destroy session server [%s]", sessionName); + SoftBusFree(pos); + } + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return SOFTBUS_OK; +} + +int32_t TransCreateSessionServer(const char *pkgName, const char *sessionName) +{ + if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || + !IsValidString(sessionName, SESSION_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + if (CheckTransPermission(sessionName, pkgName, ACTION_CREATE) < SOFTBUS_OK) { + LOG_ERR("TransCreateSessionServer no permission!\n"); + return SOFTBUS_PERMISSION_DENIED; + } + SessionServer *newNode = (SessionServer *)SoftBusCalloc(sizeof(SessionServer)); + if (newNode == NULL) { + return SOFTBUS_ERR; + } + if (strcpy_s(newNode->pkgName, sizeof(newNode->pkgName), pkgName) != EOK) { + SoftBusFree(newNode); + return SOFTBUS_ERR; + } + if (strcpy_s(newNode->sessionName, sizeof(newNode->sessionName), sessionName) != EOK) { + SoftBusFree(newNode); + return SOFTBUS_ERR; + } + newNode->type = SEC_TYPE_CIPHERTEXT; + + int ret = TransSessionServerAddItem(newNode); + if (ret != SOFTBUS_OK) { + SoftBusFree(newNode); + if (ret == SOFTBUS_SERVER_NAME_REPEATED) { + LOG_INFO("SessionServer is already created [%s]", sessionName); + return SOFTBUS_SERVER_NAME_REPEATED; + } + return ret; + } + LOG_INFO("CreateSessionServer OK, pkg name: [%s], session name: [%s]", pkgName, sessionName); + return SOFTBUS_OK; +} + +int32_t TransRemoveSessionServer(const char *pkgName, const char *sessionName) +{ + if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || + !IsValidString(sessionName, SESSION_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + if (CheckTransPermission(sessionName, pkgName, ACTION_CREATE) < SOFTBUS_OK) { + LOG_ERR("TransOpenSession no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + return TransSessionServerDelItem(sessionName); +} + +int32_t TransOpenSession(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, int32_t flags) +{ + LOG_INFO("trans server opensession."); + if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) || + !IsValidString(groupId, GROUP_ID_SIZE_MAX)) { + return INVALID_CHANNEL_ID; + } + + char pkgName[PKG_NAME_SIZE_MAX]; + if (TransGetPkgNameBySessionName(mySessionName, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("TransGetPkgNameBySessionName failed"); + return SOFTBUS_ERR; + } + if (CheckTransPermission(mySessionName, pkgName, ACTION_OPEN) < SOFTBUS_OK) { + LOG_ERR("TransOpenSession no permission!"); + return SOFTBUS_PERMISSION_DENIED; + } + + if (!TransSessionServerIsExist(mySessionName)) { + LOG_ERR("session server invalid"); + return INVALID_CHANNEL_ID; + } + + return TransOpenChannel(mySessionName, peerSessionName, peerDeviceId, groupId, flags); +} + +int32_t TransGetPkgNameBySessionName(const char *sessionName, char *pkgName, uint16_t len) +{ + if ((sessionName == NULL) || (pkgName == NULL) || (len == 0)) { + return SOFTBUS_ERR; + } + if (g_sessionServerList == NULL) { + LOG_INFO("not init"); + return SOFTBUS_ERR; + } + + SessionServer *pos = NULL; + SessionServer *tmp = NULL; + if (pthread_mutex_lock(&g_sessionServerList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) { + if (strcmp(pos->sessionName, sessionName) == 0) { + int32_t ret = strcpy_s(pkgName, len, pos->pkgName); + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + if (ret != 0) { + LOG_ERR("strcpy_s error ret, [%d]", ret); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; + } + } + + (void)pthread_mutex_unlock(&g_sessionServerList->lock); + return SOFTBUS_ERR; +} \ No newline at end of file diff --git a/core/transmission/trans_channel/BUILD.gn b/core/transmission/trans_channel/BUILD.gn new file mode 100755 index 000000000..14a09a43e --- /dev/null +++ b/core/transmission/trans_channel/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_server_trans_channel") { + sources = [ "manager/src/trans_channel_manager.c" ] + include_dirs = [ + "manager/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/common/wifi_common/base_listener/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + deps = [ + "proxy:trans_proxychannel", + "tcp_direct:trans_tcp_direct", + ] + } +} else { + shared_library("softbus_server_trans_channel") { + sources = [ "manager/src/trans_channel_manager.c" ] + include_dirs = [ + "manager/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/common/wifi_common/base_listener/include", + "//third_party/bounds_checking_function/include", + ] + deps = [ + "proxy:trans_proxychannel", + "tcp_direct:trans_tcp_direct", + ] + } +} diff --git a/core/transmission/trans_channel/manager/include/trans_channel_manager.h b/core/transmission/trans_channel/manager/include/trans_channel_manager.h new file mode 100644 index 000000000..d7d000e12 --- /dev/null +++ b/core/transmission/trans_channel/manager/include/trans_channel_manager.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TRANS_CHANNEL_MANAGER_H +#define TRANS_CHANNEL_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransChannelInit(void); + +void TransChannelDeinit(void); + +int32_t TransOpenChannel(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int32_t flags); + +int32_t TransCloseChannel(int32_t channelId); + +int32_t TransSendMsg(int32_t channelId, const void *data, uint32_t len, int32_t msgType); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/core/transmission/trans_channel/manager/src/trans_channel_manager.c b/core/transmission/trans_channel/manager/src/trans_channel_manager.c new file mode 100755 index 000000000..1772a590d --- /dev/null +++ b/core/transmission/trans_channel/manager/src/trans_channel_manager.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_channel_manager.h" +#include "securec.h" + +#include "bus_center_manager.h" +#include "softbus_conn_interface.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_permission.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_proxychannel_session.h" +#include "softbus_utils.h" +#ifndef SOFTBUS_WATCH +#include "trans_tcp_direct_manager.h" +#endif +#define TCP_PORT_LEN 10 + +int GetConnectOptionTcp(const char *peerDeviceId, ConnectOption *opt) +{ + opt->type = CONNECT_TCP; + + char ip[IP_MAX_LEN] = {0}; + if (LnnGetRemoteStrInfo(peerDeviceId, STRING_KEY_WLAN_IP, ip, sizeof(ip)) != 0) { + LOG_ERR("get remote node ip err"); + return SOFTBUS_ERR; + } + if (strcpy_s(opt->info.ipOption.ip, sizeof(opt->info.ipOption.ip), ip) != 0) { + return SOFTBUS_ERR; + } + + int port = 0; + if (LnnGetRemoteNumInfo(peerDeviceId, NUM_KEY_SESSION_PORT, &port) != 0) { + LOG_ERR("get momote node ip err"); + return SOFTBUS_ERR; + } + opt->info.ipOption.port = port; + + return SOFTBUS_OK; +} + +static ChannelType TransGetChannelType(void) +{ +#ifdef SOFTBUS_WATCH + return CHANNEL_TYPE_PROXY; +#else + return CHANNEL_TYPE_TCP_DIRECT; +#endif +} + +int32_t TransChannelInit(void) +{ + int type = TransGetChannelType(); + switch (type) { + case CHANNEL_TYPE_PROXY: + if (TransProxyManagerInit() != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + if (TransTcpDirectInit() != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + break; +#endif + default: + break; + } + return SOFTBUS_OK; +} + +void TransChannelDeinit(void) +{ + int type = TransGetChannelType(); + switch (type) { + case CHANNEL_TYPE_PROXY: + TransProxyManagerDeinit(); + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + TransTcpDirectDeinit(); + break; +#endif + default: + break; + } +} + +static int GetConnectOptionBr(const char *peerDeviceId, ConnectOption *opt) +{ + opt->type = CONNECT_BR; + char brMac[BT_MAC_LEN] = {0}; + if (LnnGetRemoteStrInfo(peerDeviceId, STRING_KEY_BT_MAC, brMac, sizeof(brMac)) != 0) { + LOG_ERR("get remote node mac err"); + return SOFTBUS_ERR; + } + + if (strcpy_s(opt->info.brOption.brMac, sizeof(opt->info.brOption.brMac), brMac) != 0) { + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +static AppInfo *GetAppInfo(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int32_t flags) +{ + (void)flags; + AppInfo *appInfo = (AppInfo *)SoftBusCalloc(sizeof(AppInfo)); + if (appInfo == NULL) { + return NULL; + } + appInfo->appType = APP_TYPE_NORMAL; + appInfo->myData.apiVersion = API_V2; + + if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, appInfo->myData.deviceId, + sizeof(appInfo->myData.deviceId)) != 0) { + goto EXIT_ERR; + } + + if (strcpy_s(appInfo->groupId, sizeof(appInfo->groupId), groupId) != 0) { + goto EXIT_ERR; + } + if (strcpy_s(appInfo->myData.sessionName, sizeof(appInfo->myData.sessionName), mySessionName) != 0) { + goto EXIT_ERR; + } + + appInfo->peerData.apiVersion = API_V2; + if (strcpy_s(appInfo->peerData.sessionName, sizeof(appInfo->peerData.sessionName), peerSessionName) != 0) { + goto EXIT_ERR; + } + if (LnnGetRemoteStrInfo(peerDeviceId, STRING_KEY_UUID, + appInfo->peerData.deviceId, sizeof(appInfo->peerData.deviceId)) != SOFTBUS_OK) { + LOG_ERR("get remote node uuid err"); + goto EXIT_ERR; + } + + return appInfo; +EXIT_ERR: + if (appInfo != NULL) { + SoftBusFree(appInfo); + } + return NULL; +} + +int32_t TransOpenChannel(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int32_t flags) +{ + int32_t channelId = INVALID_CHANNEL_ID; + if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) || + !IsValidString(groupId, GROUP_ID_SIZE_MAX)) { + return channelId; + } + + ConnectOption connOpt = {0}; + AppInfo *appInfo = GetAppInfo(mySessionName, peerSessionName, peerDeviceId, groupId, flags); + if (appInfo == NULL) { + LOG_ERR("get app info err"); + return channelId; + } + + int type = TransGetChannelType(); + switch (type) { + case CHANNEL_TYPE_PROXY: + if (GetConnectOptionBr(peerDeviceId, &connOpt) != SOFTBUS_OK) { + LOG_ERR("get connection opt err"); + break; + } + if (TransProxyOpenProxyChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) { + LOG_ERR("open proxy channel err"); + channelId = INVALID_CHANNEL_ID; + } + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + if (GetConnectOptionTcp(peerDeviceId, &connOpt) != SOFTBUS_OK) { + LOG_ERR("get connection opt err"); + break; + } + + if (TransOpenTcpDirectChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) { + LOG_ERR("open direct channel err"); + channelId = INVALID_CHANNEL_ID; + } + break; +#endif + default: + break; + } + SoftBusFree(appInfo); + return channelId; +} + +int32_t TransCloseChannel(int32_t channelId) +{ + char pkgName[PKG_NAME_SIZE_MAX]; + char sessionName[SESSION_NAME_SIZE_MAX]; + if (TransProxyGetNameByChanId(channelId, pkgName, sessionName, + PKG_NAME_SIZE_MAX, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("Trans close channel get pkgName by chanId failed"); + return SOFTBUS_ERR; + } + if (CheckTransPermission(sessionName, pkgName, ACTION_OPEN) < SOFTBUS_OK) { + LOG_ERR("Trans close channel no permission"); + return SOFTBUS_PERMISSION_DENIED; + } + return TransProxyCloseProxyChannel(channelId); +} + +int32_t TransSendMsg(int32_t channelId, const void *data, uint32_t len, int32_t msgType) +{ + char pkgName[PKG_NAME_SIZE_MAX]; + char sessionName[SESSION_NAME_SIZE_MAX]; + if (TransProxyGetNameByChanId(channelId, pkgName, sessionName, + PKG_NAME_SIZE_MAX, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("Trans send msg get pkgName by chanId failed"); + return SOFTBUS_ERR; + } + if (CheckTransPermission(sessionName, pkgName, 0) < SOFTBUS_OK) { + LOG_ERR("Trans send msg no permission"); + return SOFTBUS_PERMISSION_DENIED; + } + return TransProxyPostSessionData(channelId, (uint8_t*)data, len, msgType); +} + diff --git a/core/transmission/trans_channel/proxy/BUILD.gn b/core/transmission/trans_channel/proxy/BUILD.gn new file mode 100755 index 000000000..2a2597dfa --- /dev/null +++ b/core/transmission/trans_channel/proxy/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("trans_proxychannel") { + sources = [ + "src/softbus_proxychannel_control.c", + "src/softbus_proxychannel_listener.c", + "src/softbus_proxychannel_manager.c", + "src/softbus_proxychannel_message.c", + "src/softbus_proxychannel_network.c", + "src/softbus_proxychannel_session.c", + "src/softbus_proxychannel_transceiver.c", + ] + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/common/message_handler/include", + "//third_party/cJSON", + "//third_party/mbedtls/include/mbedtls", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + deps = [ + "//foundation/communication/dsoftbus/core/common/json_utils:json_utils", + ] + } +} else { + shared_library("trans_proxychannel") { + sources = [ + "src/softbus_proxychannel_control.c", + "src/softbus_proxychannel_listener.c", + "src/softbus_proxychannel_manager.c", + "src/softbus_proxychannel_message.c", + "src/softbus_proxychannel_network.c", + "src/softbus_proxychannel_session.c", + "src/softbus_proxychannel_transceiver.c", + ] + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/proxy/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/common/message_handler/include", + "//third_party/cJSON", + "//third_party/mbedtls/include/mbedtls", + ] + deps = [ + "//foundation/communication/dsoftbus/core/common/json_utils:json_utils", + ] + } +} diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_control.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_control.h new file mode 100644 index 000000000..90704edfb --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_control.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_CONTROL_H +#define SOFTBUS_PROXYCHANNEL_CONTROL_H +#include "softbus_proxychannel_message.h" + +int32_t TransProxySendMessage(ProxyChannelInfo *info, char *payLoad, int32_t payLoadLen, int32_t priority); +int32_t TransProxyHandshake(ProxyChannelInfo *info); +int32_t TransProxyAckHandshake(uint32_t connId, ProxyChannelInfo *chan); +void TransProxyKeepalive(uint32_t connId, const ProxyChannelInfo *info); +int32_t TransProxyAckKeepalive(ProxyChannelInfo *info); +int32_t TransProxyResetPeer(ProxyChannelInfo *info); + +#endif diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_listener.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_listener.h new file mode 100755 index 000000000..7691f591a --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_listener.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_LISTENER_H +#define SOFTBUS_PROXYCHANNEL_LISTENER_H +#include +#include "softbus_app_info.h" + +int32_t OnProxyChannelOpened(int32_t channelId, const AppInfo *appInfo, unsigned char isServer); +int32_t OnProxyChannelOpenFailed(int32_t channelId, const AppInfo *appInfo); +int32_t OnProxyChannelClosed(int32_t channelId, const AppInfo *appInfo); +int32_t OnProxyChannelMsgReceived(int32_t channelId, const AppInfo *appInfo, const char *data, uint32_t len); + +#endif diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_manager.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_manager.h new file mode 100755 index 000000000..b7654269e --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_manager.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_MANAGER_H +#define SOFTBUS_PROXYCHANNEL_MANAGER_H + +#include "stdint.h" +#include "softbus_app_info.h" +#include "softbus_conn_interface.h" +#include "softbus_proxychannel_message.h" + +int32_t TransProxyManagerInit(void); +void TransProxyManagerDeinit(void); + +int32_t TransProxyGetNewChanSeq(int32_t channelId); +int32_t TransProxyOpenProxyChannel(const AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId); +int32_t TransProxyCloseProxyChannel(int32_t channelId); +int32_t TransProxySendMsg(int32_t channelId, const char *data, int32_t dataLen, int32_t priority); +void TransProxyDelByConnId(uint32_t connId); +void TransProxyOpenProxyChannelSuccess(int32_t chanId); +void TransProxyOpenProxyChannelFail(int32_t channelId, const AppInfo *appInfo); +void TransProxyonMessageReceived(const ProxyMessage *msg); +int32_t TransProxyGetSessionKeyByChanId(int32_t channelId, char *sessionKey, int32_t sessionKeySize); +int16_t TransProxyGetNewMyId(void); +int32_t TransProxyManagerInit(void); +void TransProxyDelChanByReqId(int32_t reqId); +int32_t TransProxyCreateChanInfo(ProxyChannelInfo *chan, int32_t channelId, const AppInfo *appInfo); +void TransProxyChanProcessByReqId(int32_t reqId, uint32_t connId); +void TransProxyDelChanByChanId(int32_t chanlId); +int32_t TransProxySetChiperSide(int32_t channelId, int32_t side); +int32_t TransProxyGetChiperSide(int32_t channelId, int32_t *side); +int32_t TransProxyGetNameByChanId(int32_t chanId, char *pkgName, char *sessionName, + uint16_t pkgLen, uint16_t sessionLen); + +#endif diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_message.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_message.h new file mode 100755 index 000000000..580aa696e --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_message.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_MESSAGE_H +#define SOFTBUS_PROXYCHANNEL_MESSAGE_H +#include "stdint.h" +#include "common_list.h" +#include "softbus_app_info.h" +typedef enum { + PROXYCHANNEL_MSG_TYPE_NORMAL, + PROXYCHANNEL_MSG_TYPE_HANDSHAKE, + PROXYCHANNEL_MSG_TYPE_HANDSHAKE_ACK, + PROXYCHANNEL_MSG_TYPE_RESET, + PROXYCHANNEL_MSG_TYPE_KEEPALIVE, + PROXYCHANNEL_MSG_TYPE_KEEPALIVE_ACK, + PROXYCHANNEL_MSG_TYPE_MAX +} MsgType; + +#define JSON_KEY_TYPE "TYPE" +#define JSON_KEY_IDENTITY "IDENTITY" +#define JSON_KEY_DEVICE_ID "DEVICE_ID" +#define JSON_KEY_DST_BUS_NAME "DST_BUS_NAME" +#define JSON_KEY_SRC_BUS_NAME "SRC_BUS_NAME" +#define JSON_KEY_HAS_PRIORITY "HAS_PRIORITY" +#define JSON_KEY_UID "UID" +#define JSON_KEY_PID "PID" +#define JSON_KEY_GROUP_ID "GROUP_ID" +#define JSON_KEY_PKG_NAME "PKG_NAME" +#define JSON_KEY_SESSION_KEY "SESSION_KEY" +#define JSON_KEY_REQUEST_ID "REQUEST_ID" + +typedef struct { + uint8_t type; // MsgType //VESION + uint8_t chiper; + int16_t myId; + int16_t peerId; + int16_t reserved; +} ProxyMessageHead; + +typedef struct { + ProxyMessageHead msgHead; + int32_t dateLen; + char *data; + uint32_t connId; + int32_t chiperSide; +} ProxyMessage; + +#define VERSION 1 +#define PROXY_CHANNEL_HEAD_LEN 8 +#define VERSION_SHIFT 4 +#define FOUR_BIT_MASK 0xF +#define ENCRYPTED 0x1 +#define AUTH_SERVER_SIDE 0x2 +#define USE_BLE_CIPHER 0x4 + +#define IDENTITY_LEN 32 +typedef enum { + PROXY_CHANNEL_STATUS_PYH_CONNECTED, + PROXY_CHANNEL_STATUS_PYH_CONNECTING, + PROXY_CHANNEL_STATUS_HANDSHAKEING, + PROXY_CHANNEL_STATUS_KEEPLIVEING, + PROXY_CHANNEL_STATUS_TIMEOUT, + PROXY_CHANNEL_STATUS_HANDSHAKE_TIMEOUT, + PROXY_CHANNEL_STATUS_COMPLETED +} ProxyChannelStatus; + +#define BASE64KEY 45 // encrypt SessionKey len +typedef struct { + char sessionKeyBase64[BASE64KEY]; + size_t len; +} SessionKeyBase64; + +typedef struct { + ListNode node; + int32_t channelId; + int32_t reqId; + int8_t isServer; + int8_t status; + uint16_t timeout; + int16_t myId; + int16_t peerId; + uint32_t connId; + int32_t seq; + char identity[IDENTITY_LEN + 1]; + AppInfo appInfo; + int32_t chiperSide; +} ProxyChannelInfo; + +int32_t TransProxyUnpackHandshakeAckMsg(const char *msg, ProxyChannelInfo *chanInfo); +char* TransProxyPackHandshakeAckMsg(ProxyChannelInfo *chan); +int32_t TransProxyParseMessage(char *data, int32_t len, ProxyMessage *msg); +int32_t TransProxyPackMessage(ProxyMessageHead *msg, uint32_t connId, + char *payload, int32_t payloadLen, char** data, int32_t *dataLen); +char* TransProxyPackHandshakeMsg(ProxyChannelInfo *info); +int32_t TransProxyUnpackHandshakeMsg(const char *msg, ProxyChannelInfo *chan); +char* TransProxyPackIdentity(const char *identity); +int32_t TransProxyUnpackIdentity(const char *msg, char *identity, int32_t identitySize); + +#endif diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_network.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_network.h new file mode 100644 index 000000000..8a3ed8a09 --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_network.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_NETWORK_H +#define SOFTBUS_PROXYCHANNEL_NETWORK_H + +#include "stdint.h" + +#include "softbus_app_info.h" + +int32_t NotifyNetworkingChannelOpened(int32_t channelId, const AppInfo *appInfo, unsigned char isServer); + +void NotifyNetworkingChannelOpenFailed(int32_t channelId, const char *NetworkId); + +void NotifyNetworkingChannelClosed(int32_t channelId); + +void NotifyNetworkingMsgReceived(int32_t channelId, const char *data, uint32_t len); + +#endif + diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_session.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_session.h new file mode 100644 index 000000000..bf7f2431b --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_session.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_SESSION_H +#define SOFTBUS_PROXYCHANNEL_SESSION_H +#include "stdint.h" +#include "softbus_def.h" + +typedef enum { + PROXY_FLAG_BYTES = 0, + PROXY_FLAG_ACK = 1, + PROXY_FLAG_MESSAGE = 2, + PROXY_FILE_FIRST_FRAME = 3, + PROXY_FILE_ONGOINE_FRAME = 4, + PROXY_FILE_LAST_FRAME = 5, + PROXY_FILE_ONLYONE_FRAME = 6, + PROXY_FILE_ALLFILE_SENT = 7, + PROXY_FLAG_ASYNC_MESSAGE = 8, +} ProxyPacketType; + +typedef enum { + PROXY_CHANNEL_PRORITY_MESSAGE = 0, + PROXY_CHANNEL_PRORITY_BYTES = 1, + PROXY_CHANNEL_PRORITY_FILE = 2, + PROXY_CHANNEL_PRORITY_BUTT = 3, +} ProxyChannelPriority; + +int32_t TransProxyPostSessionData(int32_t channelId, const uint8_t* data, uint32_t len, SessionPktType flags); +void TransOnNormalMsgReceived(const char *pkgName, int32_t channelId, const char *data, uint32_t len); + +#endif diff --git a/core/transmission/trans_channel/proxy/include/softbus_proxychannel_transceiver.h b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_transceiver.h new file mode 100755 index 000000000..6dc09aff3 --- /dev/null +++ b/core/transmission/trans_channel/proxy/include/softbus_proxychannel_transceiver.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_PROXYCHANNEL_TRANSCEIVER_H +#define SOFTBUS_PROXYCHANNEL_TRANSCEIVER_H +#include "common_list.h" +#include "softbus_app_info.h" +#include "softbus_conn_interface.h" +#include "softbus_proxychannel_message.h" + +typedef struct { + ListNode node; + uint32_t requestId; + ConnectOption connInfo; + uint32_t connId; + int32_t ref; + uint32_t state; +} ProxyConnInfo; + +void TransProxyPostResetPeerMsgToLoop(const ProxyChannelInfo *chan); +void TransProxyPostHandshakeMsgToLoop(int32_t chanId); +void TransProxyPostDisConnectMsgToLoop(uint32_t connId); +void TransProxyPostOpenClosedMsgToLoop(const ProxyChannelInfo *chan); +void TransProxyPostOpenFailMsgToLoop(const ProxyChannelInfo *chan); +void TransProxyPostKeepAliveMsgToLoop(const ProxyChannelInfo *chan); +int32_t TransProxyTransInit(void); +int32_t TransProxyCloseConnChannel(uint32_t connectionId); +int32_t TransProxyOpenConnChannel(const AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId); +int32_t TransProxyTransSendMsg(uint32_t connectionId, char *buf, int32_t len, int32_t priority); +int32_t TransProxyGetConnectOption(uint32_t connectionId, ConnectOption *info); +void TransCreateConnByConnId(uint32_t connId); +int32_t TransDecConnRefByConnId(uint32_t connId); +int32_t TransAddConnRefByConnId(uint32_t connId); + +#endif diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_control.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_control.c new file mode 100755 index 000000000..8392f17ff --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_control.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_proxychannel_control.h" + +#include +#include + +#include "auth_interface.h" +#include "cJSON.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_proxychannel_message.h" +#include "softbus_proxychannel_transceiver.h" +#include "softbus_utils.h" + +int32_t TransProxySendMessage(ProxyChannelInfo *info, char *payLoad, int32_t payLoadLen, int32_t priority) +{ + char *buf = NULL; + int32_t bufLen = 0; + ProxyMessageHead msgHead = {0}; + + msgHead.type = (PROXYCHANNEL_MSG_TYPE_NORMAL & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + if (info->appInfo.appType != APP_TYPE_NORMAL) { + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + } + msgHead.myId = info->myId; + msgHead.peerId = info->peerId; + if (TransProxyPackMessage(&msgHead, info->connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack msg error"); + return SOFTBUS_TRANS_PROXY_PACKMSG_ERR; + } + + return TransProxyTransSendMsg(info->connId, buf, bufLen, priority); +} + +int32_t TransProxyHandshake(ProxyChannelInfo *info) +{ + char *buf = NULL; + int32_t bufLen = 0; + char *payLoad = NULL; + int32_t payLoadLen; + ProxyMessageHead msgHead = {0}; + + msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + msgHead.myId = info->myId; + msgHead.peerId = INVALID_CHANNEL_ID; + LOG_INFO("handshake myId %d", msgHead.myId); + payLoad = TransProxyPackHandshakeMsg(info); + if (payLoad == NULL) { + LOG_ERR("pack handshake fail"); + return SOFTBUS_ERR; + } + payLoadLen = strlen(payLoad) + 1; + if (TransProxyPackMessage(&msgHead, info->connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack handshake head fail"); + cJSON_free(payLoad); + return SOFTBUS_ERR; + } + cJSON_free(payLoad); + + if ((msgHead.chiper & AUTH_SERVER_SIDE)) { + if (TransProxySetChiperSide(info->channelId, SERVER_SIDE_FLAG) != SOFTBUS_OK) { + LOG_ERR("set chiper side fail"); + return SOFTBUS_ERR; + } + } + if (TransProxyTransSendMsg(info->connId, buf, bufLen, CONN_HIGH) != SOFTBUS_OK) { + LOG_ERR("send handshake buf fail"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransProxyAckHandshake(uint32_t connId, ProxyChannelInfo *chan) +{ + char *buf = NULL; + int32_t bufLen = 0; + char *payLoad = NULL; + int32_t payLoadLen; + ProxyMessageHead msgHead = {0}; + + LOG_INFO("send handshake ack msg myid %d peerid %d", chan->myId, chan->peerId); + msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + payLoad = TransProxyPackHandshakeAckMsg(chan); + if (payLoad == NULL) { + LOG_ERR("pack handshake ack fail"); + return SOFTBUS_ERR; + } + payLoadLen = strlen(payLoad) + 1; + msgHead.myId = chan->myId; + msgHead.peerId = chan->peerId; + + if (TransProxyPackMessage(&msgHead, connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack handshake ack head fail"); + cJSON_free(payLoad); + return SOFTBUS_ERR; + } + cJSON_free(payLoad); + if (TransProxyTransSendMsg(connId, buf, bufLen, CONN_HIGH) != SOFTBUS_OK) { + LOG_ERR("send handshakeack buf fail"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +void TransProxyKeepalive(uint32_t connId, const ProxyChannelInfo *info) +{ + char *buf = NULL; + int32_t bufLen = 0; + char *payLoad = NULL; + int32_t payLoadLen; + ProxyMessageHead msgHead = {0}; + + msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + payLoad = TransProxyPackIdentity(info->identity); + LOG_ERR("pack keepalive fail"); + if (payLoad == NULL) { + return; + } + payLoadLen = strlen(payLoad) + 1; + msgHead.myId = info->myId; + msgHead.peerId = info->peerId; + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + + if (TransProxyPackMessage(&msgHead, connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack keepalive head fail"); + cJSON_free(payLoad); + return; + } + cJSON_free(payLoad); + if (TransProxyTransSendMsg(connId, buf, bufLen, CONN_HIGH) != SOFTBUS_OK) { + LOG_ERR("send keepalive buf fail"); + return; + } + return; +} + +int32_t TransProxyAckKeepalive(ProxyChannelInfo *info) +{ + char *buf = NULL; + int32_t bufLen = 0; + char *payLoad = NULL; + int32_t payLoadLen; + ProxyMessageHead msgHead = {0}; + + msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + payLoad = TransProxyPackIdentity(info->identity); + if (payLoad == NULL) { + LOG_ERR("pack keepalive ack fail"); + return SOFTBUS_ERR; + } + payLoadLen = strlen(payLoad) + 1; + msgHead.myId = info->myId; + msgHead.peerId = info->peerId; + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + + if (TransProxyPackMessage(&msgHead, info->connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack keepalive ack head fail"); + cJSON_free(payLoad); + return SOFTBUS_ERR; + } + cJSON_free(payLoad); + if (TransProxyTransSendMsg(info->connId, buf, bufLen, CONN_HIGH) != SOFTBUS_OK) { + LOG_ERR("send keepalive ack buf fail"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int32_t TransProxyResetPeer(ProxyChannelInfo *info) +{ + char *buf = NULL; + int32_t bufLen = 0; + char *payLoad = NULL; + int32_t payLoadLen; + ProxyMessageHead msgHead = {0}; + + LOG_INFO("send reset msg myId %d peerid %d", info->myId, info->peerId); + msgHead.type = (PROXYCHANNEL_MSG_TYPE_RESET & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT); + payLoad = TransProxyPackIdentity(info->identity); + if (payLoad == NULL) { + LOG_ERR("pack reset fail"); + return SOFTBUS_ERR; + } + payLoadLen = strlen(payLoad) + 1; + msgHead.myId = info->myId; + msgHead.peerId = info->peerId; + msgHead.chiper = (msgHead.chiper | ENCRYPTED); + + if (TransProxyPackMessage(&msgHead, info->connId, payLoad, payLoadLen, &buf, &bufLen) != SOFTBUS_OK) { + LOG_ERR("pack reset head fail"); + cJSON_free(payLoad); + return SOFTBUS_ERR; + } + cJSON_free(payLoad); + if (TransProxyTransSendMsg(info->connId, buf, bufLen, CONN_LOW) != SOFTBUS_OK) { + LOG_ERR("send reset buf fail"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_listener.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_listener.c new file mode 100644 index 000000000..5f0724ef3 --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_listener.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "softbus_proxychannel_listener.h" + +#include + +#include "bus_center_manager.h" +#include "softbus_conn_interface.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_proxychannel_network.h" +#include "softbus_proxychannel_session.h" +#include "softbus_utils.h" + +static int32_t NotifyNormalChannelClosed(const char *pkgName, int32_t channelId) +{ + int32_t ret = GetClientProvideInterface()->onChannelClosed(pkgName, channelId); + LOG_INFO("proxy channel close, channelId = %d, ret = %d", channelId, ret); + return ret; +} + +static int32_t NotifyNormalChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + int32_t ret = GetClientProvideInterface()->onChannelOpenFailed(pkgName, channelId); + LOG_INFO("proxy channel open fail, channelId = %d, ret = %d", channelId, ret); + return ret; +} + +static int32_t NotifyNormalChannelOpened(int32_t channelId, const AppInfo *appInfo, bool isServer) +{ + ChannelInfo info = {0}; + info.channelId = channelId; + info.channelType = CHANNEL_TYPE_PROXY; + info.isServer = isServer; + info.isEnabled = true; + info.groupId = (char*)appInfo->groupId; + info.peerSessionName = (char*)appInfo->peerData.sessionName; + info.peerDeviceId = (char*)appInfo->peerData.deviceId; + info.peerPid = appInfo->peerData.pid; + info.peerUid = appInfo->peerData.uid; + char buf[NETWORK_ID_BUF_LEN] = {0}; + int32_t ret = LnnGetNetworkIdByUuid(appInfo->peerData.deviceId, buf, NETWORK_ID_BUF_LEN); + if (ret != SOFTBUS_OK) { + LOG_ERR("get info networkId fail."); + return SOFTBUS_ERR; + } + info.peerDeviceId = buf; + + ret = GetClientProvideInterface()->onChannelOpened(appInfo->myData.pkgName, + appInfo->myData.sessionName, &info); + LOG_INFO("proxy channel open, channelId = %d, ret = %d", channelId, ret); + return ret; +} + +int32_t OnProxyChannelOpened(int32_t channelId, const AppInfo *appInfo, unsigned char isServer) +{ + int32_t ret; + + if (appInfo == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + LOG_INFO("proxy channel opened: channeld=%d, appType=%d, isServer=%d", + channelId, appInfo->appType, isServer); + + switch (appInfo->appType) { + case APP_TYPE_NORMAL: + ret = NotifyNormalChannelOpened(channelId, appInfo, isServer); + break; + case APP_TYPE_AUTH: + ret = SOFTBUS_ERR; + break; + case APP_TYPE_INNER: + ret = NotifyNetworkingChannelOpened(channelId, appInfo, isServer); + break; + default: + ret = SOFTBUS_ERR; + break; + } + LOG_INFO("open ret %d", ret); + return ret; +} + +int32_t OnProxyChannelOpenFailed(int32_t channelId, const AppInfo *appInfo) +{ + int32_t ret = SOFTBUS_OK; + + if (appInfo == NULL) { + return SOFTBUS_INVALID_PARAM; + } + LOG_INFO("param: channelId=%d, appType=%d", + channelId, appInfo->appType); + + switch (appInfo->appType) { + case APP_TYPE_NORMAL: + ret = NotifyNormalChannelOpenFailed(appInfo->myData.pkgName, channelId); + break; + case APP_TYPE_AUTH: + ret = SOFTBUS_ERR; + break; + case APP_TYPE_INNER: + NotifyNetworkingChannelOpenFailed(channelId, appInfo->peerData.deviceId); + break; + default: + ret = SOFTBUS_ERR; + break; + } + return ret; +} + +int32_t OnProxyChannelClosed(int32_t channelId, const AppInfo *appInfo) +{ + if (appInfo == NULL) { + return SOFTBUS_INVALID_PARAM; + } + LOG_INFO("param: channelId=%d, appType=%d", channelId, appInfo->appType); + + int32_t ret = SOFTBUS_OK; + switch (appInfo->appType) { + case APP_TYPE_NORMAL: + ret = NotifyNormalChannelClosed(appInfo->myData.pkgName, channelId); + break; + case APP_TYPE_AUTH: + ret = SOFTBUS_ERR; + break; + case APP_TYPE_INNER: + NotifyNetworkingChannelClosed(channelId); + break; + default: + ret = SOFTBUS_ERR; + break; + } + return ret; +} + +int32_t OnProxyChannelMsgReceived(int32_t channelId, const AppInfo *appInfo, + const char *data, uint32_t len) +{ + int32_t ret = SOFTBUS_OK; + + if (appInfo == NULL || data == NULL || len == 0) { + return SOFTBUS_INVALID_PARAM; + } + + switch (appInfo->appType) { + case APP_TYPE_NORMAL: + TransOnNormalMsgReceived(appInfo->myData.pkgName, channelId, data, len); + break; + case APP_TYPE_AUTH: + ret = SOFTBUS_ERR; + break; + case APP_TYPE_INNER: + NotifyNetworkingMsgReceived(channelId, data, len); + break; + default: + ret = SOFTBUS_ERR; + break; + } + return ret; +} + +static int32_t TransProxyGetConnectOptionBr(const char *peerNetworkId, ConnectOption *opt) +{ + char brMac[BT_MAC_LEN] = {0}; + int ret; + + ret = LnnGetRemoteStrInfo(peerNetworkId, STRING_KEY_BT_MAC, brMac, sizeof(brMac)); + if (ret != SOFTBUS_OK) { + LOG_ERR("get momote node mac err %d", ret); + return SOFTBUS_ERR; + } + + opt->type = CONNECT_BR; + if (strcpy_s(opt->info.brOption.brMac, sizeof(opt->info.brOption.brMac), brMac) != 0) { + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +static int32_t TransProxyGetAppInfo(const char *sessionName, const char *peerNetworkId, AppInfo *appInfo) +{ + int ret; + + appInfo->appType = APP_TYPE_INNER; + appInfo->myData.apiVersion = API_V2; + ret = LnnGetLocalStrInfo(STRING_KEY_UUID, appInfo->myData.deviceId, + sizeof(appInfo->myData.deviceId)); + if (ret != SOFTBUS_OK) { + LOG_ERR("get local devid fail %d", ret); + return SOFTBUS_ERR; + } + if (strcpy_s(appInfo->myData.sessionName, sizeof(appInfo->myData.sessionName), sessionName) != 0) { + return SOFTBUS_ERR; + } + appInfo->peerData.apiVersion = API_V2; + if (strcpy_s(appInfo->peerData.sessionName, sizeof(appInfo->peerData.sessionName), sessionName) != 0) { + return SOFTBUS_ERR; + } + + ret = LnnGetRemoteStrInfo(peerNetworkId, STRING_KEY_UUID, + appInfo->peerData.deviceId, sizeof(appInfo->peerData.deviceId)); + if (ret != SOFTBUS_OK) { + LOG_ERR("get remote node uuid err %d", ret); + return SOFTBUS_GET_REMOTE_UUID_ERR; + } + + return SOFTBUS_OK; +} + +int32_t TransOpenNetWorkingChannel(const char *sessionName, const char *peerNetworkId) +{ + AppInfo appInfo; + ConnectOption connOpt; + int32_t channelId = INVALID_CHANNEL_ID; + + if (!IsValidString(sessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerNetworkId, DEVICE_ID_SIZE_MAX)) { + return channelId; + } + + if (TransProxyGetConnectOptionBr(peerNetworkId, &connOpt) != SOFTBUS_OK) { + LOG_ERR("networking get conn opthon fail"); + return channelId; + } + (void)memset_s(&appInfo, sizeof(AppInfo), 0, sizeof(AppInfo)); + if (TransProxyGetAppInfo(sessionName, peerNetworkId, &appInfo) != SOFTBUS_OK) { + LOG_ERR("networking get app info fail"); + return channelId; + } + + if (TransProxyOpenProxyChannel(&appInfo, &connOpt, &channelId) != SOFTBUS_OK) { + LOG_ERR("networking open channel fail"); + channelId = INVALID_CHANNEL_ID; + } + return channelId; +} + +int32_t TransSendNetworkingMessage(int32_t channelId, const char *data, int32_t dataLen, int32_t priority) +{ + return TransProxySendMsg(channelId, data, dataLen, priority); +} + +int32_t TransCloseNetWorkingChannel(int32_t channelId) +{ + return TransProxyCloseProxyChannel(channelId); +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_manager.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_manager.c new file mode 100755 index 000000000..bf278acce --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_manager.c @@ -0,0 +1,1023 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "softbus_proxychannel_manager.h" + +#include +#include + +#include "bus_center_info_key.h" +#include "bus_center_manager.h" +#include "common_list.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_proxychannel_control.h" +#include "softbus_proxychannel_listener.h" +#include "softbus_proxychannel_message.h" +#include "softbus_proxychannel_transceiver.h" +#include "softbus_utils.h" +#include "trans_session_manager.h" + +#define PROXY_CHANNEL_CONTROL_TIMEOUT 19 +#define PROXY_CHANNEL_BT_IDLE_TIMEOUT 240 // 4min +static SoftBusList *g_proxyChannelList = NULL; +static pthread_mutex_t g_myIdLock; + +static int32_t MyIdIsValid(int16_t myId) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->myId == myId) { + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; +} + +static bool IsLittleEndianCPU() +{ +#define CHECK_NUM 0x0100 +#define CHECK_NUM_HIGH 0x01 + + uint16_t num = CHECK_NUM; + + if (*((char *)&num) == CHECK_NUM_HIGH) { + return false; + } + return true; +} + +static uint16_t EndianSwap16(uint16_t num) +{ +#define HIGH_MASK 0xFF00 +#define LOW_MASK 0x00FF +#define ENDIAN_SHIFT 8 + + if (!IsLittleEndianCPU()) { + return num; + } + return (((num & HIGH_MASK) >> ENDIAN_SHIFT) | ((num & LOW_MASK) << ENDIAN_SHIFT)); +} + +int16_t TransProxyGetNewMyId(void) +{ +#define MYID_MAX_NUM 100 + static int16_t myId = 0; + int32_t cnt = MYID_MAX_NUM; + if (pthread_mutex_lock(&g_myIdLock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + while (cnt) { + cnt--; + myId++; + int16_t ret = myId % MYID_MAX_NUM + 1; + ret = EndianSwap16(ret); + if (MyIdIsValid(ret) == SOFTBUS_OK) { + pthread_mutex_unlock(&g_myIdLock); + return ret; + } + } + pthread_mutex_unlock(&g_myIdLock); + return INVALID_CHANNEL_ID; +} + +static int32_t ChanIsEqual(ProxyChannelInfo *a, ProxyChannelInfo *b) +{ + if ((a->myId == b->myId) && + (a->peerId == b->peerId) && + (strncmp(a->identity, b->identity, sizeof(a->identity)) == 0)) { + return SOFTBUS_OK; + } + return SOFTBUS_ERR; +} + +static int32_t ResetChanIsEqual(int status, ProxyChannelInfo *a, ProxyChannelInfo *b) +{ + if (status == PROXY_CHANNEL_STATUS_HANDSHAKEING) { + if ((a->myId == b->myId) && + (strncmp(a->identity, b->identity, sizeof(a->identity)) == 0)) { + return SOFTBUS_OK; + } + } + + if ((a->myId == b->myId) && + (a->peerId == b->peerId) && + (strncmp(a->identity, b->identity, sizeof(a->identity)) == 0)) { + return SOFTBUS_OK; + } + return SOFTBUS_ERR; +} + +static int32_t TransProxyUpdateAckInfo(ProxyChannelInfo *info) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + LOG_ERR("g_proxyChannelList or item is null"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if ((item->myId == info->myId) && (strncmp(item->identity, info->identity, sizeof(item->identity)) == 0)) { + item->peerId = info->peerId; + item->status = PROXY_CHANNEL_STATUS_COMPLETED; + item->timeout = 0; + (void)memcpy_s(&(item->appInfo.peerData), sizeof(item->appInfo.peerData), + &(info->appInfo.peerData), sizeof(info->appInfo.peerData)); + (void)memcpy_s(info, sizeof(ProxyChannelInfo), item, sizeof(ProxyChannelInfo)); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +static void TransProxyAddChanItem(ProxyChannelInfo *chan) +{ + if (g_proxyChannelList == NULL) { + SoftBusFree(chan); + return; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + SoftBusFree(chan); + return; + } + ListAdd(&(g_proxyChannelList->list), &(chan->node)); + g_proxyChannelList->cnt++; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; +} + +int32_t TransProxyGetChanByChanId(int32_t chanId, ProxyChannelInfo *chan) +{ + ProxyChannelInfo *item = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == chanId) { + (void)memcpy_s(chan, sizeof(ProxyChannelInfo), item, sizeof(ProxyChannelInfo)); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +void TransProxyDelChanByReqId(int32_t reqId) +{ + ProxyChannelInfo *item = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if ((item->reqId == reqId) && + (item->status == PROXY_CHANNEL_STATUS_PYH_CONNECTING)) { + ListDelete(&(item->node)); + LOG_INFO("del item (%d)", item->channelId); + TransProxyPostOpenFailMsgToLoop(item); + g_proxyChannelList->cnt--; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; +} + +void TransProxyDelChanByChanId(int32_t chanlId) +{ + ProxyChannelInfo *item = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == chanlId) { + ListDelete(&(item->node)); + SoftBusFree(item); + g_proxyChannelList->cnt--; + LOG_INFO("del chan info!"); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; +} + +void TransProxyChanProcessByReqId(int32_t reqId, uint32_t connId) +{ + ProxyChannelInfo *item = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->reqId == reqId && item->status == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + item->status = PROXY_CHANNEL_STATUS_HANDSHAKEING; + item->connId = connId; + TransAddConnRefByConnId(connId); + TransProxyPostHandshakeMsgToLoop(item->channelId); + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; +} + +void TransProxyDelByConnId(uint32_t connId) +{ + ProxyChannelInfo *removeNode = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (removeNode->connId == connId) { + if (removeNode->status == PROXY_CHANNEL_STATUS_HANDSHAKEING || + removeNode->status == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + OnProxyChannelOpenFailed(removeNode->channelId, &(removeNode->appInfo)); + } else { + OnProxyChannelClosed(removeNode->channelId, &(removeNode->appInfo)); + } + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_proxyChannelList->cnt--; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return; +} + +static int32_t TransProxyDelByChannelId(int32_t channelId, ProxyChannelInfo *channelInfo) +{ + ProxyChannelInfo *removeNode = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (removeNode->channelId == channelId) { + if (channelInfo != NULL) { + (void)memcpy_s(channelInfo, sizeof(ProxyChannelInfo), removeNode, sizeof(ProxyChannelInfo)); + } + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_proxyChannelList->cnt--; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +static int32_t TransProxyResetChan(ProxyChannelInfo *chanInfo) +{ + ProxyChannelInfo *removeNode = NULL; + ProxyChannelInfo *nextNode = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (ResetChanIsEqual(removeNode->status, removeNode, chanInfo) == SOFTBUS_OK) { + (void)memcpy_s(chanInfo, sizeof(ProxyChannelInfo), removeNode, sizeof(ProxyChannelInfo)); + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_proxyChannelList->cnt--; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + + return SOFTBUS_ERR; +} + +static int32_t TransProxyGetRecvMsgChanInfo(int16_t myId, int16_t peerId, ProxyChannelInfo *chanInfo) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->myId == myId || item->peerId == peerId) { + if (item->status == PROXY_CHANNEL_STATUS_COMPLETED) { + item->timeout = 0; + } + (void)memcpy_s(chanInfo, sizeof(ProxyChannelInfo), item, sizeof(ProxyChannelInfo)); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +static int32_t TransProxyKeepAlvieChan(ProxyChannelInfo *chanInfo) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (ChanIsEqual(item, chanInfo) == SOFTBUS_OK) { + if (item->status == PROXY_CHANNEL_STATUS_KEEPLIVEING || item->status == PROXY_CHANNEL_STATUS_COMPLETED) { + item->timeout = 0; + item->status = PROXY_CHANNEL_STATUS_COMPLETED; + } + (void)memcpy_s(chanInfo, sizeof(ProxyChannelInfo), item, sizeof(ProxyChannelInfo)); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +static int32_t TransProxyGetSendMsgChanInfo(int32_t channelId, ProxyChannelInfo *chanInfo) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == channelId) { + if (item->status == PROXY_CHANNEL_STATUS_COMPLETED) { + item->timeout = 0; + } + (void)memcpy_s(chanInfo, sizeof(ProxyChannelInfo), item, sizeof(ProxyChannelInfo)); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +int32_t TransProxyGetNewChanSeq(int32_t channelId) +{ + ProxyChannelInfo *item = NULL; + int32_t seq = 0; + + if (g_proxyChannelList == NULL) { + return seq; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return seq; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == channelId) { + seq = item->seq; + item->seq++; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return seq; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return seq; +} + +int32_t TransProxySetChiperSide(int32_t channelId, int32_t side) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == channelId) { + item->chiperSide = side; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +int32_t TransProxyGetChiperSide(int32_t channelId, int32_t *side) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == channelId) { + *side = item->chiperSide; + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +int32_t TransProxyGetSessionKeyByChanId(int32_t channelId, char *sessionKey, int32_t sessionKeySize) +{ + ProxyChannelInfo *item = NULL; + + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(item, &g_proxyChannelList->list, ProxyChannelInfo, node) { + if (item->channelId == channelId) { + if (item->status == PROXY_CHANNEL_STATUS_COMPLETED) { + item->timeout = 0; + } + if (memcpy_s(sessionKey, sessionKeySize, item->appInfo.sessionKey, + sizeof(item->appInfo.sessionKey)) != EOK) { + LOG_ERR("memcpy_s fail!"); + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + return SOFTBUS_ERR; +} + +void TransProxyProcessHandshakeAckMsg(const ProxyMessage *msg) +{ + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return; + } + + LOG_INFO("recv ack msg"); + if (TransProxyUnpackHandshakeAckMsg(msg->data, info) != SOFTBUS_OK) { + SoftBusFree(info); + LOG_ERR("UnpackHandshakeAckMsg fail"); + return; + } + + info->myId = msg->msgHead.myId; + info->peerId = msg->msgHead.peerId; + LOG_INFO("recv Handshake ack myid %d peerid %d identity %s", info->myId, info->peerId, info->identity); + if (TransProxyUpdateAckInfo(info) != SOFTBUS_OK) { + SoftBusFree(info); + LOG_ERR("UpdateAckInfo fail"); + return; + } + (void)OnProxyChannelOpened(info->channelId, &(info->appInfo), 0); + SoftBusFree(info); +} + +void TransProxyProcessHandshakeMsg(const ProxyMessage *msg) +{ + LOG_INFO("recv Handshake myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + ProxyChannelInfo *chan = (ProxyChannelInfo *)SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (chan == NULL) { + return; + } + + if (TransProxyUnpackHandshakeMsg(msg->data, chan) != SOFTBUS_OK) { + LOG_ERR("UnpackHandshakeMsg fail"); + SoftBusFree(chan); + return; + } + int32_t ret = TransGetPkgNameBySessionName(chan->appInfo.myData.sessionName, + chan->appInfo.myData.pkgName, sizeof(chan->appInfo.myData.pkgName)); + if (ret != SOFTBUS_OK) { + LOG_ERR("proc handshake get pkg name fail"); + SoftBusFree(chan); + return; + } + + if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, chan->appInfo.myData.deviceId, + sizeof(chan->appInfo.myData.deviceId)) != 0) { + LOG_ERR("Handshake get local info fail"); + SoftBusFree(chan); + return; + } + + int16_t newChanId = TransProxyGetNewMyId(); + ret = OnProxyChannelOpened(newChanId, &(chan->appInfo), 1); + if (ret != SOFTBUS_OK) { + LOG_ERR("OnProxyChannelOpened fail"); + SoftBusFree(chan); + return; + } + + chan->isServer = 1; + chan->status = PROXY_CHANNEL_STATUS_COMPLETED; + chan->connId = msg->connId; + chan->myId = newChanId; + chan->channelId = newChanId; + chan->peerId = msg->msgHead.peerId; + chan->chiperSide = msg->chiperSide; + TransProxyAddChanItem(chan); + if (TransProxyAckHandshake(msg->connId, chan) != SOFTBUS_OK) { + LOG_ERR("AckHandshake fail"); + OnProxyChannelClosed(newChanId, &(chan->appInfo)); + TransProxyDelChanByChanId(newChanId); + return; + } + TransCreateConnByConnId(msg->connId); +} + +void TransProxyProcessResetMsg(const ProxyMessage *msg) +{ + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return; + } + + LOG_INFO("recv reset myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + if (TransProxyUnpackIdentity(msg->data, info->identity, sizeof(info->identity)) != SOFTBUS_OK) { + LOG_ERR("reset identity fail"); + SoftBusFree(info); + return; + } + + info->peerId = msg->msgHead.peerId; + info->myId = msg->msgHead.myId; + + if (TransProxyResetChan(info) != SOFTBUS_OK) { + LOG_ERR("reset chan fail myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + SoftBusFree(info); + return; + } + + if (info->status == PROXY_CHANNEL_STATUS_HANDSHAKEING) { + OnProxyChannelOpenFailed(info->channelId, &(info->appInfo)); + } else { + OnProxyChannelClosed(info->channelId, &(info->appInfo)); + } + (void)TransProxyCloseConnChannel(msg->connId); + SoftBusFree(info); +} + +void TransProxyProcessKeepAlive(const ProxyMessage *msg) +{ + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return; + } + + LOG_INFO("recv keepalive myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + if (TransProxyUnpackIdentity(msg->data, info->identity, sizeof(info->identity)) != SOFTBUS_OK) { + LOG_ERR("keep alive unpack identity fail"); + SoftBusFree(info); + return; + } + info->peerId = msg->msgHead.peerId; + info->myId = msg->msgHead.myId; + + if (TransProxyKeepAlvieChan(info) != SOFTBUS_OK) { + LOG_ERR("reset keep alive proc fail myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + SoftBusFree(info); + return; + } + + TransProxyAckKeepalive(info); + SoftBusFree(info); +} + +void TransProxyProcessKeepAliveAck(const ProxyMessage *msg) +{ + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return; + } + + LOG_INFO("recv keepalive ack myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + if (TransProxyUnpackIdentity(msg->data, info->identity, sizeof(info->identity)) != SOFTBUS_OK) { + SoftBusFree(info); + return; + } + info->peerId = msg->msgHead.peerId; + info->myId = msg->msgHead.myId; + + if (TransProxyKeepAlvieChan(info) != SOFTBUS_OK) { + LOG_ERR("reset keep alive ack proc fail myid %d peerid %d", msg->msgHead.myId, msg->msgHead.peerId); + SoftBusFree(info); + return; + } + SoftBusFree(info); +} + +void TransProxyProcessDataRecv(const ProxyMessage *msg) +{ + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return; + } + + if (TransProxyGetRecvMsgChanInfo(msg->msgHead.myId, msg->msgHead.peerId, info) != SOFTBUS_OK) { + LOG_ERR("data recv get info fail mid %d pid %d", msg->msgHead.myId, msg->msgHead.peerId); + SoftBusFree(info); + return; + } + + OnProxyChannelMsgReceived(info->channelId, &(info->appInfo), msg->data, msg->dateLen); + SoftBusFree(info); +} + +void TransProxyonMessageReceived(const ProxyMessage *msg) +{ + switch (msg->msgHead.type) { + case PROXYCHANNEL_MSG_TYPE_HANDSHAKE: { + TransProxyProcessHandshakeMsg(msg); + break; + } + case PROXYCHANNEL_MSG_TYPE_HANDSHAKE_ACK: { + TransProxyProcessHandshakeAckMsg(msg); + break; + } + case PROXYCHANNEL_MSG_TYPE_RESET: { + TransProxyProcessResetMsg(msg); + break; + } + case PROXYCHANNEL_MSG_TYPE_KEEPALIVE: { + TransProxyProcessKeepAlive(msg); + break; + } + case PROXYCHANNEL_MSG_TYPE_KEEPALIVE_ACK: { + TransProxyProcessKeepAliveAck(msg); + break; + } + case PROXYCHANNEL_MSG_TYPE_NORMAL: { + TransProxyProcessDataRecv(msg); + break; + } + default: { + break; + } + } + + if (msg->msgHead.chiper != 0) { + SoftBusFree(msg->data); + } +} + +int32_t TransProxyCreateChanInfo(ProxyChannelInfo *chan, int32_t channelId, const AppInfo *appInfo) +{ + chan->myId = channelId; + chan->channelId = channelId; + if (GenerateRandomStr(chan->identity, sizeof(chan->identity)) != SOFTBUS_OK) { + LOG_ERR("GenerateRandomStr err"); + return SOFTBUS_ERR; + } + + if (GenerateRandomArray((uint8_t *)appInfo->sessionKey, sizeof(appInfo->sessionKey)) != SOFTBUS_OK) { + LOG_ERR("GenerateRandomArray err"); + return SOFTBUS_ERR; + } + + (void)memcpy_s(&(chan->appInfo), sizeof(chan->appInfo), appInfo, sizeof(AppInfo)); + TransProxyAddChanItem(chan); + return SOFTBUS_OK; +} + +void TransProxyOpenProxyChannelSuccess(int32_t chanId) +{ + ProxyChannelInfo *chan = NULL; + + LOG_INFO("send handshake msg"); + chan = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (chan == NULL) { + return; + } + + if (TransProxyGetChanByChanId(chanId, chan) != SOFTBUS_OK) { + (void)TransProxyCloseConnChannel(chan->connId); + SoftBusFree(chan); + LOG_ERR("disconnect device chanId %d", chanId); + return; + } + + if (TransProxyHandshake(chan) == SOFTBUS_ERR) { + (void)TransProxyCloseConnChannel(chan->connId); + LOG_ERR("shake hand err"); + OnProxyChannelOpenFailed(chan->channelId, &(chan->appInfo)); + TransProxyDelChanByChanId(chanId); + } + SoftBusFree(chan); + return; +} + +void TransProxyOpenProxyChannelFail(int32_t channelId, const AppInfo *appInfo) +{ + (void)OnProxyChannelOpenFailed(channelId, appInfo); +} + +int32_t TransProxyOpenProxyChannel(const AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId) +{ + if (appInfo == NULL || connInfo == NULL || channelId == NULL) { + LOG_ERR("open normal channel: invalid para"); + return SOFTBUS_ERR; + } + + return TransProxyOpenConnChannel(appInfo, connInfo, channelId); +} + +int32_t TransProxyCloseProxyChannel(int32_t channelId) +{ + int32_t ret; + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return SOFTBUS_MALLOC_ERR; + } + + if (TransProxyDelByChannelId(channelId, info) != SOFTBUS_OK) { + LOG_ERR("del channel err %d", channelId); + SoftBusFree(info); + return SOFTBUS_TRANS_PROXY_DEL_CHANNELID_INVALID; + } + + TransProxyResetPeer(info); + ret = TransProxyCloseConnChannel(info->connId); + SoftBusFree(info); + return ret; +} + +int32_t TransProxySendMsg(int32_t channelId, const char *data, int32_t dataLen, int32_t priority) +{ + int32_t ret; + ProxyChannelInfo *info = SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (info == NULL) { + return SOFTBUS_MALLOC_ERR; + } + + if (TransProxyGetSendMsgChanInfo(channelId, info) != SOFTBUS_OK) { + LOG_ERR("get channelId err %d", channelId); + SoftBusFree(info); + return SOFTBUS_TRANS_PROXY_SEND_CHANNELID_INVALID; + } + + if (info->status != PROXY_CHANNEL_STATUS_COMPLETED && info->status != PROXY_CHANNEL_STATUS_KEEPLIVEING) { + LOG_ERR("status is err %d", info->status); + SoftBusFree(info); + return SOFTBUS_TRANS_PROXY_CHANNLE_STATUS_INVALID; + } + + ret = TransProxySendMessage(info, (char *)data, dataLen, priority); + SoftBusFree(info); + return ret; +} +void TransProxyTimerItemProc(const ListNode *proxyProcList) +{ + ProxyChannelInfo *removeNode = NULL; + ProxyChannelInfo *nextNode = NULL; + uint32_t connId; + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, proxyProcList, ProxyChannelInfo, node) { + ListDelete(&(removeNode->node)); + if (removeNode->status == PROXY_CHANNEL_STATUS_TIMEOUT) { + connId = removeNode->connId; + ProxyChannelInfo *resetMsg = SoftBusMalloc(sizeof(ProxyChannelInfo)); + if (resetMsg != NULL) { + (void)memcpy_s(resetMsg, sizeof(ProxyChannelInfo), removeNode, sizeof(ProxyChannelInfo)); + TransProxyPostResetPeerMsgToLoop(resetMsg); + } + TransProxyPostOpenClosedMsgToLoop(removeNode); + TransProxyPostDisConnectMsgToLoop(connId); + } + if (removeNode->status == PROXY_CHANNEL_STATUS_HANDSHAKE_TIMEOUT) { + connId = removeNode->connId; + TransProxyPostOpenFailMsgToLoop(removeNode); + TransProxyPostDisConnectMsgToLoop(connId); + } + if (removeNode->status == PROXY_CHANNEL_STATUS_KEEPLIVEING) { + LOG_INFO("send keepalive channel %d ", removeNode->myId); + TransProxyPostKeepAliveMsgToLoop(removeNode); + } + } +} + +void TransProxyTimerProc(void) +{ + ProxyChannelInfo *removeNode = NULL; + ProxyChannelInfo *nextNode = NULL; + ListNode proxyProcList; + + if (g_proxyChannelList == 0 || g_proxyChannelList->cnt == 0) { + return; + } + if (pthread_mutex_lock(&g_proxyChannelList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + ListInit(&proxyProcList); + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, &g_proxyChannelList->list, ProxyChannelInfo, node) { + removeNode->timeout++; + if (removeNode->status == PROXY_CHANNEL_STATUS_HANDSHAKEING || + removeNode->status == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + if (removeNode->timeout >= PROXY_CHANNEL_CONTROL_TIMEOUT) { + removeNode->status = PROXY_CHANNEL_STATUS_HANDSHAKE_TIMEOUT; + LOG_INFO("channel (%d) handshake is timeout", removeNode->myId); + ListDelete(&(removeNode->node)); + ListAdd(&proxyProcList, &(removeNode->node)); + g_proxyChannelList->cnt--; + } + } + if (removeNode->status == PROXY_CHANNEL_STATUS_KEEPLIVEING) { + if (removeNode->timeout >= PROXY_CHANNEL_CONTROL_TIMEOUT) { + removeNode->status = PROXY_CHANNEL_STATUS_TIMEOUT; + LOG_INFO("channel (%d) keepalvie is timeout", removeNode->myId); + ListDelete(&(removeNode->node)); + ListAdd(&proxyProcList, &(removeNode->node)); + g_proxyChannelList->cnt--; + } + } + if (removeNode->status == PROXY_CHANNEL_STATUS_COMPLETED) { + if (removeNode->timeout >= PROXY_CHANNEL_BT_IDLE_TIMEOUT) { + removeNode->status = PROXY_CHANNEL_STATUS_TIMEOUT; + ListDelete(&(removeNode->node)); + ListAdd(&proxyProcList, &(removeNode->node)); + LOG_INFO("channel (%d) is idle", removeNode->myId); + g_proxyChannelList->cnt--; + } + } + } + (void)pthread_mutex_unlock(&g_proxyChannelList->lock); + TransProxyTimerItemProc(&proxyProcList); +} + +int32_t TransProxyManagerInit(void) +{ + if (pthread_mutex_init(&g_myIdLock, NULL) != 0) { + LOG_ERR("init lock failed"); + return SOFTBUS_ERR; + } + + if (TransProxyTransInit() != SOFTBUS_OK) { + LOG_ERR("TransProxyTransInit fail"); + return SOFTBUS_ERR; + } + + g_proxyChannelList = CreateSoftBusList(); + if (g_proxyChannelList == NULL) { + return SOFTBUS_ERR; + } + + if (RegisterTimeoutCallback(SOFTBUS_PROXYCHANNEL_TIMER_FUN, TransProxyTimerProc) != SOFTBUS_OK) { + DestroySoftBusList(g_proxyChannelList); + return SOFTBUS_ERR; + } + + LOG_INFO("proxy channel init ok"); + return SOFTBUS_OK; +} + +int32_t TransProxyGetNameByChanId(int32_t chanId, char *pkgName, char *sessionName, + uint16_t pkgLen, uint16_t sessionLen) +{ + if (pkgName == NULL || sessionName == NULL) { + return SOFTBUS_INVALID_PARAM; + } + ProxyChannelInfo *chan = (ProxyChannelInfo *)SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (chan == NULL) { + return SOFTBUS_MALLOC_ERR; + } + if (TransProxyGetChanByChanId(chanId, chan) != SOFTBUS_OK) { + SoftBusFree(chan); + return SOFTBUS_ERR; + } + if (TransGetPkgNameBySessionName(chan->appInfo.myData.sessionName, pkgName, pkgLen) != SOFTBUS_OK) { + SoftBusFree(chan); + return SOFTBUS_ERR; + } + if (strcpy_s(sessionName, sessionLen, chan->appInfo.myData.sessionName) != EOK) { + SoftBusFree(chan); + return SOFTBUS_MEM_ERR; + } + SoftBusFree(chan); + return SOFTBUS_OK; +} + +void TransProxyManagerDeinit(void) +{ + (void)RegisterTimeoutCallback(SOFTBUS_PROXYCHANNEL_TIMER_FUN, NULL); +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_message.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_message.c new file mode 100755 index 000000000..86258fe2e --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_message.c @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_proxychannel_message.h" + +#include + +#include "auth_interface.h" +#include "base64.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_proxychannel_transceiver.h" +#include "softbus_utils.h" + +int32_t ChiperSideProc(ProxyMessage *msg, int32_t *side) +{ + if (msg->msgHead.type == PROXYCHANNEL_MSG_TYPE_HANDSHAKE) { + *side = ((msg->msgHead.chiper & AUTH_SERVER_SIDE) ? CLIENT_SIDE_FLAG : SERVER_SIDE_FLAG); + return SOFTBUS_OK; + } + if (TransProxyGetChiperSide(msg->msgHead.myId, side) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransProxyParseMessageHead(ProxyMessage *msg, char *data, int32_t len) +{ + char *ptr = data; + uint8_t firstByte = *ptr; + ptr += sizeof(int8_t); + int8_t version = (firstByte >> VERSION_SHIFT) & FOUR_BIT_MASK; + msg->msgHead.type = firstByte & FOUR_BIT_MASK; + if (version != VERSION || msg->msgHead.type >= PROXYCHANNEL_MSG_TYPE_MAX) { + LOG_ERR("parseMessage: unsupported message, version(%d), type(%d)", version, msg->msgHead.type); + return SOFTBUS_ERR; + } + + msg->msgHead.chiper = *ptr; + ptr += sizeof(int8_t); + msg->msgHead.peerId = *(int16_t *)ptr; + ptr += sizeof(uint16_t); + msg->msgHead.myId = *(int16_t *)ptr; + msg->data = data + sizeof(ProxyMessageHead); + msg->dateLen = len - sizeof(ProxyMessageHead); + return SOFTBUS_OK; +} + +int32_t TransProxyParseMessage(char *data, int32_t len, ProxyMessage *msg) +{ + uint8_t isEncrypted; + int32_t isServer; + ConnectOption option; + OutBuf deBuf = {0}; + + if (len <= PROXY_CHANNEL_HEAD_LEN) { + LOG_ERR("parseMessage: invalid message length(%d)", len); + return SOFTBUS_ERR; + } + if (TransProxyParseMessageHead(msg, data, len) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + isEncrypted = ((msg->msgHead.chiper & ENCRYPTED) != 0); + if (isEncrypted) { + if (ChiperSideProc(msg, &isServer) != SOFTBUS_OK) { + LOG_ERR("get side fail chanId[%d]", msg->msgHead.myId); + return SOFTBUS_ERR; + } + msg->chiperSide = isServer; + if (TransProxyGetConnectOption(msg->connId, &option) != 0) { + LOG_ERR("parse msg GetConnectOption fail connId[%d]", msg->connId); + return SOFTBUS_ERR; + } + + deBuf.buf = SoftBusCalloc(len - PROXY_CHANNEL_HEAD_LEN); + if (deBuf.buf == NULL) { + return SOFTBUS_ERR; + } + deBuf.bufLen = len - PROXY_CHANNEL_HEAD_LEN; + if (AuthDecrypt(&option, (AuthSideFlag)isServer, (uint8_t *)(data + PROXY_CHANNEL_HEAD_LEN), + len - PROXY_CHANNEL_HEAD_LEN, &deBuf) != 0) { + SoftBusFree(deBuf.buf); + LOG_ERR("pack msg decrypt fail isServer"); + return SOFTBUS_ERR; + } + msg->data = (char *)deBuf.buf; + msg->dateLen = deBuf.outLen; + } + + return SOFTBUS_OK; +} + +int32_t TransProxyPackMessage(ProxyMessageHead *msg, uint32_t connId, + char *payload, int32_t payloadLen, char **data, int32_t *dataLen) +{ + char *buf = NULL; + int32_t bufLen; + int32_t connHeadLen; + connHeadLen = ConnGetHeadSize(); + AuthSideFlag isServer = CLIENT_SIDE_FLAG; + + if (msg->chiper == 0) { + bufLen = PROXY_CHANNEL_HEAD_LEN + connHeadLen + payloadLen; + buf = (char*)SoftBusCalloc(bufLen); + if (buf == NULL) { + return SOFTBUS_ERR; + } + (void)memcpy_s(buf + connHeadLen, bufLen - connHeadLen, msg, sizeof(ProxyMessageHead)); + (void)memcpy_s(buf + connHeadLen + PROXY_CHANNEL_HEAD_LEN, + bufLen - connHeadLen - PROXY_CHANNEL_HEAD_LEN, payload, payloadLen); + *data = buf; + *dataLen = bufLen; + } else { + OutBuf enBuf = {0}; + ConnectOption option; + int ret; + + if (TransProxyGetConnectOption(connId, &option) != SOFTBUS_OK) { + LOG_ERR("pack msg GetConnectOption fail connId[%u]", connId); + return SOFTBUS_ERR; + } + bufLen = PROXY_CHANNEL_HEAD_LEN + connHeadLen + payloadLen + AuthGetEncryptHeadLen(); + buf = SoftBusCalloc(bufLen); + if (buf == NULL) { + return SOFTBUS_ERR; + } + enBuf.buf = (unsigned char *)(buf + PROXY_CHANNEL_HEAD_LEN + connHeadLen); + enBuf.bufLen = bufLen - PROXY_CHANNEL_HEAD_LEN - connHeadLen; + ret = AuthEncrypt(&option, &isServer, (uint8_t *)payload, payloadLen, &enBuf); + if (ret != SOFTBUS_OK) { + SoftBusFree(buf); + LOG_ERR("pack msg encrypt fail %d", ret); + return SOFTBUS_ERR; + } + + if (isServer == SERVER_SIDE_FLAG) { + msg->chiper = msg->chiper | AUTH_SERVER_SIDE; + } + + (void)memcpy_s(buf + connHeadLen, bufLen - connHeadLen, msg, sizeof(ProxyMessageHead)); + (void)memcpy_s(buf + connHeadLen + PROXY_CHANNEL_HEAD_LEN, + bufLen - connHeadLen - PROXY_CHANNEL_HEAD_LEN, enBuf.buf, enBuf.outLen); + *data = buf; + *dataLen = PROXY_CHANNEL_HEAD_LEN + connHeadLen + enBuf.outLen; + } + + return SOFTBUS_OK; +} + +static int32_t PackHandshakeMsgForNormal(SessionKeyBase64 *sessionBase64, AppInfo *appInfo, cJSON *root) +{ + int32_t ret = mbedtls_base64_encode((unsigned char *)sessionBase64->sessionKeyBase64, + sizeof(sessionBase64->sessionKeyBase64), &(sessionBase64->len), + (unsigned char *)appInfo->sessionKey, sizeof(appInfo->sessionKey)); + if (ret != 0) { + LOG_ERR("mbedtls_base64_encode FAIL %d", ret); + return ret; + } + LOG_INFO("mbedtls_base64_encode len %d", sessionBase64->len); + if (!AddNumberToJsonObject(root, JSON_KEY_UID, appInfo->myData.uid) || + !AddNumberToJsonObject(root, JSON_KEY_PID, appInfo->myData.pid) || + !AddStringToJsonObject(root, JSON_KEY_GROUP_ID, appInfo->groupId) || + !AddStringToJsonObject(root, JSON_KEY_PKG_NAME, appInfo->myData.pkgName) || + !AddStringToJsonObject(root, JSON_KEY_SESSION_KEY, sessionBase64->sessionKeyBase64)) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +char *TransProxyPackHandshakeMsg(ProxyChannelInfo *info) +{ + cJSON *root = 0; + SessionKeyBase64 sessionBase64; + char *buf = 0; + AppInfo *appInfo = &(info->appInfo); + int32_t ret; + + root = cJSON_CreateObject(); + if (root == NULL) { + return NULL; + } + (void)memset_s(&sessionBase64, sizeof(SessionKeyBase64), 0, sizeof(SessionKeyBase64)); + if (!AddNumberToJsonObject(root, JSON_KEY_TYPE, appInfo->appType) || + !AddStringToJsonObject(root, JSON_KEY_IDENTITY, info->identity) || + !AddStringToJsonObject(root, JSON_KEY_DEVICE_ID, appInfo->myData.deviceId) || + !AddStringToJsonObject(root, JSON_KEY_SRC_BUS_NAME, appInfo->myData.sessionName) || + !AddStringToJsonObject(root, JSON_KEY_DST_BUS_NAME, appInfo->peerData.sessionName)) { + cJSON_Delete(root); + return NULL; + } + (void)cJSON_AddTrueToObject(root, JSON_KEY_HAS_PRIORITY); + + if (appInfo->appType == APP_TYPE_NORMAL) { + ret = PackHandshakeMsgForNormal(&sessionBase64, appInfo, root); + if (ret != SOFTBUS_OK) { + cJSON_Delete(root); + return NULL; + } + } else if (appInfo->appType == APP_TYPE_AUTH) { + if (!AddStringToJsonObject(root, JSON_KEY_PKG_NAME, appInfo->myData.pkgName)) { + cJSON_Delete(root); + return NULL; + } + } else { + ret = mbedtls_base64_encode((uint8_t *)sessionBase64.sessionKeyBase64, + sizeof(sessionBase64.sessionKeyBase64), &(sessionBase64.len), + (uint8_t *)appInfo->sessionKey, sizeof(appInfo->sessionKey)); + if (ret != 0) { + LOG_ERR("mbedtls_base64_encode FAIL %d", ret); + cJSON_Delete(root); + return NULL; + } + if (!AddStringToJsonObject(root, JSON_KEY_SESSION_KEY, sessionBase64.sessionKeyBase64)) { + cJSON_Delete(root); + return NULL; + } + } + + buf = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + return buf; +} + +char *TransProxyPackHandshakeAckMsg(ProxyChannelInfo *chan) +{ + cJSON *root = NULL; + char *buf = NULL; + AppInfo *appInfo = &(chan->appInfo); + + if (appInfo->appType == APP_TYPE_NOT_CARE) { + return NULL; + } + + root = cJSON_CreateObject(); + if (root == NULL) { + return NULL; + } + + if (!AddStringToJsonObject(root, JSON_KEY_IDENTITY, chan->identity) || + !AddStringToJsonObject(root, JSON_KEY_DEVICE_ID, appInfo->myData.deviceId)) { + cJSON_Delete(root); + return NULL; + } + (void)cJSON_AddTrueToObject(root, JSON_KEY_HAS_PRIORITY); + if (appInfo->appType == APP_TYPE_NORMAL) { + if (!AddNumberToJsonObject(root, JSON_KEY_UID, appInfo->myData.uid) || + !AddNumberToJsonObject(root, JSON_KEY_PID, appInfo->myData.pid) || + !AddStringToJsonObject(root, JSON_KEY_PKG_NAME, appInfo->myData.pkgName)) { + cJSON_Delete(root); + return NULL; + } + } else if (appInfo->appType == APP_TYPE_AUTH) { + if (!AddStringToJsonObject(root, JSON_KEY_PKG_NAME, appInfo->myData.pkgName)) { + cJSON_Delete(root); + return NULL; + } + } + + buf = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + return buf; +} + +int32_t TransProxyUnpackHandshakeAckMsg(const char *msg, ProxyChannelInfo *chanInfo) +{ + cJSON *root = 0; + AppInfo *appInfo = &(chanInfo->appInfo); + + root = cJSON_Parse(msg); + if (root == NULL) { + return SOFTBUS_ERR; + } + + if (!GetJsonObjectStringItem(root, JSON_KEY_IDENTITY, chanInfo->identity, sizeof(chanInfo->identity)) || + !GetJsonObjectStringItem(root, JSON_KEY_DEVICE_ID, appInfo->peerData.deviceId, + sizeof(appInfo->peerData.deviceId))) { + LOG_ERR("fail to get json item"); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + + if (!GetJsonObjectStringItem(root, JSON_KEY_PKG_NAME, appInfo->peerData.pkgName, + sizeof(appInfo->peerData.pkgName))) { + LOG_INFO("no item to get pkg name"); + } + cJSON_Delete(root); + return SOFTBUS_OK; +} + +static int32_t UnpackHandshakeMsgForNormal(cJSON *root, AppInfo *appInfo, char *sessionKey, int32_t sessionKeyLen) +{ + if (!GetJsonObjectNumberItem(root, JSON_KEY_UID, &(appInfo->peerData.uid)) || + !GetJsonObjectNumberItem(root, JSON_KEY_PID, &(appInfo->peerData.pid)) || + !GetJsonObjectStringItem(root, JSON_KEY_PKG_NAME, appInfo->peerData.pkgName, + sizeof(appInfo->peerData.pkgName)) || + !GetJsonObjectStringItem(root, JSON_KEY_SESSION_KEY, sessionKey, sessionKeyLen)) { + LOG_ERR("Failed to get handshake msg APP_TYPE_NORMAL"); + return SOFTBUS_ERR; + } + size_t len = 0; + int32_t ret = mbedtls_base64_decode((uint8_t *)appInfo->sessionKey, sizeof(appInfo->sessionKey), + &len, (uint8_t *)sessionKey, strlen(sessionKey)); + if (len != sizeof(appInfo->sessionKey) || ret != 0) { + LOG_ERR("decode session fail %d ", ret); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransProxyUnpackHandshakeMsg(const char *msg, ProxyChannelInfo *chan) +{ + cJSON *root = cJSON_Parse(msg); + if (root == NULL) { + return SOFTBUS_ERR; + } + char sessionKey[BASE64KEY] = {0}; + AppInfo *appInfo = &(chan->appInfo); + int32_t appType = 0; + + if (!GetJsonObjectNumberItem(root, JSON_KEY_TYPE, &(appType)) || + !GetJsonObjectStringItem(root, JSON_KEY_IDENTITY, chan->identity, sizeof(chan->identity)) || + !GetJsonObjectStringItem(root, JSON_KEY_DEVICE_ID, appInfo->peerData.deviceId, + sizeof(appInfo->peerData.deviceId)) || + !GetJsonObjectStringItem(root, JSON_KEY_SRC_BUS_NAME, appInfo->peerData.sessionName, + sizeof(appInfo->peerData.sessionName)) || + !GetJsonObjectStringItem(root, JSON_KEY_DST_BUS_NAME, appInfo->myData.sessionName, + sizeof(appInfo->myData.sessionName))) { + LOG_ERR("Failed to get handshake msg"); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + appInfo->appType = (AppType)appType; + + if (appInfo->appType == APP_TYPE_NORMAL) { + int32_t ret = UnpackHandshakeMsgForNormal(root, appInfo, sessionKey, BASE64KEY); + if (ret != SOFTBUS_OK) { + cJSON_Delete(root); + return ret; + } + } else if (appInfo->appType == APP_TYPE_AUTH) { + if (!GetJsonObjectStringItem(root, JSON_KEY_PKG_NAME, + appInfo->peerData.pkgName, sizeof(appInfo->peerData.pkgName))) { + LOG_ERR("Failed to get handshake msg"); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + } else { + if (!GetJsonObjectStringItem(root, JSON_KEY_SESSION_KEY, sessionKey, sizeof(sessionKey))) { + LOG_ERR("Failed to get handshake msg"); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + size_t len = 0; + int32_t ret = mbedtls_base64_decode((uint8_t *)appInfo->sessionKey, sizeof(appInfo->sessionKey), + &len, (uint8_t *)sessionKey, strlen(sessionKey)); + if (len != sizeof(appInfo->sessionKey) || ret != 0) { + LOG_ERR("decode session fail %d ", ret); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + } + cJSON_Delete(root); + return SOFTBUS_OK; +} + +char *TransProxyPackIdentity(const char *identity) +{ + cJSON *root = NULL; + char *buf = NULL; + + if (identity == NULL) { + return NULL; + } + + root = cJSON_CreateObject(); + if (root == NULL) { + return NULL; + } + + if (!AddStringToJsonObject(root, JSON_KEY_IDENTITY, identity)) { + cJSON_Delete(root); + return NULL; + } + + buf = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + return buf; +} + +int32_t TransProxyUnpackIdentity(const char *msg, char *identity, int32_t identitySize) +{ + cJSON *root = NULL; + + root = cJSON_Parse(msg); + if (root == NULL) { + return SOFTBUS_ERR; + } + + if (!GetJsonObjectStringItem(root, JSON_KEY_IDENTITY, identity, identitySize)) { + LOG_ERR("fail to get json item"); + cJSON_Delete(root); + return SOFTBUS_ERR; + } + + cJSON_Delete(root); + return SOFTBUS_OK; +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_network.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_network.c new file mode 100755 index 000000000..e5d4900e2 --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_network.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_proxychannel_network.h" + +#include + +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_transmission_interface.h" + +static INetworkingListener g_netChanlistener = {0}; + +int32_t NotifyNetworkingChannelOpened(int32_t chanId, const AppInfo *appInfo, unsigned char isServer) +{ + if (g_netChanlistener.onChannelOpened == NULL) { + LOG_ERR("net onChannelOpened is null"); + return SOFTBUS_ERR; + } + + if (g_netChanlistener.onChannelOpened(chanId, appInfo->peerData.deviceId, isServer) != SOFTBUS_OK) { + LOG_ERR("notify channel open fail"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +void NotifyNetworkingChannelOpenFailed(int32_t channelId, const char *networkId) +{ + if (g_netChanlistener.onChannelOpenFailed == NULL) { + LOG_ERR("net onChannelOpenFailed is null"); + return; + } + g_netChanlistener.onChannelOpenFailed(channelId, networkId); +} + +void NotifyNetworkingChannelClosed(int32_t chanId) +{ + if (g_netChanlistener.onChannelClosed == NULL) { + LOG_ERR("net onChannelClosed is null"); + return; + } + g_netChanlistener.onChannelClosed(chanId); +} + +void NotifyNetworkingMsgReceived(int32_t chanId, const char *data, uint32_t len) +{ + if (g_netChanlistener.onMessageReceived == NULL) { + return; + } + g_netChanlistener.onMessageReceived(chanId, data, len); +} + + +int32_t TransRegisterNetworkingChannelListener(const INetworkingListener *listener) +{ + if (memcpy_s(&g_netChanlistener, sizeof(INetworkingListener), + listener, sizeof(INetworkingListener)) != EOK) { + return SOFTBUS_ERR; + } + + LOG_INFO("register net listener ok"); + return SOFTBUS_OK; +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_session.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_session.c new file mode 100755 index 000000000..018a1edd0 --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_session.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_proxychannel_session.h" + +#include + +#include "softbus_crypto.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_transmission_interface.h" + +typedef struct { + unsigned char *inData; + uint32_t inLen; + unsigned char *outData; + uint32_t outLen; +} ProxyDataInfo; + +typedef struct { + int32_t priority; + int32_t sliceNum; + int32_t sliceSeq; + int32_t reserved; +} SliceHead; + +typedef struct { + int32_t magicNumber; + int32_t seq; + int32_t flags; + int32_t dataLen; +} PacketHead; + +int32_t NotifyClientMsgReceived(const char *pkgName, int32_t channelId, const char *data, uint32_t len, + SessionPktType type) +{ + int32_t ret = GetClientProvideInterface()->onChannelMsgReceived(pkgName, channelId, data, len, type); + if (ret != SOFTBUS_OK) { + LOG_ERR("notify err(%d)", ret); + } + return ret; +} + +int32_t ProxyTypeToProxyIndex(ProxyPacketType packetType) +{ + switch (packetType) { + case PROXY_FLAG_MESSAGE: + case PROXY_FLAG_ASYNC_MESSAGE: + case PROXY_FLAG_ACK: + return PROXY_CHANNEL_PRORITY_MESSAGE; + case PROXY_FLAG_BYTES: + return PROXY_CHANNEL_PRORITY_BYTES; + default: + return PROXY_CHANNEL_PRORITY_BYTES; + } +} + +ProxyPacketType SessionTypeToPacketType(SessionPktType sessionType) +{ + switch (sessionType) { + case TRANS_SESSION_BYTES: + return PROXY_FLAG_BYTES; + case TRANS_SESSION_MESSAGE: + return PROXY_FLAG_ASYNC_MESSAGE; + default: + return PROXY_FLAG_BYTES; + } +} + +SendPriority ProxyTypeToConnPri(ProxyPacketType proxyType) +{ + switch (proxyType) { + case PROXY_FLAG_BYTES: + return CONN_MIDDLE; + case PROXY_FLAG_ASYNC_MESSAGE: + case PROXY_FLAG_ACK: + return CONN_HIGH; + default: + return CONN_DEFAULT; + } +} + +int32_t TransProxyEncryptPacketData(int32_t channelId, int32_t seq, ProxyDataInfo *dataInfo) +{ + char sessionKey[SESSION_KEY_LENGTH] = {0}; + AesGcmCipherKey cipherKey = {0}; + uint32_t checkLen; + + if (TransProxyGetSessionKeyByChanId(channelId, sessionKey, sizeof(sessionKey)) != SOFTBUS_OK) { + LOG_ERR("get channelId(%d) session key err", channelId); + return SOFTBUS_ERR; + } + + checkLen = dataInfo->inLen + OVERHEAD_LEN; + cipherKey.keyLen = SESSION_KEY_LENGTH; + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) { + LOG_ERR("memcpy_s key error."); + return SOFTBUS_ERR; + } + int32_t ret = SoftBusEncryptDataWithSeq(&cipherKey, dataInfo->inData, dataInfo->inLen, + dataInfo->outData, &(dataInfo->outLen), seq); + if (ret != SOFTBUS_OK || dataInfo->outLen != checkLen) { + LOG_ERR("Trans Proxy encrypt error. %d ", ret); + return SOFTBUS_ENCRYPT_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransProxyDecryptPacketData(int32_t channelId, int32_t seq, ProxyDataInfo *dataInfo) +{ + char sessionKey[SESSION_KEY_LENGTH] = {0}; + AesGcmCipherKey cipherKey = {0}; + int ret; + + if (TransProxyGetSessionKeyByChanId(channelId, sessionKey, sizeof(sessionKey)) != SOFTBUS_OK) { + LOG_ERR("DecryptPacket get chan fail channid %d.", channelId); + return SOFTBUS_ERR; + } + cipherKey.keyLen = SESSION_KEY_LENGTH; // 256 bit encryption + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) { + LOG_ERR("memcpy key error."); + return SOFTBUS_ERR; + } + (void)memset_s(sessionKey, sizeof(sessionKey), 0, sizeof(sessionKey)); + ret = SoftBusDecryptDataWithSeq(&cipherKey, dataInfo->inData, dataInfo->inLen, + dataInfo->outData, &(dataInfo->outLen), seq); + (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey)); + if (ret != SOFTBUS_OK) { + LOG_ERR("trans proxy Decrypt Data fail. %d ", ret); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransProxyGetPktSeqId(int32_t channelId, ProxyDataInfo *dataInfo, ProxyPacketType flag) +{ + int32_t seq = 0; + + if (flag == PROXY_FLAG_ACK) { + if (memcpy_s(&seq, sizeof(seq), dataInfo->inData, dataInfo->inLen) == EOK) { + return seq; + } + } + + return TransProxyGetNewChanSeq(channelId); +} + +int32_t TransProxyPackBytes(int32_t channelId, ProxyDataInfo *dataInfo, ProxyPacketType flag) +{ +#define MAGIC_NUMBER 0xBABEFACE + uint32_t outBufLen; + uint8_t *outBuf = NULL; + PacketHead *pktHead = NULL; + SliceHead *sliceHead = NULL; + ProxyDataInfo enDataInfo = {0}; + int32_t seq; + + outBufLen = dataInfo->inLen + OVERHEAD_LEN + sizeof(PacketHead) + sizeof(SliceHead); + outBuf = SoftBusCalloc(outBufLen); + if (outBuf == NULL) { + LOG_ERR("calloc error"); + return SOFTBUS_MEM_ERR; + } + seq = TransProxyGetPktSeqId(channelId, dataInfo, flag); + LOG_INFO("trans proxy send packet seq %d flag %d", seq, flag); + enDataInfo.outData = outBuf + sizeof(PacketHead) + sizeof(SliceHead); + enDataInfo.outLen = outBufLen - sizeof(PacketHead) - sizeof(SliceHead); + enDataInfo.inData = dataInfo->inData; + enDataInfo.inLen = dataInfo->inLen; + if (TransProxyEncryptPacketData(channelId, seq, &enDataInfo) != SOFTBUS_OK) { + SoftBusFree(outBuf); + LOG_ERR("tran pack encrypt data fail. channid %d", channelId); + return SOFTBUS_TRANS_PROXY_SESS_ENCRYPT_ERR; + } + + sliceHead = (SliceHead*)(outBuf); + sliceHead->priority = ProxyTypeToProxyIndex(flag); + sliceHead->sliceNum = 1; + sliceHead->sliceSeq = 0; + + pktHead = (PacketHead*)(sliceHead + 1); + pktHead->magicNumber = MAGIC_NUMBER; + pktHead->seq = seq; + pktHead->flags = flag; + pktHead->dataLen = enDataInfo.outLen; + + dataInfo->outData = outBuf; + dataInfo->outLen = enDataInfo.outLen + sizeof(PacketHead) + sizeof(SliceHead); + return SOFTBUS_OK; +} + +int32_t TransProxyPostPacketData(int32_t channelId, const unsigned char *data, uint32_t len, ProxyPacketType flags) +{ + ProxyDataInfo packDataInfo = {0}; + int32_t ret; + + if (data == NULL) { + LOG_ERR("invalid para"); + return SOFTBUS_INVALID_PARAM; + } + + packDataInfo.inData = (unsigned char *)data; + packDataInfo.inLen = len; + ret = TransProxyPackBytes(channelId, &packDataInfo, flags); + if (ret != SOFTBUS_OK) { + LOG_ERR("PackBytes err"); + return ret; + } + LOG_INFO("InLen = %u, outLen = %u flags %d", len, packDataInfo.outLen, flags); + ret = TransProxySendMsg(channelId, (const char *)packDataInfo.outData, packDataInfo.outLen, + ProxyTypeToConnPri(flags)); + SoftBusFree(packDataInfo.outData); + return ret; +} + +int32_t TransProxyPostSessionData(int32_t channelId, const unsigned char *data, uint32_t len, SessionPktType flags) +{ + ProxyPacketType type; + + type = SessionTypeToPacketType(flags); + return TransProxyPostPacketData(channelId, data, len, type); +} +static void TransProxySendSessionAck(int32_t channelId, int32_t seq) +{ +#define PROXY_ACK_SIZE 4 + unsigned char ack[PROXY_ACK_SIZE]; + + if (memcpy_s(ack, PROXY_ACK_SIZE, &seq, sizeof(int32_t)) != EOK) { + LOG_ERR("memcpy seq err"); + } + if (TransProxyPostPacketData(channelId, ack, PROXY_ACK_SIZE, PROXY_FLAG_ACK) != SOFTBUS_OK) { + LOG_ERR("send ack err, seq = %d", seq); + } +} + +int32_t TransProxyNotifySession(const char *pkgName, int32_t channelId, ProxyPacketType flags, int32_t seq, + const char *data, uint32_t len) +{ + switch (flags) { + case PROXY_FLAG_BYTES: + return NotifyClientMsgReceived(pkgName, channelId, data, len, TRANS_SESSION_BYTES); + case PROXY_FLAG_MESSAGE: + TransProxySendSessionAck(channelId, seq); + return NotifyClientMsgReceived(pkgName, channelId, data, len, TRANS_SESSION_MESSAGE); + case PROXY_FLAG_ASYNC_MESSAGE: + return NotifyClientMsgReceived(pkgName, channelId, data, len, TRANS_SESSION_MESSAGE); + default: + LOG_ERR("invalid flags(%d)", flags); + return SOFTBUS_INVALID_PARAM; + } +} + +int32_t TransProxySessionDataLenCheck(uint32_t dataLen, ProxyPacketType type) +{ + switch (type) { + case PROXY_FLAG_MESSAGE: + case PROXY_FLAG_ASYNC_MESSAGE: { + if (dataLen > TRANS_MESSAGE_LENGTH_MAX) { + return SOFTBUS_ERR; + } + break; + } + case PROXY_FLAG_BYTES: { + if (dataLen > TRANS_BYTES_LENGTH_MAX) { + return SOFTBUS_ERR; + } + break; + } + default: { + return SOFTBUS_OK; + } + } + return SOFTBUS_OK; +} + +static int32_t TransProxyProcessSessionData(const char *pkgName, int32_t channelId, PacketHead *dataHead, + const char *data) +{ + ProxyDataInfo dataInfo = {0}; + uint32_t outLen; + int32_t ret; + + if (dataHead->dataLen <= OVERHEAD_LEN) { + return SOFTBUS_ERR; + } + + outLen = dataHead->dataLen - OVERHEAD_LEN; + dataInfo.outData = (unsigned char *)SoftBusCalloc(outLen); + if (dataInfo.outData == NULL) { + return SOFTBUS_MALLOC_ERR; + } + dataInfo.inData = (unsigned char *)data; + dataInfo.inLen = dataHead->dataLen; + dataInfo.outLen = outLen; + + ret = TransProxyDecryptPacketData(channelId, dataHead->seq, &dataInfo); + if (ret != SOFTBUS_OK) { + LOG_ERR("decrypt err"); + SoftBusFree(dataInfo.outData); + return SOFTBUS_DECRYPT_ERR; + } + + if (TransProxySessionDataLenCheck(dataInfo.outLen, dataHead->flags) != SOFTBUS_OK) { + LOG_ERR("data len is too large %d type %d", dataInfo.outLen, dataHead->flags); + SoftBusFree(dataInfo.outData); + return SOFTBUS_ERR; + } + + LOG_INFO("ProcessData debug: len %d \n", dataInfo.outLen); + if (TransProxyNotifySession(pkgName, channelId, (ProxyPacketType)dataHead->flags, dataHead->seq, + (const char *)dataInfo.outData, dataInfo.outLen) != SOFTBUS_OK) { + LOG_ERR("process data err"); + SoftBusFree(dataInfo.outData); + return SOFTBUS_ERR; + } + SoftBusFree(dataInfo.outData); + return SOFTBUS_OK; +} + +void TransProxyNoSubPacketProc(const char *pkgName, int32_t channelId, const char *data, uint32_t len) +{ + PacketHead *head = NULL; + + head = (PacketHead*)data; + if ((uint32_t)head->magicNumber != MAGIC_NUMBER) { + LOG_ERR("invalid magicNumber %x", head->magicNumber); + return; + } + if (head->dataLen <= 0) { + LOG_ERR("invalid dataLen %d", head->dataLen); + return; + } + LOG_ERR("NoSubPacketProc data info %d", head->dataLen); + int32_t ret = TransProxyProcessSessionData(pkgName, channelId, head, data + sizeof(PacketHead)); + if (ret != SOFTBUS_OK) { + LOG_ERR("process data err"); + return; + } + return; +} + +void TransOnNormalMsgReceived(const char *pkgName, int32_t channelId, const char *data, uint32_t len) +{ + SliceHead *head = NULL; + + if (data == NULL || len <= sizeof(SliceHead)) { + return; + } + LOG_ERR("TransOnNormalMsgReceived len %u", len); + + head = (SliceHead*)data; + if (head->priority < 0 || head->priority >= PROXY_CHANNEL_PRORITY_BUTT) { + LOG_ERR("invalid index %d", head->priority); + return; + } + + if (head->sliceNum != 1 || head->sliceSeq >= head->sliceNum) { + LOG_ERR("invalid sliceNum %d sliceSeq %d", head->sliceNum, head->sliceSeq); + return; + } + + TransProxyNoSubPacketProc(pkgName, channelId, data + sizeof(SliceHead), len - sizeof(SliceHead)); +} diff --git a/core/transmission/trans_channel/proxy/src/softbus_proxychannel_transceiver.c b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_transceiver.c new file mode 100755 index 000000000..bc47b43d2 --- /dev/null +++ b/core/transmission/trans_channel/proxy/src/softbus_proxychannel_transceiver.c @@ -0,0 +1,679 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_proxychannel_transceiver.h" + +#include + +#include "message_handler.h" +#include "softbus_conn_interface.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_proxychannel_control.h" +#include "softbus_proxychannel_listener.h" +#include "softbus_proxychannel_manager.h" +#include "softbus_proxychannel_message.h" +#include "softbus_utils.h" + +static SoftBusList *g_proxyConnectionList = NULL; +char *g_transProxyLoopName = "transProxyLoopName"; +SoftBusHandler g_transLoophandler = {0}; +typedef enum { + LOOP_HANDSHAKE_MSG, + LOOP_DISCONNECT_MSG, + LOOP_OPENFAIL_MSG, + LOOP_OPENCLOSE_MSG, + LOOP_KEEPALIVE_MSG, + LOOP_RESETPEER_MSG, +} LoopMsg; + +static int32_t TransDelConnByReqId(uint32_t reqId) +{ + ProxyConnInfo *removeNode = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (removeNode->requestId == reqId && removeNode->state == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_proxyConnectionList->cnt--; + break; + } + } + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_OK; +} + +void TransDelConnByConnId(uint32_t connId) +{ + ProxyConnInfo *removeNode = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (removeNode->connId == connId) { + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + LOG_INFO("del conn item"); + g_proxyConnectionList->cnt--; + break; + } + } + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; +} + +int32_t TransDecConnRefByConnId(uint32_t connId) +{ + ProxyConnInfo *removeNode = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (removeNode->connId == connId) { + removeNode->ref--; + if (removeNode->ref <= 0) { + ListDelete(&(removeNode->node)); + SoftBusFree(removeNode); + g_proxyConnectionList->cnt--; + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + LOG_INFO("conn ref is 0"); + return SOFTBUS_OK; + } else { + LOG_INFO("removeNode->ref %d", removeNode->ref); + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_ERR; + } + } + } + + LOG_INFO("not find conn item"); + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_OK; +} + +int32_t TransAddConnRefByConnId(uint32_t connId) +{ + ProxyConnInfo *item = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (item->connId == connId) { + item->ref++; + LOG_INFO("add conn ref %d", item->ref); + break; + } + } + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_OK; +} + +static void TransProxyLoopMsgHandler(SoftBusMessage *msg) +{ + int32_t chanId; + uint32_t connectionId; + ProxyChannelInfo *chan = NULL; + + if (msg == NULL) { + return; + } + LOG_INFO("trans loop process msg type %d", msg->what); + switch (msg->what) { + case LOOP_HANDSHAKE_MSG: + chanId = *((int32_t *)msg->obj); + TransProxyOpenProxyChannelSuccess(chanId); + break; + case LOOP_DISCONNECT_MSG: + connectionId = (uint32_t)msg->arg2; + TransProxyCloseConnChannel(connectionId); + break; + case LOOP_OPENFAIL_MSG: + chan = (ProxyChannelInfo *)msg->obj; + if (chan == NULL) { + return; + } + OnProxyChannelOpenFailed(chan->channelId, &(chan->appInfo)); + break; + case LOOP_OPENCLOSE_MSG: + chan = (ProxyChannelInfo *)msg->obj; + if (chan == NULL) { + return; + } + OnProxyChannelClosed(chan->channelId, &(chan->appInfo)); + break; + case LOOP_KEEPALIVE_MSG: + chan = (ProxyChannelInfo *)msg->obj; + if (chan == NULL) { + return; + } + TransProxyKeepalive(chan->connId, chan); + break; + case LOOP_RESETPEER_MSG: + chan = (ProxyChannelInfo *)msg->obj; + if (chan == NULL) { + return; + } + TransProxyResetPeer(chan); + break; + default: + break; + } +} + +void TransProxyFreeLoopMsg(SoftBusMessage *msg) +{ + if (msg != NULL) { + if (msg->obj != NULL) { + SoftBusFree(msg->obj); + } + SoftBusFree((void *)msg); + } +} +static SoftBusMessage *TransProxyCreateLoopMsg(int32_t what, uint64_t arg1, uint64_t arg2, char *data) +{ + SoftBusMessage *msg = NULL; + msg = SoftBusCalloc(sizeof(SoftBusMessage)); + if (msg == NULL) { + return NULL; + } + msg->what = what; + msg->arg1 = arg1; + msg->arg2 = arg2; + msg->handler = &g_transLoophandler; + msg->FreeMessage = TransProxyFreeLoopMsg; + msg->obj = (void *)data; + return msg; +} + +void TransProxyPostResetPeerMsgToLoop(const ProxyChannelInfo *chan) +{ + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_RESETPEER_MSG, 0, 0, (char *)chan); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +void TransProxyPostHandshakeMsgToLoop(int32_t chanId) +{ + int32_t *chanIdMsg = (int32_t *)SoftBusCalloc(sizeof(int32_t)); + if (chanIdMsg == NULL) { + return; + } + *chanIdMsg = chanId; + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_HANDSHAKE_MSG, 0, 0, (char *)chanIdMsg); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +void TransProxyPostDisConnectMsgToLoop(uint32_t connId) +{ + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_DISCONNECT_MSG, 0, connId, NULL); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +void TransProxyPostKeepAliveMsgToLoop(const ProxyChannelInfo *chan) +{ + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_KEEPALIVE_MSG, 0, 0, (char *)chan); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +void TransProxyPostOpenFailMsgToLoop(const ProxyChannelInfo *chan) +{ + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_OPENFAIL_MSG, 0, 0, (char *)chan); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +void TransProxyPostOpenClosedMsgToLoop(const ProxyChannelInfo *chan) +{ + SoftBusMessage *msg = TransProxyCreateLoopMsg(LOOP_OPENCLOSE_MSG, 0, 0, (char *)chan); + if (msg == NULL) { + return; + } + g_transLoophandler.looper->PostMessage(g_transLoophandler.looper, msg); + return; +} + +int32_t TransProxyLoopInit() +{ + g_transLoophandler.name = g_transProxyLoopName; + g_transLoophandler.looper = GetLooper(LOOP_TYPE_DEFAULT); + if (g_transLoophandler.looper == NULL) { + return SOFTBUS_ERR; + } + g_transLoophandler.HandleMessage = TransProxyLoopMsgHandler; + return SOFTBUS_OK; +} +int32_t TransProxyGetConnectOption(uint32_t connectionId, ConnectOption *info) +{ + ConnectionInfo connInfo = {0}; + + if (info == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (ConnGetConnectionInfo(connectionId, &connInfo) != SOFTBUS_OK) { + LOG_ERR("CONN_GetConnectionInfo fail connectionId %u", connectionId); + return SOFTBUS_ERR; + } + info->type = connInfo.type; + switch (info->type) { + case CONNECT_BR: { + (void)memcpy_s(info->info.brOption.brMac, sizeof(info->info.brOption.brMac), + connInfo.info.brInfo.brMac, sizeof(connInfo.info.brInfo.brMac)); + break; + } + case CONNECT_BLE: { + (void)memcpy_s(info->info.bleOption.bleMac, sizeof(info->info.bleOption.bleMac), + connInfo.info.bleInfo.bleMac, sizeof(connInfo.info.bleInfo.bleMac)); + (void)memcpy_s(info->info.bleOption.deviceIdHash, sizeof(info->info.bleOption.deviceIdHash), + connInfo.info.bleInfo.deviceIdHash, sizeof(connInfo.info.bleInfo.deviceIdHash)); + break; + } + case CONNECT_TCP: { + (void)memcpy_s(info->info.ipOption.ip, sizeof(info->info.ipOption.ip), + connInfo.info.ipInfo.ip, sizeof(connInfo.info.ipInfo.ip)); + info->info.ipOption.port = connInfo.info.ipInfo.port; + break; + } + default: { + return SOFTBUS_ERR; + } + } + return SOFTBUS_OK; +} + +int32_t TransProxyTransSendMsg(uint32_t connectionId, char *buf, int32_t len, int32_t priority) +{ + ConnPostData data = {0}; + static uint64_t seq = 1; + int32_t ret; + + data.module = MODULE_PROXY_CHANNEL; + data.seq = seq++; + data.flag = priority; + data.len = len; + data.buf = buf; + LOG_INFO("send buf connid %d len %d seq %llu pri %d", connectionId, len, data.seq, priority); + ret = ConnPostBytes(connectionId, &data); + if (ret < 0) { + LOG_ERR("conn send buf fail %d", ret); + return ret; + } + return SOFTBUS_OK; +} + +static void TransProxyOnConnected(uint32_t connId, const ConnectionInfo *connInfo) +{ + (void)connInfo; + LOG_INFO("connect enabled, connId = %u", connId); + return; +} + +static void TransProxyOnDisConnect(uint32_t connId, const ConnectionInfo *connInfo) +{ + (void)connInfo; + LOG_INFO("connect disabled, id = %u", connId); + TransProxyDelByConnId(connId); + TransDelConnByConnId(connId); + return; +} + +int32_t TransAddConnItem(ProxyConnInfo *chan) +{ + ProxyConnInfo *item = NULL; + ProxyConnInfo *tmpItem = NULL; + int find = 0; + + if (g_proxyConnectionList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(item, tmpItem, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (strcmp(item->connInfo.info.brOption.brMac, chan->connInfo.info.brOption.brMac) == 0) { + LOG_INFO("conn ref = %d", item->ref); + find = 1; + break; + } + } + if (find == 0) { + LOG_INFO("add conn item"); + ListAdd(&(g_proxyConnectionList->list), &(chan->node)); + g_proxyConnectionList->cnt++; + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_OK; + } else { + uint32_t state = item->state; + uint32_t connId = item->connId; + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + LOG_INFO("conn state %d conn id %d", state, connId); + if (state == PROXY_CHANNEL_STATUS_PYH_CONNECTED) { + TransProxyChanProcessByReqId(chan->requestId, connId); + } + return SOFTBUS_ERR; + } +} + +void TransCreateConnByConnId(uint32_t connId) +{ + ProxyConnInfo *item = NULL; + ProxyConnInfo *tmpNode = NULL; + ConnectionInfo info = {0}; + + if (g_proxyConnectionList == NULL) { + return; + } + + if (ConnGetConnectionInfo(connId, &info) != SOFTBUS_OK) { + LOG_ERR("CreateConn get conn info fail %d", connId); + return; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + LIST_FOR_EACH_ENTRY_SAFE(item, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (item->connId == connId) { + item->ref++; + LOG_INFO("repeat conn ref = %d", item->ref); + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; + } + } + + item = SoftBusCalloc(sizeof(ProxyConnInfo)); + if (item == NULL) { + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; + } + item->ref++; + item->state = PROXY_CHANNEL_STATUS_PYH_CONNECTED; + LOG_INFO("create conn ref = %d", item->ref); + item->connId = connId; + (void)memcpy_s(&(item->connInfo), sizeof(ConnectOption), &info, sizeof(ConnectOption)); + ListAdd(&(g_proxyConnectionList->list), &(item->node)); + g_proxyConnectionList->cnt++; + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; +} + + +static int32_t TransGetConnByMac(const char *brMac, ProxyConnInfo *conn) +{ + ProxyConnInfo *getNode = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY_SAFE(getNode, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (strcmp(getNode->connInfo.info.brOption.brMac, brMac) == 0) { + (void)memcpy_s(conn, sizeof(ProxyConnInfo), getNode, sizeof(ProxyConnInfo)); + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return SOFTBUS_ERR; +} + +void TransSetConnStateByReqId(uint32_t reqId, uint32_t connId, uint32_t state) +{ + ProxyConnInfo *getNode = NULL; + ProxyConnInfo *tmpNode = NULL; + + if (g_proxyConnectionList == NULL) { + return; + } + + if (pthread_mutex_lock(&g_proxyConnectionList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(getNode, tmpNode, &g_proxyConnectionList->list, ProxyConnInfo, node) { + if (getNode->requestId == reqId && getNode->state == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + getNode->state = state; + getNode->connId = connId; + getNode->requestId = 0; + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; + } + } + (void)pthread_mutex_unlock(&g_proxyConnectionList->lock); + return; +} + +static void TransOnConnectSuccessed(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *connInfo) +{ + LOG_INFO("Connect Successe reqid %d, connectionId %d", requestId, connectionId); + TransSetConnStateByReqId(requestId, connectionId, PROXY_CHANNEL_STATUS_PYH_CONNECTED); + TransProxyChanProcessByReqId(requestId, connectionId); +} + +static void TransOnConnectFailed(uint32_t requestId, int32_t reason) +{ + LOG_ERR("Connect fail id %u, reason %d", requestId, reason); + if (TransDelConnByReqId(requestId) != SOFTBUS_OK) { + LOG_ERR("Connect fail del reqid %u fail", requestId); + } + + TransProxyDelChanByReqId(requestId); +} + +int32_t TransProxyCloseConnChannel(uint32_t connectionId) +{ + if (TransDecConnRefByConnId(connectionId) == SOFTBUS_OK) { + LOG_INFO("disconnect device connid %d", connectionId); + } + return SOFTBUS_OK; +} + +int32_t TransProxyConnExistProc(ProxyConnInfo *conn, const AppInfo *appInfo, int32_t chanNewId) +{ + ProxyChannelInfo *chan = NULL; + chan = (ProxyChannelInfo *)SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (chan == NULL) { + LOG_ERR("SoftBusCalloc fail"); + return SOFTBUS_ERR; + } + + if (conn->state == PROXY_CHANNEL_STATUS_PYH_CONNECTING) { + chan->reqId = conn->requestId; + chan->status = PROXY_CHANNEL_STATUS_PYH_CONNECTING; + if (TransProxyCreateChanInfo(chan, chanNewId, appInfo) != SOFTBUS_OK) { + LOG_ERR("TransProxyCreateChanInfo err"); + SoftBusFree(chan); + return SOFTBUS_ERR; + } + } else { + chan->connId = conn->connId; + chan->status = PROXY_CHANNEL_STATUS_HANDSHAKEING; + if (TransProxyCreateChanInfo(chan, chanNewId, appInfo) != SOFTBUS_OK) { + LOG_ERR("TransProxyCreateChanInfo err"); + SoftBusFree(chan); + return SOFTBUS_ERR; + } + TransAddConnRefByConnId(conn->connId); + TransProxyPostHandshakeMsgToLoop(chanNewId); + } + return SOFTBUS_OK; +} + +int32_t TransProxyOpenConnChannel(const AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId) +{ + ConnectResult result = {0}; + ProxyConnInfo conn; + uint32_t reqId; + int32_t ret, chanNewId; + + reqId = ConnGetNewRequestId(MODULE_PROXY_CHANNEL); + chanNewId = TransProxyGetNewMyId(); + if (TransGetConnByMac(connInfo->info.brOption.brMac, &conn) == SOFTBUS_OK) { + if (TransProxyConnExistProc(&conn, appInfo, chanNewId) == SOFTBUS_ERR) { + return SOFTBUS_ERR; + } + *channelId = chanNewId; + return SOFTBUS_OK; + } + + ProxyChannelInfo *chan = (ProxyChannelInfo *)SoftBusCalloc(sizeof(ProxyChannelInfo)); + if (chan == NULL) { + LOG_ERR("SoftBusCalloc fail"); + return SOFTBUS_ERR; + } + chan->reqId = reqId; + chan->status = PROXY_CHANNEL_STATUS_PYH_CONNECTING; + if (TransProxyCreateChanInfo(chan, chanNewId, appInfo) != SOFTBUS_OK) { + SoftBusFree(chan); + LOG_ERR("TransProxyCreateChanInfo err"); + return SOFTBUS_ERR; + } + + ProxyConnInfo *connChan = (ProxyConnInfo *)SoftBusCalloc(sizeof(ProxyConnInfo)); + if (connChan == NULL) { + TransProxyDelChanByChanId(chanNewId); + return SOFTBUS_ERR; + } + connChan->requestId = reqId; + connChan->state = PROXY_CHANNEL_STATUS_PYH_CONNECTING; + *channelId = chanNewId; + + LOG_INFO("Connect dev reqid %d", reqId); + (void)memcpy_s(&(connChan->connInfo), sizeof(ConnectOption), connInfo, sizeof(ConnectOption)); + if (TransAddConnItem(connChan) != SOFTBUS_OK) { + LOG_INFO("conn add repeat"); + SoftBusFree(connChan); + return SOFTBUS_OK; + } + result.OnConnectFailed = TransOnConnectFailed; + result.OnConnectSuccessed = TransOnConnectSuccessed; + ret = ConnConnectDevice(connInfo, reqId, &result); + if (ret != SOFTBUS_OK) { + LOG_ERR("connect device err"); + TransDelConnByReqId(reqId); + TransProxyDelChanByChanId(chanNewId); + return ret; + } + return ret; +} + +static void TransProxyOnDataReceived(uint32_t connectionId, ConnModule moduleId, + int64_t seq, char *data, int32_t len) +{ + ProxyMessage msg; + + LOG_INFO("data recv connid :%u, moduleId %d, seq : %lld len %d", connectionId, moduleId, seq, len); + if (data == NULL) { + LOG_ERR("invalid param"); + return; + } + if (moduleId != MODULE_PROXY_CHANNEL) { + return; + } + (void)memset_s(&msg, sizeof(ProxyMessage), 0, sizeof(ProxyMessage)); + msg.connId = connectionId; + if (TransProxyParseMessage(data, len, &msg) != SOFTBUS_OK) { + LOG_ERR("parse proxy msg err"); + return; + } + TransProxyonMessageReceived(&msg); +} + +int32_t TransProxyTransInit(void) +{ + ConnectCallback proxyCallback = {0}; + + proxyCallback.OnConnected = TransProxyOnConnected; + proxyCallback.OnDisconnected = TransProxyOnDisConnect; + proxyCallback.OnDataReceived = TransProxyOnDataReceived; + if (ConnSetConnectCallback(MODULE_PROXY_CHANNEL, &proxyCallback) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + + g_proxyConnectionList = CreateSoftBusList(); + if (g_proxyConnectionList == NULL) { + LOG_ERR("create observer list failed"); + return SOFTBUS_ERR; + } + if (TransProxyLoopInit() != SOFTBUS_OK) { + LOG_ERR("create loopInit fail"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} diff --git a/core/transmission/trans_channel/tcp_direct/BUILD.gn b/core/transmission/trans_channel/tcp_direct/BUILD.gn new file mode 100755 index 000000000..7cc4b101c --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +static_library("trans_tcp_direct") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/transmission/common/include", + "//third_party/cJSON", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/wifi_common/base_listener/include", + "$dsoftbus_root_path/core/common/wifi_common/tcp_socket/include", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/transmission/session/include", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "src/trans_tcp_direct_listener.c", + "src/trans_tcp_direct_manager.c", + "src/trans_tcp_direct_message.c", + ] + deps = [ + "$dsoftbus_root_path/core/common:softbus_core_common", + "$dsoftbus_root_path/core/connection/common:conn_common", + "$dsoftbus_root_path/core/transmission/common:transmission_common", + ] +} diff --git a/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_listener.h b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_listener.h new file mode 100755 index 000000000..c91783335 --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_listener.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SOFTBUS_SESSION_LISTENER +#define SOFTBUS_SESSION_LISTENER + +#include "softbus_base_listener.h" +#include "trans_tcp_direct_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransTdcStartSessionListener(const char *ip, const int port); +int32_t TransTdcStopSessionListener(void); +SoftbusBaseListener *TransTdcGetSessionListener(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_manager.h b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_manager.h new file mode 100755 index 000000000..df9a09111 --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_manager.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_DIRECT_CHANNEL_INTERFACE_H +#define SOFTBUS_DIRECT_CHANNEL_INTERFACE_H + +#include + +#include "softbus_app_info.h" +#include "softbus_base_listener.h" +#include "softbus_conn_interface.h" +#include "softbus_property.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DC_MSG_PACKET_HEAD_SIZE 24 +#define SESSION_KEY_INDEX_SIZE 4 +#define MESSAGE_INDEX_SIZE 4 + +#define MAGIC_NUMBER 0xBABEFACE +#define MODULE_SESSION 6 +#define FLAG_REPLY 1 + +#define SKEY_LENGTH 16 + +typedef enum { + TCP_DIRECT_CHANNEL_STATUS_CONNECTED, + TCP_DIRECT_CHANNEL_STATUS_CONNECTING, + TCP_DIRECT_CHANNEL_STATUS_HANDSHAKING, + TCP_DIRECT_CHANNEL_STATUS_HANDSHAKE_TIMEOUT, +} TcpDirectChannelStatus; + +typedef struct { + char sessionKey[SKEY_LENGTH]; + int sessionIndex; +} IAuthConnection; + +typedef struct { + uint32_t offset; + uint8_t data[MAX_BUF_LENGTH]; +} DcDataBuffer; + +typedef struct { + ListNode node; + DcDataBuffer dataBuffer; + bool serverSide; + bool authStarted; + bool openChannelFinished; + long channelId; + TriggerType triggerType; + pthread_mutex_t lock; + pthread_cond_t cond; + AppInfo appInfo; + IAuthConnection authConn; + uint32_t status; + uint32_t timeout; +} SessionConn; + +typedef struct { + uint32_t magicNumber; + uint32_t module; + uint64_t seq; + uint32_t flags; + uint32_t dataLen; +} TdcPacketHead; + +int32_t TransOpenTcpDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int *fd); +int32_t TransCloseDirectChannel(int32_t channelId); +uint64_t TransTdcGetNewSeqId(bool serverSide); +SessionConn *GetTdcInfoByChannelId(int32_t channelId); +SessionConn *GetTdcInfoByFd(int fd); + +int32_t TransTdcAddSessionConn(SessionConn *conn, const TriggerType triggerType); +void TransTdcStopSessionConn(int32_t channelId); +void TransTdcCloseSessionConn(int32_t channelId); + +SoftBusList *GetTdcInfoList(void); +void SetTdcInfoList(SoftBusList *sessionConnList); +int32_t TransTcpDirectInit(void); +void TransTcpDirectDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_message.h b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_message.h new file mode 100755 index 000000000..78cc763b5 --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/include/trans_tcp_direct_message.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SESSION_CONNECT_H +#define SOFTBUS_SESSION_CONNECT_H + +#include + +#include "softbus_app_info.h" +#include "softbus_base_listener.h" +#include "stdbool.h" +#include "stdint.h" +#include "trans_tcp_direct_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransTdcPostBytes(int32_t channelId, TdcPacketHead *packetHead, const char *data); +int32_t TransTdcProcessPacket(int32_t channelId); + +int32_t NotifyChannelOpenFailed(int32_t channelId); +int32_t NotifyChannelClosed(int32_t channelId); + +#ifdef __cplusplus +} +#endif +#endif // SOFTBUS_SESSION_CONNECT_H diff --git a/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_listener.c b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_listener.c new file mode 100755 index 000000000..e70828b1a --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_listener.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_tcp_direct_listener.h" + +#include +#include +#include + +#include "auth_interface.h" +#include "bus_center_manager.h" +#include "softbus_base_listener.h" +#include "softbus_crypto.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_message_open_channel.h" +#include "softbus_tcp_socket.h" +#include "trans_tcp_direct_message.h" + +static SoftbusBaseListener *g_sessionListener = NULL; + +static int32_t StartVerifySession(SessionConn *conn) +{ + LOG_INFO("StartVerifySession"); + if (conn->authStarted == true) { + return SOFTBUS_OK; + } + + uint64_t seq = TransTdcGetNewSeqId(conn->serverSide); + if (GenerateSessionKey(conn->appInfo.sessionKey, SESSION_KEY_LENGTH) != SOFTBUS_OK) { + LOG_ERR("Generate SessionKey failed"); + return SOFTBUS_ERR; + } + char *bytes = PackRequest(&conn->appInfo); + if (bytes == NULL) { + LOG_ERR("Pack Request failed"); + return SOFTBUS_ERR; + } + uint32_t flags = 0; + uint32_t dataLen = strlen(bytes) + OVERHEAD_LEN + MESSAGE_INDEX_SIZE; + TdcPacketHead packetHead = { + .magicNumber = MAGIC_NUMBER, + .module = MODULE_SESSION, + .seq = seq, + .flags = flags, + .dataLen = dataLen, + }; + + if (TransTdcPostBytes(conn->channelId, &packetHead, bytes) != SOFTBUS_OK) { + LOG_ERR("TransTdc post bytes failed"); + SoftBusFree(bytes); + return SOFTBUS_ERR; + } + SoftBusFree(bytes); + LOG_INFO("StartVerifySession ok"); + + conn->authStarted = true; + return SOFTBUS_OK; +} + +static int32_t GetUuidFromAuth(const char *ip, char *uuid, uint32_t len) +{ + if (ip == NULL || uuid == NULL) { + return SOFTBUS_ERR; + } + ConnectOption option = {0}; + option.type = CONNECT_TCP; + if (strcpy_s(option.info.ipOption.ip, IP_LEN, ip) != 0) { + LOG_ERR("strcpy_s peer ip err."); + return SOFTBUS_MEM_ERR; + } + if (AuthGetUuidByOption(&option, uuid, len) != SOFTBUS_OK) { + LOG_ERR("get uuid fail."); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +static int32_t OnConnectEvent(int events, int cfd, const char *ip) +{ + if (events == SOFTBUS_SOCKET_EXCEPTION) { + LOG_ERR("Exception occurred"); + return SOFTBUS_ERR; + } + if (cfd < 0 || ip == NULL) { + LOG_ERR("invalid param, cfd = %d", cfd); + return SOFTBUS_INVALID_PARAM; + } + SessionConn *item = (SessionConn *)SoftBusMalloc(sizeof(SessionConn)); + if (item == NULL) { + LOG_ERR("Malloc error occurred"); + return SOFTBUS_MALLOC_ERR; + } + item->appInfo.myData.apiVersion = API_V2; + item->appInfo.fd = cfd; + item->serverSide = true; + item->channelId = cfd; + item->status = TCP_DIRECT_CHANNEL_STATUS_CONNECTING; + item->timeout = 0; + + if (LnnGetLocalStrInfo(STRING_KEY_UUID, item->appInfo.myData.deviceId, + sizeof(item->appInfo.myData.deviceId)) != 0) { + LOG_ERR("get local deviceId failed"); + SoftBusFree(item); + return SOFTBUS_ERR; + } + + if (GetUuidFromAuth(ip, item->appInfo.peerData.deviceId, DEVICE_ID_SIZE_MAX) != SOFTBUS_OK) { + SoftBusFree(item); + return SOFTBUS_ERR; + } + + if (memcpy_s(item->appInfo.peerData.ip, IP_LEN, ip, strlen(ip) + 1) != EOK) { + SoftBusFree(item); + return SOFTBUS_MEM_ERR; + } + + char *authState = ""; + if (memcpy_s(item->appInfo.myData.authState, AUTH_STATE_SIZE_MAX, "", strlen(authState) + 1) != EOK) { + SoftBusFree(item); + return SOFTBUS_MEM_ERR; + } + + if (TransTdcAddSessionConn(item, RW_TRIGGER) != SOFTBUS_OK) { + LOG_ERR("TransTdcAddSessionConn failed"); + TransTdcCloseSessionConn(item->channelId); + SoftBusFree(item); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static int32_t OnDataEvent(int events, int fd) +{ + SessionConn *item = GetTdcInfoByFd(fd); + if (item == NULL || item->appInfo.fd != fd) { + LOG_ERR("fd[%d] is not exist tdc info", fd); + return SOFTBUS_ERR; + } + + if (events == SOFTBUS_SOCKET_EXCEPTION) { + LOG_ERR("Exception occurred"); + TransTdcCloseSessionConn(item->channelId); + if (item->serverSide == true || item->openChannelFinished == true) { + SoftBusFree(item); + } + return SOFTBUS_ERR; + } + if (events == SOFTBUS_SOCKET_OUT && item->serverSide == false) { + if (StartVerifySession(item) != SOFTBUS_OK) { + TransTdcCloseSessionConn(item->channelId); + if (item->serverSide == true || item->openChannelFinished == true) { + SoftBusFree(item); + } + return SOFTBUS_ERR; + } + } + if (TransTdcProcessPacket(item->channelId) != SOFTBUS_OK) { + LOG_ERR("ProcessPacket err"); + TransTdcCloseSessionConn(item->channelId); + if (item->serverSide == true || item->openChannelFinished == true) { + SoftBusFree(item); + } + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransTdcStartSessionListener(const char *ip, const int port) +{ + if (ip == NULL || port < 0) { + LOG_ERR("Invalid para."); + return SOFTBUS_INVALID_PARAM; + } + if (g_sessionListener == NULL) { + g_sessionListener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener)); + if (g_sessionListener == NULL) { + LOG_ERR("Failed to create listener"); + return SOFTBUS_ERR; + } + } + + g_sessionListener->onConnectEvent = OnConnectEvent; + g_sessionListener->onDataEvent = OnDataEvent; + + int32_t ret = SetSoftbusBaseListener(DIRECT_CHANNEL_SERVER, g_sessionListener); + if (ret != SOFTBUS_OK) { + LOG_ERR("Set BaseListener Failed."); + SoftBusFree(g_sessionListener); + g_sessionListener = NULL; + return ret; + } + + if (GetTdcInfoList() == NULL) { + SetTdcInfoList(CreateSoftBusList()); + if (GetTdcInfoList() == NULL) { + SoftBusFree(g_sessionListener); + g_sessionListener = NULL; + LOG_ERR("GetTdcInfoList is null."); + return SOFTBUS_MALLOC_ERR; + } + } + + int serverPort = StartBaseListener(DIRECT_CHANNEL_SERVER, ip, port, SERVER_MODE); + return serverPort; +} + +int32_t TransTdcStopSessionListener(void) +{ + int32_t ret = SetSoftbusBaseListener(DIRECT_CHANNEL_SERVER, g_sessionListener); + if (ret != SOFTBUS_OK) { + LOG_ERR("Set BaseListener Failed."); + return ret; + } + + if (g_sessionListener != NULL) { + SoftBusFree(g_sessionListener); + g_sessionListener = NULL; + } + + if (GetTdcInfoList() != NULL) { + DestroySoftBusList(GetTdcInfoList()); + SetTdcInfoList(NULL); + } + + ret = StopBaseListener(DIRECT_CHANNEL_SERVER); + return ret; +} + +SoftbusBaseListener *TransTdcGetSessionListener(void) +{ + return g_sessionListener; +} + diff --git a/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_manager.c b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_manager.c new file mode 100755 index 000000000..98d021b30 --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_manager.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_tcp_direct_manager.h" + +#include +#include + +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_tcp_socket.h" +#include "trans_tcp_direct_listener.h" +#include "trans_tcp_direct_message.h" + +#define TCP_DIRECT_CHANNEL_OPEN_TIMEOUT 19 + +static SoftBusList *g_sessionConnList = NULL; + +static int32_t InitTdcInfo(SessionConn *newConn) +{ + if (pthread_mutex_init(&(newConn->lock), NULL)) { + LOG_ERR("create mutex lock fail."); + return SOFTBUS_ERR; + } + + if (TransTdcAddSessionConn(newConn, RW_TRIGGER) != SOFTBUS_OK) { + TransTdcCloseSessionConn(newConn->channelId); + LOG_ERR("TransTdc add sessionConn err."); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +static void TransTdcTimerProc(void) +{ + SessionConn *removeNode = NULL; + SessionConn *nextNode = NULL; + + if (g_sessionConnList == NULL || g_sessionConnList->cnt == 0) { + return; + } + if (pthread_mutex_lock(&g_sessionConnList->lock) != 0) { + LOG_ERR("lock mutex fail!"); + return; + } + + LIST_FOR_EACH_ENTRY_SAFE(removeNode, nextNode, &g_sessionConnList->list, SessionConn, node) { + removeNode->timeout++; + if (removeNode->status == TCP_DIRECT_CHANNEL_STATUS_HANDSHAKING) { + if (removeNode->timeout >= TCP_DIRECT_CHANNEL_OPEN_TIMEOUT) { + removeNode->status = TCP_DIRECT_CHANNEL_STATUS_HANDSHAKE_TIMEOUT; + + (void)pthread_mutex_unlock(&g_sessionConnList->lock); + NotifyChannelOpenFailed(removeNode->channelId); + pthread_mutex_lock(&g_sessionConnList->lock); + + ListDelete(&removeNode->node); + g_sessionConnList->cnt--; + int fd = removeNode->appInfo.fd; + if (fd >= 0) { + LOG_INFO("fd[%d] is shutdown", fd); + DelTrigger(DIRECT_CHANNEL_SERVER, fd, removeNode->triggerType); + TcpShutDown(fd); + } + + LOG_ERR("channel (%ld) handshake is timeout", removeNode->channelId); + SoftBusFree(removeNode); + } + } + } + (void)pthread_mutex_unlock(&g_sessionConnList->lock); +} + +static int32_t OpenConnTcp(AppInfo *appInfo, const ConnectOption *connInfo) +{ + if (appInfo == NULL || connInfo == NULL) { + LOG_ERR("Invalid para."); + return SOFTBUS_ERR; + } + char *ip = (char*)connInfo->info.ipOption.ip; + char *myIp = NULL; + int sessionPort = connInfo->info.ipOption.port; + int fd = OpenTcpClientSocket(ip, myIp, sessionPort); + if (fd < 0) { + LOG_ERR("Open socket err."); + return SOFTBUS_ERR; + } + + return fd; +} + +int32_t TransOpenTcpDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int *fd) +{ + if (appInfo == NULL || connInfo == NULL || fd == NULL) { + LOG_ERR("param is invalid."); + return SOFTBUS_INVALID_PARAM; + } + + char *ip = (char*)connInfo->info.ipOption.ip; + int sessionPort = connInfo->info.ipOption.port; + appInfo->routeType = WIFI_STA; + SessionConn *newConn = (SessionConn*)SoftBusMalloc(sizeof(SessionConn)); + if (newConn == NULL) { + LOG_ERR("Malloc err."); + return SOFTBUS_ERR; + } + if (memcpy_s(&newConn->appInfo, sizeof(AppInfo), appInfo, sizeof(AppInfo)) != EOK) { + SoftBusFree(newConn); + LOG_ERR("Memcpy ip err."); + return SOFTBUS_ERR; + } + newConn->appInfo.fd = -1; + newConn->serverSide = false; + newConn->channelId = INVALID_CHANNEL_ID; + if (strcpy_s(newConn->appInfo.peerData.ip, IP_LEN, ip) != EOK) { + SoftBusFree(newConn); + LOG_ERR("strcpy_s err."); + return SOFTBUS_ERR; + } + newConn->appInfo.peerData.port = sessionPort; + newConn->status = TCP_DIRECT_CHANNEL_STATUS_HANDSHAKING; + newConn->timeout = 0; + + if (InitTdcInfo(newConn) != SOFTBUS_OK) { + SoftBusFree(newConn); + return SOFTBUS_ERR; + } + + *fd = OpenConnTcp(appInfo, connInfo); + if (*fd <= 0) { + TransCloseDirectChannel(newConn->channelId); + SoftBusFree(newConn); + LOG_ERR("OpenConnTcp err."); + return SOFTBUS_ERR; + } + + newConn->appInfo.fd = *fd; + newConn->channelId = *fd; + if (AddTrigger(DIRECT_CHANNEL_SERVER, newConn->appInfo.fd, RW_TRIGGER) != SOFTBUS_OK) { + TransCloseDirectChannel(newConn->channelId); + SoftBusFree(newConn); + LOG_ERR("AddTrigger failed"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int32_t TransCloseDirectChannel(int channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("SessionConn is not exit"); + return SOFTBUS_ERR; + } + TransTdcCloseSessionConn(channelId); + SoftBusFree(tdcInfo); + return SOFTBUS_OK; +} + +int32_t TransTdcAddSessionConn(SessionConn *conn, TriggerType triggerType) +{ + if (conn == NULL || g_sessionConnList == NULL || TransTdcGetSessionListener() == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + pthread_mutex_lock(&(g_sessionConnList->lock)); + ListInit(&conn->node); + ListTailInsert(&g_sessionConnList->list, &conn->node); + g_sessionConnList->cnt++; + pthread_mutex_unlock(&g_sessionConnList->lock); + conn->triggerType = triggerType; + conn->authStarted = false; + conn->openChannelFinished = false; + if (conn->appInfo.fd >= 0) { + if (AddTrigger(DIRECT_CHANNEL_SERVER, conn->appInfo.fd, triggerType) != SOFTBUS_OK) { + LOG_ERR("AddTrigger failed"); + return SOFTBUS_ERR; + } + } + return SOFTBUS_OK; +} + +void TransTdcStopSessionConn(int32_t channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("get tdc intfo err"); + return; + } + DelTrigger(DIRECT_CHANNEL_SERVER, tdcInfo->appInfo.fd, tdcInfo->triggerType); + return; +} + +void TransTdcCloseSessionConn(int32_t channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL || g_sessionConnList == NULL) { + LOG_ERR("get tdc intfo err"); + return; + } + pthread_mutex_lock(&(g_sessionConnList->lock)); + ListDelete(&tdcInfo->node); + g_sessionConnList->cnt--; + pthread_mutex_unlock(&(g_sessionConnList->lock)); + int fd = tdcInfo->appInfo.fd; + TransTdcStopSessionConn(tdcInfo->channelId); + if (fd >= 0) { + LOG_INFO("fd[%d] is shutdown", fd); + TcpShutDown(fd); + } + NotifyChannelClosed(tdcInfo->channelId); +} + +SessionConn *GetTdcInfoByChannelId(int32_t channelId) +{ + if (g_sessionConnList == NULL) { + LOG_ERR("get tdc intfo err, infoList is null."); + return NULL; + } + SessionConn *connInfo = NULL; + pthread_mutex_lock(&(g_sessionConnList->lock)); + LIST_FOR_EACH_ENTRY(connInfo, &g_sessionConnList->list, SessionConn, node) { + if (connInfo->channelId == channelId) { + pthread_mutex_unlock(&g_sessionConnList->lock); + return connInfo; + } + } + pthread_mutex_unlock(&g_sessionConnList->lock); + + LOG_ERR("get tdc info is null"); + return NULL; +} + +SessionConn *GetTdcInfoByFd(int fd) +{ + if (g_sessionConnList == NULL) { + LOG_ERR("get tdc intfo err, infoList is null."); + return NULL; + } + SessionConn *connInfo = NULL; + pthread_mutex_lock(&(g_sessionConnList->lock)); + LIST_FOR_EACH_ENTRY(connInfo, &g_sessionConnList->list, SessionConn, node) { + if (connInfo->appInfo.fd == fd) { + pthread_mutex_unlock(&g_sessionConnList->lock); + return connInfo; + } + } + pthread_mutex_unlock(&g_sessionConnList->lock); + + return NULL; +} + +uint64_t TransTdcGetNewSeqId(bool serverSide) +{ +#define TRANS_SEQ_STEP 2 + static uint64_t seq = 0; + seq += TRANS_SEQ_STEP; + if (serverSide) { + return seq + 1; + } + return seq; +} + +SoftBusList *GetTdcInfoList(void) +{ + return g_sessionConnList; +} + +void SetTdcInfoList(SoftBusList *sessionConnList) +{ + g_sessionConnList = sessionConnList; + return; +} + +int32_t TransTcpDirectInit(void) +{ + if (RegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, TransTdcTimerProc) != SOFTBUS_OK) { + LOG_ERR("RegisterTimeoutCallback failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +void TransTcpDirectDeinit(void) +{ + (void)RegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, NULL); +} diff --git a/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_message.c b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_message.c new file mode 100644 index 000000000..ab657fb52 --- /dev/null +++ b/core/transmission/trans_channel/tcp_direct/src/trans_tcp_direct_message.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_tcp_direct_message.h" + +#include +#include + +#include "auth_interface.h" +#include "bus_center_manager.h" +#include "cJSON.h" +#include "softbus_crypto.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_message_open_channel.h" +#include "softbus_tcp_socket.h" +#include "trans_session_manager.h" +#include "trans_tcp_direct_manager.h" + +#define MAX_PACKET_SIZE (64 * 1024) + +static int32_t PackBytes(int32_t channelId, const uint8_t *data, TdcPacketHead *packetHead, uint8_t *buffer, + uint32_t bufLen) +{ + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL || data == NULL || buffer == NULL || packetHead == NULL || bufLen == 0) { + LOG_ERR("Invalid para."); + return SOFTBUS_INVALID_PARAM; + } + if (memcpy_s(buffer, bufLen, packetHead, sizeof(TdcPacketHead)) != EOK) { + LOG_ERR("memcpy packetHead error."); + return SOFTBUS_ERR; + } + + ConnectOption option = {0}; + option.type = CONNECT_TCP; + if (strcpy_s(option.info.ipOption.ip, IP_LEN, conn->appInfo.peerData.ip) != 0) { + LOG_ERR("strcpy_s peer ip err."); + return SOFTBUS_ERR; + } + option.info.ipOption.port = conn->appInfo.peerData.port; + + AuthSideFlag side; + uint32_t len = packetHead->dataLen - SESSION_KEY_INDEX_SIZE - OVERHEAD_LEN; + OutBuf outbuf = {0}; + outbuf.buf = buffer + DC_MSG_PACKET_HEAD_SIZE; + outbuf.bufLen = packetHead->dataLen; + + int32_t ret = AuthEncrypt(&option, &side, (uint8_t*)data, len, &outbuf); + if (ret != SOFTBUS_OK) { + LOG_ERR("AuthDecrypt err."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransTdcPostBytes(int32_t channelId, TdcPacketHead *packetHead, const char *data) +{ + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL || data == NULL || packetHead == NULL) { + LOG_ERR("Invalid para."); + return SOFTBUS_INVALID_PARAM; + } + uint32_t bufferLen = packetHead->dataLen + DC_MSG_PACKET_HEAD_SIZE; + if (bufferLen <= OVERHEAD_LEN + MESSAGE_INDEX_SIZE + DC_MSG_PACKET_HEAD_SIZE) { + LOG_ERR("Invalid bufferLen."); + return SOFTBUS_INVALID_PARAM; + } + char *buffer = (char *)SoftBusMalloc(bufferLen); + if (buffer == NULL) { + LOG_ERR("buffer malloc error."); + return SOFTBUS_MALLOC_ERR; + } + if (PackBytes(channelId, (uint8_t*)data, packetHead, (uint8_t*)buffer, bufferLen) != SOFTBUS_OK) { + LOG_ERR("Pack Bytes error."); + SoftBusFree(buffer); + return SOFTBUS_ENCRYPT_ERR; + } + if (SendTcpData(conn->appInfo.fd, buffer, bufferLen, 0) != (int)bufferLen) { + SoftBusFree(buffer); + return SOFTBUS_ERR; + } + SoftBusFree(buffer); + return SOFTBUS_OK; +} + +static int32_t RecvPacket(int32_t channelId, uint32_t len) +{ + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL || len >= MAX_BUF_LENGTH) { + LOG_ERR("Invalid para, len=%u", len); + return SOFTBUS_INVALID_PARAM; + } + while (conn->dataBuffer.offset < len) { + int32_t rc = RecvTcpData(conn->appInfo.fd, (char*)(conn->dataBuffer.data + conn->dataBuffer.offset), + len - conn->dataBuffer.offset, 0); + if (rc < 0) { + return rc; + } else if (rc == 0) { + break; + } else { + conn->dataBuffer.offset += (uint32_t)rc; + } + } + return conn->dataBuffer.offset; +} + +static int32_t DecryptMessage(int32_t channelId, const TdcPacketHead *pktHead, uint8_t *out, uint32_t *outLen) +{ + if (channelId < 0 || pktHead == NULL || out == NULL || outLen == NULL) { + LOG_ERR("param is invalid."); + return SOFTBUS_ERR; + } + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL) { + LOG_ERR("channelId[%d] is not exist.", channelId); + return SOFTBUS_ERR; + } + + ConnectOption option = {0}; + option.type = CONNECT_TCP; + if (strcpy_s(option.info.ipOption.ip, IP_LEN, conn->appInfo.peerData.ip) != 0) { + LOG_ERR("strcpy_s peer ip err."); + return SOFTBUS_ERR; + } + option.info.ipOption.port = conn->appInfo.peerData.port; + + AuthSideFlag side = CLIENT_SIDE_FLAG; + uint8_t *data = conn->dataBuffer.data + DC_MSG_PACKET_HEAD_SIZE; + uint32_t len = pktHead->dataLen; + + OutBuf outbuf = {0}; + outbuf.bufLen = pktHead->dataLen - SESSION_KEY_INDEX_SIZE - OVERHEAD_LEN + 1; + outbuf.buf = out; + int32_t ret = AuthDecrypt(&option, side, data, len, &outbuf); + if (ret != SOFTBUS_OK) { + LOG_ERR("AuthDecrypt err."); + return SOFTBUS_ERR; + } + *outLen = outbuf.outLen; + return ret; +} + +static int32_t NotifyChannelOpened(int32_t channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("notify channel open failed, get tdcInfo is null"); + return SOFTBUS_ERR; + } + ChannelInfo info = {0}; + info.channelId = channelId; + info.channelType = CHANNEL_TYPE_TCP_DIRECT; + info.isServer = tdcInfo->serverSide; + info.isEnabled = true; + info.fd = channelId; + info.sessionKey = tdcInfo->appInfo.sessionKey; + + info.peerSessionName = tdcInfo->appInfo.peerData.sessionName; + info.groupId = tdcInfo->appInfo.groupId; + info.keyLen = SESSION_KEY_LENGTH; + + char buf[NETWORK_ID_BUF_LEN] = {0}; + int32_t ret = LnnGetNetworkIdByUuid(tdcInfo->appInfo.peerData.deviceId, buf, NETWORK_ID_BUF_LEN); + if (ret != SOFTBUS_OK) { + LOG_ERR("get info networkId fail."); + return SOFTBUS_ERR; + } + info.peerDeviceId = buf; + + char pkgName[PKG_NAME_SIZE_MAX] = {0}; + if (TransGetPkgNameBySessionName(info.peerSessionName, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("get pkg name fail."); + return SOFTBUS_ERR; + } + ret = GetClientProvideInterface()->onChannelOpened(pkgName, tdcInfo->appInfo.myData.sessionName, &info); + tdcInfo->status = TCP_DIRECT_CHANNEL_STATUS_CONNECTED; + return ret; +} + +int32_t NotifyChannelOpenFailed(int32_t channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("notify channel open failed, get tdcInfo is null"); + return SOFTBUS_ERR; + } + + char pkgName[PKG_NAME_SIZE_MAX] = {0}; + if (TransGetPkgNameBySessionName(tdcInfo->appInfo.peerData.sessionName, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("get pkg name fail."); + return SOFTBUS_ERR; + } + + int ret = GetClientProvideInterface()->onChannelOpenFailed(pkgName, channelId); + LOG_INFO("TCP direct channel failed, channelId = %d, ret = %d", channelId, ret); + return ret; +} + +int32_t NotifyChannelClosed(int32_t channelId) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("notify channel closed failed(%d), get tdcInfo is null", channelId); + return SOFTBUS_ERR; + } + + if (tdcInfo->serverSide == false) { + int ret = GetClientProvideInterface()->onChannelClosed(tdcInfo->appInfo.myData.pkgName, channelId); + LOG_INFO("TCP direct channel close, channelId = %d, ret = %d", channelId, ret); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t OpenDataBusReply(int32_t channelId, uint64_t seq, const cJSON *reply) +{ + SessionConn *tdcInfo = GetTdcInfoByChannelId(channelId); + if (tdcInfo == NULL) { + LOG_ERR("notify channel open failed, get tdcInfo is null"); + return SOFTBUS_ERR; + } + if (UnpackReply(reply, &tdcInfo->appInfo) != SOFTBUS_OK) { + LOG_ERR("UnpackReply failed"); + return SOFTBUS_ERR; + } + + TransTdcStopSessionConn(tdcInfo->channelId); + int32_t ret = NotifyChannelOpened(tdcInfo->channelId); + pthread_mutex_lock(&(GetTdcInfoList()->lock)); + tdcInfo->openChannelFinished = true; + ListDelete(&tdcInfo->node); + GetTdcInfoList()->cnt--; + pthread_mutex_unlock(&(GetTdcInfoList()->lock)); + + if (tdcInfo->serverSide == true || tdcInfo->openChannelFinished == true) { + SoftBusFree(tdcInfo); + } + return ret; +} + +static int32_t OpenDataBusRequest(int32_t channelId, uint32_t flags, uint64_t seq, const cJSON *request) +{ + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL || request == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (UnpackRequest(request, &conn->appInfo) != SOFTBUS_OK) { + LOG_ERR("UnpackRequest error"); + return SOFTBUS_ERR; + } + TransTdcStopSessionConn(channelId); + int32_t ret = NotifyChannelOpened(channelId); + TdcPacketHead packetHead = { + .magicNumber = MAGIC_NUMBER, + .module = MODULE_SESSION, + .seq = seq, + .flags = flags | FLAG_REPLY, + .dataLen = 0, + }; + + if (ret != SOFTBUS_OK) { + LOG_ERR("NotifyChannelOpened err"); + char *errDesc = "notifyChannelOpened"; + char *errReply = PackError(ret, errDesc); + if (errReply == NULL) { + LOG_ERR("Failed to send notify channel opened"); + return SOFTBUS_ERR; + } + + packetHead.dataLen = strlen(errReply) + OVERHEAD_LEN + MESSAGE_INDEX_SIZE; + ret = TransTdcPostBytes(channelId, &packetHead, errReply); + if (ret != SOFTBUS_OK) { + LOG_ERR("TransTdc post bytes failed"); + SoftBusFree(errReply); + return SOFTBUS_ERR; + } + SoftBusFree(errReply); + return SOFTBUS_ERR; + } + char *reply = PackReply(&conn->appInfo); + if (reply == NULL) { + LOG_ERR("PackReply failed"); + return SOFTBUS_ERR; + } + + packetHead.dataLen = strlen(reply) + OVERHEAD_LEN + MESSAGE_INDEX_SIZE; + ret = TransTdcPostBytes(channelId, &packetHead, reply); + if (ret != SOFTBUS_OK) { + LOG_ERR("TransTdc post bytes failed"); + SoftBusFree(reply); + return SOFTBUS_ERR; + } + SoftBusFree(reply); + pthread_mutex_lock(&(GetTdcInfoList()->lock)); + ListDelete(&conn->node); + GetTdcInfoList()->cnt--; + pthread_mutex_unlock(&(GetTdcInfoList()->lock)); + if (conn->serverSide == true || conn->openChannelFinished == true) { + SoftBusFree(conn); + } + return SOFTBUS_OK; +} + +static int32_t MessageReceived(int32_t channelId, uint32_t flags, uint64_t seq, const cJSON *packet) +{ + if (flags & FLAG_REPLY) { + return OpenDataBusReply(channelId, seq, packet); + } + return OpenDataBusRequest(channelId, FLAG_REPLY, seq, packet); +} + +static int32_t DataReceived(int32_t channelId, const TdcPacketHead *pktHead) +{ + switch (pktHead->module) { + case MODULE_SESSION: { + uint8_t *out = (uint8_t*)SoftBusCalloc(pktHead->dataLen - SESSION_KEY_INDEX_SIZE - OVERHEAD_LEN + 1); + if (out == NULL) { + LOG_INFO("malloc fail."); + return SOFTBUS_ERR; + } + uint32_t outLen; + if (DecryptMessage(channelId, pktHead, out, &outLen) != SOFTBUS_OK) { + LOG_ERR("Decrypt Message err."); + SoftBusFree(out); + return SOFTBUS_ERR; + } + out[outLen] = 0; + cJSON *packet = cJSON_Parse((char*)out); + if (packet == NULL) { + SoftBusFree(out); + LOG_ERR("json parse failed."); + return SOFTBUS_ERR; + } + int ret = MessageReceived(channelId, pktHead->flags, pktHead->seq, packet); + SoftBusFree(out); + cJSON_Delete(packet); + return ret; + } + default: { + NotifyChannelClosed(channelId); + TransTdcCloseSessionConn(channelId); + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL) { + LOG_ERR("Invalid para"); + return SOFTBUS_INVALID_PARAM; + } + SoftBusFree(conn); + return -1; + } + } +} + +int32_t TransTdcProcessPacket(int32_t channelId) +{ + SessionConn *conn = GetTdcInfoByChannelId(channelId); + if (conn == NULL) { + LOG_ERR("Invalid para"); + return SOFTBUS_INVALID_PARAM; + } + conn->dataBuffer.offset = 0; + int rc = RecvPacket(channelId, DC_MSG_PACKET_HEAD_SIZE); + if (rc <= 0) { + LOG_ERR("recv failed."); + return SOFTBUS_ERR; + } + if (rc < DC_MSG_PACKET_HEAD_SIZE) { + LOG_ERR("MsgPacketHeadRecv failed, recv next time."); + return SOFTBUS_OK; + } + + TdcPacketHead *pktHead = (TdcPacketHead *)(conn->dataBuffer.data); + if (pktHead->magicNumber != MAGIC_NUMBER) { + LOG_ERR("Invalid packetHead"); + return SOFTBUS_ERR; + } + uint32_t dataLen = pktHead->dataLen; + if (dataLen > MAX_PACKET_SIZE - DC_MSG_PACKET_HEAD_SIZE) { + LOG_ERR("Invalid packet size, %u", dataLen); + return SOFTBUS_ERR; + } + + rc = RecvPacket(channelId, DC_MSG_PACKET_HEAD_SIZE + dataLen); + if (rc < 0) { + LOG_ERR("Connection break"); + return SOFTBUS_ERR; + } + if (rc < (int)(DC_MSG_PACKET_HEAD_SIZE + dataLen)) { + LOG_ERR("DataPacketRecv failed"); + return SOFTBUS_OK; + } + if (DataReceived(channelId, pktHead) != SOFTBUS_OK) { + LOG_ERR("Data Received failed"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + diff --git a/dsoftbus.gni b/dsoftbus.gni new file mode 100755 index 000000000..ed0c946fd --- /dev/null +++ b/dsoftbus.gni @@ -0,0 +1,14 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +dsoftbus_root_path = "//foundation/communication/dsoftbus" diff --git a/figures/dsoftbus-architecture.png b/figures/dsoftbus-architecture.png new file mode 100755 index 0000000000000000000000000000000000000000..2ecec04f1bb0a85ae2e82bae62f6022a3c8c8201 GIT binary patch literal 23536 zcmd?Rc|6qL+drOCSt^EP%`!+NLbhV27+YdOqHIZ$kZffcgR+b)W0$3wifq}EJxh&! zovc$Lj4fmvhM8gby;SedyZipUfB$^H_v7)sANT!uXgqq&%Q@G%&ULQqd0ppuPWTl= zox?1AEPM9sIjpA(Gv2djZ_=JU4BJcxfF~zv4POAi7(9%1H1-sB3(NxlVRX1?aB-NNW<0Lt4n3@Ir6x>?kOd4Hx89f1ZH`)DaH5F$JQ<@Uze+`Ol zxp=<(aL810-I_Qk)->h4V{l}EzWPIwTQTt@#lKPj&&M$9~a zgn^J^(Q36T&HVTp>U0`hi2hv%`^|r2KRDElLX%5@``pmDYT0J_hvzUF8&9?)vqrx%Pt^ z@}LDijb}q>^K%QPNqijDZB#A#viPdG;mE#?QuyKq?%0I$VwT&ym+pPmd6kKDFaM*m z@=e2v8ec11PDqdXE!EC6-6{0}wSa@iez>8daqfQFj~^WI=mixO*Em;LhE1;bH|#b1 zt^)y!P8WiP>Rc3TQw$#6GnrzHr)*zJ4`KeOCs2IXe_8=c4aA2*x5kSo%lB$G*}Ih; z+uL60q#`dpZG9biW4aY>@XX<*G-5fsv*$q9yA4_w*XcHNiOc~1a_-cX>~G)tV@dIZ zRtconlMk+IEXmuikSi}`ThW_~U-ft?gKGm}TTcE#o97JW%XQPL$Kc=AW}H?hd}OD% z>({1UZ(5qUmuS|tDJ)AjlHDvt@cnFA%}x5NqT{w_1qW{e8t4Etpnrtj+#v-Y`92og ziu$F*wZ^!vl%^B>OZqV9l9jm7!}312pP*46xrLOj9aGq%P3xUgx`iO>c$4*Sv|mbD zc|&}HShkCgw!w)YgX53YC-BRC@Y>2kxfb-D^dEYGpp|(7-VX#!J${oS{4=%U4Ye{g6k(@}Ule=a-q)BdD-6rjgp7Y;Gf@Tg##+HETED zX=P^Cm&BOWm#QO~`7iP+7JbONSZC=_7v5GDB?MiS1i zjC0msvKre{-vie49`)AogwE;n4oHlDP$Uam1?$>(uYSC$dR^sx@%MfjtT;xAqkF9B> zZ4zDKQPih(mo(N6mWab?w}P2iuPF5~Wn;29u=7w1n(j&NeIDiEk08ud;b&ztd?YTI&DRD#Tu#l^r|mF#a8x zNa?(;yWFtzdKqPT(`W+Il(%W%(x|A0zZ#;I^GXzNq<7t9%F{OG++J2`@Dozi;;f_W zmgwEM6Dz}L!$+qqnDpoLYL{PQ)DDs_0iq5isiSFIPBR3+86I5R^vIT_UVgtG<;}7+ z>p)BMjH&DJ=t>b%Gr`PX>l`_|Saqar-qvuSPrKE-aGv#YR0YIgnkHvclJr__x+(pw z?56D^-^+!sN}NewC|M`YjW;^a*Y2;$#+lsN=y;RF2PqpHSe8bL z#$Lh7{*qekFzcf^9sZ5=sK7ki=jmrN3#u0RKQe8xXRE6bYr@R3=CrIzRP8(03(m0NQ#07J#Zypmi65a>@U}J*<5}+<@=X}^C0CfjH?C}n-W6D5-4jSVf#a)szWD~ zhdw!ZD-r8*C2F#;Hg`D4e097W)~f)mI9Qd67l1Z4q9^Q!L8VYsl9kZB!uZ?VbLwnsVJF?GCaf@-K(4_iaUW?KHl^^s46XV{?pqFYa&D$f06cNWki*Z zz+RhMB&~=|NZ1Umi;k1tyz_Il9Zhog?iQB*!sBzm@V54f0}zDA&v_!jJUVWPRY>kHm%+PxiY{dK?2R zuuyYG$5!$e903{tr=5A!_u%+BD2qO?+|OxY(Fc72CNgwBrq%A(ME&=Fq6rMd{gibH zB}z#Uq$>M2koIZQc7#p3eTsGgz&QZZH_CgoMZxGN51mcS@BM`Bj&GjfjCY~@Sp$ov zqr2|_KSNSk#r?k!{x!Lf*FT@7mOqu0R{VwfP5&e6ub=mWoC24ebKU8m*&$1108Kpq zax@9-?okLz%2)%FRPMHvzbxJ=8%1(}u6JU$)35>7Ccq2w+`m$Qw6`$xXcA}aYFt&( z@vpmosj&NPa;N|A?_UCWLe=d>rxvA<*Qnt`z(=RJht2tNNolRgJ13>JZp)->4!zx- zPvu=*c(e@@qFsP_tKtPdQuL?mb_e{lwd)G-VJW{+W(U{??0zWlG5ufCCDptJfa~#y z0Sg=Yn$;-1_FZ2M^(C9Sf1ePo0S=`2PEJ>{e}CH_#L z5G&(|xNUe~V;E<1up3ld`sH-EIU@Iv;TfNW#oVct*1z@H(LxmO(Gh@<&#uH3N5)Jh zDsP~)7P+Ek#QtnALejSF)Lin9UD~=~%bakrng(5ZpuuaT zN*=w?UiTknmI$bJtRZal!Zd6}5yzqOHu3`_qqxSqosVdNus??JUtr_+FVjyovjm9y z%*ygnoi1(DmA6T9j;&5}^?GUhdg|sU;?1xqTKy??NNX-fM2iS)ZwM ze>jL?9vEvRQ5aXqqPUpdE1ZQ|DtcUn55Hr0?hQq(CeD|92EmCbO-#=kq(wK*o)ma# z3AZ-ES7l=}H9aTbv~3nByRx`+5M`(?V`fU#Y4gfr99Be)6;;YeaVri}Yx4-I$^3gNj`}j3Yc$r-(SZ7Q)2fQT} zJWdGd7hu>gYQ$3y>dz+F6&8!R6tGQZdWo^00zCwkf>K2pRJjam-&7iUyK>Jp`WJDM zg{DsJ03q#PuJ8V#SFfKogHX>Fp9E@*dB%n@y~(}sSP%fwphA!`Fc0WP^vYuB+WALudGGMCUOz`im7?WBKmIW7IN1x>0v z8qGfGBPtK-NN%*Zwt>f%GX)zxJp8_~f7Mt5<}$=Hz228W;`>>ZI!-v6#Q)@OkdXik zG1Y%M+auZfBe*oqp%)!|o%^{cgCa+OiN>iliX;Qo81lh`s36WLn(1=~aSoJCrpit! z-!fG9ISy@E>M`04mg-5nLdosTP=T53JQv<8sgbum<%MGJXuBS4#%Kt_MagjqJESSR?nXf~@fhM0i6{_UtQ#$6@#_1xUgd8#y$i9qcGJS7+;EOG*3HWfmdJFkHmE<;71&Ca?P&Ym?u@0E=k$$AtNjL_5vKlm8yb ziC3?muxl_GGD|fc(vT-gJF=_L#SSw`2ts=!NrKG!q)RH;fg;Vi{@kbSfqV3+xekry zh?5b%O>C`2tn=(a29OL2yX|vmVM=_K{5@_=cDW`dm)3glUp@Q`%m7{x?D!qe0bGH$ z{~41(Nno%?&))&M>e$aP4+6!$&nQ+41A;mXHo16G8gC1{4gyu3XX)?&PznqNTa3n$ z1b`CZ|L|820{{nwYE=ht+fNOAIXv`s!T&Fu)@SX+qW=?!ops^*zr%4q{BfkObqiks z)xs8=Is7I@19TQIDE{pJN2s_Ghq}98-d}}VKhnx1n`cf6vRjWFe5u1D%%~a#LugS< z+2b?hy=x7<{kyv90!F%@j{?!}$#QbA{oI!(`CA?d*I@Ub;7Hy8q?k-0u;`Bo1_47O z?z1)hEOK=I&DtfXl^EU9R+TpKJpIf=H`Vrxu$hXC$#Le_t@OV-eg`wZrZP1#2{J;t zTDvuTAMh03D#N);;nURy&t|A;kEhpg9Ai%*!%SiK(SP-&ij&U{%peSl67jBLRiih| zHPAv+a$M26+Ue7(dp=(GhfO{_DUA*TJQfBB=-?BeP&#ADw@0K)sy^W5`zun2+~Ur6 zXhw%IYTLnjqZ(BHznTUHx2>C9cSJBGM5@spN9`3_V#l6YOlIlGH5>1LPXpP|;|j5z z(>_kmP{T(;rdD^XPiM?>p;Rhlm3M(#>lRs=7`n> zqhC{tLjBK#Hr@}^1iBP z^_2=FE#JWg?b-xPe<@xdRXlC*XyJA6{M*~nQopS6NLQSJ6AM8)mTWGs!R0fKn%o8rmKuY!9B4w!s6UK2^xS4)(MC zJ*KJ4?8liv-m98IzBH;0b?YEPP|N&V#M;Hh*(ZcSWuFm!-G@h$iX7Uq6q|SlrDJQ0 ze-GUK1PDwOsO1m}e*zC!_rPc0LK*e0(8}vb-IA75KT{d#rk*7!$Ckpr-WRaZhu=V* z?j?|NJh*U@@py_>`hb(L4We$^sebX4kEhULuFh%hogO{#Y&9J3$})7?-VHnB-34bl zi7pkj)#LFJ75qNGm|U0jBN;*Xg#8xCzUHa83rPe`VK+3lUg5arzb8nC2L{tZW0-TGq%HY})qCLHT}!B4%TsAc6))jV>NNVfg1a+WK#WH; zo*u4YDU>vG*9(q-^1>Vy`VL>x*@F@IA|Bd%2>gSY|M_OfFY#L@; zWN`DzaiZ^T_oWgKIVH7P|824|uo52+<4#=3^)g7Ei(jU^rqkxlNlVnI59pa@WvtanE6q7g z3o+@1xb=L`9z%=hc6c4rtkdc|ebu;HAK8DJdQk}e;h74}>4Evbn|GToN;r!t;=&u^ z9@KjnmkAvrfdCywsWmb{KxhyvC?KQn&6W9M7mcyv?A9rys;e7D-iZ@jDsASrdK9ggmL#KPd8ey#XACwWxe({qq ziCxihqe}p=$!|=E_h-PajHa-Q>ib0_D{p+efr~?+CKSNsoBh@6n?@@39;5y@rTkl0 zH~Pv@U6bnPs?r{lbWOhAJZ#JRF?6&bWa>LFE(e)@YdRsZT!6d)`iCXm)_(#M1pyb` zpAN?RTSd5Xn^B`qJPwEB*o!F~%?^ey0!y+RHMpLerhC@kKqvIf4>V{))YIXM^KZ;s zS0j7F`YR$ldwc5|txm-mV}}k%I*46)|9Rg3_?$=G?}3|*$82Zbj|{7_@m=r!2VbDA zAvQUg|5W(`PjqjjVP@qLQA#6FO;U6mbs+etn`urIDP&SpZ385h;UH2o_@u;7btHQf zust9EdI`QR`cxkH?6Ns`lH#KHNwjC}VPByGBng>~jECViba^)eR6kh>M)%~ z2TP*a1iJknWXK9;Dz<(1aidF3LNl;Z)PEhfD^dC{7Z zT{C$ciqnJoCRq>aW_n_gP%goXn&vJMfEA$ZFuXQHfiqy~g^vmkUn*<0FS=Z5QY$J8 za>C6mfjG7Obxr8^Foem2gscc58?}?ko2B|)vST_3q4PR-{=tcuXowYmK`VI#8(KSZ z;zOg^pL!oMW$%|~*H@Rmb!$y39^vQHUz?<3t&YFo&FurapKzYU`#ObX2I3VFgSj;N zGOAB7P`5poAFDP$Y@*UGiZLl^>MlHp%6a(8{w9qyJqw zuZI)U+q*$Yezz`FF6?KV%|W8B4EZg#ErNEJ&^X{%1ofwLej+M+P8CP~=O?EbT|7A| z9M-|os;9g3+%KFp4EHir2R&EcYW=q;Si+os8T^=Ckx3+2tjL-9>uTHRQ9n>pe~?n< zX-AWxB&8Gi+gl8=DWjF{_pYz1ocp)%=zJhMG5wjy{hMo>_>5w1TfMIXqy3~d|A2w# z6a{*@{7>&UpW5`SYwLYu4>HxAx$eQrWv6CrwL%4AR%*}tq1 zE*>&Pzy3SGN`k|FPEkhwb(C&X>~QLT3gl|-sa|^K?x}hRWE~D}M&e{eW?R_2nUUb3 zKdPm~Jlg(}A1g%If{E_j9#r%J8LG{$da!NH2{FfoF4H2nPN-7%;6LvaFNU@&= z?bkf8nHi_&;ZL-^R9OGgu-4?K-2r(gD6;nSH5pxaArix`);MD$)C#?x_~622ap~DM zep@aEluf&)O0%qnbU=TL#0IK5mD_ee_En_s;5nkEc`t`GR*npRUYRZ3YdXFa2gh@- z@L;#(tmdq+;Q8gR#89ggxx%{-Bsi}KMUQScJ-m9 z*ialachr}=;ahOL*OY>7z_u)Xxo=~;3c3TSFEcWKI?SZRs`Sh#9Y8n$2GF_w4!j1A zmO?2I=N$QkL$&vw+^&Lu>wKb*WXh8|8|0(O3v$b-L5b!Q#KFoNAa@^a*j;#oo(TEE zg>LdJ)p*8NC`VyD*RPlCP}k3`wL`j$Ec{8bF<(pn)s#504mxzmJ~p(r@CS{ z?ZukG!zxuj-2Ck4t`EX&CEZ1zeQB zPt+OOYYfd)rD?LiB-HJ3_-C>7(i$b9TI96iIcf_UzPRe^?@3f)DcWd@K-}{#JQZvd zFlV-U5W^s3{d}Vm0HzqmW2cYx*J#|ju-sO0>sZ^CAhWsfrgA{9yF0s3@A`hfyvW6a z9;AIrT%;z6h)0I3c|vK2+$dtuIV1m8Y>oLd6Qym*WJJ7RJ(5E%J5qX^GN?3lj@p#% z-rRLd_P2#bRLLnqQba#B@XmNek7+_WkK>5RHBLkNGxEQRTmxnA zv;kWyn+VZMqI)M=oE{QQl(33cYNNGl>FYJW@!TcsgSgedE^V^)xOB@G!!X4Kt0+*5h;wV+YfasGPR*X$~){gXMb zW;S9NQ?yNcm&cWBTTBgXzVw{)gkVq@{20xtT{!*BP+(N)w2nFHsSTn!CYikJ7gtU? zU29gcD{Ya3&IvH{&XZvvd4fB(<_-S!GK&)fgyIfO%%TM^rd6r@dv@Z7@~CZAQy(_l%?z@m6f4N;A6v5 z)!^l210EkQXzPJE+9YNsn$0bkydO$b-tg#XC5~cckzOWanB_T%`JdnoST8-5hdT$( z+3edUcN~kHb|Doa)zdvYyD&D>F4Op{)&mlrqcWe(ADQpt6w1-TJlb71vR!1z?c?3a za~PS+A=n_mr?BBT*d0*XFd_O;rZ-^u>_m#0``%|}MCt@KlmFs51f}LE#;OOsSn#R5>XP-y30N!}RXT%0hi8+=b`)qOz3ecu^a=I*Rcwx4*M_LdWXW zk{E}N-J!irBDVe$b7}Ztd8UcF3P&9EGS7y8Up#pi1nthw^u^;9w)d<>3!llVewk6Q zo#d*Av}EBVMLj~cNYjtEXvxi)%z9=G)vnmIa6JE^R!664vVaioUS0nAT;*Bj83iX+ zNQS5EuQ35EBwViOt2f(a-o(m!80@&C$gFl`@c2nYp-}(1;B?IN?kE73%k7yL#cIqM z1~>1$ zgy89Zem7?XLQSI2rxu0FU5}>k!;YP)03~-mT70iEKkKLRI8t%1TdGTf3l%!aD*+jr@e{dL}_`AS+|p zsHz0=2P&woD26?Fn}kNXw(8kfhs~6^ZM|>paFyo75b)|Yy))pf58$dl%-4Bz0L}=)sl*`zT6uLD%uqu1F&rtEgB=8gc) z7}T_-nghRKd@TC0Gr ze-e;I|4Tv-#T=J&$mg>5#6+1GzUPD_nDDEV1o%7mvtyHT<|W0JxVPdJJQmTX{w^s= zrWN0|tqQi&zb{vw)jY7_zr&{H-$g)<9K_l4BZ(3LbF)#(-@La4nrv99h|NccnKSqG ze^M3Jx<*L_c>IA;^2q4sA;QY+hTmi#mOk8TuZRFHHSM584w_Y121eX%{-U z*iy-(%Tf49V)(C&Iib(LhPQiGKaBdPn;S>Fee)6#RL zN%~nVS{_P2Lu5aoc)FO1+@*WqA%Owh+zC-|(oSAQ9c`aa*9ybjCAzWTHq#yJrfbkS z!FtMa-UdOL ztSc8MWHvyjx`NiVQL#x5BC@#mF+Vmo?(S6G&R=mJmi=82OfdM{aQrRbG7~tTeV7gp z%(n$GJC8AIGO{-}W6$(Pk;J5ZO5`?b_JHC`JrIGu>F= z;{=7W)eRhE(6S;ba0i2YOj`K5-w~8h#kpWv|10n{@AV<={)5;dc+3pmV=_X!2ntbO z5a_)FN>p^7+ZJ4aCYO2*-TDX9n45TNP=eWO#e#4Cro2_%qkX7kT=az0E__q^o_>j} zW*dzcufC~Qo5!}CKEU=-Bc*m5WCeOa8S9`Mi)d~Gbrr536l&+915WILH1W-v0EK`#oDU)_K6AG*(*c-r+W>fEbhd6uQU!dGn=_iQA8IB3%d zPV>ZpSWv-I!ZVaT8`zq-7>T0ZI`|>%so5-D!O6B+b6i!{4+1K^)M6+Lr(hO~ z%E>gir#2~AUEHZ)4Xy(XF@O>|`<(Qu$W^|6OE2j~FUuGHswIC37H91c7qD=Tcx&2X z+IU%MuKi>UYv2|C_?h888Ag#;;e2J|uv(c zu6%v?k4j*P{ixm9{H;SU6R!tTU-i@gA|Z68xU zSdnByckfLsPWQYf#|Ux@mavjlmOv3$_(@_`OA$Bj9L~1Hgg89rJ7{H|WvzIKBmfXV z@*Ly&l)@rYZtMU;(A9@__*$VZb$`|9m2BH^?#wMo!?&EtZXqvto*#))nvvO~vC)+a zqPj=1-xNI|t+B^8@XX#|Fa+U_rFE_ZF@2efFTOEaBM+|)bVB3_5gF@K9Wb>?`d>lX z0+2Ser>eTR09NMvxs`oGIZ3J<(bTTHbDt;lGzGjaS+y!t2WTA4ijZ8Lp`5{trO+{C@P;HPJle((+MzraH+k<_`ommjG# z5vcNX4=xOD_~xEf;YzN(h%P(du+G^gWn54VyFSQrg@KWADswnJdceJ^86ffp`d-mS z+&zesRIn8#>hKTH$PWuLhrd0#aGb+t^@Y`4AzV;Nb>OR7ni8h zL~#ngeQ3I&`Lu;qn5*ZZ^`44TCoVi^1YqK^Bzie|Vqg|_jiIPHYxzl_|EQCxiy5u$i8P_A3M=#9-j z@}w%eSGsvLqCC)dc(rs*FtRT2^iP-ScEeWnX-9<)arGP=_GXe<=_h#*y@a zsEeQ<`=Sg#p{1UC%MCo*c#s4>4*B3^gQzNk?p zOXpLvB4c^L(FkA4&~Es2i+Gzj8W%Mbfz%7YEOh8$59*8`vztFQacR=%SB-399M~T! z&wDnMVIrQm;q9_V}fhj@ML_a?M&6IzyQMc@3zV(>;41Hw@c(qAymsjDeCpzLBy z9~?Vo=d|D^PHO$NtF;n?lP4B_b68F1@O2*adSV|RJof}8>|zM|;^~z7sn2~xOK4+2 zLL$*L=K@BV-*55#o{KNot@|c4KOZZ4x*Md;{hWK2O7)g@^gm@Wou`G>p})^ymML21 zy+vyh8wpQr7MxH*6Jf~5s1_+=@93H=wF#~E#)cMfRfa4P>G{E{cd&{fvuG-o&1a3I ztEn>fMAj~~lu)`L0Kl$6K{GJA^S4Xy2=K>tDG*~0Cmk+kRYg%U^98v->t-wU)MPb> zZOYJ$58~oafJ4qEPIAem%`A}xnWtr}UE6j+k`ub1)P{EFNG)`qi`Cb3??sTqfa}#0 z8?~-+kclHAz#$)hytkg}%KQ{qV@1EpOE8#ENpVq!8XsCLr4&?b-E901!q_OE58lHs z0||VgsRqlpe^R9JLP1>VMfTDw*~gg}G53IQ=k;Wa(95{^o>=c%@!i#zuU_7ZOs17L zd`{u`9+?qYuy+1&A#H7CkBPsgH?10(E9?>?r~hT3Xd3zo|3omUeD)T|oiD|&_evPB z-}CQcut`dPc`%=)JoJOznn}&j7AzkhdYJY)iUv?UCy)0ipVMm$h-Ru;+aljSOY{=s zxc~9DHV8}|QiA8boTF&|Qt6vat(OkNtz?bp_aLI$t1m*mR?KJZBT3aq>w*EuSk{u* z3T$8P?!C4&Fn2f;O*6Z``~bJ>2F#kO>;=iCy1TPn=MC=;o)U}QObspWVZJicyE>C7 z?xi8t+2(rsx0Pr;K+{ft(qYR;!q~%^VIyS~33YCSSS2>xt&)acUe;1hY zl0+~Ap34b+Di+v^*xh^n?e7vFLZkB1j;EbQ1`4IgVTTEv5G4=NEzPDdKO%@n_2Sb# zBCbSWgG2k4uv~1H#e}jcsu4GL^SBZsa*wBHhsRtzwWlz3z3P<4z{2{ z_a;zcM^C2v%^A^sz3U=x|2Qz$q;lDN>)E~mS+af=WuxZaXZ?Vh220(~CyVsQ^??Se zn<_bcuKq&xDh0(qgc-qm{Zi|`ybYSZD(mgJ;Nzsi zy}TYb7sG~alaN^U`mq6& zf@F6+;x)h{f_{5MPn@yL6DAEFVJ7XBidz662)BqnJ;Vfp`7scgFAmhJ?O7Pof`SX5 zZpQ|uv&U+au5!2hgR$@j%KQ%vmN4%wca`$VV|E>G|6z;hUx`i9#HHWaJivYVBSqUC z*>0`iC+FbL6yyIdHx)4ZgBtM%?E1eLfD%^{IAi5)@Z|X$os)9Awu=Fm2xe5RbNrSH zNVLTx+hba8pM_X=oD2Y6Z@ybt8w~7%0r|Mr{ieGsal2o^CO`kC55Zs$!+)`kV6fZC z|I;6K9s_uxVDQGxaINpHIq0Qjm=TNe02mepbsr(aV^7Cf! z)OR5%E`VhEh2<{}>d1@ZUqf;3YuJVefP^{B5;CQ_>ubT_M>@7XM}A2)0vteS0LXV> zu=}H$gff)8CfolKa>6iHW8(V9~9 zAnq&boj533uj&Izu7+QvySuZdf4dfIH4(Vk7^}P;uJ0!XS(C3UT+radIq_k_&J4W@ zjc5f98tk%%V-JUaexs4~_(AU86Wb^;9Q*a9y3NIR-Y|gb&hAAKK~>`4cp~BiZ5zE{ z4#6C_gk_XYuh~UigaKLzLa|Qch9n1z*JY0PCm~*7$4EaU(cX*9aP>CqgRS`T?Ye{q zIQDo;&BnW=Ih_2|YdCCD>92k-t_d4cez>6og1OdAbb?LDTGCOZi(8(cMt?3(rX0Zo zOy_YR>Rvdy(X;oX{LdsUi~eLNP$=bt^zB z{5_^C>3cz@T9>y#9*RPZ#@xC=YI)DVblqoO3EkiP>Lb zs)#2pQ?aJzd-ukg;3f}~v-f29PI-dZ6Eelw3T;kFi*8q~n^x`;1b?m|etEOuV99{S z-dgLB8Rc+PL6r{!p-j-@g*4{%biBL=)@(R|07p1kSo(5B@9A$hF1KwYcRx^4Aq z;kAb5i%Vz2M!!D_8a9(7_X-UQf12}WG}GlxP*;}ap_-B|TYWHsj8`q;WL^3Ll2ewY zN^}Bh;;Xann@~3%vd4P;B?(6?Zsug2!W5c9Oo)m<8_d3faEE)74R|0R7myQzBig*P z%@Uyb?nJU7DOW$LC>Kq}Zys@6d0B{pEsB!n-Yhd+fq=?Eq3Xw{G`W%*C-mtn6By5a zWtVvQ_yfxlk!KYxVL*}h_o`~_vkY=?6A}r2rl~gmL`CB$nX?}C5yMson7%hDPvea6 zSe_8LC|OQImbm=J_IR+hwf`>1{>noHm`{{FUIr(Js~k*TUbL9ME2t~D^79M zkwn47N8fyAW(z95`QA@1J?u}~WsdKwLthe7E;_E`#~%PN&%b#*pBwH(q^A~vEq_B35VZfD1)d=igIe4q$i5@24P{qKhMsM(LM)4JRSgHh7(@-HfR$K@r-^KB&c2 zH~DOk@8e>=BpHcl)aF|B}io5Vg4F3Nq||FLMDlc0WjYHf@6)PTf- zyce5C3!@t)Ye{E;!DC)gvDrEgK4&bFzCK=E-luPun>A0Ku0|WgI{j;8A84V1B_ab| zi3W0M94qWWn&w-&4R>0y^!b#mmCh@b@Ex&q$S9cNNZy(|@cfLhOS{z#Wn#`jw*(zu zA~9{vBojfBaKS{af$S3EixZ6IIfZa-5oZeZ@Ddw}k+c(5!m_>BKq=K)x|vq@tQ<2i zG7GUvQGrB08=PK;f3F92P1Km1G|lII0B2l(&hTXX7C-^HDq=uqPOFAr&xKx&V#W!( zaMa)UrbvD&Li-2skvBpciqd$F@k>6#CU=5a*2)1*x_-CMTDTX$FzYuGSZpM8 z6}1GJgsXzeGTip|S3z7c&=vajkX$TDQ+8>{mn^4L0pa!VN?$9kvXh)W`JVPVTD`W_ z@-I=9jwuNgp8q0U1#tGpp19U8@jqyPV;fWAKB~o+=A+c>y#3|EyA-%w#r*_56@Hhn zWvPDce$GPFXt(%ylft#P+SX*j$|74(90*i;n7SN^XhzHHEPR`#dRW2hh3(^PT(j3E z`d1}Rllhy%CPy3mXt{M=^rI%Tv}d}b+5S~^S=Q?HlD_`NGFTJawXXEH37%Gy(e3P2 z2Y%t5H?dvL_w3r5d1VzC|Pcks5w6j$Qz{DKmqPx;cO5TdDRe$$! z8F@jAZq-)bZ%}#?MS>{ugdbfF@eLNLDB<`>CRcp=D_M(7o>A~5%9oEx1 zHIx3~w9brDla=K-O1@jItd9Tt+m~aK9uSlJ-^gb}G9J#^dbITJrn_K|U$G2WlUrFz zNzQ6sqV^v4nxg4_97?i8(23wC*V4DvqS6x)A0|st@)OA>e7Jko`f~>;k6xa8T>6|3 zu6|Nf<1lz``YD63)y4wk!|H2)@5S`*ahUQ5-6BW#A=Z9Qxu-$|#T_FbUT&+LZrkW* z*G};HEpLD>90chGlN}bkcoLJ{J~~<)#x{t%CDGiY@ORVK)@o%p>AiBX z4zHuCW@w6J7LWOO_xa%;wrd^fZ_l>R8(02eW%apH;{0$W{joY$mPTfNUN`2nA@eT@ zD+Q15BtYt%(_>6j5G(rLWSbimOr^A%2YLXZ@*pZh&`|wd+ss;Vg-?68$KDOAez(yE zcFC2g>zsxbSCrg9+A+uliD>2`D!P3iX@SmE`tf9q{M>sr%^`0op=L(p8uJDqr88TJXVdT2+b|vd+Q>Q?r!@`i>jNj^06$JOaFPDvy{vD}xIc}11##lg zD8;}fU-hGApolY2_kSN?IQC*tZks-N*KtJHXChurmyMo~8;<}9W$rIzjzDR`t{kAg zJ_M;hW0kPg^$#zzM+?8fn>1}Z&2vo;O4!_K<%i-ZV$vHPEynPTf7dG;lG(1I zBb3$orgJoi6+r~dK?DD!E8d`L^PO9BcBq3W{JL#awb6+c=XFZ4Ui^&yEBTltccXJ_!P|sdS_iA0;PprG(=J0b3s~pN+0SnK@APXH1OYil4u3@dwXDT2ub-IugG@{v|+nn$9`=c`Q-2cy# zw&I`1*jf8AUF2EPYxNvnnbbuq(`lfmD2tNl~<`hRk9190HaeNA?3H?wsP`FSbA zZjKF{GX%H?uVwx9fOCMifx8#}-)FSNX)GP}E9g4PngkL!N3lH?KwgFK3~p@y=v$&; z@Rx#=Ub<{k&eyN45s=dn4NAj%HyzKf_s&4c9`&>}iGZ!z?47YN1ppX%A(o@kh!tQDVws9 z90S)Nx@SQ7;_4`+YiE9zbEiR;Z64gWHM2vPh5C;ZD&{2~An$h!dVsnITlBwP0pQd7 z@ZwGwRefj9VkdywXX8x+gtUO$PzrW7W(mkmJ(f~tm(_g%n-OrE4SySmB26@43VY=1 z+Of~@uO3Sfbk1bv_7K5Z=5wo*q$cY`^L2~R%gY9)$tU>#7jd~k?d5{^fbzYsWp2p(_#{9hpIh`d z&H&5H*~^x?xs98_984N5DVhN$=sezK!*6GxqR!}RVK}{%4LOb7S@(c$`Hk*W*+L82 zgeV_vyk#OdD~+sfr`GRu)RTuF*6+w}Zxy=`nyFRl7TsDZc0#fvKn-T5cpyal35)g< zL+cX@K<|ogvFiDF4N$2g_GHVWOIzm6swA_4y+`Bmk`P|ZRy?576p5fdbq*D?IH-X5r zxy9o=0KaK7a&XgIRsW}|z7`a3?J_=Q=j+G$q3qkc_kh4%fr~-rcvOo?77GTa)nG zqI$xQiSAh1R_vEN?9HyaTR)|BOfFH0!~QQkTQ?x4YqPZ;-RVV2khAbRB=sbarU=I<;=gDywW(%v<2m$WrPkK*>Y5%Vv#7a4-Fnr_L37o2nqzM z6+yyc%m9WYR?6aGQ<2aD5=($c5kf(>APK|1r$G=2C;|;(Nk9nMNir{lIpefH%`fv0 z-1m9E&wcLmx%a;B_phBr&Sbl`QjGU@=3Cdsp6roXX*AfeT_!cQssRzm7KTN(L;i_KtxIJOm?o=k) zWRirNW$?YJ@TM-^EZaA%r{Q4YH_5q+R4Z?kUO*?=%9C{a2*Hxj!Zg5AQaR z+n51XS~FQRFQsqg8gBs0dll>324bh-1%p*V*a7`pLXAQbkVJPLJb zi_k*U1a_bJ6$Ncx{Sw|txiROs7O*tr*=iPRLtHLlrVi~ui{E9Umc9^}TZ#hEp;t}1 zV6tSWWwhIF*-dpl>Mgf|Tl$8aZ%8)#oK9^W3G>cl{-8qq1ZC}9HfPIo`M zP4y%9dOj(*Xs!kC*huUwpVaRe^SowCq5g=b&-O?8g`h&LEhv$>ID@831J?-{yL&}; zIjlS^|Df$l&N->S8rtY#*)1wmY9k6wiky}upQ7A!^d~Zo$*nIwA){Ci6eeullktz^ zkSg)quO?ks^5TKk+i%pMerkm&CqKYwXMWKa4Yo4|Ka7Wl{kL>Fa2vR%d-fqMT`h0D zIup_Ow|AnuhZZy}+T$X;h6SY!OZ(}aNDr%wH-8b#x_v4P+3$l*n>z{W`$RMduCNjp z;Kzfd;st745D8K?w03!~vTUqwP*`IqR(;+ROv5FYe->kH4cbpgOVc6RPlX303+L1! zq}2IJ$3ls-`r;v%I*c)5_@k_fx*nay}?-Npm@ zX45gB?^kyb>rCRb@9K4%!n)?G0%AF*0Jnx~QjR0ulF95pMnxU?@l^(@uS-vr&fLEB ztcPk`zFG`^WQ7i+eHbq-E@nJ|{W+Sni#fej@qx3teyIq!dv*|eyu2{?Y)Vk1zx>gG zk&sqS{eB^MoUa&F1+y5aoJf7Tbgt?9$a48+)OOCysG7k^hz>Qi!rG7z zW9DYFYo(g6xi!o;#!Q(;D`htv-%&D)62RZ8bhIt3qZ}5CoM?oPN^?E^JG~<2g8KcE z#v7Ni=r2N!6sgC>Y<`xSRnnNih*Yhz7KTjE^V>p732b5QYg&hK8wIkG$(rg&-O(Jz z_CWxOV{A^7RA4r%f- z-x1A41w^)iRQ;wI6RBxwivG2FJN?V|P;u6Vn4!q#FqnP%$L+);XuEE2y-`OkkEm3j^u45B2g0&!`Ravt9-|bcn^L} z%i_nOF=!$O1AbKLiYY^nojyX)tVt0iPI6Xt@>u&$m6N^L^;H&$E5`D|jK8II}KN_7XwOJeGq? zOVlvHP29!GJyC0|ER`%qDljhgtw=trJE!K6289f8aDt>V+y+tB4}?6Jr0fNNrUyrL zxgwH)@SLKuVQHh1ub&}!7>#=$k58fPFhOtKZv%t>5z1U?_sO>vb$o#L@a=Qj_fYpr2jXhsEz^g!m u_eKc$_pU3N0vMtE$@}ha+?5sOr_qk&FiAyg*w-Wd;bC@?4q*( literal 0 HcmV?d00001 diff --git a/figures/dsoftbus-architecture_zh.png b/figures/dsoftbus-architecture_zh.png new file mode 100755 index 0000000000000000000000000000000000000000..3e880b059e8d8ef09d105c87378f4525b5426ab2 GIT binary patch literal 21386 zcmdqJcT`i|_BNVOrD%{2B1EMMf(g>31rPxNL69O{s!A7>8mdT@-aAqhL5lQ_N(s_M zq=X{9Nbe8=cPIFs_nhzi-h1yD_q$`0*+p{NesuVp=$ykAH-$;JY&5& zy^`?VP+xIMUz_qxQ|-+*$|=h}c5%5_qF3~fDQj5+*@#$@B1I_#ytby{Uzlj+APX;zN3W9!!VUJPkr_vDTdGLb_TP zA0BUwWP+ehpQhzaZwtfXa!w7RiOe_dDS0)tH3IL|Ke!3!f}n(`5^5(6NEe3^f+Vu$ zt}FLa>Vm2B2iI-<$KS7NYm|IXFe9JGeH_ljFby96NIGxo%snWPq5+Boo9jl2<&(}w zvqR-%Dv0CS&FXJ5WNWsj^pX&Rl49s#)B~{KeD?7Lpn<=_y{+Fudlvk612wwKc!)tv zh}U#UG43Y(N(6A9E}<`SN(&PI{&8uvUtA-L=1ttkPF>YhkVQL5pm(|a`H@%xA4=%g zkS-<3n+fb-Ch`wA-b=8~1k^C5U7zq2<_4is%Y&j4!6;k8^bgK2>Qf>m>SZELj(6d7o~>n zz%hk-QT-0Iq|&6bw>E;~Qu;T)9+B?We?sC`p;_xvs}#+!U}o=vzLCa~ziNKJ`cpOI zZwRuxnJVHseHty9zc8%cmtrS^Sy-G}9n>);8I?8MIk? z$PTUl;*rf^NLQxg;z2zFVNne`87g-AG9AN9c+~fIij)NKR^#~O(EhB4+cx*W2uotr zuwRxhq6j{$%t64sQaRHOcBQ9tYU*ALc}>LRLAlSG>}dQtC%g7$j7_H!HEXWBK?|<98 zfPP}8m^*n{=602XzJaf@O`7;JUllw42DGnS#J%FHvQMpKX;alzQyod?OA}TxLjx~N z-=t+wz$FzQZEQ!-xY=TUuCx7kowN8`5EwH_L&8j^jgQ@z%E501M`9nkntb8lXM;`*cCoTG{YVOLhbaG<|Ja8bB=zqb33iDg6Mrznm&p) z)_7j){aSgc&gRE%Hd$fyPV%?CJev5Q?9N3<{Q*n@IgP@eHO_7YxZayThc#$PCAxGt z7ED2BWy*$0is5?g^kOS!JYIqShH8}TR0bGsO{mL7<8;_wNPSR1ZM1oTJtH@mU2n|R z?-Ozf1pQe=!hc@0Q`?+!k+STI18fapMK0y1B<8uqN2IeQxfa7j{=ikDErSqlrW*gu zrGJ$jR4T6AC$x=!~6KNm;87B-J_wR zz^g?uyj1AO0mz%6cv`O+$GGD=hIaZp;U5mI6M=&y{zLo zW*g}Ad{RfLMQxt5l+keaI$f~K=JN{GZ#c(MIw85`7$hKWm!)u7JgY;FVLO{8YipDi z^=kB6G)2UZPmN~4Okg?ct_q-}P!fBcM0ska5KPJP6gym!W}DobT}BK;+^fu~3MQMr zD?`Xj|79hcIO~YIwVrc9@*PgEX>aZ!`2sl!gipRiJQEU>05A3w*rPKHRL3)oeK
VZ8C0mVEsj;Oz?=%^mMFJ9X^_ zSmN~ew@_=~llTEbCzzh7H0^*S00O|~_m_QfgR93n(OZn_t-t%%=T6_R-qm=N@vtXv z1P>-qBNE2w!>+$(@E;Cc#Wvv72AdYzZ>pHJ5e|ZL-7vMHaP6@|_NOUF`*gXhZeB^A z+i5lkqwj&VIz#>gN<8R!6#LY=A>(iLQ3_>LvOsExrC8z?_xYODwx{iaAVYS*wj6An z&>Y01{nxBP@Cv$YsyIjo7mtSIHhtRCcj z-1P!Z(BIQ$kK0w6vq|p8L8OS(?(K@S-v4RVgs30d2faTh|42)5dwH-xJGjI9Rx{zk zmQToPzIV$>Op$jw)|!taa(Kajj4?9*sf2W8afYz% zz^hYfx9$E8$91DuRRfr&gD)d5gMK%|(i?4?*j?`I)E0UJs5kH2wF_i3pTNzI{o=D= zL>{NHbL2(8$bA8!UlQKZsSzYe&{v-QQaU$hy?<6*BzbGK`WqsLz9O(WadL!PCiH6| zIbJS%0#b+M$3!SkR&RRJq)Kc~mV9$ZVAX0&-cycq=do*}d!O64zn36YlYb8C;FlQX zy5X|`44Ee@{F;soB2|4*JXe_^;c&RsUA9U7X6GA5VAN$xs29?~0gU4mw3#|9vmrrA;$egzSO9*$z)`2-0iba~Fa|U{W#a+I&?iMX+(i&^h ziP5F)(Iyc~x29*`OV%0zluro={};HI&__iz;3HuYsw(~%qkju^r}9M>ab!O6C@v0XpEznDq%>^_ykL_VK3qzM(p6aK!k5xYVURRHww0szmKdA%+1fQcTaGi?q2M)sw zTaCWg)BFKw^{0W$WsX;PCfbvC3X6+@70O-Q4q@zg-*_k9qYIRjEOC<XONtH|40C8NJHDFrE*SjQPulySBbFQ|E#{l zoAG(Ct$h%q0PP+Vpb{0KkUAQ>gk|u*Jl6RSmEE-DiZT; zX!$_u+-)RtRRLxioU$57lw)M&CV}Qch5?76atJNFS_xyyP?(fPzawM?P)~a8a{x@C2VHr{bfkPOy|UiM;?{9{&0*G=Mwm z7QO82va17fJ}zr|m>si47?HX2p1M-`zH@OEqsW9Dn?y+gDRBBYQ$9Oixq#?!jus() zSq`82$VW+RMDMX{P{`^WAXK@!z3&uxMcar7RgK;EF^SEb55Gcg@I?Mj#r}yc=E#4z zNcuJS-LFHkani`8a>KW|Jz;L-~kh!eUoTP|-W_!9j2refzx>a~3X#`>TKw{2< zPQQ>ijIsdwVU-GTZleUVA2HR-`M9%)>J5354~NG<@r`5bCUuYT<@O;&T9b|V4=!)E zV#rqxPW#r}ftSyi#E^Cs^F za+4nm9ss`6gV7*rGd-Z0J*ED>d1Rh>LN^yy_9UMd_J?%2wzk?^6?XPj{`?`E_$tfJ zW~ZhX(f48U=n=tP8DmN$zfcq*d@kZa{zR5>!u|!QU^6P-%15QdBtS?0VP+uWZlehQ z@D=WmDtoVD`Jx=>&$&9Hrc_r6N=WIQcsdCJz*$vCB2PGVgmYMxDH;utWQZWuaH*if z;=z|+JzX}$uwo|*k) zE=IB_Al;{t5Hc2LaDM zq2xo}KQX(AQlU4j(=!XV(7sBW7#1PPe_W}k9J!<|ax@rSWJpHcBNh=MNC2*b&l%>y zZ~hqn!G|6?a>hm)8|tWEtK9BwC%*OK{z;AQuhNC?5Wu;3YUGjvqaL?INC8%byoF`WQyiTqn?kx z3@w&UcreMg5{#5XKRjank429(m~{JhnfG7b?fs(Ss%2%Uf2BEpM-pMVJ5(%?@=TN& z2fkLaK~O=0fO`~T3sI}2)Yh+Mw9WUFV#`AaxYdh*Bp8sWOhp0iw5B6IJ?pHw)7z`s z+xG~Ny=Bzz5qGh|twW7ivy*HvEB6>-(`KFY_`6TWj|u?81?0~`fF}5l@eZr2 zWdp?8Oz4`a2lz@Km5O;Q26`5byqP(tIU!1wnrKK9j_y;Rcgk?7zK3 zT1MlaZQ-B!Pzu6;Zh?>9|HOTy`Oz(jCr(<^G>q{Y@O*FY%s>9uaN{XkPcxF(@l)`` zO#xV=3MJ$}=51toZ>~3%@mkwCU(O(amVL+0weX-}kzoG^>kTErSh61IRp{aKeAAWF0hWn>N1Ery*xgT0TXdlT4( z5!^O>rRIjdJ{xP$9hZLoAY|VmNOaUjNspHa(?4v3k)?P-(rTvQ?HRCy`X`)9lSDq| z{Qp-^1{w<(bY4S^$IW!lYHR!Cl)bgb<8B{>lhK&f#`yN8rnD#9Sq*g;v1=65NDuU_ z)m3ctNrCXyg%3xLPD4^Vt4FIzGdr~-s}D2ku;rYp1HxqPM$eDM;-xF=ji$)}iH)Rh z*iO%0yiw(fpqrSlY+$g(gG8cpcj}a*XR<*_fq@?9dFd%rvAZwrnsygrHfXrjeYd?m zQv~?z?OPDvPLs=W~t03?%ZNck8Yv; z7!WoBRSafbZXuZ$^3ob(Y%gTu5f{ZGw0NlmGpFdh*oaeRVAq=E=unl(!L~&3WXv zW~j~7AV6Nnzq7e&zrFyKE37{k=_qMF8bmla27ATHirQ(fX$ti$>+~5|)QI`sV%+d~ zy$;jBCQ#l}Bm|gpa}hc)ZwN%my3P174X|J@tioX8! zbw`|%*0NOwtl}N~PT+f1<(CrE`im!gUIRt%tZd}-NIy2`vW@Eus4;x0uUr*-qix=G z*h$CGlvc_gRk;dtWoOe~#H)@2FXfn%-y=rOA2qMfke3^x&C~2U$rS=}cM}+|5Q!!mm$uz@_BzJ1Az=#^Y%Rw_3p-Ko-n}DR@RUO04Z@Xvx+$=s`LzTY z_VQQc{dUmoELo%L%ppE&F;0&<2wBP4nQzzkva#tSdyW)9*f^%LQBz;VG$-m;!!vq| z!Hbu^$L_x_y&L+e0vD-W4Pgv^yK<)#bAWm)O`zO_im1>dg43v*ddcX3L&f5246>We zJXfIVi4;rC%Ls{OMSI{G)h-`#qDb$j@8Oo)dEKsL%XX z*L#QPLjI(}m2Y>ApI|o~$h}-`rlHq9vpbX(HrNan7ZPb3@8FQrf$rXObyCKcyV-$^ zXe$ajLTHCQ9+wEZxdJ>%*yke2djd}-(0ic<${LH8$(#QX*U-m`m6&F)%A zT;x62!?N;!X?4F1PWH16^?ss%o+$L>eRe<=U~G)AS2~+BR7!Z^WqpGcbb1%b(y9ib z@xXob@NH!OW;{*>p!^WeZDfX9{(g5?o;UaKQu~U zQaPd|S?#+30D&@BoHGG2S(=_XA@z^A8RqG2r&|brcDpIqhMPhTkYD&88^QgRGCpTs z9-RWbGW|bzpoy|BPEm+u8?Jv}=YMEqWO;K*kg;4&96&ieKzTNy&*M@qhUwkaVN@5s($bfua8bRlV?(UlNH-fKT)x z{r*o-DCu)fuSws9RlsqJhLVDk2oUoHlgE$$&KBY-&tf6OVt&W2H-xToSmK)8W!f27 zh{q=r@vjlDS!BHGd57ar;XnI+#eiOA?! zaMDqTKy$2pmxd`$fZV3ybg*ds##!xxcpfFD$j>4bN0JInn)sKv(I6|czPRo{a510E zpTd8CRjNlrhV9W&)D(UhDDW2-AQ}#hQS+`h$cX2GouwV2{-iIr5cf1l%$Io^L7I&) zR0HUa5H$<((?cubU+~lg zAzjf@Ptz-kr5{F)O*Gl0yt79Oh|snQOiEBxW=(o;w$AD<*_!I*H?~Tl`zG~b=5mkH zaH}RaO-oGblGmT+1vY^RVJRYK2P+%j9}ms5H3tuw43w+VoSe>fx1V_KG)AqOV#M2* zqvOD@)?76+r+vB@R=0`Uy-p@nM?0W`xt*a2n~f4kbfY#i28rC17cZEMrDu0v{fZM* zHSDnyIASPE883Mi3|&A+e6+&b`-? z>0)=!y>v!jKvgSQ5t-kg4743U+=H&@Nz=)hMiD(~s4)O>aCDA!wom!}um^Y?aM z68;*tmBYG7(X1+CrI94&h4-ylaRUQIlg;6gO4YOdp)pToYP$aRa(y9jk_eknSYlkj zg_lP4HW}vZEK-v2p#NTE!RjwGv};~Hu8 znAG8deGl@jVb;`0^wXkkC8cjZU84NY-;l1x7Tcc5H3~XIYgY<~>68a5Um=m*`Q2>6 zLm}`y_p`w4?WHATN~PP;C*;XPx)+XatxXcM%?YZEmRfiAtgk06OA&#x*7d90XUZ7@ z#LDX7>CCtJfFuFx1IMZGis1E+B8PRh z^U|luqiSa>rZzun#%xp~`R#rQL1&8C6K$_0#MdHUz@Hs|87o)&k^Alfiz!)wand=^ z-AT1LT|#K~ei~Yhea_?yb}ZS$c;%i7so>rx&B?$u?2=aE)bqIU-e)r_L*pwHC>!4E zxHCDDSF^jjA=-0(S#SoU&L7n-f(bWOZC}|)3fbNe{&XW9Vn#iLvn_y8HiH)JH(NI)5VRjSkm>TPzhg3m1!n*oH#Y+f68iCDnN;HveqgE8s55Qm;QZpVC{zEkzOp<^T5S)P{X?@%_KllPFA zUpPV1=sZ4!{1WUD_-dtur7d;s#=L96C9`QM;MsTHhPYovE#_R)Hh%cFM5(*zc6C6# zKD@F3x_82eeA)r>buudSabTTswQmCs%uV-YP4*k?V zQx*-s3F+#qL+Qj&(FECA*&7s?NSlZH&*C|>ZCChIz0=TL&8e@3F1M>X8)np+jr1O2 zk8*}=_or7Ed8Zoeu$6nSO$jAxZ$M0cNMT`l)Y(tUq_bkt1)7++DX|MV#fy1`7EN?mGO`n^jOIv3&G4g8-%??B#B~uH|`E{+A8(XJW zHk~v$_Z|Fn5`vBYY*RaVesa)V?D@_%HZqH-d{$D(frBZ3vGGasxf@gDic93>sPj#stpz{am-bIqiw4J2Cfoo?%E-NmwB@Xb4%}DKz-p%~FQ~)~v&VCx(*dQgQ zR@}DJQDyw}6WM4W2gB$QHg$H@a5QB1cgUog(zmQsnQ%tWWmm5reP-QSw!!k=%MgWW zc{NVHdUSiRD?K)-b>o9q=w6X+Q*0s+y?Nt4c2B=JgVP_i?t(d)j>)r4uYc<84UXjV zjqelo=}MOw0tfKtT(2o4X4=)VUZ0?kdoug&&EdR;3tJfX2D1Z;$!2IBso*uyBt_3` zTh+JW9G_dEG`iiJG>;2!U>jApWJ$}KROf?4TA$(lpe; zW`EO~*+ciqUNCEy!nS6S(`|2Y9+;B^>U~_oIa;;G)3;b{qWgR;iG!)@RZT@E^M~u@ zSI%{8vO>!gu9TK>HQiL8X=P-l40>ODUu_&D&i-26cOAXhHB6{Zs*APGmB~1;Ntuy) z6O%LkQvxsl!A1I)t+(jsTcZWq#_VEk@$PQ4Zk6Ec@(36AF7* z%_ie}ZfF{bv=3q2UT@+R8OrG6NLEggJ$TSjg1YRo4=xm}tml_m>u@Z$5MTe(AYp7DSKWSWe4T0Gfs zvt+vc{yFtj#>;Mcvi0tER}@>xpfTbTnx=UVBl{85b?mf6Nf)%Q`eZ{jZ(g&JecN0x z#(cEf<*b}8qcT~!jw^R=d=!+R+QEa4JtC&T$_D3Au+pMe)yaC{h^(p3J>nmW%7ulf z+1JUy?3m5F=2(Bn#YG5~WRDt^-z%dw;Ac# zs%(|CSmStH`liSBBsX_6L}i`BZf`u5Leq5qNo46w6V`5##4jQz_mT9~5`*J301RSE zAuLeScoH1XD~Us3Ol<6x4dH%atjhK;I7J(Mx;UInfOQeV2PXNx?|)V?AlIw-B-kHL zq5T-KRrOe&lkpfG-OE83Xa>{vI75DJSkd$Fd0qFE{;D_|X#(g#@qFSSQ$rJ0cyd;R zz&1sq&6Jo^&2CAX}yOsOP@4$7->j zo-pnvdzf>_2huB3&p4Y(Xy7eqta!SD`;uNba5CEc!-%4Yn`+TmBNhI0WWF7v`+wlC z3vCo&+aUi+U zpBBZo2Ih{v?m0dHiz4c&79XQc^3dCpy8(-(3*Rv?sc;D@{)zJMDsR)BkPNUN{- zMSa}RP#Y<(UE$?hmEH!n&bQ>sl5ueXY={6bc`vz@YT7Ngb90kv_>iPj8_g%UhySC*ES~?ASk@uLIWE8k#$z?-_*5`e@(|^ zIpf2K%WMM!;nvN=d*iRpKgj*x>%6X;7jBH5ha7GbaUIZ{f5zhU(cxFH({a9^K{|eY zB#}zs*j$Va2~+eBvFKRlb_1wC*T$#c);AD zah~B^8$>_@(&&&QTuFZZ5$5RY?$gL<1st`Z=>tYg?UN!I;!)wO6N0lhk)19|#Y?@t zXD+z*c%u}FEq|I(f9PsrclZ{WPC&43T-iNPwVDu4`cPjLbBwi+JY16>5bo~WOB+aV zWoz`@=Ie7QYk2m1cr$1p9np^umy!r$x}Q5?ECn`S+ymWnjq3e<-C%*aJ$2&ST(GCt z%}5xn^|m|r_vH$Gi5I?}o2`*tKc4yOtf=;D1-N|nwx3LO-?v2`3^!^9Aa8Wh62UX1 ziox7$tm8-*LZ;jyy*F0Pd}ncnqPif-?-(L9v5+zuf=pn`t?>)7Im;5-ARRSFdY*;) zo|LyulV^5FR9dOG&18dv)!qfvqB5&0X0{c*msY(}TCGkZ^EgyN^|KL?`UUg+PT|Wx z#MT8srFNKAUKVt?bn_Fm*Y}yLpdSNnn+G|wFV7235A)atABA$m6aK= z&t_I#ZE1qYf{C0pOaFauPSA@E*H>+@)v+*vO8>M?%|G$wHA}*$zNxG})JC)0d;z=z zZnpiiqx-5#-@cRX9ln$<|ufe7Z~ zcFVzw0`oV-Ot6>QO|3IDgEsDA&Xd<7EiffJFuXJYWur8bzNtyjM}Pg)(PJw4zJ%AL zTSJ6VjYR1Pq$i})p~!Mx3i-&SwmG>nz7VvN;0>pf7%I!_+iwplyfCLHw2;N+W@KyY7N0A{}O%D=^** zmUjin&4@@S`KmX{s@3oBecj{Q&VKDPEaFq^lp&$B-k4;F=t^}uCmZ|DbR8W>g)}RB z%^>7umZ>Wt)!}I388h=->r8C&d}6NSuTrRevfjq!I#}EWP|5b_VP#(t3M*2dERSm}Bi$uqpeG4CtDh?6_7n($Z0_+edgym8O0r!hK z-Xj{~#z)v8OETvNvYkW_4!RNp`GR;lCh&RU zq@ujdE&5zQ`h3O>o-n3LCBM9-?RDSBRuE-Gia%rSZ-XXI9rI7Aoz?U?;V$>OO0EK> zxGlP*2Lv&KVsWlgmBwBrL#gBJoP!S$vaTxBMsLe^X> zlZTOi087s{W=!ixgOdVo-g;zi74Gu%bat!7GBT=f>52KYd!O@pRHAL*!5%uAxErI= zTD#Z1(fLJ=ZPsh47ppYzsnn&{_-le86WN4L^t;oqjy5OTJ!pdPWjT;;s_65!q4F{j zRL;}YG_xVRuLUIqKxb0;&)@R=Dh@t}DyO%pWZ?I%=ieSxO6+m1Z6BK9r?_)Ua~Nf@ zkuy@^(Pa_9w=M-7HFt!R<)*)ZQfaH*PP#toqorKdDkqPx>4(bmZ>*&^qnfQF?AcyO z*W33D_X5EDUZ{A2F4v%35ucF>F{XA;PCcMvniwl(YB|${gR3>H{8w-kUy(iVHQBBX0RsLn1OVcs9*EYO|YiBQUzXFS+fb+eYghhhDM$r-xqiTa~s7 z8C9sIJ?xLOlwA^gWdHoG&Z#AkeBK=8}v^{yjQrBu`12F?#CJm&{6>ZsA5SW9B4rq`CUjO7nwQkAbA)*yq@ z=DDgvTKtiJ6UW<7^@C3X zw5V!;tv$!J=N##%ZBGxfKh%2_s(w$Sa^osMl`3hhIP&vqZx=jsd>klOpR7!I16hqG zj_sqT2R-g|_56j^#!YLXDf~7Qj^wGfm=10ZkVR>9?{97cLKG!0?=-c#w^#>KZDRQS z{=m$*;a1SfH36{>EEdMS`hs8W$5f!J<8@nuMYS5UIQ**1$jwzgKNldRY(;rlf5sYc zo^SXF%J7=Bqgyx(wfbDl@J;w0GMyUlmTr>|f#9EE{btPjexvW$PFWu|6fZ6B|Mu4_ zP{8;7JT&_prac^FShL=Tz2pn;%`{nK)X}BxHeLT2IF6>A=Lg-93YN*)Iu%;zhFA~9WKN* zu=#BDz1{=w9CbULt!;yJ?r{i51Q_Y$g7Jh<~HJZ#LXAH z63@LE%vJQwT*=F|nr&{L_1el%v@ej>lrSS3=%E%?-y||tjBBw1{0C`V+9eGHz&9JzB7oBI;%uJH6i;rpELvIZ4u@ajDt<|Te8`^Eu)wAPii(YgT|1gb;j_@nVpH|D?m)<}b=gP6*2D4|4_JuQ-$wboXEWb@2C-$PXZB z%m)?>K$$wD+Oy!u>jzYQ;J=78z7GM`%)_~1$Y0$1Uk<>7uYo=n{&4d_60(D_jwS#&~ky)OsxFFG7qDP<30S%GLv!U%0tm(IqUZX89AZB-J==d(A{d^}i5V z1O#IbD2Z+RNC0iK{-+ITh#w(Y=;&g`=`GctV(WkHn#F7CjI7M_qd*&n8)y3dI*IXY zA^)n#4#CmCB$6KC%ZSr|H=<&7t**meope|I@q2!+(OXp}n1QxjCgmDlx7nXOXbC?j z8=fD13b0Ye%3UBcvJT#8QIm_`f1e1~ug}cLdAJOeSMATdlv|aM8mka7lD-Sgt|F^o zk`DY;x^cON6k?8FoH>j-*!^)9yQBOueV~t9q}vlZ)GZO0Rk?S?Wf3G1=slw+>z)%$ z_L&MrZQRECkqsTt{Gfn8B?i?=8}X=gL7NxO3eFx!u@K+>dh$>xCC`_p=88t zb1|IEJ+r+YUm5qgDs2DI?{J0LjjG?@*Vl(ty*4gBxNo;S+Mv#BhN*>5Ir388@$u&$^$U#zFsr{PQ7uu0bFb(j6x_r(g61;t9CopL?o ziZ1ECoyw1^Vd&qzvb+LW`|gTvHi62DX2_aXw|>5o@aL@gt6ZHzAOZD}CkXQ5_sR9X z@mPWG^=3%ez4#-z2ITTGo5`jTr1AJNJ~_8(=Xqs^3@u&? zIEmtlB;PfvMIeZnSA+08j)X~)Vm=SvF3M6#U>R zsze51p;wa&2V4BY#(E1gclO)gzY;*S4eI)JAw9TGTAH&PC-06Iil5w#wz)=UZhq;j z(_lu*p7yEwWcNmeLkRsL3B(+K^vp#DBfBgfOpDd3xS3GGKhwpYaGErIykNfeqd{?cKsM&rT=8zYDQk_i4OsI-XVQ$Wo`DPzDbi%mJtoG_mEMYo*iu6C)OJXl-;Xk2)U=EId7OKu@5tw3Mm_>q8}C*aXLAsNyv$!7uss3X}Wc~h=?I%!1?V|0+y66k=8ieo+!2f}?VKmd_ z?_}Bb2KTAMUyAZyjMBL3GU^=!1aMkK{r}+E_L;3%Qw0U>aQq9OKZg)OMbZZX(TL&x z7vR6R8J&eKX>pmP?l^n-=5JH@pA42E(d}QUNsf4XY4AUI=NK|`qXzfE>#)NJ5}cjK z(KGlLz*^piRffKn9yDj{>@#Q94lp-avc(nT|8iU?;Ld-H%$?-_*ZH9T=blaBUYZ}zU>Ip6{qe))f~j{o0g z?-o))B+6YxR6U&bf9)7qAo8Z3A#Alp=S8J|mn#R4XX7{0 zqf{`{a|j|157%N^6=|1T`(;x&MqkNXGuj|bNI9lUgZ@I%G1nZ;_^GfIb)862eQY?U zl`iJcD?JYjAk8_0r;oLr>q%)}jRAjWa3M^w+F?DTADUUoU?$>6NDRjcvvTjY!`8)l zZ};2_uA0nV8BkZ@L-EzL z2rEA2&&Mal18$R|pmuVeyW@3v)JJ6lt&BaHPfuW_{((_~&J>>nc{xL!T-Lq5egh{p zN^g0w>`x>&Mz}^C`;!Xew@^4G$h09-H>NQDkgxJ;_N2~DsC}PMEpJeDgVv-0xlfou zE|X*eK>25);9VB6I6m1a=2(%aycW3x{^tJG@Bx8&A-_blbQQj{csfRM*loivgpwtR zbd(+uVLZn!N2J@w_LNJqnL08Ok&gTnHBcBq>GZd5;yA zow-fIbYA!K3`$ue@8d;O7{8fg1m($v!|?s*2Lw2-Tap*aeT|N&hr$(CbR_svMb+Q7 zy(grpd43Jp+8Oj}*W|rVywZEm2TRgyopek43vOo{lfD$->cA>MX9yz~U{-@Dj7nvv zlPNW%3ojiI6S1EIYvGZG2#v#F(J?RTp??8OGud19!O~Z`FDpy zUgwB#LO8{7PSywMJ^~T<`M12T*SR7#DZXCUu|PSy3LZxn>9t)?kn&LhL$fVKYh6#5PV1N*lCHmIO(;! z=|BIQdh3VlNH1g6ak8H6J63_Ly0r0_ci-C&G-e+D*0t>?jpPBDpR{_P4D1=74mE*H zTgZP@HSOnPD<)4m?4bVhOJr^z-ox!Mi??%Yj%@75wH(4Kc>PnP$d3_@NKGToX?kCkhUb3`i)MgH7sXn3L18kIOARhhu}F1h`> z78@cD6!}0zBHuay4%@6B6uDiHIW{AmY_IkW7V#k^XrEDVkaLEftxEER0;YPcR5Yle zX^rKBYf0p`hTU%Gs67~6o9R9{5MZKcicsETvM<{gwY^l}=w0=+vataWTM`XW_~i0` zN;@Xuz4@Jxg(+z3uw-($oHI+p?HO3n&YC7xr&{d-+-qtGnm?ufH2c=(jv`5It{Ho~ z`Et$VgjDNQj*H#C@30aLiT9UG+ifX-uMHm^9onvCFNkttXOf3JmK#5c^7pq6z3h;B zd^vu(!b`j<;%WP&M{4C8tx>U$LvXLuKNE2!zC)aPJ?}abDk;<5Hgx4n<_}(R;O-vt z{guX_uM9oxB}{7Jk%#6&-*yRGk|(Xe3TT0=4V z_tE~{kC`J{oZex!b)9UQ)KSE7H41|-dve6e=@@y1(tBK)&SSNDMuekfUe?TifZ!*3 zw|w=5(r#W=1`Wk>nboRwTuOPBt(51_Mlb2PechA^3{s-#Qnqr~KxL_(x0L_s_DagM z8DbuYjp@F6*=vy@T4GF6!npQu6I&(b{HD{vkT2y|xZH*hz) zQ5S=r_ilK%h7OsbHU$1hqkhSLvNCHJmeBw4r`ssYbbDppn&Z0TsId0$9uAR~96#XV zB6;Lf{Wu2<$m8^rcaa~uv6!$SLn(~rGb(oCde}r0=@kptIL6yP5748Pz&>M_m6}4X zlqV#2`Gye+3Hv5G!Zw!PJW$tpz&ysoMj2gW5fVohW&S4mqf)5;Y0le+g476qZdpYd#aT) zJ(Tl%ni@2O{@r=raOQ~CoC_B}F0Z*S&7W>l`I&y|0?_ju;*h_m1CuVn9(^4U6Z5x+vQ)P$GsCRbYB5l%k4XqwN} z>&xHnHF{QSU$}!U%t0w%YHRLImc&~@Cy%j8&OY;$cgf*>?+l;a^Edn=sIYkYl4_4B zvm|=iWp`hHj?bYAkg=R5802Y=5!TG*+#Z(C!nOvTGR_xgP;%EB6b*zKKdT5kh0hy4H4^{~(@ zsx-Ue2Q2B&bUGY6qp@fG?^Q`l(qH}i9jhepJ@w1~y2^@Vq`^}js- z`!~avzahm(m2&@_lHRWRT=BT)z3nEZVM*2tpWl#Av);Z!@8#uPx!i*!j$y0$b!+gT$j(LHP)3#2P zqZb;^Y)oEutgp~IjR#!yWfXgHA}a-+`4fH8$|`cXiV{PK^&fC8`tik#37|q7R@;K+ zr#4k7s0uOy=cRPMrPu9Cueo6nbbLkVVUY7+n@!m3Kh>``y(h=``SJX}xxc68*Tj5z zTxM2r-Dc6xZ-*qM%8%vB$2v!y{{HP+>`^hp&9yoDhJL2~p{u}6pU>I*|4#mP`~Gj1 z6CG10zW?`N{q6X_*ZQF?k5t92=Owq-mTdiXOz!)&SW)++wBI-4lICQ|tqy@WfxZ4) z_*?z|&-icK|NeQO(OCA(pT+h6kH3}w^Wie6@pF4}(F$~Zq3Kj z!u?miz4F=nmEV~q{U4VeU%74LtyTOA!5k+v9@qXjdHz=YuXo3PyZW@ELk_ow%3zj0)sU_&|&T@WdH5;M}%` zliEYuN$ilJ{3)*>qt$y(`z~eE{<~-bxOsmJ(w_nC#sRg+;TyK6&pcU?)})pJ9GW|@ o6?ifXs4;}RaSCtO +#include + +#include "softbus_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_STR_MAX_LEN 46 + +#define DEVICE_NAME_BUF_LEN 128 + +#define EVENT_NODE_STATE_ONLINE 0x1 +#define EVENT_NODE_STATE_OFFLINE 0x02 +#define EVENT_NODE_STATE_INFO_CHANGED 0x04 + +#define EVENT_NODE_STATE_MASK 0x07 + +typedef enum { + CONNECTION_ADDR_WLAN = 0, + CONNECTION_ADDR_BR, + CONNECTION_ADDR_BLE, + CONNECTION_ADDR_ETH, + CONNECTION_ADDR_MAX +} ConnectionAddrType; + +typedef enum { + TYPE_NETWORK_ID = 0, + TYPE_DEVICE_NAME, +} NodeBasicInfoType; + +typedef enum { + NODE_KEY_UDID = 0, + NODE_KEY_UUID, +} NodeDeivceInfoKey; + +typedef struct { + ConnectionAddrType type; + union { + struct BrAddr { + char brMac[BT_MAC_LEN]; + } br; + struct BleAddr { + char bleMac[BT_MAC_LEN]; + } ble; + struct IpAddr { + char ip[IP_STR_MAX_LEN]; + int port; + } ip; + } info; +} ConnectionAddr; + +typedef struct { + char networkId[NETWORK_ID_BUF_LEN]; + char deviceName[DEVICE_NAME_BUF_LEN]; + uint8_t deviceTypeId; +} NodeBasicInfo; + +typedef struct { + uint32_t events; + void (*onNodeOnline)(NodeBasicInfo *info); + void (*onNodeOffline)(NodeBasicInfo *info); + void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); +} INodeStateCb; + +typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode); +typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode); + +int32_t JoinLNN(const char *pkgName, ConnectionAddr *target, OnJoinLNNResult cb); +int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb); + +int32_t RegNodeDeviceStateCb(const char *pkgName, INodeStateCb *callback); +int32_t UnregNodeDeviceStateCb(INodeStateCb *callback); + +int32_t GetAllNodeDeviceInfo(const char *pkgName, NodeBasicInfo **info, int32_t *infoNum); +void FreeNodeInfo(NodeBasicInfo *info); + +int32_t GetLocalNodeDeviceInfo(const char *pkgName, NodeBasicInfo *info); + +int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, + NodeDeivceInfoKey key, uint8_t *info, int32_t infoLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/interfaces/kits/common/softbus_common.h b/interfaces/kits/common/softbus_common.h new file mode 100644 index 000000000..fc50186f8 --- /dev/null +++ b/interfaces/kits/common/softbus_common.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_COMMON_H +#define SOFTBUS_CLIENT_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BT_MAC_LEN 18 + +#define NETWORK_ID_BUF_LEN 65 +#define UDID_BUF_LEN 65 +#define UUID_BUF_LEN 65 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/interfaces/kits/discovery/discovery_service.h b/interfaces/kits/discovery/discovery_service.h new file mode 100755 index 000000000..b3c6b93f6 --- /dev/null +++ b/interfaces/kits/discovery/discovery_service.h @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISCOVERY_SERVICE_H +#define DISCOVERY_SERVICE_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** + * @brief Indicates the maximum length of the capability data in PublishInfo and SubscribeInfo. + * + */ +#define MAX_CAPABILITYDATA_LEN 513 + +/** + * @brief Indicates the maximum length of the device ID in IDiscoveryCallback. + * + */ +#define DISC_MAX_DEVICE_ID_LEN 96 + +/** + * @brief Indicates the maximum length of the account hash code in IDiscoveryCallback. + * + */ +#define DISC_MAX_ACCOUNT_HASH_LEN 96 + +/** + * @brief Indicates the maximum length of the device name in IDiscoveryCallback. + * + */ +#define DISC_MAX_DEVICE_NAME_LEN 65 + +/** + * @brief Indicates the maximum length of the custom data in IDiscoveryCallback. + * + */ +#define DISC_MAX_CUST_DATA_LEN 219 + +/** + * @brief Indicates the maximum number of capabilities contained in the bitmap in IDiscoveryCallback. + * + */ +#define DISC_MAX_CAPABILITY_NUM 2 + +/** + * @brief Indicates the maximum length of the device address in IDiscoveryCallback. + * + */ +#define CONNECT_ADDR_LEN 46 + +/** + * @brief Enumerates the modes in which services are published. + * + */ +typedef enum { + /* Passive */ + DISCOVER_MODE_PASSIVE = 0x55, + /* Proactive */ + DISCOVER_MODE_ACTIVE = 0xAA +} DiscoverMode; + +/** + * @brief Enumerates media, such as Bluetooth, Wi-Fi, and USB, used for publishing services. + * + * Currently, only COAP is supported. + * When AUTO is selected, all the supported media will be called automatically. + */ +typedef enum { + /** Automatic medium selection */ + AUTO = 0, + /** Bluetooth */ + BLE = 1, + /** Wi-Fi */ + COAP = 2, + /** USB */ + USB = 3, + MEDIUM_BUTT +} ExchanageMedium; + +/** + * @brief Enumerates frequencies for publishing services. + * + * This enumeration applies only to Bluetooth and is not supported currently. + */ +typedef enum { + /** Low */ + LOW = 0, + /** Medium */ + MID = 1, + /** High */ + HIGH = 2, + /** Super-high */ + SUPER_HIGH = 3, + FREQ_BUTT +} ExchangeFreq; + +/** + * @brief Defines service publishing information. + * + */ +typedef struct { + /** Service ID */ + int publishId; + /** Discovery mode for service publishing. For details, see {@link Discovermode}. */ + DiscoverMode mode; + /** Service publishing medium. For details, see {@link ExchanageMedium}. */ + ExchanageMedium medium; + /** Service publishing frequency. For details, see {@link ExchangeFre}. */ + ExchangeFreq freq; + /** Service publishing capabilities. For details, see {@link g_capabilityMap}. */ + const char *capability; + /** Capability data for service publishing */ + unsigned char *capabilityData; + /** Maximum length of the capability data for service publishing (512 bytes) */ + unsigned int dataLen; +} PublishInfo; + +/** + * @brief Enumerates error codes for service publishing failures. + * + * The error codes are returned to the caller through IPublishCallback. + * + */ +typedef enum { + /* Unsupported medium */ + PUBLISH_FAIL_REASON_NOT_SUPPORT_MEDIUM = 1, + /* internal error */ + PUBLISH_FAIL_REASON_INTERNAL = 2, + /* Unknown reason */ + PUBLISH_FAIL_REASON_UNKNOWN = 0xFF +} PublishFailReason; + +/** + * @brief Defines the callbacks for successful and failed service publishing. + * + */ +typedef struct { + /** Callback for successful publishing */ + void (*OnPublishSuccess)(int publishId); + /** Callback for failed publishing */ + void (*OnPublishFail)(int publishId, PublishFailReason reason); +} IPublishCallback; + +/** + * @brief Enumerates supported capabilities published by a device. + * + */ +typedef enum { + /** MeeTime */ + HICALL_CAPABILITY_BITMAP = 0, + /** Video reverse connection in the smart domain */ + PROFILE_CAPABILITY_BITMAP = 1, + /** Gallery in Vision */ + HOMEVISIONPIC_CAPABILITY_BITMAP = 2, + /** cast+ */ + CASTPLUS_CAPABILITY_BITMAP, + /** Input method in Vision */ + AA_CAPABILITY_BITMAP, + /** Device virtualization tool package */ + DVKIT_CAPABILITY_BITMAP, + /** Distributed middleware */ + DDMP_CAPABILITY_BITMAP +} DataBitMap; + +/** + * @brief Defines the mapping between supported capabilities and bitmaps. + * + */ +typedef struct { + /** Bitmaps. For details, see {@link DataBitMap}. */ + DataBitMap bitmap; + /** Capability. For details, see {@link g_capabilityMap}. */ + char *capability; +} CapabilityMap; + +/** + * @brief Defines the mapping between supported capabilities and bitmaps. + * + */ +static const CapabilityMap g_capabilityMap[] = { + {HICALL_CAPABILITY_BITMAP, (char *)"hicall"}, + {PROFILE_CAPABILITY_BITMAP, (char *)"profile"}, + {HOMEVISIONPIC_CAPABILITY_BITMAP, (char *)"homevisionPic"}, + {CASTPLUS_CAPABILITY_BITMAP, (char *)"castPlus"}, + {AA_CAPABILITY_BITMAP, (char *)"aaCapability"}, + {DVKIT_CAPABILITY_BITMAP, (char *)"dvKit"}, + {DDMP_CAPABILITY_BITMAP, (char *)"ddmpCapability"}, +}; + +/** + * @brief Defines service subscription information. + * + */ +typedef struct { + /** Service ID */ + int subscribeId; + /** Discovery mode for service subscription. For details, see {@link Discovermode}. */ + DiscoverMode mode; + /** Service subscription medium. For details, see {@link ExchanageMedium}. */ + ExchanageMedium medium; + /** Service subscription frequency. For details, see {@link ExchangeFre}. */ + ExchangeFreq freq; + /** only find the device with the same account */ + bool isSameAccount; + /** find the sleeping devices */ + bool isWakeRemote; + /** Service subscription capability. For details, see {@link g_capabilityMap}. */ + const char *capability; + /** Capability data for service subscription */ + unsigned char *capabilityData; + /** Maximum length of the capability data for service subscription (512 bytes) */ + unsigned int dataLen; +} SubscribeInfo; + +/** + * @brief Enumerates error codes for service subscription failures. + * + * The error codes are returned to the caller through IDiscoveryCallback. + * + */ +typedef enum { + /* Unsupported medium */ + DISCOVERY_FAIL_REASON_NOT_SUPPORT_MEDIUM = 1, + /* internal error */ + DISCOVERY_FAIL_REASON_INTERNAL = 2, + /* Unknown error */ + DISCOVERY_FAIL_REASON_UNKNOWN = 0xFF +} DiscoveryFailReason; + +/** + * @brief Enumerates device types. + * + */ +typedef enum { + /* Smart speaker */ + SMART_SPEAKER = 0x00, + /* PC */ + DESKTOP_PC, + /* Laptop */ + LAPTOP, + /* Mobile phone */ + SMART_PHONE, + /* Tablet */ + SMART_PAD, + /* Smart watch */ + SMART_WATCH, + /* Smart car */ + SMART_CAR, + /* Kids' watch */ + CHILDREN_WATCH, + /* Smart TV */ + SMART_TV, +} DeviceType; + +/** + * @brief Enumerates connection types returned by IDiscoveryCallback. + * + */ +typedef enum { + /** WLAN */ + CONNECT_ADDR_WLAN = 1, + /** BR */ + CONNECT_ADDR_BR, + /** BLE */ + CONNECT_ADDR_BLE, + /** MAX */ + CONNECT_ADDR_TYPE_MAX +} ConnectAddrType; + +/** + * @brief Defines connection information. + * + */ +typedef struct { + /** Connection type. For details, see {@link ConnectAddrType}. */ + ConnectAddrType type; + /** Connection address. For its length, see {@link CONNECT_ADDR_LEN}. */ + char addr[CONNECT_ADDR_LEN]; + /** Port number */ + int port; +} ConnectAddr; + +/** + * @brief Defines the device information returned by IDiscoveryCallback. + * + */ +typedef struct { + /** Device ID. Its maximum length is specified by {@link DISC_MAX_DEVICE_ID_LEN}. */ + char devId[DISC_MAX_DEVICE_ID_LEN]; + /** Account hash code. Its maximum length is specified by {@link DISC_MAX_ACCOUNT_HASH_LEN}. */ + char hwAccountHash[DISC_MAX_ACCOUNT_HASH_LEN]; + /** Device type. For details, see {@link DeviceType}. */ + DeviceType devType; + /** Device name. Its maximum length is specified by {@link DISC_MAX_DEVICE_NAME_LEN}. */ + char devName[DISC_MAX_DEVICE_NAME_LEN]; + /** Number of available connections */ + unsigned int addrNum; + /** Connection information. For details, see {@link ConnectAddr}. */ + ConnectAddr addr[CONNECT_ADDR_TYPE_MAX]; + /** Number of capabilities */ + unsigned int capabilityBitmapNum; + /** Device capability bitmap. + * The maximum number of capabilities in the bitmap is specified by {@link DISC_MAX_CAPABILITY_NUM}. + */ + unsigned int capabilityBitmap[DISC_MAX_CAPABILITY_NUM]; + /** Custom data. Its length is specified by {@link DISC_MAX_CUST_DATA_LEN}. */ + char custData[DISC_MAX_CUST_DATA_LEN]; +} DeviceInfo; + +/** + * @brief Defines a callback for service subscription. + * + * Three types of callbacks are available. + * + */ +typedef struct { + /** Callback that is invoked when a device is found */ + void (*OnDeviceFound)(const DeviceInfo *device); + /** Callback for a subscription failure */ + void (*OnDiscoverFailed)(int subscribeId, DiscoveryFailReason failReason); + /** Callback for a subscription success */ + void (*OnDiscoverySuccess)(int subscribeId); +} IDiscoveryCallback; + +/** + * @brief Publishes a specified service. + * + * Peer devices in the same LAN as the device that publishes this service can discover this service as needed. + * The service is identified by publicId and pkgName. + * + * @param pkgName Indicates the pointer to the service package name, which can contain a maximum of 64 bytes. + * @param info Indicates the pointer to the service publishing information. For details, see {@link PublishInfo}. + * @param cb Indicates the pointer to the service publishing callback {@link IPublishCallback}. + * @return Returns SOFTBUS_INVALID_PARAM if any parameter is null or invalid. + * @return Returns SOFTBUS_DISCOVER_NOT_INIT if the Intelligent Soft Bus client fails to be initialized. + * @return Returns SOFTBUS_LOCK_ERR if the mutex fails to be locked. + * @return Returns SOFTBUS_OK if the service is successfully published. + */ +int PublishService(const char *pkgName, const PublishInfo *info, const IPublishCallback *cb); + +/** + * @brief Unpublishes a specified service. + * + * @param pkgName Indicates the pointer to the service package name, which can contain a maximum of 64 bytes. + * @param publishId Indicates the service ID. + * @return Returns SOFTBUS_INVALID_PARAM if pkgName is invalid. + * @return Returns SOFTBUS_DISCOVER_NOT_INIT if the Intelligent Soft Bus client fails to be initialized. + * @return Returns SOFTBUS_OK if the service is successfully unpublished. + */ +int UnPublishService(const char *pkgName, int publishId); + +/** + * @brief Subscribes to a specified service. + * + * Information about the device that publishes the service will be reported to the device that subscribes to + * the service. + * The service is identified by subscribeId and pkgName. + * + * @param pkgName Indicates the pointer to the service package name, which can contain a maximum of 64 bytes. + * @param info Indicates the pointer to the service subscription information. For details, see {@link SubscribeInfo}. + * @param cb Indicates the service subscription callback {@link IDiscoveryCallback}. + * @return Returns SOFTBUS_INVALID_PARAM if any parameter is null or invalid. + * @return Returns SOFTBUS_DISCOVER_NOT_INIT if the Intelligent Soft Bus client fails to be initialized. + * @return Returns SOFTBUS_LOCK_ERR if the mutex fails to be locked. + * @return Returns SOFTBUS_OK if the service subscription is successful. + */ +int StartDiscovery(const char *pkgName, const SubscribeInfo *info, const IDiscoveryCallback *cb); + +/** + * @brief Unsubscribes from a specified service. + * + * @param pkgName Indicates the pointer to the service package name, which can contain a maximum of 64 bytes. + * @param subscribeId Indicates the service ID. + * @return Returns SOFTBUS_INVALID_PARAM if pkgName is invalid. + * @return Returns SOFTBUS_DISCOVER_NOT_INIT if the Intelligent Soft Bus client fails to be initialized. + * @return Returns SOFTBUS_OK if the service unsubscription is successful. + */ +int StopDiscovery(const char *pkgName, int subscribeId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* DISCOVERY_SERVICE_H */ diff --git a/interfaces/kits/transport/session.h b/interfaces/kits/transport/session.h new file mode 100644 index 000000000..f0e6d0f5e --- /dev/null +++ b/interfaces/kits/transport/session.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Softbus + * @{ + * + * @brief Provides high-speed, secure communication between devices. + * + * This module implements unified distributed communication capability management between + * nearby devices, and provides link-independent device discovery and transmission interfaces + * to support service publishing and data transmission. + * + * @since 1.0 + * @version 1.0 +*/ + +/** + * @file session.h + * + * @brief Declares unified data transmission interfaces. + * + * This file provides data transmission capabilities, including creating and removing a session server, + * opening and closing sessions, receiving data, and querying basic session information. \n + * After multiple nearby devices are discovered and networked, these interfaces can be used to + * transmit data across devices. \n + * + * @since 1.0 + * @version 1.0 + */ +#ifndef SESSION_H +#define SESSION_H +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief bussiness type of session + * + * @since 1.0 + * @version 1.0 + */ +typedef enum { + TYPE_MESSAGE = 1, + TYPE_BYTES, + TYPE_FILE, + TYPE_STREAM, + TYPE_BUTT, +} SessionType; + +/** + * @brief session attribute. + * + * control the attribute of session。 + * + * @since 1.0 + * @version 1.0 + */ +typedef struct { + /** @brief dataType{@link SessionType} */ + unsigned int dataType; +} SessionAttribute; + +/** + * @brief Defines session callbacks. + * + * When a session is opened or closed, or there is data to process, the related callback is invoked. + * + * @since 1.0 + * @version 1.0 + */ +typedef struct { + /** + * @brief Called when a session is opened. + * + * This function can be used to verify the session or initialize resources related to the session. + * + * @param sessionId Indicates the session ID. + * @param result 0 if the session is opened successfully, returns an error code otherwise. + * @return Returns 0 if the session connection is accepted; returns a non-zero value + * otherwise (you do not need to call {@link CloseSession} to close the session). + * @since 1.0 + * @version 1.0 + */ + int (*OnSessionOpened)(int sessionId, int result); + + /** + * @brief Called when a session is closed. + * + * This function can be used to release resources related to the session. + * You do not need to call {@link CloseSession}. + * + * @param sessionId Indicates the session ID. + * @since 1.0 + * @version 1.0 + */ + void (*OnSessionClosed)(int sessionId); + + /** + * @brief Called when data is received. + * + * This function is used to notify that data is received. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the data received. + * @param dataLen Indicates the length of the data received. + * @since 1.0 + * @version 1.0 + */ + void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen); + + /** + * @brief Called when message is received. + * + * This function is used to notify that message is received. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the message data received. + * @param dataLen Indicates the length of the message received. + * @since 1.0 + * @version 1.0 + */ + void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen); +} ISessionListener; + +/** + * @brief Creates a session server based on a package name and session name. + * + * A maximum of 18 session servers can be created. + * + * @param pkgName Indicates the pointer to the package name, which can be used to check whether the + * session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. + * @param sessionName Indicates the pointer to the session name, which is the unique ID of the session server. + * The value cannot be empty and can contain a maximum of 64 characters. + * @param listener Indicates the pointer to the session callback structure, which cannot be empty. + * @return Returns 0 if the operation is successful; returns -1 otherwise. + * @see RemoveSessionServer + * @since 1.0 + * @version 1.0 + */ +int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener); + +/** + * @brief Removes a session server based on a package name and session name. + * + * @param pkgName Indicates the pointer to the name of the registered package, which can be used to check + * whether the session server is in this package. The value cannot be empty and can contain a maximum of 64 characters. + * @param sessionName Indicates the pointer to the session name. The value cannot be empty and can contain + * a maximum of 64 characters. + * @return Returns 0 if the operation is successful, returns -1 otherwise. + * @see CreateSessionServer + * @since 1.0 + * @version 1.0 + */ +int RemoveSessionServer(const char *pkgName, const char *sessionName); + +/** + * @brief Initiate a session open request, which is an asynchronous process. + * + * The session connection is opened based on the service name to trigger the first packet interaction process. + * According to the {@link OnSessionOpened} Notify the user whether the session is successfully opened. + * Data can be transmitted only after the session is successfully opened. + * + * @param mySessionName local session name. + * @param peerSessionName remote session name. + * @param peerDeviceId remote device id. + * @param groupId group id. + * @param attr session attribute {@link SessionAttribute}. + * @return return sessionId if the session is opened successfully, returns an error code otherwise. + * @since 1.0 + * @version 1.0 + */ +int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, const SessionAttribute* attr); + +/** + * @brief Closes a connected session based on a session ID. + * + * @param sessionId Indicates the session ID. + * @return no return value. + * @since 1.0 + * @version 1.0 + */ +void CloseSession(int sessionId); + +/** + * @brief Sends data based on a session ID. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the data to send, which cannot be NULL. + * @param len Indicates the length of the data to send. The maximum length cannot exceed 984 characters. + * @return Returns 0 if the function is called successfully; returns -1 otherwise. + * @since 1.0 + * @version 1.0 + */ +int SendBytes(int sessionId, const void *data, unsigned int len); + +/** + * @brief Sends message based on a session ID. + * + * @param sessionId Indicates the session ID. + * @param data Indicates the pointer to the message data to send, which cannot be NULL. + * @param len Indicates the length of the message to send. + * @return Returns 0 if the function is called successfully, returns an error code otherwise. + * @since 1.0 + * @version 1.0 + */ +int SendMessage(int sessionId, const void *data, unsigned int len); + +/** + * @brief Obtains the session name registered by the local device based on the session ID. + * + * @param sessionId Indicates the session ID. + * @param sessionName Indicates the pointer to the buffer for storing the session name. + * @param len Indicates the length of the buffer. + * @return Returns 0 if the operation is successful; returns -1 otherwise. + * @since 1.0 + * @version 1.0 + */ +int GetMySessionName(int sessionId, char *sessionName, unsigned int len); + +/** + * @brief Obtains the session name registered by the peer device based on the session ID. + * + * @param sessionId Indicates the session ID. + * @param sessionName Indicates the pointer to the buffer for storing the session name. + * @param len Indicates the length of the buffer. + * @return Returns 0 if the operation is successful; returns -1 otherwise. + * @since 1.0 + * @version 1.0 + */ +int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len); + +/** + * @brief Obtains the peer device ID based on a session ID. + * + * @param sessionId Indicates the session ID. + * @param devId Indicates the pointer to the buffer for storing the device ID. + * @param len Indicates the length of the buffer. + * @return Returns 0 if the operation is successful; returns -1 otherwise. + * @since 1.0 + * @version 1.0 + */ +int GetPeerDeviceId(int sessionId, char *devId, unsigned int len); + +#ifdef __cplusplus +} +#endif +#endif // SESSION_H diff --git a/ohos.build b/ohos.build new file mode 100755 index 000000000..0cb8b9c5e --- /dev/null +++ b/ohos.build @@ -0,0 +1,39 @@ +{ + "parts": { + "dsoftbus_standard": { + "module_list": [ + "//foundation/communication/dsoftbus/core/frame/standard/server:softbus_server", + "//foundation/communication/dsoftbus/core/frame/standard/client:softbus_client", + "//foundation/communication/dsoftbus/core/frame/standard/sa_profile:softbus_sa_profile", + "//foundation/communication/dsoftbus/core/common/security/permission:softbus_permission" + ], + "test_list": [ + "//foundation/communication/dsoftbus/tests/core/authentication:unittest", + "//foundation/communication/dsoftbus/tests/core/bus_center/lnn:unittest", + "//foundation/communication/dsoftbus/tests/core/common/security:softbus_permission_test", + "//foundation/communication/dsoftbus/tests/core/connection:connectionTest", + "//foundation/communication/dsoftbus/tests/core/discovery/manager:unittest", + "//foundation/communication/dsoftbus/tests/core/transmission/trans_channel/tcp_direct:unittest", + "//foundation/communication/dsoftbus/tests/sdk/bus_center/unittest:unittest", + "//foundation/communication/dsoftbus/tests/sdk/discovery/unittest:unittest", + "//foundation/communication/dsoftbus/tests/sdk/transmission/trans_channel/tcp_direct:unittest" + ], + "inner_kits": [ + { + "type": "so", + "name": "//foundation/communication/dsoftbus/core/frame/standard/client:softbus_client", + "header": { + "header_files": [ + "bus_center/softbus_bus_center.h", + "common/softbus_common.h", + "discovery/discovery_service.h", + "transport/session.h" + ], + "header_base": "//foundation/communication/dsoftbus/interfaces/kits" + } + } + ] + } + }, + "subsystem": "communication" +} diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn new file mode 100755 index 000000000..aad5206c1 --- /dev/null +++ b/sdk/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_component("softbus_client") { + features = [ + "frame:softbus_client_frame", + "bus_center:softbus_client_bus_center", + "transmission:softbus_client_transmission", + ] +} diff --git a/sdk/bus_center/BUILD.gn b/sdk/bus_center/BUILD.gn new file mode 100755 index 000000000..8cd7a2b6f --- /dev/null +++ b/sdk/bus_center/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_client_bus_center") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/sdk/frame/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + sources = [ "src/client_bus_center.c" ] + } +} else { + shared_library("softbus_client_bus_center") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/sdk/frame/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ "src/client_bus_center.c" ] + } +} diff --git a/sdk/bus_center/include/client_bus_center.h b/sdk/bus_center/include/client_bus_center.h new file mode 100644 index 000000000..3e2c8aedf --- /dev/null +++ b/sdk/bus_center/include/client_bus_center.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_BUS_CENTER_H +#define CLIENT_BUS_CENTER_H + +#include +#include + +#include "softbus_bus_center.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t LnnOnJoinResult(void *addr, const char *networkId, int32_t retCode); +int32_t LnnOnLeaveResult(const char *networkId, int32_t retCode); +int32_t LnnOnNodeOnlineStateChanged(bool isOnline, void *info); +int32_t LnnOnNodeBasicInfoChanged(void *info, int32_t type); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/sdk/bus_center/src/client_bus_center.c b/sdk/bus_center/src/client_bus_center.c new file mode 100644 index 000000000..fd72a45fb --- /dev/null +++ b/sdk/bus_center/src/client_bus_center.c @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_bus_center.h" + +#include +#include + +#include "softbus_client_frame_manager.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_property.h" +#include "softbus_utils.h" + +#define GET_MAX_NODE_STATE_CB_CNT "MAX_NODE_STATE_CB_CNT" +#define DEFAULT_NODE_STATE_CB_CNT 10 + +static int32_t g_maxNodeStateCbCount; + +typedef struct { + ListNode node; + ConnectionAddr addr; + OnJoinLNNResult cb; +} JoinLNNCbListItem; + +typedef struct { + ListNode node; + char networkId[NETWORK_ID_BUF_LEN]; + OnLeaveLNNResult cb; +} LeaveLNNCbListItem; + +typedef struct { + ListNode node; + INodeStateCb cb; +} NodeStateCallbackItem; + +typedef struct { + SoftBusList *joinLNNCbList; + SoftBusList *leaveLNNCbList; + SoftBusList *nodeStateCbList; + pthread_mutex_t lock; +} BusCenterClient; + +static BusCenterClient g_busCenterClient; + +static bool IsSameConnectionAddr(const ConnectionAddr *addr1, const ConnectionAddr *addr2) +{ + if (addr1->type != addr2->type) { + return false; + } + if (addr1->type == CONNECTION_ADDR_BR) { + return strncmp(addr1->info.br.brMac, addr2->info.br.brMac, BT_MAC_LEN) == 0; + } + if (addr1->type == CONNECTION_ADDR_BLE) { + return strncmp(addr1->info.ble.bleMac, addr2->info.ble.bleMac, BT_MAC_LEN) == 0; + } + if (addr1->type == CONNECTION_ADDR_WLAN || addr1->type == CONNECTION_ADDR_ETH) { + return true; + } + return false; +} + +static JoinLNNCbListItem *FindJoinLNNCbItem(ConnectionAddr *addr, OnJoinLNNResult cb) +{ + JoinLNNCbListItem *item = NULL; + SoftBusList *list = g_busCenterClient.joinLNNCbList; + + LIST_FOR_EACH_ENTRY(item, &list->list, JoinLNNCbListItem, node) { + if (IsSameConnectionAddr(&item->addr, addr) && + (cb == NULL || cb == item->cb)) { + return item; + } + } + return NULL; +} + +static int32_t AddJoinLNNCbItem(ConnectionAddr *target, OnJoinLNNResult cb) +{ + JoinLNNCbListItem *item = NULL; + SoftBusList *list = g_busCenterClient.joinLNNCbList; + + item = (JoinLNNCbListItem *)SoftBusMalloc(sizeof(*item)); + if (item == NULL) { + LOG_ERR("fail: malloc join LNN cb list item"); + return SOFTBUS_MALLOC_ERR; + } + ListInit(&item->node); + item->addr = *target; + item->cb = cb; + ListAdd(&list->list, &item->node); + list->cnt++; + return SOFTBUS_OK; +} + +static LeaveLNNCbListItem *FindLeaveLNNCbItem(const char *networkId, OnLeaveLNNResult cb) +{ + LeaveLNNCbListItem *item = NULL; + SoftBusList *list = g_busCenterClient.leaveLNNCbList; + + LIST_FOR_EACH_ENTRY(item, &list->list, LeaveLNNCbListItem, node) { + if (strcmp(item->networkId, networkId) == 0 && + (cb == NULL || cb == item->cb)) { + return item; + } + } + return NULL; +} + +static int32_t AddLeaveLNNCbItem(const char *networkId, OnLeaveLNNResult cb) +{ + LeaveLNNCbListItem *item = NULL; + SoftBusList *list = g_busCenterClient.leaveLNNCbList; + + item = (LeaveLNNCbListItem *)SoftBusMalloc(sizeof(*item)); + if (item == NULL) { + LOG_ERR("fail: malloc join LNN cb list item"); + return SOFTBUS_MALLOC_ERR; + } + ListInit(&item->node); + if (strncpy_s(item->networkId, NETWORK_ID_BUF_LEN, networkId, strlen(networkId)) != EOK) { + LOG_ERR("strcpy network id fail"); + SoftBusFree(item); + return SOFTBUS_ERR; + } + item->cb = cb; + ListAdd(&list->list, &item->node); + list->cnt++; + return SOFTBUS_OK; +} + +static bool IsValidNodeStateCb(INodeStateCb *callback) +{ + if (callback == NULL) { + return false; + } + if (callback->events == 0) { + return false; + } + if ((callback->events & EVENT_NODE_STATE_ONLINE) != 0 && + callback->onNodeOnline == NULL) { + return false; + } + if ((callback->events & EVENT_NODE_STATE_OFFLINE) != 0 && + callback->onNodeOffline == NULL) { + return false; + } + if ((callback->events & EVENT_NODE_STATE_INFO_CHANGED) != 0 && + callback->onNodeBasicInfoChanged == NULL) { + return false; + } + return true; +} + +static void ClearJoinLNNList(void) +{ + JoinLNNCbListItem *item = NULL; + JoinLNNCbListItem *next = NULL; + ListNode *list = &g_busCenterClient.joinLNNCbList->list; + + LIST_FOR_EACH_ENTRY_SAFE(item, next, list, JoinLNNCbListItem, node) { + ListDelete(&item->node); + if (g_busCenterClient.joinLNNCbList->cnt > 0) { + g_busCenterClient.joinLNNCbList->cnt--; + } + SoftBusFree(item); + } +} + +static void ClearLeaveLNNList(void) +{ + LeaveLNNCbListItem *item = NULL; + LeaveLNNCbListItem *next = NULL; + ListNode *list = &g_busCenterClient.leaveLNNCbList->list; + + LIST_FOR_EACH_ENTRY_SAFE(item, next, list, LeaveLNNCbListItem, node) { + ListDelete(&item->node); + if (g_busCenterClient.leaveLNNCbList->cnt > 0) { + g_busCenterClient.leaveLNNCbList->cnt--; + } + SoftBusFree(item); + } +} + +static void ClearNodeStateCbList(void) +{ + NodeStateCallbackItem *item = NULL; + NodeStateCallbackItem *next = NULL; + ListNode *list = &g_busCenterClient.nodeStateCbList->list; + + LIST_FOR_EACH_ENTRY_SAFE(item, next, list, NodeStateCallbackItem, node) { + ListDelete(&item->node); + if (g_busCenterClient.nodeStateCbList->cnt > 0) { + g_busCenterClient.nodeStateCbList->cnt--; + } + SoftBusFree(item); + } +} + +void BusCenterClientDeinit(void) +{ + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock in deinit"); + } + if (g_busCenterClient.joinLNNCbList != NULL) { + ClearJoinLNNList(); + DestroySoftBusList(g_busCenterClient.joinLNNCbList); + g_busCenterClient.joinLNNCbList = NULL; + } + if (g_busCenterClient.leaveLNNCbList != NULL) { + ClearLeaveLNNList(); + DestroySoftBusList(g_busCenterClient.leaveLNNCbList); + g_busCenterClient.leaveLNNCbList = NULL; + } + if (g_busCenterClient.nodeStateCbList != NULL) { + ClearNodeStateCbList(); + DestroySoftBusList(g_busCenterClient.nodeStateCbList); + g_busCenterClient.nodeStateCbList = NULL; + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock in deinit"); + } + pthread_mutex_destroy(&g_busCenterClient.lock); +} + +int BusCenterClientInit(void) +{ + int32_t rc = SOFTBUS_ERR; + + pthread_mutex_init(&g_busCenterClient.lock, NULL); + if (GetPropertyInt(GET_MAX_NODE_STATE_CB_CNT, &g_maxNodeStateCbCount) != SOFTBUS_OK) { + LOG_ERR("Cannot get NodeStateCbCount from config file"); + g_maxNodeStateCbCount = DEFAULT_NODE_STATE_CB_CNT; + } + do { + g_busCenterClient.joinLNNCbList = CreateSoftBusList(); + if (g_busCenterClient.joinLNNCbList == NULL) { + LOG_ERR("init fail : joinLNNCbList = null!"); + break; + } + g_busCenterClient.leaveLNNCbList = CreateSoftBusList(); + if (g_busCenterClient.leaveLNNCbList == NULL) { + LOG_ERR("int fail : leaveLNNCbList = null!"); + break; + } + g_busCenterClient.nodeStateCbList = CreateSoftBusList(); + if (g_busCenterClient.nodeStateCbList == NULL) { + LOG_ERR("int fail : nodeStateCbList = null!"); + break; + } + rc = SOFTBUS_OK; + } while (false); + + if (rc != SOFTBUS_OK) { + BusCenterClientDeinit(); + } + LOG_INFO("BusCenterClientInit init OK!"); + return SOFTBUS_OK; +} + +int32_t GetAllNodeDeviceInfo(const char *pkgName, NodeBasicInfo **info, int32_t *infoNum) +{ + if (pkgName == NULL || info == NULL || infoNum == NULL) { + LOG_ERR("fail: params are null"); + return SOFTBUS_INVALID_PARAM; + } + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("fail: init softbus"); + return SOFTBUS_ERR; + } + return GetServerProvideInterface()->getAllOnlineNodeInfo((void **)info, sizeof(NodeBasicInfo), infoNum); +} + +void FreeNodeInfo(NodeBasicInfo *info) +{ + if (info == NULL) { + return; + } + SoftBusFree(info); +} + +int32_t GetLocalNodeDeviceInfo(const char *pkgName, NodeBasicInfo *info) +{ + if (pkgName == NULL || info == NULL) { + LOG_ERR("fail: params are null"); + return SOFTBUS_INVALID_PARAM; + } + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("fail: init softbus"); + return SOFTBUS_ERR; + } + return GetServerProvideInterface()->getLocalDeviceInfo(info, sizeof(*info)); +} + +int32_t GetNodeKeyInfo(const char *pkgName, const char *networkId, NodeDeivceInfoKey key, + uint8_t *info, int32_t infoLen) +{ + if (pkgName == NULL) { + LOG_ERR("fail: pkgName is null"); + return SOFTBUS_INVALID_PARAM; + } + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("fail: init softbus"); + return SOFTBUS_ERR; + } + if (!IsValidString(networkId, NETWORK_ID_BUF_LEN) || info == NULL) { + LOG_ERR("invalid params"); + return SOFTBUS_INVALID_PARAM; + } + return GetServerProvideInterface()->getNodeKeyInfo(networkId, key, info, infoLen); +} + +int32_t JoinLNN(const char *pkgName, ConnectionAddr *target, OnJoinLNNResult cb) +{ + int32_t rc; + SoftBusList *list = NULL; + + if (pkgName == NULL || target == NULL || cb == NULL) { + LOG_ERR("fail : params are NULL!"); + return SOFTBUS_INVALID_PARAM; + } + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("fail: init softbus"); + return SOFTBUS_ERR; + } + list = g_busCenterClient.joinLNNCbList; + if (list == NULL) { + LOG_ERR("fail : join lnn cb list = NULL!"); + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock join lnn cb list in join"); + } + rc = SOFTBUS_ERR; + do { + if (FindJoinLNNCbItem(target, cb) != NULL) { + LOG_ERR("fail : join request already exist"); + break; + } + rc = GetServerProvideInterface()->joinLNN(target, sizeof(*target)); + if (rc != SOFTBUS_OK) { + LOG_ERR("fail : request join lnn"); + } else { + rc = AddJoinLNNCbItem(target, cb); + } + } while (false); + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock join lnn cb list in join"); + } + return rc; +} + +int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb) +{ + int32_t rc; + SoftBusList *list = g_busCenterClient.leaveLNNCbList; + + if (networkId == NULL || cb == NULL) { + LOG_ERR("fail : networkId or cb is NULL!"); + return SOFTBUS_INVALID_PARAM; + } + if (list == NULL) { + LOG_ERR("fail : leave lnn cb list = NULL!"); + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock leave lnn cb list in leave"); + } + rc = SOFTBUS_ERR; + do { + if (FindLeaveLNNCbItem(networkId, cb) != NULL) { + LOG_ERR("fail : leave request already exist"); + break; + } + rc = GetServerProvideInterface()->leaveLNN(networkId); + if (rc != SOFTBUS_OK) { + LOG_ERR("fail : request leave lnn"); + } else { + rc = AddLeaveLNNCbItem(networkId, cb); + } + } while (false); + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock leave lnn cb list in leave"); + } + return rc; +} + +int32_t RegNodeDeviceStateCb(const char *pkgName, INodeStateCb *callback) +{ + SoftBusList *list = NULL; + NodeStateCallbackItem *item = NULL; + int32_t rc = SOFTBUS_ERR; + + if (pkgName == NULL || IsValidNodeStateCb(callback) == false) { + LOG_ERR("fail: invalid parameters"); + return SOFTBUS_INVALID_PARAM; + } + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("fail: init softbus"); + return SOFTBUS_ERR; + } + list = g_busCenterClient.nodeStateCbList; + if (list == NULL) { + LOG_ERR("fail: node state cb list is null"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock node state cb list in reg"); + } + do { + if (list->cnt >= (uint32_t)g_maxNodeStateCbCount) { + break; + } + item = (NodeStateCallbackItem *)SoftBusMalloc(sizeof(*item)); + if (item == NULL) { + rc = SOFTBUS_MALLOC_ERR; + break; + } + ListInit(&item->node); + item->cb = *callback; + ListAdd(&list->list, &item->node); + list->cnt++; + rc = SOFTBUS_OK; + item = NULL; + } while (false); + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock node state cb list"); + } + if (item != NULL) { + SoftBusFree(item); + } + return rc; +} + +int32_t UnregNodeDeviceStateCb(INodeStateCb *callback) +{ + SoftBusList *list = g_busCenterClient.nodeStateCbList; + NodeStateCallbackItem *item = NULL; + NodeStateCallbackItem *next = NULL; + + if (callback == NULL) { + LOG_ERR("para callback = null!"); + return SOFTBUS_INVALID_PARAM; + } + if (list == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock node state cb list in unreg"); + } + LIST_FOR_EACH_ENTRY_SAFE(item, next, &list->list, NodeStateCallbackItem, node) { + if (memcmp(&item->cb, callback, sizeof(*callback)) == 0) { + ListDelete(&item->node); + SoftBusFree(item); + if (list->cnt > 0) { + list->cnt--; + } + break; + } + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock node state cb list in unreg"); + } + return SOFTBUS_OK; +} + +int32_t LnnOnJoinResult(void *addr, const char *networkId, int32_t retCode) +{ + SoftBusList *list = g_busCenterClient.joinLNNCbList; + JoinLNNCbListItem *item = NULL; + ConnectionAddr *connAddr = (ConnectionAddr *)addr; + + if (connAddr == NULL) { + return SOFTBUS_INVALID_PARAM; + } + if (list == NULL) { + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock join lnn cb list in join result"); + } + while ((item = FindJoinLNNCbItem(addr, NULL)) != NULL) { + ListDelete(&item->node); + if (item->cb != NULL) { + item->cb(connAddr, networkId, retCode); + } + --list->cnt; + SoftBusFree(item); + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock join lnn cb list in join result"); + } + return SOFTBUS_OK; +} + +int32_t LnnOnLeaveResult(const char *networkId, int32_t retCode) +{ + SoftBusList *list = g_busCenterClient.leaveLNNCbList; + LeaveLNNCbListItem *item = NULL; + + if (networkId == NULL) { + LOG_ERR("fail: networkId is null"); + return SOFTBUS_INVALID_PARAM; + } + if (list == NULL) { + LOG_ERR("fail: leave cb list is null"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock leave lnn cb list in leave result"); + } + while ((item = FindLeaveLNNCbItem(networkId, NULL)) != NULL) { + ListDelete(&item->node); + if (item->cb != NULL) { + item->cb(networkId, retCode); + } + --list->cnt; + SoftBusFree(item); + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock leave lnn cb list in leave result"); + } + return SOFTBUS_OK; +} + +int32_t LnnOnNodeOnlineStateChanged(bool isOnline, void *info) +{ + SoftBusList *list = g_busCenterClient.nodeStateCbList; + NodeStateCallbackItem *item = NULL; + NodeBasicInfo *basicInfo = (NodeBasicInfo *)info; + + if (basicInfo == NULL || list == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock node state cb list in notify"); + } + LIST_FOR_EACH_ENTRY(item, &list->list, NodeStateCallbackItem, node) { + if (isOnline == true) { + if ((item->cb.events & EVENT_NODE_STATE_ONLINE) != 0) { + item->cb.onNodeOnline(basicInfo); + } + } else { + if ((item->cb.events & EVENT_NODE_STATE_OFFLINE) != 0) { + item->cb.onNodeOffline(basicInfo); + } + } + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock node state cb list in notify"); + } + return SOFTBUS_OK; +} + +int32_t LnnOnNodeBasicInfoChanged(void *info, int32_t type) +{ + SoftBusList *list = g_busCenterClient.nodeStateCbList; + NodeStateCallbackItem *item = NULL; + NodeBasicInfo *basicInfo = (NodeBasicInfo *)info; + + if (basicInfo == NULL || list == NULL) { + LOG_ERR("info or list is null"); + return SOFTBUS_INVALID_PARAM; + } + + if (type < 0 || type > TYPE_DEVICE_NAME) { + LOG_ERR("OnNodeBasicInfoChanged invalid type: %d", type); + return SOFTBUS_INVALID_PARAM; + } + + if (pthread_mutex_lock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: lock node basic info cb list in notify"); + } + LIST_FOR_EACH_ENTRY(item, &list->list, NodeStateCallbackItem, node) { + if ((item->cb.events & EVENT_NODE_STATE_INFO_CHANGED) != 0) { + item->cb.onNodeBasicInfoChanged(type, basicInfo); + } + } + if (pthread_mutex_unlock(&g_busCenterClient.lock) != 0) { + LOG_ERR("fail: unlock node basic info cb list in notify"); + } + return SOFTBUS_OK; +} diff --git a/sdk/discovery/BUILD.gn b/sdk/discovery/BUILD.gn new file mode 100755 index 000000000..da5c55204 --- /dev/null +++ b/sdk/discovery/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_client_discovery") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/sdk/frame/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + sources = [ "src/client_disc_manager.c" ] + } +} else { + shared_library("softbus_client_discovery") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/sdk/frame/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ "src/client_disc_manager.c" ] + } +} diff --git a/sdk/discovery/include/client_disc_manager.h b/sdk/discovery/include/client_disc_manager.h new file mode 100755 index 000000000..ee30abc1d --- /dev/null +++ b/sdk/discovery/include/client_disc_manager.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_SERVICE_MANAGER_H +#define SOFTBUS_CLIENT_SERVICE_MANAGER_H + +#include "discovery_service.h" +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t DiscClientInit(void); +int32_t DiscClientDeInit(void); + +void DiscClientOnDeviceFound(const DeviceInfo *device); +void DiscClientOnDiscoverySuccess(int32_t subscribeId); +void DiscClientOnDiscoverFailed(int32_t subscribeId, DiscoveryFailReason failReason); +void DiscClientOnPublishSuccess(int32_t publishId); +void DiscClientOnPublishFail(int32_t publishId, PublishFailReason reason); + +#ifdef __cplusplus +} +#endif + +#endif // SOFTBUS_CLIENT_SERVICE_MANAGER_H diff --git a/sdk/discovery/src/client_disc_manager.c b/sdk/discovery/src/client_disc_manager.c new file mode 100755 index 000000000..54e8ff34f --- /dev/null +++ b/sdk/discovery/src/client_disc_manager.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_disc_manager.h" +#include "securec.h" +#include "softbus.h" +#include "softbus_client_frame_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" +#include "stdbool.h" + +typedef struct { + IPublishCallback publishCb; + IDiscoveryCallback subscribeCb; + pthread_mutex_t lock; +} DiscInfo; + +static DiscInfo *g_discInfo = NULL; +static bool g_isInited = false; + +static int32_t PublishInfoCheck(const PublishInfo *info) +{ + if ((info->mode != DISCOVER_MODE_PASSIVE) && (info->mode != DISCOVER_MODE_ACTIVE)) { + LOG_ERR("mode is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->medium < AUTO) || (info->medium > COAP)) { + LOG_ERR("medium is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + LOG_ERR("freq is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + LOG_ERR("data is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + LOG_ERR("data exceeds the maximum length"); + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static int32_t SubscribeInfoCheck(const SubscribeInfo *info) +{ + if ((info->mode != DISCOVER_MODE_PASSIVE) && (info->mode != DISCOVER_MODE_ACTIVE)) { + LOG_ERR("mode is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->medium < AUTO) || (info->medium > COAP)) { + LOG_ERR("medium is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->freq < LOW) || (info->freq > SUPER_HIGH)) { + LOG_ERR("freq is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if ((info->capabilityData == NULL) && (info->dataLen != 0)) { + LOG_ERR("data is invalid"); + return SOFTBUS_INVALID_PARAM; + } + + if (info->dataLen == 0) { + return SOFTBUS_OK; + } + + if ((info->dataLen > MAX_CAPABILITYDATA_LEN) || + (strlen((char *)(info->capabilityData)) >= MAX_CAPABILITYDATA_LEN)) { + LOG_ERR("data exceeds the maximum length"); + return SOFTBUS_INVALID_PARAM; + } + + return SOFTBUS_OK; +} + +static int32_t CheckPackageName(const char *packageName) +{ + char clientPackageName[PKG_NAME_SIZE_MAX] = {0}; + if (GetSoftBusClientName(clientPackageName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { + LOG_ERR("GetSoftBusClientName failed!"); + return SOFTBUS_DISCOVER_INVALID_PKGNAME; + } + if (strcmp(clientPackageName, packageName) == 0) { + return SOFTBUS_OK; + } + return SOFTBUS_DISCOVER_INVALID_PKGNAME; +} + +static int32_t AddPublishInfo(const IPublishCallback *cb) +{ + if (pthread_mutex_lock(&(g_discInfo->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + + if (memcpy_s(&(g_discInfo->publishCb), sizeof(IPublishCallback), cb, sizeof(IPublishCallback)) != EOK) { + (void)pthread_mutex_unlock(&(g_discInfo->lock)); + LOG_ERR("memcpy failed"); + return SOFTBUS_MEM_ERR; + } + (void)pthread_mutex_unlock(&(g_discInfo->lock)); + + return SOFTBUS_OK; +} + +static int32_t AddSubscribeInfo(const IDiscoveryCallback *cb) +{ + if (pthread_mutex_lock(&(g_discInfo->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + + if (memcpy_s(&(g_discInfo->subscribeCb), sizeof(IDiscoveryCallback), cb, sizeof(IDiscoveryCallback)) != EOK) { + (void)pthread_mutex_unlock(&(g_discInfo->lock)); + LOG_ERR("memcpy failed"); + return SOFTBUS_MEM_ERR; + } + (void)pthread_mutex_unlock(&(g_discInfo->lock)); + + return SOFTBUS_OK; +} + +int32_t PublishService(const char *packageName, const PublishInfo *info, const IPublishCallback *cb) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX) || (info == NULL) || (cb == NULL)) { + return SOFTBUS_INVALID_PARAM; + } + + if (InitSoftBus(packageName) != SOFTBUS_OK) { + LOG_ERR("init softbus err"); + return SOFTBUS_DISCOVER_NOT_INIT; + } + + if (PublishInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = CheckPackageName(packageName); + if (ret != SOFTBUS_OK) { + return ret; + } + + ret = AddPublishInfo(cb); + if (ret != SOFTBUS_OK) { + return ret; + } + + ret = GetServerProvideInterface()->publishService(packageName, info); + if (ret != SOFTBUS_OK) { + LOG_ERR("Server PublishService failed, ret = %d", ret); + return ret; + } + return SOFTBUS_OK; +} + +int32_t UnPublishService(const char *packageName, int32_t publishId) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX)) { + LOG_ERR("invalid packageName"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_NOT_INIT; + } + + int32_t ret = CheckPackageName(packageName); + if (ret != SOFTBUS_OK) { + LOG_ERR("check packageName failed, ret = %d", ret); + return ret; + } + + ret = GetServerProvideInterface()->unPublishService(packageName, publishId); + if (ret != SOFTBUS_OK) { + LOG_ERR("Server UnPublishService failed, ret = %d", ret); + return ret; + } + + return SOFTBUS_OK; +} + +int32_t StartDiscovery(const char *packageName, const SubscribeInfo *info, const IDiscoveryCallback *cb) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX) || (info == NULL) || (cb == NULL)) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (InitSoftBus(packageName) != SOFTBUS_OK) { + LOG_ERR("init softbus err"); + return SOFTBUS_DISCOVER_NOT_INIT; + } + + if (SubscribeInfoCheck(info) != SOFTBUS_OK) { + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = CheckPackageName(packageName); + if (ret != SOFTBUS_OK) { + return ret; + } + + ret = AddSubscribeInfo(cb); + if (ret != SOFTBUS_OK) { + return ret; + } + + ret = GetServerProvideInterface()->startDiscovery(packageName, info); + if (ret != SOFTBUS_OK) { + LOG_ERR("Server StartDiscovery failed, ret = %d", ret); + return ret; + } + + return SOFTBUS_OK; +} + +int32_t StopDiscovery(const char *packageName, int32_t subscribeId) +{ + if ((packageName == NULL) || (strlen(packageName) >= PKG_NAME_SIZE_MAX)) { + LOG_ERR("invalid packageName"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_isInited == false) { + LOG_ERR("not init"); + return SOFTBUS_DISCOVER_NOT_INIT; + } + + int32_t ret = CheckPackageName(packageName); + if (ret != SOFTBUS_OK) { + return ret; + } + + ret = GetServerProvideInterface()->stopDiscovery(packageName, subscribeId); + if (ret != SOFTBUS_OK) { + LOG_ERR("Server StopDiscovery failed, ret = %d", ret); + return ret; + } + + return SOFTBUS_OK; +} + +int32_t DiscClientInit(void) +{ + if (g_isInited == true) { + LOG_INFO("Module has been initialised"); + return SOFTBUS_OK; + } + g_discInfo = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo)); + if (g_discInfo == NULL) { + LOG_ERR("Calloc failed"); + return SOFTBUS_MALLOC_ERR; + } + pthread_mutex_init(&(g_discInfo->lock), NULL); + g_isInited = true; + LOG_INFO("Init success"); + return SOFTBUS_OK; +} + +int32_t DiscClientDeInit(void) +{ + if (g_isInited == false) { + LOG_ERR("Module hsa not been initialised"); + return SOFTBUS_DISCOVER_NOT_INIT; + } + pthread_mutex_destroy(&g_discInfo->lock); + SoftBusFree(g_discInfo); + g_discInfo = NULL; + g_isInited = false; + LOG_INFO("DeInit success"); + return SOFTBUS_OK; +} + +void DiscClientOnDeviceFound(const DeviceInfo *device) +{ + g_discInfo->subscribeCb.OnDeviceFound(device); +} + +void DiscClientOnDiscoverySuccess(int32_t subscribeId) +{ + g_discInfo->subscribeCb.OnDiscoverySuccess(subscribeId); +} + +void DiscClientOnDiscoverFailed(int32_t subscribeId, DiscoveryFailReason failReason) +{ + g_discInfo->subscribeCb.OnDiscoverFailed(subscribeId, failReason); +} + +void DiscClientOnPublishSuccess(int32_t publishId) +{ + g_discInfo->publishCb.OnPublishSuccess(publishId); +} + +void DiscClientOnPublishFail(int32_t publishId, PublishFailReason reason) +{ + g_discInfo->publishCb.OnPublishFail(publishId, reason); +} diff --git a/sdk/frame/BUILD.gn b/sdk/frame/BUILD.gn new file mode 100755 index 000000000..d3550b3b6 --- /dev/null +++ b/sdk/frame/BUILD.gn @@ -0,0 +1,90 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_client_frame") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/sdk/include", + "$dsoftbus_root_path/sdk/discovery/include", + "$dsoftbus_root_path/sdk/transmission/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/interfaces/kits/bus_center", + + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/core/transmission/pending_packet/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + sources = [ + "$dsoftbus_root_path/core/common/inner_communication/c/softbus_client_interface_impl.c", + "$dsoftbus_root_path/core/common/inner_communication/c/softbus_server_interface.c", + "softbus_client_event_manager.c", + "softbus_client_frame_manager.c", + "softbus_client_frame_manager_weak.c", + ] + } +} else { + shared_library("softbus_client_frame") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/sdk/include", + "$dsoftbus_root_path/sdk/discovery/include", + "$dsoftbus_root_path/sdk/transmission/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/inner_communication/ipc/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/interfaces/kits/bus_center", + + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//third_party/bounds_checking_function/include", + "//foundation/communication/ipc_lite/interfaces/kits", + "//utils/native/lite/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + + sources = [ + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_client_interface_impl.c", + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_client_weak.c", + "$dsoftbus_root_path/core/common/inner_communication/ipc/softbus_server_interface.c", + "softbus_client_event_manager.c", + "softbus_client_frame_manager.c", + "softbus_client_frame_manager_weak.c", + ] + + deps = [ + "$dsoftbus_root_path/core/common/utils:softbus_utils", + "$dsoftbus_root_path/core/transmission/pending_packet:trans_pending", + "//foundation/communication/ipc_lite:liteipc", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + ] + } +} diff --git a/sdk/frame/include/softbus_client_event_manager.h b/sdk/frame/include/softbus_client_event_manager.h new file mode 100755 index 000000000..a538af34b --- /dev/null +++ b/sdk/frame/include/softbus_client_event_manager.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_EVENT_MANAGER_H +#define SOFTBUS_CLIENT_EVENT_MANAGER_H + +#include "softbus.h" +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void CLIENT_NotifyObserver(enum SoftBusEvent event, void *arg, unsigned int argLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/frame/include/softbus_client_frame_manager.h b/sdk/frame/include/softbus_client_frame_manager.h new file mode 100755 index 000000000..f734923b6 --- /dev/null +++ b/sdk/frame/include/softbus_client_frame_manager.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_FRAME_MANAGER_H +#define SOFTBUS_CLIENT_FRAME_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void SetClientIdentity(unsigned int handle, unsigned int token, unsigned int cookie, void *ctx); +int GetClientIdentity(unsigned int *handle, unsigned int *token, unsigned int *cookie, void **ctx); +int GetSoftBusClientName(char *name, unsigned int len); +int InitSoftBus(const char *pkgName); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/sdk/frame/include/softbus_client_frame_manager_weak.h b/sdk/frame/include/softbus_client_frame_manager_weak.h new file mode 100755 index 000000000..15b78cdb3 --- /dev/null +++ b/sdk/frame/include/softbus_client_frame_manager_weak.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_CLIENT_FRAME_MANAGER_WEAK_H +#define SOFTBUS_CLIENT_FRAME_MANAGER_WEAK_H + +#ifdef __cplusplus +extern "C" { +#endif + +int __attribute__ ((weak)) EventClientInit(void); +void __attribute__ ((weak))EventClientDeinit(void); + +int __attribute__ ((weak)) BusCenterClientInit(void); +void __attribute__ ((weak))BusCenterClientDeinit(void); + +int __attribute__ ((weak)) DiscClientInit(void); +void __attribute__ ((weak)) DiscClientDeinit(void); + +int __attribute__ ((weak)) TransClientInit(void); +void __attribute__ ((weak))TransClientDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif // SOFTBUS_CLIENT_FRAME_MANAGER_WEAK_H + diff --git a/sdk/frame/softbus_client_event_manager.c b/sdk/frame/softbus_client_event_manager.c new file mode 100755 index 000000000..0e9771c9a --- /dev/null +++ b/sdk/frame/softbus_client_event_manager.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_event_manager.h" + +#include "securec.h" +#include "softbus.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +#define MAX_OBSERVER_CNT 128 + +typedef struct { + ListNode node; + enum SoftBusEvent event; + EventCallback callback; + char *userData; +} Observer; + +static SoftBusList *g_observerList = NULL; +static bool g_isInited = false; + +int EventClientInit(void) +{ + if (g_isInited) { + return SOFTBUS_OK; + } + + g_observerList = CreateSoftBusList(); + if (g_observerList == NULL) { + LOG_ERR("create observer list failed"); + return SOFTBUS_ERR; + } + + g_isInited = true; + return SOFTBUS_OK; +} + +void EventClientDeinit(void) +{ + if (!g_isInited) { + LOG_ERR("event client not init"); + return; + } + + if (g_observerList) { + DestroySoftBusList(g_observerList); + g_observerList = NULL; + } + + g_isInited = false; +} + +static bool IsEventValid(enum SoftBusEvent event) +{ + if (event < EVENT_SERVER_DEATH || event >= EVENT_BUTT) { + return false; + } + return true; +} + +int RegisterEventCallback(enum SoftBusEvent event, EventCallback cb, void *userData) +{ + if (!IsEventValid(event) || cb == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + if (g_isInited != true) { + LOG_ERR("event manager not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&g_observerList->lock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + if (g_observerList->cnt >= MAX_OBSERVER_CNT) { + LOG_ERR("observer count over limit"); + (void)pthread_mutex_unlock(&g_observerList->lock); + return SOFTBUS_ERR; + } + + Observer *observer = (Observer *)SoftBusMalloc(sizeof(Observer)); + if (observer == NULL) { + LOG_ERR("malloc observer failed"); + (void)pthread_mutex_unlock(&g_observerList->lock); + return SOFTBUS_ERR; + } + + observer->event = event; + observer->callback = cb; + observer->userData = userData; + + ListInit(&observer->node); + ListAdd(&g_observerList->list, &observer->node); + g_observerList->cnt++; + (void)pthread_mutex_unlock(&g_observerList->lock); + + return SOFTBUS_OK; +} + +void CLIENT_NotifyObserver(enum SoftBusEvent event, void *arg, unsigned int argLen) +{ + if (!IsEventValid(event)) { + LOG_ERR("invalid event [%d]", event); + return; + } + + if (g_isInited != true) { + LOG_ERR("event manager not init"); + return; + } + + Observer *observer = NULL; + if (pthread_mutex_lock(&g_observerList->lock) != 0) { + LOG_ERR("lock failed"); + return; + } + + LIST_FOR_EACH_ENTRY(observer, &g_observerList->list, Observer, node) { + if ((observer->event == event) && + (observer->callback != NULL) && + (observer->callback(arg, argLen, observer->userData) != SOFTBUS_OK)) { + LOG_ERR("execute callback failed [%d]", event); + } + } + + (void)pthread_mutex_unlock(&g_observerList->lock); +} diff --git a/sdk/frame/softbus_client_frame_manager.c b/sdk/frame/softbus_client_frame_manager.c new file mode 100755 index 000000000..dc82172cc --- /dev/null +++ b/sdk/frame/softbus_client_frame_manager.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_frame_manager.h" + +#include "securec.h" +#include "softbus_client_frame_manager_weak.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" +#ifndef SOFTBUS_WATCH +#include "trans_pending_pkt.h" +#endif +struct SoftBusClientContext { + char serviceName[PKG_NAME_SIZE_MAX]; + unsigned int handle; + unsigned int token; + unsigned int cookie; + void *ctx; +}; + +static struct SoftBusClientContext *g_clientCtx = NULL; +static bool g_isInited = false; +static pthread_mutex_t g_isInitedLock = PTHREAD_MUTEX_INITIALIZER; + +static void ClientModuleDeinit(void) +{ + EventClientDeinit(); + BusCenterClientDeinit(); + DiscClientDeinit(); + TransClientDeinit(); +#ifndef SOFTBUS_WATCH + PendingDeinit(PENDING_TYPE_DIRECT); +#endif +} + +void SetClientIdentity(unsigned int handle, unsigned int token, unsigned int cookie, void *ctx) +{ + if (g_clientCtx == NULL) { + LOG_ERR("client ctx not init"); + return; + } + + g_clientCtx->handle = handle; + g_clientCtx->token = token; + g_clientCtx->cookie = cookie; + g_clientCtx->ctx = ctx; +} + +int GetClientIdentity(unsigned int *handle, unsigned int *token, unsigned int *cookie, void **ctx) +{ + if (handle == NULL || token == NULL || cookie == NULL || ctx == NULL) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + if (g_clientCtx == NULL) { + LOG_ERR("client ctx not init"); + return SOFTBUS_ERR; + } + + *handle = g_clientCtx->handle; + *token = g_clientCtx->token; + *cookie = g_clientCtx->cookie; + *ctx = g_clientCtx->ctx; + + return SOFTBUS_OK; +} + +int GetSoftBusClientName(char *name, unsigned int len) +{ + if (name == NULL || len < PKG_NAME_SIZE_MAX) { + LOG_ERR("invalid param"); + return SOFTBUS_ERR; + } + + if (g_clientCtx == NULL) { + LOG_ERR("ctx not init"); + return SOFTBUS_ERR; + } + + if (strncpy_s(name, len, g_clientCtx->serviceName, strlen(g_clientCtx->serviceName)) != EOK) { + LOG_ERR("strcpy fail"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +static int ClientModuleInit(const char *pkgName) +{ + g_clientCtx = SoftBusCalloc(sizeof(struct SoftBusClientContext)); + if (g_clientCtx == NULL) { + LOG_ERR("init ctx fail"); + return SOFTBUS_ERR; + } + + if (strcpy_s(g_clientCtx->serviceName, sizeof(g_clientCtx->serviceName), pkgName) != EOK) { + LOG_ERR("strcpy fail"); + SoftBusFree(g_clientCtx); + return SOFTBUS_ERR; + } + + if (EventClientInit() == SOFTBUS_ERR) { + LOG_ERR("init event manager failed"); + goto ERR_EXIT; + } + + if (BusCenterClientInit() == SOFTBUS_ERR) { + LOG_ERR("init bus center failed"); + goto ERR_EXIT; + } + + if (DiscClientInit() == SOFTBUS_ERR) { + LOG_ERR("init service manager failed"); + goto ERR_EXIT; + } + + if (TransClientInit() == SOFTBUS_ERR) { + LOG_ERR("init connect manager failed"); + goto ERR_EXIT; + } +#ifndef SOFTBUS_WATCH + if (PendingInit(PENDING_TYPE_DIRECT) == SOFTBUS_ERR) { + LOG_ERR("trans pending init failed.s"); + goto ERR_EXIT; + } +#endif + return SOFTBUS_OK; + +ERR_EXIT: + LOG_ERR("softbus sdk frame init failed."); + ClientModuleDeinit(); + SoftBusFree(g_clientCtx); + g_clientCtx = NULL; + return SOFTBUS_ERR; +} + +int InitSoftBus(const char *pkgName) +{ + if (pkgName == NULL || strlen(pkgName) >= PKG_NAME_SIZE_MAX) { + LOG_ERR("init softbus sdk fail."); + return SOFTBUS_ERR; + } + + if (g_isInited == true) { + return SOFTBUS_OK; + } + + if (pthread_mutex_lock(&g_isInitedLock) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (g_isInited == true) { + pthread_mutex_unlock(&g_isInitedLock); + return SOFTBUS_OK; + } + + if (ClientModuleInit(pkgName) != SOFTBUS_OK) { + LOG_ERR("ctx init fail"); + pthread_mutex_unlock(&g_isInitedLock); + return SOFTBUS_ERR; + } + + if (ServerProvideInterfaceInit() != SOFTBUS_OK) { + LOG_ERR("service init fail"); + pthread_mutex_unlock(&g_isInitedLock); + return SOFTBUS_ERR; + } + + if (ClientProvideInterfaceImplInit() != SOFTBUS_OK) { + LOG_ERR("service init fail"); + pthread_mutex_unlock(&g_isInitedLock); + return SOFTBUS_ERR; + } + + g_isInited = true; + pthread_mutex_unlock(&g_isInitedLock); + LOG_INFO("softbus sdk frame init success."); + return SOFTBUS_OK; +} + diff --git a/sdk/frame/softbus_client_frame_manager_weak.c b/sdk/frame/softbus_client_frame_manager_weak.c new file mode 100755 index 000000000..3e9c8770d --- /dev/null +++ b/sdk/frame/softbus_client_frame_manager_weak.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_client_frame_manager_weak.h" +#include "softbus_errcode.h" + +int __attribute__ ((weak)) EventClientInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak))EventClientDeinit(void) +{ +} + +int __attribute__ ((weak)) BusCenterClientInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak))BusCenterClientDeinit(void) +{ +} + +int __attribute__ ((weak)) DiscClientInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) DiscClientDeinit(void) +{ +} + +int __attribute__ ((weak)) TransClientInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak))TransClientDeinit(void) +{ +} + diff --git a/sdk/transmission/BUILD.gn b/sdk/transmission/BUILD.gn new file mode 100644 index 000000000..3f2714bc7 --- /dev/null +++ b/sdk/transmission/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +lite_component("softbus_client_transmission") { + features = [ + "session:softbus_client_trans_session", + "trans_channel:softbus_client_trans_channel", + ] +} diff --git a/sdk/transmission/session/BUILD.gn b/sdk/transmission/session/BUILD.gn new file mode 100755 index 000000000..4af6c0850 --- /dev/null +++ b/sdk/transmission/session/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_client_trans_session") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/sdk/frame/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "src/client_trans_message_service.c", + "src/client_trans_session_callback.c", + "src/client_trans_session_manager.c", + "src/client_trans_session_service.c", + ] + } +} else { + shared_library("softbus_client_trans_session") { + include_dirs = [ + "include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/sdk/frame/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/manager/include", + "//third_party/bounds_checking_function/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + ] + sources = [ + "src/client_trans_message_service.c", + "src/client_trans_session_callback.c", + "src/client_trans_session_manager.c", + "src/client_trans_session_service.c", + ] + } +} diff --git a/sdk/transmission/session/cpp/include/CommDefs.h b/sdk/transmission/session/cpp/include/CommDefs.h new file mode 100755 index 000000000..07ed43842 --- /dev/null +++ b/sdk/transmission/session/cpp/include/CommDefs.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMM_DEFS_H +#define COMM_DEFS_H + +#define COMM_UNUSED __attribute__((unused)) +#define COMM_EXPORT __attribute__((visibility("default"))) + +#define NO_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &) = delete; \ + TypeName(TypeName &&) = delete; \ + TypeName &operator = (const TypeName &) = delete; \ + TypeName &operator = (TypeName &&) = delete; +#endif // COMM_DEFS_H diff --git a/sdk/transmission/session/cpp/include/ISessionListener.h b/sdk/transmission/session/cpp/include/ISessionListener.h new file mode 100755 index 000000000..d2a64a7a3 --- /dev/null +++ b/sdk/transmission/session/cpp/include/ISessionListener.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ISESSION_LISTENER_H +#define ISESSION_LISTENER_H + +#include +#include "CommDefs.h" +#include "Session.h" + +namespace Communication { +namespace SoftBus { +class COMM_EXPORT ISessionListener { +public: + ISessionListener() = default; + virtual ~ISessionListener() = default; + + virtual int OnSessionOpened(std::shared_ptr session) = 0; + + virtual void OnSessionClosed(std::shared_ptr session) = 0; + + virtual void OnMessageReceived(std::shared_ptr session, const char *data, ssize_t len) = 0; + + virtual void OnBytesReceived(std::shared_ptr session, const char *data, ssize_t len) = 0; + + virtual bool OnDataAvailable(std::shared_ptr session, uint32_t status) = 0; +}; +} // namespace SoftBus +} // namespace Communication + +#endif // ISESSION_LISTENER_H diff --git a/sdk/transmission/session/cpp/include/ISessionService.h b/sdk/transmission/session/cpp/include/ISessionService.h new file mode 100755 index 000000000..7b9a005ce --- /dev/null +++ b/sdk/transmission/session/cpp/include/ISessionService.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ISESSION_SERVICE_H +#define ISESSION_SERVICE_H + +#include +#include "CommDefs.h" +#include "ISessionListener.h" +#include "Session.h" + +namespace Communication { +namespace SoftBus { +class COMM_EXPORT ISessionService { +public: + static std::shared_ptr GetInstance(); + + ISessionService() = default; + virtual ~ISessionService() = default; + + virtual int CreateSessionServer(const std::string &pkgName, const std::string &sessionName, + std::shared_ptr listener) = 0; + + virtual int RemoveSessionServer(const std::string &pkgName, const std::string &sessionName) = 0; + + virtual std::shared_ptr OpenSession(const std::string &mySessionName, const std::string &peerSessionName, + const std::string &peerDeviceId, const std::string &groupId, int flags) = 0; + + virtual int CloseSession(std::shared_ptr session) = 0; + + virtual int GrantPermission(int uid, int pid, const std::string &busName) = 0; + +private: + NO_COPY_AND_ASSIGN(ISessionService) + static std::shared_ptr instance_; + static std::shared_mutex instanceMutex_; +}; +} // namespace SoftBus +} // namespace Communication + +#endif // ISESSION_SERVICE_H diff --git a/sdk/transmission/session/cpp/include/Session.h b/sdk/transmission/session/cpp/include/Session.h new file mode 100755 index 000000000..fa035e2a5 --- /dev/null +++ b/sdk/transmission/session/cpp/include/Session.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_H +#define SESSION_H + +#include +#include +#include +#include "CommDefs.h" + +namespace Communication { +namespace SoftBus { +class COMM_EXPORT Session { +public: + enum { + TYPE_MESSAGE = 0x01, + TYPE_BYTES = 0x02, + TYPE_FILE = 0x04, + TYPE_STREAM = 0x08, + }; + + enum RouteType { + WIFI_STA = 1, + WIFI_P2P = 2, + BT_BR = 3, + BT_BLE = 4, + LOOPBACK = 5, + }; + + enum SessionStatus { + INIT, + OPENING, + OPENED, + CONNECTING, + CONNECTED, + CLOSING, + CLOSED, + }; + + Session() = default; + virtual ~Session() = default; + + virtual const std::string &GetMySessionName() const = 0; + + virtual const std::string &GetPeerSessionName() const = 0; + + virtual const std::string &GetDeviceId() const = 0; + + virtual const std::string &GetPeerDeviceId() const = 0; + + virtual int64_t GetChannelId() const = 0; + + virtual uid_t GetPeerUid() const = 0; + + virtual pid_t GetPeerPid() const = 0; + + virtual bool IsServerSide() const = 0; + + virtual int SendBytes(const void *buf, ssize_t len) const = 0; + + virtual int GetSessionId() const = 0; + + virtual void SetSessionId(int sessionId) = 0; + + virtual void SetMySessionName(const std::string &name) = 0; + + virtual void SetPeerSessionName(const std::string &name) = 0; + + virtual void SetPeerDeviceId(const std::string &name) = 0; + + virtual void SetDeviceId(const std::string &name) = 0; + + virtual void SetIsServer(bool isServer) = 0; + + virtual void SetPeerUid(uid_t peerUid) = 0; + + virtual void SetPeerPid(pid_t peerPid) = 0; + +private: + NO_COPY_AND_ASSIGN(Session) +}; +} // namespace SoftBus +} // namespace Communication + +#endif // SESSION_H diff --git a/sdk/transmission/session/cpp/src/session_callback_mock.cpp b/sdk/transmission/session/cpp/src/session_callback_mock.cpp new file mode 100755 index 000000000..e3da55382 --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_callback_mock.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_callback_mock.h" + +#include "Session.h" +#include "session_service_impl.h" + +using namespace Communication::SoftBus; + +int InnerOnSessionOpened(int sessionId, int result) +{ + SessionServiceImpl sessionImpl; + return sessionImpl.OpenSessionCallback(sessionId); +} + +void InnerOnSessionClosed(int sessionId) +{ + SessionServiceImpl sessionImpl; + sessionImpl.CloseSessionCallback(sessionId); +} + +void InnerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen) +{ + SessionServiceImpl sessionImpl; + sessionImpl.BytesReceivedCallback(sessionId, data, dataLen); +} + +void InnerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen) +{ + SessionServiceImpl sessionImpl; + sessionImpl.MessageReceivedCallback(sessionId, data, dataLen); +} \ No newline at end of file diff --git a/sdk/transmission/session/cpp/src/session_callback_mock.h b/sdk/transmission/session/cpp/src/session_callback_mock.h new file mode 100755 index 000000000..edb7e6753 --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_callback_mock.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_CALLBACK_MOCK_H +#define SESSION_CALLBACK_MOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +int InnerOnSessionOpened(int sessionId, int result); + +void InnerOnSessionClosed(int sessionId); + +void InnerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen); + +void InnerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen); + +#ifdef __cplusplus +} +#endif +#endif // SESSION_CALLBACK_MOCK_H \ No newline at end of file diff --git a/sdk/transmission/session/cpp/src/session_impl.cpp b/sdk/transmission/session/cpp/src/session_impl.cpp new file mode 100755 index 000000000..a0aca0818 --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_impl.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_impl.h" + +#include "session.h" +#include "session_mock.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +namespace Communication { +namespace SoftBus { +SessionImpl::SessionImpl() : sessionId_(-1), isServer_(false), peerUid_(-1), peerPid_(-1) {} + +int64_t SessionImpl::GetChannelId() const +{ + return sessionId_; +} + +void SessionImpl::SetSessionId(int sessionId) +{ + sessionId_ = sessionId; +} + +int SessionImpl::GetSessionId() const +{ + return sessionId_; +} + +void SessionImpl::SetMySessionName(const std::string &name) +{ + sessionName_ = name; +} + +const std::string &SessionImpl::GetMySessionName() const +{ + return sessionName_; +} + +void SessionImpl::SetPeerSessionName(const std::string &name) +{ + peerSessionName_ = name; +} + +const std::string &SessionImpl::GetPeerSessionName() const +{ + return peerSessionName_; +} + +void SessionImpl::SetPeerDeviceId(const std::string &name) +{ + peerDeviceId_ = name; +} + +const std::string &SessionImpl::GetPeerDeviceId() const +{ + return peerDeviceId_; +} + + +void SessionImpl::SetDeviceId(const std::string &name) +{ + deviceId_ = name; +} + +void SessionImpl::SetIsServer(bool isServer) +{ + isServer_ = isServer; +} + +void SessionImpl::SetPeerUid(uid_t peerUid) +{ + peerUid_ = peerUid; +} + +void SessionImpl::SetPeerPid(pid_t peerPid) +{ + peerPid_ = peerPid; +} + +const std::string &SessionImpl::GetDeviceId() const +{ + return deviceId_; +} + +uid_t SessionImpl::GetPeerUid() const +{ + return peerUid_; +} + +pid_t SessionImpl::GetPeerPid() const +{ + return peerPid_; +} + +bool SessionImpl::IsServerSide() const +{ + return isServer_; +} + +int SessionImpl::SendBytes(const void *buf, ssize_t len) const +{ + if (buf == nullptr || len <= 0 || len > MAX_BYTES_LENGTH) { + LOG_ERR("Invalid params"); + return SOFTBUS_ERR; + } + return SendBytesInner(sessionId_, buf, len); +} +} // namespace SoftBus +} // namespace Communication diff --git a/sdk/transmission/session/cpp/src/session_impl.h b/sdk/transmission/session/cpp/src/session_impl.h new file mode 100755 index 000000000..8211937a7 --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_impl.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_IMPL_H +#define SESSION_IMPL_H + +#include +#include +#include +#include +#include +#include "CommDefs.h" +#include "ISessionListener.h" + +namespace Communication { +namespace SoftBus { +class SessionImpl : public std::enable_shared_from_this, public Session { +public: + static constexpr int TYPE_MSG = 1; + + static constexpr int TYPE_BYTES = 2; + + static constexpr int TYPE_FILE = 4; + + SessionImpl(); + + ~SessionImpl() override = default; + + int GetSessionId() const override; + + void SetSessionId(int sessionId) override; + + void SetMySessionName(const std::string &name) override; + + const std::string &GetMySessionName() const override; + + void SetPeerSessionName(const std::string &name) override; + + const std::string &GetPeerSessionName() const override; + + void SetPeerDeviceId(const std::string &name) override; + + const std::string &GetPeerDeviceId() const override; + + const std::string &GetDeviceId() const override; + + void SetDeviceId(const std::string &name) override; + + void SetIsServer(bool isServer) override; + + void SetPeerUid(uid_t peerUid) override; + + void SetPeerPid(pid_t peerPid) override; + + int64_t GetChannelId() const override; + + uid_t GetPeerUid() const override; + + pid_t GetPeerPid() const override; + + bool IsServerSide() const override; + + int SendBytes(const void *buf, ssize_t len) const override; + +private: + NO_COPY_AND_ASSIGN(SessionImpl) + + const int MAX_BYTES_LENGTH = 128 * 1024 * 1024; + const std::string nullString_ = ""; + const std::string noSession_ = "[Session]null"; + + int sessionId_; + std::string sessionName_; + std::string peerSessionName_; + std::string deviceId_; + std::string peerDeviceId_; + bool isServer_; + uid_t peerUid_; + pid_t peerPid_; +}; +} // namespace SoftBus +} // namespace Communication + +#endif // SESSION_IMPL_H diff --git a/sdk/transmission/session/cpp/src/session_mock.cpp b/sdk/transmission/session/cpp/src/session_mock.cpp new file mode 100755 index 000000000..518711085 --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_mock.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_mock.h" + +#include "client_trans_session_manager.h" +#include "session.h" +#include "session_callback_mock.h" + +static ISessionListener g_innerSessionListener = { + .OnSessionOpened = InnerOnSessionOpened, + .OnSessionClosed = InnerOnSessionClosed, + .OnBytesReceived = InnerOnBytesReceived, + .OnMessageReceived = InnerOnMessageReceived, +}; + +int CreateSessionServerInner(const char *pkgName, const char *sessionName) +{ + return CreateSessionServer(pkgName, sessionName, &g_innerSessionListener); +} + +int RemoveSessionServerInner(const char *pkgName, const char *sessionName) +{ + return RemoveSessionServer(pkgName, sessionName); +} + +int OpenSessionInner(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int flag) +{ + SessionAttribute attr = {flag}; + return OpenSession(mySessionName, peerSessionName, peerDeviceId, groupId, &attr); +} + +void CloseSessionInner(int sessionId) +{ + return CloseSession(sessionId); +} + +int32_t SendBytesInner(int32_t sessionId, const void *data, uint32_t len) +{ + return SendBytes(sessionId, data, len); +} + +int32_t GetPeerUidInner(int32_t sessionId, int *data) +{ + return ClientGetSessionIntegerDataById(sessionId, data, KEY_PEER_UID); +} + +int32_t GetPeerPidInner(int32_t sessionId, int *data) +{ + return ClientGetSessionIntegerDataById(sessionId, data, KEY_PEER_PID); +} + +int32_t IsServerSideInner(int32_t sessionId, int *data) +{ + return ClientGetSessionIntegerDataById(sessionId, data, KEY_IS_SERVER); +} + +int32_t GetMySessionNameInner(int32_t sessionId, char *data, uint16_t len) +{ + return ClientGetSessionDataById(sessionId, data, len, KEY_SESSION_NAME); +} + +int32_t GetPeerSessionNameInner(int32_t sessionId, char *data, uint16_t len) +{ + return ClientGetSessionDataById(sessionId, data, len, KEY_PEER_SESSION_NAME); +} + +int32_t GetPeerDeviceIdInner(int32_t sessionId, char *data, uint16_t len) +{ + return ClientGetSessionDataById(sessionId, data, len, KEY_PEER_DEVICE_ID); +} \ No newline at end of file diff --git a/sdk/transmission/session/cpp/src/session_mock.h b/sdk/transmission/session/cpp/src/session_mock.h new file mode 100755 index 000000000..0a7a2e80b --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_mock.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_MOCK_H +#define SESSION_MOCK_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int CreateSessionServerInner(const char *pkgName, const char *sessionName); +int RemoveSessionServerInner(const char *pkgName, const char *sessionName); +int OpenSessionInner(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, int flag); +void CloseSessionInner(int sessionId); +int32_t SendBytesInner(int32_t sessionId, const void *data, uint32_t len); +int32_t GetPeerUidInner(int32_t sessionId, int *data); +int32_t GetPeerPidInner(int32_t sessionId, int *data); +int32_t IsServerSideInner(int32_t sessionId, int *data); +int32_t GetMySessionNameInner(int32_t sessionId, char *data, uint16_t len); +int32_t GetPeerSessionNameInner(int32_t sessionId, char *data, uint16_t len); +int32_t GetPeerDeviceIdInner(int32_t sessionId, char *data, uint16_t len); +#ifdef __cplusplus +} +#endif +#endif // SESSION_MOCK_H \ No newline at end of file diff --git a/sdk/transmission/session/cpp/src/session_service_impl.cpp b/sdk/transmission/session/cpp/src/session_service_impl.cpp new file mode 100755 index 000000000..bf9c3b37f --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_service_impl.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "session_service_impl.h" + +#include "session_impl.h" +#include "session_mock.h" +#include "softbus_bus_center.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +namespace Communication { +namespace SoftBus { +std::shared_mutex ISessionService::instanceMutex_; +std::shared_ptr ISessionService::instance_ = nullptr; +std::mutex SessionServiceImpl::listenerMutex_; +std::map> SessionServiceImpl::listenerMap_; +std::mutex SessionServiceImpl::sessionMutex_; +std::map> SessionServiceImpl::sessionMap_; + +std::shared_ptr ISessionService::GetInstance() +{ + std::shared_ptr tmp = instance_; + if (tmp == nullptr) { + std::unique_lock instanceLock(instanceMutex_); + tmp = instance_; + if (tmp == nullptr) { + tmp = std::make_shared(); + instance_ = tmp; + } + } + return instance_; +} + +int SessionServiceImpl::CreateSessionServer(const std::string &pkgName, const std::string &sessionName, + std::shared_ptr listener) +{ + if (pkgName.empty() || sessionName.empty() || listener == nullptr) { + LOG_ERR("SessionServiceImpl:CreateSessionServer, invalid parameter"); + return SOFTBUS_ERR; + } + + std::lock_guard autoLock(listenerMutex_); + listenerMap_.insert(std::pair>(sessionName, listener)); + return CreateSessionServerInner(pkgName.c_str(), sessionName.c_str()); +} + +int SessionServiceImpl::RemoveSessionServer(const std::string &pkgName, const std::string &sessionName) +{ + if (pkgName.empty() || sessionName.empty()) { + LOG_ERR("SessionServiceImpl:RemoveSessionServer, invalid parameter"); + return SOFTBUS_ERR; + } + + std::lock_guard autoLock(listenerMutex_); + auto iter = listenerMap_.find(sessionName); + if (iter != listenerMap_.end()) { + listenerMap_.erase(iter); + return RemoveSessionServerInner(pkgName.c_str(), sessionName.c_str()); + } + LOG_ERR("SessionServiceImpl:RemoveSessionServer, not find session server"); + return SOFTBUS_ERR; +} + +std::shared_ptr SessionServiceImpl::OpenSession(const std::string &mySessionName, + const std::string &peerSessionName, const std::string &peerDeviceId, const std::string &groupId, int flags) +{ + if (mySessionName.empty() || peerSessionName.empty() || peerDeviceId.empty()) { + return nullptr; + } + int sessionId = OpenSessionInner(mySessionName.c_str(), peerSessionName.c_str(), + peerDeviceId.c_str(), groupId.c_str(), flags); + if (sessionId < 0 || sessionId > MAX_SESSION_ID) { + LOG_ERR("SessionServiceImpl:OpenSession, invalid sessionId."); + return nullptr; + } + std::shared_ptr session = std::make_shared(); + session->SetSessionId(sessionId); + session->SetMySessionName(mySessionName); + session->SetPeerSessionName(peerSessionName); + session->SetPeerDeviceId(peerDeviceId); + std::lock_guard autoLock(sessionMutex_); + sessionMap_.insert(std::pair>(sessionId, session)); + return session; +} + +int SessionServiceImpl::CloseSession(std::shared_ptr session) +{ + if (session == nullptr) { + LOG_ERR("SessionServiceImpl:CloseSession, invalid parameter"); + return SOFTBUS_ERR; + } + int sessionId = session->GetSessionId(); + if (sessionId < 0 || sessionId > MAX_SESSION_ID) { + LOG_ERR("SessionServiceImpl:OpenSession, invalid sessionId."); + return SOFTBUS_ERR; + } + CloseSessionInner(sessionId); + std::lock_guard autoLock(sessionMutex_); + auto iter = sessionMap_.find(sessionId); + if (iter != sessionMap_.end()) { + sessionMap_.erase(sessionId); + } + return SOFTBUS_OK; +} + +int SessionServiceImpl::GrantPermission(int uid, int pid, const std::string &busName) +{ + if (uid < 0 || pid < 0 || busName.empty()) { + LOG_ERR("SessionServiceImpl:GrantPermission, invalid parameter"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int SessionServiceImpl::CreatNewSession(int sessionId) +{ + std::shared_ptr session = std::make_shared(); + session->SetSessionId(sessionId); + char str[SESSION_NAME_SIZE_MAX]; + int ret = GetMySessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + return ret; + } + std::string mySessionName(str); + session->SetMySessionName(mySessionName); + ret = GetPeerSessionNameInner(sessionId, str, SESSION_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + return ret; + } + std::string peerSessionName(str); + session->SetPeerSessionName(peerSessionName); + ret = GetPeerDeviceIdInner(sessionId, str, SESSION_NAME_SIZE_MAX); + if (ret != SOFTBUS_OK) { + return ret; + } + std::string peerDevId(str); + session->SetPeerDeviceId(peerDevId); + session->SetIsServer(true); + std::lock_guard autoLock(sessionMutex_); + sessionMap_.insert(std::pair>(sessionId, session)); + return SOFTBUS_OK; +} + +int SessionServiceImpl::OpenSessionCallback(int sessionId) +{ + int isServer; + if (IsServerSideInner(sessionId, &isServer) != SOFTBUS_OK) { + return SOFTBUS_ERR; + } + if (isServer && CreatNewSession(sessionId) != SOFTBUS_OK) { + LOG_ERR("OpenSessionCallback create new session failed."); + return SOFTBUS_ERR; + } + std::shared_ptr listener; + std::shared_ptr session; + if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { + LOG_ERR("OpenSessionCallback get session listener failed."); + return SOFTBUS_ERR; + } + NodeBasicInfo info; + int ret = GetLocalNodeDeviceInfo((session->GetMySessionName()).c_str(), &info); + if (ret != SOFTBUS_OK) { + return ret; + } + session->SetDeviceId(info.networkId); + int tmp; + ret = GetPeerUidInner(sessionId, &tmp); + if (ret != SOFTBUS_OK) { + return ret; + } + session->SetPeerUid(static_cast(tmp)); + ret = GetPeerPidInner(sessionId, &tmp); + if (ret != SOFTBUS_OK) { + return ret; + } + session->SetPeerPid(static_cast(tmp)); + return listener->OnSessionOpened(session); +} + +void SessionServiceImpl::CloseSessionCallback(int sessionId) +{ + std::shared_ptr listener; + std::shared_ptr session; + if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { + return; + } + listener->OnSessionClosed(session); +} + +void SessionServiceImpl::BytesReceivedCallback(int sessionId, const void *data, unsigned int len) +{ + std::shared_ptr listener; + std::shared_ptr session; + if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { + return; + } + const char *msg = static_cast(data); + ssize_t lenMsg = static_cast(len); + listener->OnBytesReceived(session, msg, lenMsg); +} + +void SessionServiceImpl::MessageReceivedCallback(int sessionId, const void *data, unsigned int len) +{ + std::shared_ptr listener; + std::shared_ptr session; + if (GetSessionListener(sessionId, listener, session) != SOFTBUS_OK) { + return; + } + const char *msg = static_cast(data); + ssize_t lenMsg = static_cast(len); + listener->OnMessageReceived(session, msg, lenMsg); +} + +int SessionServiceImpl::GetSessionListener(int sessionId, std::shared_ptr &listener, + std::shared_ptr &session) +{ + std::lock_guard autoLock(sessionMutex_); + auto iter = sessionMap_.find(sessionId); + if (iter != sessionMap_.end()) { + session = iter->second; + std::lock_guard autoLock(listenerMutex_); + auto iterListener = listenerMap_.find(session->GetMySessionName()); + if (iterListener != listenerMap_.end()) { + listener = iterListener->second; + return SOFTBUS_OK; + } + } + return SOFTBUS_ERR; +} +} // namespace SoftBus +} // namespace Communication diff --git a/sdk/transmission/session/cpp/src/session_service_impl.h b/sdk/transmission/session/cpp/src/session_service_impl.h new file mode 100755 index 000000000..7dc373e2f --- /dev/null +++ b/sdk/transmission/session/cpp/src/session_service_impl.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_SERVICE_IMPL_H +#define SESSION_SERVICE_IMPL_H + +#include "Session.h" + +#include +#include +#include +#include "ISessionListener.h" +#include "ISessionService.h" + +namespace Communication { +namespace SoftBus { +class SessionServiceImpl : public ISessionService, public std::enable_shared_from_this { +public: + SessionServiceImpl() = default; + + ~SessionServiceImpl() override = default; + + int CreateSessionServer(const std::string &pkgName, const std::string &sessionName, + std::shared_ptr listener) override; + + int RemoveSessionServer(const std::string &pkgName, const std::string &sessionName) override; + + std::shared_ptr OpenSession(const std::string &mySessionName, const std::string &peerSessionName, + const std::string &peerDeviceId, const std::string &groupId, int flags) override; + + int CloseSession(std::shared_ptr session) override; + + int GrantPermission(int uid, int pid, const std::string &busName) override; + + int OpenSessionCallback(int sessionId); + + void CloseSessionCallback(int sessionId); + + void BytesReceivedCallback(int sessionId, const void *data, unsigned int len); + + void MessageReceivedCallback(int sessionId, const void *data, unsigned int len); + +private: + static std::mutex listenerMutex_; + static std::map> listenerMap_; + + static std::mutex sessionMutex_; + static std::map> sessionMap_; + + int GetSessionListener(int sessionId, std::shared_ptr &listener, + std::shared_ptr &session); + int CreatNewSession(int sessionId); +}; +} // namespace SoftBus +} // namespace Communication + +#endif // SESSION_SERVICE_IMPL_H diff --git a/sdk/transmission/session/include/client_trans_message_service.h b/sdk/transmission/session/include/client_trans_message_service.h new file mode 100644 index 000000000..a8e455eb7 --- /dev/null +++ b/sdk/transmission/session/include/client_trans_message_service.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_MESSAGE_SERVICE_H +#define CLIENT_TRANS_MESSAGE_SERVICE_H + +#include "session.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_MESSAGE_SERVICE_H \ No newline at end of file diff --git a/sdk/transmission/session/include/client_trans_session_callback.h b/sdk/transmission/session/include/client_trans_session_callback.h new file mode 100644 index 000000000..a654e4fda --- /dev/null +++ b/sdk/transmission/session/include/client_trans_session_callback.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_SESSION_CALLBACK_H +#define CLIENT_TRANS_SESSION_CALLBACK_H + +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransOnSessionOpened(const char *sessionName, const ChannelInfo *channel, uint32_t flag); + +int32_t TransOnSessionOpenFailed(int32_t channelId); + +int32_t TransOnSessionClosed(int32_t channelId); + +int32_t TransOnDataReceived(int32_t channelId, const void *data, uint32_t len, SessionPktType type); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_SESSION_CALLBACK_H \ No newline at end of file diff --git a/sdk/transmission/session/include/client_trans_session_manager.h b/sdk/transmission/session/include/client_trans_session_manager.h new file mode 100644 index 000000000..0d6c6cef4 --- /dev/null +++ b/sdk/transmission/session/include/client_trans_session_manager.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_SESSION_MANAGER_H +#define CLIENT_TRANS_SESSION_MANAGER_H + +#include "session.h" +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char peerSessionName[SESSION_NAME_SIZE_MAX]; + char peerDeviceId[DEVICE_ID_SIZE_MAX]; + char groupId[GROUP_ID_SIZE_MAX]; + uint32_t flag; // TYPE_MESSAGE & TYPE_BYTES & TYPE_FILE +} SessionTag; + +typedef struct { + ListNode node; + uint16_t timeout; + int32_t sessionId; + int32_t channelId; + ChannelType channelType; + SessionTag info; + bool isServer; + int32_t peerUid; + int32_t peerPid; +} SessionInfo; + +typedef struct { + ListNode node; + SoftBusSecType type; + char sessionName[SESSION_NAME_SIZE_MAX]; + char pkgName[PKG_NAME_SIZE_MAX]; + union { + ISessionListener session; + } listener; + ListNode sessionList; +} ClientSessionServer; + +typedef struct { + const char *sessionName; + const char *peerSessionName; + const char *peerDeviceId; + const char *groupId; + const SessionAttribute* attr; +} SessionParam; + +typedef enum { + KEY_SESSION_NAME = 1, + KEY_PEER_SESSION_NAME, + KEY_PEER_DEVICE_ID, + KEY_IS_SERVER, + KEY_PEER_PID, + KEY_PEER_UID, +} SessionKey; + +int32_t ClientAddNewSession(const char* sessionName, SessionInfo* session); + +/** + * @brief Add session. + * @return if session already added, return SOFTBUS_TRANS_SESSION_REPEATED, else return SOFTBUS_OK or SOFTBUS_ERR. + */ +int32_t ClientAddSession(const SessionParam* param, int32_t* sessionId, bool* isEnabled); + +int32_t ClientDeleteSessionServer(SoftBusSecType type, const char* sessionName); + +int32_t ClientDeleteSession(int32_t sessionId); + +int32_t ClientGetSessionDataById(int32_t sessionId, char* data, uint16_t len, SessionKey key); + +int32_t ClientGetSessionIntegerDataById(int32_t sessionId, int *data, SessionKey key); + +int32_t ClientGetChannelBySessionId(int32_t sessionId, int32_t* channelId, int32_t* type); + +int32_t ClientSetChannelBySessionId(int32_t sessionId, int32_t channelId); + +int32_t ClientGetSessionIdByChannelId(int32_t channelId, int32_t* sessionId); + +int32_t ClientEnableSessionByChannelId(const ChannelInfo *channel, int32_t* sessionId); + +int32_t ClientGetSessionCallbackById(int32_t sessionId, ISessionListener* callback); + +int32_t ClientGetSessionCallbackByName(const char* sessionName, ISessionListener* callback); + +int32_t ClientAddSessionServer(SoftBusSecType type, const char* pkgName, const char* sessionName, + const ISessionListener* listener); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_SESSION_MANAGER_H \ No newline at end of file diff --git a/sdk/transmission/session/include/client_trans_session_service.h b/sdk/transmission/session/include/client_trans_session_service.h new file mode 100644 index 000000000..6922bdeee --- /dev/null +++ b/sdk/transmission/session/include/client_trans_session_service.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_SESSION_SERVICE_H +#define CLIENT_TRANS_SESSION_SERVICE_H + +#include "session.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_SESSION_SERVICE_H \ No newline at end of file diff --git a/sdk/transmission/session/src/client_trans_message_service.c b/sdk/transmission/session/src/client_trans_message_service.c new file mode 100644 index 000000000..dedada24d --- /dev/null +++ b/sdk/transmission/session/src/client_trans_message_service.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_message_service.h" + +#include "client_trans_channel_manager.h" +#include "client_trans_session_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +int32_t SendBytes(int32_t sessionId, const void *data, uint32_t len) +{ + if ((data == NULL) || (len == 0) || (len > TRANS_BYTES_LENGTH_MAX) || sessionId < 0) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t channelId = INVALID_CHANNEL_ID; + int32_t type = CHANNEL_TYPE_BUTT; + int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &type); + if (ret != SOFTBUS_OK) { + LOG_ERR("get channel failed"); + return ret; + } + if (type == CHANNEL_TYPE_BUTT) { + LOG_INFO("channel opening"); + return SOFTBUS_TRANS_SESSION_OPENING; + } + + return ClientTransChannelSendBytes(channelId, type, data, len); +} + +int32_t SendMessage(int32_t sessionId, const void *data, uint32_t len) +{ + if ((data == NULL) || (len == 0) || (len > TRANS_MESSAGE_LENGTH_MAX)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t channelId = INVALID_CHANNEL_ID; + int32_t type = CHANNEL_TYPE_BUTT; + int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &type); + if (ret != SOFTBUS_OK) { + LOG_ERR("get channel failed"); + return ret; + } + if (type == CHANNEL_TYPE_BUTT) { + LOG_INFO("channel opening"); + return SOFTBUS_TRANS_SESSION_OPENING; + } + + return ClientTransChannelSendMessage(channelId, type, data, len); +} \ No newline at end of file diff --git a/sdk/transmission/session/src/client_trans_session_callback.c b/sdk/transmission/session/src/client_trans_session_callback.c new file mode 100755 index 000000000..83888a8b0 --- /dev/null +++ b/sdk/transmission/session/src/client_trans_session_callback.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_session_callback.h" + +#include + +#include "client_trans_session_manager.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" + +static int32_t AcceptSessionAsServer(const char *sessionName, const ChannelInfo *channel, uint32_t flag, + int32_t *sessionId) +{ + SessionInfo *session = (SessionInfo *)SoftBusCalloc(sizeof(SessionInfo)); + if (session == NULL) { + LOG_ERR("malloc failed"); + return SOFTBUS_MALLOC_ERR; + } + + session->channelId = channel->channelId; + session->channelType = channel->channelType; + session->peerPid = channel->peerPid; + session->peerUid = channel->peerUid; + session->isServer = channel->isServer; + session->info.flag = flag; + if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, channel->peerSessionName) != EOK || + strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, channel->peerDeviceId) != EOK || + strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, channel->groupId) != EOK) { + LOG_ERR("client add peer session name or device id or group id failed"); + SoftBusFree(session); + return SOFTBUS_MEM_ERR; + } + int32_t ret = ClientAddNewSession(sessionName, session); + if (ret != SOFTBUS_OK) { + LOG_ERR("client add session failed"); + SoftBusFree(session); + return SOFTBUS_ERR; + } + *sessionId = session->sessionId; + return SOFTBUS_OK; +} + +static int32_t GetSessionCallbackByChannelId(int32_t channelId, int32_t *sessionId, ISessionListener *listener) +{ + if ((channelId < 0) || (sessionId == NULL) || (listener == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + int32_t ret = ClientGetSessionIdByChannelId(channelId, sessionId); + if (ret != SOFTBUS_OK) { + LOG_ERR("get sessionId failed, channelId [%d]", channelId); + return SOFTBUS_ERR; + } + ret = ClientGetSessionCallbackById(*sessionId, listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session listener failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransOnSessionOpened(const char *sessionName, const ChannelInfo *channel, uint32_t flag) +{ + if ((sessionName == NULL) || (channel == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + ISessionListener listener = {0}; + int32_t ret = ClientGetSessionCallbackByName(sessionName, &listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session listener failed"); + return SOFTBUS_ERR; + } + + int32_t sessionId = INVALID_SESSION_ID; + if (channel->isServer) { + ret = AcceptSessionAsServer(sessionName, channel, flag, &sessionId); + } else { + ret = ClientEnableSessionByChannelId(channel, &sessionId); + } + + if (ret != SOFTBUS_OK) { + LOG_ERR("accept session failed"); + return SOFTBUS_ERR; + } + + if ((listener.OnSessionOpened == NULL) || (listener.OnSessionOpened(sessionId, SOFTBUS_OK) != SOFTBUS_OK)) { + LOG_ERR("OnSessionOpened failed"); + (void)ClientDeleteSession(sessionId); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransOnSessionOpenFailed(int32_t channelId) +{ + int32_t sessionId; + ISessionListener listener = {0}; + int32_t ret = GetSessionCallbackByChannelId(channelId, &sessionId, &listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session callback failed"); + return ret; + } + + if (listener.OnSessionOpened != NULL) { + (void)listener.OnSessionOpened(sessionId, SOFTBUS_ERR); + } + + (void)ClientDeleteSession(sessionId); + return SOFTBUS_OK; +} + +int32_t TransOnSessionClosed(int32_t channelId) +{ + int32_t sessionId; + ISessionListener listener = {0}; + int32_t ret = GetSessionCallbackByChannelId(channelId, &sessionId, &listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session callback failed"); + return ret; + } + + if (listener.OnSessionClosed != NULL) { + listener.OnSessionClosed(sessionId); + } + + ret = ClientDeleteSession(sessionId); + if (ret != SOFTBUS_OK) { + LOG_ERR("client delete session failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransOnDataReceived(int32_t channelId, const void *data, uint32_t len, SessionPktType type) +{ + int32_t sessionId; + ISessionListener listener = {0}; + int32_t ret = GetSessionCallbackByChannelId(channelId, &sessionId, &listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session callback failed"); + return ret; + } + + switch (type) { + case TRANS_SESSION_BYTES: + if (listener.OnBytesReceived != NULL) { + listener.OnBytesReceived(sessionId, data, len); + } + break; + case TRANS_SESSION_MESSAGE: + if (listener.OnMessageReceived != NULL) { + listener.OnMessageReceived(sessionId, data, len); + } + break; + default: + LOG_ERR("unknown session type"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} \ No newline at end of file diff --git a/sdk/transmission/session/src/client_trans_session_manager.c b/sdk/transmission/session/src/client_trans_session_manager.c new file mode 100755 index 000000000..e0b2bc449 --- /dev/null +++ b/sdk/transmission/session/src/client_trans_session_manager.c @@ -0,0 +1,818 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_session_manager.h" + +#include + +#include "client_trans_channel_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_utils.h" + +#define ID_NOT_USED 0 +#define ID_USED 1 +#define SHIFT_3 3 +#define SESSION_MAP_COUNT ((MAX_SESSION_ID + 0x7) >> SHIFT_3) + +static uint8_t g_idFlagBitmap[SESSION_MAP_COUNT]; + +static SoftBusList *g_clientSessionServerList = NULL; + +void TransSessionTimer(void); + +int TransClientInit(void) +{ + if (g_clientSessionServerList != NULL) { + LOG_INFO("already init"); + return SOFTBUS_OK; + } + + if (memset_s(g_idFlagBitmap, sizeof(g_idFlagBitmap), 0, sizeof(g_idFlagBitmap)) != EOK) { + LOG_ERR("init id bitmap failed"); + return SOFTBUS_ERR; + } + + g_clientSessionServerList = CreateSoftBusList(); + if (g_clientSessionServerList == NULL) { + LOG_ERR("init list failed"); + return SOFTBUS_ERR; + } + + if (RegisterTimeoutCallback(SOFTBUS_SESSION_TIMER_FUN, TransSessionTimer) != SOFTBUS_OK) { + LOG_ERR("init trans timer failed"); + return SOFTBUS_ERR; + } + + if (ClientTransChannelInit() != SOFTBUS_OK) { + LOG_ERR("init trans channel failed"); + return SOFTBUS_ERR; + } + + LOG_INFO("init succ"); + return SOFTBUS_OK; +} + +static int32_t GenerateSessionId(void) +{ + /* need get lock before */ + for (uint32_t id = 0; id < MAX_SESSION_ID; id++) { + if (((g_idFlagBitmap[(id >> SHIFT_3)] >> (id & 0x7)) & ID_USED) == ID_NOT_USED) { + g_idFlagBitmap[(id >> SHIFT_3)] |= (ID_USED << (id & 0x7)); + return (int32_t)id; + } + } + return INVALID_SESSION_ID; +} + +static void DestroySessionId(int32_t sessionId) +{ + uint32_t id = (uint32_t)sessionId; + g_idFlagBitmap[(id >> SHIFT_3)] &= (~(ID_USED << (id & 0x7))); +} + +static void DestroyClientSessionServer(ClientSessionServer *server) +{ + if (server == NULL) { + LOG_ERR("invalid param"); + return; + } + + if (!IsListEmpty(&(server->sessionList))) { + SessionInfo *sessionNode = NULL; + SessionInfo *sessionNodeNext = NULL; + LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(server->sessionList), SessionInfo, node) { + (void)ClientTransCloseChannel(sessionNode->channelId, sessionNode->channelType); + ListDelete(&(sessionNode->node)); + DestroySessionId(sessionNode->sessionId); + server->listener.session.OnSessionClosed(sessionNode->sessionId); + SoftBusFree(sessionNode); + } + } + + ListDelete(&(server->node)); + LOG_INFO("destroy session server [%s]", server->sessionName); + SoftBusFree(server); +} + +void TransClientDeinit(void) +{ + if (g_clientSessionServerList == NULL) { + return; + } + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return; + } + ClientSessionServer *serverNode = NULL; + ClientSessionServer *serverNodeNext = NULL; + LIST_FOR_EACH_ENTRY_SAFE(serverNode, serverNodeNext, &(g_clientSessionServerList->list), + ClientSessionServer, node) { + DestroyClientSessionServer(serverNode); + } + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + + DestroySoftBusList(g_clientSessionServerList); + g_clientSessionServerList = NULL; + ClientTransChannelDeinit(); +} + +void TransSessionTimer(void) +{ +#define TRANS_SESSION_TIMEOUT (7 * 24) // hour +#define TRANS_SESSION_COUNT_TIMEOUT (60 * 60) // count per hour + static int32_t count = 0; + count++; + if (count < TRANS_SESSION_COUNT_TIMEOUT) { + return; + } + count = 0; + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return; + } + + ClientSessionServer *serverNode = NULL; + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (IsListEmpty(&(serverNode->sessionList))) { + continue; + } + SessionInfo *sessionNode = NULL; + SessionInfo *sessionNodeNext = NULL; + LIST_FOR_EACH_ENTRY_SAFE(sessionNode, sessionNodeNext, &(serverNode->sessionList), SessionInfo, node) { + sessionNode->timeout++; + if (sessionNode->timeout >= TRANS_SESSION_TIMEOUT) { + (void)ClientTransCloseChannel(sessionNode->channelId, sessionNode->channelType); + ListDelete(&(sessionNode->node)); + DestroySessionId(sessionNode->sessionId); + serverNode->listener.session.OnSessionClosed(sessionNode->sessionId); + SoftBusFree(sessionNode); + } + } + } + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return; +} + +static bool SessionServerIsExist(const char *sessionName) +{ + /* need get lock before */ + ListNode *pos = NULL; + ListNode *tmp = NULL; + ClientSessionServer *node = NULL; + LIST_FOR_EACH_SAFE(pos, tmp, &g_clientSessionServerList->list) { + node = (ClientSessionServer *)pos; + if (strcmp(node->sessionName, sessionName) == 0) { + return true; + } + } + return false; +} + +static ClientSessionServer *GetNewSessionServer(SoftBusSecType type, const char *sessionName, + const char *pkgName, const ISessionListener *listener) +{ + ClientSessionServer *server = SoftBusCalloc(sizeof(ClientSessionServer)); + if (server == NULL) { + return NULL; + } + server->type = type; + if (strcpy_s(server->pkgName, sizeof(server->pkgName), pkgName) != EOK) { + goto EXIT_ERR; + } + if (strcpy_s(server->sessionName, sizeof(server->sessionName), sessionName) != EOK) { + goto EXIT_ERR; + } + if (memcpy_s(&server->listener.session, sizeof(ISessionListener), listener, sizeof(ISessionListener)) != EOK) { + goto EXIT_ERR; + } + + ListInit(&server->node); + ListInit(&server->sessionList); + return server; +EXIT_ERR: + if (server != NULL) { + SoftBusFree(server); + } + return NULL; +} + +int32_t ClientAddSessionServer(SoftBusSecType type, const char *pkgName, const char *sessionName, + const ISessionListener *listener) +{ + if (pkgName == NULL || sessionName == NULL || listener == NULL) { + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + if (SessionServerIsExist(sessionName)) { + (void)pthread_mutex_unlock(&g_clientSessionServerList->lock); + return SOFTBUS_SERVER_NAME_REPEATED; + } + + if (g_clientSessionServerList->cnt >= MAX_SESSION_SERVER_NUMBER) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("server num reach max"); + return SOFTBUS_INVALID_NUM; + } + + ClientSessionServer *server = GetNewSessionServer(type, sessionName, pkgName, listener); + if (server == NULL) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_MEM_ERR; + } + ListAdd(&g_clientSessionServerList->list, &server->node); + g_clientSessionServerList->cnt++; + + (void)pthread_mutex_unlock(&g_clientSessionServerList->lock); + LOG_INFO("session name [%s], pkg name [%s]", server->sessionName, server->pkgName); + return SOFTBUS_OK; +} + +static bool IsValidSessionParam(const SessionParam *param) +{ + if ((param == NULL) || + (param->sessionName == NULL) || + (param->peerSessionName == NULL) || + (param->peerDeviceId == NULL) || + (param->groupId == NULL) || + (param->attr == NULL)) { + return false; + } + return true; +} + +static SessionInfo *CreateNewSession(const SessionParam *param) +{ + SessionInfo *session = (SessionInfo*)SoftBusCalloc(sizeof(SessionInfo)); + if (session == NULL) { + LOG_ERR("calloc failed"); + return NULL; + } + + if (strcpy_s(session->info.peerSessionName, SESSION_NAME_SIZE_MAX, param->peerSessionName) != EOK || + strcpy_s(session->info.peerDeviceId, DEVICE_ID_SIZE_MAX, param->peerDeviceId) != EOK || + strcpy_s(session->info.groupId, GROUP_ID_SIZE_MAX, param->groupId) != EOK) { + LOG_ERR("strcpy failed"); + SoftBusFree(session); + return NULL; + } + + session->sessionId = INVALID_SESSION_ID; + session->channelId = INVALID_CHANNEL_ID; + session->channelType = CHANNEL_TYPE_BUTT; + session->info.flag = param->attr->dataType; + + return session; +} + +static SessionInfo *GetExistSession(const SessionParam *param) +{ + /* need get lock before */ + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + SessionTag *tagInfo = NULL; + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if ((strcmp(serverNode->sessionName, param->sessionName) != 0) || IsListEmpty(&serverNode->sessionList)) { + continue; + } + LIST_FOR_EACH_ENTRY(sessionNode, &(serverNode->sessionList), SessionInfo, node) { + tagInfo = &sessionNode->info; + if ((strcmp(tagInfo->peerSessionName, param->peerSessionName) != 0) || + (strcmp(tagInfo->peerDeviceId, param->peerDeviceId) != 0) || + (strcmp(tagInfo->groupId, param->groupId) != 0) || + (tagInfo->flag != param->attr->dataType)) { + continue; + } + return sessionNode; + } + } + return NULL; +} + +static int32_t GetSessionById(int32_t sessionId, ClientSessionServer **server, SessionInfo **session) +{ + /* need get lock before */ + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (IsListEmpty(&serverNode->sessionList)) { + continue; + } + LIST_FOR_EACH_ENTRY(sessionNode, &(serverNode->sessionList), SessionInfo, node) { + if (sessionNode->sessionId == sessionId) { + *server = serverNode; + *session = sessionNode; + return SOFTBUS_OK; + } + } + } + return SOFTBUS_ERR; +} + +static int32_t AddSession(const char *sessionName, SessionInfo *session) +{ + /* need get lock before */ + session->sessionId = GenerateSessionId(); + if (session->sessionId < 0) { + return SOFTBUS_TRANS_SESSION_CNT_EXCEEDS_LIMIT; + } + ClientSessionServer *serverNode = NULL; + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (strcmp(serverNode->sessionName, sessionName) != 0) { + continue; + } + ListAdd(&serverNode->sessionList, &session->node); + return SOFTBUS_OK; + } + DestroySessionId(session->sessionId); + return SOFTBUS_TRANS_SESSIONSERVER_NOT_CREATED; +} + +int32_t ClientAddNewSession(const char *sessionName, SessionInfo *session) +{ + if (session == NULL) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + int32_t ret = AddSession(sessionName, session); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("add session failed, ret [%d]", ret); + return ret; + } + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; +} + +int32_t ClientAddSession(const SessionParam *param, int32_t *sessionId, bool *isEnabled) +{ + if (!IsValidSessionParam(param) || (sessionId == NULL) || (isEnabled == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + SessionInfo *session = GetExistSession(param); + if (session != NULL) { + *sessionId = session->sessionId; + *isEnabled = (session->channelType != CHANNEL_TYPE_BUTT); + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_TRANS_SESSION_REPEATED; + } + + session = CreateNewSession(param); + if (session == NULL) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("create session failed"); + return SOFTBUS_ERR; + } + + int32_t ret = AddSession(param->sessionName, session); + if (ret != SOFTBUS_OK) { + SoftBusFree(session); + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("Add Session failed, ret [%d]", ret); + return ret; + } + + *sessionId = session->sessionId; + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; +} + +int32_t ClientDeleteSessionServer(SoftBusSecType type, const char *sessionName) +{ + if ((type == SEC_TYPE_UNKNOWN) || (sessionName == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_NO_INIT; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_LOCK_ERR; + } + + ClientSessionServer *serverNode = NULL; + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if ((strcmp(serverNode->sessionName, sessionName) == 0) && (serverNode->type == type)) { + DestroyClientSessionServer(serverNode); + g_clientSessionServerList->cnt--; + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; + } + } + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found [%s]", sessionName); + return SOFTBUS_ERR; +} + +int32_t ClientDeleteSession(int32_t sessionId) +{ + if (sessionId < 0) { + return SOFTBUS_ERR; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (IsListEmpty(&serverNode->sessionList)) { + continue; + } + LIST_FOR_EACH_ENTRY(sessionNode, &(serverNode->sessionList), SessionInfo, node) { + if (sessionNode->sessionId != sessionId) { + continue; + } + ListDelete(&(sessionNode->node)); + DestroySessionId(sessionId); + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + SoftBusFree(sessionNode); + return SOFTBUS_OK; + } + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; +} + +int32_t ClientGetSessionDataById(int32_t sessionId, char *data, uint16_t len, SessionKey key) +{ + if ((sessionId < 0) || (data == NULL) || (len == 0)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + int32_t ret = GetSessionById(sessionId, &serverNode, &sessionNode); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; + } + + switch (key) { + case KEY_SESSION_NAME: + ret = strcpy_s(data, len, serverNode->sessionName); + break; + case KEY_PEER_SESSION_NAME: + ret = strcpy_s(data, len, sessionNode->info.peerSessionName); + break; + case KEY_PEER_DEVICE_ID: + ret = strcpy_s(data, len, sessionNode->info.peerDeviceId); + break; + default: + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_ERR; + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + if (ret != EOK) { + LOG_ERR("copy data failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t ClientGetSessionIntegerDataById(int32_t sessionId, int *data, SessionKey key) +{ + if ((sessionId < 0) || (data == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + int32_t ret = GetSessionById(sessionId, &serverNode, &sessionNode); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; + } + switch (key) { + case KEY_IS_SERVER: + *data = sessionNode->isServer; + break; + case KEY_PEER_PID: + *data = sessionNode->peerPid; + break; + case KEY_PEER_UID: + *data = sessionNode->peerUid; + break; + default: + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_ERR; + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + if (ret != EOK) { + LOG_ERR("copy data failed"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t ClientGetChannelBySessionId(int32_t sessionId, int32_t *channelId, int32_t *type) +{ + if ((sessionId < 0) || (channelId == NULL) || (type == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + int32_t ret = GetSessionById(sessionId, &serverNode, &sessionNode); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; + } + + *channelId = sessionNode->channelId; + *type = sessionNode->channelType; + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; +} + +int32_t ClientSetChannelBySessionId(int32_t sessionId, int32_t channelId) +{ + if ((sessionId < 0) || (channelId < 0)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + int32_t ret = GetSessionById(sessionId, &serverNode, &sessionNode); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; + } + sessionNode->channelId = channelId; + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; +} + +int32_t ClientGetSessionIdByChannelId(int32_t channelId, int32_t *sessionId) +{ + if ((channelId < 0) || (sessionId == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (IsListEmpty(&serverNode->sessionList)) { + continue; + } + + LIST_FOR_EACH_ENTRY(sessionNode, &(serverNode->sessionList), SessionInfo, node) { + if (sessionNode->channelId == channelId) { + *sessionId = sessionNode->sessionId; + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; + } + } + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found session with channelId [%d]", channelId); + return SOFTBUS_ERR; +} + +int32_t ClientEnableSessionByChannelId(const ChannelInfo *channel, int32_t *sessionId) +{ + if ((channel == NULL) || (sessionId == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (IsListEmpty(&serverNode->sessionList)) { + continue; + } + + LIST_FOR_EACH_ENTRY(sessionNode, &(serverNode->sessionList), SessionInfo, node) { + if (sessionNode->channelId == channel->channelId) { + sessionNode->channelType = channel->channelType; + sessionNode->peerPid = channel->peerPid; + sessionNode->peerUid = channel->peerUid; + sessionNode->isServer = channel->isServer; + *sessionId = sessionNode->sessionId; + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + return SOFTBUS_OK; + } + } + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found session with channelId [%d]", channel->channelId); + return SOFTBUS_ERR; +} + +int32_t ClientGetSessionCallbackById(int32_t sessionId, ISessionListener *callback) +{ + if (sessionId < 0 || callback == NULL) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + SessionInfo *sessionNode = NULL; + int32_t ret = GetSessionById(sessionId, &serverNode, &sessionNode); + if (ret != SOFTBUS_OK) { + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; + } + + ret = memcpy_s(callback, sizeof(ISessionListener), &serverNode->listener.session, sizeof(ISessionListener)); + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + if (ret != EOK) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t ClientGetSessionCallbackByName(const char *sessionName, ISessionListener *callback) +{ + if (sessionName == NULL || callback == NULL) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (g_clientSessionServerList == NULL) { + LOG_ERR("not init"); + return SOFTBUS_ERR; + } + + ClientSessionServer *serverNode = NULL; + + if (pthread_mutex_lock(&(g_clientSessionServerList->lock)) != 0) { + LOG_ERR("lock failed"); + return SOFTBUS_ERR; + } + + LIST_FOR_EACH_ENTRY(serverNode, &(g_clientSessionServerList->list), ClientSessionServer, node) { + if (strcmp(serverNode->sessionName, sessionName) != 0) { + continue; + } + + int32_t ret = memcpy_s(callback, sizeof(ISessionListener), + &serverNode->listener.session, sizeof(ISessionListener)); + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + if (ret != EOK) { + return SOFTBUS_ERR; + } + return SOFTBUS_OK; + } + + (void)pthread_mutex_unlock(&(g_clientSessionServerList->lock)); + LOG_ERR("not found"); + return SOFTBUS_ERR; +} \ No newline at end of file diff --git a/sdk/transmission/session/src/client_trans_session_service.c b/sdk/transmission/session/src/client_trans_session_service.c new file mode 100644 index 000000000..984240e5a --- /dev/null +++ b/sdk/transmission/session/src/client_trans_session_service.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_session_service.h" + +#include + +#include "client_trans_channel_manager.h" +#include "client_trans_session_manager.h" +#include "softbus_client_frame_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" +#include "softbus_utils.h" + +static bool IsValidSessionId(int sessionId) +{ + if ((sessionId < 0) || (sessionId > MAX_SESSION_ID)) { + LOG_ERR("invalid sessionId [%d]", sessionId); + return false; + } + return true; +} + +static bool IsValidListener(const ISessionListener *listener) +{ + if ((listener != NULL) && + (listener->OnSessionOpened != NULL) && + (listener->OnSessionClosed != NULL) && + (listener->OnBytesReceived != NULL) && + (listener->OnMessageReceived != NULL)) { + return true; + } + LOG_ERR("invalid ISessionListener"); + return false; +} + +static int32_t OpenSessionWithExistSession(int32_t sessionId, bool isEnabled) +{ + if (!isEnabled) { + LOG_INFO("the channel is opening"); + return sessionId; + } + + ISessionListener listener = {0}; + if (ClientGetSessionCallbackById(sessionId, &listener) != SOFTBUS_OK) { + LOG_ERR("get session listener failed"); + return sessionId; + } + + if ((listener.OnSessionOpened == NULL) || (listener.OnSessionOpened(sessionId, SOFTBUS_OK) != 0)) { + LOG_ERR("session callback OnSessionOpened failed"); + CloseSession(sessionId); + return INVALID_SESSION_ID; + } + return sessionId; +} + +int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener *listener) +{ + if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX) || + !IsValidListener(listener)) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (InitSoftBus(pkgName) != SOFTBUS_OK) { + LOG_ERR("init softbus err"); + return SOFTBUS_ERR; + } + + int ret = ClientAddSessionServer(SEC_TYPE_CIPHERTEXT, pkgName, sessionName, listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("add session server err"); + return ret; + } + + ret = GetServerProvideInterface()->createSessionServer(pkgName, sessionName); + if (ret == SOFTBUS_SERVER_NAME_REPEATED) { + LOG_ERR("SessionServer is already created"); + } else if (ret != SOFTBUS_OK) { + LOG_ERR("Server createSessionServer failed"); + (void)ClientDeleteSessionServer(SEC_TYPE_CIPHERTEXT, sessionName); + } + return ret; +} + +int RemoveSessionServer(const char *pkgName, const char *sessionName) +{ + if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX)) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = GetServerProvideInterface()->removeSessionServer(pkgName, sessionName); + if (ret != SOFTBUS_OK) { + LOG_ERR("remove in server failed"); + return ret; + } + + ret = ClientDeleteSessionServer(SEC_TYPE_CIPHERTEXT, sessionName); + if (ret != SOFTBUS_OK) { + LOG_ERR("delete session server [%s] failed", sessionName); + } + return ret; +} + +static int32_t CheckParamIsValid(const char *mySessionName, const char *peerSessionName, + const char *peerDeviceId, const char *groupId, const SessionAttribute *attr) +{ + if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) || + !IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) || + !IsValidString(groupId, GROUP_ID_SIZE_MAX) || + (attr == NULL) || + (attr->dataType >= TYPE_BUTT)) { + LOG_ERR("invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + if (strcmp(mySessionName, peerSessionName) != 0) { + LOG_ERR("session name not same"); + return SOFTBUS_TRANS_INVALID_SESSION_NAME; + } + + return SOFTBUS_OK; +} + +int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, + const char *groupId, const SessionAttribute *attr) +{ + int ret = CheckParamIsValid(mySessionName, peerSessionName, peerDeviceId, groupId, attr); + if (ret != SOFTBUS_OK) { + return INVALID_SESSION_ID; + } + + SessionParam param = { + .sessionName = mySessionName, + .peerSessionName = peerSessionName, + .peerDeviceId = peerDeviceId, + .groupId = groupId, + .attr = attr, + }; + + int32_t sessionId = INVALID_SESSION_ID; + bool isEnabled = false; + + ret = ClientAddSession(¶m, &sessionId, &isEnabled); + if (ret != SOFTBUS_OK) { + if (ret == SOFTBUS_TRANS_SESSION_REPEATED) { + LOG_INFO("session already opened"); + return OpenSessionWithExistSession(sessionId, isEnabled); + } + LOG_ERR("client open session failed, ret [%d]", ret); + return ret; + } + + int32_t channelId = GetServerProvideInterface()->openSession(mySessionName, peerSessionName, + peerDeviceId, groupId, (int32_t)attr->dataType); + ret = ClientSetChannelBySessionId(sessionId, channelId); + if (ret != SOFTBUS_OK) { + LOG_ERR("open session failed"); + (void)ClientDeleteSession(sessionId); + return INVALID_SESSION_ID; + } + LOG_INFO("OpenSession channelId [%d]", channelId); + return sessionId; +} + +void CloseSession(int sessionId) +{ + if (!IsValidSessionId(sessionId)) { + LOG_ERR("invalid param"); + return; + } + + int32_t channelId = INVALID_CHANNEL_ID; + int32_t type = CHANNEL_TYPE_BUTT; + + int32_t ret = ClientGetChannelBySessionId(sessionId, &channelId, &type); + if (ret == SOFTBUS_OK) { + LOG_INFO("get channel Id [%d], channel type [%d]", channelId, type); + (void)ClientTransCloseChannel(channelId, type); + } + + ISessionListener listener = {0}; + ret = ClientGetSessionCallbackById(sessionId, &listener); + if (ret != SOFTBUS_OK) { + LOG_ERR("get session listener failed"); + } + + if (listener.OnSessionClosed != NULL) { + listener.OnSessionClosed(sessionId); + } + + ClientDeleteSession(sessionId); + return; +} + +int GetMySessionName(int sessionId, char *sessionName, unsigned int len) +{ + if (!IsValidSessionId(sessionId) || (sessionName == NULL) || (len > SESSION_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + return ClientGetSessionDataById(sessionId, sessionName, len, KEY_SESSION_NAME); +} + +int GetPeerSessionName(int sessionId, char *sessionName, unsigned int len) +{ + if (!IsValidSessionId(sessionId) || (sessionName == NULL) || (len > SESSION_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + return ClientGetSessionDataById(sessionId, sessionName, len, KEY_PEER_SESSION_NAME); +} + +int GetPeerDeviceId(int sessionId, char *devId, unsigned int len) +{ + if (!IsValidSessionId(sessionId) || (devId == NULL) || (len > SESSION_NAME_SIZE_MAX)) { + return SOFTBUS_INVALID_PARAM; + } + + return ClientGetSessionDataById(sessionId, devId, len, KEY_PEER_DEVICE_ID); +} diff --git a/sdk/transmission/trans_channel/BUILD.gn b/sdk/transmission/trans_channel/BUILD.gn new file mode 100755 index 000000000..9027d24f5 --- /dev/null +++ b/sdk/transmission/trans_channel/BUILD.gn @@ -0,0 +1,78 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +if (ohos_kernel_type == "liteos_m") { + static_library("softbus_client_trans_channel") { + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/sequence_verification/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/sdk/transmission/session/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/common/include", + "manager/include", + "proxy/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "manager/src/client_trans_channel_callback.c", + "manager/src/client_trans_channel_callback_weak.c", + "manager/src/client_trans_channel_manager.c", + "manager/src/client_trans_channel_manager_weak.c", + "proxy/src/client_trans_proxy_manager.c", + ] + deps = [ "tcp_direct:direct_channel_sdk" ] + } +} else { + shared_library("softbus_client_trans_channel") { + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/security/sequence_verification/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/transport", + "$dsoftbus_root_path/sdk/transmission/session/include", + "$dsoftbus_root_path/sdk/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/common/include", + "manager/include", + "proxy/include", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + ] + sources = [ + "manager/src/client_trans_channel_callback.c", + "manager/src/client_trans_channel_callback_weak.c", + "manager/src/client_trans_channel_manager.c", + "manager/src/client_trans_channel_manager_weak.c", + "proxy/src/client_trans_proxy_manager.c", + ] + } +} diff --git a/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback.h b/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback.h new file mode 100644 index 000000000..fa8719e59 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_CHANNEL_CALLBACK_H +#define CLIENT_TRANS_CHANNEL_CALLBACK_H + +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransOnChannelOpened(const char *pkgName, const char* sessionName, const ChannelInfo *channel); + +int32_t TransOnChannelOpenFailed(const char *pkgName, int32_t channelId); + +int32_t TransOnChannelClosed(const char *pkgName, int32_t channelId); + +int32_t TransOnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, unsigned int len, + SessionPktType type); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_CHANNEL_CALLBACK_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback_weak.h b/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback_weak.h new file mode 100755 index 000000000..2dfd1d931 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/include/client_trans_channel_callback_weak.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_CHANNEL_CALLBACK_WEAK_H +#define CLIENT_TRANS_CHANNEL_CALLBACK_WEAK_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +int32_t __attribute__ ((weak)) TransOnProxyChannelOpened(const ChannelInfo *channel); +int32_t __attribute__ ((weak)) TransTdcOnChannelOpened(const ChannelInfo *channel); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // CLIENT_TRANS_CHANNEL_CALLBACK_WEAK_H + diff --git a/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager.h b/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager.h new file mode 100644 index 000000000..c496f6e8e --- /dev/null +++ b/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_CHANNEL_MANAGER_H +#define CLIENT_TRANS_CHANNEL_MANAGER_H + +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t ClientTransChannelInit(void); + +void ClientTransChannelDeinit(void); + +int32_t ClientTransCloseChannel(int32_t channelId, int32_t type); + +int32_t ClientTransChannelSendBytes(int32_t channelId, int32_t type, const void *data, uint32_t len); + +int32_t ClientTransChannelSendMessage(int32_t channelId, int32_t type, const void *data, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_CHANNEL_MANAGER_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager_weak.h b/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager_weak.h new file mode 100755 index 000000000..abf6fea72 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/include/client_trans_channel_manager_weak.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_CHANNEL_MANAGER_WEAK_H +#define CLIENT_TRANS_CHANNEL_MANAGER_WEAK_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +int32_t __attribute__ ((weak)) TransTdcManagerInit(void); + +void __attribute__ ((weak)) TransTdcManagerDeinit(void); + +int32_t __attribute__ ((weak)) TransCloseProxyChannel(int32_t channelId); + +void __attribute__ ((weak)) TransTdcCloseChannel(int32_t channelId); + +int32_t __attribute__ ((weak)) TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len); + +int32_t __attribute__ ((weak)) TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len); + +int32_t __attribute__ ((weak)) TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len); + +int32_t __attribute__ ((weak)) TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // CLIENT_TRANS_CHANNEL_MANAGER_WEAK_H + diff --git a/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback.c b/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback.c new file mode 100644 index 000000000..7026ce086 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_channel_callback.h" + +#include "client_trans_channel_manager.h" +#include "client_trans_proxy_manager.h" +#include "client_trans_session_callback.h" +#ifndef SOFTBUS_WATCH +#include "client_trans_tcp_direct_manager.h" +#include "client_trans_tcp_direct_message.h" +#endif +#include "session.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +int32_t TransOnChannelOpened(const char *pkgName, const char *sessionName, const ChannelInfo *channel) +{ + (void)pkgName; + if ((sessionName == NULL) || (channel == NULL)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = SOFTBUS_ERR; + uint32_t flag = TYPE_BUTT; + switch (channel->channelType) { + case CHANNEL_TYPE_PROXY: + ret = TransOnProxyChannelOpened(channel); + flag = TYPE_MESSAGE; + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + ret = TransTdcOnChannelOpened(channel); + break; +#endif + default: + LOG_ERR("Invalid type"); + return SOFTBUS_ERR; + } + + if (ret != SOFTBUS_OK) { + LOG_ERR("channel open failed"); + return SOFTBUS_ERR; + } + + ret = TransOnSessionOpened(sessionName, channel, flag); + if (ret != SOFTBUS_OK) { + LOG_ERR("TransOnSessionOpened failed"); + (void)ClientTransCloseChannel(channel->channelId, channel->channelType); + } + + return ret; +} + +int32_t TransOnChannelOpenFailed(const char *pkgName, int32_t channelId) +{ + (void)pkgName; + return TransOnSessionOpenFailed(channelId); +} + +int32_t TransOnChannelClosed(const char *pkgName, int32_t channelId) +{ + (void)pkgName; + return TransOnSessionClosed(channelId); +} + +int32_t TransOnChannelMsgReceived(const char *pkgName, int32_t channelId, const void *data, uint32_t len, + SessionPktType type) +{ + (void)pkgName; + return TransOnDataReceived(channelId, data, len, type); +} diff --git a/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback_weak.c b/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback_weak.c new file mode 100755 index 000000000..a3739c3f5 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/src/client_trans_channel_callback_weak.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_def.h" +#include "softbus_errcode.h" + +int32_t __attribute__ ((weak)) TransOnProxyChannelOpened(const ChannelInfo *channel) +{ + (void)channel; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) TransTdcOnChannelOpened(const ChannelInfo *channel) +{ + (void)channel; + return SOFTBUS_NOT_IMPLEMENT; +} + diff --git a/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager.c b/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager.c new file mode 100644 index 000000000..177c4d02a --- /dev/null +++ b/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_channel_manager.h" + +#include "client_trans_channel_manager_weak.h" +#include "client_trans_proxy_manager.h" +#ifndef SOFTBUS_WATCH +#include "client_trans_tcp_direct_message.h" +#endif +#include "softbus_errcode.h" +#include "softbus_log.h" + +int32_t ClientTransChannelInit(void) +{ +#ifndef SOFTBUS_WATCH + if (TransTdcManagerInit() != SOFTBUS_OK) { + LOG_ERR("trans tcp direct manager init failed."); + return SOFTBUS_ERR; + } +#endif + return SOFTBUS_OK; +} + +void ClientTransChannelDeinit(void) +{ +#ifndef SOFTBUS_WATCH + TransTdcManagerDeinit(); +#endif +} + +int32_t ClientTransCloseChannel(int32_t channelId, int32_t type) +{ + if (channelId < 0) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + int32_t ret = SOFTBUS_OK; + switch (type) { + case CHANNEL_TYPE_PROXY: + ret = TransCloseProxyChannel(channelId); + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + TransTdcCloseChannel(channelId); + break; +#endif + default: + LOG_ERR("Invalid type"); + return SOFTBUS_ERR; + } + return ret; +} + +int32_t ClientTransChannelSendBytes(int32_t channelId, int32_t type, const void *data, uint32_t len) +{ + if ((data == NULL) || (len == 0)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = SOFTBUS_OK; + switch (type) { + case CHANNEL_TYPE_PROXY: + ret = TransProxyChannelSendBytes(channelId, data, len); + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + ret = TransTdcSendBytes(channelId, data, len); + break; +#endif + default: + LOG_ERR("Invalid type"); + return SOFTBUS_ERR; + } + return ret; +} + +int32_t ClientTransChannelSendMessage(int32_t channelId, int32_t type, const void *data, uint32_t len) +{ + if ((data == NULL) || (len == 0)) { + LOG_ERR("Invalid param"); + return SOFTBUS_INVALID_PARAM; + } + + int32_t ret = SOFTBUS_OK; + switch (type) { + case CHANNEL_TYPE_PROXY: + ret = TransProxyChannelSendMessage(channelId, data, len); + break; +#ifndef SOFTBUS_WATCH + case CHANNEL_TYPE_TCP_DIRECT: + ret = TransTdcSendMessage(channelId, data, len); + break; +#endif + default: + LOG_ERR("Invalid type"); + return SOFTBUS_ERR; + } + return ret; +} \ No newline at end of file diff --git a/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager_weak.c b/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager_weak.c new file mode 100755 index 000000000..7bd847d32 --- /dev/null +++ b/sdk/transmission/trans_channel/manager/src/client_trans_channel_manager_weak.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_def.h" +#include "softbus_errcode.h" + +int32_t __attribute__ ((weak)) TransTdcManagerInit(void) +{ + return SOFTBUS_OK; +} + +void __attribute__ ((weak)) TransTdcManagerDeinit(void) +{ +} + +int32_t __attribute__ ((weak)) TransCloseProxyChannel(int32_t channelId) +{ + (void)channelId; + return SOFTBUS_NOT_IMPLEMENT; +} + +void __attribute__ ((weak)) TransTdcCloseChannel(int32_t channelId) +{ + (void)channelId; +} + +int32_t __attribute__ ((weak)) TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len) +{ + (void)channelId; + (void)data; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len) +{ + (void)channelId; + (void)data; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len) +{ + (void)channelId; + (void)data; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} + +int32_t __attribute__ ((weak)) TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len) +{ + (void)channelId; + (void)data; + (void)len; + return SOFTBUS_NOT_IMPLEMENT; +} + diff --git a/sdk/transmission/trans_channel/proxy/include/client_trans_proxy_manager.h b/sdk/transmission/trans_channel/proxy/include/client_trans_proxy_manager.h new file mode 100644 index 000000000..40d739ca7 --- /dev/null +++ b/sdk/transmission/trans_channel/proxy/include/client_trans_proxy_manager.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_PROXY_CHANNEL_H +#define CLIENT_TRANS_PROXY_CHANNEL_H + +#include "softbus_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransCloseProxyChannel(int32_t channelId); + +int32_t TransOnProxyChannelOpened(const ChannelInfo *channel); + +int32_t TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len); + +int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_PROXY_CHANNEL_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/proxy/src/client_trans_proxy_manager.c b/sdk/transmission/trans_channel/proxy/src/client_trans_proxy_manager.c new file mode 100644 index 000000000..903b96087 --- /dev/null +++ b/sdk/transmission/trans_channel/proxy/src/client_trans_proxy_manager.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_proxy_manager.h" + +#include "softbus_errcode.h" +#include "softbus_interface.h" +#include "softbus_log.h" + +int32_t TransCloseProxyChannel(int32_t channelId) +{ + LOG_INFO("TransCloseProxyChannel, channelId [%d]", channelId); + return GetServerProvideInterface()->closeChannel(channelId); +} + +int32_t TransOnProxyChannelOpened(const ChannelInfo *channel) +{ + LOG_INFO("no need do anything"); + return SOFTBUS_OK; +} + +int32_t TransProxyChannelSendBytes(int32_t channelId, const void *data, uint32_t len) +{ + int ret = GetServerProvideInterface()->sendMessage(channelId, data, len, TRANS_SESSION_BYTES); + LOG_INFO("send bytes: channelId=%d, ret=%d", channelId, ret); + return ret; +} + +int32_t TransProxyChannelSendMessage(int32_t channelId, const void *data, uint32_t len) +{ + int ret = GetServerProvideInterface()->sendMessage(channelId, data, len, TRANS_SESSION_MESSAGE); + LOG_INFO("send msg: channelId=%d, ret=%d", channelId, ret); + return ret; +} diff --git a/sdk/transmission/trans_channel/tcp_direct/BUILD.gn b/sdk/transmission/trans_channel/tcp_direct/BUILD.gn new file mode 100755 index 000000000..c75946c2f --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +static_library("direct_channel_sdk") { + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/security/sequence_verification/include", + "$dsoftbus_root_path/core/common/wifi_common/tcp_socket/include", + "$dsoftbus_root_path/core/connection/interface", + "include", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/pending_packet/include", + "$dsoftbus_root_path/sdk/transmission/session/include", + "$dsoftbus_root_path/core/authentication/interface", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + ] + cflags = [ + "-Wall", + "-fPIC", + "-fno-builtin", + "-std=c99", + ] + sources = [ + "src/client_trans_tcp_direct_listener.c", + "src/client_trans_tcp_direct_manager.c", + "src/client_trans_tcp_direct_message.c", + ] + deps = [ + "$dsoftbus_root_path/core/common:softbus_core_common", + "$dsoftbus_root_path/core/common/security/sequence_verification:softbus_seq_verification", + "$dsoftbus_root_path/core/transmission/pending_packet:trans_pending", + ] +} diff --git a/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_listener.h b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_listener.h new file mode 100755 index 000000000..768a5ccf0 --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_listener.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_TCP_DIRECT_LISTENER_H +#define CLIENT_TRANS_TCP_DIRECT_LISTENER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t TransTdcCreateListener(int32_t fd); +void TransTdcReleaseFd(int32_t fd); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_TCP_DIRECT_LISTENER_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_manager.h b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_manager.h new file mode 100755 index 000000000..a053084d1 --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_manager.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_TCP_DIRECT_MANAGER_H +#define CLIENT_TRANS_TCP_DIRECT_MANAGER_H + +#include "softbus_app_info.h" +#include "softbus_sequence_verification.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int fd; + int32_t type; + bool aliveState; + int apiVersion; + int32_t sequence; + SeqVerifyInfo verifyInfo; + pthread_cond_t cond; + pthread_mutex_t lock; + char sessionKey[SESSION_KEY_LENGTH]; + SoftBusList *pendingPacketsList; +} TcpDirectChannelDetail; + +typedef struct { + ListNode node; + int32_t channelId; + TcpDirectChannelDetail detail; +} TcpDirectChannelInfo; + +int32_t TransTdcOnChannelOpened(const ChannelInfo *channel); +int32_t TransTdcCheckSeq(int32_t fd, int32_t seq); +void TransTdcCloseChannel(int32_t channelId); + +TcpDirectChannelInfo *TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info); +TcpDirectChannelInfo *TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info); +TcpDirectChannelInfo *TransTdcGetInfoByIdWithIncSeq(int32_t channelId, TcpDirectChannelInfo *info); + +#ifdef __cplusplus +} +#endif + +#endif // CLIENT_TRANS_TCP_DIRECT_MANAGER_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_message.h b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_message.h new file mode 100755 index 000000000..ffd7d199c --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/include/client_trans_tcp_direct_message.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CLIENT_TRANS_TCP_DIRECT_MESSAGE_H +#define CLIENT_TRANS_TCP_DIRECT_MESSAGE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DC_DATA_HEAD_SIZE 16 +#ifndef MAGIC_NUMBER +#define MAGIC_NUMBER 0xBABEFACE +#endif + +enum { + FLAG_BYTES = 0, + FLAG_ACK = 1, + FLAG_MESSAGE = 2, + FILE_FIRST_FRAME = 3, + FILE_ONGOINE_FRAME = 4, + FILE_LAST_FRAME = 5, + FILE_ONLYONE_FRAME = 6, + FILE_ALLFILE_SENT = 7, + FLAG_ASYNC_MESSAGE = 8, + FLAG_SET_LOW_LATENCY = 9 +}; + +typedef struct { + uint32_t magicNumber; + int32_t seq; + uint32_t flags; + uint32_t dataLen; +} __attribute__((packed)) TcpDataPacketHead; + +int32_t TransTdcPreProcessRecvData(int32_t fd, char *data, uint32_t size); +int32_t TransTdcProcessRecvData(int32_t channelId, const char *data); + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_TRANS_TCP_DIRECT_MESSAGE_H \ No newline at end of file diff --git a/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_listener.c b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_listener.c new file mode 100755 index 000000000..ecfe5b561 --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_listener.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_tcp_direct_listener.h" + +#include +#include + +#include "client_trans_channel_callback.h" +#include "client_trans_tcp_direct_manager.h" +#include "client_trans_tcp_direct_message.h" +#include "securec.h" +#include "softbus_base_listener.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_property.h" +#include "softbus_tcp_socket.h" +#include "softbus_type_def.h" +#include "trans_pending_pkt.h" + +static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; + +static int32_t OnConnectEvent(int events, int cfd, const char *ip) +{ + (void)events; + (void)cfd; + (void)ip; + return SOFTBUS_OK; +} + +static int32_t OnDataEvent(int events, int32_t fd) +{ + TcpDirectChannelInfo channel; + (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo)); + if (TransTdcGetInfoByFd(fd, &channel) == NULL) { + LOG_WARN("can not match fd.(%d)", fd); + return SOFTBUS_ERR; + } + + if (events == SOFTBUS_SOCKET_IN) { + int32_t channelId = channel.channelId; + char *data = (char *)SoftBusCalloc(MAX_BUF_LENGTH); + if (data == NULL) { + LOG_ERR("malloc failed."); + return SOFTBUS_MALLOC_ERR; + } + int32_t ret = TransTdcPreProcessRecvData(fd, data, MAX_BUF_LENGTH); + if (ret != SOFTBUS_OK) { + TransTdcCloseChannel(channelId); + TransOnChannelClosed(NULL, channelId); + SoftBusFree(data); + LOG_ERR("preparing for data processing failed.[%d]", ret); + return ret; + } + if (TransTdcProcessRecvData(channelId, data) != SOFTBUS_OK) { + TransTdcCloseChannel(channelId); + TransOnChannelClosed(NULL, channelId); + SoftBusFree(data); + LOG_ERR("process data failed."); + return SOFTBUS_ERR; + } + SoftBusFree(data); + } + + return SOFTBUS_OK; +} + +static SoftbusBaseListener g_listener = { + .onConnectEvent = OnConnectEvent, + .onDataEvent = OnDataEvent, +}; + +int32_t TransTdcCreateListener(int32_t fd) +{ + static bool isInitedFlag = false; + pthread_mutex_lock(&g_lock); + if (isInitedFlag == false) { + isInitedFlag = true; + + if (SetSoftbusBaseListener(DIRECT_CHANNEL_CLIENT, &g_listener) != SOFTBUS_OK) { + LOG_ERR("start sdk base listener failed."); + pthread_mutex_unlock(&g_lock); + return SOFTBUS_ERR; + } + if (StartBaseClient(DIRECT_CHANNEL_CLIENT) < SOFTBUS_OK) { + LOG_ERR("client start base listener failed."); + pthread_mutex_unlock(&g_lock); + return SOFTBUS_ERR; + } + LOG_INFO("create sdk listener success."); + } + pthread_mutex_unlock(&g_lock); + + return AddTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER); +} + +void TransTdcReleaseFd(int32_t fd) +{ + if (fd < 0) { + return; + } + DelTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER); + TcpShutDown(fd); +} diff --git a/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_manager.c b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_manager.c new file mode 100755 index 000000000..85b7a2949 --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_manager.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_tcp_direct_manager.h" + +#include + +#include "client_trans_session_callback.h" +#include "client_trans_tcp_direct_listener.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_tcp_socket.h" +#include "softbus_utils.h" +#include "trans_pending_pkt.h" + +#define HEART_TIME 300 +static SoftBusList *g_tcpDirectChannelInfoList = NULL; + +TcpDirectChannelInfo *TransTdcGetInfoById(int32_t channelId, TcpDirectChannelInfo *info) +{ + TcpDirectChannelInfo *item = NULL; + + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->channelId == channelId) { + if (info != NULL) { + (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo)); + } + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return item; + } + } + + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return NULL; +} + +TcpDirectChannelInfo *TransTdcGetInfoByIdWithIncSeq(int32_t channelId, TcpDirectChannelInfo *info) +{ + TcpDirectChannelInfo *item = NULL; + + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->channelId == channelId) { + item->detail.sequence++; + if (info != NULL) { + (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo)); + } + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return item; + } + } + + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return NULL; +} + +TcpDirectChannelInfo *TransTdcGetInfoByFd(int32_t fd, TcpDirectChannelInfo *info) +{ + TcpDirectChannelInfo *item = NULL; + + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->detail.fd == fd) { + if (info != NULL) { + (void)memcpy_s(info, sizeof(TcpDirectChannelInfo), item, sizeof(TcpDirectChannelInfo)); + } + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return item; + } + } + + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return NULL; +} + +int32_t TransTdcCheckSeq(int32_t fd, int32_t seq) +{ + TcpDirectChannelInfo *item = NULL; + + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->detail.fd == fd) { + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + if (!IsPassSeqCheck(&(item->detail.verifyInfo), seq)) { + LOG_WARN("SeqCheck is false"); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; + } + } + + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + return SOFTBUS_ERR; +} + +void TransTdcCloseChannel(int32_t channelId) +{ + LOG_INFO("TransCloseTcpDirectChannel, channelId [%d]", channelId); + + TcpDirectChannelInfo *item = NULL; + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->channelId == channelId) { + TransTdcReleaseFd(item->detail.fd); + ListDelete(&item->node); + SoftBusFree(item); + item = NULL; + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + DelPendingPacketById(channelId, PENDING_TYPE_DIRECT); + LOG_INFO("Delete chanel item success."); + return; + } + } + + LOG_ERR("Target channel item not exist."); + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); +} + +int32_t TransTdcOnChannelOpened(const ChannelInfo *channel) +{ + if (channel == NULL) { + LOG_ERR("Para wrong"); + return SOFTBUS_ERR; + } + + TcpDirectChannelInfo *item = NULL; + (void)pthread_mutex_lock(&g_tcpDirectChannelInfoList->lock); + LIST_FOR_EACH_ENTRY(item, &(g_tcpDirectChannelInfoList->list), TcpDirectChannelInfo, node) { + if (item->channelId == channel->channelId) { + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + LOG_ERR("tcp direct channel id exist already."); + return SOFTBUS_ERR; + } + } + + item = (TcpDirectChannelInfo *)SoftBusCalloc(sizeof(TcpDirectChannelInfo)); + if (item == NULL) { + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + LOG_ERR("create tdc channel info failed"); + return SOFTBUS_ERR; + } + item->channelId = channel->channelId; + item->detail.fd = channel->fd; + item->detail.type = channel->channelType; + if (memcpy_s(item->detail.sessionKey, SESSION_KEY_LENGTH, channel->sessionKey, SESSION_KEY_LENGTH) != EOK) { + SoftBusFree(item); + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + LOG_ERR("memcpy_s failed"); + return SOFTBUS_ERR; + } + ListAdd(&g_tcpDirectChannelInfoList->list, &item->node); + + (void)pthread_mutex_unlock(&g_tcpDirectChannelInfoList->lock); + + if (TransTdcCreateListener(item->detail.fd) != SOFTBUS_OK) { + LOG_ERR("trans tcp direct create listener failed."); + return SOFTBUS_ERR; + } + + int32_t ret = SetTcpKeepAlive(channel->fd, HEART_TIME); + if (ret != SOFTBUS_OK) { + LOG_ERR("SetTcpKeepAlive failed."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +int32_t TransTdcManagerInit(void) +{ + g_tcpDirectChannelInfoList = CreateSoftBusList(); + if (g_tcpDirectChannelInfoList == NULL) { + LOG_ERR("init tcp direct channel info list fail."); + return SOFTBUS_ERR; + } + LOG_INFO("init tcp direct channel info list success."); + return SOFTBUS_OK; +} + +void TransTdcManagerDeinit(void) +{ + if (g_tcpDirectChannelInfoList == NULL) { + return; + } + + DestroySoftBusList(g_tcpDirectChannelInfoList); + g_tcpDirectChannelInfoList = NULL; +} + diff --git a/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_message.c b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_message.c new file mode 100755 index 000000000..b3bde8b7c --- /dev/null +++ b/sdk/transmission/trans_channel/tcp_direct/src/client_trans_tcp_direct_message.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "client_trans_tcp_direct_message.h" + +#include +#include + +#include "client_trans_session_callback.h" +#include "client_trans_tcp_direct_manager.h" +#include "softbus_crypto.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_tcp_socket.h" +#include "trans_pending_pkt.h" + +#define ACK_SIZE 4 // Message ACK 4 bytes + +static int32_t TransTdcDecrypt(const char *sessionKey, const char *in, uint32_t inLen, char *out, uint32_t *outLen) +{ + AesGcmCipherKey cipherKey = {0}; + cipherKey.keyLen = SESSION_KEY_LENGTH; // 256 bit encryption + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) { + LOG_ERR("memcpy key error."); + return SOFTBUS_ERR; + } + SoftBusDecryptData(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen); + return SOFTBUS_OK; +} + +static int32_t TransTdcEncryptWithSeq(const char *sessionKey, int32_t seqNum, const char *in, uint32_t inLen, + char *out, uint32_t *outLen) +{ + AesGcmCipherKey cipherKey = {0}; + cipherKey.keyLen = SESSION_KEY_LENGTH; + if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) { + LOG_ERR("memcpy key error."); + return SOFTBUS_ERR; + } + int ret = SoftBusEncryptDataWithSeq(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen, seqNum); + if (ret != SOFTBUS_OK || *outLen != inLen + OVERHEAD_LEN) { + LOG_ERR("encrypt error."); + return SOFTBUS_ENCRYPT_ERR; + } + return SOFTBUS_OK; +} + +static int32_t TransTdcSetPendingPacket(int32_t channelId, const char *data, uint32_t len) +{ + if (len != ACK_SIZE) { + LOG_ERR("recv invalid seq."); + return SOFTBUS_ERR; + } + + int32_t seq = (int32_t)ntohl(*(uint32_t *)data); + if (SetPendingPacket(channelId, seq, PENDING_TYPE_DIRECT) != SOFTBUS_OK) { + LOG_ERR("can not match seq."); + return SOFTBUS_ERR; + } + return SOFTBUS_OK; +} + +static char *TransTdcPackData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len, int flags, + uint32_t *outLen) +{ + uint32_t dataLen = len + OVERHEAD_LEN; + char *buf = (char *)SoftBusMalloc(dataLen + DC_DATA_HEAD_SIZE); + if (buf == NULL) { + LOG_ERR("malloc failed."); + return NULL; + } + + char *finalData = (char *)data; + int32_t finalSeq = channel->detail.sequence; + uint32_t tmpSeq; + if (flags == FLAG_ACK) { + finalSeq = *((int32_t *)data); + tmpSeq = htonl((uint32_t)finalSeq); + finalData = (char *)(&tmpSeq); + } + + TcpDataPacketHead pktHead = { + .magicNumber = MAGIC_NUMBER, + .seq = finalSeq, + .flags = flags, + .dataLen = dataLen, + }; + if (memcpy_s(buf, DC_DATA_HEAD_SIZE, &pktHead, sizeof(TcpDataPacketHead)) != EOK) { + SoftBusFree(buf); + LOG_ERR("memcpy_s error"); + return NULL; + } + if (TransTdcEncryptWithSeq(channel->detail.sessionKey, finalSeq, finalData, len, + buf + DC_DATA_HEAD_SIZE, outLen) != SOFTBUS_OK) { + LOG_ERR("encrypt error"); + SoftBusFree(buf); + return NULL; + } + return buf; +} + +static int32_t TransTdcPreProcessPostData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len, + int32_t flags) +{ + uint32_t outLen; + char *buf = TransTdcPackData(channel, data, len, flags, &outLen); + if (buf == NULL || outLen != len + OVERHEAD_LEN) { + LOG_ERR("failed to pack bytes."); + return SOFTBUS_ENCRYPT_ERR; + } + uint32_t ret = SendTcpData(channel->detail.fd, buf, outLen + DC_DATA_HEAD_SIZE, 0); + if (ret != outLen + DC_DATA_HEAD_SIZE) { + LOG_ERR("failed to send tcp data."); + SoftBusFree(buf); + return SOFTBUS_ERR; + } + SoftBusFree(buf); + return SOFTBUS_OK; +} + +int32_t TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len) +{ + TcpDirectChannelInfo channel; + (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo)); + if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) { + return SOFTBUS_ERR; + } + + int ret = TransTdcPreProcessPostData(&channel, data, len, FLAG_BYTES); + if (ret != SOFTBUS_OK) { + LOG_ERR("postBytes failed"); + return ret; + } + + return SOFTBUS_OK; +} + +int32_t TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len) +{ + TcpDirectChannelInfo channel; + (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo)); + if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) { + return SOFTBUS_ERR; + } + + int ret = TransTdcPreProcessPostData(&channel, data, len, FLAG_MESSAGE); + if (ret != SOFTBUS_OK) { + LOG_ERR("postBytes failed."); + return ret; + } + + ret = AddPendingPacket(channelId, channel.detail.sequence, PENDING_TYPE_DIRECT); + if (ret != SOFTBUS_ERR) { + DelPendingPacket(channelId, channel.detail.sequence, PENDING_TYPE_DIRECT); + } + return ret; +} + +static int32_t TransTdcSendAck(const TcpDirectChannelInfo *channel, int32_t seq) +{ + if (channel == NULL) { + return SOFTBUS_ERR; + } + + return TransTdcPreProcessPostData(channel, (char*)(&seq), ACK_SIZE, FLAG_ACK); +} + +int32_t TransTdcProcessRecvData(int32_t channelId, const char *data) +{ + TcpDataPacketHead *pktHead = (TcpDataPacketHead *)data; + int32_t seqNum = pktHead->seq; + + TcpDirectChannelInfo channel; + (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo)); + if (TransTdcGetInfoById(channelId, &channel) == NULL) { + LOG_ERR("get key fail."); + return SOFTBUS_ERR; + } + + char *plain = (char *)SoftBusCalloc(pktHead->dataLen - OVERHEAD_LEN); + if (plain == NULL) { + LOG_ERR("malloc error."); + return SOFTBUS_MALLOC_ERR; + } + + uint32_t plainLen; + int ret = TransTdcDecrypt(channel.detail.sessionKey, data + sizeof(TcpDataPacketHead), + pktHead->dataLen, plain, &plainLen); + if (ret != SOFTBUS_OK) { + LOG_ERR("decrypt error."); + SoftBusFree(plain); + return SOFTBUS_DECRYPT_ERR; + } + + switch (pktHead->flags) { + case FLAG_BYTES: + TransOnDataReceived(channel.channelId, plain, plainLen, TRANS_SESSION_BYTES); + break; + case FLAG_ACK: + TransTdcSetPendingPacket(channel.channelId, plain, plainLen); + break; + case FLAG_MESSAGE: + TransTdcSendAck(&channel, seqNum); + TransOnDataReceived(channel.channelId, plain, plainLen, TRANS_SESSION_MESSAGE); + break; + default: + LOG_ERR("unknown flag"); + break; + } + + SoftBusFree(plain); + return SOFTBUS_OK; +} + +static int32_t TransTdcProcessPackets(int32_t fd, char *data, uint32_t size, uint32_t offset) +{ + if (data == NULL || offset != sizeof(TcpDataPacketHead)) { + LOG_ERR("invalid input param."); + return SOFTBUS_ERR; + } + + TcpDataPacketHead *pktHead = (TcpDataPacketHead *)data; + if (pktHead->magicNumber != MAGIC_NUMBER) { + LOG_ERR("invalid packetHead"); + return SOFTBUS_INVALID_DATA_HEAD; + } + + if (pktHead->flags != FLAG_ACK) { + if (TransTdcCheckSeq(fd, pktHead->seq) != SOFTBUS_OK) { + LOG_ERR("cannot get tdc info"); + return SOFTBUS_ERR; + } + } + + uint32_t dataLen = pktHead->dataLen; + if (dataLen > size) { + LOG_ERR("buffer is not enough"); + return SOFTBUS_INVALID_FD; + } + int rc = RecvTcpData(fd, data + offset, dataLen, 0); + if (rc < 0) { + LOG_ERR("connection break"); + return SOFTBUS_INVALID_FD; + } + if ((uint32_t)rc != dataLen) { + LOG_ERR("dataPacketRecv failed"); + return SOFTBUS_ERR; + } + + return SOFTBUS_OK; +} + +int32_t TransTdcPreProcessRecvData(int32_t fd, char *data, uint32_t size) +{ + ssize_t rc = RecvTcpData(fd, data, DC_DATA_HEAD_SIZE, 0); + if (rc < 0) { + return SOFTBUS_INVALID_FD; + } + if (rc == DC_DATA_HEAD_SIZE) { + return TransTdcProcessPackets(fd, data, size, rc); + } + + return SOFTBUS_ERR; +} diff --git a/tests/core/authentication/BUILD.gn b/tests/core/authentication/BUILD.gn new file mode 100755 index 000000000..65fbdafe1 --- /dev/null +++ b/tests/core/authentication/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/auth" + +ohos_unittest("AuthTest") { + module_out_path = module_output_path + sources = [ "unittest/auth_test.cpp" ] + + include_dirs = [ + "//base/security/deviceauth/interfaces/innerkits", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/authentication/include", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/frame/standard/server/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "//utils/native/base/include", + "//third_party/cJSON", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":AuthTest" ] +} diff --git a/tests/core/authentication/unittest/auth_test.cpp b/tests/core/authentication/unittest/auth_test.cpp new file mode 100644 index 000000000..198c35310 --- /dev/null +++ b/tests/core/authentication/unittest/auth_test.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "auth_common.h" +#include "auth_connection.h" +#include "auth_interface.h" +#include "auth_manager.h" +#include "auth_sessionkey.h" +#include "message_handler.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_server_frame.h" + +namespace OHOS { +using namespace testing::ext; +constexpr char SERVER_MAC[BT_MAC_LEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; +constexpr char CLIENT_MAC[BT_MAC_LEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x07}; +constexpr uint8_t ENCRYPT_DATA[] = "auth_encrypt_data_test."; +constexpr uint8_t SESSION_KEY[4] = {'a', 'b', 'c', 'd'}; +constexpr uint32_t SESSION_KEY_LEN = 4; +constexpr uint64_t DEFAULT_SEQ = 123456789; +constexpr char UUID[] = "B4FE52C465D0A53D5AECE2ED9498F28BEA87C8FE3F1581CFFC673425B11F6608"; +constexpr char UDID[] = "AE3017B79036A7EE19991538BBE303E8826CEB2B5B6CC5130BD74C83BF63137F"; + +class AuthTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AuthTest::SetUpTestCase() +{ +} + +void AuthTest::TearDownTestCase() +{ +} + +void AuthTest::SetUp() +{ + LOG_INFO("AuthTest start."); +} + +void AuthTest::TearDown() +{ +} + +void OnDeviceVerifyPass(int64_t authId, ConnectOption *option, SoftBusVersion peerVersion) +{ + (void)option; + (void)peerVersion; + LOG_INFO("OnDeviceVerifyPass! authId=%lld", authId); +} + +void OnDeviceVerifyFail(int64_t authId, ConnectOption *option) +{ + (void)option; + LOG_INFO("OnDeviceVerifyFail! authId=%lld", authId); +} + +void OnRecvSyncDeviceInfo(int64_t authId, AuthSideFlag side, const char *peerUdid, uint8_t *data, uint32_t len) +{ + (void)side; + (void)peerUdid; + (void)data; + (void)len; + LOG_INFO("OnRecvSyncDeviceInfo! authId=%lld", authId); +} + +void OnDeviceNotTrusted(const char *peerUdid) +{ + (void)peerUdid; + LOG_INFO("OnDeviceNotTrusted!"); +} + +/* +* @tc.name: AUTH_INIT_Test_001 +* @tc.desc: auth init test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_INIT_Test_001, TestSize.Level0) +{ + int32_t ret; + ret = LooperInit(); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = ConnServerInit(); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = AuthInit(); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +/* +* @tc.name: AUTH_REG_CB_Test_001 +* @tc.desc: register auth callback test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_REG_CB_Test_001, TestSize.Level0) +{ + int32_t ret; + VerifyCallback cb = {0}; + cb.onDeviceVerifyPass = OnDeviceVerifyPass; + cb.onDeviceVerifyFail = OnDeviceVerifyFail; + cb.onRecvSyncDeviceInfo = OnRecvSyncDeviceInfo; + cb.onDeviceNotTrusted = OnDeviceNotTrusted; + + ret = AuthRegCallback(LNN, &cb); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +/* +* @tc.name: AUTH_SET_SESSIONKEY_Test_001 +* @tc.desc: set server side sessionkey test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_SET_SESSIONKEY_Test_001, TestSize.Level0) +{ + int32_t ret; + NecessaryDevInfo devInfo = {0}; + devInfo.type = CONNECT_BR; + devInfo.side = SERVER_SIDE_FLAG; + ret = memcpy_s(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, CLIENT_MAC, BT_MAC_LEN); + EXPECT_TRUE(ret == EOK); + devInfo.deviceKeyLen = BT_MAC_LEN; + devInfo.seq = DEFAULT_SEQ; + AuthSetLocalSessionKey(&devInfo, "udid_server", SESSION_KEY, SESSION_KEY_LEN); +} + +/* +* @tc.name: AUTH_SET_SESSIONKEY_Test_002 +* @tc.desc: set client side sessionkey test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_SET_SESSIONKEY_Test_002, TestSize.Level0) +{ + int32_t ret; + NecessaryDevInfo devInfo; + devInfo.type = CONNECT_BR; + devInfo.side = CLIENT_SIDE_FLAG; + ret = memcpy_s(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, SERVER_MAC, BT_MAC_LEN); + EXPECT_TRUE(ret == EOK); + devInfo.deviceKeyLen = BT_MAC_LEN; + devInfo.seq = DEFAULT_SEQ; + AuthSetLocalSessionKey(&devInfo, "udid_client", SESSION_KEY, SESSION_KEY_LEN); +} + +/* +* @tc.name: AUTH_ENCRYPT_AND_DECRYPT_Test_001 +* @tc.desc: auth encrypt and decrypt data test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_ENCRYPT_AND_DECRYPT_Test_001, TestSize.Level0) +{ + int32_t ret; + AuthSideFlag clientSide; + ConnectOption option; + option.type = CONNECT_BR; + + ret = memcpy_s(option.info.brOption.brMac, BT_MAC_LEN, SERVER_MAC, BT_MAC_LEN); + EXPECT_TRUE(ret == EOK); + uint32_t totalLen = strlen((char *)ENCRYPT_DATA) + AuthGetEncryptHeadLen(); + uint8_t *sendBuf = (uint8_t *)SoftBusMalloc(totalLen); + ASSERT_TRUE(sendBuf != NULL); + (void)memset_s(sendBuf, totalLen, 0, totalLen); + OutBuf outBuf; + outBuf.buf = sendBuf; + outBuf.bufLen = totalLen; + ret= AuthEncrypt(&option, &clientSide, (uint8_t *)ENCRYPT_DATA, strlen((char *)ENCRYPT_DATA), &outBuf); + EXPECT_TRUE(ret == SOFTBUS_OK); + + ConnectOption option1; + option1.type = CONNECT_BR; + + ret = memcpy_s(option1.info.brOption.brMac, BT_MAC_LEN, CLIENT_MAC, BT_MAC_LEN); + EXPECT_TRUE(ret == EOK); + uint8_t *recvBuf = (uint8_t *)SoftBusMalloc(strlen((char *)ENCRYPT_DATA) + 1); + if (recvBuf == NULL) { + SoftBusFree(sendBuf); + } + ASSERT_TRUE(recvBuf != NULL); + (void)memset_s(recvBuf, strlen((char *)ENCRYPT_DATA) + 1, 0, strlen((char *)ENCRYPT_DATA) + 1); + OutBuf outBuf1; + outBuf1.buf = recvBuf; + outBuf1.bufLen = strlen((char *)ENCRYPT_DATA) + 1; + ret = AuthDecrypt(&option1, SERVER_SIDE_FLAG, outBuf.buf, outBuf.outLen, &outBuf1); + EXPECT_TRUE(ret == SOFTBUS_OK); + SoftBusFree(sendBuf); + SoftBusFree(recvBuf); +} + +static cJSON *AuthPackDeviceInfo(void) +{ + cJSON *msg = cJSON_CreateObject(); + if (msg == NULL) { + return NULL; + } + + EXPECT_TRUE(AddStringToJsonObject(msg, CMD_TAG, CMD_RET_AUTH_INFO)); + EXPECT_TRUE(AddStringToJsonObject(msg, DATA_TAG, UUID)); + EXPECT_TRUE(AddStringToJsonObject(msg, TE_DEVICE_ID_TAG, UDID)); + EXPECT_TRUE(AddNumberToJsonObject(msg, DATA_BUF_SIZE_TAG, PACKET_SIZE)); + EXPECT_TRUE(AddNumberToJsonObject(msg, SOFTBUS_VERSION_INFO, SOFT_BUS_NEW_V1)); + return msg; +} + +/* +* @tc.name: AUTH_PACK_AND_UNPACK_Test_001 +* @tc.desc: auth pack and unpack data test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_PACK_AND_UNPACK_Test_001, TestSize.Level0) +{ + cJSON *obj = AuthPackDeviceInfo(); + EXPECT_TRUE(obj != NULL); + char *msgStr = cJSON_PrintUnformatted(obj); + EXPECT_TRUE(msgStr != NULL); + cJSON_Delete(obj); + cJSON *msg = cJSON_Parse((char*)msgStr); + cJSON_free(msgStr); + char cmd[CMD_TAG_LEN] = {0}; + EXPECT_TRUE(GetJsonObjectStringItem(msg, CMD_TAG, cmd, CMD_TAG_LEN)); + char uuid[UUID_BUF_LEN] = {0}; + EXPECT_TRUE(GetJsonObjectStringItem(msg, DATA_TAG, uuid, UUID_BUF_LEN)); + char deviceUdid[UDID_BUF_LEN] = {0}; + EXPECT_TRUE(GetJsonObjectStringItem(msg, TE_DEVICE_ID_TAG, deviceUdid, UDID_BUF_LEN)); + int32_t packetSize; + EXPECT_TRUE(GetJsonObjectNumberItem(msg, DATA_BUF_SIZE_TAG, &packetSize)); + int32_t peerVersion; + EXPECT_TRUE(GetJsonObjectNumberItem(msg, SOFTBUS_VERSION_INFO, &peerVersion)); + cJSON_Delete(msg); +} + +/* +* @tc.name: AUTH_DEINIT_Test_001 +* @tc.desc: auth deinit test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(AuthTest, AUTH_DEINIT_Test_001, TestSize.Level0) +{ + ConnServerDeinit(); + AuthDeinit(); + LooperDeinit(); +} +} \ No newline at end of file diff --git a/tests/core/bus_center/lnn/BUILD.gn b/tests/core/bus_center/lnn/BUILD.gn new file mode 100755 index 000000000..12fb010d7 --- /dev/null +++ b/tests/core/bus_center/lnn/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/LNN" + +ohos_unittest("LNNTest") { + module_out_path = module_output_path + sources = [ + "unittest/ledger_lane_hub_test.cpp", + "unittest/net_builder_test.cpp", + ] + + include_dirs = [ + "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_builder/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/distributed_ledger/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/local_ledger/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/sync_ledger/include", + "$dsoftbus_root_path/core/bus_center/lnn/net_ledger/common/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/authentication/interface", + "$dsoftbus_root_path/core/bus_center/interface", + "$dsoftbus_root_path/core/bus_center/utils/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/adapter/bus_center/include", + "//utils/native/base/include", + "//third_party/cJSON", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":LNNTest" ] +} diff --git a/tests/core/bus_center/lnn/unittest/ledger_lane_hub_test.cpp b/tests/core/bus_center/lnn/unittest/ledger_lane_hub_test.cpp new file mode 100644 index 000000000..4081cfb1d --- /dev/null +++ b/tests/core/bus_center/lnn/unittest/ledger_lane_hub_test.cpp @@ -0,0 +1,649 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "bus_center_info_key.h" +#include "lnn_distributed_net_ledger.h" +#include "lnn_exchange_ledger_info.h" +#include "lnn_lane_manager.h" +#include "lnn_local_net_ledger.h" +#include "lnn_sync_ledger_item_info.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +namespace OHOS { +using namespace testing::ext; +constexpr char NODE1_DEVICE_NAME[] = "node1_test"; +constexpr char NODE1_UDID[] = "123456ABCDEF"; +constexpr char NODE1_NETWORK_ID[] = "235689BNHFCF"; +constexpr char NODE1_UUID[] = "235689BNHFCC"; +constexpr char NODE1_BT_MAC[] = "56789TTU"; +constexpr uint32_t NODE1_AUTH_SEQ_NUM = 100; +constexpr char NODE2_DEVICE_NAME[] = "node2_test"; +constexpr char NODE2_UDID[] = "123456ABCDEG"; +constexpr char NODE2_NETWORK_ID[] = "235689BNHFCG"; +constexpr char NODE2_UUID[] = "235689BNHFCD"; +constexpr char NODE2_BT_MAC[] = "56789TYU"; +constexpr char CHANGE_DEVICE_NAME[] = "change_test"; +constexpr char NODE3_DEVICE_NAME[] = "node3_test"; +constexpr char NODE3_UDID[] = "123456ABCDEX"; +constexpr char NODE3_NETWORK_ID[] = "235689BNHFCX"; +constexpr char NODE3_UUID[] = "235689BNHFCX"; +constexpr char NODE3_BT_MAC[] = "56789TYX"; +constexpr uint32_t REMOTE_PROXY_PORT = 8080; +constexpr uint32_t REMOTE_AUTH_PORT = 7070; +constexpr uint32_t NODE_NUM = 3; +constexpr char LOCAL_UDID[] = "123456LOCALTEST"; +constexpr char LOCAL_NETWORKID[] = "235689LOCAL"; +constexpr char LOCAL_UUID[] = "235999LOCAL"; +constexpr char LOCAL_DEVNAME[] = "local_test"; +constexpr char LOCAL_CHANAGE_DEVNAME[] = "local"; +constexpr char LOCAL_BT_MAC[] = "56789TUT"; +constexpr char LOCAL_WLAN_IP[] = "10.146.181.134"; +constexpr char LOCAL_DEVTYPE[] = TYPE_WATCH; +constexpr uint32_t LOCAL_SESSION_POORT = 5000; +constexpr uint32_t LOCAL_AUTH_PORT = 6000; +constexpr uint32_t LOCAL_PROXY_PORT = 7000; +constexpr uint32_t BR_NUM = 0; +constexpr uint32_t WLAN2P4G_NUM = 1; +constexpr uint32_t WLAN5G_NUM = 2; +constexpr uint32_t LANES_NUM = 1; +static NodeInfo g_nodeInfo[NODE_NUM]; +constexpr uint32_t LANE_HUB_USEC = 1000000; +constexpr uint32_t LANE_HUB_MSEC = 1000; +constexpr uint32_t LOCAL_MAX_SIZE = 128; + +class LedgerLaneHubTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void LedgerLaneHubTest::SetUpTestCase() +{ +} + +void LedgerLaneHubTest::TearDownTestCase() +{ +} + +void LedgerLaneHubTest::SetUp() +{ + int32_t ret = LnnInitDistributedLedger(); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnInitLocalLedger(); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnInitSyncLedgerItem(); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnLanesInit(); + GTEST_LOG_(INFO) << "LaneHubTest start."; +} + +void LedgerLaneHubTest::TearDown() +{ +} + +static void ConstructBRNode(void) +{ + int32_t ret; + uint32_t cap = 0; + LnnSetNetCapability(&cap, BIT_BR); + g_nodeInfo[BR_NUM].netCapacity = cap; + ret = LnnSetDeviceUdid(&g_nodeInfo[BR_NUM], NODE1_UDID); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnSetBtMac(&g_nodeInfo[BR_NUM], NODE1_BT_MAC); + ret = LnnSetDeviceName(&g_nodeInfo[BR_NUM].deviceInfo, NODE1_DEVICE_NAME); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = strncpy_s(g_nodeInfo[BR_NUM].networkId, NETWORK_ID_BUF_LEN, NODE1_NETWORK_ID, strlen(NODE1_NETWORK_ID)); + EXPECT_TRUE(ret == EOK); + ret = strncpy_s(g_nodeInfo[BR_NUM].uuid, UUID_BUF_LEN, NODE1_UUID, strlen(NODE1_UUID)); + EXPECT_TRUE(ret == EOK); + g_nodeInfo[BR_NUM].authSeqNum = NODE1_AUTH_SEQ_NUM; + ret = LnnSetDiscoveryType(&g_nodeInfo[BR_NUM], DISCOVERY_TYPE_BR); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void ConstructWlan2P4GNode(void) +{ + int32_t ret; + uint32_t cap = 0; + LnnSetNetCapability(&cap, BIT_WIFI_24G); + g_nodeInfo[WLAN2P4G_NUM].netCapacity = cap; + ret = LnnSetDeviceUdid(&g_nodeInfo[WLAN2P4G_NUM], NODE2_UDID); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnSetBtMac(&g_nodeInfo[WLAN2P4G_NUM], NODE2_BT_MAC); + ret = LnnSetDeviceName(&g_nodeInfo[WLAN2P4G_NUM].deviceInfo, NODE2_DEVICE_NAME); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = strncpy_s(g_nodeInfo[WLAN2P4G_NUM].networkId, NETWORK_ID_BUF_LEN, NODE2_NETWORK_ID, strlen(NODE2_NETWORK_ID)); + EXPECT_TRUE(ret == EOK); + ret = strncpy_s(g_nodeInfo[WLAN2P4G_NUM].uuid, UUID_BUF_LEN, NODE2_UUID, strlen(NODE2_UUID)); + EXPECT_TRUE(ret == EOK); + g_nodeInfo[WLAN2P4G_NUM].authSeqNum = NODE1_AUTH_SEQ_NUM; + ret = LnnSetDiscoveryType(&g_nodeInfo[WLAN2P4G_NUM], DISCOVERY_TYPE_BLE); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetProxyPort(&g_nodeInfo[WLAN2P4G_NUM], REMOTE_PROXY_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnSetWiFiIp(&g_nodeInfo[WLAN2P4G_NUM], LOCAL_WLAN_IP); + ret = LnnSetAuthPort(&g_nodeInfo[WLAN2P4G_NUM], REMOTE_AUTH_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void ConstructWlan5GNode(void) +{ + int32_t ret; + uint32_t cap = 0; + LnnSetNetCapability(&cap, BIT_WIFI_5G); + g_nodeInfo[WLAN5G_NUM].netCapacity = cap; + ret = LnnSetDeviceUdid(&g_nodeInfo[WLAN5G_NUM], NODE3_UDID); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnSetBtMac(&g_nodeInfo[WLAN5G_NUM], NODE3_BT_MAC); + ret = LnnSetDeviceName(&g_nodeInfo[WLAN5G_NUM].deviceInfo, NODE3_DEVICE_NAME); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = strncpy_s(g_nodeInfo[WLAN5G_NUM].networkId, NETWORK_ID_BUF_LEN, NODE3_NETWORK_ID, strlen(NODE3_NETWORK_ID)); + EXPECT_TRUE(ret == EOK); + ret = strncpy_s(g_nodeInfo[WLAN5G_NUM].uuid, UUID_BUF_LEN, NODE3_UUID, strlen(NODE3_UUID)); + EXPECT_TRUE(ret == EOK); + g_nodeInfo[WLAN5G_NUM].authSeqNum = NODE1_AUTH_SEQ_NUM; + ret = LnnSetDiscoveryType(&g_nodeInfo[WLAN5G_NUM], DISCOVERY_TYPE_BLE); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetProxyPort(&g_nodeInfo[WLAN5G_NUM], REMOTE_PROXY_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); + LnnSetWiFiIp(&g_nodeInfo[WLAN5G_NUM], LOCAL_WLAN_IP); + ret = LnnSetAuthPort(&g_nodeInfo[WLAN5G_NUM], REMOTE_AUTH_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void ConstructCommonLocalInfo(void) +{ + int32_t ret = LnnSetLocalLedgerStrInfo(STRING_KEY_DEV_UDID, LOCAL_UDID); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_NETWORKID, LOCAL_NETWORKID); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_UUID, LOCAL_UUID); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_DEV_TYPE, LOCAL_DEVTYPE); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_DEV_NAME, LOCAL_DEVNAME); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void ConstructBtLocalInfo(void) +{ + int32_t ret = LnnSetLocalLedgerStrInfo(STRING_KEY_BT_MAC, LOCAL_BT_MAC); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerNumInfo(NUM_KEY_NET_CAP, 1 << BIT_BR); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void ConstructWiFiLocalInfo(bool is5G) +{ + int32_t ret = LnnSetLocalLedgerNumInfo(NUM_KEY_AUTH_PORT, LOCAL_AUTH_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerNumInfo(NUM_KEY_PROXY_PORT, LOCAL_PROXY_PORT); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerNumInfo(NUM_KEY_SESSION_PORT, LOCAL_SESSION_POORT); + EXPECT_TRUE(ret == SOFTBUS_OK); + if (is5G) { + ret = LnnSetLocalLedgerNumInfo(NUM_KEY_NET_CAP, 1 << BIT_WIFI_5G); + } else { + ret = LnnSetLocalLedgerNumInfo(NUM_KEY_NET_CAP, 1 << BIT_WIFI_24G); + } + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_WLAN_IP, LOCAL_WLAN_IP); + EXPECT_TRUE(ret == SOFTBUS_OK); +} + +static void GetCommonLocalInfo(void) +{ + int32_t ret; + char des[LOCAL_MAX_SIZE] = {0}; + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_UDID, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_UDID) == 0)); + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_NETWORKID, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_NETWORKID) == 0)); + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_UUID, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_UUID) == 0)); + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_TYPE, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_DEVTYPE) == 0)); + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_NAME, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_DEVNAME) == 0)); +} + +static void GetBTLocalInfo(void) +{ + int32_t ret; + char des[LOCAL_MAX_SIZE] = {0}; + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_BT_MAC, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_BT_MAC) == 0)); +} + +static void GetWiFiLocalInfo(void) +{ + int32_t ret; + int32_t port = 0; + ret = LnnGetLocalLedgerNumInfo(NUM_KEY_AUTH_PORT, &port); + EXPECT_TRUE((ret == SOFTBUS_OK) && (port == LOCAL_AUTH_PORT)); + ret = LnnGetLocalLedgerNumInfo(NUM_KEY_PROXY_PORT, &port); + EXPECT_TRUE((ret == SOFTBUS_OK) && (port == LOCAL_PROXY_PORT)); + ret = LnnGetLocalLedgerNumInfo(NUM_KEY_SESSION_PORT, &port); + EXPECT_TRUE((ret == SOFTBUS_OK) && (port == LOCAL_SESSION_POORT)); +} +/* +* @tc.name: LANE_HUB_WLAN2P4G_MESSAGE_LANE_Test_001 +* @tc.desc: Wlan2P4G message lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN2P4G_MESSAGE_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(false); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE2_NETWORK_ID, LNN_MESSAGE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_2P4G && laneInfo != NULL && laneInfo->isProxy && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_PROXY_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN2P4G_BYTES_LANE_Test_001 +* @tc.desc: Wlan2P4G bytes lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN2P4G_BYTES_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(false); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE2_NETWORK_ID, LNN_BYTES_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_2P4G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN2P4G_FILE_LANE_Test_001 +* @tc.desc: Wlan2P4G file lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN2P4G_FILE_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(false); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE2_NETWORK_ID, LNN_FILE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_2P4G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN2P4G_STREAM_LANE_Test_001 +* @tc.desc: Wlan2P4G stream lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN2P4G_STREAM_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(false); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE2_NETWORK_ID, LNN_STREAM_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_2P4G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN5G_MESSAGE_LANE_Test_001 +* @tc.desc: Wlan5G message lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN5G_MESSAGE_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan5GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN5G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(true); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE3_NETWORK_ID, LNN_MESSAGE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_5G && laneInfo != NULL && laneInfo->isProxy && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_PROXY_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN5G_BYTES_LANE_Test_001 +* @tc.desc: Wlan5G bytes lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN5G_BYTES_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan5GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN5G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(true); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE3_NETWORK_ID, LNN_BYTES_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_5G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN5G_FILE_LANE_Test_001 +* @tc.desc: Wlan2P4G file lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN5G_FILE_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN5G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(true); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE3_NETWORK_ID, LNN_FILE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_5G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_WLAN5G_STREAM_LANE_Test_001 +* @tc.desc: Wlan5G stream lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_WLAN5G_STREAM_LANE_Test_001, TestSize.Level0) +{ + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN5G_NUM]); + ConstructCommonLocalInfo(); + ConstructWiFiLocalInfo(true); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE3_NETWORK_ID, LNN_STREAM_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_WLAN_5G && laneInfo != NULL && laneInfo->isProxy == false && + laneInfo->conOption.type == CONNECTION_ADDR_WLAN && + strncmp(laneInfo->conOption.info.ip.ip, LOCAL_WLAN_IP, strlen(LOCAL_WLAN_IP)) == 0 && + laneInfo->conOption.info.ip.port == REMOTE_AUTH_PORT); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_BR_MESSAGE_LANE_Test_001 +* @tc.desc: BR message lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_BR_MESSAGE_LANE_Test_001, TestSize.Level0) +{ + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE1_NETWORK_ID, LNN_MESSAGE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_BR && laneInfo != NULL && laneInfo->isProxy && + laneInfo->conOption.type == CONNECTION_ADDR_BR && + strncmp(laneInfo->conOption.info.br.brMac, NODE1_BT_MAC, strlen(NODE1_BT_MAC)) == 0); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_BR_BYTES_LANE_Test_001 +* @tc.desc: BR bytes lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_BR_BYTES_LANE_Test_001, TestSize.Level0) +{ + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE1_NETWORK_ID, LNN_BYTES_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_BR && laneInfo != NULL && laneInfo->isProxy && + laneInfo->conOption.type == CONNECTION_ADDR_BR && + strncmp(laneInfo->conOption.info.br.brMac, NODE1_BT_MAC, strlen(NODE1_BT_MAC)) == 0); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_BR_FILE_LANE_Test_001 +* @tc.desc: BR file lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_BR_FILE_LANE_Test_001, TestSize.Level0) +{ + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE1_NETWORK_ID, LNN_FILE_LANE, LANES_NUM); + int32_t laneId = LnnGetLaneId(lanesObj, 0); + const LnnLaneInfo *laneInfo = LnnGetConnection(laneId); + EXPECT_TRUE(laneId == LNN_LINK_TYPE_BR && laneInfo != NULL && laneInfo->isProxy && + laneInfo->conOption.type == CONNECTION_ADDR_BR && + strncmp(laneInfo->conOption.info.br.brMac, NODE1_BT_MAC, strlen(NODE1_BT_MAC)) == 0); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_BR_STREAM_LANE_Test_001 +* @tc.desc: BR stream lane test +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_BR_STREAM_LANE_Test_001, TestSize.Level0) +{ + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE1_NETWORK_ID, LNN_STREAM_LANE, LANES_NUM); + EXPECT_TRUE(lanesObj == NULL); + LnnReleaseLanesObject(lanesObj); +} + +/* +* @tc.name: LANE_HUB_LnnRequestLanesObject_Test_001 +* @tc.desc: Performance test of the LnnRequestLanesObject function +* @tc.type: FUNC +* @tc.require: AR000FK6IU +*/ +HWTEST_F(LedgerLaneHubTest, LANE_HUB_LnnRequestLanesObject_Test_001, TestSize.Level0) +{ + struct timeval start; + struct timeval end; + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + + int testCount = 1000; + int times = 0; + gettimeofday(&start, NULL); + while (testCount--) { + LnnLanesObject *lanesObj = LnnRequestLanesObject(NODE1_NETWORK_ID, LNN_FILE_LANE, LANES_NUM); + EXPECT_TRUE(lanesObj != NULL); + LnnReleaseLanesObject(lanesObj); + times++; + } + gettimeofday(&end, NULL); + + int interval = LANE_HUB_USEC * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec); + int threshold = LANE_HUB_MSEC * times; + EXPECT_LT(interval, threshold); +} + +/* +* @tc.name: LEDGER_GetDistributedLedgerNode_Test_001 +* @tc.desc: Get distributed ledger node info. +* @tc.type: FUNC +* @tc.require: AR000FK6J0 +*/ +HWTEST_F(LedgerLaneHubTest, LEDGER_GetDistributedLedgerNode_Test_001, TestSize.Level0) +{ + NodeInfo *infoNetwork = NULL; + NodeInfo *infoUuid = NULL; + NodeInfo *infoUdid = NULL; + ConstructBRNode(); + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + + // GET CATEGORY_NETWORK_ID and CATEGORY_UUID + infoNetwork = LnnGetNodeInfoById(NODE1_NETWORK_ID, CATEGORY_NETWORK_ID); + infoUuid = LnnGetNodeInfoById(NODE1_UUID, CATEGORY_UUID); + infoUdid = LnnGetNodeInfoById(NODE1_UDID, CATEGORY_UDID); + EXPECT_TRUE((infoNetwork == infoUuid) && (infoNetwork == infoUdid)); + LnnRemoveNode(NODE1_UDID); + LnnRemoveNode(NODE2_UDID); +} + +/* +* @tc.name: LEDGER_GetDistributedLedgerInfo_Test_001 +* @tc.desc: test of the LnnGetDLStrInfo LnnGetDLNumInfo function +* @tc.type: FUNC +* @tc.require: AR000FK6J0 +*/ +HWTEST_F(LedgerLaneHubTest, LEDGER_GetDistributedLedgerInfo_Test_001, TestSize.Level0) +{ + char deviceName[DEVICE_NAME_BUF_LEN] = {0}; + char macAddr[MAC_LEN] = {0}; + int32_t ret; + uint32_t cap = 0; + ConstructBRNode(); + LnnAddOnlineNode(&g_nodeInfo[BR_NUM]); + + // STRING_KEY_DEV_NAME + ret = LnnGetDLStrInfo(NODE1_NETWORK_ID, STRING_KEY_DEV_NAME, deviceName, DEVICE_NAME_BUF_LEN); + EXPECT_TRUE(ret == SOFTBUS_OK); + EXPECT_TRUE(strcmp(deviceName, NODE1_DEVICE_NAME) == 0); + + // STRING_KEY_BT_MAC + ret = LnnGetDLStrInfo(NODE1_NETWORK_ID, STRING_KEY_BT_MAC, macAddr, MAC_LEN); + EXPECT_TRUE(ret == SOFTBUS_OK); + EXPECT_TRUE(strcmp(macAddr, NODE1_BT_MAC) == 0); + + // NUM_KEY_NET_CAP + ret = LnnGetDLNumInfo(NODE1_NETWORK_ID, NUM_KEY_NET_CAP, (int32_t *)&cap); + EXPECT_TRUE(ret == SOFTBUS_OK); + EXPECT_TRUE((cap & (1 << BIT_BR)) != 0); + + LnnRemoveNode(NODE1_UDID); +} + +/* +* @tc.name: LEDGER_DistributedLedgerChangeName_Test_001 +* @tc.desc: test of the LnnGetDLStrInfo LnnSetDLDeviceInfoName function +* @tc.type: FUNC +* @tc.require: AR000FK6J0 +*/ +HWTEST_F(LedgerLaneHubTest, LEDGER_DistributedLedgerChangeName_Test_001, TestSize.Level0) +{ + char deviceName[DEVICE_NAME_BUF_LEN] = {0}; + ConstructWlan2P4GNode(); + LnnAddOnlineNode(&g_nodeInfo[WLAN2P4G_NUM]); + + // change name + bool result = LnnSetDLDeviceInfoName(NODE2_UDID, CHANGE_DEVICE_NAME); + EXPECT_TRUE(result); + // STRING_KEY_DEV_NAME + int ret = LnnGetDLStrInfo(NODE2_NETWORK_ID, STRING_KEY_DEV_NAME, deviceName, DEVICE_NAME_BUF_LEN); + EXPECT_TRUE(ret == SOFTBUS_OK); + EXPECT_TRUE(strcmp(deviceName, CHANGE_DEVICE_NAME) == 0); + LnnRemoveNode(NODE2_UDID); +} + +/* +* @tc.name: LEDGER_LocalLedgerGetInfo_Test_001 +* @tc.desc: Performance test of the LnnGetLocalLedgerStrInfo and NumInfo function. +* @tc.type: FUNC +* @tc.require: AR000FK6J0 +*/ +HWTEST_F(LedgerLaneHubTest, LEDGER_LocalLedgerGetInfo_Test_001, TestSize.Level0) +{ + char des[LOCAL_MAX_SIZE] = {0}; + int32_t ret; + ConstructCommonLocalInfo(); + ConstructBtLocalInfo(); + ConstructWiFiLocalInfo(false); + GetCommonLocalInfo(); + GetBTLocalInfo(); + GetWiFiLocalInfo(); + + // change devicename + ret = LnnSetLocalLedgerStrInfo(STRING_KEY_DEV_NAME, LOCAL_CHANAGE_DEVNAME); + EXPECT_TRUE(ret == SOFTBUS_OK); + ret = LnnGetLocalLedgerStrInfo(STRING_KEY_DEV_NAME, des, LOCAL_MAX_SIZE); + EXPECT_TRUE((ret == SOFTBUS_OK) && (strcmp(des, LOCAL_CHANAGE_DEVNAME) == 0)); +} +} \ No newline at end of file diff --git a/tests/core/bus_center/lnn/unittest/net_builder_test.cpp b/tests/core/bus_center/lnn/unittest/net_builder_test.cpp new file mode 100644 index 000000000..c529d4f52 --- /dev/null +++ b/tests/core/bus_center/lnn/unittest/net_builder_test.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "bus_center_info_key.h" +#include "lnn_connection_addr_utils.h" +#include "lnn_network_id.h" +#include "softbus_bus_center.h" +#include "softbus_errcode.h" + +namespace OHOS { +using namespace testing::ext; + +constexpr char BT_MAC[] = "12:34:56:78"; +constexpr char WLAN_IP[] = "10.146.181.134"; + +class NetBuilderTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void NetBuilderTest::SetUpTestCase() +{ +} + +void NetBuilderTest::TearDownTestCase() +{ +} + +void NetBuilderTest::SetUp() +{ +} + +void NetBuilderTest::TearDown() +{ +} + +/* +* @tc.name: NET_BUILDER_GEN_ID_Test_001 +* @tc.desc: generate network id interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J3 +*/ +HWTEST_F(NetBuilderTest, NET_BUILDER_GEN_ID_Test_001, TestSize.Level0) +{ + char networkIdFirst[NETWORK_ID_BUF_LEN] = {0}; + char networkIdSecond[NETWORK_ID_BUF_LEN] = {0}; + + EXPECT_TRUE(LnnGenLocalNetworkId(networkIdFirst, NETWORK_ID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(LnnGenLocalNetworkId(networkIdSecond, NETWORK_ID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(strncmp(networkIdFirst, networkIdSecond, NETWORK_ID_BUF_LEN) != 0); +} + +/* +* @tc.name: NET_BUILDER_GEN_ID_Test_002 +* @tc.desc: generate uuid interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J3 +*/ +HWTEST_F(NetBuilderTest, NET_BUILDER_GEN_ID_Test_002, TestSize.Level0) +{ + char uuidFirst[UUID_BUF_LEN] = {0}; + char uuidSecond[UUID_BUF_LEN] = {0}; + + EXPECT_TRUE(LnnGenLocalUuid(uuidFirst, UUID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(LnnGenLocalUuid(uuidSecond, UUID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(strncmp(uuidFirst, uuidSecond, UUID_BUF_LEN) == 0); +} + +/* +* @tc.name: NET_BUILDER_CONNECTION_ADDR_Test_001 +* @tc.desc: connection address compare interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J2 +*/ +HWTEST_F(NetBuilderTest, NET_BUILDER_CONNECTION_ADDR_Test_001, TestSize.Level0) +{ + ConnectionAddr bleAddr = { + .type = CONNECTION_ADDR_BR, + }; + ConnectionAddr ethAddr = { + .type = CONNECTION_ADDR_ETH, + }; + + EXPECT_TRUE(strncpy_s(bleAddr.info.br.brMac, BT_MAC_LEN, BT_MAC, strlen(BT_MAC)) == EOK); + EXPECT_TRUE(strncpy_s(bleAddr.info.ip.ip, IP_STR_MAX_LEN, WLAN_IP, strlen(WLAN_IP)) == EOK); + EXPECT_TRUE(LnnIsSameConnectionAddr(&bleAddr, &bleAddr)); + EXPECT_TRUE(LnnIsSameConnectionAddr(ðAddr, ðAddr)); + EXPECT_FALSE(LnnIsSameConnectionAddr(&bleAddr, ðAddr)); +} +} // namespace OHOS diff --git a/tests/core/common/security/BUILD.gn b/tests/core/common/security/BUILD.gn new file mode 100755 index 000000000..270c9abf4 --- /dev/null +++ b/tests/core/common/security/BUILD.gn @@ -0,0 +1,72 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/common" + +ohos_prebuilt_etc("softbus_permission_json_test") { + source = "softbus_permission_test.json" + install_enable = true + relative_install_dir = "communication/softbus" +} + +ohos_unittest("softbus_permission_test") { + module_out_path = module_output_path + + #ldflags = [ "-lstdc++" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/security/permission/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/common/include", + "//third_party/googletest/googletest/include", + "//third_party/googletest/googletest/src", + "//third_party/bounds_checking_function/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/interfaces/kits/common", + "//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk/main/cpp/include", + "//foundation/appexecfwk/standard/kits/appkit/native/app/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/bundlemgr/", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", + "//utils/system/safwk/native/include", + "//foundation/aafwk/standard/interfaces/innerkits/want/include", + ] + sources = [ + "$dsoftbus_root_path/core/common/security/permission/common/permission_entry.c", + "$dsoftbus_root_path/core/common/security/permission/standard_system/permission_utils.cpp", + "$dsoftbus_root_path/core/common/security/permission/standard_system/softbus_permission.cpp", + "softbus_permission_test.cpp", + ] + defines = [ "PERMISSION_TEST" ] + deps = [ + ":softbus_permission_json_test", + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//foundation/appexecfwk/standard/kits:appkit_native", + "//third_party/cJSON:cjson_static", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_core", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "permission_standard:libpermissionsdk_standard", + ] +} diff --git a/tests/core/common/security/softbus_permission_test.cpp b/tests/core/common/security/softbus_permission_test.cpp new file mode 100755 index 000000000..f8e663355 --- /dev/null +++ b/tests/core/common/security/softbus_permission_test.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "permission/permission.h" +#include "permission/permission_kit.h" +#include "permission_entry.h" +#include "permission_utils.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_permission.h" +#include "softbus_utils.h" + +using namespace testing::ext; +using namespace OHOS::Security::Permission; + +namespace OHOS { +const char *JSON_FILE = "/system/etc/communication/softbus/softbus_permission_test.json"; +const std::string SYSTEM_APP_PERMISSION = "com.huawei.permission.MANAGE_DISTRIBUTED_PERMISSION"; +const std::string DANGER_APP_PERMISSION = "ohos.permission.DISTRIBUTED_DATASYNC"; +const std::string BIND_DISCOVER_SERVICE = "com.huawei.hwddmp.permission.BIND_DISCOVER_SERVICE"; + +const std::string TEST_LABEL = "test label"; +const std::string TEST_DESCRIPTION = "test description"; +const int TEST_LABEL_ID = 9527; +const int TEST_DESCRIPTION_ID = 9528; + +class SoftbusPermissionTest : public testing::Test { +public: + SoftbusPermissionTest() + {} + ~SoftbusPermissionTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void SoftbusPermissionTest::SetUpTestCase(void) +{ + TransPermissionInit(JSON_FILE); +} + +void SoftbusPermissionTest::TearDownTestCase(void) +{ + TransPermissionDeinit(); +} + +void SoftbusPermissionTest::SetUp(void) +{} + +void SoftbusPermissionTest::TearDown(void) +{} + +void AddPermission(const string &pkgName) +{ + std::vector permDefList; + PermissionDef permissionDefAlpha = { + .permissionName = SYSTEM_APP_PERMISSION, + .bundleName = pkgName, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableScope = AVAILABLE_SCOPE_ALL, + .label = TEST_LABEL, + .labelId = TEST_LABEL_ID, + .description = TEST_DESCRIPTION, + .descriptionId = TEST_DESCRIPTION_ID + }; + PermissionDef permissionDefBeta = { + .permissionName = DANGER_APP_PERMISSION, + .bundleName = pkgName, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableScope = AVAILABLE_SCOPE_ALL, + .label = TEST_LABEL, + .labelId = TEST_LABEL_ID, + .description = TEST_DESCRIPTION, + .descriptionId = TEST_DESCRIPTION_ID + }; + PermissionDef permissionDefGamma = { + .permissionName = BIND_DISCOVER_SERVICE, + .bundleName = pkgName, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableScope = AVAILABLE_SCOPE_ALL, + .label = TEST_LABEL, + .labelId = TEST_LABEL_ID, + .description = TEST_DESCRIPTION, + .descriptionId = TEST_DESCRIPTION_ID + }; + permDefList.emplace_back(permissionDefAlpha); + permDefList.emplace_back(permissionDefBeta); + permDefList.emplace_back(permissionDefGamma); + PermissionKit::AddDefPermissions(permDefList); + std::vector permList; + permList.push_back(SYSTEM_APP_PERMISSION); + permList.push_back(DANGER_APP_PERMISSION); + permList.push_back(BIND_DISCOVER_SERVICE); + PermissionKit::AddSystemGrantedReqPermissions(pkgName, permList); + PermissionKit::GrantSystemGrantedPermission(pkgName, SYSTEM_APP_PERMISSION); + PermissionKit::GrantSystemGrantedPermission(pkgName, DANGER_APP_PERMISSION); + PermissionKit::GrantSystemGrantedPermission(pkgName, BIND_DISCOVER_SERVICE); +} + +void RemovePermission(const string &pkgName) +{ + int ret = PermissionKit::RemoveDefPermissions(pkgName); + ret = PermissionKit::RemoveSystemGrantedReqPermissions(pkgName); +} + +static std::vector g_action = { + 0, + ACTION_CREATE, + ACTION_OPEN, + ACTION_CREATE | ACTION_OPEN +}; + +/* +* @tc.name: testPermission001 +* @tc.desc: test no uid permission +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission001, TestSize.Level1) +{ + int32_t ret; + uint32_t trueAction = ACTION_CREATE | ACTION_OPEN; + const char *sessionName = "com.devicegroupmanage"; + const char *pkgName = "com.devicegroupmanage"; + AddPermission(std::string(pkgName)); + for (size_t i = 0; i < g_action.size(); i++) { + ret = CheckTransPermission(sessionName, pkgName, g_action[i]); + if (((uint32_t)(g_action[i]) & trueAction) == (uint32_t)(g_action[i]) && g_action[i] != 0) { + EXPECT_EQ(ret, SYSTEM_APP); + } else { + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + } + } + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission002 +* @tc.desc: test right uid permission +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission002, TestSize.Level1) +{ + int32_t ret; + uint32_t trueAction = ACTION_CREATE | ACTION_OPEN; + const char *sessionName = "com.systemserver_CHANNEL_DPMS"; + const char *pkgName = "com.systemserver"; + AddPermission(std::string(pkgName)); + for (size_t i = 0; i < g_action.size(); i++) { + ret = CheckTransPermission(sessionName, pkgName, g_action[i]); + if (((uint32_t)(g_action[i]) & trueAction) == (uint32_t)(g_action[i]) && g_action[i] != 0) { + EXPECT_EQ(ret, SYSTEM_APP); + } else { + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + } + } + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission003 +* @tc.desc: test wrong uid permission +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission003, TestSize.Level1) +{ + int32_t ret; + const char *sessionName = "hiview_distributed_network_softbus"; + const char *pkgName = "hiview_distributed_network_softbus"; + AddPermission(std::string(pkgName)); + for (size_t i = 0; i < g_action.size(); i++) { + ret = CheckTransPermission(sessionName, pkgName, g_action[i]); + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + } + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission004 +* @tc.desc: test reg true match +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission004, TestSize.Level1) +{ + int32_t ret; + uint32_t trueAction = ACTION_CREATE | ACTION_OPEN; + vector sessionName = { + "distributeddata.test1", + "distributeddata.test123", + "distributeddata.test", + "distributeddata.", + }; + const char *pkgName = "com.hwddmp"; + AddPermission(std::string(pkgName)); + for (size_t i = 0; i < g_action.size(); i++) { + for (size_t j = 0; j < sessionName.size(); j++) { + ret = CheckTransPermission(sessionName[j], pkgName, g_action[i]); + if (((uint32_t)(g_action[i]) & trueAction) == (uint32_t)(g_action[i]) && g_action[i] != 0) { + EXPECT_EQ(ret, SYSTEM_APP); + } else { + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + } + } + } + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission005 +* @tc.desc: test name dismatch +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission005, TestSize.Level1) +{ + int32_t ret; + int32_t trueAction = ACTION_CREATE | ACTION_OPEN; + const char *validSessionName = "com.devicegroupmanage"; + const char *invalidSessionName = "com.wrongsessionname"; + const char *validPkgName = "com.devicegroupmanage"; + const char *invalidPkgName = "com.wrongpkgname"; + AddPermission(std::string(validPkgName)); + AddPermission(std::string(invalidPkgName)); + ret = CheckTransPermission(invalidSessionName, validPkgName, trueAction); + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + ret = CheckTransPermission(validSessionName, invalidPkgName, trueAction); + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + ret = CheckTransPermission(invalidSessionName, invalidPkgName, trueAction); + EXPECT_EQ(ret, SOFTBUS_PERMISSION_DENIED); + RemovePermission(std::string(validPkgName)); + RemovePermission(std::string(invalidPkgName)); +} + +/* +* @tc.name: testPermission006 +* @tc.desc: test invalid input param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission006, TestSize.Level1) +{ + const char *sessionName = "com.devicegroupmanage"; + const char *pkgName = "com.devicegroupmanage"; + AddPermission(std::string(pkgName)); + EXPECT_EQ(NATIVE_APP, CheckTransPermission(NULL, NULL, 0)); + EXPECT_EQ(SYSTEM_APP, CheckTransPermission(NULL, pkgName, g_action[3])); + EXPECT_EQ(NATIVE_APP, CheckTransPermission(sessionName, NULL, g_action[3])); + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission007 +* @tc.desc: test system app -> appInfo self app +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission007, TestSize.Level1) +{ + const char *sessionName = "SPE"; + const char *pkgName = "com.nearby"; + int32_t trueAction = ACTION_CREATE | ACTION_OPEN; + AddPermission(std::string(pkgName)); + EXPECT_EQ(SOFTBUS_PERMISSION_DENIED, CheckTransPermission(sessionName, pkgName, trueAction)); + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission008 +* @tc.desc: test system app -> appInfo native app +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission008, TestSize.Level1) +{ + const char *sessionName = "SystemAbilityManager_DDC.test"; + const char *pkgName = "test"; + int32_t trueAction = ACTION_CREATE | ACTION_OPEN; + AddPermission(std::string(pkgName)); + EXPECT_EQ(SYSTEM_APP, CheckTransPermission(sessionName, pkgName, trueAction)); + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission009 +* @tc.desc: test system app -> appInfo granted app +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission009, TestSize.Level1) +{ + const char *sessionName = "DBinder.test"; + const char *pkgName = "DBinderBus"; + int32_t trueAction = ACTION_OPEN; + AddPermission(std::string(pkgName)); + EXPECT_EQ(GRANTED_APP, CheckTransPermission(sessionName, pkgName, trueAction)); + RemovePermission(std::string(pkgName)); +} + +/* +* @tc.name: testPermission010 +* @tc.desc: test discovery permission +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusPermissionTest, testPermission010, TestSize.Level1) +{ + const char *pkgName = "com.profile"; + AddPermission(std::string(pkgName)); + EXPECT_EQ(true, CheckDiscPermission(pkgName)); + EXPECT_EQ(false, CheckDiscPermission(nullptr)); + RemovePermission(std::string(pkgName)); +} +} \ No newline at end of file diff --git a/tests/core/common/security/softbus_permission_test.json b/tests/core/common/security/softbus_permission_test.json new file mode 100755 index 000000000..4be9b3beb --- /dev/null +++ b/tests/core/common/security/softbus_permission_test.json @@ -0,0 +1,175 @@ +[ + { + "SESSION_NAME": "com\\.profile.*", + "REGEXP": "true", + "DEVID": "NETWORKID", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.profile", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com\\.def.*", + "REGEXP": "true", + "DEVID": "NETWORKID", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.def", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "DBinder.*", + "REGEXP": "true", + "DEVID": "NETWORKID", + "SEC_LEVEL": "public", + "APP_INFO": [ + { + "TYPE": "granted_app", + "PKG_NAME": "DBinderBus", + "ACTIONS": "open" + } + ] + }, + { + "SESSION_NAME": "com\\.hwddmp.*", + "REGEXP": "true", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.hwddmp", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com.devicegroupmanage", + "DEVID": "UDID", + "APP_INFO": [ + { + "TYPE": "system_app", + "PKG_NAME": "com.devicegroupmanage", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com\\.dmsdp.*", + "REGEXP": "true", + "DEVID": "UDID", + "SEC_LEVEL": "public", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.dmsdp", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "SPE", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "self_app", + "UID": "1000", + "PKG_NAME": "com.nearby", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com.nearby.MsgMiddleware", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "self_app", + "UID": "1000", + "PKG_NAME": "com.nearby", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "distributeddata.*", + "REGEXP": "true", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.hwddmp", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "SystemAbilityManager_DDC.*", + "REGEXP": "true", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "native_app", + "UID": "1000", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "hiview_distributed_network_softbus", + "DEVID": "NETWORKID", + "APP_INFO": [ + { + "TYPE": "native_app", + "UID": "0", + "PKG_NAME": "hiview_distributed_network_softbus", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "DistributedFileService.*", + "REGEXP": "true", + "DEVID": "UUID", + "APP_INFO": [ + { + "TYPE": "native_app", + "UID": "1000", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com.systemserver_CHANNEL_DPMS", + "DEVID": "NETWORKID", + "APP_INFO": [ + { + "TYPE": "system_app", + "UID": "1000", + "PKG_NAME": "com.systemserver", + "ACTIONS": "create,open" + } + ] + }, + { + "SESSION_NAME": "com.devicemanager", + "DEVID": "UDID", + "APP_INFO": [ + { + "TYPE": "system_app", + "PKG_NAME": "com.devicemanager", + "ACTIONS": "create,open" + } + ] + } +] diff --git a/tests/core/connection/BUILD.gn b/tests/core/connection/BUILD.gn new file mode 100755 index 000000000..7a4e13b07 --- /dev/null +++ b/tests/core/connection/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +group("connectionTest") { + testonly = true + deps = [ + "common:softbus_conn_common_test", + "manager:softbus_conn_manager_test", + "tcp:softbus_tcp_manager_test", + ] +} diff --git a/tests/core/connection/common/BUILD.gn b/tests/core/connection/common/BUILD.gn new file mode 100755 index 000000000..b14fe39ce --- /dev/null +++ b/tests/core/connection/common/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/connection" + +ohos_unittest("softbus_conn_common_test") { + module_out_path = module_output_path + + #ldflags = [ "-lstdc++" ] + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/common/include", + "//third_party/googletest/googletest/include", + "//third_party/googletest/googletest/src", + "//third_party/bounds_checking_function/include", + ] + sources = [ "softbus_conn_common_test.cpp" ] + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} diff --git a/tests/core/connection/common/softbus_conn_common_test.cpp b/tests/core/connection/common/softbus_conn_common_test.cpp new file mode 100755 index 000000000..73ab9a40c --- /dev/null +++ b/tests/core/connection/common/softbus_conn_common_test.cpp @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "common_list.h" +#include "softbus_base_listener.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_tcp_socket.h" +#include "softbus_thread_pool.h" +#include "softbus_utils.h" + +using namespace testing::ext; + +static const int INVALID_FD = -1; +static pthread_mutex_t g_isInitedLock; +static int g_count = 0; +static int g_port = 6666; + +namespace OHOS { +class SoftbusCommonTest : public testing::Test { +public: + SoftbusCommonTest() + {} + ~SoftbusCommonTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +int ThreadPoolTask(void* arg) +{ + pthread_mutex_lock(&g_isInitedLock); + g_count++; + pthread_mutex_unlock(&g_isInitedLock); + return SOFTBUS_OK; +} + +void SoftbusCommonTest::SetUpTestCase(void) +{ + pthread_mutex_init(&g_isInitedLock, nullptr); + GTEST_LOG_(INFO) << "SoftbusCommonTestSetUp"; +} + +void SoftbusCommonTest::TearDownTestCase(void) +{ + g_count = 0; + g_port++; + GTEST_LOG_(INFO) << "+-------------------------------------------+"; +} + +void SoftbusCommonTest::SetUp(void) +{ + g_count = 0; +} + +void SoftbusCommonTest::TearDown(void) +{ + g_count = 0; +} + +int32_t ConnectEvent(int32_t events, int32_t cfd, const char *ip) +{ + return 0; +} + +int32_t DataEvent(int32_t events, int32_t fd) +{ + return 0; +} + +/* +* @tc.name: testBaseListener001 +* @tc.desc: test GetSoftbusBaseListener invalid input param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener001, TestSize.Level1) +{ + EXPECT_EQ(SOFTBUS_INVALID_PARAM, GetSoftbusBaseListener(PROXY, nullptr)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, GetSoftbusBaseListener(AUTH, nullptr)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, GetSoftbusBaseListener(DIRECT_CHANNEL_SERVER, nullptr)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, GetSoftbusBaseListener(UNUSE_BUTT, nullptr)); +}; + +/* +* @tc.name: testBaseListener002 +* @tc.desc: test GetSoftbusBaseListener and set +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener002, TestSize.Level1) +{ + int i; + for (i = PROXY; i <= UNUSE_BUTT; i++) { + EXPECT_EQ(SOFTBUS_INVALID_PARAM, SetSoftbusBaseListener(static_cast(i), nullptr)); + } + SoftbusBaseListener *setListener = (SoftbusBaseListener *)malloc(sizeof(SoftbusBaseListener)); + ASSERT_TRUE(setListener != nullptr); + setListener->onConnectEvent = ConnectEvent; + setListener->onDataEvent = DataEvent; + for (i = PROXY; i < UNUSE_BUTT; i++) { + SoftbusBaseListener *getListener = (SoftbusBaseListener *)malloc(sizeof(SoftbusBaseListener)); + if (getListener == nullptr) { + free(setListener); + return; + } + EXPECT_EQ(SOFTBUS_OK, SetSoftbusBaseListener(static_cast(i), setListener)); + EXPECT_EQ(SOFTBUS_OK, GetSoftbusBaseListener(static_cast(i), getListener)); + EXPECT_EQ(setListener->onConnectEvent, getListener->onConnectEvent); + EXPECT_EQ(setListener->onDataEvent, getListener->onDataEvent); + DestroyBaseListener(static_cast(i)); + if (getListener != nullptr) { + free(getListener); + } + } + EXPECT_EQ(SOFTBUS_INVALID_PARAM, SetSoftbusBaseListener(UNUSE_BUTT, setListener)); + free(setListener); +}; + +/* +* @tc.name: testBaseListener003 +* @tc.desc: test start stop listener +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener003, TestSize.Level1) +{ + ListenerModule module = PROXY; + int port = 6666; + EXPECT_EQ(SOFTBUS_ERR, StopBaseListener(module)); + SoftbusBaseListener* listener = (SoftbusBaseListener*)malloc(sizeof(SoftbusBaseListener)); + ASSERT_TRUE(listener != nullptr); + listener->onConnectEvent = ConnectEvent; + listener->onDataEvent = DataEvent; + EXPECT_EQ(SOFTBUS_OK, SetSoftbusBaseListener(module, listener)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, StartBaseListener(module, nullptr, port, SERVER_MODE)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, StartBaseListener(module, "127.0.0.1", -1, SERVER_MODE)); + EXPECT_EQ(port, StartBaseListener(module, "127.0.0.1", port, SERVER_MODE)); + EXPECT_EQ(SOFTBUS_ERR, StartBaseListener(module, "127.0.0.1", port, SERVER_MODE)); + EXPECT_EQ(SOFTBUS_OK, StopBaseListener(module)); + EXPECT_EQ(SOFTBUS_OK, StopBaseListener(module)); + DestroyBaseListener(module); + free(listener); +}; + +/* +* @tc.name: testBaseListener004 +* @tc.desc: test start client +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener004, TestSize.Level1) +{ + ListenerModule module = DIRECT_CHANNEL_SERVER; + EXPECT_EQ(SOFTBUS_ERR, StopBaseListener(module)); + SoftbusBaseListener* listener = (SoftbusBaseListener*)malloc(sizeof(SoftbusBaseListener)); + ASSERT_TRUE(listener != nullptr); + listener->onConnectEvent = ConnectEvent; + listener->onDataEvent = DataEvent; + EXPECT_EQ(SOFTBUS_ERR, StartBaseClient(module)); + EXPECT_EQ(SOFTBUS_OK, SetSoftbusBaseListener(module, listener)); + EXPECT_EQ(SOFTBUS_OK, StartBaseClient(module)); + EXPECT_EQ(SOFTBUS_ERR, StartBaseClient(module)); + EXPECT_EQ(SOFTBUS_OK, StopBaseListener(module)); + DestroyBaseListener(module); + free(listener); +}; + +/* +* @tc.name: testBaseListener005 +* @tc.desc: test set start stop listener +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener005, TestSize.Level1) +{ + int ret; + int module; + int port = 6666; + for (module = PROXY; module < UNUSE_BUTT; module++) { + SoftbusBaseListener* listener = (SoftbusBaseListener*)malloc(sizeof(SoftbusBaseListener)); + if (listener == nullptr) { + for (int i = 0; i < module; i++) { + ret = StopBaseListener(static_cast(i)); + EXPECT_EQ(SOFTBUS_OK, ret); + DestroyBaseListener(static_cast(i)); + } + continue; + } + listener->onConnectEvent = ConnectEvent; + listener->onDataEvent = DataEvent; + ret = SetSoftbusBaseListener(static_cast(module), listener); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = StartBaseListener(static_cast(module), "127.0.0.1", + port + static_cast(module), SERVER_MODE); + EXPECT_EQ(port + module, ret); + free(listener); + } + for (module = PROXY; module < UNUSE_BUTT; module++) { + ret = StopBaseListener(static_cast(module)); + EXPECT_EQ(SOFTBUS_OK, ret); + DestroyBaseListener(static_cast(module)); + } +}; + +/* +* @tc.name: testBaseListener006 +* @tc.desc: test Invalid trigger param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener006, TestSize.Level1) +{ + int module; + int triggerType; + int fd = 1; + for (triggerType = READ_TRIGGER; triggerType <= RW_TRIGGER; triggerType++) { + EXPECT_EQ(SOFTBUS_INVALID_PARAM, AddTrigger(UNUSE_BUTT, fd, static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, DelTrigger(UNUSE_BUTT, fd, static_cast(triggerType))); + } + for (module = PROXY; module < UNUSE_BUTT; module++) { + for (triggerType = READ_TRIGGER; triggerType <= RW_TRIGGER; triggerType++) { + EXPECT_EQ(SOFTBUS_INVALID_PARAM, AddTrigger(static_cast(module), INVALID_FD, + static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, DelTrigger(static_cast(module), INVALID_FD, + static_cast(triggerType))); + } + } +}; + +/* +* @tc.name: testBaseListener007 +* @tc.desc: test Not set baselistener +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener007, TestSize.Level1) +{ + int module; + int triggerType; + int fd = 1; + for (module = PROXY; module < UNUSE_BUTT; module++) { + for (triggerType = READ_TRIGGER; triggerType <= RW_TRIGGER; triggerType++) { + EXPECT_EQ(SOFTBUS_ERR, AddTrigger(static_cast(module), + fd, static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_ERR, DelTrigger(static_cast(module), + fd, static_cast(triggerType))); + } + } +}; + +/* +* @tc.name: testBaseListener008 +* @tc.desc: test add del trigger +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testBaseListener008, TestSize.Level1) +{ + int module; + int triggerType; + int fd = 1; + int port = 6666; + + for (module = PROXY; module < UNUSE_BUTT; module++) { + SoftbusBaseListener* listener = (SoftbusBaseListener*)malloc(sizeof(SoftbusBaseListener)); + ASSERT_TRUE(listener != nullptr); + listener->onConnectEvent = ConnectEvent; + listener->onDataEvent = DataEvent; + EXPECT_EQ(SOFTBUS_OK, SetSoftbusBaseListener(static_cast(module), listener)); + EXPECT_EQ(port, StartBaseListener(static_cast(module), "127.0.0.1", port, SERVER_MODE)); + for (triggerType = READ_TRIGGER; triggerType <= RW_TRIGGER; triggerType++) { + EXPECT_EQ(SOFTBUS_OK, AddTrigger(static_cast(module), + fd, static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_ERR, AddTrigger(static_cast(module), + fd, static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_OK, DelTrigger(static_cast(module), + fd, static_cast(triggerType))); + EXPECT_EQ(SOFTBUS_OK, DelTrigger(static_cast(module), + fd, static_cast(triggerType))); + } + EXPECT_EQ(SOFTBUS_OK, StopBaseListener(static_cast(module))); + DestroyBaseListener(static_cast(module)); + free(listener); + } +}; + +/* +* @tc.name: testTcpSocket001 +* @tc.desc: test OpenTcpServerSocket +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testTcpSocket001, TestSize.Level1) +{ + int fd = OpenTcpServerSocket("127.0.0.1", g_port); + int ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_OK); + ASSERT_TRUE(ret == SOFTBUS_OK); + int port = GetTcpSockPort(fd); + EXPECT_EQ(port, g_port); + CloseTcpFd(fd); + + fd = OpenTcpServerSocket(nullptr, g_port); + ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + CloseTcpFd(fd); + fd = OpenTcpServerSocket("127.0.0.1", -1); + ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + CloseTcpFd(fd); +}; + +/* +* @tc.name: testTcpSocket002 +* @tc.desc: test OpenTcpClientSocket +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testTcpSocket002, TestSize.Level1) +{ + int fd = OpenTcpClientSocket("127.0.0.1", "194.0.0.1", g_port); + int ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + int port = GetTcpSockPort(fd); + EXPECT_EQ(port, -1); + CloseTcpFd(fd); + + fd = OpenTcpClientSocket(nullptr, "127.0.0.1", g_port); + ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + CloseTcpFd(fd); + fd = OpenTcpClientSocket("127.0.0.1", nullptr, g_port); + ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + CloseTcpFd(fd); + fd = OpenTcpClientSocket("127.0.0.1", "127.0.0.1", -1); + ret = (fd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + CloseTcpFd(fd); +}; + +/* +* @tc.name: testBaseListener003 +* @tc.desc: test GetTcpSockPort invalid fd +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testTcpSocket003, TestSize.Level1) +{ + int invalidFd = 1; + int port = GetTcpSockPort(invalidFd); + int ret = (port <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); +}; + +/* +* @tc.name: testTcpSocket004 +* @tc.desc: test SendTcpData invalid fd +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testTcpSocket004, TestSize.Level1) +{ + int clientFd = OpenTcpClientSocket("127.0.0.1", "127.5.0.1", g_port); + int ret = (clientFd <= 0) ? SOFTBUS_ERR : SOFTBUS_OK; + EXPECT_EQ(ret, SOFTBUS_ERR); + ssize_t bytes = SendTcpData(clientFd, "Hello world", 11, 0); + EXPECT_EQ(bytes, -1); + TcpShutDown(clientFd); +}; + +/* +* @tc.name: testThreadPool001 +* @tc.desc: test ThreadPoolInit invalid input param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testThreadPool001, TestSize.Level1) +{ + int threadNum = 2; + int queueMaxNum = 4; + int invalidNum = 0; + + ThreadPool *pool = ThreadPoolInit(invalidNum, queueMaxNum); + EXPECT_EQ(nullptr, pool); + pool = ThreadPoolInit(threadNum, invalidNum); + EXPECT_EQ(nullptr, pool); + pool = ThreadPoolInit(threadNum, queueMaxNum); + EXPECT_EQ(true, pool != nullptr); + + EXPECT_EQ(SOFTBUS_OK, ThreadPoolDestroy(pool)); +} + +/* +* @tc.name: testThreadPool002 +* @tc.desc: test ThreadPoolAddJob and remove with invalid param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testThreadPool002, TestSize.Level1) +{ + int threadNum = 2; + int queueMaxNum = 4; + + ThreadPool *pool = ThreadPoolInit(threadNum, queueMaxNum); + EXPECT_EQ(true, pool != nullptr); + + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolAddJob(nullptr, ThreadPoolTask, nullptr, ONCE, (uintptr_t)0)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolAddJob(nullptr, ThreadPoolTask, nullptr, PERSISTENT, (uintptr_t)0)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolAddJob(pool, nullptr, nullptr, ONCE, (uintptr_t)0)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolAddJob(pool, nullptr, nullptr, PERSISTENT, (uintptr_t)0)); + + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolRemoveJob(nullptr, (uintptr_t)0)); + EXPECT_EQ(SOFTBUS_OK, ThreadPoolDestroy(pool)); +} + +/* +* @tc.name: testThreadPool003 +* @tc.desc: test null ThreadPoolDestroy +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testThreadPool003, TestSize.Level1) +{ + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ThreadPoolDestroy(nullptr)); +} + +/* +* @tc.name: testThreadPool004 +* @tc.desc: test ThreadPoolAddJob out of max num +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testThreadPool004, TestSize.Level1) +{ + int threadNum = 2; + int queueMaxNum = 4; + + ThreadPool *pool = ThreadPoolInit(threadNum, queueMaxNum); + int ret = (pool != nullptr) ? SOFTBUS_OK : SOFTBUS_ERR; + EXPECT_EQ(ret, SOFTBUS_OK); + + for (int i = 0; i < queueMaxNum; i++) { + ret = ThreadPoolAddJob(pool, ThreadPoolTask, nullptr, PERSISTENT, (uintptr_t)i); + EXPECT_EQ(ret, SOFTBUS_OK); + } + ret = ThreadPoolAddJob(pool, ThreadPoolTask, nullptr, PERSISTENT, (uintptr_t)queueMaxNum); + EXPECT_EQ(ret, SOFTBUS_ERR); + sleep(3); + ret = (g_count != queueMaxNum) ? SOFTBUS_OK : SOFTBUS_ERR; + EXPECT_EQ(ret, SOFTBUS_OK); + for (int i = 0; i < queueMaxNum; i++) { + ret = ThreadPoolRemoveJob(pool, (uintptr_t)i); + EXPECT_EQ(ret, SOFTBUS_OK); + } + ret = ThreadPoolRemoveJob(pool, (uintptr_t)queueMaxNum); + EXPECT_EQ(ret, SOFTBUS_OK); + if (pool != nullptr) { + ret = ThreadPoolDestroy(pool); + EXPECT_EQ(ret, SOFTBUS_OK); + } +}; + +/* +* @tc.name: testThreadPool005 +* @tc.desc: test ThreadPoolAddJob and remove +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusCommonTest, testThreadPool005, TestSize.Level1) +{ + int threadNum = 2; + int queueMaxNum = 4; + + ThreadPool *pool = ThreadPoolInit(threadNum, queueMaxNum); + int ret = (pool != nullptr) ? SOFTBUS_OK : SOFTBUS_ERR; + EXPECT_EQ(ret, SOFTBUS_OK); + + for (int i = 0; i < queueMaxNum; i++) { + ret = ThreadPoolAddJob(pool, ThreadPoolTask, nullptr, ONCE, (uintptr_t)i); + EXPECT_EQ(ret, SOFTBUS_OK); + } + sleep(3); + EXPECT_EQ(queueMaxNum, g_count); + for (int i = 0; i < queueMaxNum; i++) { + ret = ThreadPoolRemoveJob(pool, (uintptr_t)i); + EXPECT_EQ(ret, SOFTBUS_OK); + } + if (pool != nullptr) { + ret = ThreadPoolDestroy(pool); + EXPECT_EQ(ret, SOFTBUS_OK); + } +}; +} diff --git a/tests/core/connection/manager/BUILD.gn b/tests/core/connection/manager/BUILD.gn new file mode 100755 index 000000000..7fb0d99cd --- /dev/null +++ b/tests/core/connection/manager/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/connection" + +ohos_unittest("softbus_conn_manager_test") { + module_out_path = module_output_path + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/connection/tcp/include", + "//third_party/googletest/googletest/include", + "//third_party/googletest/googletest/src", + "//third_party/bounds_checking_function/include", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + sources = [ "connection_manager_test.cpp" ] +} diff --git a/tests/core/connection/manager/connection_manager_test.cpp b/tests/core/connection/manager/connection_manager_test.cpp new file mode 100755 index 000000000..d86766b6e --- /dev/null +++ b/tests/core/connection/manager/connection_manager_test.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "common_list.h" +#include "softbus_conn_interface.h" +#include "softbus_conn_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" + +static const int CONN_HEAD_SIZE = 24; +static const int SHIFT_BITS = 16; + +static ConnectCallback *g_mangerCb = 0; +static ConnectionInfo g_connInfo = {0}; +static unsigned int g_connId = 0; + +using namespace testing::ext; + +namespace OHOS { +unsigned int ObjectGetConnectionId(unsigned int type) +{ + unsigned int ret = type << SHIFT_BITS; + ret++; + return ret; +} + +int ObjectConnectDevice(const ConnectOption *option, unsigned int requestId, const ConnectResult *result) +{ + ConnectionInfo info = {0}; + if (option == 0 || result == 0) { + return 1; + } + g_connInfo.isAvailable = 1; + g_connInfo.type = option->type; + result->OnConnectSuccessed(requestId, ObjectGetConnectionId(option->type), &info); + return 0; +} + +int ObjectPostBytes(unsigned int connectionId, const char *data, int len, int pid, int flag) +{ + int module; + int bufLen = 15; + const char *str = "reply wdf"; + ConnPktHead *head = nullptr; + if (data == nullptr) { + return 1; + } + head = (ConnPktHead *)data; + module = head->module; + + char *buf = (char *)calloc(1, CONN_HEAD_SIZE + bufLen); + if (buf == nullptr) { + return -1; + } + (void)strcpy_s(buf + CONN_HEAD_SIZE, strlen(str), str); + if (g_mangerCb) { + g_mangerCb->OnDataReceived(connectionId, static_cast(module), + 1, buf, CONN_HEAD_SIZE + bufLen); + } + free(buf); + return 0; +} + +int ObjectDisconnectDevice(unsigned int connectionId) +{ + (void)connectionId; + return 0; +} + +int ObjectGetConnectionInfo(unsigned int connectionId, ConnectionInfo *info) +{ + (void)connectionId; + if (info == nullptr) { + return -1; + } + (void)memcpy_s(info, sizeof(ConnectionInfo), &g_connInfo, sizeof(ConnectionInfo)); + return 0; +} + +int ObjectStartLocalListening(const LocalListenerInfo *info) +{ + if (info == nullptr) { + return 1; + } + if (g_mangerCb) { + g_mangerCb->OnConnected(ObjectGetConnectionId(info->type), &g_connInfo); + } + return 0; +} + +int ObjectStopLocalListening(const LocalListenerInfo *info) +{ + if (info == nullptr) { + return 1; + } + if (g_mangerCb) { + g_mangerCb->OnDisconnected(ObjectGetConnectionId(info->type), &g_connInfo); + } + return 0; +} + +ConnectFuncInterface *ConnInitObject(const ConnectCallback *callback) +{ + if (callback == 0) { + return nullptr; + } + ConnectFuncInterface *inter = (ConnectFuncInterface*)calloc(1, sizeof(ConnectFuncInterface)); + if (inter == nullptr) { + return nullptr; + } + g_mangerCb = (ConnectCallback*)callback; + + inter->ConnectDevice = ObjectConnectDevice; + inter->PostBytes = ObjectPostBytes; + inter->DisconnectDevice = ObjectDisconnectDevice; + inter->GetConnectionInfo = ObjectGetConnectionInfo; + inter->StartLocalListening = ObjectStartLocalListening; + inter->StopLocalListening = ObjectStopLocalListening; + return inter; +} + +extern "C" ConnectFuncInterface *ConnInitBr(const ConnectCallback *callback) +{ + return ConnInitObject(callback); +} + +extern "C" ConnectFuncInterface *ConnInitTcp(const ConnectCallback *callback) +{ + return ConnInitObject(callback); +} + +void ConnectedCB(unsigned int connectionId, const ConnectionInfo *info) +{ + printf("recv remote ConnectedCB %u\r\n", connectionId); + g_connId = connectionId; + return; +} + +void DisConnectCB(unsigned int connectionId, const ConnectionInfo *info) +{ + printf("DconDisConnect %u\r\n", connectionId); + return; +} + +void DataReceivedCB(unsigned int connectionId, ConnModule moduleId, int64_t seq, char *data, int len) +{ + printf("DconDataReceived moduleId %d %s %d\r\n", moduleId, data, len); + return; +} + +void ConnectSuccessedCB(unsigned int requestId, unsigned int connectionId, const ConnectionInfo *info) +{ + printf("ConnectSuccessedCB %u\r\n", connectionId); + g_connId = connectionId; + return; +} + +void ConnectFailedCB(unsigned int requestId, int reason) +{ + (void)requestId; + (void)reason; + printf("DconConnectFailed\r\n"); + return; +} + +class SoftbusConnmangerFuncTest : public testing::Test { +public: + SoftbusConnmangerFuncTest() + {} + ~SoftbusConnmangerFuncTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void SoftbusConnmangerFuncTest::SetUpTestCase(void) +{ + ConnServerInit(); +} + +void SoftbusConnmangerFuncTest::TearDownTestCase(void) +{} + +void SoftbusConnmangerFuncTest::SetUp(void) +{} + +void SoftbusConnmangerFuncTest::TearDown(void) +{} + +/* +* @tc.name: testConnmanger001 +* @tc.desc: test ConnTypeIsSupport +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger001, TestSize.Level1) +{ + int ret; + printf("testConnmanger001\r\n"); + + ret = ConnTypeIsSupport(CONNECT_TCP); + EXPECT_EQ(SOFTBUS_OK, ret); + + ret = ConnTypeIsSupport(CONNECT_BR); + EXPECT_EQ(SOFTBUS_OK, ret); + + ret = ConnTypeIsSupport(CONNECT_BLE); + EXPECT_EQ(SOFTBUS_ERR, ret); +}; + +/* +* @tc.name: testConnmanger002 +* @tc.desc: test invalid param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger002, TestSize.Level1) +{ + printf("test begin testConnmanger002 \r\n"); + ConnSetConnectCallback(static_cast(0), nullptr); + ConnConnectDevice(nullptr, 0, nullptr); + ConnPostBytes(0, nullptr); + ConnStartLocalListening(nullptr); + ConnStopLocalListening(nullptr); + EXPECT_EQ(SOFTBUS_OK, SOFTBUS_OK); +}; + +/* +* @tc.name: testConnmanger003 +* @tc.desc: test set unset callback and connect post disconnect +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger003, TestSize.Level1) +{ + int ret; + int reqId; + ConnectCallback connCb; + ConnectResult connRet; + ConnPostData data; + ConnectOption info; + const char *str = "send msg local2\r\n"; + printf("test begin testConnmanger003 \r\n"); + + connCb.OnConnected = ConnectedCB; + connCb.OnDisconnected = DisConnectCB; + connCb.OnDataReceived = DataReceivedCB; + ret = ConnSetConnectCallback(MODULE_TRUST_ENGINE, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = ConnSetConnectCallback(MODULE_AUTH_SDK, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + + info.type = CONNECT_BR; + connRet.OnConnectFailed = ConnectFailedCB; + connRet.OnConnectSuccessed = ConnectSuccessedCB; + reqId = ConnGetNewRequestId(MODULE_TRUST_ENGINE); + ret = ConnConnectDevice(&info, reqId, &connRet); + EXPECT_EQ(SOFTBUS_OK, ret); + if (g_connId) { + data.buf = (char *)calloc(1, CONN_HEAD_SIZE + 20); + ASSERT_TRUE(data.buf != NULL); + (void)strcpy_s(data.buf + 1, strlen(str), str); + data.len = CONN_HEAD_SIZE + 20; + data.module = MODULE_TRUST_ENGINE; + data.pid = 0; + ret = ConnPostBytes(g_connId, &data); + EXPECT_EQ(SOFTBUS_OK, ret); + if (data.buf != nullptr) { + free(data.buf); + } + } + ret = ConnDisconnectDevice(g_connId); + EXPECT_EQ(SOFTBUS_OK, ret); + ConnUnSetConnectCallback(MODULE_TRUST_ENGINE); + ConnUnSetConnectCallback(MODULE_AUTH_SDK); + g_connId = 0; +}; + +/* +* @tc.name: testConnmanger004 +* @tc.desc: test set unset callback and post disconnect without connect +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger004, TestSize.Level1) +{ + printf("test begin ConnManagerTest004 \r\n"); + int ret; + ConnectCallback connCb; + LocalListenerInfo info; + ConnPostData data; + const char *str = "send msg local2\r\n"; + + connCb.OnConnected = ConnectedCB; + connCb.OnDisconnected = DisConnectCB; + connCb.OnDataReceived = DataReceivedCB; + ret = ConnSetConnectCallback(MODULE_TRUST_ENGINE, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + info.type = CONNECT_BR; + ret = ConnStartLocalListening(&info); + EXPECT_EQ(SOFTBUS_OK, ret); + + if (g_connId) { + data.buf = (char*)calloc(1, CONN_HEAD_SIZE + 20); + (void)strcpy_s(data.buf + CONN_HEAD_SIZE, strlen(str), str); + ASSERT_TRUE(data.buf != NULL); + data.len = CONN_HEAD_SIZE + 20; + data.module = MODULE_TRUST_ENGINE; + data.pid = 0; + ret = ConnPostBytes(g_connId, &data); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = ConnDisconnectDevice(g_connId); + EXPECT_EQ(SOFTBUS_OK, ret); + if (data.buf != nullptr) { + free(data.buf); + } + } + + ret = ConnStopLocalListening(&info); + EXPECT_EQ(SOFTBUS_OK, ret); + ConnUnSetConnectCallback(MODULE_TRUST_ENGINE); + g_connId = 0; +}; + +/* +* @tc.name: testConnmanger005 +* @tc.desc: test set unset callback multi times +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger005, TestSize.Level1) +{ + int ret; + ConnectCallback connCb; + + connCb.OnConnected = ConnectedCB; + connCb.OnDisconnected = DisConnectCB; + connCb.OnDataReceived = DataReceivedCB; + ret = ConnSetConnectCallback(MODULE_TRUST_ENGINE, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = ConnSetConnectCallback(MODULE_AUTH_SDK, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = ConnSetConnectCallback(MODULE_AUTH_SDK, &connCb); + EXPECT_EQ(SOFTBUS_ERR, ret); + + ConnUnSetConnectCallback(MODULE_TRUST_ENGINE); + ConnUnSetConnectCallback(MODULE_AUTH_SDK); +}; + +/* +* @tc.name: testConnmanger006 +* @tc.desc: test set unset callback and connect post disconnect +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusConnmangerFuncTest, testConnmanger006, TestSize.Level1) +{ + int reqId = 1; + int ret; + ConnectCallback connCb; + ConnectOption optionInfo; + ConnectionInfo info; + ConnectResult connRet; + + connCb.OnConnected = ConnectedCB; + connCb.OnDisconnected = DisConnectCB; + connCb.OnDataReceived = DataReceivedCB; + ret = ConnSetConnectCallback(MODULE_TRUST_ENGINE, &connCb); + EXPECT_EQ(SOFTBUS_OK, ret); + + optionInfo.type = CONNECT_BR; + connRet.OnConnectFailed = ConnectFailedCB; + connRet.OnConnectSuccessed = ConnectSuccessedCB; + reqId = ConnGetNewRequestId(MODULE_TRUST_ENGINE); + ret = ConnConnectDevice(&optionInfo, reqId, &connRet); + EXPECT_EQ(SOFTBUS_OK, ret); + if (g_connId) { + ret = ConnGetConnectionInfo(g_connId, &info); + EXPECT_EQ(SOFTBUS_OK, ret); + ret = ConnDisconnectDevice(g_connId); + g_connId = 0; + EXPECT_EQ(SOFTBUS_OK, ret); + printf("testConnmanger006 ConnDisconnectDevice\r\n"); + } + printf("testConnmanger006 ConnUnSetConnectCallback\r\n"); + ConnUnSetConnectCallback(MODULE_TRUST_ENGINE); + printf("testConnmanger006 ConnUnSetConnectCallback end 11\r\n"); +}; +} \ No newline at end of file diff --git a/tests/core/connection/tcp/BUILD.gn b/tests/core/connection/tcp/BUILD.gn new file mode 100755 index 000000000..59e9ebca6 --- /dev/null +++ b/tests/core/connection/tcp/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/connection" + +ohos_unittest("softbus_tcp_manager_test") { + module_out_path = module_output_path + + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/connection/common/include", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/core/connection/manager", + "$dsoftbus_root_path/core/connection/tcp/include", + "//third_party/googletest/googletest/include", + "//third_party/googletest/googletest/src", + "//third_party/bounds_checking_function/include", + ] + sources = [ "tcp_manager_test.cpp" ] + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} diff --git a/tests/core/connection/tcp/tcp_manager_test.cpp b/tests/core/connection/tcp/tcp_manager_test.cpp new file mode 100755 index 000000000..32f3bd222 --- /dev/null +++ b/tests/core/connection/tcp/tcp_manager_test.cpp @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common_list.h" +#include "softbus_base_listener.h" +#include "softbus_conn_interface.h" +#include "softbus_conn_manager.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_log.h" +#include "softbus_mem_interface.h" +#include "softbus_property.h" +#include "softbus_tcp_connect_manager.h" +#include "softbus_tcp_socket.h" +#include "softbus_thread_pool.h" +#include "softbus_utils.h" + +static const int MAXLNE = 50; +static const std::string GET_TCP_MAX_CONN_NUM = "CONN_TCP_MAX_CONN_NUM"; +static const std::string GET_TCP_MAX_LENGTH = "CONN_TCP_MAX_LENGTH"; + +using namespace testing::ext; + +namespace OHOS { +const char *Ip = "127.0.0.1"; +const char *g_data = "1234567890"; + +static uint32_t g_connectionId = 0; +static ConnectFuncInterface *g_interface = nullptr; +static ConnectResult g_result; +static ConnectCallback g_cb; +static int g_receivedDatalength = 0; + +void TcpOnConnected(uint32_t connectionId, const ConnectionInfo *info) +{ + printf("TcpOnConnected %08x\n", connectionId); +} + +void TcpOnDisConnect(uint32_t connectionId, const ConnectionInfo *info) +{ + printf("TcpOnDisConnect %08x\n", connectionId); +} + +void TcpDataReceived(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int length) +{ + g_receivedDatalength = length; + printf("nDataReceived with length:%d\n", length); +} + +void TcpOnConnectionSuccessed(uint32_t requestId, uint32_t connectionId, const ConnectionInfo *info) +{ + g_connectionId = connectionId; + printf("OnConnectionEnabled with requestId:%u connectionId:%08x\n", requestId, connectionId); +} + +void TcpOnConnectionFailed(uint32_t requestId, int32_t reason) +{ + printf("OnConnectionFailed with requestId:%u reason:%d\n", requestId, reason); +} + +class SoftbusTcpManagerTest : public testing::Test { +public: + SoftbusTcpManagerTest() + {} + ~SoftbusTcpManagerTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void SoftbusTcpManagerTest::SetUpTestCase(void) +{} + +void SoftbusTcpManagerTest::TearDownTestCase(void) +{} + +void SoftbusTcpManagerTest::SetUp(void) +{ + g_cb.OnConnected = TcpOnConnected; + g_cb.OnDataReceived = TcpDataReceived; + g_cb.OnDisconnected = TcpOnDisConnect; + g_interface = ConnInitTcp(&g_cb); + g_result.OnConnectSuccessed = TcpOnConnectionSuccessed; + g_result.OnConnectFailed = TcpOnConnectionFailed; + g_connectionId = 0; + g_receivedDatalength = 0; +} + +void SoftbusTcpManagerTest::TearDown(void) +{ + free(g_interface); + g_interface = nullptr; +} + +void CreateServer(void *arg) +{ + int listenfd, connfd, n; + struct sockaddr_in servaddr; + char buff[MAXLNE]; + int port = 6667; + int defaultListen = 5; + + if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + printf("create socket error: %s(errno: %d)\n", strerror(errno), errno); + return; + } + + (void)memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + inet_pton(AF_INET, Ip, &servaddr.sin_addr); + servaddr.sin_port = htons(port); + + if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { + close(listenfd); + printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno); + return; + } + if (listen(listenfd, defaultListen) == -1) { + close(listenfd); + printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno); + return; + } + + while (true) { + if ((connfd = accept(listenfd, (struct sockaddr *)nullptr, nullptr)) == -1) { + printf("accept socket error: %s(errno: %d)\n", strerror(errno), errno); + continue; + } + break; + } + + while (true) { + n = recv(connfd, buff, MAXLNE, 0); + if (n <= 0) { + break; + } + printf("recv msg with length:%d from client\n", n); + n = send(connfd, buff, n, 0); + printf("send msg with length:%d to client\n", n); + } + close(connfd); + close(listenfd); +} + +/* +* @tc.name: testBaseListener001 +* @tc.desc: test TcpGetConnNum +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager001, TestSize.Level1) +{ + EXPECT_EQ(0, TcpGetConnNum()); +}; + +/* +* @tc.name: testBaseListener002 +* @tc.desc: test TcpConnectDevice with invalid param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager002, TestSize.Level1) +{ + int port= 6666; + uint32_t requestId = 1; + ConnectOption option; + option.type = CONNECT_BR; + option.info.ipOption.port = port; + (void)strcpy_s(option.info.ipOption.ip, IP_LEN, Ip); + int ret; + ret = TcpConnectDevice(nullptr, requestId, &g_result); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ret); + ret = TcpConnectDevice(&option, requestId, nullptr); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ret); + ret = TcpConnectDevice(&option, requestId, &g_result); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, ret); +}; + +/* +* @tc.name: testBaseListener003 +* @tc.desc: test TcpDisconnectDevice with wrong id +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager003, TestSize.Level1) +{ + EXPECT_EQ(SOFTBUS_ERR, TcpDisconnectDevice(g_connectionId)); +}; + +/* +* @tc.name: testBaseListener004 +* @tc.desc: test TcpGetConnectionInfo with invalid param +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager004, TestSize.Level1) +{ + ConnectionInfo info = {}; + EXPECT_EQ(SOFTBUS_INVALID_PARAM, TcpGetConnectionInfo(g_connectionId, nullptr)); + EXPECT_EQ(SOFTBUS_ERR, TcpGetConnectionInfo(g_connectionId, &info)); + EXPECT_EQ(false, info.isAvailable); +}; + +/* +* @tc.name: testBaseListener005 +* @tc.desc: test start and stop listener multi times +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager005, TestSize.Level1) +{ + int port = 6666; + LocalListenerInfo info = {}; + info.type = CONNECT_BR; + info.info.ipListenerInfo.port = port; + (void)strcpy_s(info.info.ipListenerInfo.ip, IP_LEN, Ip); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, TcpStartListening(nullptr)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_INVALID_PARAM, TcpStopListening(nullptr)); + + info.type = CONNECT_TCP; + EXPECT_EQ(SOFTBUS_ERR, TcpStopListening(&info)); + EXPECT_EQ(port, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_ERR, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_OK, TcpStopListening(&info)); + EXPECT_TRUE(SOFTBUS_OK != TcpStopListening(&info)); +}; + +/* +* @tc.name: testTcpManager006 +* @tc.desc: test TcpDisconnectDevice +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager006, TestSize.Level1) +{ + int port = 6666; + LocalListenerInfo info = {}; + info.type = CONNECT_TCP; + info.info.ipListenerInfo.port = port; + (void)strcpy_s(info.info.ipListenerInfo.ip, IP_LEN, Ip); + + uint32_t requestId = 1; + ConnectOption option; + option.type = CONNECT_TCP; + option.info.ipOption.port = port; + (void)strcpy_s(option.info.ipOption.ip, IP_LEN, Ip); + + EXPECT_EQ(port, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_OK, TcpConnectDevice(&option, requestId, &g_result)); + sleep(1); + EXPECT_EQ(2, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpDisconnectDevice(g_connectionId)); + sleep(1); + EXPECT_EQ(0, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpStopListening(&info)); +} + +/* +* @tc.name: testTcpManager007 +* @tc.desc: test post out of max length +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager007, TestSize.Level1) +{ + pthread_t pid; + + int clientPort = 6666; + int serverPort = 6667; + LocalListenerInfo info = {}; + info.type = CONNECT_TCP; + info.info.ipListenerInfo.port = clientPort; + (void)strcpy_s(info.info.ipListenerInfo.ip, IP_LEN, Ip); + + uint32_t requestId = 1; + ConnectOption option = {}; + option.type = CONNECT_TCP; + option.info.ipOption.port = serverPort; + (void)strcpy_s(option.info.ipOption.ip, IP_LEN, Ip); + + ConnPktHead head = {0}; + head.len = strlen(g_data); + char data[sizeof(head) + head.len]; + (void)memcpy_s(&data, sizeof(head), (void*)&head, sizeof(head)); + (void)memcpy_s(&data[sizeof(head)], head.len, g_data, head.len); + + pthread_create(&pid, nullptr, (void *(*)(void *))CreateServer, nullptr); + sleep(1); + EXPECT_EQ(clientPort, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_OK, TcpConnectDevice(&option, requestId, &g_result)); + EXPECT_EQ(1, TcpGetConnNum()); + for (int i = 0; i < 3; i++) { + EXPECT_EQ(SOFTBUS_OK, TcpPostBytes(g_connectionId, data, sizeof(ConnPktHead) + head.len, 0, 0)); + sleep(1); + EXPECT_EQ(int(sizeof(ConnPktHead) + head.len), g_receivedDatalength); + g_receivedDatalength = 0; + } + EXPECT_EQ(SOFTBUS_OK, TcpDisconnectDevice(g_connectionId)); + EXPECT_EQ(0, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpStopListening(&info)); + EXPECT_EQ(0, TcpGetConnNum()); + pthread_join(pid, nullptr); +} + +/* +* @tc.name: testTcpManager008 +* @tc.desc: test connect out of max connect num +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager008, TestSize.Level1) +{ + int port = 6666; + LocalListenerInfo info = {}; + info.type = CONNECT_TCP; + info.info.ipListenerInfo.port = port; + (void)strcpy_s(info.info.ipListenerInfo.ip, IP_LEN, Ip); + + uint32_t requestId = 1; + ConnectOption option; + option.type = CONNECT_TCP; + option.info.ipOption.port = port; + (void)strcpy_s(option.info.ipOption.ip, IP_LEN, Ip); + + int32_t maxConnNum; + int32_t i = 0; + GetPropertyInt(GET_TCP_MAX_CONN_NUM.c_str(), &maxConnNum); + printf("maxConnNum: %d\n", maxConnNum); + EXPECT_EQ(port, TcpStartListening(&info)); + while (TcpGetConnNum() < maxConnNum) { + EXPECT_EQ(SOFTBUS_OK, TcpConnectDevice(&option, requestId, &g_result)); + sleep(1); + i += 2; + EXPECT_EQ(i, TcpGetConnNum()); + } + EXPECT_TRUE(SOFTBUS_OK != TcpConnectDevice(&option, requestId, &g_result)); + TcpDisconnectDeviceNow(&option); + sleep(1); + EXPECT_EQ(0, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpStopListening(&info)); +} + +/* +* @tc.name: testBaseListener009 +* @tc.desc: test connect and post to self +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SoftbusTcpManagerTest, testTcpManager009, TestSize.Level1) +{ + int port = 6666; + LocalListenerInfo info = {}; + info.type = CONNECT_TCP; + info.info.ipListenerInfo.port = port; + (void)strcpy_s(info.info.ipListenerInfo.ip, IP_LEN, Ip); + + uint32_t requestId = 1; + ConnectOption option; + option.type = CONNECT_TCP; + option.info.ipOption.port = port; + (void)strcpy_s(option.info.ipOption.ip, IP_LEN, Ip); + + int maxDataLen; + GetPropertyInt(GET_TCP_MAX_LENGTH.c_str(), &maxDataLen); + ConnPktHead head = {0}; + head.len = maxDataLen + 1; + char data[sizeof(head) + maxDataLen]; + (void)memcpy_s(&data, sizeof(head), (void*)&head, sizeof(head)); + (void)memset_s(&data[sizeof(head)], head.len, 0x1, head.len); + + EXPECT_EQ(port, TcpStartListening(&info)); + EXPECT_EQ(SOFTBUS_OK, TcpConnectDevice(&option, requestId, &g_result)); + sleep(1); + EXPECT_EQ(2, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpPostBytes(g_connectionId, data, sizeof(ConnPktHead) + head.len, 0, 0)); + sleep(1); + EXPECT_EQ(0, TcpGetConnNum()); + EXPECT_EQ(SOFTBUS_OK, TcpStopListening(&info)); + EXPECT_EQ(0, TcpGetConnNum()); +} +} \ No newline at end of file diff --git a/tests/core/discovery/manager/BUILD.gn b/tests/core/discovery/manager/BUILD.gn new file mode 100755 index 000000000..746a8fecc --- /dev/null +++ b/tests/core/discovery/manager/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/disc_manager" + +ohos_unittest("DiscManagerTest") { + module_out_path = module_output_path + sources = [ "unittest/disc_manager_test.cpp" ] + + include_dirs = [ + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/discovery/interface", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/core/discovery/manager/include", + "$dsoftbus_root_path/core/discovery/coap/include", + "//utils/native/base/include", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":DiscManagerTest" ] +} diff --git a/tests/core/discovery/manager/unittest/disc_manager_test.cpp b/tests/core/discovery/manager/unittest/disc_manager_test.cpp new file mode 100755 index 000000000..fd8fdad76 --- /dev/null +++ b/tests/core/discovery/manager/unittest/disc_manager_test.cpp @@ -0,0 +1,1301 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "disc_manager.h" +#include "softbus_log.h" + +#define TEST_ERRO_MOUDULE ((MODULE_LNN) + 3) +#define ERRO_CAPDATA_LEN (MAX_CAPABILITYDATA_LEN + 1) +#define TEST_ASSERT_TRUE(ret) \ + if (ret) { \ + LOG_INFO("[succ]\n"); \ + g_succTestCount++; \ + } else { \ + LOG_INFO("[error]\n"); \ + g_failTestCount++; \ + } + + +using namespace testing::ext; + +namespace OHOS { +static int32_t g_succTestCount = 0; +static int32_t g_failTestCount = 0; +static int32_t g_devieceFoundCount = 0; +static const char *g_corrPkgName = "CorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorrCorr"; +static const char *g_erroPkgName = "ErroErroErroErroErroErroErroErroErroErroErroErroErroErroErroErroE"; + +const int32_t TEST_PUBLISHINNER_ID = 1; +const int32_t TEST_PUBLISH_ID = 2; +const int32_t TEST_SUBSCRIBEINNER_ID = 3; +const int32_t TEST_SUBSCRIBE_ID = 4; +const int32_t TEST_PUBLISHINNER_ID1 = 5; +const int32_t TEST_PUBLISH_ID1 = 6; +const int32_t TEST_SUBSCRIBEINNER_ID1 = 7; +const int32_t TEST_SUBSCRIBE_ID1 = 8; +const int32_t TEST_BITMAP_CAP = 127; + +class Disc_ManagerTest : public testing::Test { +public: + Disc_ManagerTest() + {} + ~Disc_ManagerTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp() override + {} + void TearDown() override + {} +}; + +void Disc_ManagerTest::SetUpTestCase(void) +{} + +void Disc_ManagerTest::TearDownTestCase(void) +{} + +static void TestDeviceFound(const char *packageName, const DeviceInfo *device) +{ + g_devieceFoundCount++; + LOG_INFO("[device found]success!\n"); +} + +static void TestInnerDeviceFound(const DeviceInfo *device) +{ + g_devieceFoundCount++; + LOG_INFO("[inner device found]success!\n"); +} + +static void TestDiscoverFailed(const char *packageName, int subscribeId, DiscoveryFailReason failReason) +{ + LOG_INFO("[TestCallback]TestDiscoverFailed!\n"); +} + +static void TestDiscoverySuccess(const char *packageName, int subscribeId) +{ + LOG_INFO("[TestCallback]TestDiscoverySuccess!\n"); +} + +static void TestPublishSuccess(const char *packageName, int publishId) +{ + LOG_INFO("[TestCallback]TestPublishSuccess!\n"); +} + +static void TestPublishFail(const char *packageName, int publishId, PublishFailReason reason) +{ + LOG_INFO("[TestCallback]TestPublishFail!\n"); +} + +static DiscInnerCallback g_innerCallback = { + .OnDeviceFound = TestInnerDeviceFound +}; + +static IServerDiscoveryCallback g_subscribeCb = { + .OnServerDeviceFound = TestDeviceFound, + .OnServerDiscoverFailed = TestDiscoverFailed, + .OnServerDiscoverySuccess = TestDiscoverySuccess +}; + +static IServerPublishCallback g_publishCb = { + .OnServerPublishSuccess = TestPublishSuccess, + .OnServerPublishFail = TestPublishFail +}; + +static PublishInnerInfo g_pInnerInfo = { + .publishId = TEST_PUBLISHINNER_ID, + .medium = COAP, + .freq = LOW, + .capability = "hicall", + .capabilityData = (unsigned char *)"capdata1", + .dataLen = sizeof("capdata1") +}; + +static PublishInfo g_pInfo = { + .publishId = TEST_PUBLISH_ID, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata2", + .dataLen = sizeof("capdata2") +}; + +static SubscribeInnerInfo g_sInnerInfo = { + .subscribeId = TEST_SUBSCRIBEINNER_ID, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false +}; + +static SubscribeInfo g_sInfo = { + .subscribeId = TEST_SUBSCRIBE_ID, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "hicall", + .capabilityData = (unsigned char *)"capdata4", + .dataLen = sizeof("capdata4"), + .isSameAccount = true, + .isWakeRemote = false +}; + +static PublishInnerInfo g_pInnerInfo1 = { + .publishId = TEST_PUBLISHINNER_ID1, + .medium = COAP, + .freq = LOW, + .capability = "hicall", + .capabilityData = NULL, + .dataLen = 0 +}; + +static PublishInfo g_pInfo1 = { + .publishId = TEST_PUBLISH_ID1, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = NULL, + .dataLen = 0 +}; + +static SubscribeInnerInfo g_sInnerInfo1 = { + .subscribeId = TEST_SUBSCRIBEINNER_ID1, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = NULL, + .dataLen = 0, + .isSameAccount = true, + .isWakeRemote = false +}; + +static SubscribeInfo g_sInfo1 = { + .subscribeId = TEST_SUBSCRIBE_ID1, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "hicall", + .capabilityData = NULL, + .dataLen = 0, + .isSameAccount = true, + .isWakeRemote = false +}; + +/** + * @tc.name: DiscPublishTest001 + * @tc.desc: inner module active publish,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscPublishTest001, TestSize.Level1) +{ + int ret; + ret = DiscPublish(MODULE_CONN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscPublishTest002 + * @tc.desc: inner module active publish,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscPublishTest002, TestSize.Level1) +{ + int ret; + PublishInnerInfo testInfo = { + .publishId = TEST_PUBLISHINNER_ID, + .medium = COAP, + .freq = LOW, + .capability = "hicall", + .capabilityData = (unsigned char *)"capdata1", + .dataLen = sizeof("capdata1") + }; + + DiscMgrInit(); + + ret = DiscPublish((DiscModule)TEST_ERRO_MOUDULE, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscPublish(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscPublish(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscPublish(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "hicall"; + + testInfo.capabilityData = NULL; + ret = DiscPublish(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscPublish(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscPublishTest003 + * @tc.desc: inner module active publish,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscPublishTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscPublish(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscPublish(MODULE_LNN, &g_pInnerInfo1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscPublishTest004 + * @tc.desc: inner module active publish,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscPublishTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscPublish(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscPublish(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartScanTest001 + * @tc.desc: inner module passive publish,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartScanTest001, TestSize.Level1) +{ + int ret; + ret = DiscStartScan(MODULE_CONN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscStartScanTest002 + * @tc.desc: inner module passive publish,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartScanTest002, TestSize.Level1) +{ + int ret; + PublishInnerInfo testInfo = { + .publishId = TEST_PUBLISHINNER_ID, + .medium = COAP, + .freq = LOW, + .capability = "hicall", + .capabilityData = (unsigned char *)"capdata1", + .dataLen = sizeof("capdata1") + }; + + DiscMgrInit(); + + ret = DiscStartScan((DiscModule)TEST_ERRO_MOUDULE, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscStartScan(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscStartScan(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscStartScan(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "hicall"; + + testInfo.capabilityData = NULL; + ret = DiscStartScan(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscStartScan(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartScanTest003 + * @tc.desc: inner module passive publish,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartScanTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartScan(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartScan(MODULE_LNN, &g_pInnerInfo1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartScanTest004 + * @tc.desc: inner module passive publish,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartScanTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartScan(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartScan(MODULE_LNN, &g_pInnerInfo); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartAdvertiseTest001 + * @tc.desc: inner module active discover,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartAdvertiseTest001, TestSize.Level1) +{ + int ret; + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscStartAdvertiseTest002 + * @tc.desc: inner module active discover,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartAdvertiseTest002, TestSize.Level1) +{ + int ret; + SubscribeInnerInfo testInfo = { + .subscribeId = TEST_SUBSCRIBEINNER_ID, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false + }; + + DiscMgrInit(); + + ret = DiscStartAdvertise((DiscModule)TEST_ERRO_MOUDULE, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscStartAdvertise(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscStartAdvertise(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscStartAdvertise(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "hicall"; + + testInfo.capabilityData = NULL; + ret = DiscStartAdvertise(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscStartAdvertise(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartAdvertiseTest003 + * @tc.desc: inner module active discover,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartAdvertiseTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStartAdvertiseTest004 + * @tc.desc: inner module active discover,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStartAdvertiseTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSubscribeTest001 + * @tc.desc: inner module passive discover,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSubscribeTest001, TestSize.Level1) +{ + int ret; + ret = DiscSubscribe(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscSubscribeTest002 + * @tc.desc: inner module passive discover,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSubscribeTest002, TestSize.Level1) +{ + int ret; + SubscribeInnerInfo testInfo = { + .subscribeId = TEST_SUBSCRIBEINNER_ID, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false + }; + + DiscMgrInit(); + + ret = DiscSubscribe((DiscModule)TEST_ERRO_MOUDULE, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscSubscribe(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscSubscribe(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscSubscribe(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "hicall"; + + testInfo.capabilityData = NULL; + ret = DiscSubscribe(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscSubscribe(MODULE_LNN, &testInfo); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSubscribeTest003 + * @tc.desc: inner module passive discover,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSubscribeTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscSubscribe(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscSubscribe(MODULE_CONN, &g_sInnerInfo1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSubscribeTest004 + * @tc.desc: inner module passive discover,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSubscribeTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscSubscribe(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscSubscribe(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscUnpublishTest001 + * @tc.desc: inner module stop publish,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscUnpublishTest001, TestSize.Level1) +{ + int ret; + ret = DiscUnpublish(MODULE_CONN, TEST_PUBLISHINNER_ID); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscUnpublishTest002 + * @tc.desc: inner module stop publish,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscUnpublishTest002, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublish(MODULE_LNN, &g_pInnerInfo); + + ret = DiscUnpublish((DiscModule)TEST_ERRO_MOUDULE, TEST_PUBLISHINNER_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscUnpublishTest003 + * @tc.desc: inner module stop publish,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscUnpublishTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublish(MODULE_LNN, &g_pInnerInfo); + DiscPublish(MODULE_LNN, &g_pInnerInfo1); + + ret = DiscUnpublish(MODULE_LNN, TEST_PUBLISHINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscUnpublish(MODULE_LNN, TEST_PUBLISHINNER_ID1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscUnpublishTest004 + * @tc.desc: inner module stop publish,release the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscUnpublishTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublish(MODULE_LNN, &g_pInnerInfo); + + ret = DiscUnpublish(MODULE_LNN, TEST_PUBLISHINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscUnpublish(MODULE_LNN, TEST_PUBLISHINNER_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStopAdvertiseTest001 + * @tc.desc: inner module stop discover,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStopAdvertiseTest001, TestSize.Level1) +{ + int ret; + ret = DiscStopAdvertise(MODULE_CONN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: DiscStopAdvertiseTest002 + * @tc.desc: inner module stop discover,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStopAdvertiseTest002, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartAdvertise(MODULE_LNN, &g_sInnerInfo); + + ret = DiscStopAdvertise((DiscModule)TEST_ERRO_MOUDULE, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStopAdvertiseTest003 + * @tc.desc: inner module stop discover,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStopAdvertiseTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartAdvertise(MODULE_LNN, &g_sInnerInfo); + DiscStartAdvertise(MODULE_LNN, &g_sInnerInfo1); + + ret = DiscStopAdvertise(MODULE_LNN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopAdvertise(MODULE_LNN, TEST_SUBSCRIBEINNER_ID1); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscStopAdvertiseTest004 + * @tc.desc: inner module stop discover,release the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscStopAdvertiseTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartAdvertise(MODULE_LNN, &g_sInnerInfo); + + ret = DiscStopAdvertise(MODULE_LNN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopAdvertise(MODULE_LNN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: PublishServiceTest001 + * @tc.desc: extern module publish,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, PublishServiceTest001, TestSize.Level1) +{ + int ret; + ret = DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: PublishServiceTest002 + * @tc.desc: extern module publish,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, PublishServiceTest002, TestSize.Level1) +{ + int ret; + PublishInfo testInfo = { + .publishId = TEST_PUBLISH_ID, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata2", + .dataLen = sizeof("capdata2") + }; + + DiscMgrInit(); + + ret = DiscPublishService(NULL, &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscPublishService(g_erroPkgName, &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscPublishService("pkgname1", NULL, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscPublishService("pkgname1", &testInfo, NULL); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.mode = (DiscoverMode)(DISCOVER_MODE_ACTIVE + 1); + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.mode = DISCOVER_MODE_ACTIVE; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "dvKit"; + + testInfo.capabilityData = NULL; + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscPublishService("pkgname1", &testInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: PublishServiceTest003 + * @tc.desc: extern module publish,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, PublishServiceTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscPublishService("pkgname1", &g_pInfo1, &g_publishCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscPublishService(g_corrPkgName, &g_pInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: PublishServiceTest004 + * @tc.desc: extern module publish,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, PublishServiceTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StartDiscoveryTest001 + * @tc.desc: extern module discover,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StartDiscoveryTest001, TestSize.Level1) +{ + int ret; + ret = DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: StartDiscoveryTest002 + * @tc.desc: extern module discover,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StartDiscoveryTest002, TestSize.Level1) +{ + int ret; + SubscribeInfo testInfo = { + .subscribeId = TEST_SUBSCRIBEINNER_ID, + .medium = COAP, + .mode = DISCOVER_MODE_ACTIVE, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false + }; + + DiscMgrInit(); + + ret = DiscStartDiscovery(NULL, &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscStartDiscovery(g_erroPkgName, &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscStartDiscovery("pkgname1", NULL, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscStartDiscovery("pkgname1", &testInfo, NULL); + TEST_ASSERT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.mode = (DiscoverMode)(DISCOVER_MODE_ACTIVE + 1); + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.mode = DISCOVER_MODE_ACTIVE; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capability = "dvKit"; + + testInfo.capabilityData = NULL; + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = DiscStartDiscovery("pkgname1", &testInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StartDiscoveryTest003 + * @tc.desc: extern module discover,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StartDiscoveryTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartDiscovery("pkgname1", &g_sInfo1, &g_subscribeCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartDiscovery(g_corrPkgName, &g_sInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StartDiscoveryTest004 + * @tc.desc: extern module discover,use the same parameter again. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StartDiscoveryTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: UnPublishServiceTest001 + * @tc.desc: extern module stop publish,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, UnPublishServiceTest001, TestSize.Level1) +{ + int ret; + ret = DiscUnPublishService("pkgname1", TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: UnPublishServiceTest002 + * @tc.desc: extern module stop publish,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, UnPublishServiceTest002, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + + ret = DiscUnPublishService(NULL, TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscUnPublishService(g_erroPkgName, TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscUnPublishService("pkgname2", TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: UnPublishServiceTest003 + * @tc.desc: extern module stop publish,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, UnPublishServiceTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + DiscPublishService("pkgname1", &g_pInfo1, &g_publishCb); + DiscPublishService(g_corrPkgName, &g_pInfo, &g_publishCb); + + ret = DiscUnPublishService("pkgname1", TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscUnPublishService("pkgname1", TEST_PUBLISH_ID1); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscUnPublishService(g_corrPkgName, TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: UnPublishServiceTest004 + * @tc.desc: extern module stop publish,release the same parameter again, + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, UnPublishServiceTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscPublishService("pkgname1", &g_pInfo, &g_publishCb); + + ret = DiscUnPublishService("pkgname1", TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscUnPublishService("pkgname1", TEST_PUBLISH_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StopDiscoveryTest001 + * @tc.desc: extern module stop discover,The module is not initialized. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StopDiscoveryTest001, TestSize.Level1) +{ + int ret; + ret = DiscStopDiscovery("pkgname1", TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: StopDiscoveryTest002 + * @tc.desc: extern module stop discover,use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StopDiscoveryTest002, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + + ret = DiscStopDiscovery(NULL, TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscStopDiscovery(g_erroPkgName, TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret != 0); + + ret = DiscStopDiscovery("pkgname2", TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StopDiscoveryTest003 + * @tc.desc: extern module stop discover,use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StopDiscoveryTest003, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + DiscStartDiscovery("pkgname1", &g_sInfo1, &g_subscribeCb); + DiscStartDiscovery(g_corrPkgName, &g_sInfo, &g_subscribeCb); + + ret = DiscStopDiscovery("pkgname1", TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopDiscovery("pkgname1", TEST_SUBSCRIBE_ID1); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopDiscovery(g_corrPkgName, TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: StopDiscoveryTest004 + * @tc.desc: extern module stop discover,release the same parameter again, + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, StopDiscoveryTest004, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + + ret = DiscStopDiscovery("pkgname1", TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopDiscovery("pkgname1", TEST_SUBSCRIBE_ID); + TEST_ASSERT_TRUE(ret != 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSetDiscoverCallbackTest001 + * @tc.desc: callback set process + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSetDiscoverCallbackTest001, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscSetDiscoverCallback(MODULE_CONN, &g_innerCallback); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopAdvertise(MODULE_CONN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSetDiscoverCallbackTest002 + * @tc.desc: callback set process + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSetDiscoverCallbackTest002, TestSize.Level1) +{ + int ret; + DiscMgrInit(); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscSetDiscoverCallback(MODULE_CONN, &g_innerCallback); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscStopAdvertise(MODULE_CONN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSetDiscoverCallbackTest003 + * @tc.desc: extern onDeviceFound test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSetDiscoverCallbackTest003, TestSize.Level1) +{ + DeviceInfo devInfo; + DiscMgrInit(); + DiscStartDiscovery("pkgname1", &g_sInfo, &g_subscribeCb); + devInfo.capabilityBitmap[0] = TEST_BITMAP_CAP; + DiscOnDeviceFound(&devInfo); + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSetDiscoverCallbackTest004 + * @tc.desc: inner onDeviceFound test + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSetDiscoverCallbackTest004, TestSize.Level1) +{ + int ret; + DeviceInfo devInfo; + DiscMgrInit(); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + ret = DiscSetDiscoverCallback(MODULE_CONN, &g_innerCallback); + TEST_ASSERT_TRUE(ret == 0); + + devInfo.capabilityBitmap[0] = TEST_BITMAP_CAP; + DiscOnDeviceFound(&devInfo); + + ret = DiscStopAdvertise(MODULE_CONN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} + +/** + * @tc.name: DiscSetDiscoverCallbackTest005 + * @tc.desc: inner onDeviceFound test with no callback + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_ManagerTest, DiscSetDiscoverCallbackTest005, TestSize.Level1) +{ + int ret; + DeviceInfo devInfo; + DiscMgrInit(); + + ret = DiscStartAdvertise(MODULE_CONN, &g_sInnerInfo); + TEST_ASSERT_TRUE(ret == 0); + + devInfo.capabilityBitmap[0] = TEST_BITMAP_CAP; + DiscOnDeviceFound(&devInfo); + + ret = DiscStopAdvertise(MODULE_CONN, TEST_SUBSCRIBEINNER_ID); + TEST_ASSERT_TRUE(ret == 0); + + DiscMgrDeinit(); +} +} \ No newline at end of file diff --git a/tests/core/transmission/trans_channel/tcp_direct/BUILD.gn b/tests/core/transmission/trans_channel/tcp_direct/BUILD.gn new file mode 100755 index 000000000..a42d9f5b9 --- /dev/null +++ b/tests/core/transmission/trans_channel/tcp_direct/BUILD.gn @@ -0,0 +1,61 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/transmission" + +ohos_unittest("TransTcpDirectCoreTest") { + module_out_path = module_output_path + sources = [ "unittest/trans_tcp_direct_test.cpp" ] + + include_dirs = [ + "$dsoftbus_root_path/core/adapter/bus_center/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/core/transmission/pending_packet/include", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/transport", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/cJSON", + "//utils/native/base/include", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":TransTcpDirectCoreTest" ] +} diff --git a/tests/core/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp b/tests/core/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp new file mode 100755 index 000000000..29bb75216 --- /dev/null +++ b/tests/core/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "gtest/gtest.h" +#include "session.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "trans_tcp_direct_listener.h" +#include "trans_tcp_direct_manager.h" +#include "trans_tcp_direct_message.h" + +#define TEST_ASSERT_TRUE(ret) \ + if (ret) { \ + LOG_INFO("[succ]:%d\n", __LINE__); \ + printf("[succ]:%d\n", __LINE__); \ + g_succTestCount++; \ + } else { \ + LOG_INFO("[error]:%d\n", __LINE__); \ + printf("[error]:%d\n", __LINE__); \ + g_failTestCount++; \ + } + +using namespace testing::ext; + +namespace OHOS { +static int32_t g_succTestCount = 0; +static int32_t g_failTestCount = 0; + +class TransTcpDirectTest : public testing::Test { +public: + TransTcpDirectTest() + {} + ~TransTcpDirectTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp() override + {} + void TearDown() override + {} +}; + +void TransTcpDirectTest::SetUpTestCase(void) +{} + +void TransTcpDirectTest::TearDownTestCase(void) +{} + +/** + * @tc.name: StartSessionListenerTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, StartSessionListenerTest001, TestSize.Level1) +{ + int ret = 0; + char const *ip = "192.168.8.119"; + int port = 6000; + ret = TransTdcStartSessionListener(NULL, port); + TEST_ASSERT_TRUE(ret != 0); + + ret = TransTdcStartSessionListener(ip, -1); + TEST_ASSERT_TRUE(ret != 0); + + ret = TransTdcStartSessionListener(NULL, -1); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: StoptSessionListenerTest001 + * @tc.desc: extern module active publish, stop session whitout start. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, StoptSessionListenerTest001, TestSize.Level1) +{ + int ret = 0; + ret = TransTdcStopSessionListener(); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: OpenTcpDirectChannelTest001 + * @tc.desc: extern module active publish, start channel with wrong parms. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, OpenTcpDirectChannelTest001, TestSize.Level1) +{ + int ret = 0; + AppInfo appInfo; + ConnectOption connInfo; + (void)memset_s(&appInfo, sizeof(AppInfo), 0, sizeof(AppInfo)); + (void)memset_s(&connInfo, sizeof(ConnectOption), 0, sizeof(ConnectOption)); + connInfo.type = CONNECT_TCP; + connInfo.info.ipOption.port = 6000; + if (strcpy_s(connInfo.info.ipOption.ip, sizeof(connInfo.info.ipOption.ip), "192.168.8.1") != EOK) { + return; + } + int fd = 1; + + ret = TransOpenTcpDirectChannel(NULL, &connInfo, &fd); + TEST_ASSERT_TRUE(ret != 0); + + ret = TransOpenTcpDirectChannel(&appInfo, NULL, &fd); + TEST_ASSERT_TRUE(ret != 0); + + ret = TransOpenTcpDirectChannel(&appInfo, &connInfo, NULL); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: CloseTcpDirectChannelTest001 + * @tc.desc: extern module active publish, close channel with wrong parms. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, CloseTcpDirectChannelTest001, TestSize.Level1) +{ + int ret = 0; + ret = TransCloseDirectChannel(-1); + TEST_ASSERT_TRUE(ret != 0); +} +} \ No newline at end of file diff --git a/tests/sdk/bus_center/unittest/BUILD.gn b/tests/sdk/bus_center/unittest/BUILD.gn new file mode 100755 index 000000000..b0657dba6 --- /dev/null +++ b/tests/sdk/bus_center/unittest/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/bus_center" + +ohos_unittest("BusCenterSdkTest") { + module_out_path = module_output_path + sources = [ "bus_center_sdk_test.cpp" ] + + include_dirs = [ + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits/bus_center", + "$dsoftbus_root_path/interfaces/kits/common", + "//utils/native/base/include", + "unittest/common/", + "//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk/main/cpp/include", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/client:softbus_client", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "permission_standard:libpermissionsdk_standard", + ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":BusCenterSdkTest" ] +} diff --git a/tests/sdk/bus_center/unittest/bus_center_sdk_test.cpp b/tests/sdk/bus_center/unittest/bus_center_sdk_test.cpp new file mode 100755 index 000000000..494f03445 --- /dev/null +++ b/tests/sdk/bus_center/unittest/bus_center_sdk_test.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include "permission/permission.h" +#include "permission/permission_kit.h" +#include "softbus_bus_center.h" +#include "softbus_def.h" +#include "softbus_errcode.h" +#include "softbus_permission.h" +#include "softbus_utils.h" + +namespace OHOS { +using namespace testing::ext; +using namespace OHOS::Security::Permission; + +constexpr char TEST_PKG_NAME[] = "com.softbus.test"; +constexpr int32_t DEFAULT_NODE_STATE_CB_NUM = 10; +constexpr uint8_t DEFAULT_LOCAL_DEVICE_TYPE_ID = 0; + +const std::string SYSTEM_APP_PERMISSION = "com.huawei.permission.MANAGE_DISTRIBUTED_PERMISSION"; +const std::string DANGER_APP_PERMISSION = "ohos.permission.DISTRIBUTED_DATASYNC"; + +const std::string TEST_LABEL = "test label"; +const std::string TEST_DESCRIPTION = "test description"; +const int TEST_LABEL_ID = 9527; +const int TEST_DESCRIPTION_ID = 9528; + +class BusCenterSdkTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +private: + static void AddPermission(const string &pkgName); + static void RemovePermission(const string &pkgName); +}; + +void BusCenterSdkTest::SetUpTestCase() +{ + AddPermission(TEST_PKG_NAME); +} + +void BusCenterSdkTest::TearDownTestCase() +{ + RemovePermission(TEST_PKG_NAME); +} + +void BusCenterSdkTest::SetUp() +{ +} + +void BusCenterSdkTest::TearDown() +{ +} + +void BusCenterSdkTest::AddPermission(const string &pkgName) +{ + std::vector permDefList; + PermissionDef permissionDefAlpha = { + .permissionName = SYSTEM_APP_PERMISSION, + .bundleName = pkgName, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableScope = AVAILABLE_SCOPE_ALL, + .label = TEST_LABEL, + .labelId = TEST_LABEL_ID, + .description = TEST_DESCRIPTION, + .descriptionId = TEST_DESCRIPTION_ID + }; + PermissionDef permissionDefBeta = { + .permissionName = DANGER_APP_PERMISSION, + .bundleName = pkgName, + .grantMode = GrantMode::SYSTEM_GRANT, + .availableScope = AVAILABLE_SCOPE_ALL, + .label = TEST_LABEL, + .labelId = TEST_LABEL_ID, + .description = TEST_DESCRIPTION, + .descriptionId = TEST_DESCRIPTION_ID + }; + permDefList.emplace_back(permissionDefAlpha); + permDefList.emplace_back(permissionDefBeta); + PermissionKit::AddDefPermissions(permDefList); + std::vector permList; + permList.push_back(SYSTEM_APP_PERMISSION); + permList.push_back(DANGER_APP_PERMISSION); + PermissionKit::AddSystemGrantedReqPermissions(pkgName, permList); + PermissionKit::GrantSystemGrantedPermission(pkgName, SYSTEM_APP_PERMISSION); + PermissionKit::GrantSystemGrantedPermission(pkgName, DANGER_APP_PERMISSION); +} + +void BusCenterSdkTest::RemovePermission(const string &pkgName) +{ + int ret = PermissionKit::RemoveDefPermissions(pkgName); + ret = PermissionKit::RemoveSystemGrantedReqPermissions(pkgName); +} + +static void OnNodeOnline(NodeBasicInfo *info) +{ + (void)info; +} + +static INodeStateCb g_nodeStateCb = { + .events = EVENT_NODE_STATE_ONLINE, + .onNodeOnline = OnNodeOnline, +}; + +static void OnJoinLNNDone(ConnectionAddr *addr, const char *networkId, int32_t retCode) +{ + (void)addr; + (void)networkId; + (void)retCode; +} + +static void OnLeaveLNNDone(const char *networkId, int32_t retCode) +{ + (void)networkId; + (void)retCode; +} + +/* +* @tc.name: BUS_CENTER_SDK_Join_Lnn_Test_001 +* @tc.desc: bus center JoinLNN interface exception test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_Join_Lnn_Test_001, TestSize.Level0) +{ + ConnectionAddr addr; + + EXPECT_TRUE(JoinLNN(NULL, &addr, OnJoinLNNDone) != SOFTBUS_OK); + EXPECT_TRUE(JoinLNN(TEST_PKG_NAME, NULL, OnJoinLNNDone) != SOFTBUS_OK); + EXPECT_TRUE(JoinLNN(TEST_PKG_NAME, &addr, NULL) != SOFTBUS_OK); +} + +/* +* @tc.name: BUS_CENTER_SDK_Leave_Lnn_Test_001 +* @tc.desc: bus center LeaveLNN interface exception test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_Leave_Lnn_Test_001, TestSize.Level0) +{ + char errNetIdLenMore[] = "012345678998765432100123456789987654321001234567899876543210abcde"; + char networkId[] = "0123456789987654321001234567899876543210012345678998765432100123"; + + EXPECT_TRUE(LeaveLNN(NULL, OnLeaveLNNDone) != SOFTBUS_OK); + EXPECT_TRUE(LeaveLNN(networkId, NULL) != SOFTBUS_OK); + EXPECT_TRUE(LeaveLNN(errNetIdLenMore, OnLeaveLNNDone) != SOFTBUS_OK); +} + +/* +* @tc.name: BUS_CENTER_SDK_STATE_CB_Test_001 +* @tc.desc: bus center node state callback reg and unreg interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_STATE_CB_Test_001, TestSize.Level0) +{ + EXPECT_TRUE(RegNodeDeviceStateCb(TEST_PKG_NAME, &g_nodeStateCb) == SOFTBUS_OK); + EXPECT_TRUE(UnregNodeDeviceStateCb(&g_nodeStateCb) == SOFTBUS_OK); +} + +/* +* @tc.name: BUS_CENTER_SDK_STATE_CB_Test_002 +* @tc.desc: bus center node state callback reg and unreg upper limit interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_STATE_CB_Test_002, TestSize.Level0) +{ + int i; + + for (i = 0; i <= DEFAULT_NODE_STATE_CB_NUM; ++i) { + if (i < DEFAULT_NODE_STATE_CB_NUM) { + EXPECT_TRUE(RegNodeDeviceStateCb(TEST_PKG_NAME, &g_nodeStateCb) == SOFTBUS_OK); + } else { + EXPECT_TRUE(RegNodeDeviceStateCb(TEST_PKG_NAME, &g_nodeStateCb) != SOFTBUS_OK); + } + } + for (i = 0; i < DEFAULT_NODE_STATE_CB_NUM; ++i) { + EXPECT_TRUE(UnregNodeDeviceStateCb(&g_nodeStateCb) == SOFTBUS_OK); + } +} + +/* +* @tc.name: BUS_CENTER_SDK_GET_ALL_NODE_INFO_Test_001 +* @tc.desc: get all node info interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_GET_ALL_NODE_INFO_Test_001, TestSize.Level0) +{ + NodeBasicInfo *info = NULL; + int infoNum; + + EXPECT_TRUE(GetAllNodeDeviceInfo(TEST_PKG_NAME, &info, &infoNum) == SOFTBUS_OK); + EXPECT_TRUE(info == NULL); + EXPECT_TRUE(infoNum == 0); + if (info != NULL) { + FreeNodeInfo(info); + } +} + +/* +* @tc.name: BUS_CENTER_SDK_GET_LOCAL_NODE_INFO_Test_001 +* @tc.desc: get local info interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_GET_LOCAL_NODE_INFO_Test_001, TestSize.Level0) +{ + NodeBasicInfo info; + + EXPECT_TRUE(GetLocalNodeDeviceInfo(TEST_PKG_NAME, &info) == SOFTBUS_OK); + EXPECT_TRUE(strlen(info.networkId) == (NETWORK_ID_BUF_LEN - 1)); + EXPECT_TRUE(info.deviceTypeId == DEFAULT_LOCAL_DEVICE_TYPE_ID); +} + +/* +* @tc.name: BUS_CENTER_SDK_GET_NODE_KEY_INFO_Test_001 +* @tc.desc: get node key info interface test +* @tc.type: FUNC +* @tc.require: AR000FK6J4 +*/ +HWTEST_F(BusCenterSdkTest, BUS_CENTER_SDK_GET_NODE_KEY_INFO_Test_001, TestSize.Level0) +{ + NodeBasicInfo info; + char uuid[UUID_BUF_LEN] = {0}; + char udid[UDID_BUF_LEN] = {0}; + + (void)memset_s(&info, sizeof(NodeBasicInfo), 0, sizeof(NodeBasicInfo)); + EXPECT_TRUE(GetLocalNodeDeviceInfo(TEST_PKG_NAME, &info) == SOFTBUS_OK); + EXPECT_TRUE(GetNodeKeyInfo(TEST_PKG_NAME, info.networkId, NODE_KEY_UDID, + (uint8_t *)udid, UDID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(GetNodeKeyInfo(TEST_PKG_NAME, info.networkId, NODE_KEY_UUID, + (uint8_t *)uuid, UUID_BUF_LEN) == SOFTBUS_OK); + EXPECT_TRUE(strlen(uuid) == (UUID_BUF_LEN - 1)); +} +} // namespace OHOS diff --git a/tests/sdk/discovery/unittest/BUILD.gn b/tests/sdk/discovery/unittest/BUILD.gn new file mode 100755 index 000000000..959b65611 --- /dev/null +++ b/tests/sdk/discovery/unittest/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/discovery" + +ohos_unittest("DiscSdkTest") { + module_out_path = module_output_path + sources = [ "disc_sdk_test.cpp" ] + + include_dirs = [ + "$dsoftbus_root_path/core/common/inner_communication", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/interfaces/kits/discovery", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/sdk/discovery/include", + "$dsoftbus_root_path/core/adapter/bus_center/include", + "//utils/native/base/include", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/client:softbus_client", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":DiscSdkTest" ] +} diff --git a/tests/sdk/discovery/unittest/disc_sdk_test.cpp b/tests/sdk/discovery/unittest/disc_sdk_test.cpp new file mode 100755 index 000000000..0bd5e3f67 --- /dev/null +++ b/tests/sdk/discovery/unittest/disc_sdk_test.cpp @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "client_disc_manager.h" +#include "softbus_common.h" +#include "softbus_interface.h" +#include "softbus_log.h" + +using namespace testing::ext; + +#define TEST_ERRO_MOUDULE ((MODULE_LNN) + 3) + +namespace OHOS { +static int g_subscribeId = 0; +static int g_publishId = 0; +static const char *g_pkgName = "Softbus_Kits"; +static const char *g_erroPkgName = "Softbus_Erro_Kits"; + +const int32_t ERRO_CAPDATA_LEN = 514; + +class Disc_Test : public testing::Test { +public: + Disc_Test() + {} + ~Disc_Test() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp() override + {} + void TearDown() override + {} +}; + +void Disc_Test::SetUpTestCase(void) +{} + +void Disc_Test::TearDownTestCase(void) +{} + +static int GetSubscribeId(void) +{ + g_subscribeId++; + return g_subscribeId; +} + +static int GetPublishId(void) +{ + g_publishId++; + return g_publishId; +} + +static SubscribeInfo g_sInfo = { + .subscribeId = 1, + .medium = COAP, + .mode = DISCOVER_MODE_ACTIVE, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false +}; + +static PublishInfo g_pInfo = { + .publishId = 1, + .medium = COAP, + .mode = DISCOVER_MODE_ACTIVE, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata4", + .dataLen = sizeof("capdata4") +}; + +static PublishInfo g_pInfo1 = { + .publishId = 1, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = NULL, + .dataLen = 0 +}; + +static SubscribeInfo g_sInfo1 = { + .subscribeId = 1, + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "hicall", + .capabilityData = NULL, + .dataLen = 0, + .isSameAccount = true, + .isWakeRemote = false +}; + +static void TestDeviceFound(const DeviceInfo *device) +{ + LOG_INFO("[client]TestDeviceFound\n"); +} + +static void TestDiscoverFailed(int subscribeId, DiscoveryFailReason failReason) +{ + LOG_INFO("[client]TestDiscoverFailed\n"); +} + +static void TestDiscoverySuccess(int subscribeId) +{ + LOG_INFO("[client]TestDiscoverySuccess\n"); +} + +static void TestPublishSuccess(int publishId) +{ + LOG_INFO("[client]TestPublishSuccess\n"); +} + +static void TestPublishFail(int publishId, PublishFailReason reason) +{ + LOG_INFO("[client]TestPublishFail\n"); +} + +static IDiscoveryCallback g_subscribeCb = { + .OnDeviceFound = TestDeviceFound, + .OnDiscoverFailed = TestDiscoverFailed, + .OnDiscoverySuccess = TestDiscoverySuccess +}; + +static IPublishCallback g_publishCb = { + .OnPublishSuccess = TestPublishSuccess, + .OnPublishFail = TestPublishFail +}; + +/** + * @tc.name: PublishServiceTest001 + * @tc.desc: Verify wrong parameter + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, PublishServiceTest001, TestSize.Level1) +{ + int ret; + PublishInfo testInfo = { + .publishId = GetPublishId(), + .mode = DISCOVER_MODE_ACTIVE, + .medium = COAP, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata2", + .dataLen = sizeof("capdata2") + }; + + ret = PublishService(NULL, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + + ret = PublishService(g_pkgName, NULL, &g_publishCb); + EXPECT_TRUE(ret != 0); + + ret = PublishService(g_pkgName, &testInfo, NULL); + EXPECT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.mode = (DiscoverMode)(DISCOVER_MODE_ACTIVE + 1); + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.mode = DISCOVER_MODE_ACTIVE; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.capability = "dvKit"; + + testInfo.capabilityData = NULL; + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = PublishService(g_pkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); + + ret = PublishService(g_erroPkgName, &testInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: PublishServiceTest002 + * @tc.desc: Verify normal case + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, PublishServiceTest002, TestSize.Level1) +{ + int ret; + + g_pInfo.publishId = GetPublishId(); + ret = PublishService(g_pkgName, &g_pInfo, &g_publishCb); + EXPECT_TRUE(ret == 0); + + g_pInfo1.publishId = GetPublishId(); + ret = PublishService(g_pkgName, &g_pInfo1, &g_publishCb); + EXPECT_TRUE(ret == 0); +} +/** + * @tc.name: PublishServiceTest003 + * @tc.desc: Verify same parameter again + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, PublishServiceTest003, TestSize.Level1) +{ + int ret; + + g_pInfo.publishId = GetPublishId(); + ret = PublishService(g_pkgName, &g_pInfo, &g_publishCb); + EXPECT_TRUE(ret == 0); + ret = PublishService(g_pkgName, &g_pInfo, &g_publishCb); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: StartDiscoveryTest001 + * @tc.desc: Verify wrong parameter + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StartDiscoveryTest001, TestSize.Level1) +{ + int ret; + SubscribeInfo testInfo = { + .subscribeId = GetSubscribeId(), + .medium = COAP, + .mode = DISCOVER_MODE_ACTIVE, + .freq = MID, + .capability = "dvKit", + .capabilityData = (unsigned char *)"capdata3", + .dataLen = sizeof("capdata3"), + .isSameAccount = true, + .isWakeRemote = false + }; + + ret = StartDiscovery(NULL, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + + ret = StartDiscovery(g_erroPkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + + ret = StartDiscovery(g_pkgName, NULL, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + + ret = StartDiscovery(g_pkgName, &testInfo, NULL); + EXPECT_TRUE(ret != 0); + + testInfo.medium = (ExchanageMedium)(COAP + 1); + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.medium = COAP; + + testInfo.mode = (DiscoverMode)(DISCOVER_MODE_ACTIVE + 1); + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.mode = DISCOVER_MODE_ACTIVE; + + testInfo.freq = (ExchangeFreq)(SUPER_HIGH + 1); + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.freq = LOW; + + testInfo.capability = "test"; + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.capability = "dvKit"; + + testInfo.capabilityData = NULL; + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.capabilityData = (unsigned char *)"capdata1"; + + testInfo.dataLen = ERRO_CAPDATA_LEN; + ret = StartDiscovery(g_pkgName, &testInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); + testInfo.dataLen = sizeof("capdata1"); +} +/** + * @tc.name: StartDiscoveryTest002 + * @tc.desc: Verify normal case + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StartDiscoveryTest002, TestSize.Level1) +{ + int ret; + + + g_sInfo.subscribeId = GetSubscribeId(); + ret = StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + EXPECT_TRUE(ret == 0); + + g_sInfo1.subscribeId = GetSubscribeId(); + ret = StartDiscovery(g_pkgName, &g_sInfo1, &g_subscribeCb); + EXPECT_TRUE(ret == 0); +} +/** + * @tc.name: StartDiscoveryTest003 + * @tc.desc: Verify same parameter again + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StartDiscoveryTest003, TestSize.Level1) +{ + int ret; + + g_sInfo.subscribeId = GetSubscribeId(); + ret = StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + EXPECT_TRUE(ret == 0); + ret = StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: UnPublishServiceTest001 + * @tc.desc: Verify wrong parameter + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, UnPublishServiceTest001, TestSize.Level1) +{ + int ret; + int tmpId = GetPublishId(); + + g_pInfo.publishId = tmpId; + PublishService(g_pkgName, &g_pInfo, &g_publishCb); + ret = UnPublishService(NULL, tmpId); + EXPECT_TRUE(ret != 0); + ret = UnPublishService(g_erroPkgName, tmpId); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: UnPublishServiceTest002 + * @tc.desc: Verify normal case + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, UnPublishServiceTest002, TestSize.Level1) +{ + int ret; + int tmpId1 = GetPublishId(); + int tmpId2 = GetPublishId(); + + g_pInfo.publishId = tmpId1; + PublishService(g_pkgName, &g_pInfo, &g_publishCb); + g_pInfo1.publishId = tmpId2; + PublishService(g_pkgName, &g_pInfo1, &g_publishCb); + ret = UnPublishService(g_pkgName, tmpId1); + EXPECT_TRUE(ret == 0); + ret = UnPublishService(g_pkgName, tmpId2); + EXPECT_TRUE(ret == 0); +} +/** + * @tc.name: UnPublishServiceTest003 + * @tc.desc: Verify same parameter again + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, UnPublishServiceTest003, TestSize.Level1) +{ + int ret; + int tmpId = GetPublishId(); + + g_pInfo.publishId = tmpId; + PublishService(g_pkgName, &g_pInfo, &g_publishCb); + ret = UnPublishService(g_pkgName, tmpId); + EXPECT_TRUE(ret == 0); + ret = UnPublishService(g_pkgName, tmpId); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: StopDiscoveryTest001 + * @tc.desc: Verify wrong parameter + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StopDiscoveryTest001, TestSize.Level1) +{ + int ret; + int tmpId = GetSubscribeId(); + + g_sInfo.subscribeId = tmpId; + StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + ret = StopDiscovery(NULL, tmpId); + EXPECT_TRUE(ret != 0); + ret = StopDiscovery(g_erroPkgName, tmpId); + EXPECT_TRUE(ret != 0); +} +/** + * @tc.name: StopDiscoveryTest002 + * @tc.desc: Verify normal case + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StopDiscoveryTest002, TestSize.Level1) +{ + int ret; + int tmpId1 = GetSubscribeId(); + int tmpId2 = GetSubscribeId(); + + g_sInfo.subscribeId = tmpId1; + StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + g_sInfo1.subscribeId = tmpId2; + StartDiscovery(g_pkgName, &g_sInfo1, &g_subscribeCb); + ret = StopDiscovery(g_pkgName, tmpId1); + EXPECT_TRUE(ret == 0); + ret = StopDiscovery(g_pkgName, tmpId2); + EXPECT_TRUE(ret == 0); +} +/** + * @tc.name: StopDiscoveryTest003 + * @tc.desc: Verify same parameter again + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(Disc_Test, StopDiscoveryTest003, TestSize.Level1) +{ + int ret; + int tmpId = GetSubscribeId(); + + g_sInfo.subscribeId = tmpId; + StartDiscovery(g_pkgName, &g_sInfo, &g_subscribeCb); + ret = StopDiscovery(g_pkgName, tmpId); + EXPECT_TRUE(ret == 0); + ret = StopDiscovery(g_pkgName, tmpId); + EXPECT_TRUE(ret != 0); +} +} \ No newline at end of file diff --git a/tests/sdk/transmission/trans_channel/tcp_direct/BUILD.gn b/tests/sdk/transmission/trans_channel/tcp_direct/BUILD.gn new file mode 100755 index 000000000..3be6a8a38 --- /dev/null +++ b/tests/sdk/transmission/trans_channel/tcp_direct/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/communication/dsoftbus/dsoftbus.gni") + +module_output_path = "dsoftbus_standard/transmission" + +ohos_unittest("TransTcpDirectSdkTest") { + module_out_path = module_output_path + sources = [ "unittest/trans_tcp_direct_test.cpp" ] + + include_dirs = [ + "$dsoftbus_root_path/core/adapter/bus_center/include", + "$dsoftbus_root_path/core/adapter/kernel/include", + "$dsoftbus_root_path/core/common/include", + "$dsoftbus_root_path/core/common/message_handler/include", + "$dsoftbus_root_path/core/connection/interface", + "$dsoftbus_root_path/core/transmission/common/include", + "$dsoftbus_root_path/core/transmission/interface", + "$dsoftbus_root_path/core/transmission/pending_packet/include", + "$dsoftbus_root_path/core/transmission/session/include", + "$dsoftbus_root_path/core/transmission/trans_channel/tcp_direct/include", + "$dsoftbus_root_path/core/transmission/trans_channel/manager/include", + "$dsoftbus_root_path/interfaces/kits", + "$dsoftbus_root_path/interfaces/kits/common", + "$dsoftbus_root_path/interfaces/kits/transport", + "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite", + "//base/security/deviceauth/interfaces/innerkits", + "//third_party/cJSON", + "//utils/native/base/include", + "unittest/common/", + ] + + deps = [ + "$dsoftbus_root_path/core/frame/standard/client:softbus_client", + "$dsoftbus_root_path/core/frame/standard/server:softbus_server", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + if (is_standard_system) { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + } else { + external_deps = [ "hilog:libhilog" ] + } +} + +group("unittest") { + testonly = true + deps = [ ":TransTcpDirectSdkTest" ] +} diff --git a/tests/sdk/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp b/tests/sdk/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp new file mode 100755 index 000000000..533af4efd --- /dev/null +++ b/tests/sdk/transmission/trans_channel/tcp_direct/unittest/trans_tcp_direct_test.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "gtest/gtest.h" +#include "session.h" +#include "softbus_errcode.h" +#include "softbus_json_utils.h" +#include "softbus_log.h" +#include "trans_tcp_direct_listener.h" +#include "trans_tcp_direct_manager.h" +#include "trans_tcp_direct_message.h" + +#define TEST_ASSERT_TRUE(ret) \ + if (ret) { \ + LOG_INFO("[succ]:%d\n", __LINE__); \ + printf("[succ]:%d\n", __LINE__); \ + g_succTestCount++; \ + } else { \ + LOG_INFO("[error]:%d\n", __LINE__); \ + printf("[error]:%d\n", __LINE__); \ + g_failTestCount++; \ + } + +using namespace testing::ext; + +namespace OHOS { +static int32_t g_succTestCount = 0; +static int32_t g_failTestCount = 0; + +class TransTcpDirectTest : public testing::Test { +public: + TransTcpDirectTest() + {} + ~TransTcpDirectTest() + {} + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp() override + {} + void TearDown() override + {} +}; + +void TransTcpDirectTest::SetUpTestCase(void) +{} + +void TransTcpDirectTest::TearDownTestCase(void) +{} + +static int OnSessionOpened(int sessionId, int result) +{ + LOG_INFO("session opened,sesison id = %d\r\n", sessionId); + return SOFTBUS_OK; +} + +static void OnSessionClosed(int sessionId) +{ + LOG_INFO("session closed, session id = %d\r\n", sessionId); +} + +static void OnBytesReceived(int sessionId, const void *data, unsigned int len) +{ + LOG_INFO("session bytes received, session id = %d\r\n", sessionId); +} + +static void OnMessageReceived(int sessionId, const void *data, unsigned int len) +{ + LOG_INFO("session msg received, session id = %d\r\n", sessionId); +} + +static SessionAttribute g_sessionAttr = { + .dataType = TYPE_BYTES +}; + +static ISessionListener g_sessionlistener = { + .OnSessionOpened = OnSessionOpened, + .OnSessionClosed = OnSessionClosed, + .OnBytesReceived = OnBytesReceived, + .OnMessageReceived = OnMessageReceived +}; +char const *g_pkgName = "com.huawei.communication.demo"; +char const *g_sessionName = "com.huawei.communication.demo.JtOnOpenSession"; +char const *g_networkid = "ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00"; +char const *g_groupid = "TEST_GROUP_ID"; +#define TEST_SESSION_KEY "TEST_SESSION_KEY" + +/** + * @tc.name: CreateSessionServerTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, CreateSessionServerTest001, TestSize.Level1) +{ + int ret = 0; + ret = CreateSessionServer(NULL, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret != 0); + + ret = CreateSessionServer(g_pkgName, NULL, &g_sessionlistener); + TEST_ASSERT_TRUE(ret != 0); + + ret = CreateSessionServer(g_pkgName, g_sessionName, NULL); + TEST_ASSERT_TRUE(ret != 0); + + ret = CreateSessionServer(g_pkgName, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret == 0); + + ret = RemoveSessionServer(g_pkgName, g_sessionName); + TEST_ASSERT_TRUE(ret == 0); +} + +/** + * @tc.name: CreateSessionServerTest002 + * @tc.desc: extern module active publish, use the normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, CreateSessionServerTest002, TestSize.Level1) +{ + int ret; + ret = CreateSessionServer(g_pkgName, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret == 0); + + ret = RemoveSessionServer(g_pkgName, g_sessionName); + TEST_ASSERT_TRUE(ret == 0); +} + +/** + * @tc.name: CreateSessionServerTest003 + * @tc.desc: extern module active publish, use the same normal parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, CreateSessionServerTest003, TestSize.Level1) +{ + int ret = 0; + ret = CreateSessionServer(g_pkgName, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret == 0); + + ret = CreateSessionServer(g_pkgName, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret != 0); + + ret = RemoveSessionServer(g_pkgName, g_sessionName); + TEST_ASSERT_TRUE(ret == 0); +} + +/** + * @tc.name: CreateSessionServerTest004 + * @tc.desc: extern module active publish, create 9 sessionServer, succ 8, failed at 9th. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, CreateSessionServerTest004, TestSize.Level1) +{ + int ret, i; + char const *sessionName[] = { + "com.huawei.communication.demo.JtOnOpenSession0", + "com.huawei.communication.demo.JtOnOpenSession1", + "com.huawei.communication.demo.JtOnOpenSession2", + "com.huawei.communication.demo.JtOnOpenSession3", + "com.huawei.communication.demo.JtOnOpenSession4", + "com.huawei.communication.demo.JtOnOpenSession5", + "com.huawei.communication.demo.JtOnOpenSession6", + "com.huawei.communication.demo.JtOnOpenSession7", + "com.huawei.communication.demo.JtOnOpenSession8", + "com.huawei.communication.demo.JtOnOpenSession9" + }; + + char const *pkgName[] = { + "com.huawei.communication.demo0", + "com.huawei.communication.demo1", + "com.huawei.communication.demo2", + "com.huawei.communication.demo3", + "com.huawei.communication.demo4", + "com.huawei.communication.demo5", + "com.huawei.communication.demo6", + "com.huawei.communication.demo7", + "com.huawei.communication.demo8", + "com.huawei.communication.demo9" + }; + + for (i = 0; i < 8; i++) { + ret = CreateSessionServer(pkgName[i], sessionName[i], &g_sessionlistener); + TEST_ASSERT_TRUE(ret == 0); + } + ret = CreateSessionServer(pkgName[i], sessionName[i], &g_sessionlistener); + TEST_ASSERT_TRUE(ret != 0); + + for (i = 0; i < 8; i++) { + ret = RemoveSessionServer(pkgName[i], sessionName[i]); + TEST_ASSERT_TRUE(ret == 0); + } +} + +/** + * @tc.name: RemoveSessionServerTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, RemoveSessionServerTest001, TestSize.Level1) +{ + int ret; + ret = RemoveSessionServer(NULL, g_sessionName); + TEST_ASSERT_TRUE(ret != 0); + + ret = RemoveSessionServer(g_pkgName, NULL); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: RemoveSessionServerTest002 + * @tc.desc: extern module active publish, use the same parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, RemoveSessionServerTest002, TestSize.Level1) +{ + int ret; + ret = CreateSessionServer(g_pkgName, g_sessionName, &g_sessionlistener); + TEST_ASSERT_TRUE(ret == 0); + + ret = RemoveSessionServer(g_pkgName, g_sessionName); + TEST_ASSERT_TRUE(ret == 0); + + ret = RemoveSessionServer(g_pkgName, g_sessionName); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: OpenSessionTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, OpenSessionTest001, TestSize.Level1) +{ + int ret; + ret = OpenSession(NULL, g_sessionName, g_networkid, g_groupid, &g_sessionAttr); + TEST_ASSERT_TRUE(ret != 0); + + ret = OpenSession(g_sessionName, NULL, g_networkid, g_groupid, &g_sessionAttr); + TEST_ASSERT_TRUE(ret != 0); + + ret = OpenSession(g_sessionName, g_sessionName, NULL, g_groupid, &g_sessionAttr); + TEST_ASSERT_TRUE(ret != 0); + + ret = OpenSession(g_sessionName, g_sessionName, g_networkid, NULL, &g_sessionAttr); + TEST_ASSERT_TRUE(ret != 0); + + ret = OpenSession(g_sessionName, g_sessionName, g_networkid, g_groupid, NULL); + + g_sessionAttr.dataType = TYPE_BUTT; + ret = OpenSession(g_sessionName, g_sessionName, g_networkid, g_groupid, &g_sessionAttr); + g_sessionAttr.dataType = TYPE_BYTES; + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: SendMessageTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, SendMessageTest001, TestSize.Level1) +{ + int ret; + int sessionId = 1; + char const *data = "testdata"; + uint32_t len = strlen(data); + + ret = SendMessage(-1, data, len); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendMessage(sessionId, NULL, len); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendMessage(sessionId, data, -1); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendMessage(sessionId, data, 0); + TEST_ASSERT_TRUE(ret != 0); +} + +/** + * @tc.name: SendBytesTest001 + * @tc.desc: extern module active publish, use the wrong parameter. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TransTcpDirectTest, SendBytesTest001, TestSize.Level1) +{ + int ret; + int sessionId = 1; + char const *data = "testdata"; + uint32_t len = strlen(data); + + ret = SendBytes(-1, data, len); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendBytes(sessionId, NULL, len); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendBytes(sessionId, data, -1); + TEST_ASSERT_TRUE(ret != 0); + + ret = SendBytes(sessionId, data, 0); + TEST_ASSERT_TRUE(ret != 0); +} +}