// originally based on http://developer.nokia.com/community/wiki/Windows_Phone_8_communicating_with_Arduino_using_Bluetooth using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; namespace BluetoothConnectionManager { /// /// Class to control the bluetooth connection to the Arduino. /// public class ConnectionManager { /// /// Socket used to communicate with Arduino. /// private StreamSocket socket; /// /// DataWriter used to send commands easily. /// private DataWriter dataWriter; /// /// DataReader used to receive messages easily. /// private DataReader dataReader; /// /// Thread used to keep reading data from socket. /// private BackgroundWorker dataReadWorker; /// /// Delegate used by event handler. /// /// The message received. public delegate void ByteReceivedHandler(byte data); /// /// Event fired when a new byte is received from Arduino. /// public event ByteReceivedHandler ByteReceived; // TODO this event stuff is probably overkill public delegate void ConnectionSuccessHandler(); public delegate void ConnectionFailureHandler(string reason); public event ConnectionSuccessHandler ConnectionSuccess; public event ConnectionFailureHandler ConnectionFailure; /// /// Initialize the manager, should be called in OnNavigatedTo of main page. /// public void Initialize() { socket = new StreamSocket(); dataReadWorker = new BackgroundWorker(); dataReadWorker.WorkerSupportsCancellation = true; dataReadWorker.DoWork += new DoWorkEventHandler(ReceiveMessages); } /// /// Finalize the connection manager, should be called in OnNavigatedFrom of main page. /// public void Terminate() { if (socket != null) { socket.Dispose(); } if (dataReadWorker != null) { dataReadWorker.CancelAsync(); } } /// /// Connect to the given host device. /// /// The host device name. public async void Connect(HostName deviceHostName) { if (socket != null) { try { await socket.ConnectAsync(deviceHostName, "1"); dataReader = new DataReader(socket.InputStream); dataReadWorker.RunWorkerAsync(); dataWriter = new DataWriter(socket.OutputStream); } catch (Exception ex) { Debug.WriteLine(ex); ConnectionFailure(ex.Message); } } else { ConnectionFailure("Socket is null"); } } /// /// Receive messages from the Arduino through bluetooth. /// private async void ReceiveMessages(object sender, DoWorkEventArgs e) { Debug.WriteLine("Received Message Worker"); ConnectionSuccess(); try { while (true) { // TODO see if there's a better way to do this uint sizeFieldCount = await dataReader.LoadAsync(1); if (sizeFieldCount != 1) { // The underlying socket was closed before we were able to read the whole data. ConnectionFailure("Socket closed"); return; } uint bite = dataReader.ReadByte(); Debug.WriteLine(bite); ByteReceived((byte)bite); } } catch (Exception ex) { Debug.WriteLine(ex.Message); ConnectionFailure(ex.Message); } } public async Task WriteData(byte[] data) { if (dataWriter != null) { dataWriter.WriteBytes(data); await dataWriter.StoreAsync(); return true; } else { return false; } } } }