Statistiques
| Branche: | Révision:

sicpaconnexions / SICPA_Connexions / Model / GestionnaireBLE.cs @ 03682d21

Historique | Voir | Annoter | Télécharger (10,761 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 03682d21 ajournaux
        private String retourBLE;
24
        public event EventHandler RetourBlEMofifiee;
25 87e7d061 ajournaux
        public IDevice DeviceConnected { get; set; }
26
        public IService SelectedService { get; set; }
27 03682d21 ajournaux
        public String RetourBLE
28
        {
29
            get
30
            {
31
                return retourBLE;
32
            }
33
            set
34
            {
35
                if (retourBLE != value)
36
                {
37
                    retourBLE = value;
38
                    OnRetourBLEMofifiee(EventArgs.Empty);
39
                }
40
            }
41
        }
42
43
        public void OnRetourBLEMofifiee(EventArgs e)
44
        {
45
            RetourBlEMofifiee?.Invoke(this, e);
46
        }
47 87e7d061 ajournaux
48
        public GestionnaireBLE()
49
        {
50
            gattDevices = new List<IDevice>();
51
            servicesList = new List<IService>();
52
            charList = new List<ICharacteristic>(); // List for the available Characteristics on the BLE Device
53
            bluetoothAdapter = CrossBluetoothLE.Current.Adapter;               // Point bluetoothAdapter to the current adapter on the phone
54
            bluetoothAdapter.DeviceDiscovered += (sender, foundBleDevice) =>   // When a BLE Device is found, run the small function below to add it to our list
55
            {
56
                if (foundBleDevice.Device != null && !string.IsNullOrEmpty(foundBleDevice.Device.Name))
57
                    gattDevices.Add(foundBleDevice.Device);
58
            };
59
        }
60
61
     
62
        public async Task ScanBLE()
63
        {
64
65
            if (!await PermissionsGrantedAsync())                                                           // Make sure there is permission to use Bluetooth
66
            {
67
                await Application.Current.MainPage.DisplayAlert("Persmission requise", "L'application a besoin des permissions locales", "OK");
68
                return;
69
            }
70
71
            gattDevices.Clear();                                                                           // Also clear the _gattDevices list
72
73
            if (!bluetoothAdapter.IsScanning)                                                              // Make sure that the Bluetooth adapter is scanning for devices
74
            {
75
                await bluetoothAdapter.StartScanningForDevicesAsync();
76
            }
77
78
            foreach (var device in bluetoothAdapter.ConnectedDevices)                                      // Make sure BLE devices are added to the _gattDevices list
79
                gattDevices.Add(device);
80
81
            foreach (var device in bluetoothAdapter.BondedDevices)
82
                gattDevices.Add(device);
83
84
            foreach (IDevice item in gattDevices)
85
            {
86
                if (item.Name.Contains("SICPA"))
87
                {
88
                    if (item.State == DeviceState.Connected)                                                // Check first if we are already connected to the BLE Device 
89
                    {
90
                        await RecuperationServices(item);
91
                    }
92
                    else
93
                    {
94
                        try
95
                        {
96
                            var connectParameters = new ConnectParameters(false, true);
97
                            await bluetoothAdapter.ConnectToDeviceAsync(item, connectParameters);          // if we are not connected, then try to connect to the BLE Device selected
98
                            await RecuperationServices(item);
99
                        }
100
                        catch
101
                        {
102
                            await Application.Current.MainPage.DisplayAlert("Erreur de connexion", "Erreur de connexion au BLE " + item.Name, "OK");
103
                        }
104
                    }
105
                }
106
            }
107
        }
108
109
        private async Task<bool> PermissionsGrantedAsync()      // Function to make sure that all the appropriate approvals are in place
110
        {
111
            var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
112
113
            if (status != PermissionStatus.Granted)
114
            {
115
                status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
116
            }
117
118
            return status == PermissionStatus.Granted;
119
        }
120
121
        private async Task RecuperationServices(IDevice device)
122
        {
123
            try
124
            {
125
                var servicesListReadOnly = await device.GetServicesAsync();           // Read in the Services available
126
127
                servicesList.Clear();
128
                for (int i = 0; i < servicesListReadOnly.Count; i++)                             // Cycle through the found interfaces
129
                {
130
                    servicesList.Add(servicesListReadOnly[i]);                                 // Write to a list of service interfaces
131
                    if (servicesListReadOnly[i].Id.ToString().Substring(0, 8) == "6e400001")
132
                    {
133
                        SelectedService = servicesListReadOnly[i];
134
                    }
135
                }
136
                if (SelectedService != null)
137
                {
138
                    var charListReadOnly = await SelectedService.GetCharacteristicsAsync();       // Read in available Characteristics
139
140
                    charList.Clear();
141
                    for (int i = 0; i < charListReadOnly.Count; i++)                               // Cycle through available interfaces
142
                    {
143
                        charList.Add(charListReadOnly[i]);                                        // Write to a list of Chars
144
                        // 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.
145
                        if (charListReadOnly[i].CanRead || charListReadOnly[i].CanUpdate)
146
                        {
147
                            characRead = charListReadOnly[i];
148
                            characRead.ValueUpdated += CharacRead_ValueUpdated;
149
                        }
150
                        if (charListReadOnly[i].CanWrite) characWrite = charListReadOnly[i];
151
                    }
152
                    DeviceConnected = device;
153
                }
154
                else
155
                {
156
                    await Application.Current.MainPage.DisplayAlert("Erreur récupération Characteristics", "Erreur récupération Characteristics", "OK");
157
                }
158
            }
159
            catch
160
            {
161
                await Application.Current.MainPage.DisplayAlert("Erreur d'initialisation", "Erreur d'initialisation aux services", "OK");
162
            }
163
        }
164
165
        private void CharacRead_ValueUpdated(object sender, CharacteristicUpdatedEventArgs args)
166
        {
167
            var receivedBytes = args.Characteristic.Value;                              // read in received bytes
168
            Console.WriteLine("byte array: " + BitConverter.ToString(receivedBytes));   // write to the console for debugging
169
170
171
            string charStrBytes = "";                                                                           // in the following section the received bytes will be displayed in different ways (you can select the method you need)
172
            string charStrUTF8 = "";
173
            if (receivedBytes != null)
174
            {
175
                charStrBytes = "Bytes : " + BitConverter.ToString(receivedBytes);                                // by directly converting the bytes to strings we see the bytes themselves as they are received
176
                charStrUTF8 = Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length);  // This code interprets the bytes received as ASCII characters
177
            }
178
179
            if (receivedBytes.Length <= 4)
180
            {                                                                                               // 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
181
                int char_val = 0;
182
                for (int i = 0; i < receivedBytes.Length; i++)
183
                {
184
                    char_val |= (receivedBytes[i] << i * 8);
185
                }
186
                charStrBytes += " | int: " + char_val.ToString();
187
            }
188
            RetourBLE = RetourBLE + charStrUTF8;
189
            //_charStr += Environment.NewLine;                                                                // the NewLine command is added to go to the next line
190
191
            //MainThread.BeginInvokeOnMainThread(() =>                                      // as this is a callback function, the "MainThread" needs to be invoked to update the GUI
192
            //{
193
            //    Output.Text += _charStr;
194
            //});
195
        }
