From 1da8c329d00880d50f0aacefee7a94c238e9b86d Mon Sep 17 00:00:00 2001 From: Gowtham Anandha Babu Date: Wed, 1 Feb 2017 16:24:14 +0530 Subject: [PATCH] [C# Bluetooth]: Fix GATT issues Below changes are required for GATT manual TCT to work properly. Few changes are made to align with CAPI. Change-Id: I9c14b791952894c30b4949f0628f582fe89ec581 --- .../Interop/Interop.Bluetooth.cs | 14 +++++----- .../BluetoothEnumerations.cs | 15 +++++++++++ .../Tizen.Network.Bluetooth/BluetoothGatt.cs | 30 ++++++++++++++------- .../Tizen.Network.Bluetooth/BluetoothGattImpl.cs | 31 ++++++++-------------- 4 files changed, 53 insertions(+), 37 deletions(-) mode change 100644 => 100755 src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs mode change 100644 => 100755 src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs diff --git a/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs index 842e8f6..86ac67e 100755 --- a/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs +++ b/src/Tizen.Network.Bluetooth/Interop/Interop.Bluetooth.cs @@ -413,19 +413,19 @@ internal static partial class Interop 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); + internal delegate void BtGattServerReadValueRequestedCallback(string clientAddress, int requestId, IntPtr serverHandle, IntPtr 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); + internal delegate void BtGattServerWriteValueRequestedCallback(string clientAddress, int requestId, IntPtr serverHandle, IntPtr gattHandle, int offset, bool response_needed, byte[] value, int len, IntPtr userData); [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] - internal delegate void BtClientCharacteristicValueChangedCallback(BluetoothGattAttributeHandle characteristicHandle, byte[] value, int len, IntPtr userData); + internal delegate void BtClientCharacteristicValueChangedCallback(IntPtr characteristicHandle, byte[] value, int len, IntPtr userData); [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] - internal delegate void BtGattServerNotificationStateChangeCallback(bool notify, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle characteristicHandle, IntPtr userData); + internal delegate void BtGattServerNotificationStateChangeCallback(bool notify, IntPtr serverHandle, IntPtr characteristicHandle, IntPtr userData); [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] - internal delegate void BtGattServerNotificationSentCallback(int result, string clientAddress, BluetoothGattServerHandle serverHandle, BluetoothGattAttributeHandle characteristicHandle, bool completed, IntPtr userData); + internal delegate void BtGattServerNotificationSentCallback(int result, string clientAddress, IntPtr serverHandle, IntPtr characteristicHandle, bool completed, IntPtr userData); [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] internal delegate void BtGattClientRequestCompletedCallback(int result, IntPtr requestHandle, IntPtr userData); @@ -562,10 +562,10 @@ internal static partial class Interop [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")] + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_write_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")] + [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_set_characteristic_notification_state_change_cb")] internal static extern int BtGattServeSetNotificationStateChangeCallback(BluetoothGattAttributeHandle characteristicHandle, BtGattServerNotificationStateChangeCallback callback, IntPtr userData); [DllImport(Libraries.Bluetooth, EntryPoint = "bt_gatt_server_start")] diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs old mode 100644 new mode 100755 index 6f4f107..b49775c --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothEnumerations.cs @@ -1184,4 +1184,19 @@ namespace Tizen.Network.Bluetooth /// WriteWithResponse } + + /// + /// Enumerations of the remote device request types for attributes + /// + public enum BluetoothGattRequestType + { + /// + /// Read Requested. + /// + Read = 0, + /// + /// Write Requested. + /// + Write = 1, + } } diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs old mode 100644 new mode 100755 index d059df8..473ee49 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGatt.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); @@ -16,6 +16,8 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; using System.Threading.Tasks; namespace Tizen.Network.Bluetooth @@ -27,7 +29,6 @@ namespace Tizen.Network.Bluetooth { private static BluetoothGattServer _instance; private BluetoothGattServerImpl _impl; - private BluetoothGattServer() { _impl = new BluetoothGattServerImpl(); @@ -157,12 +158,13 @@ namespace Tizen.Network.Bluetooth /// Sends a response to the remote device as a result of a read/ write request /// /// The identification of a read/ write request + /// The request type for read/write /// 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) + public void SendResponse(int requestId, BluetoothGattRequestType type, int status, byte[] value, int offset) { - _impl.SendResponse(requestId, status, value, offset); + _impl.SendResponse(requestId, (int)type, status, value, offset); } internal bool IsValid() @@ -191,6 +193,11 @@ namespace Tizen.Network.Bluetooth return client.Isvalid() ? client : null; } + public void DestroyClient() + { + _impl.GetHandle().Dispose(); + } + /// /// Address of remote device. /// @@ -788,9 +795,9 @@ namespace Tizen.Network.Bluetooth if (Server == null) return; if (_writeValueRequested == null) { - _writeValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, valueToWrite, len, userData) => + _writeValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, response_needed, valueToWrite, len, userData) => { - _writeValueRequested?.Invoke(this, new WriteRequestedEventArgs(Server, clientAddress, requestId, valueToWrite, offset)); + _writeValueRequested?.Invoke(this, new WriteRequestedEventArgs(Server, clientAddress, requestId, valueToWrite, offset, response_needed)); }; Impl.SetWriteValueRequestedEventCallback(_writeValueRequestedCallback); } @@ -847,11 +854,14 @@ namespace Tizen.Network.Bluetooth /// 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) + /// Throws excetion if value is null + public void SetValue(string value) { - Impl.SetValue(value, offset); + if (value.Equals(null)) + GattUtil.ThrowForError((int)BluetoothError.InvalidParameter, "value should not be null"); + + byte[] val = Encoding.UTF8.GetBytes(value); + Impl.SetValue(val); } /// diff --git a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs index 6ed552f..e1a8508 100755 --- a/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs +++ b/src/Tizen.Network.Bluetooth/Tizen.Network.Bluetooth/BluetoothGattImpl.cs @@ -101,9 +101,9 @@ namespace Tizen.Network.Bluetooth return attribututeList; } - internal void SendResponse(int requestId, int status, byte[] value, int offset) + internal void SendResponse(int requestId, int request_type, int status, byte[] value, int offset) { - int err = Interop.Bluetooth.BtGattServerSendResponse(requestId, 0, offset, status, value, value.Length); + int err = Interop.Bluetooth.BtGattServerSendResponse(requestId, request_type, offset, status, value, value.Length); GattUtil.ThrowForError(err, string.Format("Failed to send response for request Id {0}", requestId)); } @@ -197,7 +197,10 @@ namespace Tizen.Network.Bluetooth TaskCompletionSource tcs = new TaskCompletionSource(); Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) => { - tcs.SetResult(true); + if (result == (int)BluetoothError.None) + tcs.SetResult(true); + else + tcs.SetResult(false); }; int err = Interop.Bluetooth.BtGattClientReadValue(handle, cb, IntPtr.Zero); @@ -215,7 +218,10 @@ namespace Tizen.Network.Bluetooth TaskCompletionSource tcs = new TaskCompletionSource(); Interop.Bluetooth.BtGattClientRequestCompletedCallback cb = (result, requestHandle, userData) => { - tcs.SetResult(true); + if (result == (int)BluetoothError.None) + tcs.SetResult(true); + else + tcs.SetResult(false); }; int err = Interop.Bluetooth.BtGattClientWriteValue(handle, cb, IntPtr.Zero); @@ -539,21 +545,6 @@ namespace Tizen.Network.Bluetooth 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; @@ -634,7 +625,6 @@ namespace Tizen.Network.Bluetooth if (_hasOwnership == true) { Interop.Bluetooth.BtGattClientDestroy(handle); - Interop.Bluetooth.BtGattServerDeinitialize(); } SetHandle(IntPtr.Zero); return true; @@ -647,6 +637,7 @@ namespace Tizen.Network.Bluetooth { if (_hasOwnership == true) { + Interop.Bluetooth.BtGattServerDeinitialize(); Interop.Bluetooth.BtGattServerDestroy(handle); } SetHandle(IntPtr.Zero); -- 2.7.4