source: pacpussensors/trunk/driver/win32SerialPort.cpp@ 127

Last change on this file since 127 was 71, checked in by DHERBOMEZ Gérald, 10 years ago

Correction of Sick LIDAR LDMRS code: problem when decoding the points cloud (with Chunlei Yu).
Correction of a small bug in Win32SerialPort when receiving RX_FLAG.

File size: 22.1 KB
Line 
1/*********************************************************************
2// created: 2005/05/30 - 15:07
3// filename: win32SerialPort.cpp
4//
5// author: Gerald Dherbomez
6//
7// version: $Id: win32SerialPort.cpp 1278 2013-01-16 16:40:11Z bonnetst $
8//
9// purpose: Implementation of the win32SerialPort class.
10//
11// todo: - Manage infinite waiting when the port is not correctly
12// opened or where no data available: reinit the port
13// - add a function to write data
14// - provide 3 possibilities to use the serial port:
15// with event overlapped ok
16// with event non overlapped ok
17// without event directly todo
18// - look at why the port is not opened correctly at the
19// beginning
20*********************************************************************/
21
22#include "Win32SerialPort.h"
23
24#include "Pacpus/kernel/Log.h"
25
26#include <cassert>
27#include <iostream>
28#include <QFile>
29#include <QTextStream>
30#include <sstream>
31
32DECLARE_STATIC_LOGGER("pacpus.base.Win32SerialPort");
33
34using namespace std;
35
36static const int PORT_NAME_MAXIMUM_LENGTH = 20;
37
38static const int XON = 17;
39static const int XOFF = 19;
40
41//////////////////////////////////////////////////////////////////////////
42// Constructor
43//////////////////////////////////////////////////////////////////////////
44Win32SerialPort::Win32SerialPort(QString name)
45{
46 componentName = name;
47
48 // default values
49 baudRate_ = CBR_38400;
50 byteSize_ = 8;
51 parity_ = NOPARITY;
52 stopBits_ = ONESTOPBIT;
53
54 THREAD_ALIVE = TRUE;
55 numberBytesToRead = 0;
56 ringIndicatorDetected = FALSE;
57 comOperationStatus = 0;
58
59 ppsSense_ = RISING;
60
61 t_=0;
62
63 LOG_INFO("The win32 serial port " << componentName << " was created");
64}
65
66//////////////////////////////////////////////////////////////////////////
67// Destructor
68//////////////////////////////////////////////////////////////////////////
69Win32SerialPort::~Win32SerialPort()
70{
71 LOG_INFO("The win32 serial port " << componentName << " was destroyed");
72}
73
74//////////////////////////////////////////////////////////////////////////
75// Set the mode of the serial port driver:
76// - overlapped: it is the asynchronous mode (non blocking).
77// Use FILE_FLAG_OVERLAPPED in parameter
78// - non overlapped: it is the synchronous mode (blocking).
79// Pass 0 in parameter
80//
81// Warning: the mode has to be chosen before opening the COM port
82//////////////////////////////////////////////////////////////////////////
83void Win32SerialPort::setMode(const DWORD overlappedModeAttribute)
84{
85 // reset overlapped structure
86 memset(&overlappedStructure,0,sizeof(overlappedStructure));
87
88 overlappedMode = overlappedModeAttribute;
89}
90
91//////////////////////////////////////////////////////////////////////////
92// Open the port 'name'. 'name' follows the pattern COMx with x the port
93// number that you want to open
94//////////////////////////////////////////////////////////////////////////
95bool Win32SerialPort::openPort(const char * name)
96{
97 setPortName(name);
98
99 handlePort = CreateFile(
100 /* lpFileName = */ portName.c_str(),
101 /* dwDesiredAccess = */ GENERIC_READ | GENERIC_WRITE,
102 /* dwShareMode = */ 0,
103 /* lpSecurityAttributes = */ NULL,
104 /* dwCreationDisposition = */ OPEN_EXISTING,
105 /* dwFlagsAndAttributes = */ overlappedMode,
106 /* hTemplateFile = */ NULL
107 );
108
109 if (handlePort == INVALID_HANDLE_VALUE) {
110 LOG_ERROR("CreateFile failed with error "<< GetLastError());
111 return false;
112 }
113 return true;
114}
115
116//////////////////////////////////////////////////////////////////////////
117// Close the active COM port
118//////////////////////////////////////////////////////////////////////////
119int Win32SerialPort::closePort()
120{
121 if (!CloseHandle(handlePort)) {
122 LOG_ERROR("CloseHandle failed with error " << GetLastError());
123 return 0;
124 }
125 return 1;
126}
127
128//////////////////////////////////////////////////////////////////////////
129// Set the name of the COM port that will be used
130// Called by openPort() function
131//////////////////////////////////////////////////////////////////////////
132void Win32SerialPort::setPortName(const char * name)
133{
134 // the string "\\.\" (unescaped) is necessary to open a port COM above 9
135 portName = "\\\\.\\" + string(name);
136 LOG_DEBUG("portName = '" << portName << "'");
137 assert(PORT_NAME_MAXIMUM_LENGTH >= portName.length());
138}
139
140//////////////////////////////////////////////////////////////////////////
141// Configure the main port parameters: baudrate, parity, byte size and
142// number of stop bits
143// called by configurePort - private member
144//////////////////////////////////////////////////////////////////////////
145bool Win32SerialPort::setPort(long baudrate, char parity, int byteSize, int stopBits)
146{
147 if (!handlePort) {
148 return false;
149 }
150
151 baudRate_ = baudrate;
152 parity_ = parity;
153 byteSize_ = byteSize;
154 stopBits_ = stopBits;
155
156 stringstream baudSs;
157 baudSs << (const char *) "baud=" << baudrate;
158 baudSs << (const char *) "parity=" << parity;
159 baudSs << (const char *) "data=" << byteSize;
160 baudSs << (const char *) "stop=" << stopBits;
161 string szBaud = baudSs.str();
162
163 // LOG_DEBUG("COMM definition string = " << szBaud);
164
165 int result;
166 if (result=GetCommState(handlePort,&commConfigStructure.dcb)) {
167 commConfigStructure.dcb.fRtsControl = RTS_CONTROL_DISABLE;
168 if (BuildCommDCB(szBaud.c_str(), &commConfigStructure.dcb)) {
169 result=SetCommState(handlePort, &commConfigStructure.dcb);
170 }
171 }
172 if ( result < 0 ) {
173 LOG_WARN("Failed to set com state. Error: " << GetLastError());
174 }
175
176 PurgeComm(handlePort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
177 return result > 0;
178}
179
180void Win32SerialPort::dumpParameters(QString filename)
181{
182 // get the current DCB (device-control block) structure
183 GetCommState(handlePort, &commConfigStructure.dcb);
184
185 QFile file(filename);
186 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
187 LOG_ERROR("Cannot open file: " << filename);
188 return;
189 }
190
191 QTextStream out(&file);
192
193 // write to file
194 out << "commConfigStructure.dcb.DCBlength " << commConfigStructure.dcb.DCBlength << "\n";
195 out << "commConfigStructure.dcb.BaudRate " << commConfigStructure.dcb.BaudRate << "\n";
196 out << "commConfigStructure.dcb.ByteSize " << commConfigStructure.dcb.ByteSize << "\n";
197 out << "commConfigStructure.dcb.Parity " << commConfigStructure.dcb.Parity << "\n";
198 out << "commConfigStructure.dcb.StopBits " << commConfigStructure.dcb.StopBits << "\n";
199 out << "commConfigStructure.dcb.fBinary " << commConfigStructure.dcb.fBinary << "\n";
200 out << "commConfigStructure.dcb.fParity " << commConfigStructure.dcb.fParity << "\n";
201 out << "commConfigStructure.dcb.fOutX " << commConfigStructure.dcb.fOutX << "\n";
202 out << "commConfigStructure.dcb.fInX " << commConfigStructure.dcb.fInX << "\n";
203 out << "commConfigStructure.dcb.fOutxCtsFlow " << commConfigStructure.dcb.fOutxCtsFlow << "\n";
204 out << "commConfigStructure.dcb.fOutxDsrFlow " << commConfigStructure.dcb.fOutxDsrFlow << "\n";
205 out << "commConfigStructure.dcb.fRtsControl " << commConfigStructure.dcb.fRtsControl << "\n";
206 out << "commConfigStructure.dcb.fNull " << commConfigStructure.dcb.fNull << "\n";
207 out << "commConfigStructure.dcb.XonChar " << commConfigStructure.dcb.XonChar << "\n";
208 out << "commConfigStructure.dcb.XoffChar " << commConfigStructure.dcb.XoffChar << "\n";
209 out << "commConfigStructure.dcb.XonLim " << commConfigStructure.dcb.XonLim << "\n";
210 out << "commConfigStructure.dcb.XoffLim " << commConfigStructure.dcb.XoffLim << "\n";
211 out << "commConfigStructure.dcb.fAbortOnError " << commConfigStructure.dcb.fAbortOnError << "\n";
212 out << "commConfigStructure.dcb.fDtrControl " << commConfigStructure.dcb.fDtrControl << "\n";
213 out << "commConfigStructure.dcb.fDsrSensitivity " << commConfigStructure.dcb.fDsrSensitivity << "\n";
214
215 GetCommTimeouts( handlePort, &commTimeoutsStructure);
216
217 out << "commTimeoutsStructure.ReadIntervalTimeout " << commTimeoutsStructure.ReadIntervalTimeout << "\n";
218 out << "commTimeoutsStructure.ReadTotalTimeoutMultiplier " << commTimeoutsStructure.ReadTotalTimeoutMultiplier << "\n";
219 out << "commTimeoutsStructure.ReadTotalTimeoutConstant " << commTimeoutsStructure.ReadTotalTimeoutConstant << "\n";
220 out << "commTimeoutsStructure.WriteTotalTimeoutMultiplier " << commTimeoutsStructure.WriteTotalTimeoutMultiplier << "\n";
221 out << "commTimeoutsStructure.WriteTotalTimeoutConstant " << commTimeoutsStructure.WriteTotalTimeoutConstant << "\n";
222
223 file.close();
224}
225
226//////////////////////////////////////////////////////////////////////////
227// Configure the port with Windows requested parameters
228// Call setPort() function with provided parameters
229//////////////////////////////////////////////////////////////////////////
230int Win32SerialPort::configurePort(unsigned long baudRate, unsigned char byteSize, unsigned char parity, unsigned char stopBits)
231{
232 bool fSuccess;
233 DCB dcb;
234 dumpParameters("serialportparameters_before.txt");
235
236 printf("%d %d %d %d \n", baudRate, byteSize, parity, stopBits);
237
238 inputBufferSize = 32;
239 outputBufferSize = 32;
240
241 SetupComm( handlePort, inputBufferSize, outputBufferSize );
242 //::GetCommMask( handlePort, &evtMask );
243 //::SetCommMask( handlePort, 0 );
244
245 // Initialize the DCB structure.
246 SecureZeroMemory(&dcb, sizeof(DCB));
247 dcb.DCBlength = sizeof(DCB);
248
249
250 // get the current DCB (device-control block) structure
251 fSuccess = GetCommState(handlePort, &dcb);
252 if (!fSuccess) {
253 // Handle the error.
254 LOG_ERROR("GetCommState failed with error " << GetLastError());
255 return 0;
256 }
257
258 // fill the DCB structure
259 //commConfigStructure.dcb.DCBlength = sizeof(DCB); // G
260 dcb.BaudRate = baudRate; // port speed (CBR_xxxx)
261 dcb.ByteSize = byteSize; // number of bits/byte, 4-8
262 dcb.Parity = parity ; // 0-4=no,odd,even,mark,space
263 dcb.StopBits = stopBits; // 0,1,2 = 1, 1.5, 2
264
265
266 /* Rest of the dcb structure */
267 dcb.fBinary = TRUE;
268 dcb.fParity = TRUE;
269 dcb.fOutxCtsFlow = FALSE;
270 dcb.fOutxDsrFlow = FALSE;
271 dcb.fDtrControl = DTR_CONTROL_DISABLE;
272 dcb.fDsrSensitivity = FALSE;
273 dcb.fTXContinueOnXoff = TRUE;
274 dcb.fOutX = FALSE;
275 dcb.fInX = FALSE;
276 dcb.fErrorChar = FALSE;
277 dcb.fNull = FALSE;
278 dcb.fRtsControl = RTS_CONTROL_DISABLE;
279 dcb.fAbortOnError = FALSE;
280
281 /*
282 dcb.BaudRate = CBR_4800; // port speed (CBR_xxxx)
283 dcb.ByteSize = 8; // number of bits/byte, 4-8
284 dcb.Parity = NOPARITY ; // 0-4=no,odd,even,mark,space
285 dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
286 */
287 /*commConfigStructure.dcb.fBinary = 1; // binary mode on (off not supported by win32 API)
288 commConfigStructure.dcb.fParity = 0; // Consider parity or not ?
289 commConfigStructure.dcb.fOutX = FALSE; // XON/XOFF out flow control
290 commConfigStructure.dcb.fInX = FALSE; // XON/XOFF in flow control
291 commConfigStructure.dcb.fOutxCtsFlow = 0; // CTS output flow control
292 commConfigStructure.dcb.fOutxDsrFlow = 0; // DSR output flow control
293 commConfigStructure.dcb.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control type
294
295 commConfigStructure.dcb.fNull = 0; // Specifies whether null bytes are discarded //G
296 commConfigStructure.dcb.XonChar = XON;
297 commConfigStructure.dcb.XoffChar = XOFF;
298 commConfigStructure.dcb.XonLim = (WORD) ((inputBufferSize) / 4);
299 commConfigStructure.dcb.XoffLim = (WORD) ((outputBufferSize) / 4);
300 commConfigStructure.dcb.fAbortOnError = 1; // need rest on error (use ClearCommError) //G
301 commConfigStructure.dcb.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control type //G
302 commConfigStructure.dcb.fDsrSensitivity = FALSE; // Don't consider DSR line // G
303 */
304 // apply the DCB structure for RS-232 serial device
305 fSuccess = SetCommState(handlePort,&dcb);
306 if (!fSuccess)
307 {
308 // Handle the error.
309 printf ("SetCommState failed with error %d.\n", GetLastError());
310 return 0;
311 }
312
313 fSuccess = GetCommTimeouts( handlePort, &commTimeoutsStructure);
314 if (!fSuccess)
315 {
316 // Handle the error.
317 printf ("GetCommTimeouts failed with error %d.\n", GetLastError());
318 return 0;
319 }
320
321 if (overlappedMode) {
322 commTimeoutsStructure.ReadIntervalTimeout = MAXDWORD;
323 commTimeoutsStructure.ReadTotalTimeoutMultiplier = 0;
324 commTimeoutsStructure.ReadTotalTimeoutConstant = 0;
325 commTimeoutsStructure.WriteTotalTimeoutMultiplier = 0;
326 commTimeoutsStructure.WriteTotalTimeoutConstant = 0;
327 } else {
328 commTimeoutsStructure.ReadIntervalTimeout = 2;
329 commTimeoutsStructure.ReadTotalTimeoutMultiplier = 10;
330 commTimeoutsStructure.ReadTotalTimeoutConstant = 20;
331 commTimeoutsStructure.WriteTotalTimeoutMultiplier = 10;
332 commTimeoutsStructure.WriteTotalTimeoutConstant = 20;
333 }
334
335 SetCommTimeouts( handlePort, &commTimeoutsStructure );
336
337 // specify the set of events to be monitored
338 //if (!SetCommMask(handlePort, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXFLAG | EV_RXCHAR | EV_TXEMPTY) )
339 if (!SetCommMask(handlePort, EV_ERR | EV_RLSD | EV_RXFLAG | EV_RXCHAR) )
340 {
341 // Handle the error.
342 printf ("SetCommMask failed with error %d.\n", GetLastError());
343 return 0;
344 }
345 //setPort(baudRate, parity, byteSize, stopBits);
346
347 if (overlappedMode == FILE_FLAG_OVERLAPPED)
348 {
349 // Create an event object for use by WaitCommEvent.
350 overlappedStructure.hEvent = CreateEvent(
351 NULL, // default security attributes
352 TRUE, // (true = manual - false = auto) reset event
353 FALSE, // initial state : not signaled
354 NULL // no name
355 );
356
357 if (overlappedStructure.hEvent == NULL)
358 qWarning("overlapped event is not created\n");
359
360 // Intialize the rest of the OVERLAPPED structure to zero.
361 overlappedStructure.Internal = 0;
362 overlappedStructure.InternalHigh = 0;
363 overlappedStructure.Offset = 0;
364 overlappedStructure.OffsetHigh = 0;
365 }
366
367 dumpParameters("serialportparameters_after.txt");
368
369 return 1;
370}
371
372//////////////////////////////////////////////////////////////////////////
373// Main loop in charge of processing incoming events from the driver
374// There are 2 main functions:
375// - processIncomingEvent that detects the nature of the event : RXCHAR
376// , RING ... and get data if available
377// - processIncomingData that processes the data got by the first function
378// and transmits the stream to the decoding module
379//////////////////////////////////////////////////////////////////////////
380void Win32SerialPort::run()
381{
382 // GD 31/08/2007 - deja appelé dans GpsComponent::run()
383 //configurePort(baudRate_, byteSize_, parity_, stopBits_);
384
385 PurgeComm(handlePort, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
386
387 while (THREAD_ALIVE)
388 {
389 switch(overlappedMode)
390 {
391 case 0: // non overlapped operation
392 if (WaitCommEvent(handlePort, &evtMask, 0))
393 {
394 t_ = road_time(); // datation
395 processIncomingEvent(); // processing
396 processIncomingData();
397 }
398 else
399 {
400 qWarning("WaitCommEvent failed with error %d.\n", GetLastError());
401 msleep(50);
402 }
403 break;
404
405 case FILE_FLAG_OVERLAPPED: // overlapped operation
406 if (WaitCommEvent(handlePort, &evtMask, &overlappedStructure)) {
407 t_ = road_time(); // datation
408 processIncomingEvent();
409 processIncomingData();
410 } else {
411 // datation
412 comOperationStatus = GetLastError();
413 if (ERROR_IO_PENDING == comOperationStatus) {
414 if (WaitForSingleObject(overlappedStructure.hEvent, INFINITE) == WAIT_OBJECT_0) {
415 t_ = road_time();
416 processIncomingEvent();
417 processIncomingData();
418 } else {
419 LOG_WARN("WaitForSingleObject failed with error " << GetLastError());
420 }
421 }
422 }
423
424 break;
425 default:
426 LOG_WARN("Problem for acquiring serial port");
427
428 } // END SWITCH(OVERLAPPEDMODE)
429 } // END WHILE
430
431 LOG_INFO("Port '" << portName << "' (Win32SerialPort) thread is stopped");
432}
433
434//////////////////////////////////////////////////////////////////////////
435// It is the function responsible to process new events
436// In normal conditions EV_RXCHAR is received to alert that new data can
437// be read
438// PPS : RING (pin 9) or DCD (pin 1, aka RLSD) or DSR (pin 6)
439//////////////////////////////////////////////////////////////////////////
440void Win32SerialPort::processIncomingEvent() {
441 numberBytesRead = 0;
442 unsigned long modemStatus;
443
444 GetCommModemStatus(handlePort, &modemStatus);
445 if ( evtMask & EV_BREAK ) {
446 //printf("%s EV_BREAK\n",portName);
447 }
448
449 if ( evtMask & EV_CTS ) {
450 //printf("%s EV_CTS\n",portName);
451 }
452
453 if ( evtMask & EV_DSR ) {
454 //printf("%s EV_DSR\n",portName);
455 if ((!(modemStatus & MS_DSR_ON)) & (ppsSense_ == RISING)) {
456 ringIndicatorDetected = TRUE;
457 }
458 }
459
460 if ( evtMask & EV_ERR ) {
461 //printf("%s EV_ERR\n",portName);
462 }
463
464 if ( evtMask & EV_RING ) {
465 //printf("%s EV_RING\n", portName);
466 if ((!(modemStatus & MS_RING_ON)) & (ppsSense_ == RISING)) {
467 ringIndicatorDetected = TRUE;
468 }
469 }
470
471 if ( evtMask & EV_RLSD ) {
472 //printf("%s EV_RLSD\n",portName);
473 if ((!(modemStatus & MS_RLSD_ON)) & (ppsSense_ == RISING)) {
474 ringIndicatorDetected = TRUE;
475 }
476 }
477
478 if ( evtMask & EV_RXCHAR ) {
479 //printf("%s EV_RXCHAR\n",portName);
480 if ((numberBytesToRead = nbBytesToRead()) > 0) {
481 receivedBuffer_.resize(numberBytesToRead);
482 numberBytesRead = readBuffer(receivedBuffer_.data(),numberBytesToRead);
483 }
484 receivedBuffer_.truncate(numberBytesRead);
485 }
486
487
488 if ( evtMask & EV_RXFLAG ) {
489 printf("%s EV_RXFLAG\n",portName);
490 }
491
492 if ( evtMask & EV_TXEMPTY )
493 //printf("%s EV_TXEMPTY\n",portName);
494
495 evtMask = 0;
496 // manual reset of overlapped event
497 if (overlappedMode)
498 ResetEvent(overlappedStructure.hEvent);
499}
500
501
502
503//////////////////////////////////////////////////////////////////////////
504// Process the data received by the processIncomingEvent() function
505// It may be either bytes (data) or a ring indicator signal (PPS for GPS signal)
506//////////////////////////////////////////////////////////////////////////
507void Win32SerialPort::processIncomingData() {
508
509 if (numberBytesRead > 0) // data frame
510 {
511 FRAME * frame = new FRAME;
512 frame->t = t_;
513 frame->tr = 0;
514 frame->data = receivedBuffer_;
515
516 frameLock_.lock();
517 frame->length = frame->data.size();
518 dataFrameQueue.enqueue(frame);
519 frameLock_.unlock();
520 emit newDataAvailable(1);
521 }
522
523 if (ringIndicatorDetected == TRUE)
524 {
525 ringIndicatorDetected = FALSE;
526 FRAME * frame = new FRAME;
527 frame->t = t_;
528 frame->tr = 0;
529 frame->data = "PPS";
530 frameLock_.lock();
531 frame->length = frame->data.size();
532 dataFrameQueue.enqueue(frame);
533 frameLock_.unlock();
534 emit newDataAvailable(1);
535 }
536
537 // re-initialization
538 t_ = 0;
539 numberBytesToRead = 0;
540}
541
542
543//////////////////////////////////////////////////////////////////////////
544// Read 'maxLength' bytes on the port and copy them in buffer
545// return the number of bytes read
546//////////////////////////////////////////////////////////////////////////
547int Win32SerialPort::readBuffer(char *buffer, int maxLength)
548{
549 int countread;
550 if (overlappedMode) {
551 if (!ReadFile( handlePort,buffer,maxLength,(DWORD*)&countread,&overlappedStructure))
552 qWarning("ReadFile failed with error %d.\n", GetLastError() );
553 } else {
554 if (!ReadFile( handlePort,buffer,maxLength,(DWORD*)&countread,0))
555 qWarning("ReadFile failed with error %d.\n", GetLastError() );
556 }
557
558 return countread;
559}
560
561//////////////////////////////////////////////////////////////////////////
562// return the number bytes that are available on the port
563//////////////////////////////////////////////////////////////////////////
564DWORD Win32SerialPort::nbBytesToRead()
565{
566 if (!ClearCommError( handlePort, &comErr, &comStat ))
567 qWarning("ClearCommError failed with error %d\n",GetLastError());
568 return comStat.cbInQue;
569}
570
571//////////////////////////////////////////////////////////////////////////
572// return a pointer to the first frame in the queue and removes it
573// The reader is responsible for deleting the frame.
574//////////////////////////////////////////////////////////////////////////
575FRAME * Win32SerialPort::getNextFrame()
576{
577 FRAME *frame = NULL;
578 frameLock_.lock();
579 if (!dataFrameQueue.isEmpty()) {
580 frame = dataFrameQueue.dequeue();
581 }
582 frameLock_.unlock();
583 return frame;
584}
585
586////////////////////////////////////////////////////////////////////////
587// Old interface functions - Not to be used in new plugins
588////////////////////////////////////////////////////////////////////////
589
590int Win32SerialPort::numberOfFrames() {
591 int n;
592
593 frameLock_.lock();
594 n = dataFrameQueue.size();
595 frameLock_.unlock();
596
597 return n;
598}
599
600FRAME* Win32SerialPort::firstFrame() {
601 FRAME* f = NULL;
602
603 frameLock_.lock();
604 if (!dataFrameQueue.empty()) {
605 f = dataFrameQueue.head();
606 }
607 frameLock_.unlock();
608
609 return f;
610}
611
612int Win32SerialPort::removeFirstFrame() {
613
614 frameLock_.lock();
615 if (!dataFrameQueue.empty()) {
616 delete dataFrameQueue.dequeue();
617 }
618 frameLock_.unlock();
619
620 return 1;
621}
622
623void Win32SerialPort::setPpsSense(enum PpsSense ppsSense) {
624 ppsSense_ = ppsSense;
625}
Note: See TracBrowser for help on using the repository browser.