sicpaconnexions / SICPA_Connexions / Model / GestionnaireBLE.cs @ 87e7d061
Historique | Voir | Annoter | Télécharger (8,874 ko)
1 | 87e7d061 | ajournaux | using Plugin.BLE; |
---|---|---|---|
2 | using Plugin.BLE.Abstractions; |
||
3 | using Plugin.BLE.Abstractions.Contracts; |
||
4 | using Plugin.BLE.Abstractions.EventArgs; |
||
5 | using System; |
||
6 | using System.Collections.Generic; |
||
7 | using System.Linq; |
||
8 | using System.Text; |
||
9 | using System.Threading.Tasks; |
||
10 | |||
11 | namespace SICPA_Connexions.Model |
||
12 | { |
||
13 | public class GestionnaireBLE |
||
14 | { |
||
15 | // Class for the Bluetooth adapter |
||
16 | private readonly IAdapter bluetoothAdapter; |
||
17 | // Empty list to store BLE devices that can be detected by the Bluetooth adapter |
||
18 | private List<IDevice> gattDevices; |
||
19 | private List<IService> servicesList; |
||
20 | private List<ICharacteristic> charList; |
||
21 | private ICharacteristic characRead; |
||
22 | private ICharacteristic characWrite; |
||
23 | public IDevice DeviceConnected { get; set; } |
||
24 | public IService SelectedService { get; set; } |
||
25 | public String RetourBLE { get; set; } |
||
26 | |||
27 | public GestionnaireBLE() |
||
28 | { |
||
29 | gattDevices = new List<IDevice>(); |
||
30 | servicesList = new List<IService>(); |
||
31 | charList = new List<ICharacteristic>(); // List for the available Characteristics on the BLE Device |
||
32 | bluetoothAdapter = CrossBluetoothLE.Current.Adapter; // Point bluetoothAdapter to the current adapter on the phone |
||
33 | bluetoothAdapter.DeviceDiscovered += (sender, foundBleDevice) => // When a BLE Device is found, run the small function below to add it to our list |
||
34 | { |
||
35 | if (foundBleDevice.Device != null && !string.IsNullOrEmpty(foundBleDevice.Device.Name)) |
||
36 | gattDevices.Add(foundBleDevice.Device); |
||
37 | }; |
||
38 | } |
||
39 | |||
40 | |||
41 | public async Task ScanBLE() |
||
42 | { |
||
43 | |||
44 | if (!await PermissionsGrantedAsync()) // Make sure there is permission to use Bluetooth |
||
45 | { |
||
46 | await Application.Current.MainPage.DisplayAlert("Persmission requise", "L'application a besoin des permissions locales", "OK"); |
||
47 | return; |
||
48 | } |
||
49 | |||
50 | gattDevices.Clear(); // Also clear the _gattDevices list |
||
51 | |||
52 | if (!bluetoothAdapter.IsScanning) // Make sure that the Bluetooth adapter is scanning for devices |
||
53 | { |
||
54 | await bluetoothAdapter.StartScanningForDevicesAsync(); |
||
55 | } |
||
56 | |||
57 | foreach (var device in bluetoothAdapter.ConnectedDevices) // Make sure BLE devices are added to the _gattDevices list |
||
58 | gattDevices.Add(device); |
||
59 | |||
60 | foreach (var device in bluetoothAdapter.BondedDevices) |
||
61 | gattDevices.Add(device); |
||
62 | |||
63 | foreach (IDevice item in gattDevices) |
||
64 | { |
||
65 | if (item.Name.Contains("SICPA")) |
||
66 | { |
||
67 | if (item.State == DeviceState.Connected) // Check first if we are already connected to the BLE Device |
||
68 | { |
||
69 | await RecuperationServices(item); |
||
70 | } |
||
71 | else |
||
72 | { |
||
73 | try |
||
74 | { |
||
75 | var connectParameters = new ConnectParameters(false, true); |
||
76 | await bluetoothAdapter.ConnectToDeviceAsync(item, connectParameters); // if we are not connected, then try to connect to the BLE Device selected |
||
77 | await RecuperationServices(item); |
||
78 | } |
||
79 | catch |
||
80 | { |
||
81 | await Application.Current.MainPage.DisplayAlert("Erreur de connexion", "Erreur de connexion au BLE " + item.Name, "OK"); |
||
82 | } |
||
83 | } |
||
84 | } |
||
85 | } |
||
86 | } |
||
87 | |||
88 | private async Task<bool> PermissionsGrantedAsync() // Function to make sure that all the appropriate approvals are in place |
||
89 | { |
||
90 | var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>(); |
||
91 | |||
92 | if (status != PermissionStatus.Granted) |
||
93 | { |
||
94 | status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>(); |
||
95 | } |
||
96 | |||
97 | return status == PermissionStatus.Granted; |
||
98 | } |
||
99 | |||
100 | private async Task RecuperationServices(IDevice device) |
||
101 | { |
||
102 | try |
||
103 | { |
||
104 | var servicesListReadOnly = await device.GetServicesAsync(); // Read in the Services available |
||
105 | |||
106 | servicesList.Clear(); |
||
107 | for (int i = 0; i < servicesListReadOnly.Count; i++) // Cycle through the found interfaces |
||
108 | { |
||
109 | servicesList.Add(servicesListReadOnly[i]); // Write to a list of service interfaces |
||
110 | if (servicesListReadOnly[i].Id.ToString().Substring(0, 8) == "6e400001") |
||
111 | { |
||
112 | SelectedService = servicesListReadOnly[i]; |
||
113 | } |
||
114 | } |
||
115 | if (SelectedService != null) |
||
116 | { |
||
117 | var charListReadOnly = await SelectedService.GetCharacteristicsAsync(); // Read in available Characteristics |
||
118 | |||
119 | charList.Clear(); |
||
120 | for (int i = 0; i < charListReadOnly.Count; i++) // Cycle through available interfaces |
||
121 | { |
||
122 | charList.Add(charListReadOnly[i]); // Write to a list of Chars |
||
123 | // IMPORTANT: listview cannot cope with entries that have the exact same name. That is why I added "i" to the beginning of the name. If you add the UUID you can delete "i" again. |
||
124 | if (charListReadOnly[i].CanRead || charListReadOnly[i].CanUpdate) |
||
125 | { |
||
126 | characRead = charListReadOnly[i]; |
||
127 | characRead.ValueUpdated += CharacRead_ValueUpdated; |
||
128 | } |
||
129 | if (charListReadOnly[i].CanWrite) characWrite = charListReadOnly[i]; |
||
130 | } |
||
131 | DeviceConnected = device; |
||
132 | } |
||
133 | else |
||
134 | { |
||
135 | await Application.Current.MainPage.DisplayAlert("Erreur récupération Characteristics", "Erreur récupération Characteristics", "OK"); |
||
136 | } |
||
137 | } |
||
138 | catch |
||
139 | { |
||
140 | await Application.Current.MainPage.DisplayAlert("Erreur d'initialisation", "Erreur d'initialisation aux services", "OK"); |
||
141 | } |
||
142 | } |
||
143 | |||
144 | private void CharacRead_ValueUpdated(object sender, CharacteristicUpdatedEventArgs args) |
||
145 | { |
||
146 | var receivedBytes = args.Characteristic.Value; // read in received bytes |
||
147 | Console.WriteLine("byte array: " + BitConverter.ToString(receivedBytes)); // write to the console for debugging |
||
148 | |||
149 | |||
150 | string charStrBytes = ""; // in the following section the received bytes will be displayed in different ways (you can select the method you need) |
||
151 | string charStrUTF8 = ""; |
||
152 | if (receivedBytes != null) |
||
153 | { |
||
154 | charStrBytes = "Bytes : " + BitConverter.ToString(receivedBytes); // by directly converting the bytes to strings we see the bytes themselves as they are received |
||
155 | charStrUTF8 = Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length); // This code interprets the bytes received as ASCII characters |
||
156 | } |
||
157 | |||
158 | if (receivedBytes.Length <= 4) |
||
159 | { // If only 4 or less bytes were received than it could be that an INT was sent. The code here combines the 4 bytes back to an INT |
||
160 | int char_val = 0; |
||
161 | for (int i = 0; i < receivedBytes.Length; i++) |
||
162 | { |
||
163 | char_val |= (receivedBytes[i] << i * 8); |
||
164 | } |
||
165 | charStrBytes += " | int: " + char_val.ToString(); |
||
166 | } |
||
167 | RetourBLE = RetourBLE + charStrUTF8; |
||
168 | //_charStr += Environment.NewLine; // the NewLine command is added to go to the next line |
||
169 | |||
170 | //MainThread.BeginInvokeOnMainThread(() => // as this is a callback function, the "MainThread" needs to be invoked to update the GUI |
||
171 | //{ |
||
172 | // Output.Text += _charStr; |
||
173 | //}); |
||
174 | } |
||
175 | |||
176 | } |
||
177 | } |