From cb1a9ea078ba6c85ffc1f26d386d375d3c2ef6d3 Mon Sep 17 00:00:00 2001 From: luzhiye Date: Mon, 12 Aug 2024 06:29:01 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E7=A9=BA=E6=8C=87=E9=92=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: luzhiye --- interfaces/kits/js/napi/src/usb_info.cpp | 96 +++++++++++++++++++ .../native/src/usbd_bulkcallback_impl.cpp | 10 +- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/interfaces/kits/js/napi/src/usb_info.cpp b/interfaces/kits/js/napi/src/usb_info.cpp index aef98f13..e899f355 100644 --- a/interfaces/kits/js/napi/src/usb_info.cpp +++ b/interfaces/kits/js/napi/src/usb_info.cpp @@ -593,7 +593,15 @@ static napi_value CoreHasRight(napi_env env, napi_callback_info info) } static auto g_requestRightExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBRightAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } int32_t ret = g_usbClient.RequestRight(asyncContext->deviceName); if (ret == UEC_OK) { asyncContext->status = napi_ok; @@ -603,7 +611,15 @@ static auto g_requestRightExecute = [](napi_env env, void *data) { }; static auto g_requestRightComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBRightAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; napi_get_boolean(env, asyncContext->status == napi_ok, &queryResult); @@ -698,13 +714,29 @@ static napi_value CoreUsbFunctionsToString(napi_env env, napi_callback_info info } static auto g_setCurrentFunctionExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBFunctionAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } int32_t ret = g_usbClient.SetCurrentFunctions(asyncContext->functions); asyncContext->errCode = ret; }; static auto g_setCurrentFunctionComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBFunctionAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; if (asyncContext->errCode == UEC_OK) { @@ -852,13 +884,29 @@ static napi_value PortGetSupportedModes(napi_env env, napi_callback_info info) } static auto g_setPortRoleExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBPortRoleAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } int32_t ret = g_usbClient.SetPortRole(asyncContext->portId, asyncContext->powerRole, asyncContext->dataRole); asyncContext->errCode = ret; }; static auto g_setPortRoleComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBPortRoleAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; if (asyncContext->errCode == UEC_OK) { @@ -1103,7 +1151,15 @@ static napi_value PipeGetFileDescriptor(napi_env env, napi_callback_info info) } static auto g_controlTransferExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBControlTransferAsyncContext *asyncContext = (USBControlTransferAsyncContext *)data; + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1135,7 +1191,15 @@ static auto g_controlTransferExecute = [](napi_env env, void *data) { }; static auto g_controlTransferComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBControlTransferAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { @@ -1254,7 +1318,15 @@ static napi_value PipeControlTransfer(napi_env env, napi_callback_info info) } static auto g_usbControlTransferExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBDeviceControlTransferAsyncContext *asyncContext = (USBDeviceControlTransferAsyncContext *)data; + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1286,7 +1358,15 @@ static auto g_usbControlTransferExecute = [](napi_env env, void *data) { }; static auto g_usbControlTransferComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBDeviceControlTransferAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { @@ -1405,7 +1485,15 @@ static napi_value PipeUsbControlTransfer(napi_env env, napi_callback_info info) } static auto g_bulkTransferExecute = [](napi_env env, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBBulkTransferAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1436,7 +1524,15 @@ static auto g_bulkTransferExecute = [](napi_env env, void *data) { }; static auto g_bulkTransferComplete = [](napi_env env, napi_status status, void *data) { + if (data == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); + return napi_error; + } USBBulkTransferAsyncContext *asyncContext = reinterpret_cast(data); + if (asyncContext == nullptr) { + USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); + return napi_error; + } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { napi_create_int32(env, asyncContext->dataSize, &queryResult); diff --git a/services/native/src/usbd_bulkcallback_impl.cpp b/services/native/src/usbd_bulkcallback_impl.cpp index 240b1143..81e3f86d 100644 --- a/services/native/src/usbd_bulkcallback_impl.cpp +++ b/services/native/src/usbd_bulkcallback_impl.cpp @@ -36,6 +36,10 @@ int32_t UsbdBulkCallbackImpl::OnBulkWriteCallback(int32_t status, int32_t actLen USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write actLength failed", __func__); return UEC_SERVICE_INVALID_VALUE; } + if (remote_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); + return UEC_SERVICE_INVALID_VALUE; + } int32_t ret = remote_->SendRequest(UsbdBulkCallBack::CMD_USBD_BULK_CALLBACK_WRITE, data, reply, option); if (ret != UEC_OK) { USB_HILOGE(MODULE_USB_SERVICE, "%{public}s failed, error code is %{public}d", __func__, ret); @@ -51,12 +55,14 @@ int32_t UsbdBulkCallbackImpl::OnBulkReadCallback(int32_t status, int32_t actLeng USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write status failed", __func__); return UEC_SERVICE_INVALID_VALUE; } - if (!data.WriteInt32(actLength)) { USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write actLength failed", __func__); return UEC_SERVICE_INVALID_VALUE; } - + if (remote_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); + return UEC_SERVICE_INVALID_VALUE; + } OHOS::MessageParcel reply; OHOS::MessageOption option; int32_t ret = remote_->SendRequest(UsbdBulkCallBack::CMD_USBD_BULK_CALLBACK_READ, data, reply, option); -- Gitee From d8d3c57f79596a1af7973a799102d9ef14d8bb2c Mon Sep 17 00:00:00 2001 From: luzhiye Date: Mon, 12 Aug 2024 11:14:38 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E4=B8=8D=E9=9C=80=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E7=A9=BA=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: luzhiye --- interfaces/kits/js/napi/src/usb_info.cpp | 96 ------------------------ 1 file changed, 96 deletions(-) diff --git a/interfaces/kits/js/napi/src/usb_info.cpp b/interfaces/kits/js/napi/src/usb_info.cpp index e899f355..aef98f13 100644 --- a/interfaces/kits/js/napi/src/usb_info.cpp +++ b/interfaces/kits/js/napi/src/usb_info.cpp @@ -593,15 +593,7 @@ static napi_value CoreHasRight(napi_env env, napi_callback_info info) } static auto g_requestRightExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBRightAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } int32_t ret = g_usbClient.RequestRight(asyncContext->deviceName); if (ret == UEC_OK) { asyncContext->status = napi_ok; @@ -611,15 +603,7 @@ static auto g_requestRightExecute = [](napi_env env, void *data) { }; static auto g_requestRightComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBRightAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; napi_get_boolean(env, asyncContext->status == napi_ok, &queryResult); @@ -714,29 +698,13 @@ static napi_value CoreUsbFunctionsToString(napi_env env, napi_callback_info info } static auto g_setCurrentFunctionExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBFunctionAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } int32_t ret = g_usbClient.SetCurrentFunctions(asyncContext->functions); asyncContext->errCode = ret; }; static auto g_setCurrentFunctionComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBFunctionAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; if (asyncContext->errCode == UEC_OK) { @@ -884,29 +852,13 @@ static napi_value PortGetSupportedModes(napi_env env, napi_callback_info info) } static auto g_setPortRoleExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBPortRoleAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } int32_t ret = g_usbClient.SetPortRole(asyncContext->portId, asyncContext->powerRole, asyncContext->dataRole); asyncContext->errCode = ret; }; static auto g_setPortRoleComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBPortRoleAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; if (asyncContext->errCode == UEC_OK) { @@ -1151,15 +1103,7 @@ static napi_value PipeGetFileDescriptor(napi_env env, napi_callback_info info) } static auto g_controlTransferExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBControlTransferAsyncContext *asyncContext = (USBControlTransferAsyncContext *)data; - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1191,15 +1135,7 @@ static auto g_controlTransferExecute = [](napi_env env, void *data) { }; static auto g_controlTransferComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBControlTransferAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { @@ -1318,15 +1254,7 @@ static napi_value PipeControlTransfer(napi_env env, napi_callback_info info) } static auto g_usbControlTransferExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBDeviceControlTransferAsyncContext *asyncContext = (USBDeviceControlTransferAsyncContext *)data; - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if ((asyncContext->reqType & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1358,15 +1286,7 @@ static auto g_usbControlTransferExecute = [](napi_env env, void *data) { }; static auto g_usbControlTransferComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBDeviceControlTransferAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { @@ -1485,15 +1405,7 @@ static napi_value PipeUsbControlTransfer(napi_env env, napi_callback_info info) } static auto g_bulkTransferExecute = [](napi_env env, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBBulkTransferAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } std::vector bufferData(asyncContext->buffer, asyncContext->buffer + asyncContext->bufferLength); if (asyncContext->endpoint.GetDirection() == USB_ENDPOINT_DIR_OUT) { delete[] asyncContext->buffer; @@ -1524,15 +1436,7 @@ static auto g_bulkTransferExecute = [](napi_env env, void *data) { }; static auto g_bulkTransferComplete = [](napi_env env, napi_status status, void *data) { - if (data == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: data is nullptr", __func__); - return napi_error; - } USBBulkTransferAsyncContext *asyncContext = reinterpret_cast(data); - if (asyncContext == nullptr) { - USB_HILOGE(MODULE_JS_NAPI, "%{public}s: asyncContext is nullptr", __func__); - return napi_error; - } napi_value queryResult = nullptr; if (asyncContext->status == napi_ok) { napi_create_int32(env, asyncContext->dataSize, &queryResult); -- Gitee From ffc132656e3edf6b74caed00d905f1537153a2b8 Mon Sep 17 00:00:00 2001 From: luzhiye Date: Tue, 13 Aug 2024 01:25:33 +0000 Subject: [PATCH 3/3] update services/native/src/usbd_bulkcallback_impl.cpp. Signed-off-by: luzhiye --- services/native/src/usbd_bulkcallback_impl.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/services/native/src/usbd_bulkcallback_impl.cpp b/services/native/src/usbd_bulkcallback_impl.cpp index 81e3f86d..5b42cfa5 100644 --- a/services/native/src/usbd_bulkcallback_impl.cpp +++ b/services/native/src/usbd_bulkcallback_impl.cpp @@ -24,6 +24,10 @@ namespace OHOS { namespace USB { int32_t UsbdBulkCallbackImpl::OnBulkWriteCallback(int32_t status, int32_t actLength) { + if (remote_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); + return UEC_SERVICE_INVALID_VALUE; + } OHOS::MessageParcel data; OHOS::MessageParcel reply; OHOS::MessageOption option; @@ -31,15 +35,10 @@ int32_t UsbdBulkCallbackImpl::OnBulkWriteCallback(int32_t status, int32_t actLen USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write status failed", __func__); return UEC_SERVICE_INVALID_VALUE; } - if (!data.WriteInt32(actLength)) { USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write actLength failed", __func__); return UEC_SERVICE_INVALID_VALUE; } - if (remote_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); - return UEC_SERVICE_INVALID_VALUE; - } int32_t ret = remote_->SendRequest(UsbdBulkCallBack::CMD_USBD_BULK_CALLBACK_WRITE, data, reply, option); if (ret != UEC_OK) { USB_HILOGE(MODULE_USB_SERVICE, "%{public}s failed, error code is %{public}d", __func__, ret); @@ -50,6 +49,10 @@ int32_t UsbdBulkCallbackImpl::OnBulkWriteCallback(int32_t status, int32_t actLen int32_t UsbdBulkCallbackImpl::OnBulkReadCallback(int32_t status, int32_t actLength) { + if (remote_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); + return UEC_SERVICE_INVALID_VALUE; + } OHOS::MessageParcel data; if (!data.WriteInt32(status)) { USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write status failed", __func__); @@ -59,10 +62,6 @@ int32_t UsbdBulkCallbackImpl::OnBulkReadCallback(int32_t status, int32_t actLeng USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: write actLength failed", __func__); return UEC_SERVICE_INVALID_VALUE; } - if (remote_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "%{public}s: remote_ is nullptr", __func__); - return UEC_SERVICE_INVALID_VALUE; - } OHOS::MessageParcel reply; OHOS::MessageOption option; int32_t ret = remote_->SendRequest(UsbdBulkCallBack::CMD_USBD_BULK_CALLBACK_READ, data, reply, option); -- Gitee