Merge pull request #11190 from mathiasvr/pr-arraylen
[betaflight.git] / src / test / unit / rcdevice_unittest.cc
blob1ddd46219067d6a79543d33cde73f4eb1304123e
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
19 #include "gtest/gtest.h"
21 extern "C" {
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <ctype.h>
26 #include "platform.h"
28 #include "common/bitarray.h"
29 #include "common/maths.h"
30 #include "common/utils.h"
31 #include "common/streambuf.h"
33 #include "fc/rc_controls.h"
34 #include "fc/rc_modes.h"
35 #include "flight/imu.h"
37 #include "drivers/serial.h"
39 #include "io/beeper.h"
40 #include "io/serial.h"
42 #include "scheduler/scheduler.h"
43 #include "io/rcdevice_cam.h"
44 #include "io/rcdevice.h"
46 #include "osd/osd.h"
48 #include "pg/pg.h"
49 #include "pg/pg_ids.h"
50 #include "pg/vcd.h"
51 #include "pg/rx.h"
52 #include "pg/rcdevice.h"
54 #include "rx/rx.h"
56 float rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
58 extern rcdeviceSwitchState_t switchStates[BOXCAMERA3 - BOXCAMERA1 + 1];
59 extern runcamDevice_t *camDevice;
60 extern bool isButtonPressed;
61 extern bool rcdeviceInMenu;
62 extern rcdeviceWaitingResponseQueue waitingResponseQueue;
63 PG_REGISTER_WITH_RESET_FN(rcdeviceConfig_t, rcdeviceConfig, PG_RCDEVICE_CONFIG, 0);
64 bool unitTestIsSwitchActivited(boxId_e boxId)
66 uint8_t adjustBoxID = boxId - BOXCAMERA1;
67 rcdeviceSwitchState_s switchState = switchStates[adjustBoxID];
68 return switchState.isActivated;
72 void pgResetFn_rcdeviceConfig(rcdeviceConfig_t *rcdeviceConfig)
74 rcdeviceConfig->initDeviceAttempts = 4;
75 rcdeviceConfig->initDeviceAttemptInterval = 1000;
77 rcdeviceConfig->feature = 0;
78 rcdeviceConfig->protocolVersion = 0;
81 uint32_t millis(void);
82 int minTimeout = 180;
84 void rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEvent_e key);
85 rcdeviceResponseParseContext_t* rcdeviceRespCtxQueueShift(rcdeviceWaitingResponseQueue *queue);
88 #define MAX_RESPONSES_COUNT 10
89 #define FIVE_KEY_JOYSTICK_MIN FIVE_KEY_CABLE_JOYSTICK_MIN - 1
90 #define FIVE_KEY_JOYSTICK_MID FIVE_KEY_CABLE_JOYSTICK_MID_START + 1
91 #define FIVE_KEY_JOYSTICK_MAX FIVE_KEY_CABLE_JOYSTICK_MAX + 1
93 typedef struct testData_s {
94 bool isRunCamSplitPortConfigurated;
95 bool isRunCamSplitOpenPortSupported;
96 int8_t maxTimesOfRespDataAvailable;
97 bool isAllowBufferReadWrite;
98 uint8_t indexOfCurrentRespBuf;
99 uint8_t responseBufCount;
100 uint8_t responesBufs[MAX_RESPONSES_COUNT][RCDEVICE_PROTOCOL_MAX_PACKET_SIZE];
101 uint8_t responseBufsLen[MAX_RESPONSES_COUNT];
102 uint8_t responseDataReadPos;
103 uint32_t millis;
104 } testData_t;
106 static testData_t testData;
107 extern rcdeviceWaitingResponseQueue waitingResponseQueue;
109 static void clearResponseBuff()
111 testData.indexOfCurrentRespBuf = 0;
112 testData.responseBufCount = 0;
113 memset(testData.responseBufsLen, 0, MAX_RESPONSES_COUNT);
114 memset(testData.responesBufs, 0, MAX_RESPONSES_COUNT * 60);
116 while (rcdeviceRespCtxQueueShift(&waitingResponseQueue)) {
121 static void resetRCDeviceStatus()
123 isButtonPressed = false;
124 rcdeviceInMenu = false;
125 PG_RESET(rcdeviceConfig);
126 clearResponseBuff();
131 static void addResponseData(uint8_t *data, uint8_t dataLen, bool withDataForFlushSerial)
133 UNUSED(withDataForFlushSerial);
134 memcpy(testData.responesBufs[testData.responseBufCount], data, dataLen);
135 testData.responseBufsLen[testData.responseBufCount] = dataLen;
136 testData.responseBufCount++;
139 TEST(RCDeviceTest, TestRCSplitInitWithoutPortConfigurated)
141 runcamDevice_t device;
143 resetRCDeviceStatus();
145 waitingResponseQueue.headPos = 0;
146 waitingResponseQueue.tailPos = 0;
147 waitingResponseQueue.itemCount = 0;
148 memset(&testData, 0, sizeof(testData));
149 runcamDeviceInit(&device);
150 EXPECT_FALSE(device.isReady);
153 TEST(RCDeviceTest, TestRCSplitInitWithoutOpenPortConfigurated)
155 runcamDevice_t device;
157 resetRCDeviceStatus();
159 waitingResponseQueue.headPos = 0;
160 waitingResponseQueue.tailPos = 0;
161 waitingResponseQueue.itemCount = 0;
162 memset(&testData, 0, sizeof(testData));
163 testData.isRunCamSplitOpenPortSupported = false;
164 testData.isRunCamSplitPortConfigurated = true;
166 runcamDeviceInit(&device);
167 EXPECT_FALSE(device.isReady);
170 TEST(RCDeviceTest, TestInitDevice)
172 runcamDevice_t device;
174 resetRCDeviceStatus();
176 // test correct response
177 waitingResponseQueue.headPos = 0;
178 waitingResponseQueue.tailPos = 0;
179 waitingResponseQueue.itemCount = 0;
180 memset(&testData, 0, sizeof(testData));
181 testData.isRunCamSplitOpenPortSupported = true;
182 testData.isRunCamSplitPortConfigurated = true;
183 testData.isAllowBufferReadWrite = true;
184 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
187 runcamDeviceInit(&device);
188 testData.millis += 3001;
189 rcdeviceReceive(millis() * 1000);
190 addResponseData(responseData, sizeof(responseData), true);
191 rcdeviceReceive(millis() * 1000);
192 testData.millis += minTimeout;
193 testData.responseDataReadPos = 0;
194 testData.indexOfCurrentRespBuf = 0;
195 rcdeviceReceive(millis() * 1000);
196 rcdeviceReceive(millis() * 1000);
197 testData.millis += minTimeout;
198 EXPECT_TRUE(device.isReady);
201 TEST(RCDeviceTest, TestInitDeviceWithInvalidResponse)
203 runcamDevice_t device;
205 resetRCDeviceStatus();
207 // test correct response data with incorrect len
208 waitingResponseQueue.headPos = 0;
209 waitingResponseQueue.tailPos = 0;
210 waitingResponseQueue.itemCount = 0;
211 memset(&testData, 0, sizeof(testData));
212 testData.isRunCamSplitOpenPortSupported = true;
213 testData.isRunCamSplitPortConfigurated = true;
214 testData.isAllowBufferReadWrite = true;
216 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD, 0x33 };
217 addResponseData(responseData, sizeof(responseData), true);
218 runcamDeviceInit(&device);
219 testData.millis += 3001;
220 rcdeviceReceive(millis() * 1000);
221 testData.millis += minTimeout;
222 testData.responseDataReadPos = 0;
223 testData.indexOfCurrentRespBuf = 0;
224 rcdeviceReceive(millis() * 1000);
225 EXPECT_TRUE(device.isReady);
226 clearResponseBuff();
227 testData.millis += minTimeout;
229 // invalid crc
230 uint8_t responseDataWithInvalidCRC[] = { 0xCC, 0x01, 0x37, 0x00, 0xBE };
231 addResponseData(responseDataWithInvalidCRC, sizeof(responseDataWithInvalidCRC), true);
232 runcamDeviceInit(&device);
233 testData.millis += 3001;
234 rcdeviceReceive(millis() * 1000);
235 testData.millis += minTimeout;
236 testData.responseDataReadPos = 0;
237 testData.indexOfCurrentRespBuf = 0;
238 rcdeviceReceive(millis() * 1000);
239 EXPECT_FALSE(device.isReady);
240 clearResponseBuff();
241 testData.millis += minTimeout;
243 // incomplete response data
244 uint8_t incompleteResponseData[] = { 0xCC, 0x01, 0x37 };
245 addResponseData(incompleteResponseData, sizeof(incompleteResponseData), true);
246 runcamDeviceInit(&device);
247 testData.millis += 3001;
248 rcdeviceReceive(millis() * 1000);
249 testData.millis += minTimeout;
250 testData.responseDataReadPos = 0;
251 testData.indexOfCurrentRespBuf = 0;
252 rcdeviceReceive(millis() * 1000);
253 testData.millis += minTimeout;
254 EXPECT_FALSE(device.isReady);
255 clearResponseBuff();
256 testData.millis += minTimeout;
258 // test timeout
259 memset(&testData, 0, sizeof(testData));
260 testData.isRunCamSplitOpenPortSupported = true;
261 testData.isRunCamSplitPortConfigurated = true;
262 testData.isAllowBufferReadWrite = true;
263 runcamDeviceInit(&device);
264 testData.millis += 3001;
265 rcdeviceReceive(millis() * 1000);
266 testData.millis += minTimeout;
267 testData.responseDataReadPos = 0;
268 testData.indexOfCurrentRespBuf = 0;
269 rcdeviceReceive(millis() * 1000);
270 EXPECT_FALSE(device.isReady);
271 clearResponseBuff();
272 testData.millis += minTimeout;
275 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceUnready)
277 resetRCDeviceStatus();
279 // test correct response
280 waitingResponseQueue.headPos = 0;
281 waitingResponseQueue.tailPos = 0;
282 waitingResponseQueue.itemCount = 0;
283 memset(&testData, 0, sizeof(testData));
284 testData.isRunCamSplitOpenPortSupported = true;
285 testData.isRunCamSplitPortConfigurated = true;
286 testData.isAllowBufferReadWrite = true;
287 testData.maxTimesOfRespDataAvailable = 0;
288 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBC }; // wrong response
289 addResponseData(responseData, sizeof(responseData), true);
290 rcdeviceInit();
291 testData.millis += 3001;
292 rcdeviceReceive(millis() * 1000);
293 testData.millis += minTimeout;
294 testData.responseDataReadPos = 0;
295 testData.indexOfCurrentRespBuf = 0;
296 rcdeviceReceive(millis() * 1000);
297 testData.millis += minTimeout;
298 EXPECT_FALSE(camDevice->isReady);
300 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
301 for (uint8_t i = 0; i <= (BOXCAMERA3 - BOXCAMERA1); i++) {
302 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
305 // bind aux1 to wifi button with range [900,1600]
306 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
307 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
308 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
309 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
311 // bind aux2 to power button with range [1900, 2100]
312 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
313 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
314 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
315 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
317 // bind aux3 to change mode with range [1300, 1600]
318 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
319 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
320 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1300);
321 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
323 analyzeModeActivationConditions();
325 // make the binded mode inactive
326 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1800;
327 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
328 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
330 updateActivatedModes();
332 // runn process loop
333 rcdeviceUpdate(0);
335 // remove all request from queue
336 for (int i = 0; i < 10; i++) {
337 testData.millis += 500000;
338 rcdeviceReceive(millis());
341 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA1));
342 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA2));
343 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA3));
346 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceReady)
348 resetRCDeviceStatus();
350 // test correct response
351 memset(&testData, 0, sizeof(testData));
352 testData.isRunCamSplitOpenPortSupported = true;
353 testData.isRunCamSplitPortConfigurated = true;
354 testData.isAllowBufferReadWrite = true;
355 testData.maxTimesOfRespDataAvailable = 0;
356 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
357 addResponseData(responseData, sizeof(responseData), true);
359 camDevice->info.features = 15;
360 rcdeviceInit();
361 testData.millis += 3001;
362 rcdeviceReceive(millis() * 1000);
363 testData.millis += minTimeout;
364 testData.responseDataReadPos = 0;
365 testData.indexOfCurrentRespBuf = 0;
368 rcdeviceReceive(millis() * 1000);
369 testData.millis += minTimeout;
370 EXPECT_TRUE(camDevice->isReady);
372 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
373 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
374 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
378 // bind aux1 to wifi button with range [900,1600]
379 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
380 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
381 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
382 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
384 // bind aux2 to power button with range [1900, 2100]
385 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
386 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
387 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
388 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
390 // bind aux3 to change mode with range [1300, 1600]
391 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
392 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
393 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
394 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
396 analyzeModeActivationConditions();
398 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
399 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
400 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
402 updateActivatedModes();
404 // runn process loop
405 int8_t randNum = rand() % 127 + 6;
406 testData.maxTimesOfRespDataAvailable = randNum;
407 rcdeviceUpdate((timeUs_t)0);
409 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA1));
410 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA2));
411 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA3));
413 // remove all request from queue
414 for (int i = 0; i < 10; i++) {
415 testData.millis += 500000;
416 rcdeviceReceive(millis());
420 TEST(RCDeviceTest, TestWifiModeChangeCombine)
422 resetRCDeviceStatus();
424 memset(&testData, 0, sizeof(testData));
425 testData.isRunCamSplitOpenPortSupported = true;
426 testData.isRunCamSplitPortConfigurated = true;
427 testData.isAllowBufferReadWrite = true;
428 testData.maxTimesOfRespDataAvailable = 0;
429 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
430 addResponseData(responseData, sizeof(responseData), true);
431 rcdeviceInit();
432 testData.millis += 3001;
433 rcdeviceReceive(millis() * 1000);
434 testData.millis += minTimeout;
435 testData.responseDataReadPos = 0;
436 testData.indexOfCurrentRespBuf = 0;
437 rcdeviceReceive(millis() * 1000);
438 testData.millis += minTimeout;
439 EXPECT_TRUE(camDevice->isReady);
441 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
442 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
443 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
447 // bind aux1 to wifi button with range [900,1600]
448 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
449 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
450 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
451 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
453 // bind aux2 to power button with range [1900, 2100]
454 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
455 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
456 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
457 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
459 // bind aux3 to change mode with range [1300, 1600]
460 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
461 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
462 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
463 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
465 analyzeModeActivationConditions();
467 // // make the binded mode inactive
468 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
469 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
470 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
471 updateActivatedModes();
473 // runn process loop
474 int8_t randNum = rand() % 127 + 6;
475 testData.maxTimesOfRespDataAvailable = randNum;
476 rcdeviceUpdate((timeUs_t)0);
478 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA1));
479 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA2));
480 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA3));
483 // // make the binded mode inactive
484 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1500;
485 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1300;
486 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1900;
487 updateActivatedModes();
488 rcdeviceUpdate((timeUs_t)0);
489 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA1));
490 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA2));
491 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA3));
494 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1899;
495 updateActivatedModes();
496 rcdeviceUpdate((timeUs_t)0);
497 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA3));
499 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2001;
500 updateActivatedModes();
501 rcdeviceUpdate((timeUs_t)0);
502 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA1));
503 EXPECT_TRUE(unitTestIsSwitchActivited(BOXCAMERA2));
504 EXPECT_FALSE(unitTestIsSwitchActivited(BOXCAMERA3));
506 // remove all request from queue
507 for (int i = 0; i < 10; i++) {
508 testData.millis += 500000;
509 rcdeviceReceive(millis());
513 TEST(RCDeviceTest, Test5KeyOSDCableSimulationProtocol)
515 resetRCDeviceStatus();
517 memset(&testData, 0, sizeof(testData));
518 testData.isRunCamSplitOpenPortSupported = true;
519 testData.isRunCamSplitPortConfigurated = true;
520 testData.isAllowBufferReadWrite = true;
521 testData.maxTimesOfRespDataAvailable = 0;
522 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
523 addResponseData(responseData, sizeof(responseData), true);
524 rcdeviceInit();
525 testData.millis += 3001;
526 rcdeviceReceive(millis() * 1000);
527 testData.millis += minTimeout;
528 testData.responseDataReadPos = 0;
529 testData.indexOfCurrentRespBuf = 0;
530 rcdeviceReceive(millis() * 1000);
531 testData.millis += minTimeout;
532 EXPECT_TRUE(camDevice->isReady);
533 clearResponseBuff();
535 // test timeout of open connection
536 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
537 rcdeviceReceive(millis() * 1000);
538 testData.millis += 3000;
539 rcdeviceReceive(millis() * 1000);
540 testData.millis += minTimeout;
541 EXPECT_FALSE(rcdeviceInMenu);
542 clearResponseBuff();
544 // open connection with correct response
545 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
546 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
547 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
548 rcdeviceReceive(millis() * 1000);
549 testData.millis += minTimeout;
550 EXPECT_TRUE(rcdeviceInMenu);
551 clearResponseBuff();
553 // open connection with correct response but wrong data length
554 uint8_t incorrectResponseDataOfOpenConnection1[] = { 0xCC, 0x11, 0xe7, 0x55 };
555 addResponseData(incorrectResponseDataOfOpenConnection1, sizeof(incorrectResponseDataOfOpenConnection1), true);
556 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
557 rcdeviceReceive(millis() * 1000);
558 testData.millis += minTimeout;
559 EXPECT_TRUE(rcdeviceInMenu);
560 clearResponseBuff();
562 // open connection with invalid crc
563 uint8_t incorrectResponseDataOfOpenConnection2[] = { 0xCC, 0x10, 0x42 };
564 addResponseData(incorrectResponseDataOfOpenConnection2, sizeof(incorrectResponseDataOfOpenConnection2), true);
565 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
566 rcdeviceReceive(millis() * 1000);
567 testData.millis += minTimeout;
568 EXPECT_TRUE(rcdeviceInMenu); // when crc wrong won't change the menu state
569 clearResponseBuff();
571 // test timeout of close connection
572 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
573 rcdeviceReceive(millis() * 1000);
574 testData.millis += 3000;
575 rcdeviceReceive(millis() * 1000);
576 testData.millis += minTimeout;
577 EXPECT_TRUE(rcdeviceInMenu); // close menu timeout won't change the menu state
578 clearResponseBuff();
580 // close connection with correct response
581 uint8_t responseDataOfCloseConnection[] = { 0xCC, 0x21, 0x11 };
582 addResponseData(responseDataOfCloseConnection, sizeof(responseDataOfCloseConnection), true);
583 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
584 rcdeviceReceive(millis() * 1000);
585 testData.millis += minTimeout;
586 EXPECT_FALSE(rcdeviceInMenu);
587 clearResponseBuff();
589 // close connection with correct response but wrong data length
590 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
591 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
592 rcdeviceReceive(millis() * 1000);
593 testData.millis += minTimeout;
594 EXPECT_TRUE(rcdeviceInMenu);
595 clearResponseBuff();
597 uint8_t responseDataOfCloseConnection1[] = { 0xCC, 0x21, 0x11, 0xC1 };
598 addResponseData(responseDataOfCloseConnection1, sizeof(responseDataOfCloseConnection1), true);
599 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
600 rcdeviceReceive(millis() * 1000);
601 testData.millis += minTimeout;
602 EXPECT_FALSE(rcdeviceInMenu);
603 clearResponseBuff();
605 // close connection with response that invalid crc
606 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
607 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
608 rcdeviceReceive(millis() * 1000);
609 testData.millis += minTimeout;
610 EXPECT_TRUE(rcdeviceInMenu);
611 clearResponseBuff();
613 uint8_t responseDataOfCloseConnection2[] = { 0xCC, 0x21, 0xA1 };
614 addResponseData(responseDataOfCloseConnection2, sizeof(responseDataOfCloseConnection2), true);
615 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
616 rcdeviceReceive(millis() * 1000);
617 testData.millis += minTimeout;
618 EXPECT_TRUE(rcdeviceInMenu);
619 clearResponseBuff();
621 // release button first
622 uint8_t responseDataOfSimulation4[] = { 0xCC, 0xA5 };
623 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
624 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
625 rcdeviceReceive(millis() * 1000);
626 testData.millis += minTimeout;
627 EXPECT_FALSE(isButtonPressed);
628 clearResponseBuff();
630 // simulate press button with no response
631 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
632 testData.millis += 2000;
633 rcdeviceReceive(millis() * 1000);
634 testData.millis += minTimeout;
635 EXPECT_FALSE(isButtonPressed);
636 clearResponseBuff();
638 // simulate press button with correct response
639 uint8_t responseDataOfSimulation1[] = { 0xCC, 0xA5 };
640 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true);
641 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
642 rcdeviceReceive(millis() * 1000);
643 testData.millis += minTimeout;
644 EXPECT_TRUE(isButtonPressed);
645 clearResponseBuff();
647 // simulate press button with correct response but wrong data length
648 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true); // release first
649 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
650 rcdeviceReceive(millis() * 1000);
651 testData.millis += minTimeout;
652 EXPECT_FALSE(isButtonPressed);
653 clearResponseBuff();
655 uint8_t responseDataOfSimulation2[] = { 0xCC, 0xA5, 0x22 };
656 addResponseData(responseDataOfSimulation2, sizeof(responseDataOfSimulation2), true);
657 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
658 rcdeviceReceive(millis() * 1000);
659 testData.millis += minTimeout;
660 EXPECT_TRUE(isButtonPressed);
661 clearResponseBuff();
663 // simulate press button event with incorrect response
664 uint8_t responseDataOfSimulation3[] = { 0xCC, 0xB5, 0x22 };
665 addResponseData(responseDataOfSimulation3, sizeof(responseDataOfSimulation3), true);
666 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
667 rcdeviceReceive(millis() * 1000);
668 testData.millis += minTimeout;
669 EXPECT_TRUE(isButtonPressed);
670 clearResponseBuff();
672 // simulate release button with correct response
673 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
674 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
675 rcdeviceReceive(millis() * 1000);
676 testData.millis += minTimeout;
677 EXPECT_FALSE(isButtonPressed);
678 clearResponseBuff();
680 // simulate release button with correct response but wrong data length
681 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true); // press first
682 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
683 rcdeviceReceive(millis() * 1000);
684 testData.millis += minTimeout;
685 EXPECT_TRUE(isButtonPressed);
686 clearResponseBuff();
688 uint8_t responseDataOfSimulation5[] = { 0xCC, 0xA5, 0xFF };
689 addResponseData(responseDataOfSimulation5, sizeof(responseDataOfSimulation5), true);
690 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
691 rcdeviceReceive(millis() * 1000);
692 testData.millis += minTimeout;
693 EXPECT_FALSE(isButtonPressed);
694 clearResponseBuff();
696 // simulate release button with incorrect response
697 uint8_t responseDataOfSimulation6[] = { 0xCC, 0x31, 0xFF };
698 addResponseData(responseDataOfSimulation6, sizeof(responseDataOfSimulation6), true);
699 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
700 rcdeviceReceive(millis() * 1000);
701 testData.millis += minTimeout;
702 EXPECT_FALSE(isButtonPressed);
703 clearResponseBuff();
705 // remove all request from queue
706 for (int i = 0; i < 300; i++) {
707 testData.millis += 500000;
708 rcdeviceReceive(millis());
712 TEST(RCDeviceTest, Test5KeyOSDCableSimulationWithout5KeyFeatureSupport)
714 resetRCDeviceStatus();
716 // test simulation without device init
717 rcData[THROTTLE] = FIVE_KEY_JOYSTICK_MID; // THROTTLE Mid
718 rcData[ROLL] = FIVE_KEY_JOYSTICK_MID; // ROLL Mid
719 rcData[PITCH] = FIVE_KEY_JOYSTICK_MID; // PITCH Mid
720 rcData[YAW] = FIVE_KEY_JOYSTICK_MAX; // Yaw High
721 rcdeviceUpdate(millis() * 1000);
722 EXPECT_FALSE(rcdeviceInMenu);
723 // remove all request from queue
724 for (int i = 0; i < 10; i++) {
725 testData.millis += 500000;
726 rcdeviceReceive(millis());
729 // init device that have not 5 key OSD cable simulation feature
730 memset(&testData, 0, sizeof(testData));
731 testData.isRunCamSplitOpenPortSupported = true;
732 testData.isRunCamSplitPortConfigurated = true;
733 testData.isAllowBufferReadWrite = true;
734 testData.maxTimesOfRespDataAvailable = 0;
735 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
737 rcdeviceInit();
738 testData.millis += 3001;
739 rcdeviceReceive(millis() * 1000);
740 testData.millis += 200;
741 testData.responseDataReadPos = 0;
742 testData.indexOfCurrentRespBuf = 0;
743 addResponseData(responseData, sizeof(responseData), true);
744 rcdeviceReceive(millis() * 1000);
745 testData.millis += 200;
746 EXPECT_TRUE(camDevice->isReady);
747 clearResponseBuff();
749 // open connection, rcdeviceInMenu will be false if the codes is right
750 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
751 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), false);
752 rcdeviceUpdate(millis() * 1000);
753 EXPECT_FALSE(rcdeviceInMenu);
754 clearResponseBuff();
756 // remove all request from queue
757 for (int i = 0; i < 10; i++) {
758 testData.millis += 500000;
759 rcdeviceReceive(millis());
763 extern "C" {
764 serialPort_t *openSerialPort(serialPortIdentifier_e identifier, serialPortFunction_e functionMask, serialReceiveCallbackPtr callback, void *callbackData, uint32_t baudRate, portMode_e mode, portOptions_e options)
766 UNUSED(identifier);
767 UNUSED(functionMask);
768 UNUSED(baudRate);
769 UNUSED(mode);
770 UNUSED(options);
772 if (testData.isRunCamSplitOpenPortSupported) {
773 static serialPort_t s;
774 s.vTable = NULL;
776 // common serial initialisation code should move to serialPort::init()
777 s.rxBufferHead = s.rxBufferTail = 0;
778 s.txBufferHead = s.txBufferTail = 0;
779 s.rxBufferSize = 0;
780 s.txBufferSize = 0;
781 s.rxBuffer = s.rxBuffer;
782 s.txBuffer = s.txBuffer;
784 // callback works for IRQ-based RX ONLY
785 s.rxCallback = callback;
786 s.rxCallbackData = callbackData;
787 s.baudRate = 0;
789 return (serialPort_t *)&s;
792 return NULL;
795 const serialPortConfig_t *findSerialPortConfig(serialPortFunction_e function)
797 UNUSED(function);
798 if (testData.isRunCamSplitPortConfigurated) {
799 static serialPortConfig_t portConfig;
801 portConfig.identifier = SERIAL_PORT_USART3;
802 portConfig.msp_baudrateIndex = BAUD_115200;
803 portConfig.gps_baudrateIndex = BAUD_57600;
804 portConfig.telemetry_baudrateIndex = BAUD_AUTO;
805 portConfig.blackbox_baudrateIndex = BAUD_115200;
806 portConfig.functionMask = FUNCTION_MSP;
808 return &portConfig;
811 return NULL;
814 uint32_t serialRxBytesWaiting(const serialPort_t *instance)
816 UNUSED(instance);
818 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
819 uint8_t leftDataLen = 0;
820 if (testData.responseDataReadPos + 1 > testData.responseBufsLen[bufIndex]) {
821 return 0;
822 } else {
823 leftDataLen = testData.responseBufsLen[bufIndex] - (testData.responseDataReadPos);
826 if (leftDataLen) {
827 return leftDataLen;
830 return 0;
833 uint8_t serialRead(serialPort_t *instance)
835 UNUSED(instance);
837 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
838 uint8_t *buffer = NULL;
839 uint8_t leftDataLen = 0;
840 if (testData.responseDataReadPos >= testData.responseBufsLen[bufIndex]) {
841 leftDataLen = 0;
842 } else {
843 buffer = testData.responesBufs[bufIndex];
844 leftDataLen = testData.responseBufsLen[bufIndex] - testData.responseDataReadPos;
847 if (leftDataLen) {
848 return buffer[testData.responseDataReadPos++];
851 return 0;
854 void sbufWriteString(sbuf_t *dst, const char *string)
856 UNUSED(dst); UNUSED(string);
858 if (testData.isAllowBufferReadWrite) {
859 sbufWriteData(dst, string, strlen(string));
862 void sbufWriteU8(sbuf_t *dst, uint8_t val)
864 UNUSED(dst); UNUSED(val);
866 if (testData.isAllowBufferReadWrite) {
867 *dst->ptr++ = val;
871 void sbufWriteData(sbuf_t *dst, const void *data, int len)
873 UNUSED(dst); UNUSED(data); UNUSED(len);
875 if (testData.isAllowBufferReadWrite) {
876 memcpy(dst->ptr, data, len);
877 dst->ptr += len;
882 // modifies streambuf so that written data are prepared for reading
883 void sbufSwitchToReader(sbuf_t *buf, uint8_t *base)
885 UNUSED(buf); UNUSED(base);
887 if (testData.isAllowBufferReadWrite) {
888 buf->end = buf->ptr;
889 buf->ptr = base;
893 uint8_t sbufReadU8(sbuf_t *src)
895 if (testData.isAllowBufferReadWrite) {
896 return *src->ptr++;
899 return 0;
902 void sbufAdvance(sbuf_t *buf, int size)
904 if (testData.isAllowBufferReadWrite) {
905 buf->ptr += size;
909 int sbufBytesRemaining(sbuf_t *buf)
911 if (testData.isAllowBufferReadWrite) {
912 return buf->end - buf->ptr;
914 return 0;
917 const uint8_t* sbufConstPtr(const sbuf_t *buf)
919 return buf->ptr;
922 void sbufReadData(sbuf_t *src, void *data, int len)
924 if (testData.isAllowBufferReadWrite) {
925 memcpy(data, src->ptr, len);
929 uint16_t sbufReadU16(sbuf_t *src)
931 uint16_t ret;
932 ret = sbufReadU8(src);
933 ret |= sbufReadU8(src) << 8;
934 return ret;
937 void sbufWriteU16(sbuf_t *dst, uint16_t val)
939 sbufWriteU8(dst, val >> 0);
940 sbufWriteU8(dst, val >> 8);
943 void sbufWriteU16BigEndian(sbuf_t *dst, uint16_t val)
945 sbufWriteU8(dst, val >> 8);
946 sbufWriteU8(dst, (uint8_t)val);
949 bool featureIsEnabled(uint32_t) { return false; }
951 void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count)
953 UNUSED(instance); UNUSED(data); UNUSED(count);
955 // reset the input buffer
956 testData.responseDataReadPos = 0;
957 testData.indexOfCurrentRespBuf++;
958 if (testData.indexOfCurrentRespBuf >= testData.responseBufCount) {
959 testData.indexOfCurrentRespBuf = 0;
961 // testData.maxTimesOfRespDataAvailable = testData.responseDataLen + 1;
964 const serialPortConfig_t *findNextSerialPortConfig(serialPortFunction_e function)
966 UNUSED(function);
968 return NULL;
971 void closeSerialPort(serialPort_t *serialPort)
973 UNUSED(serialPort);
976 uint8_t* sbufPtr(sbuf_t *buf)
978 return buf->ptr;
981 uint32_t sbufReadU32(sbuf_t *src)
983 uint32_t ret;
984 ret = sbufReadU8(src);
985 ret |= sbufReadU8(src) << 8;
986 ret |= sbufReadU8(src) << 16;
987 ret |= sbufReadU8(src) << 24;
988 return ret;
991 uint32_t millis(void) { return testData.millis++; }
992 uint32_t micros(void) { return millis() * 1000; }
993 void beeper(beeperMode_e mode) { UNUSED(mode); }
994 uint8_t armingFlags = 0;
995 bool cmsInMenu;
996 uint32_t resumeRefreshAt = 0;
997 int getArmingDisableFlags(void) {return 0;}
998 void pinioBoxTaskControl(void) {}
999 attitudeEulerAngles_t attitude = { { 0, 0, 0 } };