From: liangzhenying <867174124@qq.com> Date: Tue, 24 Dec 2024 06:33:49 +0000 (+0800) Subject: 富瑞坤去掉鉴权 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=e8b64cfe8d78e746545a232ba18eb6b43e73201a;p=mirrors%2FMouseSdk-MacOS.git 富瑞坤去掉鉴权 --- diff --git a/Document/Scenario2_Client.cpp b/Document/Scenario2_Client.cpp new file mode 100644 index 0000000..ac0d479 --- /dev/null +++ b/Document/Scenario2_Client.cpp @@ -0,0 +1,926 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#include "pch.h" +#include "Scenario2_Client.h" +#include "Scenario2_Client.g.cpp" +#include "SampleConfiguration.h" +#include "BluetoothLEAttributeDisplay.h" +extern "C" { +#include "stb_app.h" +#include "stb_hal.h" +} +#include +#include + +using namespace winrt; +using namespace Windows::Devices::Bluetooth; +using namespace Windows::Devices::Bluetooth::GenericAttributeProfile; +using namespace Windows::Devices::Enumeration; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::Globalization; +using namespace Windows::Security::Cryptography; +using namespace Windows::Storage::Streams; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Navigation; +using namespace Windows::Foundation::Collections; +using namespace Windows::Storage::Streams; + +// +GattCharacteristic CusWriteCharacteristic{ nullptr }; +SDKTemplate::MainPage g_rootPage = nullptr; +std::wstring g_tokenStr; + +#include + + +void STB_STDCALL cus_printf(const char* format, ...) +{ + char buffer[1024]; + va_list args; + va_start(args, format); + int len = vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + OutputDebugStringA(buffer); + + return; +} + +void STB_STDCALL cus_printf_str(char* str) +{ + OutputDebugStringA(str); + return; +} + +//int32_t stb_hal_send_data(uint8_t* data, uint32_t len) +int32_t STB_STDCALL cus_hal_send_data2device(uint8_t* data, uint32_t len) +{ + std::ostringstream oss; + // 把数据转换成十六进制字符串 + IBuffer buffer; + for (uint32_t i = 0; i < len; ++i) + { + oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(data[i]) << " "; + } + // 转换为字符串并使用 OutputDebugString 输出 + std::string hexData = oss.str(); + OutputDebugString(L"[STBAPP] send data 2 device:\n"); + OutputDebugStringA(hexData.c_str()); + DataWriter writer; + for (uint32_t i = 0; i < len; ++i) + { + writer.WriteByte(data[i]); + } + writer.WriteByte('\n'); + buffer = writer.DetachBuffer(); + CusWriteCharacteristic.WriteValueAsync(buffer); + return 0; +} + +void STB_STDCALL cust_event_callback_func(uint32_t type, uint8_t* data, uint32_t data_len) +{ + + switch (type) { + case STB_DYNREG_SUCCESS: + OutputDebugString(L"\n\STB_DYNREG_SUCCESS\n\r"); + g_rootPage.NotifyUser(L"dynreg success.", SDKTemplate::NotifyType::StatusMessage); + break; + case STB_DYNREG_FAIL: + OutputDebugString(L"\n\rSTB_DYNREG_FAIL\n\r"); + g_rootPage.NotifyUser(L"dynreg failed.", SDKTemplate::NotifyType::ErrorMessage); + break; + case STB_MQTT_CONNECT_SUCCESS: + OutputDebugString(L"\n\STB_MQTT_CONNECT_SUCCESS\n\r"); + g_rootPage.NotifyUser(L"mqtt connect success.", SDKTemplate::NotifyType::StatusMessage); + break; + case STB_MQTT_CONNECT_FAIL: + OutputDebugString(L"\n\STB_MQTT_CONNECT_FAIL\n\r"); + g_rootPage.NotifyUser(L"mqtt connect fail.", SDKTemplate::NotifyType::ErrorMessage); + break; + case STB_MQTT_CONNECT_OFFLINE: + OutputDebugString(L"\n\STB_MQTT_CONNECT_OFFLINE\n\r"); + g_rootPage.NotifyUser(L"mqtt connect offline.", SDKTemplate::NotifyType::ErrorMessage); + break; + case STB_MQTT_CONNECT_ONLINE: + OutputDebugString(L"\n\STB_MQTT_CONNECT_ONLINE\n\r"); + g_rootPage.NotifyUser(L"mqtt connect online.", SDKTemplate::NotifyType::StatusMessage); + break; + case STB_DM_DATA_ARRIVED_TOKEN: + OutputDebugString(L"\n\STB_DM_DATA_ARRIVED_TOKEN\n\r"); + break; + case STB_DM_DATA_ARRIVED_TOKEN_TIMEOUT: + OutputDebugString(L"\n\STB_DM_DATA_ARRIVED_TOKEN_TIMEOUT\n\r"); + break; + case STB_DM_DATA_ARRIVED_HOST: + OutputDebugString(L"\n\STB_DM_DATA_ARRIVED_HOST\n\r"); + break; + case STB_DM_DATA_ARRIVED_PARAMS_SIGN: + OutputDebugString(L"\n\STB_DM_DATA_ARRIVED_PARAMS_SIGN\n\r"); + break; + default: + OutputDebugString(L"\n\UNKNOWN_MSG\n\r"); + break; + } + + + if (data != nullptr && data_len > 0) + { + if (type == STB_DM_DATA_ARRIVED_TOKEN || type == STB_DM_DATA_ARRIVED_TOKEN_TIMEOUT || type == STB_DM_DATA_ARRIVED_PARAMS_SIGN) + { + if (type == STB_DM_DATA_ARRIVED_TOKEN) + { + g_tokenStr.clear(); + } + + for (uint32_t i = 0; i < data_len; ++i) + { + g_tokenStr.append(1, static_cast(data[i])); + } + g_tokenStr.append(1, '\n'); + if (type == STB_DM_DATA_ARRIVED_PARAMS_SIGN) + { + g_rootPage.NotifyUser(g_tokenStr.c_str(), SDKTemplate::NotifyType::StatusMessage); + } + + } + else + { + // 将 data 转换为字符串打印 + std::wstring dataStr = L"[STBAPP]Data: "; + for (uint32_t i = 0; i < data_len; ++i) + { + dataStr.append(1, static_cast(data[i])); + } + OutputDebugString(dataStr.c_str()); + OutputDebugString(L"\n\[STBAPP]EndCB\n\r"); + + g_rootPage.NotifyUser(dataStr.c_str(), SDKTemplate::NotifyType::StatusMessage); + } + + } + +} +namespace +{ + void SetVisibility(UIElement const& element, bool visible) + { + element.Visibility(visible ? Visibility::Visible : Visibility::Collapsed); + } + + // Utility function to convert a string to an int32_t and detect bad input + bool TryParseInt(const wchar_t* str, int32_t& result) + { + wchar_t* end; + errno = 0; + result = std::wcstol(str, &end, 0); + + if (str == end) + { + // Not parseable. + return false; + } + + if (errno == ERANGE || result < INT_MIN || INT_MAX < result) + { + // Out of range. + return false; + } + + if (*end != L'\0') + { + // Extra unparseable characters at the end. + return false; + } + + return true; + } + + template + T Read(DataReader const& reader); + + template<> + uint32_t Read(DataReader const& reader) + { + return reader.ReadUInt32(); + } + + template<> + int32_t Read(DataReader const& reader) + { + return reader.ReadInt32(); + } + + template<> + uint8_t Read(DataReader const& reader) + { + return reader.ReadByte(); + } + + template + bool TryExtract(IBuffer const& buffer, T& result) + { + if (buffer.Length() >= sizeof(T)) + { + DataReader reader = DataReader::FromBuffer(buffer); + result = Read(reader); + return true; + } + return false; + } +} + +namespace winrt +{ + hstring to_hstring(GattCommunicationStatus status) + { + switch (status) + { + case GattCommunicationStatus::Success: return L"Success"; + case GattCommunicationStatus::Unreachable: return L"Unreachable"; + case GattCommunicationStatus::ProtocolError: return L"ProtocolError"; + case GattCommunicationStatus::AccessDenied: return L"AccessDenied"; + } + return to_hstring(static_cast(status)); + } +} + +namespace winrt::SDKTemplate::implementation +{ +#pragma region UI Code + Scenario2_Client::Scenario2_Client() + { + InitializeComponent(); + g_rootPage = rootPage; + } + + void Scenario2_Client::OnNavigatedTo(NavigationEventArgs const&) + { + SelectedDeviceRun().Text(SampleState::SelectedBleDeviceName); + if (SampleState::SelectedBleDeviceId.empty()) + { + ConnectButton().IsEnabled(false); + } + } + + fire_and_forget Scenario2_Client::OnNavigatedFrom(NavigationEventArgs const&) + { + auto lifetime = get_strong(); + if (!co_await ClearBluetoothLEDeviceAsync()) + { + rootPage.NotifyUser(L"Error: Unable to reset app state", NotifyType::ErrorMessage); + } + } +#pragma endregion + +#pragma region Enumerating Services + IAsyncOperation Scenario2_Client::ClearBluetoothLEDeviceAsync() + { + auto lifetime = get_strong(); + + if (notificationsToken) + { + // Need to clear the CCCD from the remote device so we stop receiving notifications + GattCommunicationStatus result = co_await registeredCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue::None); + if (result != GattCommunicationStatus::Success) + { + co_return false; + } + else + { + selectedCharacteristic.ValueChanged(std::exchange(notificationsToken, {})); + } + } + + if (bluetoothLeDevice != nullptr) + { + bluetoothLeDevice.Close(); + bluetoothLeDevice = nullptr; + } + co_return true; + } + + fire_and_forget Scenario2_Client::ConnectButton_Click() + { + auto lifetime = get_strong(); + + ConnectButton().IsEnabled(false); + + if (!co_await ClearBluetoothLEDeviceAsync()) + { + rootPage.NotifyUser(L"Error: Unable to reset state, try again.", NotifyType::ErrorMessage); + ConnectButton().IsEnabled(true); + co_return; + } + + try + { + // BT_Code: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent. + bluetoothLeDevice = co_await BluetoothLEDevice::FromIdAsync(SampleState::SelectedBleDeviceId); + + if (bluetoothLeDevice == nullptr) + { + rootPage.NotifyUser(L"Failed to connect to device.", NotifyType::ErrorMessage); + } + } + catch (hresult_error& ex) + { + if (ex.to_abi() == HRESULT_FROM_WIN32(ERROR_DEVICE_NOT_AVAILABLE)) + { + rootPage.NotifyUser(L"Bluetooth radio is not on.", NotifyType::ErrorMessage); + } + else + { + throw; + } + } + + if (bluetoothLeDevice != nullptr) + { + // Note: BluetoothLEDevice.GattServices property will return an empty list for unpaired devices. For all uses we recommend using the GetGattServicesAsync method. + // BT_Code: GetGattServicesAsync returns a list of all the supported services of the device (even if it's not paired to the system). + // If the services supported by the device are expected to change during BT usage, subscribe to the GattServicesChanged event. + GattDeviceServicesResult result = co_await bluetoothLeDevice.GetGattServicesAsync(BluetoothCacheMode::Uncached); + + if (result.Status() == GattCommunicationStatus::Success) + { + IVectorView services = result.Services(); + rootPage.NotifyUser(L"Found " + to_hstring(services.Size()) + L" services", NotifyType::StatusMessage); + for (auto&& service : services) + { + ComboBoxItem item; + item.Content(box_value(DisplayHelpers::GetServiceName(service))); + item.Tag(service); + ServiceList().Items().Append(item); + } + ConnectButton().Visibility(Visibility::Collapsed); + ServiceList().Visibility(Visibility::Visible); + } + else + { + rootPage.NotifyUser(L"Device unreachable", NotifyType::ErrorMessage); + } + } + ConnectButton().IsEnabled(true); + } + void Scenario2_Client::STB_StartAuth_Click() + { + OutputDebugString(L"[STBAPP] Auth button cliecked\n"); + OutputDebugString(L"[STBAPP] identify start\n"); + stb_app_start_identify(); + return; + } + void Scenario2_Client::STB_Init_Click() + { + OutputDebugString(L"[STBAPP] init button cliecked\n"); + stb_app_printf_str_register(cus_printf_str); + stb_app_init("tis_test"); + stb_app_event_callback_register(cust_event_callback_func); + //stb_app_printf_register(cus_printf); + stb_app_send_data_to_device_register(cus_hal_send_data2device); + return; + } + void Scenario2_Client::STB_GetToken_Click() + { + OutputDebugString(L"[STBAPP] token button cliecked\n"); + stb_app_get_token_async(); + return; + } + void Scenario2_Client::STB_Factory_Dev1_Click() + { + OutputDebugString(L"[STBAPP] Factory1 click\n"); + char *ds = device_register("k1r8dWlSOjM","474849404142","wZUBUo2vnR0LvMq9"); + if (ds != NULL) + { + device_active("k1r8dWlSOjM", "474849404142", ds); + } + return; + } + void Scenario2_Client::STB_Factory_Dev2_Click() + { + OutputDebugString(L"[STBAPP] Factory2 click\n"); + char* ds = device_register("k1r8dWlSOjM", "474849404140", "wZUBUo2vnR0LvMq9"); + if (ds != NULL) + { + device_active("k1r8dWlSOjM", "474849404140", ds); + } + return; + } + void Scenario2_Client::STB_Factory_Dev3_Click() + { + OutputDebugString(L"[STBAPP] Factory3 click\n"); + + return; + } +#pragma region Enumerating Characteristics + fire_and_forget Scenario2_Client::ServiceList_SelectionChanged() + { + auto lifetime = get_strong(); + + auto selectedItem = ServiceList().SelectedItem().as(); + GattDeviceService service = selectedItem ? selectedItem.Tag().as() : nullptr; + + CharacteristicList().Items().Clear(); + RemoveValueChangedHandler(); + + IVectorView characteristics{ nullptr }; + try + { + // Ensure we have access to the device. + auto accessStatus = co_await service.RequestAccessAsync(); + if (accessStatus == DeviceAccessStatus::Allowed) + { + // BT_Code: Get all the child characteristics of a service. Use the cache mode to specify uncached characterstics only + // and the new Async functions to get the characteristics of unpaired devices as well. + GattCharacteristicsResult result = co_await service.GetCharacteristicsAsync(BluetoothCacheMode::Uncached); + if (result.Status() == GattCommunicationStatus::Success) + { + characteristics = result.Characteristics(); + } + else + { + rootPage.NotifyUser(L"Error accessing service.", NotifyType::ErrorMessage); + } + } + else + { + // Not granted access + rootPage.NotifyUser(L"Error accessing service.", NotifyType::ErrorMessage); + + } + } + catch (hresult_error& ex) + { + rootPage.NotifyUser(L"Restricted service. Can't read characteristics: " + ex.message(), NotifyType::ErrorMessage); + } + + if (characteristics) + { + for (GattCharacteristic&& c : characteristics) + { + ComboBoxItem item; + item.Content(box_value(DisplayHelpers::GetCharacteristicName(c))); + item.Tag(c); + CharacteristicList().Items().Append(item); + } + } + CharacteristicList().Visibility(Visibility::Visible); + } +#pragma endregion + + void Scenario2_Client::AddValueChangedHandler() + { + ValueChangedSubscribeToggle().Content(box_value(L"Unsubscribe from value changes")); + if (!notificationsToken) + { + registeredCharacteristic = selectedCharacteristic; + notificationsToken = registeredCharacteristic.ValueChanged({ get_weak(), &Scenario2_Client::Characteristic_ValueChanged }); + } + } + void Scenario2_Client::RemoveValueChangedHandler() + { + ValueChangedSubscribeToggle().Content(box_value(L"Subscribe to value changes")); + if (notificationsToken) + { + registeredCharacteristic.ValueChanged(std::exchange(notificationsToken, {})); + registeredCharacteristic = nullptr; + } + } + + fire_and_forget Scenario2_Client::CharacteristicList_SelectionChanged() + { + auto lifetime = get_strong(); + + auto selectedItem = CharacteristicList().SelectedItem().as(); + selectedCharacteristic = selectedItem ? selectedItem.Tag().as() : nullptr; + if ((selectedCharacteristic.CharacteristicProperties() & (GattCharacteristicProperties::Indicate | GattCharacteristicProperties::Notify)) != GattCharacteristicProperties::None) + { + OutputDebugString(L"[STBAPP] NotifyChar defined\n"); + NotifyCharacteristic = selectedCharacteristic; + } + if ((selectedCharacteristic.CharacteristicProperties() & (GattCharacteristicProperties::Write | GattCharacteristicProperties::WriteWithoutResponse)) != GattCharacteristicProperties::None) + { + OutputDebugString(L"[STBAPP] WriteChar defined\n"); + CusWriteCharacteristic = selectedCharacteristic; + } + + + + if (selectedCharacteristic == nullptr) + { + EnableCharacteristicPanels(GattCharacteristicProperties::None); + rootPage.NotifyUser(L"No characteristic selected", NotifyType::ErrorMessage); + co_return; + } + + // Get all the child descriptors of a characteristics. Use the cache mode to specify uncached descriptors only + // and the new Async functions to get the descriptors of unpaired devices as well. + GattDescriptorsResult result = co_await selectedCharacteristic.GetDescriptorsAsync(BluetoothCacheMode::Uncached); + if (result.Status() != GattCommunicationStatus::Success) + { + rootPage.NotifyUser(L"Descriptor read failure: " + to_hstring(result.Status()), NotifyType::ErrorMessage); + } + + // BT_Code: There's no need to access presentation format unless there's at least one. + presentationFormat = nullptr; + if (selectedCharacteristic.PresentationFormats().Size() > 0) + { + + if (selectedCharacteristic.PresentationFormats().Size() == 1) + { + // Get the presentation format since there's only one way of presenting it + presentationFormat = selectedCharacteristic.PresentationFormats().GetAt(0); + } + else + { + // It's difficult to figure out how to split up a characteristic and encode its different parts properly. + // In this case, we'll just encode the whole thing to a string to make it easy to print out. + } + } + + // Enable/disable operations based on the GattCharacteristicProperties. + EnableCharacteristicPanels(selectedCharacteristic.CharacteristicProperties()); + } + + void Scenario2_Client::EnableCharacteristicPanels(GattCharacteristicProperties properties) + { + // BT_Code: Hide the controls which do not apply to this characteristic. + SetVisibility(CharacteristicReadButton(), + (properties & GattCharacteristicProperties::Read) != GattCharacteristicProperties::None); + + SetVisibility(CharacteristicWritePanel(), + (properties & (GattCharacteristicProperties::Write | GattCharacteristicProperties::WriteWithoutResponse)) != GattCharacteristicProperties::None); + CharacteristicWriteValue().Text(L""); + + SetVisibility(ValueChangedSubscribeToggle(), + (properties & (GattCharacteristicProperties::Indicate | GattCharacteristicProperties::Notify)) != GattCharacteristicProperties::None); + } + + fire_and_forget Scenario2_Client::CharacteristicReadButton_Click() + { + auto lifetime = get_strong(); + + // BT_Code: Read the actual value from the device by using Uncached. + GattReadResult result = co_await selectedCharacteristic.ReadValueAsync(BluetoothCacheMode::Uncached); + if (result.Status() == GattCommunicationStatus::Success) + { + rootPage.NotifyUser(L"Read result: " + FormatValueByPresentation(result.Value(), presentationFormat), NotifyType::StatusMessage); + } + else + { + rootPage.NotifyUser(L"Read failed: Status = " + to_hstring(result.Status()), NotifyType::ErrorMessage); + } + } + + fire_and_forget Scenario2_Client::CharacteristicWriteButton_Click() + { +#if 1 + auto lifetime = get_strong(); + + hstring text = CharacteristicWriteValue().Text(); + if (!text.empty()) + { + std::vector byteStrings; + std::wstringstream wss(text.c_str()); + std::wstring byteStr; + while (wss >> byteStr) + { + byteStrings.push_back(byteStr); + } + + // 转换并格式化字节为十六进制字符串,添加 "0x" 前缀 + std::vector bytes; + std::wstringstream hexStream; + for (const auto& byteStr : byteStrings) + { + uint8_t byteValue = static_cast(std::stoi(byteStr, nullptr, 16)); + bytes.push_back(byteValue); + hexStream << L"0x" << std::hex << std::setw(2) << std::setfill(L'0') << static_cast(byteValue) << L", "; + } + std::wstring formattedHexStr = hexStream.str(); + // 去除末尾的逗号和空格 + if (!formattedHexStr.empty()) + { + formattedHexStr.pop_back(); + formattedHexStr.pop_back(); + } + + // 使用格式化后的十六进制数据 + IBuffer writeBuffer; + DataWriter writer; + for (const auto& byte : bytes) + { + writer.WriteByte(byte); + } + writeBuffer = writer.DetachBuffer(); + + co_await WriteBufferToSelectedCharacteristicAsync(writeBuffer); + } + else + { + rootPage.NotifyUser(L"No data to write to device", NotifyType::ErrorMessage); + } +#else + auto lifetime = get_strong(); + + hstring text = CharacteristicWriteValue().Text(); + if (!text.empty()) + { + IBuffer writeBuffer = CryptographicBuffer::ConvertStringToBinary(CharacteristicWriteValue().Text(), BinaryStringEncoding::Utf8); + + co_await WriteBufferToSelectedCharacteristicAsync(writeBuffer); + } + else + { + rootPage.NotifyUser(L"No data to write to device", NotifyType::ErrorMessage); + } +#endif + } + + fire_and_forget Scenario2_Client::CharacteristicWriteButtonInt_Click() + { + auto lifetime = get_strong(); + + int32_t readValue; + if (TryParseInt(CharacteristicWriteValue().Text().begin(), readValue)) + { + DataWriter writer; + writer.ByteOrder(ByteOrder::LittleEndian); + writer.WriteInt32(readValue); + + co_await WriteBufferToSelectedCharacteristicAsync(writer.DetachBuffer()); + } + else + { + rootPage.NotifyUser(L"Data to write has to be an int32", NotifyType::ErrorMessage); + } + } + + IAsyncOperation Scenario2_Client::WriteBufferToSelectedCharacteristicAsync(IBuffer buffer) + { + auto lifetime = get_strong(); + + try + { + // BT_Code: Writes the value from the buffer to the characteristic. + GattWriteResult result = co_await selectedCharacteristic.WriteValueWithResultAsync(buffer); + + if (result.Status() == GattCommunicationStatus::Success) + { + rootPage.NotifyUser(L"Successfully wrote value to device", NotifyType::StatusMessage); + co_return true; + } + else + { + rootPage.NotifyUser(L"Write failed: Status = " + to_hstring(result.Status()), NotifyType::ErrorMessage); + co_return false; + } + } + catch (hresult_error& ex) + { + if (ex.code() == E_BLUETOOTH_ATT_INVALID_PDU) + { + rootPage.NotifyUser(ex.message(), NotifyType::ErrorMessage); + co_return false; + } + if (ex.code() == E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED || ex.code() == E_ACCESSDENIED) + { + // This usually happens when a device reports that it support writing, but it actually doesn't. + rootPage.NotifyUser(ex.message(), NotifyType::ErrorMessage); + co_return false; + } + throw; + } + } + + fire_and_forget Scenario2_Client::ValueChangedSubscribeToggle_Click() + { + auto lifetime = get_strong(); + + if (!notificationsToken) + { + GattClientCharacteristicConfigurationDescriptorValue cccdValue = GattClientCharacteristicConfigurationDescriptorValue::None; + if ((selectedCharacteristic.CharacteristicProperties() & GattCharacteristicProperties::Indicate) != GattCharacteristicProperties::None) + { + cccdValue = GattClientCharacteristicConfigurationDescriptorValue::Indicate; + } + + else if ((selectedCharacteristic.CharacteristicProperties() & GattCharacteristicProperties::Notify) != GattCharacteristicProperties::None) + { + cccdValue = GattClientCharacteristicConfigurationDescriptorValue::Notify; + } + + try + { + // BT_Code: Must write the CCCD in order for server to send indications. + // We receive them in the ValueChanged event handler. + GattCommunicationStatus status = co_await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(cccdValue); + + if (status == GattCommunicationStatus::Success) + { + AddValueChangedHandler(); + rootPage.NotifyUser(L"Successfully subscribed for value changes", NotifyType::StatusMessage); + } + else + { + rootPage.NotifyUser(L"Error registering for value changes: Status = " + to_hstring(status), NotifyType::ErrorMessage); + } + } + catch (hresult_access_denied& ex) + { + // This usually happens when a device reports that it support indicate, but it actually doesn't. + rootPage.NotifyUser(ex.message(), NotifyType::ErrorMessage); + } + } + else + { + try + { + // BT_Code: Must write the CCCD in order for server to send notifications. + // We receive them in the ValueChanged event handler. + // Note that this sample configures either Indicate or Notify, but not both. + GattCommunicationStatus result = co_await + selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync( + GattClientCharacteristicConfigurationDescriptorValue::None); + if (result == GattCommunicationStatus::Success) + { + RemoveValueChangedHandler(); + rootPage.NotifyUser(L"Successfully un-registered for notifications", NotifyType::StatusMessage); + } + else + { + rootPage.NotifyUser(L"Error un-registering for notifications: Status = " + to_hstring(result), NotifyType::ErrorMessage); + } + } + catch (hresult_access_denied& ex) + { + // This usually happens when a device reports that it support notify, but it actually doesn't. + rootPage.NotifyUser(ex.message(), NotifyType::ErrorMessage); + } + } + } + + fire_and_forget Scenario2_Client::Characteristic_ValueChanged(GattCharacteristic const&, GattValueChangedEventArgs args) + { + auto lifetime = get_strong(); + + // BT_Code: An Indicate or Notify reported that the value has changed. + // Display the new value with a timestamp. + hstring newValue = FormatValueByPresentation(args.CharacteristicValue(), presentationFormat); + std::time_t now = clock::to_time_t(clock::now()); + char buffer[26]; + ctime_s(buffer, ARRAYSIZE(buffer), &now); + hstring message = L"Value at " + to_hstring(buffer) + L": " + newValue; + co_await resume_foreground(Dispatcher()); + CharacteristicLatestValue().Text(message); + } + + /// + /// Process the raw data received from the device into application usable data, + /// according the the Bluetooth Heart Rate Profile. + /// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml&u=org.bluetooth.characteristic.heart_rate_measurement.xml + /// This function throws an std::out_of_range if the data cannot be parsed. + /// + /// Raw data received from the heart rate monitor. + /// The heart rate measurement value. + int32_t ParseHeartRateValue(IBuffer const& buffer) + { + // Heart Rate profile defined flag values + const uint8_t heartRateValueFormat = 0x1; + + com_array bytes; + CryptographicBuffer::CopyToByteArray(buffer, bytes); + + if (bytes.at(0) & heartRateValueFormat) + { + return bytes.at(1) | (bytes.at(2) << 8); + } + return bytes.at(1); + } + + hstring Scenario2_Client::FormatValueByPresentation(IBuffer const& buffer, GenericAttributeProfile::GattPresentationFormat const& format) + { + // BT_Code: For the purpose of this sample, this function converts only UInt32 and + // UTF-8 buffers to readable text. It can be extended to support other formats if your app needs them. + if (format != nullptr) + { + if (format.FormatType() == GattPresentationFormatTypes::UInt32()) + { + uint32_t value; + if (TryExtract(buffer, value)) + { + return to_hstring(value); + } + return L"(error: Invalid UInt32)"; + + } + else if (format.FormatType() == GattPresentationFormatTypes::Utf8()) + { + try + { + return CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, buffer); + } + catch (hresult_invalid_argument&) + { + return L"(error: Invalid UTF-8 string)"; + } + } + else + { + // Add support for other format types as needed. + return L"Unsupported format: " + CryptographicBuffer::EncodeToHexString(buffer); + } + } + else if (buffer != nullptr) + { + // We don't know what format to use. Let's try some well-known profiles, or default back to UTF-8. + if (selectedCharacteristic.Uuid() == GattCharacteristicUuids::HeartRateMeasurement()) + { + try + { + return L"Heart Rate: " + to_hstring(ParseHeartRateValue(buffer)); + } + catch (std::out_of_range&) + { + return L"Heart Rate: (unable to parse)"; + } + } + else if (selectedCharacteristic.Uuid() == GattCharacteristicUuids::BatteryLevel()) + { + // battery level is encoded as a percentage value in the first byte according to + // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.battery_level.xml + uint8_t percent; + if (TryExtract(buffer, percent)) + { + return L"Battery Level: " + to_hstring(percent) + L"%"; + } + return L"Battery Level: (unable to parse)"; + } + // This is our custom calc service Result UUID. Format it like an Int + else if (selectedCharacteristic.Uuid() == Constants::ResultCharacteristicUuid) + { + int32_t value; + if (TryExtract(buffer, value)) + { + return to_hstring(value); + } + return L"Invalid response from calc server"; + } + else if (NotifyCharacteristic.Uuid() == Constants::MicCharacteristicUuid) + { + return L"Mic data: " + CryptographicBuffer::EncodeToHexString(buffer); + } + else if (NotifyCharacteristic.Uuid() == Constants::IdentifyCharacteristicUuid) + { + com_array bytes; + CryptographicBuffer::CopyToByteArray(buffer, bytes); + stb_app_recv_data_from_device(bytes.data(), static_cast(bytes.size())); + return L"Bizbus data: " + CryptographicBuffer::EncodeToHexString(buffer); + } + // No guarantees on if a characteristic is registered for notifications. + else if (registeredCharacteristic != nullptr) + { + // This is our custom calc service Result UUID. Format it like an Int + if (registeredCharacteristic.Uuid() == Constants::ResultCharacteristicUuid) + { + int32_t value; + if (TryExtract(buffer, value)) + { + return to_hstring(value); + } + return L"Invalid response from calc server"; + } + } + else + { + try + { + return L"Unknown format: " + CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, buffer); + + } + catch (hresult_invalid_argument&) + { + return L"Unknown format"; + } + } + } + else + { + return L"Empty data received"; + } + return L"Unknown format"; + } +} + + + diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj index 60fcca3..cf220de 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj +++ b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj @@ -415,7 +415,7 @@ 18E0C5922D0FF8E30093BA8F /* stb_identify.so in Frameworks */ = {isa = PBXBuildFile; fileRef = 18E0C58F2D0FF8E30093BA8F /* stb_identify.so */; }; 18E0C5932D0FF8E40093BA8F /* stb_app.h in Headers */ = {isa = PBXBuildFile; fileRef = 18E0C5902D0FF8E30093BA8F /* stb_app.h */; }; 18E0C5942D0FF8E40093BA8F /* stb_identify.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18E0C5912D0FF8E30093BA8F /* stb_identify.a */; }; - 18E0C5972D1000DF0093BA8F /* ByteDanceSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 18E0C5952D1000DF0093BA8F /* ByteDanceSdk.h */; }; + 18E0C5972D1000DF0093BA8F /* ByteDanceSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 18E0C5952D1000DF0093BA8F /* ByteDanceSdk.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18E0C5982D1000DF0093BA8F /* ByteDanceSdk.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E0C5962D1000DF0093BA8F /* ByteDanceSdk.m */; }; 18EF7AF92C7603E800AC5223 /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 18EF7AEA2C7603E800AC5223 /* adpcm.h */; }; 18EF7AFA2C7603E800AC5223 /* TlwMouseSdk.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EF7AEB2C7603E800AC5223 /* TlwMouseSdk.m */; }; @@ -429,6 +429,10 @@ 18EF7B052C7603E800AC5223 /* TlwConnectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18EF7AF62C7603E800AC5223 /* TlwConnectManager.h */; }; 18FCA3972C7F2AD100C44A37 /* AiMouseAuth.h in Headers */ = {isa = PBXBuildFile; fileRef = 18FCA3952C7F2AD100C44A37 /* AiMouseAuth.h */; }; 18FCA3982C7F2AD100C44A37 /* AiMouseAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FCA3962C7F2AD100C44A37 /* AiMouseAuth.m */; }; + 3FCF534F2D1A5C97007EC52F /* LogManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FCF534E2D1A5C97007EC52F /* LogManager.m */; }; + 3FCF53502D1A5C97007EC52F /* LogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FCF534D2D1A5C97007EC52F /* LogManager.h */; }; + 3FCF53512D1A5C97007EC52F /* LogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FCF534D2D1A5C97007EC52F /* LogManager.h */; }; + 3FCF53522D1A5C97007EC52F /* LogManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FCF534E2D1A5C97007EC52F /* LogManager.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -621,7 +625,6 @@ 188814BC2C85BB76009299A9 /* AiBkzhAuthManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiBkzhAuthManager.m; sourceTree = ""; }; 188814C02C85C2BA009299A9 /* AESCBCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESCBCHelper.h; sourceTree = ""; }; 188814C12C85C2BA009299A9 /* AESCBCHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AESCBCHelper.m; sourceTree = ""; }; - 189365512CEB0C3700023B62 /* libAiMouseSdk copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libAiMouseSdk copy.a"; path = "/Users/apple/Desktop/code/MouseSdk-MacOS/MouseSdk/AiMouseSdk/build/Debug/libAiMouseSdk copy.a"; sourceTree = ""; }; 189365522CEB115200023B62 /* KeyboardHidManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyboardHidManager.h; sourceTree = ""; }; 189365532CEB115200023B62 /* KeyboardHidManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeyboardHidManager.m; sourceTree = ""; }; 189365562CEB153000023B62 /* MSUtilis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSUtilis.h; sourceTree = ""; }; @@ -654,6 +657,9 @@ 18EF7AF62C7603E800AC5223 /* TlwConnectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TlwConnectManager.h; sourceTree = ""; }; 18FCA3952C7F2AD100C44A37 /* AiMouseAuth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiMouseAuth.h; sourceTree = ""; }; 18FCA3962C7F2AD100C44A37 /* AiMouseAuth.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiMouseAuth.m; sourceTree = ""; }; + 3FCF534C2D1A4E38007EC52F /* libAiMouseSdk copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libAiMouseSdk copy.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 3FCF534D2D1A5C97007EC52F /* LogManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogManager.h; sourceTree = ""; }; + 3FCF534E2D1A5C97007EC52F /* LogManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LogManager.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -715,6 +721,7 @@ 180E7AA82BD7BB12008558E8 /* AiMouseSdk */, 180E7AA72BD7BB12008558E8 /* Products */, 180E7D092BD8FEB2008558E8 /* Frameworks */, + 3FCF534C2D1A4E38007EC52F /* libAiMouseSdk copy.a */, ); sourceTree = ""; }; @@ -1027,6 +1034,8 @@ 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */, 189365562CEB153000023B62 /* MSUtilis.h */, 189365572CEB153000023B62 /* MSUtilis.m */, + 3FCF534D2D1A5C97007EC52F /* LogManager.h */, + 3FCF534E2D1A5C97007EC52F /* LogManager.m */, ); path = Manager; sourceTree = ""; @@ -1166,6 +1175,7 @@ 18EF7B052C7603E800AC5223 /* TlwConnectManager.h in Headers */, 180E7CF92BD8FC4F008558E8 /* dirac.h in Headers */, 18E0C5932D0FF8E40093BA8F /* stb_app.h in Headers */, + 3FCF53502D1A5C97007EC52F /* LogManager.h in Headers */, 184A71032BDA4C050025A332 /* AFNetworkReachabilityManager.h in Headers */, 184A71242BDE2DA60025A332 /* AiSecretModel.h in Headers */, 180E7CCF2BD8FC4E008558E8 /* video_enc_params.h in Headers */, @@ -1327,6 +1337,7 @@ 18862B282C806BD900D3564D /* hwcontext_mediacodec.h in Headers */, 18862B292C806BD900D3564D /* AiAudioDecoder.h in Headers */, 18862B2A2C806BD900D3564D /* encryption_info.h in Headers */, + 3FCF53512D1A5C97007EC52F /* LogManager.h in Headers */, 18862B2B2C806BD900D3564D /* blowfish.h in Headers */, 18862B2C2C806BD900D3564D /* AiAliAuthManager.h in Headers */, 18862B2D2C806BD900D3564D /* jni.h in Headers */, @@ -1490,7 +1501,7 @@ ); name = "AiMouseSdk copy"; productName = AiMouseSdk; - productReference = 189365512CEB0C3700023B62 /* libAiMouseSdk copy.a */; + productReference = 3FCF534C2D1A4E38007EC52F /* libAiMouseSdk copy.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -1551,6 +1562,7 @@ 18EF7B042C7603E800AC5223 /* TlwAudioManager.m in Sources */, 18E0C5982D1000DF0093BA8F /* ByteDanceSdk.m in Sources */, 189960112CEAD7B50042505F /* KeyboardSdk.m in Sources */, + 3FCF534F2D1A5C97007EC52F /* LogManager.m in Sources */, 180E7BE72BD7BD84008558E8 /* AiAudioManager.m in Sources */, 18EF7AFB2C7603E800AC5223 /* TlwTools.m in Sources */, 18EF7AFA2C7603E800AC5223 /* TlwMouseSdk.m in Sources */, @@ -1579,6 +1591,7 @@ 18862BAF2C806BD900D3564D /* TimerManager.m in Sources */, 18862BB02C806BD900D3564D /* HidManager.m in Sources */, 18862BB22C806BD900D3564D /* AiMouseTools2.m in Sources */, + 3FCF53522D1A5C97007EC52F /* LogManager.m in Sources */, 18862BB32C806BD900D3564D /* AiSecretModel.m in Sources */, 18862BB42C806BD900D3564D /* AiSender.m in Sources */, 18862BB52C806BD900D3564D /* AiTrippleModel.m in Sources */, diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6349347 --- /dev/null +++ b/MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + AiMouseSdk copy.xcscheme_^#shared#^_ + + orderHint + 3 + + AiMouseSdk.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.h b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.h index e0ff37e..fad4a25 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.h +++ b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.h @@ -19,25 +19,12 @@ @property (nonatomic, strong) NSString *mac;///设备MAC地址 @end -typedef NS_ENUM(NSInteger,AiMouseAuthType) { - AiMouseAuthType_none = 0,///不鉴权 - AiMouseAuthType_BeiKeZhiHui = 1,/// 北科智慧 - AiMouseAuthType_Ali = 2,/// 阿里 -}; - typedef NS_ENUM(NSInteger,AiMouseErrorCode) { AiMouseErrorCode_timeOut = 1001,///请求超时 AiMouseErrorCode_busy = 1002,/// 繁忙,有命令未执行完 AiMouseErrorCode_unknown = 1003,/// 未知错误 }; -/// 日志等级 -typedef NS_ENUM(NSInteger,AiMouseLogLevel) { - AiMouseLogLevel_none = 0, - AiMouseLogLevel_error, - AiMouseLogLevel_info, -}; - typedef NS_ENUM(NSInteger,AiMouseConnectType) { AiMouseConnectType_bluetooth = 0,///蓝牙 AiMouseConnectType_hid = 1,///hid @@ -85,7 +72,6 @@ typedef NS_ENUM(NSInteger,AiMouseAuthState) { @end @interface AiMouse : NSObject -@property (nonatomic, readonly) NSString *version;/// 版本号 @property (nonatomic, weak) id delegate;/// 代理 @property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型 @property (nonatomic, assign) BOOL connected;//是否已连接 @@ -93,10 +79,6 @@ typedef NS_ENUM(NSInteger,AiMouseAuthState) { /// 单利 +(AiMouse *)shared; -/// 设置日志等级 -/// - Parameter level: 等级 -- (void)setLogLevel:(AiMouseLogLevel)level; - /// 断开连接 - (void)didDisconnect; @@ -105,10 +87,6 @@ typedef NS_ENUM(NSInteger,AiMouseAuthState) { /// - Parameter type: 连接类型 - (void)switchConnect:(AiMouseConnectType)type isConnected:(BOOL)isConneted; -///// 开始鉴权 -///// - Parameter finished: 鉴权结果回调 -//- (void)startAuthentication:(void (^)(AiMouseAuthState state))complete; - /// 传输业务数据给sdk /// - Parameter data:ai特征传过来的数据 - (void)sendAiDataToSdk:(NSData *)data; diff --git a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m index b95a2e4..e3c303e 100644 --- a/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m +++ b/MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseSdk.m @@ -26,19 +26,12 @@ @end @implementation AiMouseDeviceInfo -(NSString *)description{ -// NSString *info = [NSString stringWithFormat:@"\n battery_power = %@\n CPI = %@\n CPI_list = %@\n version = %@\n brand = %@\n sn = %@\n mac = %@\n productKey = %@\n secretKey = %@\n deviceSecret = %@ \n record_mode = %@ \n mouse_mode = %@ \n url = %@ \n urlActive = %@ ",self.battery_power,self.CPI,self.CPI_list,self.version,self.brand,self.sn,self.mac,self.productKey,self.secretKey,self.deviceSecret,self.record_mode,self.mouse_mode,self.url,self.urlActive]; - NSString *info = [NSString stringWithFormat:@"\n type = %d \n battery_power = %@\n CPI = %@\n CPI_list = %@\n version = %@\n brand = %@\n sn = %@\n mac = %@\n productKey = %@\n secretKey = %@\n deviceSecret = %@ ",self.type,self.battery_power,self.CPI,self.CPI_list,self.version,self.brand,self.sn,self.mac,self.productKey,self.secretKey,self.deviceSecret]; return info; } @end @interface AiMouse() -@property (nonatomic, assign) AiMouseLogLevel logLevel; - -@property (nonatomic, strong) AiAuthManager *authManager; -@property (nonatomic, strong) AiAliAuthManager *aliAuthManager; -@property (nonatomic, strong) AiBkzhAuthManager *bkAuthManager; @property (nonatomic, strong) AiAudioManager *audioManager; @property (nonatomic, strong) AiRecordManager *recordManager; @@ -46,7 +39,6 @@ @property (nonatomic, strong) AiDeviceInfoManager *deviceInfoManager; @property (nonatomic, strong) NSString *updateDeviceSecret;//更新的deviceSecret -@property (nonatomic, assign) BOOL isAuthing; @end @implementation AiMouse @@ -61,17 +53,12 @@ -(instancetype)init{ if (self = [super init]) { - _logLevel = AiMouseLogLevel_none; _connectType = AiMouseConnectType_bluetooth; -// NSLog(@"[AiMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]); [self.recordManager checkPermissions]; } return self; } --(NSString *)version{ - return @"1.0.33"; -} -(AiDeviceInfoManager *)deviceInfoManager{ if (!_deviceInfoManager) { @@ -94,58 +81,6 @@ return _deviceInfoManager;; } --(AiAuthManager *)authManager{ - if (!_authManager) { - _authManager = [[AiAuthManager alloc] init]; - __weak typeof(self) ws = self; - _authManager.outputLog = ^(NSString * _Nonnull log) { - [ws showLog:log]; - }; - _authManager.setDeviceSecret = ^(NSString * _Nonnull value, AiCmdFinishBlock _Nonnull finished) { - [ws setDeviceSecret:value completation:finished]; - }; - _authManager.authCallBack = ^(BOOL isSuccess) { - [ws authResult:isSuccess]; -// [ws setDeviceSecret:@"" completation:nil]; - }; - } - return _authManager; -} - --(AiAliAuthManager *)aliAuthManager{ - if (!_aliAuthManager) { - _aliAuthManager = [[AiAliAuthManager alloc] init]; - __weak typeof(self) ws = self; - _aliAuthManager.outputLog = ^(NSString * _Nonnull log) { - [ws showLog:log]; - }; - _aliAuthManager.setDeviceSecret = ^(NSString * _Nonnull value, AiAliCmdFinishBlock _Nonnull finished) { - [ws setDeviceSecret:value completation:finished]; - }; - _aliAuthManager.authCallBack = ^(BOOL isSuccess) { - [ws authResult:isSuccess]; -// [ws setDeviceSecret:@"" completation:nil]; - }; - } - return _aliAuthManager; -} --(AiBkzhAuthManager *)bkAuthManager{ - if (!_bkAuthManager) { - _bkAuthManager = [[AiBkzhAuthManager alloc] init]; - __weak typeof(self) ws = self; - _bkAuthManager.outputLog = ^(NSString * _Nonnull log) { - [ws showLog:log]; - }; - _bkAuthManager.setDeviceSecret = ^(NSString * _Nonnull value, AiBkzhCmdFinishBlock _Nonnull finished) { - [ws setDeviceSecret:value completation:finished]; - }; - _bkAuthManager.authCallBack = ^(BOOL isSuccess) { - [ws authResult:isSuccess]; - }; - } - return _bkAuthManager; -} - -(AiAudioManager *)audioManager{ if (!_audioManager) { _audioManager = [[AiAudioManager alloc] init]; @@ -172,9 +107,6 @@ } #pragma mark - pub Api -- (void)setLogLevel:(AiMouseLogLevel)level{ - _logLevel = level; -} - (void)didDisconnect{ [self stopRecord:true]; // [self.connectManager disConnected]; @@ -200,32 +132,6 @@ } } } -//开始鉴权 -- (void)startAuthentication:(AiMouseAuthType)type finished:(void (^)(AiMouseAuthState))complete{ - if (type == AiMouseAuthType_none){ - complete(AiMouseAuthState_Success); - return; - } - [self showLog:@"开始鉴权"]; - self.authBlock = complete; - __block typeof(self) ws = self; - [self getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) { - if (error ) { - ws.authBlock(AiMouseAuthState_Failure); - } - else{ - if(type == AiMouseAuthType_Ali){ - [ws.aliAuthManager loginWith:deviceInfo]; - } - else if(type == AiMouseAuthType_BeiKeZhiHui){ - [ws.bkAuthManager loginWith:deviceInfo]; - } - else{ - [ws.authManager loginWith:deviceInfo]; - } - } - }]; -} - (void)sendAiDataToSdk:(NSData *)data{ // [self showLog:[NSString stringWithFormat:@"[receive][Voice] %@",data]]; @@ -288,31 +194,7 @@ [self.deviceInfoManager receiveData:data]; } -- (void)setDeviceSecret:(NSString *)value completation:(AiCmdFinishBlock)complete{ - self.updateDeviceSecret = value; - __weak typeof(self) ws = self; - [self.deviceInfoManager setDeviceSecret:value completation:^(BOOL isSuccess) { - if (isSuccess) { - [ws showLog:@"写入deviceSecret成功,查询是否获读取成功..."]; - //更新成功,检查是否读取到 - [ws.deviceInfoManager getDeviceInfo:^(AiMouseDeviceInfo * _Nonnull deviceInfo, NSError * _Nonnull error) { - if ([deviceInfo.deviceSecret isEqualToString:value]) { - [ws showLog:@"写入deviceSecret成功,读取成功!"]; - complete(true); - } - else{ - //查不到,继续写入 - [ws showLog:@"查询不到deviceSecret,继续写入!!!"]; - [ws setDeviceSecret:ws.updateDeviceSecret completation:complete]; - } - }]; - } - else{ - [ws showLog:@"写入deviceSecret失败!"]; - [ws setDeviceSecret:ws.updateDeviceSecret completation:complete]; - } - }]; -} + - (void)getDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))complete{ __weak typeof(self) ws = self; @@ -400,18 +282,10 @@ } #pragma mark - other - (void)sendRecordData:(NSData *)data{ -// if (self.authState != AiMouseAuthState_Success){ -// [self showLog:@"设备还未鉴权!!!"]; -// return; -// }; // [self showLog:[NSString stringWithFormat:@"[audio] %@",data]]; if (self.delegate) [self.delegate aiMouseSendRecordData:data]; } - (void)sendCmdData:(NSData *)data{ -// if (self.authState != AiMouseAuthState_Success){ -// [self showLog:@"设备还未鉴权!!!"]; -// return; -// } [self showLog:[NSString stringWithFormat:@"[send] %@",data]]; if (self.delegate) [self.delegate aiMouseSendCmdData:data]; } @@ -427,22 +301,10 @@ if (self.delegate && [self.delegate respondsToSelector:@selector(aiMouseAddLog:)]) { [self.delegate aiMouseAddLog:[NSString stringWithFormat:@"[frk]%@",log]]; } -// if(self.logLevel == AiMouseLogLevel_info){ -// NSLog(@"[frk]%@",log); -// } } - (void)checkAuthState{ - if (self.isAuthing) { - return; - } - self.isAuthing = true; - __weak typeof(self) ws = self; - [self startAuthentication:AiMouseAuthType_none finished:^(AiMouseAuthState state) { - ws.isAuthing = false; - [ws showLog:state == AiMouseAuthState_Success? @"鉴权成功":@"鉴权失败"]; - if(ws.delegate) [ws.delegate aiMouseAuthenticationResult:state]; - }]; + if(self.delegate) [self.delegate aiMouseAuthenticationResult:AiMouseAuthState_Success]; } #pragma mark - deviceInfo - (void)startRecord{ diff --git a/MouseSdk/AiMouseSdk/ByteDance/ByteDanceSdk.m b/MouseSdk/AiMouseSdk/ByteDance/ByteDanceSdk.m index 510a131..059156d 100644 --- a/MouseSdk/AiMouseSdk/ByteDance/ByteDanceSdk.m +++ b/MouseSdk/AiMouseSdk/ByteDance/ByteDanceSdk.m @@ -7,28 +7,87 @@ #import "ByteDanceSdk.h" #import "stb_app.h" +#import "AiMouseTools.h" +#import "LogManager.h" +//appID:tis_test +// +//token:x3hWlrnUZXG2mlIlmvQ35gUUSTkmOa0m +// +//expireTime:1734588385677 +// +//host:ainf.tis.cn-beijing.volces.com +// +//urlParam:productKey=k1r8dWlSOjM&deviceName=1A2B3C4D5E6F&iotInstanceId=iot-060aenzm×tamp=1734501985677&sign=f140c796052fbd3a66cad9814e19d6f9ac571fcf3595c1116e1be39225295033 @implementation ByteDanceSdk -+(ByteDanceSdk *)shared{ - static ByteDanceSdk *manager = nil; - static dispatch_once_t oncePredicate; - dispatch_once(&oncePredicate, ^{ - manager = [[ByteDanceSdk alloc]init]; - [manager initSdk]; - }); - return manager; +//+(ByteDanceSdk *)shared{ +// static ByteDanceSdk *manager = nil; +// static dispatch_once_t oncePredicate; +// dispatch_once(&oncePredicate, ^{ +// manager = [[ByteDanceSdk alloc]init]; +// [manager initSdk]; +// }); +// return manager; +//} + +-(instancetype)init{ + if (self = [super init]) { + [self initSdk]; + } + return self; } - (void)initSdk{ - NSString *appId = @""; + [[LogManager shared] addLog:@"开始初始化"]; + stb_app_printf_str_register(cus_printf_str); + NSString *appId = @"tis_test"; int code = stb_app_init([appId UTF8String]); - stb_app_event_callback_register(eventCallBack); + stb_app_event_callback_register(cust_event_callback_func); + stb_app_send_data_to_device_register(cus_hal_send_data2device); } -static void eventCallBack(uint32_t type,uint8_t *report, uint32_t data_len){ +- (void)startAuth{ + stb_app_start_identify(); +} + +#pragma mark - ByteDance +void STB_STDCALL cus_printf_str(char* str) +{ + NSString *logStr = [NSString stringWithFormat:@"%s", str]; + [[LogManager shared] addLog:logStr]; + return; +} +static void cust_event_callback_func(uint32_t type,uint8_t *report, uint32_t data_len){ NSData *data = [[NSData alloc] initWithBytes:report length:data_len]; - NSLog(@"type = ,data = %@,data_len = %d",type,data,data_len); + [[LogManager shared] addLog:[NSString stringWithFormat:@"type = ,data = %@,data_len = %d",type,data,data_len]]; } + +int32_t STB_STDCALL cus_hal_send_data2device(uint8_t* data, uint32_t len) +{ + NSData *sendData = [[NSData alloc] initWithBytes:data length:len]; + [[LogManager shared] addLog:[NSString stringWithFormat:@"sendData = %@",[AiMouseTools dataToHexString_placeholder:sendData]]]; +// std::ostringstream oss; +// // 把数据转换成十六进制字符串 +// IBuffer buffer; +// for (uint32_t i = 0; i < len; ++i) +// { +// oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(data[i]) << " "; +// } +// // 转换为字符串并使用 OutputDebugString 输出 +// std::string hexData = oss.str(); +// OutputDebugString(L"[STBAPP] send data 2 device:\n"); +// OutputDebugStringA(hexData.c_str()); +// DataWriter writer; +// for (uint32_t i = 0; i < len; ++i) +// { +// writer.WriteByte(data[i]); +// } +// writer.WriteByte('\n'); +// buffer = writer.DetachBuffer(); +// CusWriteCharacteristic.WriteValueAsync(buffer); + return 0; +} + @end diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h index 215acec..ea26770 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.h +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.h @@ -110,6 +110,7 @@ NS_ASSUME_NONNULL_BEGIN /// - finished: 执行结果回调 - (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished; + @end NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m index 433ba2d..c570ca9 100644 --- a/MouseSdk/AiMouseSdk/Manager/DeviceManger.m +++ b/MouseSdk/AiMouseSdk/Manager/DeviceManger.m @@ -53,8 +53,6 @@ [self setupBle]; [self setupHid]; [self setupTimer]; -// [self setupKeyboard]; - [[ByteDanceSdk shared] init]; } return self; } @@ -68,25 +66,11 @@ self.tlwSdk = [[TlwMouse alloc] init]; [self.tlwSdk setDelegate:self]; - [self.tlwSdk setLogLevel:(TlwMouseLogLevel_none)]; self.frkSdk = [AiMouse shared]; [self.frkSdk setDelegate:self]; - [self.frkSdk setLogLevel:AiMouseLogLevel_none]; } -- (void)setupKeyboard{ - [KeyboardHidManager shared].receiveInfoDataCallBack = ^(NSData * _Nonnull data) { - - }; - [KeyboardHidManager shared].connectStateCallBack = ^(BOOL connected) { - [self.kbSdk switchConnect:AiMouseConnectType_hid isConnected:true]; - }; - [KeyboardHidManager shared].logCallBack = ^(NSString * _Nonnull log) { - [self showLog:log]; - }; - [[KeyboardHidManager shared] open]; -} - (void)setupTimer{ [TimerManager shared].timerCallBack = ^{ // [self showLog:@"timer action。。。"]; diff --git a/MouseSdk/AiMouseSdk/Manager/LogManager.h b/MouseSdk/AiMouseSdk/Manager/LogManager.h new file mode 100644 index 0000000..afbdf05 --- /dev/null +++ b/MouseSdk/AiMouseSdk/Manager/LogManager.h @@ -0,0 +1,20 @@ +// +// LogManager.h +// AiMouseManager +// +// Created by liangshi on 2024/12/24. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface LogManager : NSObject ++(LogManager *)shared; + +- (void)addLog:(NSString *)log type:(NSString *)type; + +- (void)addLog:(NSString *)log; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/Manager/LogManager.m b/MouseSdk/AiMouseSdk/Manager/LogManager.m new file mode 100644 index 0000000..dab9a3a --- /dev/null +++ b/MouseSdk/AiMouseSdk/Manager/LogManager.m @@ -0,0 +1,26 @@ +// +// LogManager.m +// AiMouseManager +// +// Created by liangshi on 2024/12/24. +// + +#import "LogManager.h" + +@implementation LogManager + ++(LogManager *)shared{ + static LogManager *manager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + manager = [[LogManager alloc]init]; +// [manager initSdk]; + }); + return manager; +} + +- (void)addLog:(NSString *)log{ + NSString *str = [NSString stringWithFormat:@"%@",log]; + NSLog(str); +} +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h index 4888b3a..dd6cc23 100644 --- a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h @@ -68,9 +68,6 @@ typedef NS_ENUM(NSInteger,TlwMouseLogLevel) { @property (nonatomic, readonly) AiMouseConnectType connectType;//连接类型 @property (nonatomic, readonly) BOOL connected;//是否已连接 -/// 设置日志等级 -/// - Parameter level: 等级 -- (void)setLogLevel:(TlwMouseLogLevel)level; /// 断开连接 - (void)didDisconnect; diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m index ba115f3..a3b98f2 100644 --- a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m @@ -25,7 +25,6 @@ @interface TlwMouse() -@property (nonatomic, assign) TlwMouseLogLevel logLevel; @property (nonatomic, strong) TlwAudioManager *audioManager; @property (nonatomic, strong) AiRecordManager *recordManager; @@ -51,7 +50,6 @@ -(instancetype)init{ if (self = [super init]) { - _logLevel = TlwMouseLogLevel_none; _connectType = AiMouseConnectType_bluetooth; // NSLog(@"[TlwMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]); [self.recordManager checkPermissions]; @@ -101,9 +99,6 @@ } #pragma mark - pub Api -- (void)setLogLevel:(TlwMouseLogLevel)level{ - _logLevel = level; -} - (void)didDisconnect{ _connected = false; [self stopRecord]; @@ -764,9 +759,6 @@ if (self.delegate && [self.delegate respondsToSelector:@selector(tlwMouseAddLog:)]) { [self.delegate tlwMouseAddLog:[NSString stringWithFormat:@"[tlw]%@",log]]; } - // if(self.logLevel == TlwMouseLogLevel_info){ - // NSLog(@"[tlw]%@",log); - // } } diff --git a/MouseSdk/MouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist b/MouseSdk/MouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..4333a46 --- /dev/null +++ b/MouseSdk/MouseSdk.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MouseSdk.xcscheme_^#shared#^_ + + orderHint + 1 + + + + diff --git a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..4b64755 Binary files /dev/null and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/yaozuopan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MouseSdk/MouseSdk/ViewController.m b/MouseSdk/MouseSdk/ViewController.m index 85ecaf6..5c68a7b 100644 --- a/MouseSdk/MouseSdk/ViewController.m +++ b/MouseSdk/MouseSdk/ViewController.m @@ -88,6 +88,16 @@ self.deviceInfoLabel = label; [self.view addSubview:label]; } + + { + NSButton *btn = [[NSButton alloc]initWithFrame:NSMakeRect(50, self.view.bounds.size.height - 300, 100, 45)]; + btn.bordered = true; + btn.title = @"字节"; + [btn setTarget:self]; + [btn setAction:@selector(byteDanceAction:)]; + btn.state = 1; + [self.view addSubview:btn]; + } } #pragma mark - action @@ -199,4 +209,31 @@ } }]; } + +#pragma mark - byteDance +- (void)byteDanceAction:(NSButton *)sender { + NSMenu *popupMenu = [[NSMenu alloc] initWithTitle:@"Popup Menu"]; + NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"鉴权" action:@selector(startAuth:) keyEquivalent:@"1"]; +// NSMenuItem *item2 = [[NSMenuItem alloc] initWithTitle:@"语音停止" action:@selector(voiceStop:) keyEquivalent:@"2"]; +// NSMenuItem *item3 = [[NSMenuItem alloc] initWithTitle:@"设置DPI" action:@selector(setDPI:) keyEquivalent:@"3"]; +// NSMenuItem *item4 = [[NSMenuItem alloc] initWithTitle:@"鼠标状态查询" action:@selector(searchState:) keyEquivalent:@"4"]; +// NSMenuItem *item5 = [[NSMenuItem alloc] initWithTitle:@"设置滚轮开关" action:@selector(setUrlState:) keyEquivalent:@"5"]; +// NSMenuItem *item6 = [[NSMenuItem alloc] initWithTitle:@"获取滚轮开关" action:@selector(getUrlState:) keyEquivalent:@"6"]; + + [popupMenu addItem:item1]; +// [popupMenu addItem:item2]; +// [popupMenu addItem:item3]; +// [popupMenu addItem:item4]; +// [popupMenu addItem:item5]; +// [popupMenu addItem:item6]; + + NSPoint buttonLocation = [sender convertPoint:NSZeroPoint toView:self.view]; + [popupMenu popUpMenuPositioningItem:nil atLocation:buttonLocation inView:self.view]; +} + +- (void)startAuth:(NSMenuItem*)sender { +// [[DeviceManger shared] startByteDanceAuth]; +} + + @end diff --git a/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist b/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..d2ea65a --- /dev/null +++ b/MouseSdk/Pods/Pods.xcodeproj/xcuserdata/yaozuopan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + Masonry.xcscheme_^#shared#^_ + + orderHint + 4 + + Pods-MouseSdk.xcscheme_^#shared#^_ + + orderHint + 2 + + + +