196
197 03682d21 ajournaux
        public  async Task LectureTag(IDevice deviceConnected)
198
        {
199
            try
200
            {
201
                String cmd = "READ";
202
203
                List<byte> local_frame = new List<byte>();
204
                CRC crcProcess = new CRC();
205
                byte local_crc;
206
207
                local_frame.Add(BytesPrtc.STX); //add STX byte
208
                local_frame.Add(BytesPrtc.DST_TX); //add DST byte
209
                local_frame.Add(BytesPrtc.SRC_TX); //add SRC byte
210
                for (int i = 0; i < cmd.Length; i++)
211
                {
212
                    local_frame.Add((byte)cmd[i]); //add cmd string 
213
                }
214
                crcProcess.putBytes(local_frame.ToArray()); //send that buffer (without "the CRC" and ETX bytes !)
215
                local_crc = crcProcess.getCRC(); //calculate CRC with that buffer
216
217
                local_frame.Add(local_crc); //add CRC byte
218
                local_frame.Add(BytesPrtc.ETX); //add ETX byte
219
220
                /////////////////////////////////////////////
221
                //And now send buffer !
222
                await characWrite.WriteAsync(local_frame.ToArray());
223
                await characRead.StartUpdatesAsync();
224
            }
225
            catch
226
            {
227
                await Application.Current.MainPage.DisplayAlert("Erreur de lecture", "Erreur de lecture du Tag", "OK");
228
            }
229
        }
230
231 87e7d061 ajournaux
    }
232
}