2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
19 using System.Threading.Tasks;
21 namespace Tizen.Network.Bluetooth
24 /// Bluetooth GATT server
26 public class BluetoothGattServer
28 private static BluetoothGattServer _instance;
29 private BluetoothGattServerImpl _impl;
31 private BluetoothGattServer()
33 _impl = new BluetoothGattServerImpl();
37 /// (event) called when indication acknowledgement received, once for each notified client
39 public event EventHandler<NotificationSentEventArg> NotificationSent
43 _impl._notificationSent += value;
47 _impl._notificationSent -= value;
52 /// Creates bluetooth gatt server
54 /// <returns></returns>
55 public static BluetoothGattServer CreateServer()
57 if (_instance == null)
59 BluetoothGattServer server = new BluetoothGattServer();
69 /// Registers the server along with the GATT services of the application it is hosting
77 /// Registers a specified service to this server
79 /// <param name="service">service, which needs to be registered with this server</param>
80 public void RegisterGattService(BluetoothGattService service)
82 if (service.IsRegistered())
84 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
86 _impl.RegisterGattService(this, service);
90 /// Unregisters a specified service from this server
92 /// <param name="service">service, which needs to be unregistered from this server</param>
94 /// Once unregistered, service object will become invalid and should not be used to access sevices's or any children attribute's methods/ members.
96 public void UnregisterGattService(BluetoothGattService service)
98 if (service.GetGattServer() != this)
100 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
103 _impl.UnregisterGattService(service);
107 /// Unregisters all services from this server
110 /// Once unregistered, servicees will become invalid and should not be used to access sevices's or any children attribute's methods/ members.
112 public void UnregisterGattServices()
114 _impl.UnregisterAllGattServices(this);
118 /// Gets service with given UUID that belongs to this server.
120 /// <param name="uuid">UUID for the service to get</param>
121 /// <returns>service with given uuid if it exists, null otherwise</returns>
122 public BluetoothGattService GetService(string uuid)
124 return _impl.GetService(this, uuid);
128 /// Gets list of services that belongs to this server.
130 /// <returns>list of services that belongs to this server</returns>
131 public IEnumerable<BluetoothGattService> GetServices()
133 return _impl.GetServices(this);
137 /// Send indication for value change of the characteristic to the remote devices
139 /// <param name="characteristic">characteristic whose value is changes</param>
140 /// <param name="clientAddress">Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled.</param>
141 public async Task<bool> SendIndicationAsync(BluetoothGattCharacteristic characteristic, string clientAddress)
143 return await _impl.SendIndicationAsync(this, characteristic, clientAddress);
147 /// Send notification for value change of the characteristic to the remote devices
149 /// <param name="characteristic">characteristic The characteristic which has a changed value</param>
150 /// <param name="clientAddress">Remote device address to send notify or indicate and if set to NULL then notify/indicate all is enabled.</param>
151 public void SendNotification(BluetoothGattCharacteristic characteristic, string clientAddress)
153 _impl.SendNotification(characteristic, clientAddress);
157 /// Sends a response to the remote device as a result of a read/ write request
159 /// <param name="requestId">The identification of a read/ write request</param>
160 /// <param name="status">error value in case of failure, 0 for success</param>
161 /// <param name="value">Value to be sent</param>
162 /// <param name="offset">Fffset from where the value is read</param>
163 public void SendResponse(int requestId, int status, byte[] value, int offset)
165 _impl.SendResponse(requestId, status, value, offset);
168 internal bool IsValid()
170 return _impl.GetHandle().IsInvalid == false;
175 /// Bluetooth GATT client
177 public class BluetoothGattClient
179 private BluetoothGattClientImpl _impl;
180 private string _remoteAddress = string.Empty;
182 internal BluetoothGattClient(string remoteAddress)
184 _impl = new BluetoothGattClientImpl(remoteAddress);
185 _remoteAddress = remoteAddress;
188 internal static BluetoothGattClient CreateClient(string remoteAddress)
190 BluetoothGattClient client = new BluetoothGattClient(remoteAddress);
191 return client.Isvalid() ? client : null;
195 /// Address of remote device.
197 public string RemoteAddress
201 if (string.IsNullOrEmpty(_remoteAddress))
203 _remoteAddress = _impl.GetRemoteAddress();
205 return _remoteAddress;
210 /// Gets service with given UUID that belongs to this client.
212 /// <param name="uuid">UUID for the service to get</param>
213 /// <returns>service with given uuid if it exists, null otherwise</returns>
214 public BluetoothGattService GetService(string uuid)
216 return _impl.GetService(this, uuid);
220 /// Gets list of services that belongs to this client.
222 /// <returns>list of services that belongs to this client</returns>
223 public IEnumerable<BluetoothGattService> GetServices()
225 return _impl.GetServices(this);
229 /// Reads the value of given characteristic from the remote device asynchronously.
231 /// <param name="characteristic">characteristic to be read</param>
232 /// <returns>true on success, false otherwise</returns>
233 public async Task<bool> ReadValueAsync(BluetoothGattCharacteristic characteristic)
235 return await _impl.ReadValueAsyncTask(characteristic.GetHandle());
239 /// Reads the value of given descriptor from the remote device asynchronously.
241 /// <param name="descriptor">descriptor to be read</param>
242 /// <returns>true on success, false otherwise</returns>
243 public async Task<bool> ReadValueAsync(BluetoothGattDescriptor descriptor)
245 return await _impl.ReadValueAsyncTask(descriptor.GetHandle());
249 /// Write value of given characteristic to remote device asynchronously.
251 /// <param name="characteristic">characteristic to be written</param>
252 /// <returns>true on success, false otherwise</returns>
253 public async Task<bool> WriteValueAsync(BluetoothGattCharacteristic characteristic)
255 return await _impl.WriteValueAsyncTask(characteristic.GetHandle());
259 /// Write value of given descriptor to remote device asynchronously.
261 /// <param name="descriptor">descriptor to be written</param>
262 /// <returns>true on success, false otherwise</returns>
263 public async Task<bool> WriteValueAsync(BluetoothGattDescriptor descriptor)
265 return await _impl.WriteValueAsyncTask(descriptor.GetHandle());
268 internal bool Isvalid()
270 return _impl.GetHandle().IsInvalid == false;
275 /// Bluetooth GATT service
277 public class BluetoothGattService
279 private BluetoothGattServiceImpl _impl;
280 private BluetoothGattClient _parentClient = null;
281 private BluetoothGattServer _parentServer = null;
282 private BluetoothGattService _parentService = null;
287 /// <param name="uuid">UUID of the service</param>
288 /// <param name="type">type of service</param>
289 public BluetoothGattService(string uuid, BluetoothGattServiceType type)
292 _impl = new BluetoothGattServiceImpl(uuid, type);
295 internal BluetoothGattService(BluetoothGattServiceImpl impl, string uuid)
302 /// Specification name from the UUID
304 public string Uuid { get; }
307 /// Adds a characteristic to this service
309 /// <param name="characteristic">characteristic to be added</param>
310 /// <returns>true on success, false otherwise</returns>
311 public void AddCharacteristic(BluetoothGattCharacteristic characteristic)
313 if (GetGattClient() != null)
315 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
318 if (characteristic.GetService() != null)
320 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
323 _impl.AddCharacteristic(characteristic);
324 characteristic.SetParent(this);
328 /// Gets characteristic with given UUID that belongs to this service.
330 /// <param name="uuid">UUID for the characteristic to get</param>
331 /// <returns>characteristic with given uuid if it exists, null otherwise</returns>
332 public BluetoothGattCharacteristic GetCharacteristic(string uuid)
334 return _impl.GetCharacteristic(this, uuid);
338 /// Gets list of characteristic that belongs to this service.
340 /// <returns>list of characteristic that belongs to this service</returns>
341 public IEnumerable<BluetoothGattCharacteristic> GetCharacteristics()
343 return _impl.GetCharacteristics(this);
347 /// Includes a service to this service
349 /// <param name="service">service to be included</param>
350 /// <returns>true on success, false otherwise</returns>
351 public void AddService(BluetoothGattService service)
353 if (GetGattClient() != null)
355 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
358 if (service.IsRegistered())
360 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
363 _impl.AddIncludeService(service);
364 service.SetParent(this);
368 /// <param name="uuid">UUID for the service to get</param>
369 /// <returns>service with given uuid if it exists, null otherwise</returns>
370 public BluetoothGattService GetIncludeService(string uuid)
372 return _impl.GetIncludeService(this, uuid);
376 /// Gets included service list of this service.
378 /// <returns>included service list of this service</returns>
379 public IEnumerable<BluetoothGattService> GetIncludeServices()
381 return _impl.GetIncludeServices(this);
385 /// Gets the server instance which the specified service belongs to.
387 /// <returns>server instance which the specified service belongs to</returns>
388 public BluetoothGattServer GetGattServer()
390 return _parentServer;
394 /// Gets the client instance which the specified service belongs to.
396 /// <returns>client instance which the specified service belongs to</returns>
397 public BluetoothGattClient GetGattClient()
399 return _parentClient;
402 internal BluetoothGattAttributeHandle GetHandle()
404 return _impl.GetHandle();
407 internal void SetParent(BluetoothGattService parent)
411 _parentService = parent;
412 _impl.ReleaseHandleOwnership();
416 internal void SetParent(BluetoothGattClient parent)
420 _parentClient = parent;
421 _impl.ReleaseHandleOwnership();
425 internal void SetParent(BluetoothGattServer parent)
429 _parentServer = parent;
430 _impl.ReleaseHandleOwnership();
434 internal void UnregisterService()
436 _parentServer = null;
437 _parentClient = null;
438 _parentService = null;
441 internal bool IsRegistered()
443 return _parentClient != null || _parentServer != null || _parentService != null;
448 /// Bluetooth GATT characteristic
450 public class BluetoothGattCharacteristic : BluetoothGattAttribute
452 private BluetoothGattCharacteristicImpl _impl;
453 private BluetoothGattService _parent = null;
455 private Interop.Bluetooth.BtClientCharacteristicValueChangedCallback _characteristicValueChangedCallback;
456 private Interop.Bluetooth.BtGattServerNotificationStateChangeCallback _notificationStateChangedCallback;
458 private EventHandler<ValueChangedEventArgs> _characteristicValueChanged;
459 internal EventHandler<NotificationStateChangedEventArg> _notificationStateChanged;
464 /// <param name="uuid">UUID of the characterstic</param>
465 /// <param name="permissions">Permissions for the characterstic</param>
466 /// <param name="properties">Properties set for the characterstic</param>
467 /// <param name="value">Value associated with the characterstic</param>
468 /// <remarks>throws in case of internal error</remarks>
469 public BluetoothGattCharacteristic(string uuid, BluetoothGattPermission permissions, BluetoothGattProperty properties, byte[] value) : base(uuid, permissions)
471 _impl = new BluetoothGattCharacteristicImpl(uuid, permissions, properties, value);
474 internal BluetoothGattCharacteristic(BluetoothGattCharacteristicImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission)
480 /// (event) CharacteristicValueChanged is raised when server notifies for change in this characteristic value
483 /// Adding event handle on charateristic on server side will not have any effect
485 public event EventHandler<ValueChangedEventArgs> ValueChanged
491 if (_characteristicValueChanged == null)
493 _characteristicValueChangedCallback = (gattHandle, characteristicValue, len, userData) =>
495 _characteristicValueChanged?.Invoke(this, new ValueChangedEventArgs(characteristicValue));
498 _impl.SetCharacteristicValueChangedEvent(_characteristicValueChangedCallback);
500 _characteristicValueChanged = value;
507 _characteristicValueChanged = null;
508 if (_characteristicValueChanged == null)
510 _impl.UnsetCharacteristicValueChangedEvent();
518 /// (event) NotificationStateChanged is called when client enables or disables the Notification/Indication for particular characteristics.
521 /// Adding event handle on charateristic on client side will not have any effect
523 public event EventHandler<NotificationStateChangedEventArg> NotificationStateChanged
529 if (_notificationStateChangedCallback == null)
531 _notificationStateChangedCallback = (notify, serverHandle, characteristicHandle, userData) =>
533 _notificationStateChanged?.Invoke(this, new NotificationStateChangedEventArg(Server, notify));
536 _impl.SetNotificationStateChangedEvent(_notificationStateChangedCallback);
539 _notificationStateChanged = value;
546 _notificationStateChanged = null;
547 // CAPI does not allow unsetting ReadValueRequestedEventCallback.
553 /// Property for this characteristic
555 public BluetoothGattProperty Properties
559 return _impl.GetProperties();
565 _impl.SetProperties(value);
571 /// Write type to be used for write operations
573 public BluetoothGattWriteType WriteType
577 return _impl.GetWriteType();
581 _impl.SetWriteType(value);
585 internal override BluetoothGattClient Client
589 return _parent?.GetGattClient();
593 internal override BluetoothGattServer Server
597 return _parent?.GetGattServer();
601 internal override BluetoothGattAttributeImpl Impl
610 /// Adds a descriptor to this characteristic
612 /// <param name="descriptor">descriptor to be added</param>
613 /// <returns>true on success, false otherwise</returns>
614 public void AddDescriptor(BluetoothGattDescriptor descriptor)
618 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotSupported);
621 if (descriptor.GetCharacteristic() != null)
623 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.InvalidParameter);
626 _impl.AddDescriptor(descriptor);
627 descriptor.SetParent(this);
631 /// Gets descriptor with given UUID that belongs to this characteristic.
633 /// <param name="uuid">UUID for the descriptor to get</param>
634 /// <returns>descriptor with given uuid if it exists, null otherwise</returns>
635 public BluetoothGattDescriptor GetDescriptor(string uuid)
637 return _impl.GetDescriptor(this, uuid);
641 /// Gets list of descriptors that belongs to this characteristic.
643 /// <returns>list of descriptors that belongs to this characteristic</returns>
644 public IEnumerable<BluetoothGattDescriptor> GetDescriptors()
646 return _impl.GetDescriptors(this);
650 /// Gets the service instance which the specified characterstic belongs to.
652 /// <returns>characteristic instance, the specified characterstic belongs to.</returns>
653 public BluetoothGattService GetService()
658 internal void SetParent(BluetoothGattService parent)
663 ReleaseHandleOwnership();
669 /// Bluetooth GATT descriptor
671 public class BluetoothGattDescriptor : BluetoothGattAttribute
673 private BluetoothGattCharacteristic _parent = null;
674 private BluetoothGattDescriptorImpl _impl;
679 /// <param name="uuid">UUID of the descriptor</param>
680 /// <param name="permisions">Permissions for the descriptor</param>
681 /// <param name="value">Value associated with the descriptor</param>
682 /// <remarks>throws in case of internal error</remarks>
683 public BluetoothGattDescriptor(string uuid, BluetoothGattPermission permisions, byte[] value) : base (uuid, permisions)
685 _impl = new BluetoothGattDescriptorImpl(uuid, permisions, value);
688 internal BluetoothGattDescriptor(BluetoothGattDescriptorImpl impl, string uuid, BluetoothGattPermission permission) : base(uuid, permission)
693 internal override BluetoothGattClient Client
697 return _parent?.Client;
701 internal override BluetoothGattServer Server
705 return _parent?.Server;
709 internal override BluetoothGattAttributeImpl Impl
718 /// Gets the characteristic instance which the specified descriptor belongs to.
720 /// <returns>characteristic instance, the specified descriptor belongs to.</returns>
721 public BluetoothGattCharacteristic GetCharacteristic()
726 internal void SetParent(BluetoothGattCharacteristic parent)
731 ReleaseHandleOwnership();
737 /// Bluetooth GATT attribute
739 public abstract class BluetoothGattAttribute
741 private Interop.Bluetooth.BtGattServerReadValueRequestedCallback _readValueRequestedCallback;
742 private Interop.Bluetooth.BtGattServerWriteValueRequestedCallback _writeValueRequestedCallback;
744 private EventHandler<ReadRequestedEventArgs> _readValueRequested;
745 private EventHandler<WriteRequestedEventArgs> _writeValueRequested;
747 public BluetoothGattAttribute(string uuid, BluetoothGattPermission permission)
750 Permissions = permission;
756 /// Event called when client request to read value of a characteristic or descriptor
758 public event EventHandler<ReadRequestedEventArgs> ReadRequested
762 if (Server == null) return;
763 if (_readValueRequestedCallback == null)
765 _readValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, userData) =>
767 _readValueRequested?.Invoke(this, new ReadRequestedEventArgs(Server, clientAddress, requestId, offset));
769 Impl.SetReadValueRequestedEventCallback(_readValueRequestedCallback);
771 _readValueRequested = value;
775 if (Server == null) return;
776 _readValueRequested = null;
777 // CAPI does not allow unsetting ReadValueRequestedEventCallback.
782 /// Event called when a value of a characteristic or descriptor has been changed by a client
784 public event EventHandler<WriteRequestedEventArgs> WriteRequested
788 if (Server == null) return;
789 if (_writeValueRequested == null)
791 _writeValueRequestedCallback = (clientAddress, requestId, serverHandle, gattHandle, offset, valueToWrite, len, userData) =>
793 _writeValueRequested?.Invoke(this, new WriteRequestedEventArgs(Server, clientAddress, requestId, valueToWrite, offset));
795 Impl.SetWriteValueRequestedEventCallback(_writeValueRequestedCallback);
797 _writeValueRequested = value;
801 if (Server == null) return;
802 _writeValueRequested = null;
803 // CAPI does not allow unsetting ReadValueRequestedEventCallback.
810 public string Uuid { get; }
813 /// Permissions for this attribute
815 public BluetoothGattPermission Permissions { get; }
818 /// Value of this descriptor
824 return Impl.GetValue();
828 Impl.SetValue(value);
832 internal abstract BluetoothGattClient Client { get; }
833 internal abstract BluetoothGattServer Server { get; }
834 internal abstract BluetoothGattAttributeImpl Impl { get; }
837 /// Returns string value at specified offset
839 /// <param name="offset"></param>
840 /// <returns>string value at specified offset</returns>
841 public string GetValue(int offset)
843 return Impl.GetValue(offset);
847 /// Sets string value as specified offset
849 /// <param name="value">value to set</param>
850 /// <param name="offset">offset in the attribute value buffer</param>
851 /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of string value) is greater then length of value buffer</exception>
852 public void SetValue(string value, int offset)
854 Impl.SetValue(value, offset);
858 /// Returns value at specified offset as int value of specified type
860 /// <param name="type">type of int value</param>
861 /// <param name="offset">offset in the attribute value buffer</param>
862 /// <returns>int value at given offset</returns>
863 /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of int value) is greater then length of value buffer</exception>
864 public int GetValue(IntDataType type, int offset)
866 return Impl.GetValue(type, offset);
870 /// Update Value at specified offset by int value of specified type
872 /// <param name="type">type of int value</param>
873 /// <param name="value">value to set</param>
874 /// <param name="offset">offset in the attribute value buffer</param>
875 /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of int value) is greater then length of value buffer</exception>
876 public void SetValue(IntDataType type, int value, int offset)
878 Impl.SetValue(type, value, offset);
882 /// Returns value at specified offset as float value of specified type
884 /// <param name="type">type of float value</param>
885 /// <param name="offset">offset in the attribute value buffer</param>
886 /// <returns>float value at given offset</returns>
887 /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of float value) is greater then length of value buffer</exception>
888 public float GetValue(FloatDataType type, int offset)
890 return Impl.GetValue(type, offset);
894 /// Update Value at specified offset by float value of specified type
896 /// <param name="type">type of float value</param>
897 /// <param name="mantissa">mantissa of float value</param>
898 /// <param name="exponent">exponent of float value</param>
899 /// <param name="offset">offset in the attribute value buffer</param>
900 /// <exception cref="InvalidOperationException">Throws excetion if (offset + size of float value) is greater then length of value buffer</exception>
901 public void SetValue(FloatDataType type, int mantissa, int exponent, int offset)
903 Impl.SetValue(type, mantissa, exponent, offset);
906 internal void ReleaseHandleOwnership()
908 Impl.ReleaseHandleOwnership();
911 internal BluetoothGattAttributeHandle GetHandle()
913 return Impl.GetHandle();