comparison OSTC3Operations.cpp @ 1:0b3630a29ad8

Initial version based on previous repository. Project was ported to QT6 and in now cmake based.
author Ideenmodellierer <tiefenrauscher@web.de>
date Thu, 27 Nov 2025 18:40:28 +0100
parents
children
comparison
equal deleted inserted replaced
0:76ccd6ce50c0 1:0b3630a29ad8
1 //////////////////////////////////////////////////////////////////////////////
2 /// \file OSTC3Operations.cpp
3 /// \brief Implementing various operations for OSTC3 dive computer
4 /// \author JD Gascuel.
5 ///
6 /// \copyright (c) 2011-2016 JD Gascuel. All rights reserved.
7 /// $Id$
8 //////////////////////////////////////////////////////////////////////////////
9 //
10 // BSD 2-Clause License:
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions
14 // are met:
15 //
16 // 1. Redistributions of source code must retain the above copyright notice,
17 // this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright notice,
20 // this list of conditions and the following disclaimer in the documentation
21 // and/or other materials provided with the distribution.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 // THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //////////////////////////////////////////////////////////////////////////////
36
37 #include "OSTC3Operations.h"
38
39 #include "Utils/Exception.h"
40 #include "Utils/Log.h"
41 #include "Utils/ProgressEvent.h"
42
43 #include "SettingsDialog.h"
44 #include "HexFile.h"
45
46 #include <QApplication>
47 #include <QDateTime>
48 #include <QDir>
49 #include <QRegularExpression>
50
51 // Byte extration, compatible littleendian or bigendian.
52 #define LOW(x) ((unsigned char)((x) % 256))
53 #define HIGH(x) ((unsigned char)((x / (1<<8)) % 256))
54 #define UPPER(x) ((unsigned char)((x / (1<<16)) % 256))
55 #define UP32(x) ((unsigned char)((x / (1<<24)) % 256))
56
57 #define FIRMWARE_AREA 0x3E0000
58 #define FIRMWARE_SIZE 0x01E000 // 120KB
59 #define FIRMWARE_BLOCK 0x1000 // 4KB
60
61 //////////////////////////////////////////////////////////////////////////////
62
63 OSTC3Operations::OSTC3Operations()
64 : descriptionString(""),
65 emulatorName("OSTC3"),
66 _computerFirmware(0),
67 _computerSerial(0),
68 _connectMode(CLOSED_MODE)
69 {
70 memset(computerText, 0, sizeof computerText);
71 }
72
73 OSTC3Operations::~OSTC3Operations()
74 {
75 if( _connectMode != CLOSED_MODE )
76 disconnect(true);
77 }
78
79 //////////////////////////////////////////////////////////////////////////////
80
81 QStringList OSTC3Operations::listPorts() const
82 {
83 return listUSBPorts();
84 }
85
86 //////////////////////////////////////////////////////////////////////////////
87
88 bool OSTC3Operations::connect()
89 {
90 LOG_TRACE( "Enter download mode..." );
91
92 try {
93 _connectMode = CLOSED_MODE;
94 _serial.open( Settings::port, emulatorName);
95 _serial.sleep(333); // Initial 1/3 sec. delay to first comm.
96
97 for(int retry=0; retry < 10; ++retry)
98 {
99 // Allow for 0.1sec extra delay
100 try {
101 _serial.writeByte(0xBB);
102 } catch(const WriteTimeout& ) {
103 // Bluetooth not present: one can open the pseudo COM port,
104 // but we will have a timeout on first write byte...
105 if( retry < 9 ) {
106 LOG_INFO("Cannot connect to " << Settings::port <<" (" << (retry+1) << "/10)...");
107 _serial.sleep(1000);
108 continue;
109 }
110 LOG_THROW("Cannot connect to " << model() <<".");
111 return false;
112 }
113
114 _serial.sleep(100);
115
116 //---- Check acknowledge, w/o fatal timeouts.
117 unsigned char ok = 0;
118 unsigned char echo = 0;
119 try {
120 echo = _serial.readByte();
121
122 // Already in connect() mode ???
123 if( echo == 'M' )
124 break;
125
126 ok = _serial.readByte();
127 }
128 catch(const ReadTimeout&) {
129 LOG_INFO("Retry " << (retry+1) << "/10...");
130 }
131
132 if( echo != 0xBB || ok != 0x4D ) { // DOWNLOAD modes only.
133 if( retry < 9 )
134 {
135 _serial.purge();
136 _serial.sleep(400);
137 continue;
138 }
139 LOG_THROW("Unable to enter hwOS service mode");
140 return false;
141 }
142 break;
143 }
144 getIdentity();
145
146 QString banner = Log::applicationName();
147 writeText(banner);
148 LOG_TRACE("Connected.");
149 _connectMode = DOWNLOAD_MODE;
150 return true;
151 }
152 catch(const Exception& e) {
153 disconnect();
154 LOG_THROW("Port " << Settings::port << ": " << e.what());
155 }
156 return false;
157 }
158
159 //////////////////////////////////////////////////////////////////////////////
160
161 bool OSTC3Operations::disconnect(bool /*closing*/)
162 {
163 if( _connectMode == CLOSED_MODE ) return false;
164
165 descriptionString.clear(); // cleanup for interface updateStatus()
166 _connectMode = CLOSED_MODE;
167
168 _serial.purge();
169 _serial.writeByte(0xFF); // Exit communications, just in case...
170 _serial.sleep(100);
171
172 _serial.purge();
173 _serial.close();
174
175 return true;
176 }
177
178 //////////////////////////////////////////////////////////////////////////////
179
180 void OSTC3Operations::getIdentity()
181 {
182 descriptionString.clear();
183
184 LOG_TRACE("Getting model...");
185 HardwareDescriptor hw = hardwareDescriptor();
186 // if( hw != HW_OSTC3 )
187 // LOG_THROW("Not an OSTC3.");
188
189 LOG_TRACE("Getting identity...");
190 getCommonIdentity();
191
192 LOG_INFO("Found " << descriptionString.trimmed());
193 }
194
195 //////////////////////////////////////////////////////////////////////////////
196
197 void OSTC3Operations::getCommonIdentity()
198 {
199 unsigned char echo = retryCommand(_serial, 'i'); // 0x69
200 if( echo != 'i' )
201 LOG_THROW("Bad identity reply (1)");
202
203 unsigned char header[4 + 60 + 1] = {0};
204 _serial.readBlock(header, sizeof header);
205 if( header[64] != 0x4D ) // DOWNLOAD modes only.
206 LOG_THROW("Bad identity reply (2)");
207
208 _computerSerial = header[0] + header[1]*256;
209 _computerFirmware = header[2] * 100 + header[3];
210 memcpy(computerText, header+4, sizeof computerText);
211
212 descriptionString = QString("%1 #%2, fw %3.%4, %5")
213 .arg(model())
214 .arg(serialNumber(), 4, 10, QChar('0'))
215 .arg(firmware() / 100).arg(firmware() % 100, 2, 10, QChar('0'))
216 .arg( QString::fromLatin1((char*)(computerText), 60)
217 .replace(QChar('\0'), " ") );
218 }
219
220 //////////////////////////////////////////////////////////////////////////////
221
222 int OSTC3Operations::firmware() const
223 {
224 return _computerFirmware;
225 }
226
227 int OSTC3Operations::serialNumber() const
228 {
229 return _computerSerial;
230 }
231
232 QString OSTC3Operations::customText() const
233 {
234 return QString::fromLatin1(computerText, sizeof computerText);
235 }
236
237 //////////////////////////////////////////////////////////////////////////////
238
239 QSize OSTC3Operations::nameSize() const
240 {
241 return QSize(12, 5);
242 }
243
244 //////////////////////////////////////////////////////////////////////////////
245
246 void OSTC3Operations::writeText(const QString& msg)
247 {
248 QByteArray buffer = msg.leftJustified(16, ' ', true).toLatin1();
249 LOG_TRACE("Echoing string '" << buffer << "'");
250
251 // 2014-10-27 jDG: On OSTC3 v1.60, after an ERASE AREA, we do get
252 // a spurious L here (instead of n)...
253 unsigned char echo = retryCommand(_serial, 'n'); // 0x6E Echo string.
254 if( echo != 'n' )
255 LOG_THROW("Bad message reply (1)");
256
257 _serial.writeBlock((const unsigned char*)buffer.data(), 16);
258 _serial.sleep(25); // Allow 25msec to display the message...
259
260 unsigned char ok = _serial.readByte();
261 if( ok != 0x4C && ok != 0x4D ) // DOWNLOAD or SERVICE modes.
262 LOG_THROW("Bad message reply (2)");
263 }
264
265 //////////////////////////////////////////////////////////////////////////////
266
267 void OSTC3Operations::setDate(const QDateTime &date)
268 {
269 LOG_TRACE("Set Date " << date.toString("MM/dd/yyyy hh:mm"));
270
271 unsigned char buffer[6];
272 buffer[0] = date.time().hour();
273 buffer[1] = date.time().minute();
274 buffer[2] = date.time().second();
275 buffer[3] = date.date().month();
276 buffer[4] = date.date().day();
277 buffer[5] = date.date().year() % 100;
278
279 unsigned char echo = retryCommand(_serial, 'b'); // 0x62 Sync date
280 if( echo != 'b' )
281 LOG_THROW("Bad clock reply (1)");
282
283 _serial.writeBlock(buffer, sizeof buffer);
284 _serial.sleep(5);
285
286 unsigned char ok = _serial.readByte();
287 if( ok != 0x4D ) // DOWNLOAD mode only.
288 LOG_THROW("Bad clock reply (2)");
289
290 writeText( "Set " + date.toString("MM/dd hh:mm") );
291 }
292
293 //////////////////////////////////////////////////////////////////////////////
294
295 void OSTC3Operations::setName(const QString &newName)
296 {
297 LOG_TRACE("Set Name '" << newName << "'");
298
299 char buffer[60];
300 memset(buffer, 0, sizeof buffer);
301 strncpy(buffer, newName.toLatin1().constData(), sizeof buffer);
302
303 unsigned char echo = retryCommand(_serial, 'c'); // 0x63 Send custom text
304 if( echo != 'c' )
305 LOG_THROW("Bad text reply (1)");
306
307 _serial.writeBlock((unsigned char*)buffer, sizeof buffer);
308 _serial.sleep(5);
309
310 unsigned char ok = _serial.readByte();
311 if( ok != 0x4D ) // DOWNLOAD modes only.
312 LOG_THROW("Bad text reply (2)");
313
314 getIdentity();
315 // Echo the first line of customtext:
316 writeText(newName.left(12).trimmed());
317 }
318
319 //////////////////////////////////////////////////////////////////////////////
320
321 void OSTC3Operations::setIcons(const QString &)
322 {
323 LOG_THROW("Set icons: Not yet implemented");
324 }
325
326 QImage OSTC3Operations::dumpScreen() const
327 {
328 LOG_THROW("Dump screen: Not yet implemented");
329 return QImage();
330 }
331
332 //////////////////////////////////////////////////////////////////////////////
333
334 static unsigned char ostc3SecretKey[16] = {
335 241,233, 176, 48,
336 69,111, 190, 85,
337 255,231, 248, 49,
338 19,108, 242,254
339 };
340
341 //////////////////////////////////////////////////////////////////////////////
342
343 void OSTC3Operations::eraseRange(unsigned int addr, unsigned int size)
344 {
345 // Convert size to number of pages, rounded up.
346 size = ((size + 4095) / 4096);
347
348 // Erase just the needed pages.
349 unsigned char buffer[4];
350 buffer[0] = UPPER(addr);
351 buffer[1] = HIGH(addr);
352 buffer[2] = LOW(addr);
353 buffer[3] = LOW(size);
354
355 unsigned char reply = retryCommand(_serial, 'B'); // Command 'B'
356 if( reply != 0x42 )
357 LOG_THROW("eraseRange (1)");
358
359 _serial.writeBlock(buffer, 4);
360
361 // Wait (120/4)ms by block of 4K, plus 3% VAT to be sure.
362 _serial.sleep(40 + size * 31);
363
364 unsigned char ok = _serial.readByte();
365 if( ok != 0x4c ) // SERVICE MODE acknowledge.
366 LOG_THROW("eraseRange (2)");
367 }
368
369 //////////////////////////////////////////////////////////////////////////////
370
371 void OSTC3Operations::writeBlock(unsigned int addr,
372 const unsigned char *data,
373 unsigned int size)
374 {
375 unsigned char buffer[3];
376 buffer[0] = UPPER(addr);
377 buffer[1] = HIGH(addr);
378 buffer[2] = LOW(addr);
379
380 unsigned char reply = retryCommand(_serial, '0'); // 0x30
381 if( reply != '0' )
382 LOG_THROW("startWrite");
383
384 _serial.writeBlock(buffer, sizeof buffer);
385 _serial.sleep(2);
386
387 _serial.writeBlock(data, size);
388 // Approximated EEPROM write time some 1sec timeout ??
389 // 1KB = 240 + 1000 = 1240 : Ok.
390 // 4KB = 1.1sec : Ok.
391 _serial.sleep(1100);
392
393 unsigned char ok = _serial.readByte();
394 if( ok != 0x4c && ok != 0x4d ) // DOWNLOAD or SERVICE modes.
395 LOG_THROW("stopWrite");
396 }
397
398
399 //////////////////////////////////////////////////////////////////////////////
400
401 void OSTC3Operations::readBlock(unsigned int addr, unsigned char* ptr, unsigned int size)
402 {
403 unsigned char buffer[6];
404 buffer[0] = UPPER(addr);
405 buffer[1] = HIGH(addr);
406 buffer[2] = LOW(addr);
407 buffer[3] = UPPER(size);
408 buffer[4] = HIGH(size);
409 buffer[5] = LOW(size);
410
411 unsigned char reply = retryCommand(_serial, 0x20); // Command ' '
412 if( reply != 0x20 )
413 LOG_THROW("readBytes");
414
415 _serial.writeBlock(buffer, sizeof buffer);
416 _serial.sleep(500); // Allow some time to start emitting...
417 _serial.readBlock(ptr, size);
418
419 // Note: in that case, the OK byte is send AFTER the data block.
420 unsigned char ok = _serial.readByte();
421 if( ok != 0x4C ) // SERVICE modes only.
422 LOG_THROW("readBytes (2)");
423 }
424
425 //////////////////////////////////////////////////////////////////////////////
426
427 void OSTC3Operations::upgradeFirmware(unsigned int checksum)
428 {
429 unsigned char buffer[5];
430 buffer[0] = LOW(checksum);
431 buffer[1] = HIGH(checksum);
432 buffer[2] = UPPER(checksum);
433 buffer[3] = UP32(checksum);
434
435 // Compute magic checksum's checksum.
436 buffer[4] = 0x55;
437 buffer[4] ^= buffer[0]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7);
438 buffer[4] ^= buffer[1]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7);
439 buffer[4] ^= buffer[2]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7);
440 buffer[4] ^= buffer[3]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7);
441
442 unsigned char reply = retryCommand(_serial, 0x50); // 'P' : send FW to bootloader
443 if( reply != 0x50 )
444 LOG_THROW("Flashing start (1)");
445
446 _serial.writeBlock(buffer, sizeof buffer);
447 unsigned char ok = _serial.readByte();
448 if( ok != 0x4C ) // SERVICE modes only.
449 LOG_THROW("Flashing start (2)");
450
451 // NOTE: the device never return, because it always do a reset,
452 // with ot without reprogramming...
453 _serial.sleep(500);
454 _serial.close();
455 descriptionString.clear();
456 }
457
458 QString OSTC3Operations::firmwareTemplate() const
459 {
460 return "*_firmware.hex";
461 }
462
463 #if 0
464 QRegExp OSTC3Operations::portTemplate() const
465 {
466 #if defined(Q_OS_MAC)
467 return QRegExp("tty.usbserial-.*", Qt::CaseInsensitive);
468 #elif defined(Q_OS_LINUX)
469 // Seems ok for debian, ubuntu, redhat, CentOS and SUSE (google dixit)
470 return QRegExp("ttyUSB.*", Qt::CaseSensitive);
471 #elif defined(Q_OS_WIN)
472 return QRegExp("COM.*", Qt::CaseSensitive);
473 #endif
474 }
475 #endif
476
477 QRegularExpression OSTC3Operations::portTemplate() const
478 {
479 #if defined(Q_OS_MAC)
480 return QRegularExpression("tty.usbserial-.*",
481 QRegularExpression::CaseInsensitiveOption);
482 #elif defined(Q_OS_LINUX)
483 // Debian, Ubuntu, RedHat, CentOS, SUSE
484 return QRegularExpression("ttyUSB.*"); // default: case-sensitive
485 #elif defined(Q_OS_WIN)
486 return QRegularExpression("COM.*"); // default: case-sensitive
487 #endif
488 }
489 //////////////////////////////////////////////////////////////////////////////
490
491 void OSTC3Operations::connectServiceMode()
492 {
493 LOG_TRACE( "Enter service mode..." );
494
495 // NOTE: Service mode requires a special starting sequence, different from
496 // the usual download mode state.
497 // Also, the general acknowledge byte is changed to 0x4c 'L'.
498
499 assert( _connectMode != SERVICE_MODE );
500 _serial.open( Settings::port, emulatorName);
501 _serial.sleep(333); // Initial 1/3 sec before trying service mode...
502
503 for(int retry=0; retry < 10; ++retry)
504 {
505 unsigned char serviceMode[] = { 0xAA, 0xAB, 0xCD, 0xEF };
506
507 try {
508 _serial.writeBlock(serviceMode, sizeof serviceMode);
509 }
510 catch(const WriteTimeout&) {
511 // Bluetooth not present: one can open the pseudo COM port,
512 // but we will have a timeout on first write byte...
513 if( retry < 9 ) {
514 LOG_INFO("Cannot connect to " << Settings::port <<" (" << (retry+1) << "/10)...");
515 _serial.sleep(1000);
516 continue;
517 }
518 LOG_THROW("Cannot connect to " << model() << ".");
519 return;
520 }
521
522 // Allow for 0.1sec extra delay
523 _serial.sleep(100);
524
525 //---- Check acknowledge:
526 unsigned char echo = 0;
527 try {
528 echo = _serial.readByte();
529 }
530 catch(...) {}
531
532 if( echo != 0x4b ) {
533 serviceModeFailed:
534 if( retry < 9 )
535 {
536 _serial.purge();
537 _serial.sleep(400);
538 continue;
539 }
540 LOG_THROW("Unable to enter " << model() <<" service mode");
541 }
542
543 echo = _serial.readByte();
544 if( echo != 0xAB )
545 goto serviceModeFailed;
546 echo = _serial.readByte();
547 if( echo != 0xCD )
548 goto serviceModeFailed;
549 echo = _serial.readByte();
550 if( echo != 0xEF )
551 goto serviceModeFailed;
552 echo = _serial.readByte();
553 if( echo != 0x4c ) // SERVICE modes only.
554 goto serviceModeFailed;
555 break;
556 }
557 _connectMode = SERVICE_MODE;
558 }
559
560 //////////////////////////////////////////////////////////////////////////////
561
562 void OSTC3Operations::upgradeFW(const QString &fileName)
563 {
564 //---- Load and check firmware -------------------------------------------
565 LOG_INFO("Loading firmware.");
566 HexFile hex;
567 loadFirmware(hex, fileName);
568
569 //---- Enter Service Mode ------------------------------------------------
570 connectServiceMode();
571
572 //---- Erase old Firmware ------------------------------------------------
573 PROGRESS(0, FIRMWARE_SIZE);
574 LOG_INFO("Erasing Firmware.");
575
576 writeText(" Erasing FW...");
577 eraseRange(FIRMWARE_AREA, FIRMWARE_SIZE);
578
579 //---- Upload Firmware ---------------------------------------------------
580 LOG_INFO("Uploading firmware.");
581 writeText(" Uploading...");
582
583 for(int len = 0x00000; len < FIRMWARE_SIZE; len += FIRMWARE_BLOCK)
584 {
585 unsigned char percent = int(len * 100.0f / FIRMWARE_SIZE + 0.5f);
586 writeText( QString(" Uploading %1%")
587 .arg(percent, 2) );
588 PROGRESS(percent, 100);
589
590 writeBlock(FIRMWARE_AREA+len, hex.data()+len, FIRMWARE_BLOCK);
591 }
592 PROGRESS(100, 100);
593
594 //---- Verify firmware ---------------------------------------------------
595 LOG_INFO("Verify firmware.");
596 writeText(" Verifying...");
597 {
598 unsigned char* buffer = new unsigned char[FIRMWARE_SIZE];
599 Q_CHECK_PTR(buffer);
600
601 for(int len = 0x00000; len < FIRMWARE_SIZE; len += FIRMWARE_BLOCK)
602 {
603 unsigned char percent = int(len * 100.0f / FIRMWARE_SIZE + 0.5f);
604 writeText( QString(" Verifying %1%")
605 .arg(percent, 2) );
606 PROGRESS(percent, 100);
607
608 readBlock(FIRMWARE_AREA+len, buffer+len, FIRMWARE_BLOCK);
609 }
610 PROGRESS(100, 100);
611 qApp->processEvents(QEventLoop::ExcludeUserInputEvents, 10);
612
613 for(int i=0; i<FIRMWARE_SIZE; ++i)
614 if( buffer[i] != hex.data()[i] )
615 {
616 writeText(" Verify FAILED");
617 LOG_THROW("readback is different");
618 }
619
620 delete[] buffer;
621 }
622 PROGRESS_THROTTLE();
623
624 //---- Flashing firmware -------------------------------------------------
625 LOG_INFO("Programming.");
626 writeText(" Programming...");
627 upgradeFirmware( hex.checksum() );
628
629 //---- Done --------------------------------------------------------------
630 // Low-level close, to avoid trying to send a 0xFF byte...
631 _serial.close();
632 _connectMode = CLOSED_MODE;
633 LOG_INFO("Upgrade done.");
634 PROGRESS_RESET();
635 }
636
637 void OSTC3Operations::loadFirmware(HexFile& hex, const QString& fileName) const
638 {
639 hex.allocate(FIRMWARE_SIZE);
640 hex.loadEncrypted(fileName, ostc3SecretKey);
641 }
642
643 //////////////////////////////////////////////////////////////////////////////
644
645 QString OSTC3Operations::model() const
646 {
647 return "OSTC hwOS (USB)";
648 }
649
650 QString OSTC3Operations::description()
651 {
652 return descriptionString;
653 }
654
655 //////////////////////////////////////////////////////////////////////////////
656
657 HardwareOperations::CompanionFeatures OSTC3Operations::supported() const
658 {
659 // No ICON, no DUMPSCREEN, no VPM
660 return CompanionFeatures(PARAMETERS|DATE|NAME|FIRMWARE
661 |HELIUM_DIVE|CCR_DIVE);
662 }
663
664 //////////////////////////////////////////////////////////////////////////////
665 void OSTC3Operations::getSignal()
666 {
667 return;
668 }
669 void OSTC3Operations::getAllHeader(unsigned char* pBuffer)
670 {
671 return;
672 }
673 void OSTC3Operations::writeAllHeader(unsigned char* pBuffer)
674 {
675 return;
676 }
677
678 void OSTC3Operations::getAllSamples(unsigned char* pBuffer)
679 {
680 return;
681 }
682 void OSTC3Operations::writeAllSamples(unsigned char* pBuffer)
683 {
684 return;
685 }