From: Sudha Bheemanna Date: Tue, 20 Dec 2016 07:25:05 +0000 (+0530) Subject: [C# Bluetooth] Adding C# Bluetooth code. X-Git-Tag: submit/trunk/20170823.075128~118^2~31 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8d61d8c368bbc1e4ba17d960eac289dfaa701f41;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [C# Bluetooth] Adding C# Bluetooth code. Added inital files for the C# bluetooth code. This branch to be used as base for futher development and issue fixing. Change-Id: If5a8dc4f2253f1afa4b551ac434839259209d1fa Signed-off-by: Sudha Bheemanna --- diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Tizen.Bluetooth/Interop/Interop.Bluetooth.cs b/Tizen.Bluetooth/Interop/Interop.Bluetooth.cs new file mode 100644 index 0000000..81aaf74 --- /dev/null +++ b/Tizen.Bluetooth/Interop/Interop.Bluetooth.cs @@ -0,0 +1,597 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using Tizen.Network.Bluetooth; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Bluetooth + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void StateChangedCallback(int result, int state, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void NameChangedCallback(string deviceName, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void VisibilityModeChangedCallback(int result, int visibility, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void VisibilityDurationChangedCallback(int duration, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DiscoveryStateChangedCallback(int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool BondedDeviceCallback([MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceStruct device, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BondCreatedCallback(int result, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceStruct device, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void BondDestroyedCallback(int result, string deviceAddress, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AuthorizationChangedCallback(int authorization, string deviceAddress, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ServiceSearchedCallback(int result, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceSdpStruct sdp, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DeviceConnectionStateChangedCallback(bool connected, [MarshalAs(UnmanagedType.Struct)]ref BluetoothDeviceConnectionStruct device, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool ConnectedProfileCallback(int profile, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void DataReceivedCallback([MarshalAs(UnmanagedType.Struct)]ref SocketDataStruct socketData, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SocketConnectionStateChangedCallback(int result, BluetoothSocketState connectionState, [MarshalAs(UnmanagedType.Struct)]ref SocketConnectionStruct socketConnection, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AudioConnectionStateChangedCallback(int result, bool connected, string deviceAddress, int profileType, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void HidConnectionStateChangedCallback(int result, bool connected, string deviceAddress, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void TargetConnectionStateChangedCallback(bool connected, string deviceAddress, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void EqualizerStateChangedCallback(int equalizer, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void RepeatModeChangedCallback(int repeat, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ShuffleModeChangedCallback(int shuffle, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ScanModeChangedCallback(int scan, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ConnectionChangedCallback(int result, bool connected, string deviceAddress, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ClientCharacteristicValueChangedCallback(IntPtr characteristicHandle, string value, int len, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void GattClientRequestedCallback(int result, IntPtr handle, IntPtr userData); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool GattForEachCallback(int total, int index, IntPtr handle, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_initialize")] + internal static extern int Initialize(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_deinitialize")] + internal static extern int Deinitialize(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_name")] + internal static extern int GetName(out string name); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name")] + internal static extern int SetName(string name); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_state")] + internal static extern int GetState(out BluetoothState isActivated); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_address")] + internal static extern int GetAddress(out string address); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_visibility")] + internal static extern int GetVisibility(out int visibility, out int duration); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_discovering")] + internal static extern int IsDiscovering(out bool isDiscovering); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_start_device_discovery")] + internal static extern int StartDiscovery(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_stop_device_discovery")] + internal static extern int StopDiscovery(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_foreach_bonded_device")] + internal static extern int GetBondedDevices(BondedDeviceCallback bondedDeviceCb, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_bonded_device_info")] + internal static extern int GetBondedDeviceByAddress(string deviceAddress, out IntPtr deviceInfo); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_free_device_info")] + internal static extern int FreeDeviceInfo(BluetoothDeviceStruct deviceInfo); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_is_service_used")] + internal static extern int IsServiceUsed(string serviceUuid, out bool used); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_get_local_oob_data")] + internal static extern int GetOobData(out IntPtr hash, out IntPtr randomizer, out int hashLen, out int randomizerLen); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_remote_oob_data")] + internal static extern int SetOobData(string deviceAddress, IntPtr hash, IntPtr randomizer, int hashLen, int randomizerLen); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_remove_remote_oob_data")] + internal static extern int RemoveOobData(string deviceAddress); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_state_changed_cb")] + internal static extern int SetStateChangedCallback(StateChangedCallback stateChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_state_changed_cb")] + internal static extern int UnsetStateChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_name_changed_cb")] + internal static extern int SetNameChangedCallback(NameChangedCallback nameChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_name_changed_cb")] + internal static extern int UnsetNameChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_mode_changed_cb")] + internal static extern int SetVisibilityModeChangedCallback(VisibilityModeChangedCallback visibilityChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_mode_changed_cb")] + internal static extern int UnsetVisibilityModeChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_visibility_duration_changed_cb")] + internal static extern int SetVisibilityDurationChangedCallback(VisibilityDurationChangedCallback durationChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_visibility_duration_changed_cb")] + internal static extern int UnsetVisibilityDurationChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_set_device_discovery_state_changed_cb")] + internal static extern int SetDiscoveryStateChangedCallback(DiscoveryStateChangedCallback discoveryChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_unset_device_discovery_state_changed_cb")] + internal static extern int UnsetDiscoveryStateChangedCallback(); + + //Bluetooth Device + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_create_bond")] + internal static extern int CreateBond(string deviceAddress); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_destroy_bond")] + internal static extern int DestroyBond(string deviceAddress); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_cancel_bonding")] + internal static extern int CancelBonding(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_alias")] + internal static extern int SetAlias(string deviceAddress, string alias); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_authorization")] + internal static extern int SetAuthorization(string deviceAddress, int state); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_get_service_mask_from_uuid_list")] + internal static extern int GetMaskFromUuid([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)] string[] uuids, int count, out BluetoothServiceClassType serviceMask); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_start_service_search")] + internal static extern int StartServiceSearch(string deviceAddress); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_foreach_connected_profiles")] + internal static extern int GetConnectedProfiles(string deviceAddress, ConnectedProfileCallback connectedProfileCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_is_profile_connected")] + internal static extern int IsProfileConnected(string deviceAddress, int profile, out bool connectionStatus); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_bond_created_cb")] + internal static extern int SetBondCreatedCallback(BondCreatedCallback bondCreatedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_bond_created_cb")] + internal static extern int UnsetBondCreatedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_bond_destroyed_cb")] + internal static extern int SetBondDestroyedCallback(BondDestroyedCallback bondDestroyedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_bond_destroyed_cb")] + internal static extern int UnsetBondDestroyedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_authorization_changed_cb")] + internal static extern int SetAuthorizationChangedCallback(AuthorizationChangedCallback authorizationChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_authorization_changed_cb")] + internal static extern int UnsetAuthorizationChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_service_searched_cb")] + internal static extern int SetServiceSearchedCallback(ServiceSearchedCallback serviceSearchedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_service_searched_cb")] + internal static extern int UnsetServiceSearchedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_set_connection_state_changed_cb")] + internal static extern int SetConnectionStateChangedCallback(DeviceConnectionStateChangedCallback connectionChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_device_unset_connection_state_changed_cb")] + internal static extern int UnsetConnectionStateChangedCallback(); + + // Bluetooth LE Adapter + + //Callback for event + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void AdapterLeScanResultChangedCallBack(int result, + [MarshalAs(UnmanagedType.Struct)]ref BluetoothLeScanDataStruct scanData, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void AdvertisingStateChangedCallBack(int result, IntPtr advertiserHandle, + BluetoothLeAdvertisingState advertisingState, IntPtr userData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void GattConnectionStateChangedCallBack(int result, bool connected, + string remoteAddress, IntPtr userData); + + //Bluetooth Le Adapter Apis + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_start_scan")] + public static extern int StartScan(AdapterLeScanResultChangedCallBack callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_stop_scan")] + public static extern int StopScan(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_uuids")] + public static extern int GetScanResultServiceUuid(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, ref IntPtr uuids, ref int count); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_device_name")] + public static extern int GetLeScanResultDeviceName(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, out string deviceName); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_tx_power_level")] + public static extern int GetScanResultTxPowerLevel(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, out int txPowerLevel); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_solicitation_uuids")] + public static extern int GetScaResultSvcSolicitationUuids(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, out IntPtr uuids, out int count); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_service_data_list")] + public static extern int GetScanResultServiceDataList(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType PacketType, out IntPtr serviceDataArray, out int count); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_free_service_data_list")] + public static extern int FreeServiceDataList(IntPtr serviceData, int count); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_appearance")] + public static extern int GetScanResultAppearance(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, out int appearance); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_get_scan_result_manufacturer_data")] + public static extern int GetScanResultManufacturerData(ref BluetoothLeScanDataStruct scanData, + BluetoothLePacketType packetType, out int manufId, out IntPtr manufData, + out int manufDataLength); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_connect")] + internal static extern int GattConnect(string deviceAddress, bool autoConnect); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_disconnect")] + internal static extern int GattDisconnect(string deviceAddress); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_connection_state_changed_cb")] + internal static extern int SetGattConnectionStateChangedCallback( + GattConnectionStateChangedCallBack gattConnectionChangedCb, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_unset_connection_state_changed_cb")] + internal static extern int UnsetGattConnectionStateChangedCallback(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_create_advertiser")] + public static extern int CreateAdvertiser(out IntPtr advertiserHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_destroy_advertiser")] + public static extern int DestroyAdvertiser(IntPtr advertiserHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_uuid")] + public static extern int AddAdvertisingServiceUuid(IntPtr advertiserHandle, + BluetoothLePacketType PacketType, string uuid); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_solicitation_uuid")] + public static extern int AddAdvertisingServiceSolicitationUuid(IntPtr advertiserHandle, + BluetoothLePacketType PacketType, string uuid); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_service_data")] + public static extern int AddAdvertisingServiceData(IntPtr advertiserHandle, + BluetoothLePacketType PacketType, string uuid, IntPtr serviceData, int serviceDatalength); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_appearance")] + public static extern int SetAdvertisingAppearance(IntPtr advertiserHandle, + BluetoothLePacketType packetType, int appearance); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_add_advertising_manufacturer_data")] + public static extern int AddAdvertisingManufData(IntPtr advertiserHandle, BluetoothLePacketType packetType, + int manufId, IntPtr manufData, int manufacturerDataLength); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_device_name")] + public static extern int SetAdvertisingDeviceName(IntPtr advertiserHandle, BluetoothLePacketType packetType, + bool includeName); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_tx_power_level")] + public static extern int SetAdvertisingTxPowerLevel(IntPtr advertiserHandle, BluetoothLePacketType packetType, + bool includePowerLevel); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_clear_advertising_data")] + public static extern int ClearAdvertisingData(IntPtr advertiserHandle, BluetoothLePacketType packetType); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_start_advertising_new")] + public static extern int BluetoothLeStartAdvertising(IntPtr advertiserHandle, + AdvertisingStateChangedCallBack callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_stop_advertising")] + public static extern int BluetoothLeStopAdvertising(IntPtr advertiserHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_mode")] + public static extern int SetAdvertisingMode(IntPtr advertiserHandle, + BluetoothLeAdvertisingMode advertisingMode); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_adapter_le_set_advertising_connectable")] + public static extern int SetAdvertisingConnectable(IntPtr advertiserHandle, + bool connectable); + + //Bluetooth Socket + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_create_rfcomm")] + internal static extern int CreateServerSocket(string serviceUuid, out int socketFd); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_destroy_rfcomm")] + internal static extern int DestroyServerSocket(int socketFd); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_listen_and_accept_rfcomm")] + internal static extern int Listen(int socketFd, int pendingConnections); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_connect_rfcomm")] + internal static extern int ConnectSocket(string address, string serviceUuid); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_disconnect_rfcomm")] + internal static extern int DisconnectSocket(int socketFd); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_send_data")] + internal static extern int SendData(int socketFd, string data, int dataLength); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_set_data_received_cb")] + internal static extern int SetDataReceivedCallback(DataReceivedCallback callback, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_data_received_cb")] + internal static extern int UnsetDataReceivedCallback(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_set_connection_state_changed_cb")] + internal static extern int SetConnectionStateChangedCallback(SocketConnectionStateChangedCallback callback, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_socket_unset_connection_state_changed_cb")] + internal static extern int UnsetSocketConnectionStateChangedCallback(); + + // Bluetooth Audio + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_initialize")] + internal static extern int InitializeAudio(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_deinitialize")] + internal static extern int DeinitializeAudio(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_connect")] + internal static extern int Connect(string deviceAddress, int profileType); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_disconnect")] + internal static extern int Disconnect(string deviceAddress, int profileType); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_set_connection_state_changed_cb")] + internal static extern int SetAudioConnectionStateChangedCallback(AudioConnectionStateChangedCallback audioStateChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_audio_unset_connection_state_changed_cb")] + internal static extern int UnsetAudioConnectionStateChangedCallback(); + + //Bluetooth Hid + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_initialize")] + internal static extern int InitializeHid(HidConnectionStateChangedCallback hidConnectionChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_deinitialize")] + internal static extern int DeinitializeHid(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_connect")] + internal static extern int Connect(string deviceAddress); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_hid_host_disconnect")] + internal static extern int Disconnect(string deviceAddress); + + //Bluetooth Avrcp + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_initialize")] + internal static extern int InitializeAvrcp(TargetConnectionStateChangedCallback targetStateChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_deinitialize")] + internal static extern int DeinitializeAvrcp(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_equalizer_state")] + internal static extern int NotifyEqualizerState(int state); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_repeat_mode")] + internal static extern int NotifyRepeatMode(int repeat); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_shuffle_mode")] + internal static extern int NotifyShuffleMode(int shuffle); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_scan_mode")] + internal static extern int NotifyScanMode(int scan); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_player_state")] + internal static extern int NotifyPlayerState(int state); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_position")] + internal static extern int NotifyCurrentPosition(uint position); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_target_notify_track")] + internal static extern int NotifyTrack(string title, string artist, string album, string genre, uint trackNum, uint totaltracks, uint duration); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_equalizer_state_changed_cb")] + internal static extern int SetEqualizerStateChangedCallback(EqualizerStateChangedCallback equalizerStateChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_equalizer_state_changed_cb")] + internal static extern int UnsetEqualizerStateChangedCallback(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_repeat_mode_changed_cb")] + internal static extern int SetRepeatModeChangedCallback(RepeatModeChangedCallback repeatModeChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_repeat_mode_changed_cb")] + internal static extern int UnsetRepeatModeChangedCallback(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_shuffle_mode_changed_cb")] + internal static extern int SetShuffleModeChangedCallback(ShuffleModeChangedCallback shuffleModeChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_shuffle_mode_changed_cb")] + internal static extern int UnsetShuffleModeChangedCallback(); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_set_scan_mode_changed_cb")] + internal static extern int SetScanModeChangedCallback(ScanModeChangedCallback scanModeChangedCb, IntPtr userData); + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_avrcp_unset_scan_mode_changed_cb")] + internal static extern int UnsetScanModeChangedCallback(); + + // Bluetooth GATT + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate bool BtGattForeachCallback(int total, int index, IntPtr gattHandle, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtGattServerReadValueRequestedCallback(string clientAddress, int requestId, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle gattHandle, int offset, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtGattServerWriteValueRequestedCallback(string clientAddress, int requestId, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle gattHandle, int offset, byte[] value, int len, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtClientCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle, byte[] value, int len, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtGattServerNotificationStateChangeCallback(bool notify, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle characteristicHandle, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtGattServerNotificationSentCallback(int result, string clientAddress, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle characteristicHandle, bool completed, IntPtr userData); + + [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] + internal delegate void BtGattClientRequestCompletedCallback(int result, IntPtr requestHandle, IntPtr userData); + + // Gatt Attribute + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_destroy")] + internal static extern int BtGattDestroy(IntPtr gattHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_uuid")] + internal static extern int BtGattGetUuid(BluetoothGattAttributeHandle gattHandle, out string uuid); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_value")] + internal static extern int BtGattGetValue(BluetoothGattAttributeHandle gattHandle, out IntPtr nativeValue, out int valueLength); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_value")] + internal static extern int BtGattSetValue(BluetoothGattAttributeHandle gattHandle, byte[] value, int valueLength); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_int_value")] + internal static extern int BtGattGetIntValue(BluetoothGattAttributeHandle gattHandle, int type, int offset, out int value); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_int_value")] + internal static extern int BtGattSetIntValue(BluetoothGattAttributeHandle gattHandle, int type, int value, int offset); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_get_float_value")] + internal static extern int BtGattGetFloatValue(BluetoothGattAttributeHandle gattHandle, int type, int offset, out float value); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_set_float_value")] + internal static extern int BtGattSetFloatValue(BluetoothGattAttributeHandle gattHandle, int type, int mantissa, int exponent, int offset); + + // GATT Descriptor + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_descriptor_create")] + internal static extern int BtGattDescriptorCreate(string uuid, int permissions, byte[] value, int valueLength, out BluetoothGattAttributeHandle descriptorHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_descriptor_get_permissions")] + internal static extern int BtGattDescriptorGetPermissions(BluetoothGattAttributeHandle descriptorHandle, out int permissions); + + // GATT Characteristic + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_create")] + internal static extern int BtGattCharacteristicCreate(string uuid, int permissions, int properties, byte[] value, int valueLength, out BluetoothGattAttributeHandle characteristicHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_permissions")] + internal static extern int BtGattCharacteristicGetPermissions(BluetoothGattAttributeHandle characteristicHandle, out int permissions); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_properties")] + internal static extern int BtGattCharacteristicGetProperties(BluetoothGattAttributeHandle characteristicHandle, out int properties); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_set_properties")] + internal static extern int BtGattCharacteristicSetProperties(BluetoothGattAttributeHandle characteristicHandle, int properties); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_write_type")] + internal static extern int BtGattCharacteristicGetWriteType(BluetoothGattAttributeHandle characteristicHandle, out int writeType); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_set_write_type")] + internal static extern int BtGattCharacteristicSetWriteType(BluetoothGattAttributeHandle characteristicHandle, int writeType); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_add_descriptor")] + internal static extern int BtGattCharacteristicAddDescriptor(BluetoothGattAttributeHandle characteristicHandle, BluetoothGattAttributeHandle descriptorHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_get_descriptor")] + internal static extern int BtGattCharacteristicGetDescriptor(BluetoothGattAttributeHandle characteristicHandle, string uuid, out BluetoothGattAttributeHandle descriptorHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_characteristic_foreach_descriptors")] + internal static extern int BtGattCharacteristicForeachDescriptors(BluetoothGattAttributeHandle characteristicHandle, BtGattForeachCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_set_characteristic_value_changed_cb")] + internal static extern int BtGattClientSetCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle, BtClientCharacteristicValueChangedCallback cb, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_unset_characteristic_value_changed_cb")] + internal static extern int BtGattClientUnsetCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle); + + // GATT Service + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_create")] + internal static extern int BtGattServiceCreate(string uuid, int type, out BluetoothGattAttributeHandle serviceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_add_characteristic")] + internal static extern int BtGattServiceAddCharacteristic(BluetoothGattAttributeHandle serviceHandle, BluetoothGattAttributeHandle characteristicHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_get_characteristic")] + internal static extern int BtGattServiceGetCharacteristic(BluetoothGattAttributeHandle serviceHandle, string uuid, out BluetoothGattAttributeHandle characteristicHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_foreach_characteristics")] + internal static extern int BtGattServiceForeachCharacteristics(BluetoothGattAttributeHandle serviceHandle, BtGattForeachCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_add_included_service")] + internal static extern int BtGattServiceAddIncludedService(BluetoothGattAttributeHandle serviceHandle, BluetoothGattAttributeHandle includedServiceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_get_included_service")] + internal static extern int BtGattServiceGetIncludedService(BluetoothGattAttributeHandle serviceHandle, string uuid, out BluetoothGattAttributeHandle includedServiceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_service_foreach_included_services")] + internal static extern int BtGattServiceForeachIncludedServices(BluetoothGattAttributeHandle serviceHandle, BtGattForeachCallback callback, IntPtr userData); + + // GATT Client + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_destroy")] + internal static extern int BtGattClientDestroy(IntPtr clientHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_create")] + internal static extern int BtGattClientCreate(string remoteAddress, out BluetoothGattClientHandle clientHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_get_remote_address")] + internal static extern int BtGattClientGetRemoteAddress(BluetoothGattClientHandle clientHandle, out string remoteAddress); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_get_service")] + internal static extern int BtGattClientGetService(BluetoothGattClientHandle clientHandle, string uuid, out BluetoothGattAttributeHandle serviceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_foreach_services")] + internal static extern int BtGattClientForeachServices(BluetoothGattClientHandle clientHandle, BtGattForeachCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_read_value")] + internal static extern int BtGattClientReadValue(BluetoothGattAttributeHandle gattHandle, BtGattClientRequestCompletedCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_client_write_value")] + internal static extern int BtGattClientWriteValue(BluetoothGattAttributeHandle gattHandle, BtGattClientRequestCompletedCallback callback, IntPtr userData); + + // GATT Server + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_destroy")] + internal static extern int BtGattServerDestroy(IntPtr serverHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_create")] + internal static extern int BtGattServerCreate(out BluetoothGattServerHandle serverHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_initialize")] + internal static extern int BtGattServerInitialize(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_deinitialize")] + internal static extern int BtGattServerDeinitialize(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_read_value_requested_cb")] + internal static extern int BtGattServerSetReadValueRequestedCallback(BluetoothGattAttributeHandle gattHandle, BtGattServerReadValueRequestedCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_read_value_requested_cb")] + internal static extern int BtGattServerSetWriteValueRequestedCallback(BluetoothGattAttributeHandle gattHandle, BtGattServerWriteValueRequestedCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_notification_state_change_cb")] + internal static extern int BtGattServeSetNotificationStateChangeCallback(BluetoothGattAttributeHandle characteristicHandle, BtGattServerNotificationStateChangeCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_start")] + internal static extern int BtGattServerStart(); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_register_service")] + internal static extern int BtGattServerRegisterService(BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle serviceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_unregister_service")] + internal static extern int BtGattServerUnregisterService(BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle serviceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_unregister_all_services")] + internal static extern int BtGattServerUnregisterAllServices(BluetoothGattServerHandle serverHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_get_service")] + internal static extern int BtGattServerGetService(BluetoothGattServerHandle serverHandle, string uuid, out BluetoothGattAttributeHandle serviceHandle); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_foreach_services")] + internal static extern int BtGattServerForeachServices(BluetoothGattServerHandle serverHandle, BtGattForeachCallback callback, IntPtr userData); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_send_response")] + internal static extern int BtGattServerSendResponse(int requestId, int requestType, int offset, int status, byte[] value, int valueLen); + + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_notify")] + internal static extern int BtGattServerNotify(BluetoothGattAttributeHandle characteristicHandle, bool sendIndication, BtGattServerNotificationSentCallback callback, string clientAddress, IntPtr userData); + } +} + + diff --git a/Tizen.Bluetooth/Interop/Interop.Glib.cs b/Tizen.Bluetooth/Interop/Interop.Glib.cs new file mode 100644 index 0000000..576a6e2 --- /dev/null +++ b/Tizen.Bluetooth/Interop/Interop.Glib.cs @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Glib + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool GSourceFunc(IntPtr userData); + + [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)] + internal static extern uint IdleAdd(GSourceFunc d, IntPtr data); + } +} diff --git a/Tizen.Bluetooth/Interop/Interop.Libc.cs b/Tizen.Bluetooth/Interop/Interop.Libc.cs new file mode 100644 index 0000000..825599e --- /dev/null +++ b/Tizen.Bluetooth/Interop/Interop.Libc.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Libc + { + [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)] + internal static extern int Free(IntPtr ptr); + } +} diff --git a/Tizen.Bluetooth/Interop/Interop.Libraries.cs b/Tizen.Bluetooth/Interop/Interop.Libraries.cs new file mode 100644 index 0000000..4aa83d4 --- /dev/null +++ b/Tizen.Bluetooth/Interop/Interop.Libraries.cs @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal static partial class Interop +{ + internal static partial class Libraries + { + public const string Bluetooth = "libcapi-network-bluetooth.so.0"; + public const string Glib = "libglib-2.0.so.0"; + public const string Libc = "libc.so.6"; + } +} diff --git a/Tizen.Bluetooth/Properties/AssemblyInfo.cs b/Tizen.Bluetooth/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..31b2b2b --- /dev/null +++ b/Tizen.Bluetooth/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Tizen.Bluetooth")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Tizen.Bluetooth")] +[assembly: AssemblyCopyright("Copyright \u00A9 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("99a90243-7db1-4704-a078-3529c2da4e81")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.Net45.csproj b/Tizen.Bluetooth/Tizen.Bluetooth.Net45.csproj new file mode 100644 index 0000000..739aaca --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth.Net45.csproj @@ -0,0 +1,90 @@ + + + + Debug + AnyCPU + {BF719F11-CDEA-4D04-A85B-4521A69E3614} + Library + Properties + Tizen.Bluetooth + Tizen.Bluetooth + 512 + v4.5 + + + true + full + false + bin\Debug\Net45\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\Net45\ + TRACE + prompt + 4 + false + + + true + + + Tizen.Bluetooth.snk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.Net45.project.json b/Tizen.Bluetooth/Tizen.Bluetooth.Net45.project.json new file mode 100644 index 0000000..1ec1af2 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth.Net45.project.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "Tizen": "1.0.2" + }, + "frameworks": { + "net45": {} + }, + "runtimes": { + "win": {} + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.csproj b/Tizen.Bluetooth/Tizen.Bluetooth.csproj new file mode 100644 index 0000000..511cbd4 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth.csproj @@ -0,0 +1,100 @@ + + + + Debug + AnyCPU + {3EE5842E-7004-43BC-825B-29FFDEC18D4E} + Library + Properties + Tizen.Bluetooth + Tizen.Bluetooth + 512 + + + .NETStandard + v1.3 + .NETStandard,Version=v1.3 + false + true + $(NoWarn);1701;1702 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + true + + + Tizen.Bluetooth.snk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory) + <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory) + true + + \ No newline at end of file diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.nuspec b/Tizen.Bluetooth/Tizen.Bluetooth.nuspec new file mode 100644 index 0000000..fd37dce --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth.nuspec @@ -0,0 +1,21 @@ + + + + Tizen.Bluetooth + $version$ + Samsung Electronics + false + https://www.apache.org/licenses/LICENSE-2.0 + https://www.tizen.org/ + https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png + © Samsung Electronics Co., Ltd All Rights Reserved + Provides the Bluetooth API for Tizen.Net + + + + + + + + + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.project.json b/Tizen.Bluetooth/Tizen.Bluetooth.project.json new file mode 100644 index 0000000..a4c6be0 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth.project.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "NETStandard.Library": "1.6.0", + "Tizen": "1.0.2" + }, + "frameworks": { + "netstandard1.3": {} + } +} \ No newline at end of file diff --git a/Tizen.Bluetooth/Tizen.Bluetooth.snk b/Tizen.Bluetooth/Tizen.Bluetooth.snk new file mode 100644 index 0000000..f3d151d Binary files /dev/null and b/Tizen.Bluetooth/Tizen.Bluetooth.snk differ diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapter.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapter.cs new file mode 100644 index 0000000..727bb46 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapter.cs @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class which is used to control a bluetooth adapter and get the list of bonded devices.
+ /// The BluetoothAdapter class is used to discover neighbouring bluetooth devices. + ///
+ /// http://tizen.org/privilege/bluetooth + static public class BluetoothAdapter + { + /// + /// A property to check whether Bluetooth is enabled. + /// + static public bool IsBluetoothEnabled + { + get + { + return BluetoothAdapterImpl.Instance.IsBluetoothEnabled; + } + } + + /// + /// The local adapter address. + /// + /// + /// The Bluetooth must be enabled. + /// + static public string Address + { + get + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.Address; + } + else + { + return null; + } + } + } + + /// + /// The name of the local adapter. + /// + /// + /// The Bluetooth must be enabled. + /// + static public string Name + { + get + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.Name; + } + else + { + return null; + } + } + set + { + BluetoothAdapterImpl.Instance.Name = value; + } + } + + /// + /// The visibility mode of the Bluetooth adapter. + /// + /// + /// The Bluetooth must be enabled. + /// + static public VisibilityMode Visibility + { + get + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.Visibility; + } + else + { + return VisibilityMode.NonDiscoverable; + } + } + } + + /// + /// A property to check whether device discovery is in progress. + /// + /// + /// The Bluetooth must be enabled. + /// + static public bool IsDiscoveryInProgress + { + get + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.IsDiscoveryInProgress; + } + else + { + return false; + } + } + } + + /// + /// The remaining time, in seconds, until the visibility mode is changed from TimeLimitedDiscoverable to NonDiscoverable. + /// + /// + /// The Bluetooth must be enabled. + /// + static public int RemainingTimeAsVisible + { + get + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.RemainingTimeAsVisible; + } + else + { + return 0; + } + } + } + + /// + /// (event) StateChanged is raised when bluetooth adapter state is changed. + /// + static public event EventHandler StateChanged + { + add + { + BluetoothAdapterImpl.Instance.StateChanged += value; + } + remove + { + BluetoothAdapterImpl.Instance.StateChanged -= value; + } + } + + /// + /// (event) NameChanged is raised when bluetooth adapter name is changed. + /// + static public event EventHandler NameChanged + { + add + { + BluetoothAdapterImpl.Instance.NameChanged += value; + } + remove + { + BluetoothAdapterImpl.Instance.NameChanged -= value; + } + } + + /// + /// (event) VisibilityModeChanged is raised when bluetooth adapter visibility mode is changed. + /// + static public event EventHandler VisibilityModeChanged + { + add + { + BluetoothAdapterImpl.Instance.VisibilityModeChanged += value; + } + remove + { + BluetoothAdapterImpl.Instance.VisibilityModeChanged -= value; + } + } + + /// + /// (event) VisibilityDurationChanged is raised very second until the visibility mode is changed to NonDiscoverable. + /// + static public event EventHandler VisibilityDurationChanged + { + add + { + BluetoothAdapterImpl.Instance.VisibilityDurationChanged += value; + } + remove + { + BluetoothAdapterImpl.Instance.VisibilityDurationChanged -= value; + } + } + + /// + /// (event) DiscoveryStateChanged is raised when the device discovery state is changed. + /// + static public event EventHandler DiscoveryStateChanged + { + add + { + BluetoothAdapterImpl.Instance.DiscoveryStateChanged += value; + } + remove + { + BluetoothAdapterImpl.Instance.DiscoveryStateChanged -= value; + } + } + + /// + /// Event that is called when the LE Scan result is obtained. + /// + static public event EventHandler ScanResultChanged + { + add + { + BluetoothLeImplAdapter.Instance.AdapterLeScanResultChanged += value; + } + remove { + BluetoothLeImplAdapter.Instance.AdapterLeScanResultChanged -= value; + } + } + + /// + /// Starts the device discovery process. + /// + /// + /// The Bluetooth must be enabled and device discovery can be stopped by StopDiscovery(). + /// If this succeeds, DiscoveryStateChanged event will be invoked. + /// + static public void StartDiscovery() + { + if (IsBluetoothEnabled) + { + BluetoothAdapterImpl.Instance.StartDiscovery(); + } + } + + /// + /// Stops the device discovery process. + /// + /// + /// The device discovery must be in progress with StartDiscovery(). + /// If this succeeds, DiscoveryStateChanged event will be invoked. + /// + static public void StopDiscovery() + { + if (IsDiscoveryInProgress) + { + BluetoothAdapterImpl.Instance.StopDiscovery(); + } + } + + /// + /// Retrieves the device information of all bonded devices. + /// + /// + /// The Bluetooth must be enabled. + /// + /// List of Bonded BluetoothDeviceInfo objects. + static public IEnumerable GetBondedDevices() + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.GetBondedDevices(); + } + else + { + return null; + } + } + + /// + /// Gets the device information of a bonded device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// Information of bonded BluetoothDeviceInfo object. + static public BluetoothDevice GetBondedDevice(string address) + { + if (IsBluetoothEnabled) + { + return BluetoothAdapterImpl.Instance.GetBondedDevice(address); + } + else + { + return null; + } + } + + /// + /// Checks whether the UUID of service is used or not. + /// + /// true if the specified serviceUuid is used; otherwise, false. + /// The UUID of Service. + static public bool IsServiceUsed(string serviceUuid) + { + return BluetoothAdapterImpl.Instance.IsServiceUsed(serviceUuid); + } + + /// + /// Gets the hash and randomizer value of local oob data object. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The BluetoothOobData object. + static public BluetoothOobData GetLocalOobData() + { + if (IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothAdapterImpl.Instance.GetLocalOobData(); + } + else + { + return null; + } + } + + /// + /// Sets the Hash and Randmoizer value of oob data into the remote device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// Remote Device address. + /// BluetoothOobData object. + static public void SetRemoteOobData(string address, BluetoothOobData oobData) + { + if (IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAdapterImpl.Instance.SetRemoteOobData(address, oobData); + } + } + + /// + /// Removes the Hash and Randomizer value of oob data from the remote device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// Remote Device address. + static public void RemoveRemoteOobData(string address) + { + if (IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAdapterImpl.Instance.RemoveRemoteOobData(address); + } + } + + /// + /// Starts the Bluetooth Le scan operation to discover BLE devices + /// + /// + /// Bluetooth must be enabled. + /// the result of the operation StartLeScan + static public void StartLeScan() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.StartScan (); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to in start the le scan operation, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Stops the Bluetooth Le scan operation. + /// + /// + /// The Bluetooth must be enabled. + /// the result of the operation stopLescan + static public void StopLeScan() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.StopScan (); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to stop the le scan operation, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Returns BluetoothLeAdvertiser instance. + /// + /// + /// The bluetooth must be enabled before calling this API. + /// + /// The BluetoothLeAdvertiser instance. + static public BluetoothLeAdvertiser GetBluetoothLeAdvertiser() + { + return BluetoothLeAdvertiser.Instance; + } + + /// + /// Registers a rfcomm server socket with a specific UUID. + /// + /// + /// The bluetooth must be enabled before calling this API. + /// + /// The BluetoothServerSocket instance. + /// The UUID of service to provide. + static public BluetoothServerSocket CreateServerSocket(string serviceUuid) + { + if (IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothAdapterImpl.Instance.CreateServerSocket (serviceUuid); + } + else + { + return null; + } + } + + /// + /// Removes the rfcomm server socket which was created using CreateServerSocket(). + /// + /// + /// The socket must be created with CreateServerSocket(). ConnectionStateChanged event is raised after this API is called. + /// + /// The server socket instance which is created using CreateServerSocket(). + static public void DestroyServerSocket(BluetoothServerSocket socket) + { + if (IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAdapterImpl.Instance.DestroyServerSocket(socket); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapterImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapterImpl.cs new file mode 100644 index 0000000..92c4b0a --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAdapterImpl.cs @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth +{ + static internal class Globals + { + internal const string LogTag = "Tizen.Network.Bluetooth"; + internal static bool IsInitialize = false; + internal static bool IsAudioInitialize = false; + internal static bool IsHidInitialize = false; + } + + internal partial class BluetoothAdapterImpl : IDisposable + { + private event EventHandler _stateChanged; + private event EventHandler _nameChanged; + private event EventHandler _visibilityModeChanged; + private event EventHandler _visibilityDurationChanged; + private event EventHandler _discoveryStateChanged; + + private Interop.Bluetooth.StateChangedCallback _stateChangedCallback; + private Interop.Bluetooth.NameChangedCallback _nameChangedCallback; + private Interop.Bluetooth.VisibilityModeChangedCallback _visibilityChangedCallback; + private Interop.Bluetooth.VisibilityDurationChangedCallback _visibilitydurationChangedCallback; + private Interop.Bluetooth.DiscoveryStateChangedCallback _discoveryStateChangedCallback; + + private static readonly BluetoothAdapterImpl _instance = new BluetoothAdapterImpl(); + private bool disposed = false; + + internal event EventHandler StateChanged + { + add + { + if (_stateChanged == null) + { + RegisterStateChangedEvent(); + } + _stateChanged += value; + } + remove + { + _stateChanged -= value; + if (_stateChanged == null) + { + UnregisterStateChangedEvent(); + } + } + } + + internal event EventHandler NameChanged + { + add + { + if (_nameChanged == null) + { + RegisterNameChangedEvent(); + } + _nameChanged += value; + } + remove + { + _nameChanged -= value; + if (_nameChanged == null) + { + UnregisterNameChangedEvent(); + } + } + } + + internal event EventHandler VisibilityModeChanged + { + add + { + if (_visibilityModeChanged == null) + { + RegisterVisibilityChangedEvent(); + } + _visibilityModeChanged += value; + } + remove + { + _visibilityModeChanged -= value; + if (_visibilityModeChanged == null) + { + UnregisterVisibilityChangedEvent(); + } + } + } + + internal event EventHandler VisibilityDurationChanged + { + add + { + if (_visibilityDurationChanged == null) + { + RegisterVisibilityDurationChangedEvent(); + } + _visibilityDurationChanged += value; + } + remove + { + _visibilityDurationChanged -= value; + if (_visibilityDurationChanged == null) + { + UnregisterVisibilityDurationChangedEvent(); + } + } + } + + internal event EventHandler DiscoveryStateChanged + { + add + { + if (_discoveryStateChanged == null) + { + RegisterDiscoveryStateChangedEvent(); + } + _discoveryStateChanged+= value; + } + remove + { + _discoveryStateChanged -= value; + if (_discoveryStateChanged == null) + { + UnregisterDiscoveryStateChangedEvent(); + } + } + } + + private void RegisterStateChangedEvent() + { + _stateChangedCallback = (int result, int state, IntPtr userData) => + { + if (_stateChanged != null) + { + BluetoothState st = (BluetoothState)state; + BluetoothError res = (BluetoothError)result; + _stateChanged(null, new StateChangedEventArgs(res,st)); + } + }; + int ret = Interop.Bluetooth.SetStateChangedCallback(_stateChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set state changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset state changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterNameChangedEvent() + { + _nameChangedCallback = (string deviceName, IntPtr userData) => + { + if (_nameChanged != null) + { + _nameChanged(null, new NameChangedEventArgs(deviceName)); + } + }; + int ret = Interop.Bluetooth.SetNameChangedCallback(_nameChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set name changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterNameChangedEvent() + { + int ret = Interop.Bluetooth.UnsetNameChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset name changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterVisibilityChangedEvent() + { + _visibilityChangedCallback = (int result, int mode, IntPtr userData) => + { + if (_visibilityModeChanged != null) + { + VisibilityMode visibility = (VisibilityMode)mode; + BluetoothError res = (BluetoothError)result; + _visibilityModeChanged(null, new VisibilityModeChangedEventArgs(res,visibility)); + } + }; + int ret = Interop.Bluetooth.SetVisibilityModeChangedCallback(_visibilityChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set visibility mode changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterVisibilityChangedEvent() + { + int ret = Interop.Bluetooth.UnsetVisibilityModeChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset visibility mode changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterVisibilityDurationChangedEvent() + { + _visibilitydurationChangedCallback = (int duration, IntPtr userData) => + { + if (_visibilityDurationChanged != null) + { + _visibilityDurationChanged(null, new VisibilityDurationChangedEventArgs(duration)); + } + }; + int ret = Interop.Bluetooth.SetVisibilityDurationChangedCallback(_visibilitydurationChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set visibility duration changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterVisibilityDurationChangedEvent() + { + int ret = Interop.Bluetooth.UnsetVisibilityDurationChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset visiiblity duration changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterDiscoveryStateChangedEvent() + { + _discoveryStateChangedCallback = (int result, BluetoothDeviceDiscoveryState state, IntPtr deviceInfo, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Discovery state changed callback is called"); + if (_discoveryStateChanged != null) + { + BluetoothError res = (BluetoothError)result; + switch(state) + { + case BluetoothDeviceDiscoveryState.Started: + _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state)); + break; + case BluetoothDeviceDiscoveryState.Finished: + { + _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state)); + break; + } + case BluetoothDeviceDiscoveryState.Found: + { + BluetoothDiscoveredDeviceStruct info = (BluetoothDiscoveredDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDiscoveredDeviceStruct)); + _discoveryStateChanged(null, new DiscoveryStateChangedEventArgs(res,state,BluetoothUtils.ConvertStructToDiscoveredDevice(info))); + break; + } + default: + break; + } + } + }; + int ret = Interop.Bluetooth.SetDiscoveryStateChangedCallback(_discoveryStateChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set discovery state changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterDiscoveryStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetDiscoveryStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset discovery state changed callback, Error - " + (BluetoothError)ret); + } + } + + internal bool IsBluetoothEnabled + { + get + { + BluetoothState active; + int ret = Interop.Bluetooth.GetState(out active); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get state, Error - " + (BluetoothError)ret); + } + if (active == BluetoothState.Enabled) + return true; + else + return false; + } + } + internal string Address + { + get + { + string address; + int ret = Interop.Bluetooth.GetAddress(out address); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get address, Error - " + (BluetoothError)ret); + return ""; + } + return address; + } + } + + internal VisibilityMode Visibility + { + get + { + int visibilityMode; + int time; + int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out time); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get visibility mode, Error - " + (BluetoothError)ret); + return VisibilityMode.NonDiscoverable; + } + return (VisibilityMode)visibilityMode; + } + } + + internal bool IsDiscoveryInProgress + { + get + { + bool isDiscovering; + int ret = Interop.Bluetooth.IsDiscovering(out isDiscovering); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get discovery progress state, Error - " + (BluetoothError)ret); + } + return isDiscovering; + } + } + + internal int RemainingTimeAsVisible + { + get + { + int duration = 0; + int visibilityMode; + int ret = Interop.Bluetooth.GetVisibility(out visibilityMode, out duration); + if ((ret != (int)BluetoothError.None) || ((VisibilityMode)visibilityMode != VisibilityMode.TimeLimitedDiscoverable)) + { + Log.Error(Globals.LogTag, "Failed to get remaining visible time, Error - " + (BluetoothError)ret); + } + return duration; + } + } + + internal string Name + { + get + { + string name; + int ret = Interop.Bluetooth.GetName(out name); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get adapter name, Error - " + (BluetoothError)ret); + return ""; + } + return name; + } + set + { + int ret = Interop.Bluetooth.SetName(value.ToString()); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set adapter name, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + internal void StartDiscovery() + { + int ret = Interop.Bluetooth.StartDiscovery(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to start discovery, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void StopDiscovery() + { + int ret = Interop.Bluetooth.StopDiscovery(); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to stop discovery, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal IEnumerable GetBondedDevices() + { + List deviceList = new List(); + Interop.Bluetooth.BondedDeviceCallback callback = (ref BluetoothDeviceStruct deviceInfo, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Bonded devices cb is called"); + if(!deviceInfo.Equals(null)) + { + deviceList.Add(BluetoothUtils.ConvertStructToDeviceClass(deviceInfo)); + } + return true; + }; + int ret = Interop.Bluetooth.GetBondedDevices(callback, IntPtr.Zero); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get bonded devices, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return deviceList; + } + + internal BluetoothDevice GetBondedDevice(string address) + { + IntPtr deviceInfo; + int ret = Interop.Bluetooth.GetBondedDeviceByAddress(address, out deviceInfo); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get bonded device by address, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + BluetoothDeviceStruct device = (BluetoothDeviceStruct)Marshal.PtrToStructure(deviceInfo, typeof(BluetoothDeviceStruct)); + + return BluetoothUtils.ConvertStructToDeviceClass(device); + } + + internal bool IsServiceUsed(string serviceUuid) + { + bool isUsed; + int ret = Interop.Bluetooth.IsServiceUsed(serviceUuid, out isUsed); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to check the usage of service, Error - " + (BluetoothError)ret); + } + return isUsed; + } + + internal BluetoothOobData GetLocalOobData() + { + BluetoothOobData oobData = new BluetoothOobData(); + IntPtr hash; + IntPtr randomizer; + int hashLength; + int randomizerLength; + int ret = Interop.Bluetooth.GetOobData(out hash, out randomizer, out hashLength, out randomizerLength); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get the local oob data, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + byte[] hashArr = new byte[hashLength]; + Marshal.Copy(hash, hashArr, 0, hashLength); + byte[] randomizerArr = new byte[randomizerLength]; + Marshal.Copy(randomizer, randomizerArr, 0, randomizerLength); + + oobData.HashValue = hashArr; + oobData.RandomizerValue = randomizerArr; + return oobData; + } + + internal void SetRemoteOobData(string deviceAddress, BluetoothOobData oobData) + { + byte[] hash = oobData.HashValue; + byte[] randomizer = oobData.RandomizerValue; + int hashLength = hash.Length; + int randomizerLength = randomizer.Length; + + IntPtr hashPtr = Marshal.AllocHGlobal(hashLength); + Marshal.Copy(hash, 0, hashPtr, hashLength); + IntPtr randomizerPtr = Marshal.AllocHGlobal(randomizerLength); + Marshal.Copy(randomizer, 0, randomizerPtr, randomizerLength); + + int ret = Interop.Bluetooth.SetOobData(deviceAddress, hashPtr, randomizerPtr, hashLength, randomizerLength); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set the remote oob data, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void RemoveRemoteOobData(string deviceAddress) + { + int ret = Interop.Bluetooth.RemoveOobData(deviceAddress); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to remove the remote oob data, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal BluetoothServerSocket CreateServerSocket(string serviceUuid) + { + int socketFd; + int ret = Interop.Bluetooth.CreateServerSocket(serviceUuid, out socketFd); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to create server socket, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + Log.Info (Globals.LogTag, "Created socketfd: "+ socketFd); + return new BluetoothServerSocket(socketFd); + } + + internal void DestroyServerSocket(BluetoothServerSocket socket) + { + int ret = Interop.Bluetooth.DestroyServerSocket(socket.socketFd); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to destroy socket, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal static BluetoothAdapterImpl Instance + { + get + { + return _instance; + } + } + + private BluetoothAdapterImpl() + { + initialize(); + } + + ~BluetoothAdapterImpl() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + RemoveAllRegisteredEvent(); + deinitialize(); + disposed = true; + } + + private void initialize() + { + int ret = Interop.Bluetooth.Initialize(); + if (ret != (int)BluetoothError.None) + { + Log.Error (Globals.LogTag, "Failed to initialize bluetooth, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + else + { + Globals.IsInitialize = true; + } + } + + private void deinitialize() + { + int ret = Interop.Bluetooth.Deinitialize(); + if (ret != (int)BluetoothError.None) + { + Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + else + { + Globals.IsInitialize = false; + } + } + + private void RemoveAllRegisteredEvent() + { + //unregister all remaining events when this object is released. + if (_stateChanged != null) + { + UnregisterStateChangedEvent(); + } + + if (_nameChanged != null) + { + UnregisterNameChangedEvent(); + } + + if (_visibilityDurationChanged != null) + { + UnregisterVisibilityDurationChangedEvent(); + } + + if (_visibilityModeChanged != null) + { + UnregisterVisibilityChangedEvent(); + } + + if (_discoveryStateChanged != null) + { + UnregisterDiscoveryStateChangedEvent(); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudio.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudio.cs new file mode 100644 index 0000000..d66a401 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudio.cs @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class which is used to handle the connection with other Bluetooth audio devices + /// like headset, hands-free and headphone. + /// + /// http://tizen.org/privilege/bluetooth + public class BluetoothAudio : BluetoothProfile + { + internal BluetoothAudio() + { + } + + /// + /// (event) AudioConnectionStateChanged is called when audio connection state is changed. + /// + public event EventHandler AudioConnectionStateChanged + { + add + { + BluetoothAudioImpl.Instance.AudioConnectionStateChanged += value; + } + remove + { + BluetoothAudioImpl.Instance.AudioConnectionStateChanged -= value; + } + } + + /// + /// Connect the remote device with the given audio profile. + /// + /// + /// The device must be bonded with remote device by CreateBond().If connection request succeeds, AudioConnectionStateChanged event will be invoked. + /// If audio profile type is All and this request succeeds, then AudioConnectionStateChanged event will be called twice when HspHfp
+ /// and AdvancedAudioDistribution is connected. + ///
+ /// Type of audio profile. + public void Connect(BluetoothAudioProfileType profileType) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothAudioImpl.Instance.Connect(RemoteAddress, profileType); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to Connect - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Disconnects the remote device with the given audio profile. + /// + /// + /// The device must be connected by Connect().If the disconnection request succeeds, AudioConnectionStateChanged event will be invoked. + /// If audio profile type is All and this request succeeds, then AudioConnectionStateChanged event will be called twice when HspHfp
+ /// and AdvancedAudioDistribution is disconnected. + ///
+ /// Type of audio profile. + public void Disconnect(BluetoothAudioProfileType type) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothAudioImpl.Instance.Disconnect(RemoteAddress, type); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to Disconnect - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudioImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudioImpl.cs new file mode 100644 index 0000000..eeb1977 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAudioImpl.cs @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + internal class BluetoothAudioImpl : IDisposable + { + private event EventHandler _audioConnectionChanged; + private Interop.Bluetooth.AudioConnectionStateChangedCallback _audioConnectionChangedCallback; + + private static readonly BluetoothAudioImpl _instance = new BluetoothAudioImpl(); + private bool disposed = false; + + internal event EventHandler AudioConnectionStateChanged + { + add + { + if (_audioConnectionChanged == null) + { + RegisterAudioConnectionChangedEvent(); + } + _audioConnectionChanged += value; + } + remove + { + _audioConnectionChanged -= value; + if (_audioConnectionChanged == null) + { + UnregisterAudioConnectionChangedEvent(); + } + } + } + + private void RegisterAudioConnectionChangedEvent() + { + _audioConnectionChangedCallback = (int result, bool connected, string deviceAddress, int profileType, IntPtr userData) => + { + if (_audioConnectionChanged != null) + { + _audioConnectionChanged(null, new AudioConnectionStateChangedEventArgs(result, connected, deviceAddress, (BluetoothAudioProfileType)profileType)); + } + }; + int ret = Interop.Bluetooth.SetAudioConnectionStateChangedCallback(_audioConnectionChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set audio connection changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterAudioConnectionChangedEvent() + { + int ret = Interop.Bluetooth.UnsetAudioConnectionStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset audio connection changed callback, Error - " + (BluetoothError)ret); + } + } + + internal int Connect(string deviceAddress, BluetoothAudioProfileType type) + { + int ret = Interop.Bluetooth.Connect(deviceAddress, (int)type); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to connect device with the given profile type, Error - " + (BluetoothError)ret); + } + return ret; + } + + internal int Disconnect(string deviceAddress, BluetoothAudioProfileType type) + { + int ret = Interop.Bluetooth.Disconnect(deviceAddress, (int)type); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to disconnect device with the given profile type, Error - " + (BluetoothError)ret); + } + return ret; + } + + internal static BluetoothAudioImpl Instance + { + get + { + return _instance; + } + } + + private BluetoothAudioImpl () + { + Log.Info(Globals.LogTag, "Initializing audio"); + initialize(); + } + + ~BluetoothAudioImpl() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + deinitialize(); + RemoveAllRegisteredEvent(); + disposed = true; + } + + private void initialize() + { + if (Globals.IsInitialize) + { + int ret = Interop.Bluetooth.InitializeAudio (); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to initialize bluetoothaudio, Error - " + (BluetoothError)ret); + Globals.IsAudioInitialize = false; + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + else + { + Globals.IsAudioInitialize = true; + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized); + } + } + + private void deinitialize() + { + if (Globals.IsAudioInitialize) { + int ret = Interop.Bluetooth.DeinitializeAudio (); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to deinitialize bluetoothaudio, Error - " + (BluetoothError)ret); + } + } + } + + private void RemoveAllRegisteredEvent() + { + if (_audioConnectionChanged != null) + { + UnregisterAudioConnectionChangedEvent(); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcp.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcp.cs new file mode 100644 index 0000000..f83ad82 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcp.cs @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class which is used to notify changes of the target device(e.g.media player) to the control device(e.g.headset). + /// + /// http://tizen.org/privilege/bluetooth + public class BluetoothAvrcp : BluetoothProfile + { + internal BluetoothAvrcp() + { + } + + /// + /// (event) TargetConnectionStateChanged is invoked when the connection state is changed. + /// + public event EventHandler TargetConnectionStateChanged + { + add + { + BluetoothAvrcpImpl.Instance.TargetConnectionStateChanged += value; + } + remove + { + BluetoothAvrcpImpl.Instance.TargetConnectionStateChanged -= value; + } + } + + /// + /// (event) EqualizerStateChanged is invoked when the equalizer state is changed by the remote control device. + /// + public event EventHandler EqualizerStateChanged + { + add + { + BluetoothAvrcpImpl.Instance.EqualizerStateChanged += value; + } + remove + { + BluetoothAvrcpImpl.Instance.EqualizerStateChanged -= value; + } + } + + /// + /// (event) RepeatModeChanged is invoked when the repeat mode is changed by the remote control device. + /// + public event EventHandler RepeatModeChanged + { + add + { + BluetoothAvrcpImpl.Instance.RepeatModeChanged += value; + } + remove + { + BluetoothAvrcpImpl.Instance.RepeatModeChanged -= value; + } + } + + /// + /// (event) ShuffleModeChanged is invoked when the shuffle mode is changed by the remote control device. + /// + public event EventHandler ShuffleModeChanged + { + add + { + BluetoothAvrcpImpl.Instance.ShuffleModeChanged += value; + } + remove + { + BluetoothAvrcpImpl.Instance.ShuffleModeChanged -= value; + } + } + + /// + /// (event) ScanModeChanged is invoked when the scan mode is changed by the remote control device. + /// + public event EventHandler ScanModeChanged + { + add + { + BluetoothAvrcpImpl.Instance.ScanModeChanged += value; + } + remove + { + BluetoothAvrcpImpl.Instance.ScanModeChanged -= value; + } + } + + /// + /// Notifies the equalize state to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Equalizer state. + public void NotifyEqualizerState(EqualizerState state) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyEqualizeState(state); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the repeat mode to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Repeat mode. + public void NotifyRepeatMode(RepeatMode mode) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyRepeatMode(mode); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the shuffle mode to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Shuffle mode. + public void NotifyShuffleMode(ShuffleMode mode) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyShuffleMode(mode); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the scan mode to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Scan mode. + public void NotifyScanMode(ScanMode mode) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyScanMode(mode); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the player state to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Player state. + public void NotifyPlayerState(PlayerState state) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyPlayerState(state); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the current position of song to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Current position in milliseconds. + public void NotifyCurrentPosition(uint position) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyCurrentPosition(position); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Notifies the track to the remote device. + /// + /// + /// The remote device must be connected. + /// + /// Data of the track. + public void NotifyTrack(Track trackData) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothAvrcpImpl.Instance.NotifyTrack(trackData); + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } +} + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcpImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcpImpl.cs new file mode 100644 index 0000000..b9606bd --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothAvrcpImpl.cs @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + internal class BluetoothAvrcpImpl : IDisposable + { + private event EventHandler _targetConnectionChanged; + private event EventHandler _equalizerStateChanged; + private event EventHandler _repeatModeChanged; + private event EventHandler _scanModeChanged; + private event EventHandler _shuffleModeChanged; + + private Interop.Bluetooth.TargetConnectionStateChangedCallback _targetConnectionChangedCallback; + private Interop.Bluetooth.EqualizerStateChangedCallback _equalizerStateChangedCallback; + private Interop.Bluetooth.RepeatModeChangedCallback _repeatModeChangedCallback; + private Interop.Bluetooth.ShuffleModeChangedCallback _shuffleModeChangedCallback; + private Interop.Bluetooth.ScanModeChangedCallback _scanModeChangedCallback; + + private static BluetoothAvrcpImpl _instance = new BluetoothAvrcpImpl(); + private bool disposed = false; + + internal event EventHandler TargetConnectionStateChanged + { + add + { + _targetConnectionChanged += value; + } + remove + { + _targetConnectionChanged -= value; + } + } + + internal event EventHandler EqualizerStateChanged + { + add + { + if (_equalizerStateChanged == null) + { + RegisterEqualizerStateChangedEvent(); + } + _equalizerStateChanged += value; + } + remove + { + _equalizerStateChanged -= value; + if (_equalizerStateChanged == null) + { + UnregisterEqualizerStateChangedEvent(); + } + } + } + + internal event EventHandler RepeatModeChanged + { + add + { + if (_repeatModeChanged == null) + { + RegisterRepeatModeChangedEvent(); + } + _repeatModeChanged += value; + } + remove + { + _repeatModeChanged -= value; + if (_repeatModeChanged == null) + { + UnregisterRepeatModeChangedEvent(); + } + } + } + + internal event EventHandler ShuffleModeChanged + { + add + { + if (_shuffleModeChanged == null) + { + RegisterShuffleModeChangedEvent(); + } + _shuffleModeChanged += value; + } + remove + { + _shuffleModeChanged -= value; + if (_shuffleModeChanged == null) + { + UnregisterShuffleModeChangedEvent(); + } + } + } + + internal event EventHandler ScanModeChanged + { + add + { + if (_scanModeChanged == null) + { + RegisterScanModeChangedEvent(); + } + _scanModeChanged += value; + } + remove + { + _scanModeChanged -= value; + if (_scanModeChanged == null) + { + UnregisterScanModeChangedEvent(); + } + } + } + + private void RegisterEqualizerStateChangedEvent() + { + _equalizerStateChangedCallback = (int equalizer, IntPtr userData) => + { + if (_equalizerStateChanged != null) + { + EqualizerState state = (EqualizerState) equalizer; + _equalizerStateChanged(null, new EqualizerStateChangedEventArgs(state)); + } + }; + int ret = Interop.Bluetooth.SetEqualizerStateChangedCallback(_equalizerStateChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set equalizer state changed callback, Error - " + (BluetoothError)ret); + } + } + private void UnregisterEqualizerStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetEqualizerStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset equalizer state changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterRepeatModeChangedEvent() + { + _repeatModeChangedCallback = (int repeat, IntPtr userData) => + { + if (_repeatModeChanged != null) + { + RepeatMode mode = (RepeatMode)repeat; + _repeatModeChanged(null, new RepeatModeChangedEventArgs(mode)); + } + }; + int ret = Interop.Bluetooth.SetRepeatModeChangedCallback(_repeatModeChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set repeat mode changed callback, Error - " + (BluetoothError)ret); + } + } + private void UnregisterRepeatModeChangedEvent() + { + int ret = Interop.Bluetooth.UnsetRepeatModeChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset repeat mode changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterShuffleModeChangedEvent() + { + Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent"); + _shuffleModeChangedCallback = (int shuffle, IntPtr userData) => + { + Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent callback"); + if (_shuffleModeChanged != null) + { + ShuffleMode mode = (ShuffleMode) shuffle; + _shuffleModeChanged(null, new ShuffleModeChangedeventArgs(mode)); + } + }; + int ret = Interop.Bluetooth.SetShuffleModeChangedCallback(_shuffleModeChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Debug (Globals.LogTag, "failed inside RegisterShuffleModeChangedEvent"); + Log.Error(Globals.LogTag, "Failed to set shuffle mode changed callback, Error - " + (BluetoothError)ret); + } + } + private void UnregisterShuffleModeChangedEvent() + { + int ret = Interop.Bluetooth.UnsetShuffleModeChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset shuffle mode changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterScanModeChangedEvent() + { + _scanModeChangedCallback = (int scan, IntPtr userData) => + { + if (_scanModeChanged != null) + { + ScanMode mode = (ScanMode) scan; + _scanModeChanged(null, new ScanModeChangedEventArgs(mode)); + } + }; + int ret = Interop.Bluetooth.SetScanModeChangedCallback(_scanModeChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set scan mode changed callback, Error - " + (BluetoothError)ret); + } + } + private void UnregisterScanModeChangedEvent() + { + int ret = Interop.Bluetooth.UnsetScanModeChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset scan mode changed callback, Error - " + (BluetoothError)ret); + } + } + + private void targetInitialize() + { + if (Globals.IsInitialize) + { + _targetConnectionChangedCallback = (bool connected, string deviceAddress, IntPtr userData) => + { + if (_targetConnectionChanged != null) + { + _targetConnectionChanged(null, new TargetConnectionStateChangedEventArgs(connected, deviceAddress)); + } + }; + + int ret = Interop.Bluetooth.InitializeAvrcp(_targetConnectionChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error (Globals.LogTag, "Failed to initialize bluetooth avrcp, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + else + { + Globals.IsAudioInitialize = true; + } + } + else + { + Log.Error(Globals.LogTag, "Failed to initialize Avrcp, BT not initialized"); + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized); + } + } + + private void targetDeinitialize() + { + if (Globals.IsAudioInitialize) + { + int ret = Interop.Bluetooth.DeinitializeAvrcp(); + if (ret != (int)BluetoothError.None) + { + Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth avrcp, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + else + { + Globals.IsAudioInitialize = false; + } + } + } + + internal void NotifyEqualizeState(EqualizerState state) + { + int ret = Interop.Bluetooth.NotifyEqualizerState((int)state); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify equalizer state to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyRepeatMode(RepeatMode repeat) + { + int ret = Interop.Bluetooth.NotifyRepeatMode((int)repeat); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify repeat mode to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyShuffleMode(ShuffleMode shuffle) + { + int ret = Interop.Bluetooth.NotifyShuffleMode((int)shuffle); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify shuffle mode to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyScanMode(ScanMode scan) + { + int ret = Interop.Bluetooth.NotifyScanMode((int)scan); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify scan mode to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyPlayerState(PlayerState state) + { + int ret = Interop.Bluetooth.NotifyPlayerState((int)state); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify player state to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyCurrentPosition(uint position) + { + int ret = Interop.Bluetooth.NotifyCurrentPosition(position); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify position to remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal void NotifyTrack(Track trackData) + { + string title = trackData.Title; + string artist = trackData.Artist; + string album = trackData.Album; + string genre = trackData.Genre; + uint trackNum = trackData.TrackNum; + uint totalTracks = trackData.TotalTracks; + uint duration = trackData.Duration; + + int ret = Interop.Bluetooth.NotifyTrack(title, artist, album, genre, trackNum, totalTracks, duration); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to notify track data to the remote device, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal static BluetoothAvrcpImpl Instance + { + get + { + return _instance; + } + } + + private BluetoothAvrcpImpl() + { + targetInitialize(); + } + + ~BluetoothAvrcpImpl() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + targetDeinitialize(); + RemoveAllRegisteredEvent(); + disposed = true; + } + + private void RemoveAllRegisteredEvent() + { + //unregister all remaining events when this object is released. + if (_equalizerStateChanged != null) + { + UnregisterEqualizerStateChangedEvent(); + } + if (_repeatModeChanged != null) + { + UnregisterRepeatModeChangedEvent(); + } + if (_scanModeChanged != null) + { + UnregisterScanModeChangedEvent(); + } + if (_shuffleModeChanged != null) + { + UnregisterShuffleModeChangedEvent(); + } + } + } +} + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothData.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothData.cs new file mode 100644 index 0000000..f219bc5 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothData.cs @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class to handle device class type and service. + /// + public class BluetoothClass + { + internal BluetoothMajorDeviceClassType MajorType; + internal BluetoothMinorDeviceClassType MinorType; + internal int Mask; + + internal BluetoothClass() + { + } + + /// + /// Type of the major device class. + /// + public BluetoothMajorDeviceClassType MajorDeviceClassType + { + get + { + return MajorType; + } + } + /// + /// Type of the minor device class. + /// + public BluetoothMinorDeviceClassType MinorDeviceClassType + { + get + { + return MinorType; + } + } + /// + /// Major service class mask. + /// + public int MajorServiceClassMask + { + get + { + return Mask; + } + } + } + + /// + /// A class containing the information of Bluetooth oob data. + /// + public class BluetoothOobData + { + /// + /// Default Constructor.Initializes an object of BluetoothOobData + /// + public BluetoothOobData() + { + } + + /// + /// Hash value. + /// + public byte[] HashValue + { + get; + set; + } + /// + /// Randomizer value. + /// + public byte[] RandomizerValue + { + get; + set; + } + } + + /// + /// A class containing the information of Bluetooth device sdp data. + /// + public class BluetoothDeviceSdpData + { + internal string Address; + internal Collection Uuid; + + internal BluetoothDeviceSdpData() + { + } + + /// + /// The device address. + /// + public string DeviceAddress + { + get + { + return Address; + } + } + /// + /// The service UUID. + /// + public IEnumerable ServiceUuid + { + get + { + return Uuid; + } + } + } + + /// + /// A class containing the information of Bluetooth device connection data. + /// + public class BluetoothDeviceConnectionData + { + internal string RemoteAddress; + internal BluetoothConnectionLinkType Link; + internal BluetoothDisconnectReason Reason; + + internal BluetoothDeviceConnectionData() + { + } + + /// + /// The device address. + /// + public string Address + { + get + { + return RemoteAddress; + } + } + /// + /// The type of the connection link. + /// + public BluetoothConnectionLinkType LinkType + { + get + { + return Link; + } + } + /// + /// The disconnect reason. + /// + public BluetoothDisconnectReason DisconnectReason + { + get + { + return Reason; + } + } + } + + /// + /// A class containing the information of track data. + /// + public class Track + { + /// + /// Default Constructor.Initializes an object of Track + /// + public Track() + { + } + + /// + /// Title of track. + /// + public string Title + { + get; + set; + } + /// + /// Artist of track. + /// + public string Artist + { + get; + set; + } + /// + /// Album of track. + /// + public string Album + { + get; + set; + } + /// + /// Genre of track. + /// + public string Genre + { + get; + set; + } + /// + /// Track number. + /// + public uint TrackNum + { + get; + set; + } + /// + /// Number of all tracks. + /// + public uint TotalTracks + { + get; + set; + } + /// + /// Duration of track in milliseconds. + /// + public uint Duration + { + get; + set; + } + } + + /// + [StructLayout(LayoutKind.Sequential)] + internal struct BluetoothLeScanDataStruct + { + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string RemoteAddress; + + internal BluetoothLeDeviceAddressType AddressType; + + internal int Rssi; + + internal int AdvDataLength; + + internal IntPtr AdvData; + + internal int ScanDataLength; + + internal IntPtr ScanData; + } + + /// + /// A class containing the information of Manufacturer data. + /// + public class ManufacturerData + { + /// + /// Default Constructor.Initializes an object of ManufacturerData + /// + public ManufacturerData() + { + } + + /// + /// The manufacturer id. + /// + public int Id + { + get; + set; + } + /// + /// The length of the manufacturer data. + /// + public int DataLength + { + get; + set; + } + /// + /// The manufacturer data. + /// + public byte[] Data + { + get; + set; + } + } + + internal class BluetoothLeScanData + { + internal string RemoteAddress + { + get; + set; + } + internal BluetoothLeDeviceAddressType AddressType + { + get; + set; + } + internal int Rssi + { + get; + set; + } + internal int AdvDataLength + { + get; + set; + } + internal byte[] AdvData + { + get; + set; + } + internal int ScanDataLength + { + get; + set; + } + internal byte[] ScanData + { + get; + set; + } + } + + internal struct BluetoothLeServiceDataStruct + { + /// + /// Bluetooth Le service uuid. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] + internal string ServiceUuid; + /// + /// Bluetooth Le service data + /// + [MarshalAs(UnmanagedType.LPStr)] + internal string ServiceData; + + internal int ServiceDataLength; + } + + /// + /// A class containing the information of Bluetooth service data. + /// + public class BluetoothServiceData + { + /// + /// Default Constructor.Initializes an object of BluetoothServiceData + /// + public BluetoothServiceData() + { + } + + /// + /// The Uuid of service. + /// + public string Uuid + { + get; + set; + } + /// + /// The data length of the service data. + /// + public int DataLength + { + get; + set; + } + /// + /// The service data. + /// + public byte[] Data + { + get; + set; + } + } + + /// + /// A class containing the service data information. + /// + public class BluetoothLeServiceData + { + internal string Uuid; + internal string Data; + internal int Length; + + internal BluetoothLeServiceData() + { + } + + /// + /// Bluetooth Le service uuid. + /// + public string ServiceUuid + { + get + { + return Uuid; + } + } + /// + /// Bluetooth Le service data + /// + public string ServiceData + { + get + { + return Data; + } + } + /// + /// The length of the service data. + /// + public int ServiceDataLength + { + get + { + return Length; + } + } + } + + /// + /// A class containing the information of Socket data. + /// + public class SocketData + { + internal string RecvData; + internal int Size; + internal int Fd; + + internal SocketData() + { + } + + /// + /// The socket fd. + /// + public int SocketFd + { + get + { + return Fd; + } + } + /// + /// The length of the received data. + /// + public int DataSize + { + get + { + return Size; + } + } + /// + /// The received data. + /// + public string Data + { + get + { + return RecvData; + } + } + } + + /// + /// A class containing the information of Socket connection. + /// + public class SocketConnection + { + internal string Uuid; + internal string RemoteAddress; + internal int Fd; + + internal SocketConnection() + { + } + + /// + /// The connected socket fd. + /// + public int SocketFd + { + get + { + return Fd; + } + } + /// + /// The remote device address. + /// + public string Address + { + get + { + return RemoteAddress; + } + } + /// + /// The service Uuid. + /// + public string ServiceUuid + { + get + { + return Uuid; + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothDevice.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothDevice.cs new file mode 100644 index 0000000..f589744 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothDevice.cs @@ -0,0 +1,673 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class which is used to handle the connection with other devices and set authorization of other devices.
+ /// The BluetoothDevice class is used to search for services available on remote devices. + ///
+ /// http://tizen.org/privilege/bluetooth + public class BluetoothDevice + { + private event EventHandler _bondCreated; + private event EventHandler _bondDestroyed; + private event EventHandler _authorizationChanged; + private event EventHandler _serviceSearched; + private event EventHandler _connectionChanged; + + private Interop.Bluetooth.BondCreatedCallback _bondCreatedCallback; + private Interop.Bluetooth.BondDestroyedCallback _bondDestroyedCallback; + private Interop.Bluetooth.AuthorizationChangedCallback _authorizationChangedCallback; + private Interop.Bluetooth.ServiceSearchedCallback _serviceSearchedCallback; + private Interop.Bluetooth.DeviceConnectionStateChangedCallback _connectionChangedCallback; + + internal string RemoteDeviceAddress; + internal string RemoteDeviceName; + internal int RemoteDeviceRssi; + internal BluetoothClass RemoteDeviceClass; + internal Collection RemoteDeviceService; + internal int RemoteDeviceCount; + internal bool RemotePaired; + internal bool RemoteAuthorized; + internal bool RemoteConnected; + internal BluetoothAppearanceType RemoteAppearance; + internal int RemoteManufLength; + internal string RemoteManufData; + + internal BluetoothDevice() + { + } + + /// + /// Address of device. + /// + public string Address + { + get + { + return RemoteDeviceAddress; + } + } + /// + /// Name of device. + /// + public string Name + { + get + { + return RemoteDeviceName; + } + } + /// + /// Strength indicator of received signal of device. + /// + public int Rssi + { + get + { + return RemoteDeviceRssi; + } + } + /// + /// Class of device. + /// + public BluetoothClass Class + { + get + { + return RemoteDeviceClass; + } + } + /// + /// Service UUID list of device. + /// + public IEnumerable ServiceUuidList + { + get + { + return RemoteDeviceService; + } + } + /// + /// The number of services. + /// + public int ServiceCount + { + get + { + return RemoteDeviceCount; + } + } + /// + /// The paired state of device. + /// + public bool IsPaired + { + get + { + return RemotePaired; + } + } + /// + /// The connection state of device. + /// + public bool IsConnected + { + get + { + return RemoteConnected; + } + } + /// + /// The authorization state of device. + /// + public bool IsAuthorized + { + get + { + return RemoteAuthorized; + } + } + /// + /// Bluetooth Appearance. + /// + public BluetoothAppearanceType AppearanceType + { + get + { + return RemoteAppearance; + } + } + + /// + /// The length of manufacturer data. + /// + public int ManufacturerDataLength + { + get + { + return RemoteManufLength; + } + } + /// + /// The manufacturer data. + /// + public string ManufacturerData + { + get + { + return RemoteManufData; + } + } + + /// + /// (event) BondCreated is raised when process of creating bond is finished. + /// + public event EventHandler BondCreated + { + add + { + if (_bondCreated == null) + { + RegisterBondCreatedEvent(); + } + _bondCreated += value; + } + remove + { + _bondCreated -= value; + if (_bondCreated == null) + { + UnregisterBondCreatedEvent(); + } + } + } + + /// + /// (event) BondDestroyed is raised when the bond is destroyed. + /// + public event EventHandler BondDestroyed + { + add + { + if (_bondDestroyed == null) + { + RegisterBondDestroyedEvent(); + } + _bondDestroyed += value; + } + remove + { + _bondDestroyed -= value; + if (_bondDestroyed == null) + { + UnregisterBondDestroyedEvent(); + } + } + } + + /// + /// (event) AuthorizationChanged is raised when the authorization of device is changed. + /// + public event EventHandler AuthorizationChanged + { + add + { + if (_authorizationChanged == null) + { + RegisterAuthorizationChangedEvent(); + } + _authorizationChanged += value; + } + remove + { + _authorizationChanged -= value; + if (_authorizationChanged == null) + { + UnregisterAuthorizationChangedEvent(); + } + } + } + + /// + /// (event) ServiceSearched is raised when the process of service searched is finished. + /// + public event EventHandler ServiceSearched + { + add + { + if (_serviceSearched == null) + { + RegisterServiceSearchedEvent(); + } + _serviceSearched += value; + } + remove + { + _serviceSearched -= value; + if (_serviceSearched == null) + { + UnregisterServiceSearchedEvent(); + } + } + } + + /// + /// (event) ConnectionStateChanged is raised when the connection state is changed. + /// + public event EventHandler ConnectionStateChanged + { + add + { + if (_connectionChanged == null) + { + RegisterConnectionChangedEvent(); + } + _connectionChanged += value; + } + remove + { + _connectionChanged -= value; + if (_connectionChanged == null) + { + UnregisterConnectionChangedEvent(); + } + } + } + + private void RegisterBondCreatedEvent() + { + _bondCreatedCallback = (int result, ref BluetoothDeviceStruct device, IntPtr userData) => + { + if (_bondCreated != null) + { + BluetoothError res = (BluetoothError)result; + _bondCreated(null, new BondCreatedEventArgs(res, BluetoothUtils.ConvertStructToDeviceClass(device))); + } + }; + int ret = Interop.Bluetooth.SetBondCreatedCallback(_bondCreatedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set bond created callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterBondCreatedEvent() + { + int ret = Interop.Bluetooth.UnsetBondCreatedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset bond created callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterBondDestroyedEvent() + { + _bondDestroyedCallback = (int result, string deviceAddress, IntPtr userData) => + { + if (_bondDestroyed != null) + { + BluetoothError res = (BluetoothError)result; + _bondDestroyed(null, new BondDestroyedEventArgs(res, deviceAddress)); + } + }; + int ret = Interop.Bluetooth.SetBondDestroyedCallback(_bondDestroyedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set bond destroyed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterBondDestroyedEvent() + { + int ret = Interop.Bluetooth.UnsetBondDestroyedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset bond destroyed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterServiceSearchedEvent() + { + _serviceSearchedCallback = (int result, ref BluetoothDeviceSdpStruct sdp, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Servicesearched cb is called"); + if (_serviceSearched != null) + { + BluetoothError res = (BluetoothError)result; + _serviceSearched(null, new ServiceSearchedEventArgs(res, BluetoothUtils.ConvertStructToSdpData(sdp))); + } + }; + int ret = Interop.Bluetooth.SetServiceSearchedCallback(_serviceSearchedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set service searched callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterServiceSearchedEvent() + { + int ret = Interop.Bluetooth.UnsetServiceSearchedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset service searched callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterAuthorizationChangedEvent() + { + _authorizationChangedCallback = (int authorization, string deviceAddress, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Authorization changed cb is called"); + if (_authorizationChanged != null) + { + BluetoothAuthorizationType auth = (BluetoothAuthorizationType)authorization; + _authorizationChanged(null, new AuthorizationChangedEventArgs(auth, deviceAddress)); + } + }; + int ret = Interop.Bluetooth.SetAuthorizationChangedCallback(_authorizationChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set authroization changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterAuthorizationChangedEvent() + { + int ret = Interop.Bluetooth.UnsetAuthorizationChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset authroization changed callback, Error - " + (BluetoothError)ret); + } + } + + private void RegisterConnectionChangedEvent() + { + _connectionChangedCallback = (bool connected, ref BluetoothDeviceConnectionStruct device, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Connection state changed cb is called"); + if (_connectionChanged != null) + { + _connectionChanged(null, new DeviceConnectionStateChangedEventArgs(connected, BluetoothUtils.ConvertStructToConnectionData(device))); + } + }; + + int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(_connectionChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (BluetoothError)ret); + } + } + + private void UnregisterConnectionChangedEvent() + { + int ret = Interop.Bluetooth.UnsetConnectionStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (BluetoothError)ret); + } + } + + /// + /// Creates a bond with remote Bluetooth device. + /// + /// + /// The Bluetooth must be enabled and remote device must be discoverable by StartDiscovery().The bond can be destroyed by DestroyBond(). + /// The bonding request can be cancelled by CancelBonding().If this succeeds, BondCreated event will be invoked. + /// + public void CreateBond() + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + int ret = Interop.Bluetooth.CreateBond(RemoteDeviceAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to create bond, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + /// + /// Cancels the bonding process. + /// + /// + /// Bonding must be in progress by CreateBond(). + /// + public void CancelBonding() + { + int ret = Interop.Bluetooth.CancelBonding(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to cancel bonding process, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + /// + /// Destroys the bond. + /// + /// + /// The Bluetooth must be enabled and the bond must be created by CreateBond(). + /// If this succeeds, BondDestroyed event will be invoked. + /// + public void DestroyBond() + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + int ret = Interop.Bluetooth.DestroyBond(RemoteDeviceAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to destroy bond, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + /// + /// Sets an alias for the bonded device. + /// + /// + /// The Bluetooth must be enabled and the bond must be created by CreateBond(). + /// + /// Alias name of remote device. + public void SetAlias(string aliasName) + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + int ret = Interop.Bluetooth.SetAlias(RemoteDeviceAddress, aliasName); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set alias name, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + /// + /// Sets the authorization of a bonded device. + /// + /// + /// The Bluetooth must be enabled and the bond must be created by CreateBond(). + /// If this succeeds, AuthorizationChanged event will be invoked. + /// + /// Authorization state. + public void SetAuthorization(BluetoothAuthorizationType authorizationState) + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + int ret = Interop.Bluetooth.SetAuthorization(RemoteDeviceAddress, (int)authorizationState); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set authroization state, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + /// + /// Gets the mask from UUID. + /// + /// The service mask list converted from the given UUID list. + /// Uuid list of the device. + public BluetoothServiceClassType GetMaskFromUuid(string[] uuids) + { + BluetoothServiceClassType serviceMask; + + int ret = Interop.Bluetooth.GetMaskFromUuid(uuids, uuids.Length, out serviceMask); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get service mask, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return serviceMask; + } + + /// + /// Starts the search for services supported by the specified device. + /// + /// + /// The Bluetooth must be enabled and remote device must be discoverable by StartDiscovery().The bond must be created by CreateBond(). + /// If this succeeds, ServiceSearched will be invoked. + /// + public void StartServiceSearch() + { + Log.Info(Globals.LogTag, "startservicesearch entry"); + if (BluetoothAdapter.IsBluetoothEnabled) + { + int ret = Interop.Bluetooth.StartServiceSearch(RemoteDeviceAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to start service search, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + + /// + /// Gets the connected profiles. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The connected Bluetooth profiles. + public IEnumerable GetConnectedProfiles() + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + List profileList = new List(); + Interop.Bluetooth.ConnectedProfileCallback callback = (int profile, IntPtr userData) => + { + if (!profile.Equals(null)) + { + profileList.Add((BluetoothProfileType)profile); + } + return true; + }; + int ret = Interop.Bluetooth.GetConnectedProfiles(RemoteDeviceAddress, callback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get connected profiles, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return profileList; + } + else + { + return null; + } + } + + /// + /// Determines if profile is connected to the specified remote device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// true if profile is connected; otherwise, false. + /// Bluetooth Profile type. + public bool IsProfileConnected(BluetoothProfileType profileType) + { + if (BluetoothAdapter.IsBluetoothEnabled) + { + bool isConnected; + int ret = Interop.Bluetooth.IsProfileConnected(RemoteDeviceAddress, (int)profileType, out isConnected); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get profile connected state, Error - " + (BluetoothError)ret); + } + return isConnected; + } + else + { + return false; + } + } + + /// + /// Returns the instance of Bluetooth profile type. + /// + /// + /// The Bluetooth must be enabled. + /// + public T GetProfile() where T : BluetoothProfile + { + /* + * FIXME: Find a proper way for dynamic allocation. + */ + T profile = null; + String type = typeof(T).ToString(); + if (type.Equals("Tizen.Network.Bluetooth.BluetoothAudio")) + { + BluetoothAudio audio = new BluetoothAudio(); + profile = (audio as T); + } + else if (type.Equals("Tizen.Network.Bluetooth.BluetoothAvrcp")) + { + BluetoothAvrcp avrcp = new BluetoothAvrcp(); + profile = (avrcp as T); + } + else if (type.Equals("Tizen.Network.Bluetooth.BluetoothHid")) + { + BluetoothHid hid = new BluetoothHid(); + profile = (hid as T); + } + profile.RemoteAddress = RemoteDeviceAddress; + return profile; + } + + /// + /// Creates the client socket. + /// + /// The IBluetoothClientSocket instance. + /// The UUID of service. + public IBluetoothClientSocket CreateSocket(string serviceUuid) + { + BluetoothSocket clientSocket = new BluetoothSocket(); + clientSocket.remoteAddress = this.Address; + clientSocket.serviceUuid = serviceUuid; + return (IBluetoothClientSocket)clientSocket; + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEnumerations.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEnumerations.cs new file mode 100644 index 0000000..6f4f107 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEnumerations.cs @@ -0,0 +1,1187 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using Tizen.Internals.Errors; + +namespace Tizen.Network.Bluetooth +{ + /// + /// Enumeration for Bluetooth state. + /// + public enum BluetoothState + { + /// + /// Disabled state. + /// + Disabled = 0, + /// + /// Enabled state. + /// + Enabled + } + + /// + /// Enumeration for Bluetooth errors. + /// + public enum BluetoothError + { + /// + /// Successful + /// + None = ErrorCode.None, + /// + /// Operation cancelled + /// + Cancelled = ErrorCode.Canceled, + /// + /// Invalid parameter + /// + InvalidParameter = ErrorCode.InvalidParameter, + /// + /// Out of memory + /// + OutOfMemory = ErrorCode.OutOfMemory, + /// + /// Device or resource busy + /// + ResourceBusy = ErrorCode.ResourceBusy, + /// + /// Timeout error + /// + TimedOut = ErrorCode.TimedOut, + /// + /// Operation now in progress + /// + NowInProgress = ErrorCode.NowInProgress, + /// + /// Bluetooth is Not Supported + /// + NotSupported = ErrorCode.NotSupported, + /// + /// Permission denied + /// + PermissionDenied = ErrorCode.PermissionDenied, + /// + /// Quota exceeded + /// + QuotaExceeded = ErrorCode.QuotaExceeded, + /// + /// No data available + /// + NoData = ErrorCode.NoData, + /// + /// Local adapter not initialized + /// + NotInitialized = -0x01C00000 | 0x0101, + /// + /// Local adapter not enabled + /// + NotEnabled = -0x01C00000 | 0x0102, + /// + /// Operation already done + /// + AlreadyDone = -0x01C00000 | 0x0103, + /// + /// Operation failed + /// + OperationFailed = -0x01C00000 | 0x0104, + /// + /// Operation not in progress + /// + NotInProgress = -0x01C00000 | 0x0105, + /// + /// Remote device not bonded + /// + RemoteDeviceNotBonded = -0x01C00000 | 0x0106, + /// + /// Authentication rejected + /// + AuthRejected = -0x01C00000 | 0x0107, + /// + /// Authentication failed + /// + AuthFailed = -0x01C00000 | 0x0108, + /// + /// Remote device not found + /// + RemoteDeviceNotFound = -0x01C00000 | 0x0109, + /// + /// Service search failed + /// + ServiceSearchFailed = -0x01C00000 | 0x010A, + /// + /// Remote device is not connected + /// + RemoteDeviceNotConnected = -0x01C00000 | 0x010B, + /// + /// Resource temporarily unavailable + /// + ResourceUnavailable = -0x01C00000 | 0x010C, + /// + /// Service Not Found + /// + ServiceNotFound = -0x01C00000 | 0x010D + } + + /// + /// Enumeration for Bluetooth visibility mode. + /// + public enum VisibilityMode + { + /// + /// Non discoverable mode. + /// + NonDiscoverable = 0, + /// + /// Discoverable mode. + /// + Discoverable = 1, + /// + /// Discoverable mode with limited time. + /// + TimeLimitedDiscoverable = 2 + } + + /// + /// Enumeration for Bluetooth major device class type. + /// + public enum BluetoothMajorDeviceClassType + { + /// + /// Miscellaneous major class type. + /// + Misc = 0x00, + /// + /// Computer major class type. + /// + Computer = 0x01, + /// + /// Phone major class type. + /// + Phone = 0x02, + /// + /// LAN/Network access point major class type. + /// + LanNetworkAccessPoint = 0x03, + /// + /// Audio/Video major class type. + /// + AudioVideo = 0x04, + /// + /// Peripheral major class type. + /// + Peripheral = 0x05, + /// + /// Imaging major class type. + /// + Imaging = 0x06, + /// + /// Wearable major class type. + /// + Wearable = 0x07, + /// + /// Toy major class type. + /// + Toy = 0x08, + /// + /// Health major class type. + /// + Health = 0x09, + /// + /// Uncategorized major class type. + /// + Uncategorized = 0x1F + } + + /// + /// Enumeration for Bluetooth minor device class type. + /// + public enum BluetoothMinorDeviceClassType + { + /// + /// Uncategorized computer minor class type. + /// + ComputerUncategorized = 0x00, + /// + /// Desktop workstation computer minor class type. + /// + ComputerDesktopWorkstation = 0x04, + /// + /// Server computer minor class type. + /// + ComputerServer = 0x08, + /// + /// Laptop computer minor class type. + /// + ComputerLaptop = 0x0C, + /// + /// Handheld PC/PDA computer minor class type. + /// + ComputerHandheldPcOrPda = 0x10, + /// + /// Palm sized PC/PDA computer minor class type. + /// + ComputerPalmSizedPcOrPda = 0x14, + /// + /// Wearable computer minor class type. + /// + ComputerWearableComputer = 0x18, + + /// + /// Unclassified phone minor class type. + /// + PhoneUncategorized = 0x00, + /// + /// Cellular phone minor class type. + /// + PhoneCellular = 0x04, + /// + /// Cordless phone minor class type. + /// + PhoneCordless = 0x08, + /// + /// SmartPhone phone minor class type. + /// + PhoneSmartPhone = 0x0C, + /// + /// Wired modem or voice gateway phone minor class type. + /// + PhoneWiredModemOrVoiceGateway = 0x10, + /// + /// ISDN phone minor class type. + /// + PhoneCommonIsdnAccess = 0x14, + + /// + /// Fully available LAN/Network access point minor class type. + /// + LanNetworkAccessPointFullyAvailable = 0x04, + /// + /// 1-17% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint1To17PercentUtilized = 0x20, + /// + /// 17-33% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint17To33PercentUtilized = 0x40, + /// + /// 33-50% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint33To50PercentUtilized = 0x60, + /// + /// 50-67% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint50To67PercentUtilized = 0x80, + /// + /// 67-83% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint67To83PercentUtilized = 0xA0, + /// + /// 83-99% utilized LAN/Network access point minor class type. + /// + LanNetworkAccessPoint83To99PercentUtilized = 0xC0, + /// + /// No service available LAN/Network access point minor class type. + /// + LanNetworkAccessPointNoServiceAvailable = 0xE0, + + /// + /// Uncategorized audio/video minor class type. + /// + AudioVideoUncategorized = 0x00, + /// + /// Wearable headset audio/video minor class type. + /// + AudioVideoWearableHeadset = 0x04, + /// + /// Hands free audio/video minor class type. + /// + AudioVideoHandsFree = 0x08, + /// + /// Microphone audio/video minor class type. + /// + AudioVideoMicrophone = 0x10, + /// + /// Loudspeaker audio/video minor class type. + /// + AudioVideoLoudspeaker = 0x14, + /// + /// Headphones audio/video minor class type. + /// + AudioVideoHeadphones = 0x18, + /// + /// Portable audio audio/video minor class type. + /// + AudioVideoPortableAudio = 0x1C, + /// + /// Car audio audio/video minor class type. + /// + AudioVideoCarAudio = 0x20, + /// + /// SetTopbox audio/video minor class type. + /// + AudioVideoSetTopBox = 0x24, + /// + /// Hifi audio audio/video minor class type. + /// + AudioVideoHifiAudioDevice = 0x28, + /// + /// VCR audio/video minor class type. + /// + AudioVideoVcr = 0x2C, + /// + /// Video camera audio/video minor class type. + /// + AudioVideoVideoCamera = 0x30, + /// + /// Camcorder audio/video minor class type. + /// + AudioVideoCamcorder = 0x34, + /// + /// Video monitor audio/video minor class type. + /// + AudioVideoVideoMonitor = 0x38, + /// + /// Video display and loudspeaker audio/video minor class type. + /// + AudioVideoVideoDisplayLoudspeaker = 0x3C, + /// + /// Video conferencing audio/video minor class type. + /// + AudioVideoVideoConferencing = 0x40, + /// + /// Gaming/toy audio/video minor class type. + /// + AudioVideoGamingToy = 0x48, + + /// + /// Uncategorized peripheral minor class type. + /// + PeripheralUncategorized = 0x00, + /// + /// Keyboard peripheral minor class type. + /// + PeripheralKeyBoard = 0x40, + /// + /// Pointing device peripheral minor class type. + /// + PeripheralPointingDevice = 0x80, + /// + /// Combo keyboard peripheral minor class type. + /// + PeripheralComboKeyboardPointingDevice = 0xC0, + /// + /// Joystick peripheral minor class type. + /// + PeripheralJoystick = 0x04, + /// + /// Game pad peripheral minor class type. + /// + PeripheralGamePad = 0x08, + /// + /// Remote control peripheral minor class type. + /// + PeripheralRemoteControl = 0x0C, + /// + /// Sensing device peripheral minor class type. + /// + PeripheralSensingDevice = 0x10, + /// + /// Digitizer peripheral minor class type. + /// + PeripheralDigitizerTablet = 0x14, + /// + /// Card reader peripheral minor class type. + /// + PeripheralCardReader = 0x18, + /// + /// Digital pen peripheral minor class type. + /// + PeripheralDigitalPen = 0x1C, + /// + /// Handheld scanner peripheral minor class type. + /// + PeripheralHandheldScanner = 0x20, + /// + /// Handheld gestural input computer minor class type. + /// + PeripheralHandheldGesturalInputDevice = 0x24, + + /// + /// Display imaging minor class type. + /// + ImagingDisplay = 0x10, + /// + /// Camera imaging minor class type. + /// + ImagingCamera = 0x20, + /// + /// Scanner imaging minor class type. + /// + ImagingScanner = 0x40, + /// + /// Printer imaging minor class type. + /// + ImagingPrinter = 0x80, + + /// + /// Wrist watch wearable minor class type. + /// + WearableWristWatch = 0x04, + /// + /// Pager wearable minor class type. + /// + WearablePager = 0x08, + /// + /// Jacket wearable minor class type. + /// + WearableJacket = 0x0C, + /// + /// Helmet wearable minor class type. + /// + WearableHelmet = 0x10, + /// + /// Glasses wearable minor class type. + /// + WearableGlasses = 0x14, + + /// + /// Robot toy minor class type. + /// + ToyRobot = 0x04, + /// + /// Vehicle toy minor class type. + /// + ToyVehicle = 0x08, + /// + /// Doll toy minor class type. + /// + ToyDollAction = 0x0C, + /// + /// Controller toy minor class type. + /// + ToyController = 0x10, + /// + /// Game toy minor class type. + /// + ToyGame = 0x14, + + /// + /// Uncategorized health minor class type. + /// + HealthUncategorized = 0x00, + /// + /// BP monitor health minor class type. + /// + HealthBloodPressureMonitor = 0x04, + /// + /// Thermometer health minor class type. + /// + HealthThermometer = 0x08, + /// + /// Scale health minor class type. + /// + HealthWeighingScale = 0x0C, + /// + /// Glucose meter health minor class type. + /// + HealthGlucoseMeter= 0x10, + /// + /// Pulse oximeter health minor class type. + /// + HealthPulseOximeter = 0x14, + /// + /// Heart/Pulse rate monitor health minor class type. + /// + HealthHeartPulseRateMonitor = 0x18, + /// + /// Display health minor class type. + /// + HealthDataDisplay = 0x1C, + /// + /// Step counter health minor class type. + /// + HealthStepCounter = 0x20, + /// + /// Body composition analyzer health minor class type. + /// + HealthBodyCompositionAnalyzer = 0x24, + /// + /// Peak flow monitor health minor class type. + /// + HealthPeakFlowMonitor = 0x28, + /// + /// Medication monitor health minor class type. + /// + HealthMedicationMonitor = 0x2C, + /// + /// Knee prosthesis health minor class type. + /// + HealthKneeProsthesis = 0x30, + /// + /// Ankle prosthesis health minor class type. + /// + HealthAnkleProsthesis = 0x34 + } + + /// + /// Enumeration for Bluetooth device discovery state. + /// + public enum BluetoothDeviceDiscoveryState + { + /// + /// Device discovery is started. + /// + Started = 0, + /// + /// Device discovery is finished. + /// + Finished, + /// + /// The remote device is found. + /// + Found + } + + /// + /// Enumeration for Bluetooth appearance type. + /// + public enum BluetoothAppearanceType + { + /// + /// Unknown. + /// + Unknown = 0, + /// + /// Generic phone. + /// + GenericPhone = 1, + /// + /// Generic computer. + /// + GenericComputer = 2, + /// + /// Generic watch. + /// + GenericWatch = 3 + } + + /// + /// Enumeration for Bluetooth audio profile type. + /// + public enum BluetoothAudioProfileType + { + /// + /// All supported profiles of audio. + /// + All = 0, + /// + /// Headset and Hands-Free profile. + /// + HspHfp, + /// + /// Advanced audio distribution profile. + /// + AdvancedAudioDistribution, + /// + /// Audio Gateway profile. + /// + AudioGateway, + /// + /// Advanced Audio Distribution profile sink role. + /// + AdvancedAudioDistributionSink + } + + /// + /// Enumeration for Bluetooth service class type. + /// + public enum BluetoothServiceClassType + { + /// + /// No service class. + /// + None = 0, + /// + /// Res service class. + /// + Res = 0x00000001, + /// + /// Spp service class. + /// + Spp = 0x00000002, + /// + /// Dun service class. + /// + Dun = 0x00000004, + /// + /// Fax service class. + /// + Fax = 0x00000008, + /// + /// Lap service class. + /// + Lap = 0x00000010, + /// + /// Hsp service class. + /// + Hsp = 0x00000020, + /// + /// Hfp service class. + /// + Hfp = 0x00000040, + /// + /// Opp service class. + /// + Opp = 0x00000080, + /// + /// Ftp service class. + /// + Ftp = 0x00000100, + /// + /// Ctp service class. + /// + Ctp = 0x00000200, + /// + /// Icp service class. + /// + Icp = 0x00000400, + /// + /// Sync service class. + /// + Sync = 0x00000800, + /// + /// Bpp service class. + /// + Bpp = 0x00001000, + /// + /// Bip service class. + /// + Bip = 0x00002000, + /// + /// Panu service class. + /// + Panu = 0x00004000, + /// + /// Nap service class. + /// + Nap = 0x00008000, + /// + /// Gn service class. + /// + Gn = 0x00010000, + /// + /// Sap service class. + /// + Sap = 0x00020000, + /// + /// A2dp service class. + /// + A2dp = 0x00040000, + /// + /// Avrcp service class. + /// + Avrcp = 0x00080000, + /// + /// Pbap service class. + /// + Pbap = 0x00100000, + /// + /// Hid service class. + /// + Hid = 0x00200000, + /// + /// A2dp Source service class. + /// + A2dpSource = 0x00400000, + /// + /// All service class. + /// + All = 0x00FFFFFF, + /// + /// Max service class. + /// + Max + } + + /// + /// Enumeration for Bluetooth profile type. + /// + public enum BluetoothProfileType + { + /// + /// Rfcomm profile. + /// + Rfcomm = 0, + /// + /// Advanced Audio Distribution Profile Source role + /// + AdvancedAudioDistribution, + /// + /// Headset profile. + /// + Headset, + /// + /// Human Interface Device profile. + /// + HumanInterfaceDevice, + /// + /// Network Access Point profile. + /// + NetworkAccessPoint, + /// + /// Audio Gateway profile. + /// + AudioGateway, + /// + /// Generic Attribute profile. + /// + GenericAttribute, + /// + /// Nap Server profile. + /// + NapServer, + /// + /// Advanced Audio Distribution profile sink role. + /// + AdvancedAudioDistributionSink + } + + /// + /// Enumeration for Bluetooth authorization type. + /// + public enum BluetoothAuthorizationType + { + /// + /// Authorized type. + /// + Authorized = 0, + /// + /// Unauthorized type. + /// + Unauthorized + } + + /// + /// Enumeration for Bluetooth connection link type. + /// + public enum BluetoothConnectionLinkType + { + /// + /// BR/EDR link. + /// + BrEdr = 0, + /// + /// LE link. + /// + Le, + /// + /// The default connection type. + /// + Default + } + + /// + /// Enumeration for Bluetooth disconnect reason. + /// + public enum BluetoothDisconnectReason + { + /// + /// Disconnected by unknown reason. + /// + Unknown = 0, + /// + /// Disconnected by timeout. + /// + Timeout, + /// + /// Disconnected by local host. + /// + LocalHost, + /// + /// Disconnected by remote. + /// + Remote + } + + /// + /// Enumerations of connected Bluetooth device event role. + /// + public enum BluetoothSocketRole + { + /// + /// Unknown role. + /// + Unknown, + /// + /// Server role. + /// + Server, + /// + /// Client role. + /// + Client + } + + /// + /// Enumerations of Bluetooth socket connection state. + /// + public enum BluetoothSocketState + { + /// + /// RFCOMM is connected. + /// + Connected, + /// + /// RFCOMM is disconnected. + /// + Disconnected + } + + /// + /// Enumeration for equalizer state. + /// + public enum EqualizerState + { + /// + /// Equalizer Off. + /// + Off = 0, + /// + /// Equalizer On. + /// + On + } + + /// + /// Enumeration for repeat mode. + /// + public enum RepeatMode + { + /// + /// Repeat off. + /// + Off = 0, + /// + /// Single track repeat. + /// + SingleTrack, + /// + /// All track repeat. + /// + AllTrack, + /// + /// Group repeat. + /// + Group + } + + /// + /// Enumeration for shuffle mode. + /// + public enum ShuffleMode + { + /// + /// Shuffle off. + /// + Off = 0, + /// + /// All tracks shuffle. + /// + AllTrack, + /// + /// Group shuffle. + /// + Group + } + + /// + /// Enumeration for scan mode. + /// + public enum ScanMode + { + /// + /// Scan off. + /// + Off = 0, + /// + /// All tracks scan. + /// + AllTrack, + /// + /// Group scan. + /// + Group + } + + /// + /// Enumeration for player state. + /// + public enum PlayerState + { + /// + /// Stopped state. + /// + Stopped = 0, + /// + /// Playing state. + /// + Playing, + /// + /// Paused state. + /// + Paused, + /// + /// Seek forward state. + /// + SeekForward, + /// + /// Seek rewind state. + /// + SeekRewind + } + + /// + /// Enumeration for Bluetooth Le device address type. + /// + public enum BluetoothLeDeviceAddressType + { + /// + /// The bluetooth le public address. + /// + BluetoothLePublicAddress, + /// + /// The bluetooth le private address. + /// + BluetoothLePrivateAddress + } + + /// + /// Enumeration for Bluetooth LePacket type. + /// + public enum BluetoothLePacketType + { + /// + /// The bluetooth le advertising packet. + /// + BluetoothLeAdvertisingPacket, + /// + /// The bluetooth le scan response packet. + /// + BluetoothLeScanResponsePacket + } + + /// + /// Enumeration for Bluetooth Le data type. + /// + public enum BluetoothLeDataType + { + /// + /// The bluetooth le packet data list 16 bit service uuid. + /// + BluetoothLePacketDataList16BitServiceUuid, + /// + /// The bluetooth le packet manufacturer data. + /// + BluetoothLePacketManufacturerData + } + + /// + /// Enumeration for Bluetooth Le Advertising mode type. + /// + public enum BluetoothLeAdvertisingMode + { + /// + /// The bluetooth le advertising balanced mode. + /// + BluetoothLeAdvertisingBalancedMode, + /// + /// The bluetooth le advertising low latency mode. + /// + BluetoothLeAdvertisingLowLatencyMode, + /// + /// The bluetooth le advertising low energy mode. + /// + BluetoothLeAdvertisingLowEnergyMode + } + + /// + /// Enumeration for Bluetooth Le Advertising mode type. + /// + public enum BluetoothLeAdvertisingState + { + /// + /// The bluetooth le advertising stopped. + /// + BluetoothLeAdvertisingStopped, + /// + /// The bluetooth le advertising started. + /// + BluetoothLeAdvertisingStarted + } + + /// + /// Enumerations of the integer type for GATT handle's value. + /// + public enum IntDataType + { + /// + /// 8 bit signed int type. + /// + SignedInt8, + /// + /// 16 bit signed int type. + /// + SignedInt16, + /// + /// 32 bit signed int type. + /// + SignedInt32, + /// + /// 8 bit unsigned int type. + /// + UnsignedInt8, + /// + /// 16 bit unsigned int type. + /// + UnsignedInt16, + /// + /// 32 bit unsigned int type. + /// + UnsignedInt32 + } + + /// + /// Enumerations of the float type for GATT handle's value. + /// + public enum FloatDataType + { + /// + /// 32 bit float type. + /// + Float, + /// + /// 16 bit float type. + /// + SFloat, + } + + /// + /// Enumerations of the GATT handle's type. + /// + public enum GattHandleType + { + /// + /// GATT service type. + /// + Service, + /// + /// GATT characteristic type. + /// + Characteristic, + /// + /// GATT descriptor type. + /// + Descriptor + } + + /// + /// Enumerations of the service type. + /// + public enum BluetoothGattServiceType + { + /// + /// GATT primary service type. + /// + Primary, + /// + /// GATT secondary service type. + /// + Secondary + } + + /// + /// Enumerations of the characteristic's property. + /// + [Flags] + public enum BluetoothGattProperty + { + /// + /// Broadcast property. + /// + Broadcast = 1, + /// + /// Read property. + /// + Read = 2, + /// + /// Write without response property. + /// + WriteWithoutResponse = 4, + /// + /// Write property. + /// + Write = 8, + /// + /// Notify property. + /// + Notify = 16, + /// + /// Indicate property. + /// + Indicate = 32, + /// + /// Authenticated signed writes property. + /// + AuthenticatedSignedWrites = 64, + /// + /// Extended properties. + /// + ExtendedProperties = 128, + } + + /// + /// Enumerations of bluetooth gatt permission type. + /// + [Flags] + public enum BluetoothGattPermission + { + /// + /// Read permission. + /// + Read = 1, + /// + /// Write permission. + /// + Write = 2, + } + + /// + /// Enumerations of the write type. + /// + public enum BluetoothGattWriteType + { + /// + /// Write without response. + /// + NoResponse, + /// + /// Write with response. + /// + WriteWithResponse + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothError.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothError.cs new file mode 100644 index 0000000..76ab207 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothError.cs @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + static internal class BluetoothErrorFactory + { + static internal void ThrowBluetoothException(int exception) + { + BluetoothError error = (BluetoothError)exception; + switch (error) + { + case BluetoothError.InvalidParameter: + throw new InvalidOperationException("Invalid parameter"); + + case BluetoothError.Cancelled: + throw new InvalidOperationException("Operation cancelled"); + + case BluetoothError.AlreadyDone: + throw new InvalidOperationException("Operation already done"); + + case BluetoothError.TimedOut: + throw new InvalidOperationException("Timeout error"); + + case BluetoothError.AuthFailed: + throw new InvalidOperationException("Authentication failed"); + + case BluetoothError.AuthRejected: + throw new InvalidOperationException("Authentication rejected"); + + case BluetoothError.NoData: + throw new InvalidOperationException("No data available"); + + case BluetoothError.NotEnabled: + throw new InvalidOperationException("Local adapter not enabled"); + + case BluetoothError.NotInitialized: + throw new InvalidOperationException("Local adapter not initialized"); + + case BluetoothError.NowInProgress: + throw new InvalidOperationException("Operation now in progress"); + + case BluetoothError.NotInProgress: + throw new InvalidOperationException("Operation not in progress"); + + case BluetoothError.NotSupported: + throw new InvalidOperationException("Bluetooth is not supported"); + + case BluetoothError.OperationFailed: + throw new InvalidOperationException("Operation failed"); + + case BluetoothError.OutOfMemory: + throw new InvalidOperationException("Out of memory"); + + case BluetoothError.PermissionDenied: + throw new InvalidOperationException("Permission denied"); + + case BluetoothError.QuotaExceeded: + throw new InvalidOperationException("Quota exceeded"); + + case BluetoothError.RemoteDeviceNotBonded: + throw new InvalidOperationException("Remote device not bonded"); + + case BluetoothError.RemoteDeviceNotConnected: + throw new InvalidOperationException("Remote device not connected"); + + case BluetoothError.RemoteDeviceNotFound: + throw new InvalidOperationException("Remote device not found"); + + case BluetoothError.ResourceBusy: + throw new InvalidOperationException("Device or resource busy"); + + case BluetoothError.ResourceUnavailable: + throw new InvalidOperationException("Resource temporarily unavailable"); + + case BluetoothError.ServiceNotFound: + throw new InvalidOperationException("Service Not Found"); + + case BluetoothError.ServiceSearchFailed: + throw new InvalidOperationException("Service search failed"); + + default: + throw new InvalidOperationException("Unknown exception"); + } + } + } +} + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEventArgs.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEventArgs.cs new file mode 100644 index 0000000..8c136d6 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothEventArgs.cs @@ -0,0 +1,1039 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Tizen.Network.Bluetooth +{ + /// + /// An extended EventArgs class which contains changed Bluetooth state. + /// + public class StateChangedEventArgs : EventArgs + { + private BluetoothState _type; + private BluetoothError _result; + + internal StateChangedEventArgs(BluetoothError result, BluetoothState type) + { + _type = type; + _result = result; + } + + /// + /// The state of Bluetooth. + /// + public BluetoothState BTState + { + get + { + return _type; + } + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth name. + /// + public class NameChangedEventArgs : EventArgs + { + private string _name; + + internal NameChangedEventArgs(string name) + { + _name = name; + } + + /// + /// The name of the device. + /// + public string DeviceName + { + get + { + return _name; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth visibility mode. + /// + public class VisibilityModeChangedEventArgs : EventArgs + { + private VisibilityMode _mode; + private BluetoothError _result; + + internal VisibilityModeChangedEventArgs(BluetoothError result, VisibilityMode mode) + { + _result = result; + _mode = mode; + } + + /// + /// The visibility mode. + /// + public VisibilityMode Visibility + { + get + { + return _mode; + } + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + } + + /// + /// An extended EventArgs class which contains the duration until the visibility mode is changed from TimeLimitedDiscoverable to NonDiscoverable. + /// + public class VisibilityDurationChangedEventArgs : EventArgs + { + private int _duration; + + internal VisibilityDurationChangedEventArgs(int duration) + { + _duration = duration; + } + + /// + /// The duration. + /// + public int Duration + { + get + { + return _duration; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth device discovery state and the discovered device information. + /// + public class DiscoveryStateChangedEventArgs : EventArgs + { + private BluetoothError _result; + private BluetoothDeviceDiscoveryState _state; + private BluetoothDevice _device; + + internal DiscoveryStateChangedEventArgs(BluetoothError result, BluetoothDeviceDiscoveryState state) + { + _result = result; + _state = state; + } + + internal DiscoveryStateChangedEventArgs(BluetoothError result, BluetoothDeviceDiscoveryState state, BluetoothDevice device) + { + _result = result; + _state = state; + _device = device; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + + /// + /// The state of the discovery. + /// + public BluetoothDeviceDiscoveryState DiscoveryState + { + get + { + return _state; + } + } + + /// + /// The remote device found. + /// + public BluetoothDevice DeviceFound + { + get + { + return _device; + } + } + } + + /// + /// An extended EventArgs class which contains the bonded device information. + /// + public class BondCreatedEventArgs : EventArgs + { + private BluetoothError _result; + private BluetoothDevice _device; + + internal BondCreatedEventArgs(BluetoothError result, BluetoothDevice device) + { + _result = result; + _device = device; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + + /// + /// The remote device. + /// + public BluetoothDevice Device + { + get + { + return _device; + } + } + } + + /// + /// An extended EventArgs class which contains the address of the remote Bluetooth device to destroy bond with. + /// + public class BondDestroyedEventArgs : EventArgs + { + private BluetoothError _result; + private string _address; + + internal BondDestroyedEventArgs(BluetoothError result, string address) + { + _result = result; + _address = address; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + + /// + /// The remote device address. + /// + /// The device address. + public string DeviceAddress + { + get + { + return _address; + } + } + } + + /// + /// An extended EventArgs class which contains the authorization state and address of the remote Bluetooth device. + /// + public class AuthorizationChangedEventArgs : EventArgs + { + private BluetoothAuthorizationType _authType; + private string _address; + + internal AuthorizationChangedEventArgs(BluetoothAuthorizationType authType, string address) + { + _authType = authType; + _address = address; + } + + /// + /// The authorization. + /// + public BluetoothAuthorizationType Authorization + { + get + { + return _authType; + } + } + + /// + /// The device address. + /// + public string DeviceAddress + { + get + { + return _address; + } + } + + } + + /// + /// An extended EventArgs class which contains the service lists found on the remote Bluetooth device. + /// + public class ServiceSearchedEventArgs : EventArgs + { + private BluetoothDeviceSdpData _sdpData; + private BluetoothError _result; + + internal ServiceSearchedEventArgs(BluetoothError result, BluetoothDeviceSdpData sdpData) + { + _result = result; + _sdpData = sdpData; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + /// + /// The sdp data. + /// + public BluetoothDeviceSdpData SdpData + { + get + { + return _sdpData; + } + } + } + + /// + /// An extended EventArgs class which contains the connection state and connection information of the remote device. + /// + public class DeviceConnectionStateChangedEventArgs : EventArgs + { + private bool _isConnected; + private BluetoothDeviceConnectionData _connectionData; + + internal DeviceConnectionStateChangedEventArgs(bool isConnected, BluetoothDeviceConnectionData connectionData) + { + _isConnected = isConnected; + _connectionData = connectionData; + } + + /// + /// A value indicating whether the device is connected. + /// + public bool IsConnected + { + get + { + return _isConnected; + } + } + + /// + /// The device connection data. + /// + public BluetoothDeviceConnectionData ConnectionData + { + get + { + return _connectionData; + } + } + } + + /// + /// An extended EventArgs class which contains data received information. + /// + public class SocketDataReceivedEventArgs : EventArgs + { + private SocketData _data; + + internal SocketDataReceivedEventArgs(SocketData data) + { + _data = data; + } + + /// + /// The socket data. + /// + public SocketData Data + { + get + { + return _data; + } + } + } + + /// + /// An extended EventArgs class which contains changed connection state. + /// + public class SocketConnectionStateChangedEventArgs : EventArgs + { + private BluetoothError _result; + private BluetoothSocketState _state; + private SocketConnection _connection; + + internal SocketConnectionStateChangedEventArgs(BluetoothError result, BluetoothSocketState state, SocketConnection connection) + { + _result = result; + _state = state; + _connection = connection; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + + /// + /// The socket state. + /// + public BluetoothSocketState State + { + get + { + return _state; + } + } + + /// + /// The socket connection. + /// + public SocketConnection Connection + { + get + { + return _connection; + } + } + } + + public class AcceptStateChangedEventArgs : EventArgs + { + private BluetoothError _result; + private BluetoothSocketState _state; + private SocketConnection _connection; + private IBluetoothServerSocket _server; + + internal AcceptStateChangedEventArgs(BluetoothError result, BluetoothSocketState state, SocketConnection connection, BluetoothSocket server) + { + _result = result; + _state = state; + _connection = connection; + _server = (IBluetoothServerSocket)server; + } + + /// + /// The BluetoothError result. + /// + public BluetoothError Result + { + get + { + return _result; + } + } + + /// + /// The socket state. + /// + public BluetoothSocketState State + { + get + { + return _state; + } + } + + /// + /// The socket connection. + /// + public SocketConnection Connection + { + get + { + return _connection; + } + } + + /// + /// The server socket instance. + /// + public IBluetoothServerSocket Server + { + get + { + return _server; + } + } + } + + /// + /// An extended EventArgs class which contains the connection state,remote address and the type of audio profile. + /// + public class AudioConnectionStateChangedEventArgs : EventArgs + { + private int _result; + private bool _isConnected; + private string _address; + private BluetoothAudioProfileType _type; + + internal AudioConnectionStateChangedEventArgs(int result, bool isConnected, string address, BluetoothAudioProfileType type) + { + _result = result; + _type = type; + _isConnected = isConnected; + _address = address; + } + + /// + /// The result. + /// + public int Result + { + get + { + return _result; + } + } + + /// + /// A value indicating whether this instance is connected. + /// + public bool IsConnected + { + get + { + return _isConnected; + } + } + + /// + /// The address. + /// + public string Address + { + get + { + return _address; + } + } + + /// + /// The type of the audio profile. + /// + public BluetoothAudioProfileType ProfileType + { + get + { + return _type; + } + } + } + + /// + /// An extended EventArgs class which contains the connection state and address of the remote Bluetooth device. + /// + public class HidConnectionStateChangedEventArgs : EventArgs + { + private int _result; + private bool _isConnected; + private string _address; + + internal HidConnectionStateChangedEventArgs(int result, bool isConnected, string address) + { + _result = result; + _isConnected = isConnected; + _address = address; + } + + /// + /// The result. + /// + public int Result + { + get + { + return _result; + } + } + + /// + /// A value indicating whether this instance is connected. + /// + public bool IsConnected + { + get + { + return _isConnected; + } + } + + /// + /// The address. + /// + public string Address + { + get + { + return _address; + } + } + } + + /// + /// An extended EventArgs class which contains the changed equalizer state. + /// + public class EqualizerStateChangedEventArgs : EventArgs + { + private EqualizerState _state; + + internal EqualizerStateChangedEventArgs(EqualizerState state) + { + _state = state; + } + + /// + /// The state of equalizer. + /// + public EqualizerState State + { + get + { + return _state; + } + } + } + + /// + /// An extended EventArgs class which contains the changed repeat mode. + /// + public class RepeatModeChangedEventArgs : EventArgs + { + private RepeatMode _mode; + + internal RepeatModeChangedEventArgs(RepeatMode mode) + { + _mode = mode; + } + + /// + /// The repeat mode. + /// + public RepeatMode Mode + { + get + { + return _mode; + } + } + } + + /// + /// An extended EventArgs class which contains the changed shuffle mode. + /// + public class ShuffleModeChangedeventArgs : EventArgs + { + private ShuffleMode _mode; + + internal ShuffleModeChangedeventArgs(ShuffleMode mode) + { + _mode = mode; + } + + /// + /// The shuffle mode. + /// + public ShuffleMode Mode + { + get + { + return _mode; + } + } + } + + /// + /// An extended EventArgs class which contains the changed scan mode. + /// + public class ScanModeChangedEventArgs : EventArgs + { + private ScanMode _mode; + + internal ScanModeChangedEventArgs(ScanMode mode) + { + _mode = mode; + } + + /// + /// The scan mode. + /// + public ScanMode Mode + { + get + { + return _mode; + } + } + } + + /// + /// An extended EventArgs class which contains the connection state and the remote device address. + /// + public class TargetConnectionStateChangedEventArgs : EventArgs + { + private bool _isConnected; + private string _address; + + internal TargetConnectionStateChangedEventArgs(bool isConnected, string address) + { + _isConnected = isConnected; + _address = address; + } + + /// + /// A value indicating whether this instance is connected. + /// + public bool IsConnected + { + get + { + return _isConnected; + } + } + + /// + /// The address. + /// + public string Address + { + get + { + return _address; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth LE advertising state changed information. + /// + public class AdvertisingStateChangedEventArgs : EventArgs + { + private BluetoothLeAdvertisingState _state; + private int _result; + private IntPtr _advertiserHandle; + + //TODO : Add conversion code from IntPtr to BluetoothLeAdvertiser class later + internal AdvertisingStateChangedEventArgs(int result, IntPtr advertiserHandle, + BluetoothLeAdvertisingState state) + { + _result = result; + _advertiserHandle = advertiserHandle; + _state = state; + } + + /// + /// The result. + /// + public int Result + { + get + { + return _result; + } + } + + /// + /// The advertiser handle. + /// + public IntPtr AdvertiserHandle + { + get + { + return _advertiserHandle; + } + } + + /// + /// The Le advertising state. + /// + public BluetoothLeAdvertisingState State + { + get + { + return _state; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth LE scan result information. + /// + public class AdapterLeScanResultChangedEventArgs : EventArgs + { + private BluetoothLeDevice _deviceData; + private int _result; + + internal AdapterLeScanResultChangedEventArgs(int result, BluetoothLeDevice deviceData) + { + _deviceData = deviceData; + _result = result; + } + + /// + /// The result. + /// + public int Result + { + get + { + return _result; + } + } + + /// + /// The Le device data. + /// + public BluetoothLeDevice DeviceData + { + get + { + return _deviceData; + } + } + } + + /// + /// An extended EventArgs class which contains changed Bluetooth LE GATT connection state. + /// + public class GattConnectionStateChangedEventArgs : EventArgs + { + private bool _isConnected; + private int _result; + private string _remoteAddress; + + internal GattConnectionStateChangedEventArgs(int result, bool connected, string remoteAddress) + { + _isConnected = connected; + _result = result; + _remoteAddress = remoteAddress; + } + + /// + /// The result. + /// + public int Result + { + get + { + return _result; + } + } + + /// + /// A value indicating whether this instance is connected. + /// + public bool IsConnected + { + get + { + return _isConnected; + } + } + + /// + /// The remote address. + /// + public string RemoteAddress + { + get + { + return _remoteAddress; + } + } + } + + /// + /// An extended EventArgs class which contains changed attribute value. + /// + public class ValueChangedEventArgs : EventArgs + { + internal ValueChangedEventArgs(byte[] value) + { + Value = value; + } + + /// + /// The attribute value. + /// + public byte[] Value { get; } + } + + /// + /// An extended EventArgs class which contains read value request data. + /// + public class ReadRequestedEventArgs : EventArgs + { + internal ReadRequestedEventArgs(BluetoothGattServer server, string clientAddress, int requestId, int offset) + { + Server = server; + ClientAddress = clientAddress; + RequestId = requestId; + Offset = offset; + } + + /// + /// The gatt server instance. + /// + public BluetoothGattServer Server { get; } + /// + /// The client address. + /// + public string ClientAddress { get; } + /// + /// The request identifier. + /// + public int RequestId { get; } + /// + /// The offset. + /// + public int Offset { get; } + } + + /// + /// An extended EventArgs class which contains read value request data. + /// + public class WriteRequestedEventArgs : EventArgs + { + internal WriteRequestedEventArgs(BluetoothGattServer server, string clientAddress, int requestId, byte[] value, int offset) + { + Server = server; + ClientAddress = clientAddress; + RequestId = requestId; + Value = value; + Offset = offset; + } + + /// + /// The gatt server instance. + /// + public BluetoothGattServer Server { get; } + /// + /// The client address. + /// + public string ClientAddress { get; } + /// + /// The request identifier. + /// + public int RequestId { get; } + /// + /// The read value. + /// + public byte[] Value { get; } + /// + /// The offset. + /// + public int Offset { get; } + } + + /// + /// An extended EventArgs class which contains client preference to enables or disables the Notification/Indication. + /// + public class NotificationStateChangedEventArg : EventArgs + { + internal NotificationStateChangedEventArg(BluetoothGattServer server, bool value) + { + Server = server; + Value = value; + } + + /// + /// The gatt server instance. + /// + public BluetoothGattServer Server { get; } + /// + /// A value indicating whether the notification is enabled + /// + public bool Value { get; } + } + + /// + /// An extended EventArgs class which contains read value request data. + /// + public class NotificationSentEventArg : EventArgs + { + internal NotificationSentEventArg(BluetoothGattServer server, string clientAddress, int result, bool completed) + { + Result = result; + ClientAddress = clientAddress; + Server = server; + Completed = completed; + } + + /// + /// The gatt server instance. + /// + public BluetoothGattServer Server { get; } + /// + /// The client address. + /// + public string ClientAddress { get; } + /// + /// The result. + /// + public int Result { get; } + /// + /// Gets a value indicating whether notification sent is completed. + /// + public bool Completed { get; } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGatt.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGatt.cs new file mode 100644 index 0000000..d059df8 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGatt.cs @@ -0,0 +1,916 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Tizen.Network.Bluetooth +{ + /// + /// Bluetooth GATT server + /// + public class BluetoothGattServer + { + private static BluetoothGattServer _instance; + private BluetoothGattServerImpl _impl; + + private BluetoothGattServer() + { + _impl = new BluetoothGattServerImpl(); + } + + /// + /// (event) called when indication acknowledgement received, once for each notified client + /// + public event EventHandler NotificationSent + { + add + { + _impl._notificationSent += value; + } + remove + { + _impl._notificationSent -= value; + } + } + + /// + /// Creates bluetooth gatt server + /// + /// + public static BluetoothGattServer CreateServer() + { + if (_instance == null) + { + BluetoothGattServer server = new BluetoothGattServer(); + if (server.IsValid()) + { + _instance = server; + } + } + return _instance; + } + + /// + /// Registers the server along with the GATT services of the application it is hosting + /// + public void Start() + { + _impl.Start(); + } + + /// + /// Registers a specified service to this server + /// + /// service, which needs to be registered with this server + public void RegisterGattService(BluetoothGattService service) + { + if (service.IsRegistered()) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter); + } + _impl.RegisterGattService(this, service); + } + + /// + /// Unregisters a specified service from this server + /// + /// service, which needs to be unregistered from this server + /// + /// Once unregistered, service object will become invalid and should not be used to access sevices's or any children attribute's methods/ members. + /// + public void UnregisterGattService(BluetoothGattService service) + { + if (service.GetGattServer() != this) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter); + } + + _impl.UnregisterGattService(service); + } + + /// + /// Unregisters all services from this server + /// + /// + /// Once unregistered, servicees will become invalid and should not be used to access sevices's or any children attribute's methods/ members. + /// + public void UnregisterGattServices() + { + _impl.UnregisterAllGattServices(this); + } + + /// + /// Gets service with given UUID that belongs to this server. + /// + /// UUID for the service to get + /// service with given uuid if it exists, null otherwise + public BluetoothGattService GetService(string uuid) + { + return _impl.GetService(this, uuid); + } + + /// + /// Gets list of services that belongs to this server. + /// + /// list of services that belongs to this server + public IEnumerable GetServices() + { + return _impl.GetServices(this); + } + + /// + /// Send indication for value change of the characteristic to the remote devices + /// + /// characteristic whose value is changes + /// Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled. + public async Task SendIndicationAsync(BluetoothGattCharacteristic characteristic, string clientAddress) + { + return await _impl.SendIndicationAsync(this, characteristic, clientAddress); + } + + /// + /// Send notification for value change of the characteristic to the remote devices + /// + /// characteristic The characteristic which has a changed value + /// Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled. + public void SendNotification(BluetoothGattCharacteristic characteristic, string clientAddress) + { + _impl.SendNotification(characteristic, clientAddress); + } + + /// + /// Sends a response to the remote device as a result of a read/ write request + /// + /// The identification of a read/ write request + /// error value in case of failure, 0 for success + /// Value to be sent + /// Fffset from where the value is read + public void SendResponse(int requestId, int status, byte[] value, int offset) + { + _impl.SendResponse(requestId, status, value, offset); + } + + internal bool IsValid() + { + return _impl.GetHandle().IsInvalid == false; + } + } + + /// + /// Bluetooth GATT client + /// + public class BluetoothGattClient + { + private BluetoothGattClientImpl _impl; + private string _remoteAddress = string.Empty; + + internal BluetoothGattClient(string remoteAddress) + { + _impl = new BluetoothGattClientImpl(remoteAddress); + _remoteAddress = remoteAddress; + } + + internal static BluetoothGattClient CreateClient(string remoteAddress) + { + BluetoothGattClient client = new BluetoothGattClient(remoteAddress); + return client.Isvalid() ? client : null; + } + + /// + /// Address of remote device. + /// + public string RemoteAddress + { + get + { + if (string.IsNullOrEmpty(_remoteAddress)) + { + _remoteAddress = _impl.GetRemoteAddress(); + } + return _remoteAddress; + } + } + + /// + /// Gets service with given UUID that belongs to this client. + /// + /// UUID for the service to get + /// service with given uuid if it exists, null otherwise + public BluetoothGattService GetService(string uuid) + { + return _impl.GetService(this, uuid); + } + + /// + /// Gets list of services that belongs to this client. + /// + /// list of services that belongs to this client + public IEnumerable GetServices() + { + return _impl.GetServices(this); + } + + /// + /// Reads the value of given characteristic from the remote device asynchronously. + /// + /// characteristic to be read + /// true on success, false otherwise + public async Task ReadValueAsync(BluetoothGattCharacteristic characteristic) + { + return await _impl.ReadValueAsyncTask(characteristic.GetHandle()); + } + + /// + /// Reads the value of given descriptor from the remote device asynchronously. + /// + /// descriptor to be read + /// true on success, false otherwise + public async Task ReadValueAsync(BluetoothGattDescriptor descriptor) + { + return await _impl.ReadValueAsyncTask(descriptor.GetHandle()); + } + + /// + /// Write value of given characteristic to remote device asynchronously. + /// + /// characteristic to be written + /// true on success, false otherwise + public async Task WriteValueAsync(BluetoothGattCharacteristic characteristic) + { + return await _impl.WriteValueAsyncTask(characteristic.GetHandle()); + } + + /// + /// Write value of given descriptor to remote device asynchronously. + /// + /// descriptor to be written + /// true on success, false otherwise + public async Task WriteValueAsync(BluetoothGattDescriptor descriptor) + { + return await _impl.WriteValueAsyncTask(descriptor.GetHandle()); + } + + internal bool Isvalid() + { + return _impl.GetHandle().IsInvalid == false; + } + } + + /// + /// Bluetooth GATT service + /// + public class BluetoothGattService + { + private BluetoothGattServiceImpl _impl; + private BluetoothGattClient _parentClient = null; + private BluetoothGattServer _parentServer = null; + private BluetoothGattService _parentService = null; + + /// + /// Constructor + /// + /// UUID of the service + /// type of service + public BluetoothGattService(string uuid, BluetoothGattServiceType type) + { + Uuid = uuid; + _impl = new BluetoothGattServiceImpl(uuid, type); + } + + internal BluetoothGattService(BluetoothGattServiceImpl impl, string uuid) + { + Uuid = uuid; + _impl = impl; + } + + /// + /// Specification name from the UUID + /// + public string Uuid { get; } + + /// + /// Adds a characteristic to this service + /// + /// characteristic to be added + /// true on success, false otherwise + public void AddCharacteristic(BluetoothGattCharacteristic characteristic) + { + if (GetGattClient() != null) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported); + } + + if (characteristic.GetService() != null) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter); + } + + _impl.AddCharacteristic(characteristic); + characteristic.SetParent(this); + } + + /// + /// Gets characteristic with given UUID that belongs to this service. + /// + /// UUID for the characteristic to get + /// characteristic with given uuid if it exists, null otherwise + public BluetoothGattCharacteristic GetCharacteristic(string uuid) + { + return _impl.GetCharacteristic(this, uuid); + } + + /// + /// Gets list of characteristic that belongs to this service. + /// + /// list of characteristic that belongs to this service + public IEnumerable GetCharacteristics() + { + return _impl.GetCharacteristics(this); + } + + /// + /// Includes a service to this service + /// + /// service to be included + /// true on success, false otherwise + public void AddService(BluetoothGattService service) + { + if (GetGattClient() != null) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported); + } + + if (service.IsRegistered()) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter); + } + + _impl.AddIncludeService(service); + service.SetParent(this); + } + + /// + /// UUID for the service to get + /// service with given uuid if it exists, null otherwise + public BluetoothGattService GetIncludeService(string uuid) + { + return _impl.GetIncludeService(this, uuid); + } + + /// + /// Gets included service list of this service. + /// + /// included service list of this service + public IEnumerable GetIncludeServices() + { + return _impl.GetIncludeServices(this); + } + + /// + /// Gets the server instance which the specified service belongs to. + /// + /// server instance which the specified service belongs to + public BluetoothGattServer GetGattServer() + { + return _parentServer; + } + + /// + /// Gets the client instance which the specified service belongs to. + /// + /// client instance which the specified service belongs to + public BluetoothGattClient GetGattClient() + { + return _parentClient; + } + + internal BluetoothGattAttributeHandle GetHandle() + { + return _impl.GetHandle(); + } + + internal void SetParent(BluetoothGattService parent) + { + if (!IsRegistered()) + { + _parentService = parent; + _impl.ReleaseHandleOwnership(); + } + } + + internal void SetParent(BluetoothGattClient parent) + { + if (!IsRegistered()) + { + _parentClient = parent; + _impl.ReleaseHandleOwnership(); + } + } + + internal void SetParent(BluetoothGattServer parent) + { + if (!IsRegistered()) + { + _parentServer = parent; + _impl.ReleaseHandleOwnership(); + } + } + + internal void UnregisterService() + { + _parentServer = null; + _parentClient = null; + _parentService = null; + } + + internal bool IsRegistered() + { + return _parentClient != null || _parentServer != null || _parentService != null; + } + } + + /// + /// Bluetooth GATT characteristic + /// + public class BluetoothGattCharacteristic : BluetoothGattAttribute + { + private BluetoothGattCharacteristicImpl _impl; + private BluetoothGattService _parent = null; + + private Interop.Bluetooth.BtClientCharacteristicValueChangedCallback _characteristicValueChangedCallback; + private Interop.Bluetooth.BtGattServerNotificationStateChangeCallback _notificationStateChangedCallback; + + private EventHandler _characteristicValueChanged; + internal EventHandler _notificationStateChanged; + + /// + /// Constructor + /// + /// UUID of the characterstic + /// Permissions for the characterstic + /// Properties set for the characterstic + /// Value associated with the characterstic + /// throws in case of internal error + public BluetoothGattCharacteristic(string uuid, BluetoothGattPermission permissions, BluetoothGattProperty properties, byte[] value) : base(uuid, permissions) + { + _impl = new BluetoothGattCharacteristicImpl(uuid, permissions, properties, value); + } + + internal BluetoothGattCharacteristic(BluetoothGattCharacteristicImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission) + { + _impl = impl; + } + + /// + /// (event) CharacteristicValueChanged is raised when server notifies for change in this characteristic value + /// + /// + /// Adding event handle on charateristic on server side will not have any effect + /// + public event EventHandler ValueChanged + { + add + { + if (Client != null) + { + if (_characteristicValueChanged == null) + { + _characteristicValueChangedCallback = (gattHandle, characteristicValue, len, userData) => + { + _characteristicValueChanged?.Invoke(this, new ValueChangedEventArgs(characteristicValue)); + }; + + _impl.SetCharacteristicValueChangedEvent(_characteristicValueChangedCallback); + } + _characteristicValueChanged = value; + } + } + remove + { + if (Client != null) + { + _characteristicValueChanged = null; + if (_characteristicValueChanged == null) + { + _impl.UnsetCharacteristicValueChangedEvent(); + } + + } + } + } + + /// + /// (event) NotificationStateChanged is called when client enables or disables the Notification/Indication for particular characteristics. + /// + /// + /// Adding event handle on charateristic on client side will not have any effect + /// + public event EventHandler NotificationStateChanged + { + add + { + if (Server != null) + { + if (_notificationStateChangedCallback == null) + { + _notificationStateChangedCallback = (notify, serverHandle, characteristicHandle, userData) => + { + _notificationStateChanged?.Invoke(this, new NotificationStateChangedEventArg(Server, notify)); + }; + + _impl.SetNotificationStateChangedEvent(_notificationStateChangedCallback); + } + + _notificationStateChanged = value; + } + } + remove + { + if (Server != null) + { + _notificationStateChanged = null; + // CAPI does not allow unsetting ReadValueRequestedEventCallback. + } + } + } + + /// + /// Property for this characteristic + /// + public BluetoothGattProperty Properties + { + get + { + return _impl.GetProperties(); + } + set + { + if (Server != null) + { + _impl.SetProperties(value); + } + } + } + + /// + /// Write type to be used for write operations + /// + public BluetoothGattWriteType WriteType + { + get + { + return _impl.GetWriteType(); + } + set + { + _impl.SetWriteType(value); + } + } + + internal override BluetoothGattClient Client + { + get + { + return _parent?.GetGattClient(); + } + } + + internal override BluetoothGattServer Server + { + get + { + return _parent?.GetGattServer(); + } + } + + internal override BluetoothGattAttributeImpl Impl + { + get + { + return _impl; + } + } + + /// + /// Adds a descriptor to this characteristic + /// + /// descriptor to be added + /// true on success, false otherwise + public void AddDescriptor(BluetoothGattDescriptor descriptor) + { + if (Client != null) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported); + } + + if (descriptor.GetCharacteristic() != null) + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter); + } + + _impl.AddDescriptor(descriptor); + descriptor.SetParent(this); + } + + /// + /// Gets descriptor with given UUID that belongs to this characteristic. + /// + /// UUID for the descriptor to get + /// descriptor with given uuid if it exists, null otherwise + public BluetoothGattDescriptor GetDescriptor(string uuid) + { + return _impl.GetDescriptor(this, uuid); + } + + /// + /// Gets list of descriptors that belongs to this characteristic. + /// + /// list of descriptors that belongs to this characteristic + public IEnumerable GetDescriptors() + { + return _impl.GetDescriptors(this); + } + + /// + /// Gets the service instance which the specified characterstic belongs to. + /// + /// characteristic instance, the specified characterstic belongs to. + public BluetoothGattService GetService() + { + return _parent; + } + + internal void SetParent(BluetoothGattService parent) + { + if (_parent == null) + { + _parent = parent; + ReleaseHandleOwnership(); + } + } + } + + /// + /// Bluetooth GATT descriptor + /// + public class BluetoothGattDescriptor : BluetoothGattAttribute + { + private BluetoothGattCharacteristic _parent = null; + private BluetoothGattDescriptorImpl _impl; + + /// + /// Constructor + /// + /// UUID of the descriptor + /// Permissions for the descriptor + /// Value associated with the descriptor + /// throws in case of internal error + public BluetoothGattDescriptor(string uuid, BluetoothGattPermission permisions, byte[] value) : base (uuid, permisions) + { + _impl = new BluetoothGattDescriptorImpl(uuid, permisions, value); + } + + internal BluetoothGattDescriptor(BluetoothGattDescriptorImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission) + { + _impl = impl; + } + + internal override BluetoothGattClient Client + { + get + { + return _parent?.Client; + } + } + + internal override BluetoothGattServer Server + { + get + { + return _parent?.Server; + } + } + + internal override BluetoothGattAttributeImpl Impl + { + get + { + return _impl; + } + } + + /// + /// Gets the characteristic instance which the specified descriptor belongs to. + /// + /// characteristic instance, the specified descriptor belongs to. + public BluetoothGattCharacteristic GetCharacteristic() + { + return _parent; + } + + internal void SetParent(BluetoothGattCharacteristic parent) + { + if (_parent == null) + { + _parent = parent; + ReleaseHandleOwnership(); + } + } + } + + /// + /// Bluetooth GATT attribute + /// + public abstract class BluetoothGattAttribute + { + private Interop.Bluetooth.BtGattServerReadValueRequestedCallback _readValueRequestedCallback; + private Interop.Bluetooth.BtGattServerWriteValueRequestedCallback _writeValueRequestedCallback; + + private EventHandler _readValueRequested; + private EventHandler _writeValueRequested; + + public BluetoothGattAttribute(string uuid, BluetoothGattPermission permission) + { + Uuid = uuid; + Permissions = permission; + } + + // Events + + /// + /// Event called when client request to read value of a characteristic or descriptor + /// + public event EventHandler ReadRequested + { + add + { + if (Server == null) return; + if (_readValueRequestedCallback == null) + { + _readValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, userData) => + { + _readValueRequested?.Invoke(this, new ReadRequestedEventArgs(Server, clientAddress, requestId, offset)); + }; + Impl.SetReadValueRequestedEventCallback(_readValueRequestedCallback); + } + _readValueRequested = value; + } + remove + { + if (Server == null) return; + _readValueRequested = null; + // CAPI does not allow unsetting ReadValueRequestedEventCallback. + } + } + + /// + /// Event called when a value of a characteristic or descriptor has been changed by a client + /// + public event EventHandler WriteRequested + { + add + { + if (Server == null) return; + if (_writeValueRequested == null) + { + _writeValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, valueToWrite, len, userData) => + { + _writeValueRequested?.Invoke(this, new WriteRequestedEventArgs(Server, clientAddress, requestId, valueToWrite, offset)); + }; + Impl.SetWriteValueRequestedEventCallback(_writeValueRequestedCallback); + } + _writeValueRequested = value; + } + remove + { + if (Server == null) return; + _writeValueRequested = null; + // CAPI does not allow unsetting ReadValueRequestedEventCallback. + } + } + + /// + /// Attribute's UUID + /// + public string Uuid { get; } + + /// + /// Permissions for this attribute + /// + public BluetoothGattPermission Permissions { get; } + + /// + /// Value of this descriptor + /// + public byte[] Value + { + get + { + return Impl.GetValue(); + } + set + { + Impl.SetValue(value); + } + } + + internal abstract BluetoothGattClient Client { get; } + internal abstract BluetoothGattServer Server { get; } + internal abstract BluetoothGattAttributeImpl Impl { get; } + + /// + /// Returns string value at specified offset + /// + /// + /// string value at specified offset + public string GetValue(int offset) + { + return Impl.GetValue(offset); + } + + /// + /// Sets string value as specified offset + /// + /// value to set + /// offset in the attribute value buffer + /// Throws excetion if (offset + size of string value) is greater then length of value buffer + public void SetValue(string value, int offset) + { + Impl.SetValue(value, offset); + } + + /// + /// Returns value at specified offset as int value of specified type + /// + /// type of int value + /// offset in the attribute value buffer + /// int value at given offset + /// Throws excetion if (offset + size of int value) is greater then length of value buffer + public int GetValue(IntDataType type, int offset) + { + return Impl.GetValue(type, offset); + } + + /// + /// Update Value at specified offset by int value of specified type + /// + /// type of int value + /// value to set + /// offset in the attribute value buffer + /// Throws excetion if (offset + size of int value) is greater then length of value buffer + public void SetValue(IntDataType type, int value, int offset) + { + Impl.SetValue(type, value, offset); + } + + /// + /// Returns value at specified offset as float value of specified type + /// + /// type of float value + /// offset in the attribute value buffer + /// float value at given offset + /// Throws excetion if (offset + size of float value) is greater then length of value buffer + public float GetValue(FloatDataType type, int offset) + { + return Impl.GetValue(type, offset); + } + + /// + /// Update Value at specified offset by float value of specified type + /// + /// type of float value + /// mantissa of float value + /// exponent of float value + /// offset in the attribute value buffer + /// Throws excetion if (offset + size of float value) is greater then length of value buffer + public void SetValue(FloatDataType type, int mantissa, int exponent, int offset) + { + Impl.SetValue(type, mantissa, exponent, offset); + } + + internal void ReleaseHandleOwnership() + { + Impl.ReleaseHandleOwnership(); + } + + internal BluetoothGattAttributeHandle GetHandle() + { + return Impl.GetHandle(); + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGattImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGattImpl.cs new file mode 100644 index 0000000..450169b --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothGattImpl.cs @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Tizen.Network.Bluetooth +{ + internal class BluetoothGattServerImpl + { + private BluetoothGattServerHandle _handle; + internal event EventHandler _notificationSent; + + internal BluetoothGattServerImpl() + { + int err = Interop.Bluetooth.BtGattServerInitialize(); + GattUtil.ThrowForError(err, "Failed to initialize server"); + + err = Interop.Bluetooth.BtGattServerCreate(out _handle); + GattUtil.ThrowForError(err, "Failed to create server"); + } + + internal void Start() + { + int err = Interop.Bluetooth.BtGattServerStart(); + GattUtil.ThrowForError(err, "Failed to start server"); + } + + internal void RegisterGattService(BluetoothGattServer server, BluetoothGattService service) + { + int err = Interop.Bluetooth.BtGattServerRegisterService(_handle, service.GetHandle()); + GattUtil.ThrowForError(err, "Failed to Register service"); + + service.SetParent(server); + } + + internal void UnregisterGattService(BluetoothGattService service) + { + int err = Interop.Bluetooth.BtGattServerUnregisterService(_handle, service.GetHandle()); + GattUtil.ThrowForError(err, "Failed to Unregister service"); + + service.UnregisterService(); + } + + internal void UnregisterAllGattServices(BluetoothGattServer server) + { + int err = Interop.Bluetooth.BtGattServerUnregisterAllServices(_handle); + GattUtil.ThrowForError(err, "Failed to Unregister all services"); + } + + internal BluetoothGattService GetService(BluetoothGattServer server, string uuid) + { + BluetoothGattAttributeHandle serviceHandle; + int err = Interop.Bluetooth.BtGattServerGetService(_handle, uuid, out serviceHandle); + if (err.IsFailed()) + { + GattUtil.Error(err, string.Format("Failed to get service with UUID ({0})", uuid)); + return null; + } + + BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(serviceHandle), uuid); ; + service.SetParent(server); + return service; + } + + internal IEnumerable GetServices(BluetoothGattServer server) + { + List attribututeList = new List(); + Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) => + { + BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false); + BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, ""); ; + if (service != null) + { + service.SetParent(server); + attribututeList.Add(service); + } + return true; + }; + + int err = Interop.Bluetooth.BtGattServerForeachServices(_handle, cb, IntPtr.Zero); + GattUtil.Error(err, "Failed to get all services"); + + return attribututeList; + } + + internal void SendResponse(int requestId, int status, byte[] value, int offset) + { + int err = Interop.Bluetooth.BtGattServerSendResponse(requestId, 0, offset, status, value, value.Length); + GattUtil.ThrowForError(err, string.Format("Failed to send response for request Id {0}", requestId)); + } + + internal void SendNotification(BluetoothGattCharacteristic characteristic, string clientAddress) + { + int err = Interop.Bluetooth.BtGattServerNotify(characteristic.GetHandle(), false, null, clientAddress, IntPtr.Zero); + GattUtil.ThrowForError(err, string.Format("Failed to send value changed notification for characteristic uuid {0}", characteristic.Uuid)); + } + + internal Task SendIndicationAsync(BluetoothGattServer server, BluetoothGattCharacteristic characteristic, string clientAddress) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + Interop.Bluetooth.BtGattServerNotificationSentCallback cb = (result, address, serverHandle, characteristicHandle, completed, userData) => + { + _notificationSent?.Invoke(characteristic, new NotificationSentEventArg(server, address, result, completed)); + if (completed) + { + tcs.SetResult(true); + } + }; + + int err = Interop.Bluetooth.BtGattServerNotify(characteristic.GetHandle(), true, cb, clientAddress, IntPtr.Zero); + GattUtil.ThrowForError(err, string.Format("Failed to send value changed indication for characteristic uuid {0}", characteristic.Uuid)); + + return tcs.Task; + } + + internal BluetoothGattServerHandle GetHandle() + { + return _handle; + } + } + + internal class BluetoothGattClientImpl + { + private BluetoothGattClientHandle _handle; + + internal BluetoothGattClientImpl(string remoteAddress) + { + int err = Interop.Bluetooth.BtGattClientCreate(remoteAddress, out _handle); + GattUtil.ThrowForError(err, "Failed to get native client handle"); + } + + internal string GetRemoteAddress() + { + string remoteAddress; + int err = Interop.Bluetooth.BtGattClientGetRemoteAddress(_handle, out remoteAddress); + GattUtil.ThrowForError(err, "Failed to get remote address for this client"); + + return remoteAddress; + } + + internal BluetoothGattService GetService(BluetoothGattClient client, string uuid) + { + BluetoothGattAttributeHandle serviceHandle; + int err = Interop.Bluetooth.BtGattClientGetService(_handle, uuid, out serviceHandle); + if (err.IsFailed()) + { + GattUtil.Error(err, string.Format("Failed to get service with UUID ({0})", uuid)); + return null; + } + + BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(serviceHandle), uuid); ; + service.SetParent(client); + return service; + } + + internal IEnumerable GetServices(BluetoothGattClient client) + { + List attribututeList = new List(); + Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) => + { + BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false); + BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, ""); + if (service != null) + { + service.SetParent(client); + attribututeList.Add(service); + } + return true; + }; + + int err = Interop.Bluetooth.BtGattClientForeachServices(_handle, cb, IntPtr.Zero); + GattUtil.Error(err, "Failed to get all services"); + + return attribututeList; + } + + internal Task ReadValueAsyncTask(BluetoothGattAttributeHandle handle) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) => + { + tcs.SetResult(true); + }; + + int err = Interop.Bluetooth.BtGattClientReadValue(handle, cb, IntPtr.Zero); + if (err.IsFailed()) + { + GattUtil.Error(err, "Failed to read value from remote device"); + tcs.SetResult(false); + BluetoothErrorFactory.ThrowBluetoothException(err); + } + return tcs.Task; + } + + internal Task WriteValueAsyncTask(BluetoothGattAttributeHandle handle) + { + TaskCompletionSource tcs = new TaskCompletionSource(); + Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) => + { + tcs.SetResult(true); + }; + + int err = Interop.Bluetooth.BtGattClientWriteValue(handle, cb, IntPtr.Zero); + if (err.IsFailed()) + { + GattUtil.Error(err, "Failed to write value to remote device"); + tcs.SetResult(false); + BluetoothErrorFactory.ThrowBluetoothException(err); + } + return tcs.Task; + } + + internal BluetoothGattClientHandle GetHandle() + { + return _handle; + } + } + + internal class BluetoothGattServiceImpl : BluetoothGattAttributeImpl + { + internal BluetoothGattServiceImpl(string uuid, BluetoothGattServiceType type) + { + int err = Interop.Bluetooth.BtGattServiceCreate(uuid, (int)type, out _handle); + GattUtil.ThrowForError(err, "Failed to get native service handle"); + } + + internal BluetoothGattServiceImpl(BluetoothGattAttributeHandle handle) + { + _handle = handle; + } + + internal static BluetoothGattService CreateBluetoothGattService(BluetoothGattAttributeHandle handle, string uuid) + { + if (uuid == "") + { + int err = Interop.Bluetooth.BtGattGetUuid(handle, out uuid); + GattUtil.ThrowForError(err, "Failed to get UUID"); + } + + BluetoothGattServiceImpl impl = new BluetoothGattServiceImpl(handle); + return new BluetoothGattService(impl, uuid); + } + + internal void AddCharacteristic(BluetoothGattCharacteristic characteristic) + { + int err = Interop.Bluetooth.BtGattServiceAddCharacteristic(_handle, characteristic.GetHandle()); + GattUtil.ThrowForError(err, string.Format("Failed to add characteristic with UUID ({0})", characteristic.Uuid)); + } + + internal BluetoothGattCharacteristic GetCharacteristic(BluetoothGattService service, string uuid) + { + BluetoothGattAttributeHandle attributeHandle; + int err = Interop.Bluetooth.BtGattServiceGetCharacteristic(_handle, uuid, out attributeHandle); + if (err.IsFailed()) + { + GattUtil.Error(err, string.Format("Failed to get Characteristic with UUID ({0})", uuid)); + return null; + } + + BluetoothGattCharacteristic Characteristic = BluetoothGattCharacteristicImpl.CreateBluetoothGattGattCharacteristic(attributeHandle, uuid); + Characteristic.SetParent(service); + return Characteristic; + } + + internal IEnumerable GetCharacteristics(BluetoothGattService service) + { + List attribututeList = new List(); + Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) => + { + BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false); + BluetoothGattCharacteristic Characteristic = BluetoothGattCharacteristicImpl.CreateBluetoothGattGattCharacteristic(handle, ""); + if (Characteristic != null) + { + Characteristic.SetParent(service); + attribututeList.Add(Characteristic); + } + return true; + }; + + int err = Interop.Bluetooth.BtGattServiceForeachCharacteristics(service.GetHandle(), cb, IntPtr.Zero); + GattUtil.Error(err, "Failed to get all Characteristic"); + + return attribututeList; + } + + internal void AddIncludeService(BluetoothGattService includedService) + { + int err = Interop.Bluetooth.BtGattServiceAddIncludedService(_handle, includedService.GetHandle()); + GattUtil.ThrowForError(err, string.Format("Failed to add service with UUID ({0})", includedService.Uuid)); + } + + internal BluetoothGattService GetIncludeService(BluetoothGattService parentService, string uuid) + { + BluetoothGattAttributeHandle attributeHandle; + int err = Interop.Bluetooth.BtGattServiceGetIncludedService(_handle, uuid, out attributeHandle); + if (err.IsFailed()) + { + GattUtil.Error(err, string.Format("Failed to get included service with UUID ({0})", uuid)); + return null; + } + + BluetoothGattService service = new BluetoothGattService(new BluetoothGattServiceImpl(attributeHandle), uuid); + service.SetParent(parentService); + return service; + } + + internal IEnumerable GetIncludeServices(BluetoothGattService parentService) + { + List attribututeList = new List(); + Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) => + { + BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false); + BluetoothGattService service = BluetoothGattServiceImpl.CreateBluetoothGattService(handle, ""); + if (service != null) + { + service.SetParent(parentService); + attribututeList.Add(service); + } + return true; + }; + + int err = Interop.Bluetooth.BtGattServiceForeachIncludedServices(parentService.GetHandle(), cb, IntPtr.Zero); + GattUtil.Error(err, "Failed to get all services"); + + return attribututeList; + } + } + + internal class BluetoothGattCharacteristicImpl : BluetoothGattAttributeImpl + { + internal BluetoothGattCharacteristicImpl(string uuid, BluetoothGattPermission permission, BluetoothGattProperty property, byte[] value) + { + int err = Interop.Bluetooth.BtGattCharacteristicCreate(uuid, (int)permission, (int)property, value, value.Length, out _handle); + GattUtil.ThrowForError(err, "Failed to get native characteristic handle"); + } + + internal BluetoothGattCharacteristicImpl(BluetoothGattAttributeHandle handle) + { + _handle = handle; + } + + internal static BluetoothGattCharacteristic CreateBluetoothGattGattCharacteristic(BluetoothGattAttributeHandle handle, string uuid) + { + int permission; + int err = Interop.Bluetooth.BtGattCharacteristicGetPermissions(handle, out permission); + GattUtil.ThrowForError(err, "Failed to get permissions"); + + if (uuid == "") + { + err = Interop.Bluetooth.BtGattGetUuid(handle, out uuid); + GattUtil.ThrowForError(err, "Failed to get UUID"); + } + + BluetoothGattCharacteristicImpl impl = new BluetoothGattCharacteristicImpl(handle); + return new BluetoothGattCharacteristic(impl, uuid, (BluetoothGattPermission)permission); + } + + internal void SetCharacteristicValueChangedEvent(Interop.Bluetooth.BtClientCharacteristicValueChangedCallback callback) + { + int err = Interop.Bluetooth.BtGattClientSetCharacteristicValueChangedCallback(_handle, callback, IntPtr.Zero); + GattUtil.Error(err, "Failed to set client characteristic value changed callback"); + } + + internal void UnsetCharacteristicValueChangedEvent() + { + int err = Interop.Bluetooth.BtGattClientUnsetCharacteristicValueChangedCallback(_handle); + GattUtil.Error(err, "Failed to unset client characteristic value changed callback"); + } + + internal void SetNotificationStateChangedEvent(Interop.Bluetooth.BtGattServerNotificationStateChangeCallback callback) + { + int err = Interop.Bluetooth.BtGattServeSetNotificationStateChangeCallback(_handle, callback, IntPtr.Zero); + GattUtil.Error(err, "Failed to set characteristic notification state changed callback"); + } + + internal BluetoothGattProperty GetProperties() + { + int properties = 0 ; + int err = Interop.Bluetooth.BtGattCharacteristicGetProperties(_handle, out properties); + GattUtil.Error(err, "Failed to get characteristic properties"); + return (BluetoothGattProperty)properties; + } + + internal void SetProperties(BluetoothGattProperty perperties) + { + int err = Interop.Bluetooth.BtGattCharacteristicSetProperties(_handle, (int)perperties); + GattUtil.Error(err, "Failed to set characteristic properties"); + } + + internal BluetoothGattWriteType GetWriteType() + { + int writeType; + int err = Interop.Bluetooth.BtGattCharacteristicGetWriteType(_handle, out writeType); + GattUtil.Error(err, "Failed to get characteristic writetype"); + return (BluetoothGattWriteType) writeType; + } + + internal void SetWriteType(BluetoothGattWriteType writeType) + { + int err = Interop.Bluetooth.BtGattCharacteristicSetWriteType(_handle, (int)writeType); + GattUtil.Error(err, "Failed to get characteristic writetype"); + } + + internal void AddDescriptor(BluetoothGattDescriptor descriptor) + { + int err = Interop.Bluetooth.BtGattCharacteristicAddDescriptor(_handle, descriptor.GetHandle()); + GattUtil.ThrowForError(err, string.Format("Failed to add descriptor with UUID ({0})", descriptor.Uuid)); + } + + internal BluetoothGattDescriptor GetDescriptor(BluetoothGattCharacteristic characteristic, string uuid) + { + BluetoothGattAttributeHandle handle; + int err = Interop.Bluetooth.BtGattCharacteristicGetDescriptor(_handle, uuid, out handle); + if (err.IsFailed()) + { + GattUtil.Error(err, string.Format("Failed to get descriptor with UUID ({0})", uuid)); + return null; + } + BluetoothGattDescriptor descriptor = BluetoothGattDescriptorImpl.CreateBluetoothGattDescriptor(handle, uuid); + descriptor.SetParent(characteristic); + return descriptor; + } + + internal IEnumerable GetDescriptors(BluetoothGattCharacteristic characteristic) + { + List attribututeList = new List(); + Interop.Bluetooth.BtGattForeachCallback cb = (total, index, attributeHandle, userData) => + { + BluetoothGattAttributeHandle handle = new BluetoothGattAttributeHandle(attributeHandle, false); + BluetoothGattDescriptor descriptor = BluetoothGattDescriptorImpl.CreateBluetoothGattDescriptor(handle, ""); + if (descriptor != null) + { + descriptor.SetParent(characteristic); + attribututeList.Add(descriptor); + } + return true; + }; + + int err = Interop.Bluetooth.BtGattCharacteristicForeachDescriptors(characteristic.GetHandle(), cb, IntPtr.Zero); + GattUtil.Error(err, "Failed to get all descriptor"); + + return attribututeList; + } + } + + internal class BluetoothGattDescriptorImpl : BluetoothGattAttributeImpl + { + internal BluetoothGattDescriptorImpl(string uuid, BluetoothGattPermission permission, byte[] value) + { + int err = Interop.Bluetooth.BtGattDescriptorCreate(uuid, (int)permission, value, value.Length, out _handle); + GattUtil.ThrowForError(err, "Failed to get native descriptor handle"); + } + + internal BluetoothGattDescriptorImpl(BluetoothGattAttributeHandle handle) + { + _handle = handle; + } + + internal static BluetoothGattDescriptor CreateBluetoothGattDescriptor(BluetoothGattAttributeHandle handle, string uuid) + { + int permission; + int err = Interop.Bluetooth.BtGattDescriptorGetPermissions(handle, out permission); + GattUtil.ThrowForError(err, string.Format("Failed to get permissions with UUID ({0})", uuid)); + + if (uuid == "") + { + int ret = Interop.Bluetooth.BtGattGetUuid(handle, out uuid); + GattUtil.ThrowForError(ret, "Failed to get UUID"); + } + + BluetoothGattDescriptorImpl impl = new BluetoothGattDescriptorImpl(handle); + return new BluetoothGattDescriptor(impl, uuid, (BluetoothGattPermission)permission); + } + } + + internal abstract class BluetoothGattAttributeImpl + { + protected BluetoothGattAttributeHandle _handle; + + internal string GetUuid() + { + string uuid; + int err = Interop.Bluetooth.BtGattGetUuid(_handle, out uuid); + GattUtil.Error(err, "Failed to get attribute uuid"); + + return uuid; + } + + internal byte[] GetValue() + { + IntPtr nativeValue; + int nativeValueLength; + int err = Interop.Bluetooth.BtGattGetValue(_handle, out nativeValue, out nativeValueLength); + GattUtil.Error(err, "Failed to get attribute value"); + + return GattUtil.IntPtrToByteArray(nativeValue, nativeValueLength); + } + + internal void SetValue(byte[] value) + { + int err = Interop.Bluetooth.BtGattSetValue(_handle, value, value.Length); + GattUtil.ThrowForError(err, "Failed to set attribute value"); + } + + internal string GetValue(int offset) + { + byte[] value = GetValue(); + + int nullPos = value.Length - offset; + for (int i = offset; i < value.Length; ++i) + { + if (value[i] == '\0') + { + nullPos = i; + break; + } + } + + string strValue = ""; + strValue = Encoding.UTF8.GetString(value, offset, nullPos - offset); + return strValue; + } + + internal void SetValue(string value, int offset) + { + byte[] byteValue = GetValue(); + byte[] strValue = Encoding.UTF8.GetBytes(value); + int length = offset + strValue.Length; + if (length >= byteValue.Length) + { + GattUtil.ThrowForError((int)BluetoothError.InvalidParameter, "Can not fit value to buffer"); + } + + Buffer.BlockCopy(strValue, 0, byteValue, offset, strValue.Length); + byteValue[length] = (byte)'\0'; + SetValue(byteValue); + } + + internal int GetValue(IntDataType type, int offset) + { + int value; + int err = Interop.Bluetooth.BtGattGetIntValue(_handle, (int)type, offset, out value); + GattUtil.Error(err, "Failed to get attribute int value at offset"); + return value; + } + + internal void SetValue(IntDataType type, int value, int offset) + { + int err = Interop.Bluetooth.BtGattSetIntValue(_handle, (int)type, value, offset); + GattUtil.ThrowForError(err, "Failed to set attribute int value at offset"); + } + + internal float GetValue(FloatDataType type, int offset) + { + float value; + int err = Interop.Bluetooth.BtGattGetFloatValue(_handle, (int)type, offset, out value); + GattUtil.Error(err, "Failed to get attribute float value at offset"); + return value; + } + + internal void SetValue(FloatDataType type, int mantissa, int exponent, int offset) + { + int err = Interop.Bluetooth.BtGattSetFloatValue(_handle, (int)type, mantissa, exponent, offset); + GattUtil.ThrowForError(err, "Failed to set attribute float value at offset"); + } + + internal void SetReadValueRequestedEventCallback(Interop.Bluetooth.BtGattServerReadValueRequestedCallback callback) + { + int err = Interop.Bluetooth.BtGattServerSetReadValueRequestedCallback(_handle, callback, IntPtr.Zero); + GattUtil.ThrowForError(err, "Failed to set attribute read value requested callback"); + } + + internal void SetWriteValueRequestedEventCallback(Interop.Bluetooth.BtGattServerWriteValueRequestedCallback callback) + { + int err = Interop.Bluetooth.BtGattServerSetWriteValueRequestedCallback(_handle, callback, IntPtr.Zero); + GattUtil.ThrowForError(err, "Failed to set attribute write value requested callback"); + } + + internal BluetoothGattAttributeHandle GetHandle() + { + return _handle; + } + + internal void ReleaseHandleOwnership() + { + _handle.ReleaseOwnership(); + } + } + + + internal class BluetoothGattAttributeHandle : BluetoothGattHandle + { + public BluetoothGattAttributeHandle(IntPtr nativeHandle, bool hasOwnership) : base(nativeHandle, hasOwnership) + { + } + + public BluetoothGattAttributeHandle() + { + } + + protected override bool ReleaseHandle() + { + if (_hasOwnership == true) + { + Interop.Bluetooth.BtGattDestroy(handle); + } + SetHandle(IntPtr.Zero); + return true; + } + } + + internal class BluetoothGattClientHandle : BluetoothGattHandle + { + protected override bool ReleaseHandle() + { + if (_hasOwnership == true) + { + Interop.Bluetooth.BtGattClientDestroy(handle); + Interop.Bluetooth.BtGattServerDeinitialize(); + } + SetHandle(IntPtr.Zero); + return true; + } + } + + internal class BluetoothGattServerHandle : BluetoothGattHandle + { + protected override bool ReleaseHandle() + { + if (_hasOwnership == true) + { + Interop.Bluetooth.BtGattServerDestroy(handle); + } + SetHandle(IntPtr.Zero); + return true; + } + } + + internal abstract class BluetoothGattHandle : SafeHandle + { + protected bool _hasOwnership; + + public BluetoothGattHandle() : base(IntPtr.Zero, true) + { + _hasOwnership = true; + } + + public BluetoothGattHandle(IntPtr nativeHandle, bool hasOwnership) : base(nativeHandle, true) + { + _hasOwnership = hasOwnership; + } + + public override bool IsInvalid + { + get { return handle == IntPtr.Zero; } + } + + public void ReleaseOwnership() + { + _hasOwnership = false; + } + } + + internal static class GattUtil + { + internal static byte[] IntPtrToByteArray(IntPtr nativeValue, int lenght) + { + byte[] value = new byte[lenght]; + if (nativeValue != IntPtr.Zero) + { + Marshal.Copy(nativeValue, value, 0, lenght); + } + return value; + } + + internal static void Error(int err, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0) + { + if (err.IsFailed()) + { + Log.Error(Globals.LogTag, string.Format("{0}, err: {1}", message, (BluetoothError)err), file, func, line); + } + } + + internal static void ThrowForError(int err, string message, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0) + { + if (err.IsFailed()) + { + Log.Error(Globals.LogTag, string.Format("{0}, err: {1}", message, (BluetoothError)err), file, func, line); + BluetoothErrorFactory.ThrowBluetoothException(err); + } + } + + internal static bool IsFailed(this int err) + { + return err != (int)BluetoothError.None; + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHid.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHid.cs new file mode 100644 index 0000000..e546dd1 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHid.cs @@ -0,0 +1,75 @@ +using System; + +namespace Tizen.Network.Bluetooth +{ + /// + /// A class which is used to handle the connection to Bluetooth HID like keyboards and mouse. + /// + /// http://tizen.org/privilege/bluetooth + public class BluetoothHid : BluetoothProfile + { + internal BluetoothHid() + { + } + + /// + /// (event) HidConnectionStateChanged is called when hid host connection state is changed. + /// + public event EventHandler HidConnectionStateChanged + { + add + { + BluetoothHidImpl.Instance.HidConnectionStateChanged += value; + } + remove + { + BluetoothHidImpl.Instance.HidConnectionStateChanged -= value; + } + } + + /// + /// Connect the remote device with the Hid service. + /// + /// + /// The device must be bonded with remote device by CreateBond(). + /// If connection request succeeds, HidConnectionStateChanged event will be invoked. + /// + public void Connect() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothHidImpl.Instance.Connect(RemoteAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to Connect - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Disconnects the remote device with the Hid service. + /// + public void Disconnect() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothHidImpl.Instance.Disconnect(RemoteAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to Disconnect - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } +} + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHidImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHidImpl.cs new file mode 100644 index 0000000..b8a9122 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothHidImpl.cs @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Tizen.Network.Bluetooth +{ + internal class BluetoothHidImpl : IDisposable + { + private event EventHandler _hidConnectionChanged; + private Interop.Bluetooth.HidConnectionStateChangedCallback _hidConnectionChangedCallback; + + private static readonly BluetoothHidImpl _instance = new BluetoothHidImpl(); + private bool disposed = false; + + internal event EventHandler HidConnectionStateChanged + { + add + { + _hidConnectionChanged += value; + } + remove + { + //nothing to be done + } + } + + internal int Connect(string deviceAddress) + { + if (Globals.IsHidInitialize) + { + int ret = Interop.Bluetooth.Connect (deviceAddress); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to connect device with the hid service, Error - " + (BluetoothError)ret); + } + return ret; + } + return (int)BluetoothError.NotInitialized; + } + + internal int Disconnect(string deviceAddress) + { + if (Globals.IsHidInitialize) + { + int ret = Interop.Bluetooth.Disconnect (deviceAddress); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to disconnect device with the hid service, Error - " + (BluetoothError)ret); + } + return ret; + } + return (int)BluetoothError.NotInitialized; + } + + internal static BluetoothHidImpl Instance + { + get + { + return _instance; + } + } + private BluetoothHidImpl () + { + initialize(); + } + ~BluetoothHidImpl() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + deinitialize(); + disposed = true; + } + + private void initialize() + { + if (Globals.IsInitialize) + { + _hidConnectionChangedCallback = (int result, bool connected, string deviceAddress, IntPtr userData) => + { + if (_hidConnectionChanged != null) + { + _hidConnectionChanged(null, new HidConnectionStateChangedEventArgs(result, connected, deviceAddress)); + } + }; + + int ret = Interop.Bluetooth.InitializeHid (_hidConnectionChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to initialize bluetooth hid, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + else + { + Globals.IsHidInitialize = true; + } + } + else + { + Log.Error(Globals.LogTag, "Failed to initialize HID, BT not initialized"); + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized); + } + } + + private void deinitialize() + { + if (Globals.IsHidInitialize) + { + int ret = Interop.Bluetooth.DeinitializeHid (); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth hid, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } else { + Globals.IsHidInitialize = false; + } + } + } + } +} + diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapter.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapter.cs new file mode 100644 index 0000000..92c3355 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapter.cs @@ -0,0 +1,765 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth { + + /// + /// This class is BluetoothLeAdvertiser. Handles the Le Advertising operation amd callback. + /// + public class BluetoothLeAdvertiser + { + private static readonly BluetoothLeAdvertiser _instance = new BluetoothLeAdvertiser(); + + internal static BluetoothLeAdvertiser Instance + { + get + { + return _instance; + } + } + + private BluetoothLeAdvertiser() + { + } + + /// + /// Event that is called when the LE advertising state changes + /// + public event EventHandler AdvertisingStateChanged + { + add + { + BluetoothLeImplAdapter.Instance.AdapterLeAdvertisingStateChanged += value; + } + remove + { + BluetoothLeImplAdapter.Instance.AdapterLeAdvertisingStateChanged -= value; + } + } + /// + /// Start advertising using the advertisedata object. + /// + /// + /// Bluetooth must be enabled. + /// + /// The advertiser object carrying information of the advertising. + public void StartAdvertising(BluetoothLeAdvertiseData advertiseData) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.StartAdvertising (advertiseData.GetHandle ()); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to start advertising- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Stops the advertising. + /// + /// + /// Bluetooth must be enabled. + /// + /// The advertiser object carrying information of the advertising. + public void StopAdvertising(BluetoothLeAdvertiseData advertiseData) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.StopAdvertising (advertiseData.GetHandle ()); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to stop advertising operation- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } + + /// + /// This class is BluetoothLeDevice. + /// Handles the Le device operations like getting data from the scan result information. + /// + public class BluetoothLeDevice + { + //properties of Bluetoothlesacandata + private string _remoteAddress; + private BluetoothLeDeviceAddressType _addressType; + private int _rssi; + private byte[] _advDataValue; + private byte[] _scanDataValue; + private BluetoothLePacketType _packetType; + private BluetoothLeScanData _scanData; + + /// + /// Event that is called when the Gatt client connects/disconnects with the server + /// + public event EventHandler GattConnectionStateChanged + { + add + { + BluetoothLeImplAdapter.Instance.LeGattConnectionStateChanged += value; + } + remove + { + BluetoothLeImplAdapter.Instance.LeGattConnectionStateChanged -= value; + } + } + + internal BluetoothLeDevice(BluetoothLeScanData scanData) + { + _scanData = new BluetoothLeScanData (); + _scanData = scanData; + + Log.Info (Globals.LogTag, "scanData.Rssi" + _scanData.Rssi); + _rssi = scanData.Rssi; + Log.Info (Globals.LogTag, "scanData.RemoteAddress" + _scanData.RemoteAddress); + if (scanData.RemoteAddress != null) + _remoteAddress = scanData.RemoteAddress; + Log.Info (Globals.LogTag, "scanData.AddressType" + _scanData.AddressType); + _addressType = scanData.AddressType; + Log.Info (Globals.LogTag, "scanData.AdvData" + _scanData.AdvData); + _advDataValue = new byte[_scanData.AdvDataLength]; + scanData.AdvData.CopyTo(_advDataValue, 0); + Log.Info (Globals.LogTag, "scanData.ScanData" + _scanData.ScanData); + _scanDataValue = new byte[_scanData.ScanDataLength]; + scanData.ScanData.CopyTo(_scanDataValue, 0); + } + + ~BluetoothLeDevice() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + BluetoothLeImplAdapter.Instance.FreeServiceDataList(); + } + } + + /// + /// The remote address. + /// + public string RemoteAddress + { + get + { + return _remoteAddress; + } + } + + /// + /// The type of the address. + /// + public BluetoothLeDeviceAddressType AddressType + { + get + { + return _addressType; + } + } + + /// + /// The rssi value. + /// + public int Rssi + { + get + { + return _rssi; + } + } + + /// + /// The advertsing data information. + /// + public byte[] AdvertsingDataInformation + { + get + { + return _advDataValue; + } + } + + /// + /// The scan data information. + /// + public byte[] ScanDataInformation + { + get + { + return _scanDataValue; + } + } + + /// + /// The type of the packet. + /// + public BluetoothLePacketType PacketType + { + get + { + return _packetType; + } + set + { + _packetType = value; + } + } + + /// + /// Get service uuids list from the Le scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns list of string service uuids. + public IEnumerable ServiceUuid + { + get + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + Log.Info(Globals.LogTag, "Retrieving Service uuid- "); + return BluetoothLeImplAdapter.Instance.GetLeScanResultServiceUuids(_scanData, _packetType); + } + return null; + } + } + + /// + /// Get device name from the Le scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns device name. + public string DeviceName + { + get + { + Log.Info(Globals.LogTag, "Retrieving device name- "); + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetLeScanResultDeviceName(_scanData, _packetType); + } + return null; + } + } + /// + /// Get transmission power level from the Le scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns the transmission power level in dB. + public int TxPowerLevel + { + get + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetScanResultTxPowerLevel(_scanData, _packetType); + } + return -1; + } + } + + /// + /// Get service solicitation uuid list from the scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns list of service solicitation uuids. + public IEnumerable ServiceSolictationUuid + { + get + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetScanResultSvcSolicitationUuids(_scanData, _packetType); + } + return null; + } + } + /// + /// Gets the manufacturer data from the scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns the appearance value. + public int Appearance + { + get + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetScanResultAppearance(_scanData, _packetType); + } + return -1; + } + } + /// + /// Gets the manufacturer data from the scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns the manufacturer data containing the manucturer data and id information. + public ManufacturerData ManufacturerData + { + get + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetScanResultManufacturerData(_scanData, _packetType); + } + return null; + } + } + + /// + /// Get service data list from the scan result information + /// + /// + /// The Bluetooth must be enabled. + /// + /// Returns the service data list. + public IEnumerable GetServiceDataList() + { + int serviceCount = 0; + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + return BluetoothLeImplAdapter.Instance.GetScanResultServiceDataList(_scanData, + _packetType, out serviceCount); + } + return null; + } + + + /// + /// Creates a GATT connection with the remote device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The auto connect flag + /// client instance + public BluetoothGattClient GattConnect(bool autoConnect) + { + BluetoothGattClient client = null; + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.GattConnect (_remoteAddress, autoConnect); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to create GATT Connection with remote device- " + (BluetoothError)ret); + } + else + { + client = BluetoothGattClient.CreateClient(_remoteAddress); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + return client; + } + + /// + /// Disconnect a GATT connection with the remote device. + /// + /// + /// The Bluetooth must be enabled. + /// + public void GattDisconnect() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = BluetoothLeImplAdapter.Instance.GattDisconnect (_remoteAddress); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to disconnect GATT connection with remote device- " + (BluetoothError)ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } + + /// + /// Bluetooth le advertise data. Handles the data advertising. + /// + public class BluetoothLeAdvertiseData:IDisposable + { + private IntPtr _handle = IntPtr.Zero; + private BluetoothLeAdvertisingMode _mode; + private bool _advertisingConnectable; + private BluetoothLePacketType _packetType; + private int _appearance; + private bool _includePowerLevel; + private bool _includeDeviceName; + + /// + /// Default Constructor.Initializes an object of BluetoothLeAdvertiseData + /// + public BluetoothLeAdvertiseData() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + Log.Debug(Globals.LogTag, " Creating LeAdvertiser()"); + int ret = Interop.Bluetooth.CreateAdvertiser(out _handle); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to create advertiser object- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + ~BluetoothLeAdvertiseData() + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + //clean-up + ClearAdvertisingData (BluetoothLePacketType.BluetoothLeAdvertisingPacket); + ClearAdvertisingData (BluetoothLePacketType.BluetoothLeScanResponsePacket); + BluetoothLeImplAdapter.Instance.DestroyAdvertiser (_handle); + } + Dispose(false); + } + + internal IntPtr GetHandle() + { + return _handle; + } + + /// + /// The advertising mode to control the advertising power and latency. + /// + /// + /// The Bluetooth must be enabled. + /// + public BluetoothLeAdvertisingMode AdvertisingMode + { + get + { + return _mode; + } + set + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + _mode = value; + int ret = Interop.Bluetooth.SetAdvertisingMode (GetHandle (), _mode); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to set advertising mode- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + } + } + } + + /// + /// The advertising connectable type. + /// + /// + /// The Bluetooth must be enabled. + /// + public bool AdvertisingConnectable + { + get + { + return _advertisingConnectable; + } + set + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + _advertisingConnectable = value; + int ret = Interop.Bluetooth.SetAdvertisingConnectable (GetHandle (), _advertisingConnectable); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to set advertising connectable value- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + } + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + //todo... + } + + /// + /// The type of the packet. + /// + public BluetoothLePacketType PacketType + { + get + { + return _packetType; + } + set + { + _packetType = value; + } + } + /// + /// Sets the external appearance of this device to advertise or scan response data + /// Please refer to the adopted Bluetooth specification for the the appearance.. + /// + /// + /// The Bluetooth must be enabled. + /// + public int Appearance + { + get + { + return _appearance; + } + set + { + _appearance = value; + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) { + int ret = Interop.Bluetooth.SetAdvertisingAppearance (GetHandle (), _packetType, _appearance); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to add appearance value to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + } + /// + /// Sets whether the device name has to be incuded in the advertise or scan response data + /// The maximum advertised or responded data size is 31 bytes including data type and system wide data. + /// + /// + /// The Bluetooth must be enabled. + /// + public bool IncludeDeviceName + { + get + { + return _includeDeviceName; + } + set + { + _includeDeviceName = value; + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = Interop.Bluetooth.SetAdvertisingDeviceName(GetHandle(), _packetType, _includeDeviceName); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to add device name to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + } + } + + + /// + /// Set whether the transmission power level should be included in advertise or scan response data. + /// The maximum advertised or responded data size is 31 bytes including data type and system wide data. + /// + /// + /// The Bluetooth must be enabled. + /// + public bool IncludeTxPowerLevel + { + get + { + return _includePowerLevel; + } + set + { + _includePowerLevel = value; + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = Interop.Bluetooth.SetAdvertisingTxPowerLevel(GetHandle(), _packetType, _includePowerLevel); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to add advertising service solicitation uuid- " + (BluetoothError)ret); + } + } + } + } + /// + /// Add a service UUID to advertise or scan response data. + /// The maximum advertised or responded data size is 31 bytes + /// including data type and system wide data + /// + /// + /// The Bluetooth must be enabled. + /// + /// The packet type + /// The service uuid to add to advertise data + public void AddAdvertisingServiceUuid(BluetoothLePacketType packetType, string serviceUuid) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = Interop.Bluetooth.AddAdvertisingServiceUuid (GetHandle (), packetType, serviceUuid); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to add service uuid to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Add a service solicitation UUID to advertise or scan response data. + /// The maximum advertised or responded data size is 31 bytes + /// including data type and system wide data. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The packet type + /// The service solicitation uuid to add to advertise data + public void AddAdvertisingServiceSolicitationUuid(BluetoothLePacketType packetType, + string serviceSolicitationUuid) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = Interop.Bluetooth.AddAdvertisingServiceSolicitationUuid(GetHandle(), packetType, + serviceSolicitationUuid); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to add service solicitation uuid to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Add a service data to advertise or scan response data. + /// The maximum advertised or responded data size is 31 bytes + /// including data type and system wide data. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The packet type + /// The service data to be added to advertising + public void AddAdvertisingServiceData(BluetoothLePacketType packetType, BluetoothServiceData data) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + IntPtr serviceDataPtr; + serviceDataPtr = Marshal.AllocHGlobal(data.DataLength); + Marshal.Copy(data.Data, 0, serviceDataPtr, data.DataLength); + + for (int i = 0; i < 3; i++) + Log.Error (Globals.LogTag, " service data is " + data.Data [i]); + int ret = Interop.Bluetooth.AddAdvertisingServiceData(GetHandle(), packetType, + data.Uuid, serviceDataPtr, data.DataLength); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to add service data to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Add manufacturer specific data to advertise or scan response data. + /// Please refer to the adopted Bluetooth specification for the the appearance.. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The packet type + /// The manufacturer specific data + public void AddAdvertisingManufacturerData(BluetoothLePacketType packetType, + ManufacturerData manufacturerData) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + IntPtr manufDataPtr; + manufDataPtr = Marshal.AllocHGlobal(manufacturerData.DataLength); + Marshal.Copy(manufacturerData.Data, 0, manufDataPtr, manufacturerData.DataLength); + + int ret = Interop.Bluetooth.AddAdvertisingManufData(GetHandle(), packetType, + manufacturerData.Id, manufDataPtr, manufacturerData.DataLength); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to add service solicitation uuid to advertising data- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + + /// + /// Clear all data to be advertised or responded to scan request from LE scanning device. + /// + /// + /// The Bluetooth must be enabled. + /// + /// The packet type to be cleared + internal void ClearAdvertisingData(BluetoothLePacketType packetType) + { + if (BluetoothAdapter.IsBluetoothEnabled && Globals.IsInitialize) + { + int ret = Interop.Bluetooth.ClearAdvertisingData (GetHandle (), packetType); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to Clear Advertising Data- " + (BluetoothError)ret); + } + } + else + { + BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotEnabled); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapterImpl.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapterImpl.cs new file mode 100644 index 0000000..ae098cf --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothLeAdapterImpl.cs @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading.Tasks; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth +{ + internal class BluetoothLeImplAdapter : IDisposable + { + private static readonly BluetoothLeImplAdapter _instance = new BluetoothLeImplAdapter(); + + private bool disposed = false; + + private event EventHandler _adapterLeScanResultChanged = null; + private Interop.Bluetooth.AdapterLeScanResultChangedCallBack _adapterLeScanResultChangedCallback; + + private event EventHandler _advertisingStateChanged = null; + private Interop.Bluetooth.AdvertisingStateChangedCallBack _advertisingStateChangedCallback; + + private event EventHandler _gattConnectionStateChanged = null; + private Interop.Bluetooth.GattConnectionStateChangedCallBack _gattConnectionStateChangedCallback; + + private int _serviceListCount = 0; + private IList _list = new List(); + private bool _scanStarted; + + internal static BluetoothLeImplAdapter Instance + { + get + { + return _instance; + } + } + + private BluetoothLeImplAdapter() + { + } + + ~BluetoothLeImplAdapter() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + if (_gattConnectionStateChanged != null) + { + UnRegisterGattConnectionStateChangedEvent(); + } + + //stop scan operation in progress + StopScan (); + + disposed = true; + } + + internal event EventHandler AdapterLeScanResultChanged + { + add + { + _adapterLeScanResultChanged += value; + } + remove { + _adapterLeScanResultChanged -= value; + } + } + + internal event EventHandler AdapterLeAdvertisingStateChanged + { + add + { + _advertisingStateChanged += value; + } + remove + { + _advertisingStateChanged -= value; + } + } + + internal event EventHandler LeGattConnectionStateChanged + { + add + { + if (_gattConnectionStateChanged == null) + { + RegisterGattConnectionStateChangedEvent(); + } + _gattConnectionStateChanged += value; + } + remove + { + _gattConnectionStateChanged -= value; + if (_gattConnectionStateChanged == null) + { + UnRegisterGattConnectionStateChangedEvent(); + } + } + } + + internal void RegisterGattConnectionStateChangedEvent() + { + _gattConnectionStateChangedCallback = (int result, bool connected, + string remoteDeviceAddress, IntPtr userData) => + { + if (_gattConnectionStateChanged != null) + { + Log.Info(Globals.LogTag, "Setting gatt connection state changed callback" ); + GattConnectionStateChangedEventArgs e = new GattConnectionStateChangedEventArgs (result, + connected, remoteDeviceAddress); + + _gattConnectionStateChanged(null, e); + } + }; + + int ret = Interop.Bluetooth.SetGattConnectionStateChangedCallback( + _gattConnectionStateChangedCallback, IntPtr.Zero); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set gatt connection state changed callback, Error - " + (BluetoothError)ret); + } + } + + internal void UnRegisterGattConnectionStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetGattConnectionStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset gatt connection state changed callback, Error - " + (BluetoothError)ret); + } + } + + internal int StartScan() + { + _adapterLeScanResultChangedCallback = (int result, ref BluetoothLeScanDataStruct scanData, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Inside scan callback " ); + BluetoothLeScanData scanDataInfo = new BluetoothLeScanData(); + scanDataInfo = BluetoothUtils.ConvertStructToLeScanData(scanData, scanDataInfo); + + BluetoothLeDevice device = new BluetoothLeDevice(scanDataInfo); + + AdapterLeScanResultChangedEventArgs e = new AdapterLeScanResultChangedEventArgs (result, + device); + _adapterLeScanResultChanged (null, e); + }; + + IntPtr data = IntPtr.Zero; + int ret = Interop.Bluetooth.StartScan(_adapterLeScanResultChangedCallback, data); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to start BLE scan - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + _scanStarted = true; + return ret; + } + + internal int StopScan() + { + int ret = (int)BluetoothError.None; + + if (_scanStarted) + { + ret = Interop.Bluetooth.StopScan (); + if (ret != (int)BluetoothError.None) { + Log.Error (Globals.LogTag, "Failed to stop BLE scan - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException (ret); + } + } + return ret; + } + + internal IList GetLeScanResultServiceUuids(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + IntPtr uuidListArray = IntPtr.Zero; + int count = -1; + + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct.RemoteAddress = scanData.RemoteAddress; + scanDataStruct.AddressType = scanData.AddressType; + scanDataStruct.Rssi = scanData.Rssi; + scanDataStruct.AdvDataLength = scanData.AdvDataLength; + + scanDataStruct.AdvData = Marshal.AllocHGlobal(scanData.AdvDataLength); + Marshal.Copy (scanData.AdvData, 0, scanDataStruct.AdvData, scanData.AdvDataLength); + + scanDataStruct.ScanDataLength = scanData.ScanDataLength; + scanDataStruct.ScanData = Marshal.AllocHGlobal(scanData.ScanDataLength); + Marshal.Copy (scanData.ScanData, 0, scanDataStruct.ScanData, scanData.ScanDataLength); + + int ret = Interop.Bluetooth.GetScanResultServiceUuid(ref scanDataStruct, packetType, + ref uuidListArray, ref count); + if (ret != (int)BluetoothError.None) + { + Log.Info(Globals.LogTag, "Failed to service uuids list- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + Log.Info(Globals.LogTag, "count of uuids : " + count); + + IntPtr[] uuidList = new IntPtr[count]; + Marshal.Copy(uuidListArray, uuidList, 0, count); + IList list = new List(); + foreach(IntPtr uuids in uuidList) + { + list.Add(Marshal.PtrToStringAnsi(uuids)); + Interop.Libc.Free(uuids); + } + + Interop.Libc.Free(uuidListArray); + return list; + } + + internal string GetLeScanResultDeviceName(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + string deviceName; + + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + int ret = Interop.Bluetooth.GetLeScanResultDeviceName(ref scanDataStruct, packetType, out deviceName); + if (ret != (int)BluetoothError.None) { + Log.Error(Globals.LogTag, "Failed to get Device name- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + Log.Info (Globals.LogTag, "Device name " + deviceName); + return deviceName; + } + + internal int GetScanResultTxPowerLevel(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + int powerLevel; + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + int ret = Interop.Bluetooth.GetScanResultTxPowerLevel(ref scanDataStruct, packetType, out powerLevel); + if (ret != (int)BluetoothError.None) { + Log.Error(Globals.LogTag, "Failed to get tx power level- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + Log.Info (Globals.LogTag, "TxPowerLevel is --- " + powerLevel); + return powerLevel; + } + + internal IList GetScanResultSvcSolicitationUuids(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + IntPtr uuidListArray; + int count; + + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + int ret = Interop.Bluetooth.GetScaResultSvcSolicitationUuids(ref scanDataStruct, packetType, out uuidListArray, out count); + if (ret != (int)BluetoothError.None) { + Log.Error(Globals.LogTag, "Failed to get service solicitation uuids " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + IntPtr[] uuidList = new IntPtr[count]; + Marshal.Copy(uuidListArray, uuidList, 0, count); + IList list = new List(); + foreach(IntPtr uuids in uuidList) + { + list.Add(Marshal.PtrToStringAnsi(uuids)); + Interop.Libc.Free(uuids); + } + + Interop.Libc.Free(uuidListArray); + return list; + } + + internal IList GetScanResultServiceDataList(BluetoothLeScanData scanData, + BluetoothLePacketType packetType, out int serviceCount) + { + int ret = 0; + IntPtr serviceListArray; + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + ret = Interop.Bluetooth.GetScanResultServiceDataList(ref scanDataStruct, packetType, out serviceListArray, out _serviceListCount); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get Service Data List, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + BluetoothLeServiceDataStruct[] serviceArray = new BluetoothLeServiceDataStruct[_serviceListCount]; + IntPtr current = serviceListArray; + for (int i = 0; i < _serviceListCount; i++) + { + //serviceArray[i] = new BluetoothLeServiceDataStruct();// check + Marshal.PtrToStructure(current, serviceArray[i]); + BluetoothLeServiceData serviceData = new BluetoothLeServiceData(); + BluetoothUtils.ConvertStructToLeServiceData(serviceArray[i], serviceData); + + _list.Add(serviceData); + + Marshal.DestroyStructure(current, typeof(BluetoothLeServiceDataStruct)); + + current = (IntPtr)((long)current + Marshal.SizeOf(serviceArray[i])); + Log.Info (Globals.LogTag, "Service Data " + i + serviceArray[i].ServiceData + +serviceArray[i].ServiceDataLength); + } + + serviceCount = _serviceListCount; + Log.Info (Globals.LogTag, "serviceCount "+serviceCount); + + Marshal.FreeHGlobal (scanDataStruct.AdvData); + Marshal.FreeHGlobal (scanDataStruct.ScanData); + return _list; + } + + internal int FreeServiceDataList() + { + int iServiceDataSize = Marshal.SizeOf(typeof(BluetoothLeServiceData)); + IntPtr structServiceData = Marshal.AllocHGlobal(iServiceDataSize); + Marshal.StructureToPtr(_list, structServiceData, false); + + int ret = Interop.Bluetooth.FreeServiceDataList(structServiceData, _serviceListCount); + if(ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to free Service Data List, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + Marshal.FreeHGlobal(structServiceData); + + return 0; + } + + internal int GetScanResultAppearance(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + int appearance; + + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + int ret = Interop.Bluetooth.GetScanResultAppearance(ref scanDataStruct, packetType, out appearance); + if (ret != (int)BluetoothError.None) { + Log.Error(Globals.LogTag, "Failed to get Appearance value- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return appearance; + } + + internal ManufacturerData GetScanResultManufacturerData(BluetoothLeScanData scanData, BluetoothLePacketType packetType) + { + ManufacturerData data = new ManufacturerData(); + + BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct(); + scanDataStruct = BluetoothUtils.ConvertLeScanDataToStruct (scanData, scanDataStruct); + + int dataId; + int dataLength; + IntPtr manufData; + + int ret = Interop.Bluetooth.GetScanResultManufacturerData(ref scanDataStruct, packetType, out dataId, + out manufData, out dataLength); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to get Manufacturer data - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + + Marshal.Copy (manufData, data.Data, 0, data.DataLength); + data.Id = dataId; + data.DataLength = dataLength; + + return data; + } + + internal int GattConnect(string remoteAddress, bool autoConnect) + { + int ret = Interop.Bluetooth.GattConnect (remoteAddress, autoConnect); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to establish GATT connection - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return ret; + } + + internal int GattDisconnect(string remoteAddress) + { + int ret = Interop.Bluetooth.GattDisconnect (remoteAddress); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to disconnect GATT connection - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return ret; + } + + internal int CreateAdvertiser(out IntPtr advertiserHandle) + { + return Interop.Bluetooth.CreateAdvertiser (out advertiserHandle); + } + + internal int DestroyAdvertiser(IntPtr advertiserHandle) + { + int ret = Interop.Bluetooth.DestroyAdvertiser (advertiserHandle); + if (ret != (int)BluetoothError.None) { + Log.Error(Globals.LogTag, "Failed to destroy the Advertiser- " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return ret; + } + + internal int StartAdvertising(IntPtr advertisingHandle) + { + _advertisingStateChangedCallback = (int result, IntPtr advertiserHandle, + BluetoothLeAdvertisingState state, IntPtr userData) => + { + Log.Info(Globals.LogTag, "Setting advertising state changed callback !! " ); + // TODO: Convert the advertiserHandle to leAdvertiser later + //BluetoothLeAdvertiser leAdvertiser = (BluetoothLeAdvertiser)Marshal.PtrToStructure(advertiserHandle, typeof(BluetoothLeAdvertiser)); + AdvertisingStateChangedEventArgs e = new AdvertisingStateChangedEventArgs(result, advertiserHandle, state); + _advertisingStateChanged(null, e); + }; + + IntPtr uData = IntPtr.Zero; + int ret = Interop.Bluetooth.BluetoothLeStartAdvertising (advertisingHandle, + _advertisingStateChangedCallback, uData ); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to start BLE advertising - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + return ret; + } + + + internal int StopAdvertising(IntPtr advertisingHandle) + { + return Interop.Bluetooth.BluetoothLeStopAdvertising (advertisingHandle); + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothProfile.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothProfile.cs new file mode 100644 index 0000000..6dff1cf --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothProfile.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT 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 Tizen.Network.Bluetooth +{ + /// + /// A generic class to represent all Bluetooth profiles.
+ /// Any common properties/functions to be added in this class in future. + ///
+ /// http://tizen.org/privilege/bluetooth + public abstract class BluetoothProfile + { + internal string RemoteAddress { get; set; } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothServerSocket.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothServerSocket.cs new file mode 100644 index 0000000..0d1615e --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothServerSocket.cs @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth +{ + /// + /// BluetoothSocket provides functions for managing connections to other devices and exchanging data. + /// + public class BluetoothServerSocket : IDisposable + { + private event EventHandler _acceptStateChanged; + internal int socketFd; + private bool disposed = false; + + /// + /// (event) AcceptStateChanged is raised when socket connection state is changed. + /// + public event EventHandler AcceptStateChanged + { + add + { + if (_acceptStateChanged == null) + { + RegisterAcceptStateChangedEvent(); + } + _acceptStateChanged += value; + } + remove + { + _acceptStateChanged -= value; + if (_acceptStateChanged == null) + { + UnregisterAcceptStateChangedEvent(); + } + } + } + + private void RegisterAcceptStateChangedEvent() + { + Interop.Bluetooth.SocketConnectionStateChangedCallback ConnectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) => + { + Log.Info(Globals.LogTag, "AcceptStateChanged cb is called"); + if (_acceptStateChanged != null) + { + BluetoothSocket socket = new BluetoothSocket(); + socket.connectedSocket = socketConnection.SocketFd; + GCHandle handle2 = (GCHandle) userData; + _acceptStateChanged(handle2.Target as BluetoothServerSocket, new AcceptStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection), socket)); + } + }; + GCHandle handle1 = GCHandle.Alloc(this); + IntPtr data = (IntPtr) handle1; + int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(ConnectionStateChangedCallback, data); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set accept state changed callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + private void UnregisterAcceptStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset accept state changed callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + internal BluetoothServerSocket(int socketFd) + { + Log.Info (Globals.LogTag, "Constructing server socket"); + this.socketFd = socketFd; + } + + /// + /// Starts listening on passed rfcomm socket and accepts connection requests. + /// + /// + /// The socket must be created with CreateServerSocket(). This API invokes ConnectionStateChanged event. + /// + public void Listen() + { + int ret = Interop.Bluetooth.Listen(socketFd, 1); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to accept connection, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + ~BluetoothServerSocket() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + RemoveRegisteredEvents(); + disposed = true; + } + + private void RemoveRegisteredEvents() + { + //unregister all remaining events when this object is released. + if (_acceptStateChanged != null) + { + UnregisterAcceptStateChangedEvent(); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothSocket.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothSocket.cs new file mode 100644 index 0000000..4fb8416 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothSocket.cs @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth +{ + /// + /// IBluetoothServerSocket interface. Handles the server socket operations. + /// + public interface IBluetoothServerSocket + { + event EventHandler DataReceived; + event EventHandler ConnectionStateChanged; + void SendData(string data); + } + + /// + /// IBluetoothClientSocket interface. Handles the client socket operations. + /// + public interface IBluetoothClientSocket : IBluetoothServerSocket + { + void Connect(); + void Disconnect(); + } + + internal class BluetoothSocket : IBluetoothClientSocket, IDisposable + { + private event EventHandler _dataReceived; + private event EventHandler _connectionStateChanged; + private bool disposed = false; + internal int connectedSocket; + internal string remoteAddress; + internal string serviceUuid; + + /// + /// This event occurs when socket server received data from client. + /// + public event EventHandler DataReceived + { + add + { + if (_dataReceived == null) + { + RegisterDataReceivedEvent(); + } + _dataReceived += value; + } + remove + { + _dataReceived -= value; + if (_dataReceived == null) + { + UnregisterDataReceivedEvent(); + } + } + } + + /// + /// This event occurs when connection state between two devices is changed. + /// + public event EventHandler ConnectionStateChanged + { + add + { + if (_connectionStateChanged == null) + { + RegisterConnectionStateChangedEvent(); + } + _connectionStateChanged += value; + } + remove + { + _connectionStateChanged -= value; + if (_connectionStateChanged == null) + { + UnregisterConnectionStateChangedEvent(); + } + } + } + + private void RegisterDataReceivedEvent() + { + Interop.Bluetooth.DataReceivedCallback DataReceivedCallback = (ref SocketDataStruct socketData, IntPtr userData) => + { + Log.Info(Globals.LogTag, "DataReceivedCallback is called"); + if (_dataReceived != null) + { + GCHandle handle2 = (GCHandle) userData; + _dataReceived(handle2.Target as IBluetoothServerSocket, new SocketDataReceivedEventArgs(BluetoothUtils.ConvertStructToSocketData(socketData))); + } + }; + GCHandle handle1 = GCHandle.Alloc (this); + IntPtr uData = (IntPtr) handle1; + int ret = Interop.Bluetooth.SetDataReceivedCallback(DataReceivedCallback, uData); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set data received callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + private void UnregisterDataReceivedEvent() + { + int ret = Interop.Bluetooth.UnsetDataReceivedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset data received callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + private void RegisterConnectionStateChangedEvent() + { + Interop.Bluetooth.SocketConnectionStateChangedCallback ConnectionStateChangedCallback = (int result, BluetoothSocketState connectionState, ref SocketConnectionStruct socketConnection, IntPtr userData) => + { + Log.Info(Globals.LogTag, "ConnectionStateChangedCallback is called"); + if (_connectionStateChanged != null) + { + connectedSocket = socketConnection.SocketFd; + GCHandle handle2 = (GCHandle) userData; + _connectionStateChanged(handle2.Target as IBluetoothServerSocket, new SocketConnectionStateChangedEventArgs((BluetoothError)result, connectionState, BluetoothUtils.ConvertStructToSocketConnection(socketConnection))); + } + }; + GCHandle handle1 = GCHandle.Alloc(this); + IntPtr data = (IntPtr) handle1; + int ret = Interop.Bluetooth.SetConnectionStateChangedCallback(ConnectionStateChangedCallback, data); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to set connection state changed callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + private void UnregisterConnectionStateChangedEvent() + { + int ret = Interop.Bluetooth.UnsetSocketConnectionStateChangedCallback(); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to unset connection state changed callback, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + /// + /// Connects to a specific RFCOMM based service on a remote Bluetooth device UUID. + /// + /// + /// The bluetooth must be enabled, discoverable with StartDiscovery(), bonded with the remote device using CreateBond(). ConnectionStateChanged event is raised once this API is called. + /// + /// The address of the remote Bluetooth device. + /// The UUID of service provided by the remote Bluetooth device. + void IBluetoothClientSocket.Connect() + { + int ret = Interop.Bluetooth.ConnectSocket(remoteAddress, serviceUuid); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to connect to socket, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + /// + /// Disconnects the RFCOMM connection with the given file descriptor of conneted socket. + /// + /// + /// The connection must be established. + /// + /// The file descriptor of socket to close. + void IBluetoothClientSocket.Disconnect() + { + int ret = Interop.Bluetooth.DisconnectSocket(connectedSocket); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to disconnect socket, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + /// + /// Sends data to the connected device. + /// + /// The number of bytes written (zero indicates nothing was written). + /// + /// The connection must be established. + /// + /// The file descriptor of connected socket. + /// The data to be sent. + public void SendData(string data) + { + int ret = Interop.Bluetooth.SendData(connectedSocket, data, data.Length); + if (ret != (int)BluetoothError.None) + { + Log.Error(Globals.LogTag, "Failed to send data, Error - " + (BluetoothError)ret); + BluetoothErrorFactory.ThrowBluetoothException(ret); + } + } + + ~BluetoothSocket() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + // Free managed objects. + } + //Free unmanaged objects + RemoveRegisteredEvents(); + disposed = true; + } + + private void RemoveRegisteredEvents() + { + //unregister all remaining events when this object is released. + if (_dataReceived != null) + { + UnregisterDataReceivedEvent(); + } + if (_connectionStateChanged != null) + { + UnregisterConnectionStateChangedEvent(); + } + } + } +} diff --git a/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothStructs.cs b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothStructs.cs new file mode 100644 index 0000000..05d0110 --- /dev/null +++ b/Tizen.Bluetooth/Tizen.Bluetooth/BluetoothStructs.cs @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Reflection; +using System.Linq; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Runtime.InteropServices; + +namespace Tizen.Network.Bluetooth +{ + /// + /// Structure of device class type and service. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct BluetoothClassStruct + { + /// + /// Type of the major device class. + /// + internal BluetoothMajorDeviceClassType MajorDeviceClassType; + /// + /// Type of the minor device class. + /// + internal BluetoothMinorDeviceClassType MinorDeviceClassType; + /// + /// Major service class mask. + /// + internal int MajorServiceClassMask; + } + + /// + /// Structure containing the information of Bluetooth device. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct BluetoothDeviceStruct + { + /// + /// Address of device. + /// + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string Address; + + /// + /// Name of device. + /// + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string Name; + + /// + /// Class of device. + /// + internal BluetoothClassStruct Class; + + /// + /// Service UUID list of device. + /// + internal IntPtr ServiceUuidList; + + /// + /// Service count of device. + /// + internal int ServiceCount; + + /// + /// The paired state of device. + /// + [MarshalAsAttribute(UnmanagedType.I1)] + internal bool IsPaired; + + /// + /// The connection state of device. + /// + [MarshalAsAttribute(UnmanagedType.I1)] + internal bool IsConnected; + + /// + /// The authorization state of device. + /// + [MarshalAsAttribute(UnmanagedType.I1)] + internal bool IsAuthorized; + + /// + /// The length of the manufacturer data. + /// + internal int ManufacturerDataLength; + + /// + /// The manufacturer data. + /// + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string ManufacturerData; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct BluetoothDiscoveredDeviceStruct + { + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string Address; + + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string Name; + + internal BluetoothClassStruct Class; + + internal int Rssi; + + [MarshalAsAttribute(UnmanagedType.I1)] + internal bool IsPaired; + + internal IntPtr ServiceUuidList; + + internal int ServiceCount; + + internal BluetoothAppearanceType AppearanceType; + + internal int ManufacturerDataLength; + + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string ManufacturerData; + } + + internal struct BluetoothDeviceSdpStruct + { + [MarshalAsAttribute(UnmanagedType.LPStr)] + internal string DeviceAddress; + internal IntPtr ServiceUuid; + internal int ServiceCount; + } + + internal struct BluetoothDeviceConnectionStruct + { + internal string Address; + internal BluetoothConnectionLinkType LinkType; + internal BluetoothDisconnectReason DisconnectReason; + } + + internal struct SocketDataStruct + { + internal int SocketFd; + internal int DataSize; + internal string Data; + } + + internal struct SocketConnectionStruct + { + internal int SocketFd; + internal int ServerFd; + internal BluetoothSocketRole LocalRole; + internal string Address; + internal string ServiceUuid; + } + + internal static class BluetoothUtils + { + internal static BluetoothDevice ConvertStructToDeviceClass(BluetoothDeviceStruct device) + { + BluetoothDevice resultDevice = new BluetoothDevice(); + Collection uuidList = null; + + if (device.ServiceCount > 0) + { + IntPtr[] extensionList = new IntPtr[device.ServiceCount]; + Marshal.Copy (device.ServiceUuidList, extensionList, 0, device.ServiceCount); + uuidList = new Collection (); + foreach (IntPtr extension in extensionList) { + string uuid = Marshal.PtrToStringAnsi (extension); + uuidList.Add (uuid); + } + } + + resultDevice.RemoteDeviceAddress = device.Address; + resultDevice.RemoteDeviceName = device.Name; + resultDevice.RemoteDeviceClass = new BluetoothClass(); + resultDevice.Class.MajorType = device.Class.MajorDeviceClassType; + resultDevice.Class.MinorType = device.Class.MinorDeviceClassType; + resultDevice.Class.Mask = device.Class.MajorServiceClassMask; + resultDevice.RemotePaired = device.IsPaired; + resultDevice.RemoteConnected = device.IsConnected; + resultDevice.RemoteAuthorized = device.IsAuthorized; + resultDevice.RemoteDeviceService = uuidList; + resultDevice.RemoteDeviceCount = device.ServiceCount; + resultDevice.RemoteManufLength = device.ManufacturerDataLength; + resultDevice.RemoteManufData = device.ManufacturerData; + + return resultDevice; + } + + internal static BluetoothDevice ConvertStructToDiscoveredDevice(BluetoothDiscoveredDeviceStruct structDevice) + { + BluetoothDevice resultDevice = new BluetoothDevice(); + Collection uuidList = null; + + if (structDevice.ServiceCount > 0) { + IntPtr[] extensionList = new IntPtr[structDevice.ServiceCount]; + Marshal.Copy (structDevice.ServiceUuidList, extensionList, 0, structDevice.ServiceCount); + uuidList = new Collection (); + foreach (IntPtr extension in extensionList) { + string uuid = Marshal.PtrToStringAnsi (extension); + uuidList.Add (uuid); + } + } + + resultDevice.RemoteDeviceAddress = structDevice.Address; + resultDevice.RemoteDeviceName = structDevice.Name; + + resultDevice.RemoteDeviceClass = new BluetoothClass(); + resultDevice.Class.MajorType = structDevice.Class.MajorDeviceClassType; + resultDevice.Class.MinorType = structDevice.Class.MinorDeviceClassType; + resultDevice.Class.Mask = structDevice.Class.MajorServiceClassMask; + + resultDevice.RemoteDeviceRssi = structDevice.Rssi; + resultDevice.RemoteAppearance = structDevice.AppearanceType; + + if (structDevice.ServiceCount > 0) { + resultDevice.RemoteDeviceService = uuidList; + resultDevice.RemoteDeviceCount = structDevice.ServiceCount; + } + + resultDevice.RemotePaired = structDevice.IsPaired; + resultDevice.RemoteManufData = structDevice.ManufacturerData; + resultDevice.RemoteManufLength = structDevice.ManufacturerDataLength; + return resultDevice; + } + + internal static BluetoothDeviceSdpData ConvertStructToSdpData(BluetoothDeviceSdpStruct structData) + { + BluetoothDeviceSdpData resultData = new BluetoothDeviceSdpData(); + Collection uuidList = null; + + if (structData.ServiceCount > 0) { + IntPtr[] extensionList = new IntPtr[structData.ServiceCount]; + Marshal.Copy (structData.ServiceUuid, extensionList, 0, structData.ServiceCount); + uuidList = new Collection (); + foreach (IntPtr extension in extensionList) { + string uuid = Marshal.PtrToStringAnsi (extension); + uuidList.Add (uuid); + } + } + + resultData.Uuid = uuidList; + resultData.Address = structData.DeviceAddress; + + return resultData; + } + + internal static BluetoothDeviceConnectionData ConvertStructToConnectionData(BluetoothDeviceConnectionStruct structInfo) + { + BluetoothDeviceConnectionData resultData = new BluetoothDeviceConnectionData(); + resultData.RemoteAddress = structInfo.Address; + resultData.Link = structInfo.LinkType; + resultData.Reason = structInfo.DisconnectReason; + return resultData; + } + + internal static BluetoothLeScanData ConvertStructToLeScanData(BluetoothLeScanDataStruct structScanData, BluetoothLeScanData scanData) + { + scanData.RemoteAddress = structScanData.RemoteAddress; + scanData.AddressType = structScanData.AddressType; + scanData.Rssi = structScanData.Rssi; + + scanData.AdvDataLength = structScanData.AdvDataLength; + scanData.AdvData = new byte[scanData.AdvDataLength]; + Marshal.Copy (structScanData.AdvData, scanData.AdvData, 0, scanData.AdvDataLength); + + scanData.ScanDataLength = structScanData.ScanDataLength; + scanData.ScanData = new byte[scanData.ScanDataLength]; + Marshal.Copy (structScanData.ScanData, scanData.ScanData, 0, scanData.ScanDataLength); + + return scanData; + } + + internal static BluetoothLeScanDataStruct ConvertLeScanDataToStruct(BluetoothLeScanData scanData, BluetoothLeScanDataStruct scanDataStruct) + { + scanDataStruct.RemoteAddress = scanData.RemoteAddress; + scanDataStruct.AddressType = scanData.AddressType; + scanDataStruct.Rssi = scanData.Rssi; + + scanDataStruct.AdvDataLength = scanData.AdvDataLength; + scanDataStruct.AdvData = Marshal.AllocHGlobal (scanData.AdvDataLength); + Marshal.Copy (scanData.AdvData, 0, scanDataStruct.AdvData, scanData.AdvDataLength); + + scanDataStruct.ScanDataLength = scanData.ScanDataLength; + scanDataStruct.ScanData = Marshal.AllocHGlobal (scanData.ScanDataLength); + Marshal.Copy (scanData.ScanData, 0, scanDataStruct.ScanData, scanData.ScanDataLength); + + return scanDataStruct; + } + + internal static BluetoothLeServiceData ConvertStructToLeServiceData(BluetoothLeServiceDataStruct structServiceData, BluetoothLeServiceData serviceData) + { + serviceData.Data = structServiceData.ServiceData; + serviceData.Uuid = structServiceData.ServiceUuid; + serviceData.Length = structServiceData.ServiceDataLength; + + return serviceData; + } + + internal static SocketData ConvertStructToSocketData(SocketDataStruct structInfo) + { + SocketData data = new SocketData(); + data.Fd = structInfo.SocketFd; + data.Size = structInfo.DataSize; + data.RecvData = structInfo.Data; + return data; + } + + internal static SocketConnection ConvertStructToSocketConnection(SocketConnectionStruct structInfo) + { + SocketConnection connectionInfo = new SocketConnection(); + connectionInfo.Fd = structInfo.SocketFd; + connectionInfo.RemoteAddress = structInfo.Address; + connectionInfo.Uuid = structInfo.ServiceUuid; + return connectionInfo; + } + } +} + diff --git a/packaging/csapi-bluetooth.manifest b/packaging/csapi-bluetooth.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/csapi-bluetooth.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/csapi-bluetooth.spec b/packaging/csapi-bluetooth.spec new file mode 100644 index 0000000..4413fe8 --- /dev/null +++ b/packaging/csapi-bluetooth.spec @@ -0,0 +1,76 @@ +%{!?dotnet_assembly_path: %define dotnet_assembly_path /opt/usr/share/dotnet.tizen/framework} + +%if 0%{?tizen_build_devel_mode} +%define BUILDCONF Debug +%else +%define BUILDCONF Release +%endif + +Name: csapi-bluetooth +Summary: Tizen Bluetooth API for C# +Version: 1.0.2 +Release: 1 +Group: Development/Libraries +License: Apache-2.0 +URL: https://www.tizen.org +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest + +AutoReqProv: no +ExcludeArch: %{ix86} aarch64 + +BuildRequires: mono-compiler +BuildRequires: mono-devel + +BuildRequires: dotnet-build-tools + +# C# API Requries +BuildRequires: csapi-tizen-nuget + +%description +Tizen Bluetooth API for C# + +%prep +%setup -q +cp %{SOURCE1} . + +%define Assemblies Tizen.Bluetooth + +%build +for ASM in %{Assemblies}; do +# NuGet Restore +find $ASM/*.project.json -exec nuget restore {} \; +# Build +find $ASM/*.csproj -exec xbuild {} /p:Configuration=%{BUILDCONF} \; +# NuGet Pack +nuget pack $ASM/$ASM.nuspec -Version %{version} -Properties Configuration=%{BUILDCONF} +done + +%install +# Runtime Binary +mkdir -p %{buildroot}%{dotnet_assembly_path} +for ASM in %{Assemblies}; do +%if 0%{?_with_corefx} + install -p -m 644 $ASM/bin/%{BUILDCONF}/$ASM.dll %{buildroot}%{dotnet_assembly_path} +%else + install -p -m 644 $ASM/bin/%{BUILDCONF}/Net45/$ASM.dll %{buildroot}%{dotnet_assembly_path} +%endif +done +# NuGet +mkdir -p %{buildroot}/nuget +install -p -m 644 *.nupkg %{buildroot}/nuget + +%files +%manifest %{name}.manifest +%license LICENSE +%attr(644,root,root) %{dotnet_assembly_path}/*.dll + +%package nuget +Summary: NuGet package for %{name} +Group: Development/Libraries + +%description nuget +NuGet package for %{name} + +%files nuget +/nuget/*.nupkg