Statistiques
| Branche: | Révision:

sicpaconnexions / SICPA_Connexions / Model / GestionnaireBLE.cs @ 87e7d061

Historique | Voir | Annoter | Télécharger (8,874 ko)

1
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
}