-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRovingNetworks.cs
More file actions
413 lines (369 loc) · 14.1 KB
/
RovingNetworks.cs
File metadata and controls
413 lines (369 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
//=======================================================================================
//
// Purpose: Povide a method of talking to a Roving Networks RN-42 Bluetooth module in
// command mode.
//
//
// Copyright (C) 2011 Mark Stevens
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software") to use
// the Software in a non-commercial environment subject to the following conditions:
//
// 1. The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 2. The original author shall be acknowledged in any software and documentation
// including (but not restricted to) books, articles and online posts.
//
// Use in a commercial environment is subject to the written consent of the author
// and/or copyright holder.
//
// The Software, documentation, instructions for use and associated materials
// are provided "as is" without warranty of any kind express or implied. The
// author and copyright holders shall in no way be held liable for any claim
// or damages arising as a result of the use of the software and/or documentation.
//
//=======================================================================================
using System;
using System.Collections;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace NetduinoApplication1
{
class RovingNetworks : IDisposable
{
#region Constants
/// <summary>
/// Size of the buffer for the com port.
/// </summary>
private const int BUFFER_SIZE = 1024;
// event queue to push onto NetComms
public ArrayList CommsCommands { get; set; }
public AutoResetEvent CommandEvent { get; set; }
#endregion
#region Enums
/// <summary>
/// Determine which mode the module is in.
/// </summary>
public enum ConnectionState
{
/// <summary>
/// We have not yet made a connection to the bluetooth device.
/// </summary>
Disconnected,
/// <summary>
/// Bluetooth module is in Command mode.
/// </summary>
Command,
/// <summary>
/// Bluetooth module is in data mode (default).
/// </summary>
Data
}
#endregion
#region Private variables
/// <summary>
/// Serial port used to communicate with the bluetooth module.
/// </summary>
private SerialPort _bluetoothModule;
/// <summary>
/// Buffer for the data from the Bluetooth device.
/// </summary>
private byte[] _buffer = new byte[BUFFER_SIZE];
/// <summary>
/// Amount of data in the buffer.
/// </summary>
private int _currentBufferLength = 0;
/// <summary>
/// Used to track when Dispose is called.
/// </summary>
private bool _disposed = false;
#endregion
#region Properties
/// <summary>
/// Current connection type.
/// </summary>
public ConnectionState ConnectionStatus { get; private set; }
#endregion
#region Constructor(s) and Dispose
/// <summary>
/// Default constructor.
/// </summary>
private RovingNetworks()
{
ConnectionStatus = ConnectionState.Disconnected;
}
/// <summary>
/// Create a new instance of the RovingNetworks RN-42 class nad open a connection
/// using the specified connection setting.
/// </summary>
/// <param name="port">Serial port to use to talk to the Bluetooth device.</param>
/// <param name="baudRate">Baud rate for the device.</param>
/// <param name="parity">Parity settings for the device.</param>
/// <param name="dataBits">Number of data bits for the device.</param>
/// <param name="stopBits">Number of stop bits for the device.</param>
public RovingNetworks(string port, BaudRate baudRate, Parity parity, int dataBits, StopBits stopBits)
{
int rate;
switch (baudRate)
{
case BaudRate.Baudrate1200:
rate = 1200;
break;
case BaudRate.Baudrate2400:
rate = 2400;
break;
case BaudRate.Baudrate4800:
rate = 4800;
break;
case BaudRate.Baudrate9600:
rate = 9600;
break;
case BaudRate.Baudrate19200:
rate = 19200;
break;
case BaudRate.Baudrate38400:
rate = 38400;
break;
case BaudRate.Baudrate57600:
rate = 57600;
break;
case BaudRate.Baudrate115200:
rate = 115200;
break;
case BaudRate.Baudrate230400:
rate = 230400;
break;
default:
rate = -1;
break;
}
this._bluetoothModule = new SerialPort(port, rate, parity, dataBits, stopBits);
ConnectionStatus = ConnectionState.Data;
this._bluetoothModule.DataReceived += new SerialDataReceivedEventHandler(_bluetoothModule_DataReceived);
this._bluetoothModule.Open();
//this._SerialPort = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
//this._SerialPort.DataReceived += new SerialDataReceivedEventHandler(_SerialPort_DataReceived);
//this._SerialPort.Open();
}
/// <summary>
/// Implement IDisposable.
/// </summary>
public void Dispose()
{
Dispose(true);
// Call to GC.SupressFinalize will take this object
// off the finalization queue and prevent multiple
// executions.
GC.SuppressFinalize(this);
}
/// <summary>
/// Initiate object disposal.
/// </summary>
/// <param name="disposing">Flag used to determine if the method is being called by the runtime (false) or programmatically (true).</param>
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_bluetoothModule.Dispose();
}
_disposed = true; // Done - prevent accidental or intentional Dispose calls.
}
}
#endregion
#region Methods
/// <summary>
/// Clear the buffer holding the responses from the bluetooth module.
/// </summary>
private void ClearBuffer()
{
lock (_buffer)
{
_buffer[0] = 0;
_currentBufferLength = 0;
}
}
public void write(string data)
{
_bluetoothModule.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);
}
/// <summary>
/// Send a command to the bluetooth module and return the single line result
/// from the module.
/// </summary>
/// <param name="command">Cammnd to send ot the module.</param>
/// <exception cref="InvalidOperationException">This exception is thrown when the device is not in command mode.</exception>
/// <returns>Result text from the bluetooth module.</returns>
public string SendCommand(string command)
{
string result;
ClearBuffer();
_bluetoothModule.Write(Encoding.UTF8.GetBytes(command), 0, command.Length);
result = ReadLine();
while (result == "")
{
result = ReadLine();
}
return (result);
}
/// <summary>
/// Send a command to the bluetooth module where a multi-line response is expected.
/// </summary>
/// <remarks>
/// This method assumes that all of the responses from a command will be returned within the
/// specified timeout period. Any responses after the timeout will not be returned.
/// </remarks>
/// <param name="command">Command to send to the bluetooth module.</param>
/// <param name="timeout">Timeout (in milliseconds) between sending the command and expecting the result.</param>
/// <returns>ArrayList of strings containing the response from the bluetooth module.</returns>
public ArrayList SendCommand(string command, int timeout)
{
ArrayList result;
string line;
ClearBuffer();
result = new ArrayList();
_bluetoothModule.Write(Encoding.UTF8.GetBytes(command), 0, command.Length);
Thread.Sleep(timeout);
line = ReadLine();
while (line != "")
{
result.Add(line);
line = ReadLine();
}
return (result);
}
/// <summary>
/// Put the bluetooth device into command mode.
/// </summary>
/// <returns>True if the connection is establised, false otherwise.</returns>
public bool EnterCommandMode()
{
if (SendCommand("$$$") == "CMD")
{
ConnectionStatus = ConnectionState.Command;
return (true);
}
return (false);
}
/// <summary>
/// Exit command mode.
/// </summary>
/// <returns>True if command mode was exited successfully, false otherwise.</returns>
/// <exception cref="InvalidOperationException">Thrown if the system is not in command mode.</exception>
///
public void ExitCommandModeJustInCase()
{
ClearBuffer();
string command = "---";
_bluetoothModule.Write(Encoding.UTF8.GetBytes(command), 0, command.Length);
}
public bool ExitCommandMode()
{
if (SendCommand("---") == "END")
{
ConnectionStatus = ConnectionState.Data;
return (true);
}
return (false);
}
/// <summary>
/// Read a line of text from the input buffer.
/// </summary>
/// <returns></returns>
private string ReadLine()
{
string result;
result = "";
lock (_buffer)
{
for (int index = 0; index < _currentBufferLength; index++)
{
if (_buffer[index] == '\n')// || index == _currentBufferLength-1)
{
_buffer[index] = 0;
result = "" + new string(Encoding.UTF8.GetChars(_buffer));
_currentBufferLength = _currentBufferLength - index - 1;
Array.Copy(_buffer, index + 1, _buffer, 0, _currentBufferLength);
break;
}
}
}
return (result);
}
private void sendToComms(string c)
{
ArrayList com = new ArrayList();
string[] comms = c.Split(',');
int siz = comms.Length;
for (int i = 0; i < siz; i++)
{
com.Add(comms[i]);
}
lock (CommsCommands)
{
CommsCommands.Add(com);
CommandEvent.Set();
}
}
#endregion
#region Events.
/// <summary>
/// Receive data from the bluetooth module and place into the data buffer.
/// </summary>
/// <param name="sender">Serial port generating the event.</param>
/// <param name="e">Type of data received over the serial port.</param>
private void _bluetoothModule_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (e.EventType == SerialData.Chars)
{
lock (_buffer)
{
int amount;
byte[] buffer;
string res;
buffer = new byte[BUFFER_SIZE];
int amountToRead = this._bluetoothModule.BytesToRead;
//amount = ((SerialPort) sender).Read(buffer, 0, BUFFER_SIZE);
amount = this._bluetoothModule.Read(buffer, 0, amountToRead); // starts out as 512 big!!!???
//Debug.Print("recevieved: " + buffer);
if (amount > 0)
{
for (int index = amount - 1; index >= 0; index--)
{/*
if (buffer[index] == '\r')
{
if (index != amount)
{
Array.Copy(buffer, index + 1, buffer, index, amount - index - 1);
}
amount--;
}
* */
}
if ((amount + _currentBufferLength) <= BUFFER_SIZE)
{
Array.Copy(buffer, 0, _buffer, _currentBufferLength, amount);
_currentBufferLength += amount;
// do read line here, then push onto event queue for NetComms.
while ((res = ReadLine()) != "")
{
// push onto event queue..
//sendToComms(res);
Program.DelegateMethod(res);
}
}
else
{
throw new Exception("Buffer overflow");
}
}
}
}
}
#endregion
}
}