[Bluetooth][Non-ACR] Fix unhandled exception in GetBondedDevice() (#2514) (#3216)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Bluetooth / Tizen.Network.Bluetooth / BluetoothStructs.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 using System;
18 using System.Reflection;
19 using System.Linq;
20 using System.Collections.Generic;
21 using System.Collections.ObjectModel;
22 using System.Collections.Specialized;
23 using System.Runtime.InteropServices;
24
25 using Tizen.Internals;
26
27 namespace Tizen.Network.Bluetooth
28 {
29     /// <summary>
30     /// The structure of the device class type and service.
31     /// </summary>
32     [NativeStruct("bt_class_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
33     [StructLayout(LayoutKind.Sequential)]
34     internal struct BluetoothClassStruct
35     {
36         /// <summary>
37         /// The type of the major device class.
38         /// </summary>
39         internal BluetoothMajorDeviceClassType MajorDeviceClassType;
40         /// <summary>
41         /// The type of the minor device class.
42         /// </summary>
43         internal BluetoothMinorDeviceClassType MinorDeviceClassType;
44         /// <summary>
45         /// The major service class mask.
46         /// </summary>
47         internal int MajorServiceClassMask;
48     }
49
50     /// <summary>
51     /// This structure contains the information of the Bluetooth device.
52     /// </summary>
53     [NativeStruct("bt_device_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
54     [StructLayout(LayoutKind.Sequential)]
55     internal struct BluetoothDeviceStruct
56     {
57         /// <summary>
58         /// The address of the device.
59         /// </summary>
60         [MarshalAsAttribute(UnmanagedType.LPStr)]
61         internal string Address;
62
63         /// <summary>
64         /// The name of the device.
65         /// </summary>
66         internal IntPtr Name;
67
68         /// <summary>
69         /// The class of the device.
70         /// </summary>
71         internal BluetoothClassStruct Class;
72
73         /// <summary>
74         /// The service UUID list of the device.
75         /// </summary>
76         internal IntPtr ServiceUuidList;
77
78         /// <summary>
79         /// The service count of the device.
80         /// </summary>
81         internal int ServiceCount;
82
83         /// <summary>
84         /// The paired state of the device.
85         /// </summary>
86         [MarshalAsAttribute(UnmanagedType.I1)]
87         internal bool IsPaired;
88
89         /// <summary>
90         /// The connection state of the device.
91         /// </summary>
92         [MarshalAsAttribute(UnmanagedType.I1)]
93         internal bool IsConnected;
94
95         /// <summary>
96         /// The authorization state of the device.
97         /// </summary>
98         [MarshalAsAttribute(UnmanagedType.I1)]
99         internal bool IsAuthorized;
100
101         /// <summary>
102         /// The length of the manufacturer the data.
103         /// </summary>
104         internal int ManufacturerDataLength;
105
106         /// <summary>
107         /// The manufacturer data.
108         /// </summary>
109         internal IntPtr ManufacturerData;
110     }
111     [NativeStruct("bt_adapter_device_discovery_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
112     [StructLayout(LayoutKind.Sequential)]
113     internal struct BluetoothDiscoveredDeviceStruct
114     {
115         [MarshalAsAttribute(UnmanagedType.LPStr)]
116         internal string Address;
117
118         internal IntPtr Name;
119
120         internal BluetoothClassStruct Class;
121
122         internal int Rssi;
123
124         [MarshalAsAttribute(UnmanagedType.I1)]
125         internal bool IsPaired;
126
127         internal IntPtr ServiceUuidList;
128
129         internal int ServiceCount;
130
131         internal BluetoothAppearanceType AppearanceType;
132
133         internal int ManufacturerDataLength;
134
135         internal IntPtr ManufacturerData;
136     }
137
138     [NativeStruct("bt_device_sdp_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
139     [StructLayout(LayoutKind.Sequential)]
140     internal struct BluetoothDeviceSdpStruct
141     {
142         [MarshalAsAttribute(UnmanagedType.LPStr)]
143         internal string DeviceAddress;
144         internal IntPtr ServiceUuid;
145         internal int ServiceCount;
146     }
147
148     [NativeStruct("bt_device_connection_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
149     [StructLayout(LayoutKind.Sequential)]
150     internal struct BluetoothDeviceConnectionStruct
151     {
152         internal string Address;
153         internal BluetoothConnectionLinkType LinkType;
154         internal BluetoothDisconnectReason DisconnectReason;
155     }
156
157     [NativeStruct("bt_socket_received_data_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
158     [StructLayout(LayoutKind.Sequential)]
159     internal struct SocketDataStruct
160     {
161         internal int SocketFd;
162         internal int DataSize;
163         internal IntPtr Data;
164     }
165
166     [NativeStruct("bt_socket_connection_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
167     [StructLayout(LayoutKind.Sequential)]
168     internal struct SocketConnectionStruct
169     {
170         internal int SocketFd;
171         internal int ServerFd;
172         internal BluetoothSocketRole LocalRole;
173         internal string Address;
174         internal string ServiceUuid;
175     }
176
177     [NativeStruct("bt_adapter_le_device_scan_result_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
178     [StructLayout(LayoutKind.Sequential)]
179     internal struct BluetoothLeScanDataStruct
180     {
181         [MarshalAsAttribute(UnmanagedType.LPStr)]
182         internal string RemoteAddress;
183
184         internal BluetoothLeDeviceAddressType AddressType;
185
186         internal int Rssi;
187
188         internal int AdvDataLength;
189
190         internal IntPtr AdvData;
191
192         internal int ScanDataLength;
193
194         internal IntPtr ScanData;
195     }
196
197     [NativeStruct("bt_adapter_le_service_data_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
198     [StructLayout(LayoutKind.Sequential)]
199     internal struct BluetoothLeServiceDataStruct
200     {
201         /// <summary>
202         /// The Bluetooth LE service UUID.
203         /// </summary>
204         [MarshalAs(UnmanagedType.LPStr)]
205         internal string ServiceUuid;
206         /// <summary>
207         /// The Bluetooth LE service data.
208         /// </summary>
209         internal IntPtr ServiceData;
210
211         internal int ServiceDataLength;
212     }
213
214     [NativeStruct("bt_hid_device_received_data_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
215     [StructLayout(LayoutKind.Sequential)]
216     internal struct BluetoothHidDeviceReceivedDataStruct
217     {
218         [MarshalAsAttribute(UnmanagedType.LPStr)]
219         internal string RemoteAddress;
220         internal BluetoothHidHeaderType headerType;
221         internal BluetoothHidParamType paramType;
222         internal int dataSize;
223         internal IntPtr data;
224     }
225
226     [NativeStruct("bt_avrcp_metadata_attributes_info_s", Include="bluetooth_type.h", PkgConfig="capi-network-bluetooth")]
227     [StructLayout(LayoutKind.Sequential)]
228     internal struct TrackInfoStruct
229     {
230         internal IntPtr Title;
231         internal IntPtr Artist;
232         internal IntPtr Album;
233         internal IntPtr Genre;
234         internal uint total_tracks;
235         internal uint number;
236         internal uint duration;
237     }
238
239     [NativeStruct("bt_gatt_client_att_mtu_info_s", Include = "bluetooth_type.h", PkgConfig = "capi-network-bluetooth")]
240     [StructLayout(LayoutKind.Sequential)]
241     internal struct AttMtuInfoStruct
242     {
243         [MarshalAsAttribute(UnmanagedType.LPStr)]
244         internal string RemoteAddress;
245         internal int Mtu;
246         internal int Status;
247     }
248
249     internal static class BluetoothUtils
250     {
251         internal static BluetoothDevice ConvertStructToDeviceClass(BluetoothDeviceStruct device)
252         {
253             const int DeviceNameLengthMax = 248;
254             const int UuidLengthMax = 50;
255
256             BluetoothDevice resultDevice = new BluetoothDevice();
257             Collection<string> uuidList = null;
258
259             if (device.ServiceCount > 0)
260             {
261                 IntPtr[] extensionList = new IntPtr[device.ServiceCount];
262                 Marshal.Copy (device.ServiceUuidList, extensionList, 0, device.ServiceCount);
263                 uuidList = new Collection<string> ();
264                 foreach (IntPtr extension in extensionList) {
265                     if (extension != IntPtr.Zero)
266                     {
267                         string uuid = Marshal.PtrToStringAnsi (extension, UuidLengthMax);
268                         uuidList.Add (uuid);
269                     }
270                 }
271             }
272
273             resultDevice.RemoteDeviceAddress = device.Address;
274             if (device.Name != IntPtr.Zero)
275                 resultDevice.RemoteDeviceName = Marshal.PtrToStringAnsi(device.Name, DeviceNameLengthMax);
276             resultDevice.RemoteDeviceClass = new BluetoothClass();
277             resultDevice.Class.MajorType = device.Class.MajorDeviceClassType;
278             resultDevice.Class.MinorType = device.Class.MinorDeviceClassType;
279             resultDevice.Class.Mask = device.Class.MajorServiceClassMask;
280             resultDevice.RemotePaired = device.IsPaired;
281             resultDevice.RemoteConnected = device.IsConnected;
282             resultDevice.RemoteAuthorized = device.IsAuthorized;
283             resultDevice.RemoteDeviceService = uuidList;
284             resultDevice.RemoteDeviceCount = device.ServiceCount;
285             resultDevice.RemoteManufLength = device.ManufacturerDataLength;
286
287             if (device.ManufacturerData != IntPtr.Zero)
288                 resultDevice.RemoteManufData = Marshal.PtrToStringAnsi(device.ManufacturerData, device.ManufacturerDataLength);
289
290             return resultDevice;
291         }
292
293         internal static BluetoothDevice ConvertStructToDiscoveredDevice(BluetoothDiscoveredDeviceStruct structDevice)
294         {
295             BluetoothDevice resultDevice = new BluetoothDevice();
296             Collection<string> uuidList = null;
297             const int DeviceNameLengthMax = 248;
298             const int UuidLengthMax = 50;
299
300             if (structDevice.ServiceCount > 0) {
301                 IntPtr[] extensionList = new IntPtr[structDevice.ServiceCount];
302                 Marshal.Copy (structDevice.ServiceUuidList, extensionList, 0, structDevice.ServiceCount);
303                 uuidList = new Collection<string> ();
304                 foreach (IntPtr extension in extensionList) {
305                     if (extension != IntPtr.Zero)
306                     {
307                         string uuid = Marshal.PtrToStringAnsi(extension, UuidLengthMax);
308                         uuidList.Add(uuid);
309                     }
310                 }
311             }
312
313             resultDevice.RemoteDeviceAddress = structDevice.Address;
314             if (structDevice.Name != IntPtr.Zero)
315                 resultDevice.RemoteDeviceName = Marshal.PtrToStringAnsi(structDevice.Name, DeviceNameLengthMax);
316
317             resultDevice.RemoteDeviceClass = new BluetoothClass();
318             resultDevice.Class.MajorType = structDevice.Class.MajorDeviceClassType;
319             resultDevice.Class.MinorType = structDevice.Class.MinorDeviceClassType;
320             resultDevice.Class.Mask = structDevice.Class.MajorServiceClassMask;
321
322             resultDevice.RemoteDeviceRssi = structDevice.Rssi;
323             resultDevice.RemoteAppearance = structDevice.AppearanceType;
324
325             if (structDevice.ServiceCount > 0) {
326                 resultDevice.RemoteDeviceService = uuidList;
327                 resultDevice.RemoteDeviceCount = structDevice.ServiceCount;
328             }
329
330             resultDevice.RemotePaired = structDevice.IsPaired;
331             resultDevice.RemoteManufLength = structDevice.ManufacturerDataLength;
332
333             if (structDevice.ManufacturerData != IntPtr.Zero)
334                 resultDevice.RemoteManufData = Marshal.PtrToStringAnsi(structDevice.ManufacturerData, structDevice.ManufacturerDataLength);
335
336             return resultDevice;
337         }
338
339         internal static BluetoothDeviceSdpData ConvertStructToSdpData(BluetoothDeviceSdpStruct structData)
340         {
341             BluetoothDeviceSdpData resultData = new BluetoothDeviceSdpData();
342             Collection<string> uuidList = null;
343
344             if (structData.ServiceCount > 0) {
345                 IntPtr[] extensionList = new IntPtr[structData.ServiceCount];
346                 Marshal.Copy (structData.ServiceUuid, extensionList, 0, structData.ServiceCount);
347                 uuidList = new Collection<string> ();
348                 foreach (IntPtr extension in extensionList) {
349                     string uuid = Marshal.PtrToStringAnsi (extension);
350                     uuidList.Add (uuid);
351                 }
352             }
353
354             resultData.Uuid = uuidList;
355             resultData.Address = structData.DeviceAddress;
356
357             return resultData;
358         }
359
360         internal static BluetoothDeviceConnectionData ConvertStructToConnectionData(BluetoothDeviceConnectionStruct structInfo)
361         {
362             BluetoothDeviceConnectionData resultData = new BluetoothDeviceConnectionData();
363             resultData.RemoteAddress = structInfo.Address;
364             resultData.Link = structInfo.LinkType;
365             resultData.Reason = structInfo.DisconnectReason;
366             return resultData;
367         }
368
369         internal static BluetoothLeScanData ConvertStructToLeScanData(BluetoothLeScanDataStruct structScanData)
370         {
371             BluetoothLeScanData scanData = new BluetoothLeScanData();
372
373             scanData.RemoteAddress = structScanData.RemoteAddress;
374             scanData.AddressType = structScanData.AddressType;
375             scanData.Rssi = structScanData.Rssi;
376
377             if (structScanData.AdvDataLength > 0)
378             {
379                 scanData.AdvDataLength = structScanData.AdvDataLength;
380                 scanData.AdvData = new byte[scanData.AdvDataLength];
381                 Marshal.Copy (structScanData.AdvData, scanData.AdvData, 0, scanData.AdvDataLength);
382             }
383
384             if (structScanData.ScanDataLength > 0)
385             {
386                 scanData.ScanDataLength = structScanData.ScanDataLength;
387                 scanData.ScanData = new byte[scanData.ScanDataLength];
388                 Marshal.Copy (structScanData.ScanData, scanData.ScanData, 0, scanData.ScanDataLength);
389             }
390             return scanData;
391         }
392
393         internal static BluetoothLeScanDataStruct ConvertLeScanDataToStruct(BluetoothLeScanData scanData)
394         {
395             BluetoothLeScanDataStruct scanDataStruct = new BluetoothLeScanDataStruct();
396
397             scanDataStruct.RemoteAddress = scanData.RemoteAddress;
398             scanDataStruct.AddressType = scanData.AddressType;
399             scanDataStruct.Rssi = scanData.Rssi;
400
401             if (scanData.AdvDataLength > 0)
402             {
403                 scanDataStruct.AdvDataLength = scanData.AdvDataLength;
404                 scanDataStruct.AdvData = Marshal.AllocHGlobal(scanData.AdvDataLength);
405                 Marshal.Copy (scanData.AdvData, 0, scanDataStruct.AdvData, scanData.AdvDataLength);
406             }
407
408             if (scanData.ScanDataLength > 0)
409             {
410                 scanDataStruct.ScanDataLength = scanData.ScanDataLength;
411                 scanDataStruct.ScanData = Marshal.AllocHGlobal(scanData.ScanDataLength);
412                 Marshal.Copy (scanData.ScanData, 0, scanDataStruct.ScanData, scanData.ScanDataLength);
413             }
414
415             return scanDataStruct;
416         }
417
418         internal static BluetoothLeServiceData ConvertStructToLeServiceData(BluetoothLeServiceDataStruct structServiceData)
419         {
420             BluetoothLeServiceData serviceData = new BluetoothLeServiceData();
421             Log.Info(Globals.LogTag, "ServiceDataLength" + structServiceData.ServiceDataLength);
422
423             if (structServiceData.ServiceDataLength > 0)
424             {
425                 serviceData.Uuid = structServiceData.ServiceUuid;
426                 serviceData.Length = structServiceData.ServiceDataLength;
427                 serviceData.Data = new byte[serviceData.Length];
428                 Marshal.Copy(structServiceData.ServiceData, serviceData.Data, 0, serviceData.Length);
429             }
430             return serviceData;
431         }
432
433         internal static SocketData ConvertStructToSocketData(SocketDataStruct structInfo)
434         {
435             SocketData data = new SocketData();
436             Log.Info(Globals.LogTag, "SocketDataLength" + structInfo.DataSize);
437
438             data._fd = structInfo.SocketFd;
439             if (structInfo.DataSize > 0)
440             {
441                 data._dataSize = structInfo.DataSize;
442                 data._data = new byte[data._dataSize];
443                 Marshal.Copy(structInfo.Data, data._data, 0, data._dataSize);
444                 data._recvData = Marshal.PtrToStringAnsi(structInfo.Data, structInfo.DataSize);
445             }
446             return data;
447         }
448
449         internal static SocketConnection ConvertStructToSocketConnection(SocketConnectionStruct structInfo)
450         {
451             SocketConnection connectionInfo = new SocketConnection();
452             connectionInfo.Fd = structInfo.SocketFd;
453             connectionInfo.RemoteAddress = structInfo.Address;
454             connectionInfo.Uuid = structInfo.ServiceUuid;
455             connectionInfo.ServerFd = structInfo.ServerFd;
456
457             BluetoothSocket clientSocket = new BluetoothSocket();
458             clientSocket.connectedSocket = structInfo.SocketFd;
459             clientSocket.remoteAddress = structInfo.Address;
460             clientSocket.serviceUuid = structInfo.ServiceUuid;
461             connectionInfo.ClientSocket = (IBluetoothServerSocket)clientSocket;
462
463             return connectionInfo;
464         }
465     }
466 }
467