Révision 0875d625 TestTeoBluetooth/TestTeoBluetooth.Android/Connection/BluetoothConnection.cs

Voir les différences:

TestTeoBluetooth/TestTeoBluetooth.Android/Connection/BluetoothConnection.cs
1 1
using Android.App;
2
using Android.Bluetooth;
2 3
using Android.Content;
3 4
using Android.OS;
4 5
using Android.Runtime;
5 6
using Android.Views;
6 7
using Android.Widget;
8
using Java.Util;
7 9
using System;
8 10
using System.Collections.Generic;
11
using System.IO;
9 12
using System.Linq;
10 13
using System.Text;
14
using System.Threading;
15
using System.Threading.Tasks;
16
using TeoTestBluetooth.Droid.Utils;
17
using TeoTestBluetooth.Models;
18
using TestTeoBluetooth.Connection;
11 19

  
12 20
namespace TestBLE.Droid.Connection
13 21
{
14 22
    /* Classe permettant d'établir une connection Bluetooth
15 23
     * Avec socket RFCOMM connecté au SPP
16 24
     */
17
    public class BluetoothConnection
25
    public class BluetoothConnection : IBluetoothConnectionService
18 26
    {
19 27

  
28
        private readonly BluetoothAdapter bluetoothAdapter;
29
        private Thread listeningThread;
30
        private BluetoothSocket socket;
31
        private readonly string sppUUID = "00001101-0000-1000-8000-00805f9b34fb";
32

  
33
        public BluetoothConnection()
34
        { 
35
            bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
36
        }
37
        public async Task<bool> Connect(Device btDevice)
38
        {
39
            try
40
            {
41
                // Si jamais on est en train de scanner
42
                // On annule le scan
43
                if (bluetoothAdapter.IsDiscovering)
44
                {
45
                    bluetoothAdapter.CancelDiscovery();
46
                }
47

  
48
                BluetoothDevice droidBtDevice = bluetoothAdapter.GetRemoteDevice(btDevice.MACAddress);
49
                //Android.Bluetooth.BluetoothDevice droidBtDevice = adapter.BondedDevices.FirstOrDefault(x => (x.Address == bluetoothDevice.Address));
50
                if (droidBtDevice != null)
51
                {
52
                    // Si le socket est occupé pour une autre connexion
53
                    // On ferme la connexion existante
54
                    if (socket != null)
55
                    {
56
                        await CloseConnection();
57
                    }
58

  
59
                    // Creation du canal RFCOMM (non sécurisé)
60
                    socket = droidBtDevice.CreateInsecureRfcommSocketToServiceRecord(UUID.FromString(sppUUID));
61

  
62
                    CancellationTokenSource cts = new CancellationTokenSource();
63

  
64
                    cts.CancelAfter(50000);
65
                    await socket.ConnectAsync().WithCancellation(cts.Token);
66

  
67
                    if (listeningThread != null) listeningThread.Abort();
68
                    listeningThread = new Thread(async delagate => await ListeningAsync());
69
                    listeningThread.Start();
70

  
71
                    return true;
72
                }
73
            }
74
            catch (Exception ex)
75
            {
76
                System.Diagnostics.Debug.WriteLine(ex);
77
            }
78

  
79
            return false;
80
        }
81

  
82
        // Fonction d'écoute pour le Thread d'écoute
83
        private async Task ListeningAsync()
84
        {
85
            try
86
            {
87
                byte[] buffer = new byte[1024];
88
                while (socket.IsConnected)
89
                {
90
                    int byteAvailable = await socket.InputStream.ReadAsync(buffer, 0, buffer.Length);
91
                    // Resize the byte array 
92
                    byte[] filledBuffer = buffer.Take(byteAvailable).ToArray();
93
                    Application.SynchronizationContext.Post(_ => { OnDataReceived(filledBuffer); }, null);
94
                }
95
            }
96
            catch (IOException ex)
97
            {
98
                System.Diagnostics.Debug.WriteLine(ex);
99
            }
100
            catch (ThreadAbortException taEx)
101
            {
102
                System.Diagnostics.Debug.WriteLine(taEx);
103
            }
104
            catch (Exception ex)
105
            {
106
                System.Diagnostics.Debug.WriteLine(ex);
107
            }
108
        }
109

  
110
        public EventHandler<string> DataReceivedEvent { get; set; }
111
        private string _bufferedData;
112

  
113
        /* 
114
         * Fonction appelée à la reception de données
115
         * Trigger l'evenement DataReceivedEvent
116
         * 
117
         * IMPORTANT: Les trames peuvent arriver découpées,
118
         * Donc les données sont gardées dans un buffer d'envoi
119
         * nommé _bufferedData
120
         */
121
        private void OnDataReceived(byte[] buffer)
122
        {
123
            // Si le premier character est 2 (ASCII: STX)
124
            // Alors c'est le début de la trame.
125
            if (buffer[0] == 2)
126
            {
127
                _bufferedData = "";
128
                // Si character seul on quitte
129
                if (buffer.Length == 1)
130
                {
131
                    return;
132
                }
133
                // On enlève STX
134
                buffer = buffer.Skip(1).ToArray();
135
                // On mets le début de la trame dans buffer d'envoi
136
                _bufferedData += Encoding.ASCII.GetString(buffer);
137
            }
138

  
139
            // Si le dernier character est 13 (ASCII: CR)
140
            // Alors la trame est terminée
141
            if (buffer[^1] == 13)
142
            {
143
                // On enlève CR
144
                buffer = buffer.SkipLast(1).ToArray();
145
                // Conversion en chaîne de caractères
146
                // Et on complète le buffer d'envoi
147
                _bufferedData += Encoding.ASCII.GetString(buffer);
148
                // Trigger evènement
149
                DataReceivedEvent.Invoke(this, _bufferedData);
150
            }
151
        }
152

  
153
        private Task<bool> CloseConnection()
154
        {
155
            while (socket.IsConnected) socket.Close();
156
            return Task.FromResult(true);
157
        }
158

  
159
        public Task<bool> SendCommand(byte[] hexValues)
160
        {
161
            if (socket.IsConnected == false)
162
            {
163
                return Task.FromResult(false);
164
            }
165
            else
166
            {
167
                // Envoi de la commande
168
                socket.OutputStream.Write(hexValues, 0, hexValues.Length);
169
                socket.OutputStream.Flush();
170
            }
171
            return Task.FromResult(true);
172
        }
173

  
20 174
    }
21 175
}

Formats disponibles : Unified diff