Remove deprecated CLI name command
[betaflight.git] / src / test / unit / rcdevice_unittest.cc
blob2f8c7abbf045a5f5a2d042335f1644aaea015754
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"
36 #include "drivers/serial.h"
38 #include "io/beeper.h"
39 #include "io/serial.h"
41 #include "scheduler/scheduler.h"
42 #include "io/rcdevice_cam.h"
43 #include "io/rcdevice.h"
45 #include "osd/osd.h"
47 #include "pg/pg.h"
48 #include "pg/pg_ids.h"
49 #include "pg/vcd.h"
50 #include "pg/rx.h"
51 #include "pg/rcdevice.h"
53 #include "rx/rx.h"
55 int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
57 extern rcdeviceSwitchState_t switchStates[BOXCAMERA3 - BOXCAMERA1 + 1];
58 extern runcamDevice_t *camDevice;
59 extern bool isButtonPressed;
60 extern bool rcdeviceInMenu;
61 extern rcdeviceWaitingResponseQueue waitingResponseQueue;
62 PG_REGISTER_WITH_RESET_FN(rcdeviceConfig_t, rcdeviceConfig, PG_RCDEVICE_CONFIG, 0);
63 bool unitTestIsSwitchActivited(boxId_e boxId)
65 uint8_t adjustBoxID = boxId - BOXCAMERA1;
66 rcdeviceSwitchState_s switchState = switchStates[adjustBoxID];
67 return switchState.isActivated;
71 void pgResetFn_rcdeviceConfig(rcdeviceConfig_t *rcdeviceConfig)
73 rcdeviceConfig->initDeviceAttempts = 4;
74 rcdeviceConfig->initDeviceAttemptInterval = 1000;
76 rcdeviceConfig->feature = 0;
77 rcdeviceConfig->protocolVersion = 0;
80 uint32_t millis(void);
81 int minTimeout = 180;
83 void rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEvent_e key);
84 rcdeviceResponseParseContext_t* rcdeviceRespCtxQueueShift(rcdeviceWaitingResponseQueue *queue);
87 #define MAX_RESPONSES_COUNT 10
88 #define FIVE_KEY_JOYSTICK_MIN FIVE_KEY_CABLE_JOYSTICK_MIN - 1
89 #define FIVE_KEY_JOYSTICK_MID FIVE_KEY_CABLE_JOYSTICK_MID_START + 1
90 #define FIVE_KEY_JOYSTICK_MAX FIVE_KEY_CABLE_JOYSTICK_MAX + 1
92 typedef struct testData_s {
93 bool isRunCamSplitPortConfigurated;
94 bool isRunCamSplitOpenPortSupported;
95 int8_t maxTimesOfRespDataAvailable;
96 bool isAllowBufferReadWrite;
97 uint8_t indexOfCurrentRespBuf;
98 uint8_t responseBufCount;
99 uint8_t responesBufs[MAX_RESPONSES_COUNT][RCDEVICE_PROTOCOL_MAX_PACKET_SIZE];
100 uint8_t responseBufsLen[MAX_RESPONSES_COUNT];
101 uint8_t responseDataReadPos;
102 uint32_t millis;
103 } testData_t;
105 static testData_t testData;
106 extern rcdeviceWaitingResponseQueue waitingResponseQueue;
108 static void clearResponseBuff()
110 testData.indexOfCurrentRespBuf = 0;
111 testData.responseBufCount = 0;
112 memset(testData.responseBufsLen, 0, MAX_RESPONSES_COUNT);
113 memset(testData.responesBufs, 0, MAX_RESPONSES_COUNT * 60);
115 while (rcdeviceRespCtxQueueShift(&waitingResponseQueue)) {
120 static void resetRCDeviceStatus()
122 isButtonPressed = false;
123 rcdeviceInMenu = false;
124 PG_RESET(rcdeviceConfig);
125 clearResponseBuff();
130 static void addResponseData(uint8_t *data, uint8_t dataLen, bool withDataForFlushSerial)
132 UNUSED(withDataForFlushSerial);
133 memcpy(testData.responesBufs[testData.responseBufCount], data, dataLen);
134 testData.responseBufsLen[testData.responseBufCount] = dataLen;
135 testData.responseBufCount++;
138 TEST(RCDeviceTest, TestRCSplitInitWithoutPortConfigurated)
140 runcamDevice_t device;
142 resetRCDeviceStatus();
144 waitingResponseQueue.headPos = 0;
145 waitingResponseQueue.tailPos = 0;
146 waitingResponseQueue.itemCount = 0;
147 memset(&testData, 0, sizeof(testData));
148 runcamDeviceInit(&device);
149 EXPECT_EQ(false, device.isReady);
152 TEST(RCDeviceTest, TestRCSplitInitWithoutOpenPortConfigurated)
154 runcamDevice_t device;
156 resetRCDeviceStatus();
158 waitingResponseQueue.headPos = 0;
159 waitingResponseQueue.tailPos = 0;
160 waitingResponseQueue.itemCount = 0;
161 memset(&testData, 0, sizeof(testData));
162 testData.isRunCamSplitOpenPortSupported = false;
163 testData.isRunCamSplitPortConfigurated = true;
165 runcamDeviceInit(&device);
166 EXPECT_EQ(false, device.isReady);
169 TEST(RCDeviceTest, TestInitDevice)
171 runcamDevice_t device;
173 resetRCDeviceStatus();
175 // test correct response
176 waitingResponseQueue.headPos = 0;
177 waitingResponseQueue.tailPos = 0;
178 waitingResponseQueue.itemCount = 0;
179 memset(&testData, 0, sizeof(testData));
180 testData.isRunCamSplitOpenPortSupported = true;
181 testData.isRunCamSplitPortConfigurated = true;
182 testData.isAllowBufferReadWrite = true;
183 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
186 runcamDeviceInit(&device);
187 testData.millis += 3001;
188 rcdeviceReceive(millis() * 1000);
189 addResponseData(responseData, sizeof(responseData), true);
190 rcdeviceReceive(millis() * 1000);
191 testData.millis += minTimeout;
192 testData.responseDataReadPos = 0;
193 testData.indexOfCurrentRespBuf = 0;
194 rcdeviceReceive(millis() * 1000);
195 rcdeviceReceive(millis() * 1000);
196 testData.millis += minTimeout;
197 EXPECT_EQ(device.isReady, true);
200 TEST(RCDeviceTest, TestInitDeviceWithInvalidResponse)
202 runcamDevice_t device;
204 resetRCDeviceStatus();
206 // test correct response data with incorrect len
207 waitingResponseQueue.headPos = 0;
208 waitingResponseQueue.tailPos = 0;
209 waitingResponseQueue.itemCount = 0;
210 memset(&testData, 0, sizeof(testData));
211 testData.isRunCamSplitOpenPortSupported = true;
212 testData.isRunCamSplitPortConfigurated = true;
213 testData.isAllowBufferReadWrite = true;
215 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD, 0x33 };
216 addResponseData(responseData, sizeof(responseData), true);
217 runcamDeviceInit(&device);
218 testData.millis += 3001;
219 rcdeviceReceive(millis() * 1000);
220 testData.millis += minTimeout;
221 testData.responseDataReadPos = 0;
222 testData.indexOfCurrentRespBuf = 0;
223 rcdeviceReceive(millis() * 1000);
224 EXPECT_EQ(device.isReady, true);
225 clearResponseBuff();
226 testData.millis += minTimeout;
228 // invalid crc
229 uint8_t responseDataWithInvalidCRC[] = { 0xCC, 0x01, 0x37, 0x00, 0xBE };
230 addResponseData(responseDataWithInvalidCRC, sizeof(responseDataWithInvalidCRC), true);
231 runcamDeviceInit(&device);
232 testData.millis += 3001;
233 rcdeviceReceive(millis() * 1000);
234 testData.millis += minTimeout;
235 testData.responseDataReadPos = 0;
236 testData.indexOfCurrentRespBuf = 0;
237 rcdeviceReceive(millis() * 1000);
238 EXPECT_EQ(device.isReady, false);
239 clearResponseBuff();
240 testData.millis += minTimeout;
242 // incomplete response data
243 uint8_t incompleteResponseData[] = { 0xCC, 0x01, 0x37 };
244 addResponseData(incompleteResponseData, sizeof(incompleteResponseData), true);
245 runcamDeviceInit(&device);
246 testData.millis += 3001;
247 rcdeviceReceive(millis() * 1000);
248 testData.millis += minTimeout;
249 testData.responseDataReadPos = 0;
250 testData.indexOfCurrentRespBuf = 0;
251 rcdeviceReceive(millis() * 1000);
252 testData.millis += minTimeout;
253 EXPECT_EQ(device.isReady, false);
254 clearResponseBuff();
255 testData.millis += minTimeout;
257 // test timeout
258 memset(&testData, 0, sizeof(testData));
259 testData.isRunCamSplitOpenPortSupported = true;
260 testData.isRunCamSplitPortConfigurated = true;
261 testData.isAllowBufferReadWrite = true;
262 runcamDeviceInit(&device);
263 testData.millis += 3001;
264 rcdeviceReceive(millis() * 1000);
265 testData.millis += minTimeout;
266 testData.responseDataReadPos = 0;
267 testData.indexOfCurrentRespBuf = 0;
268 rcdeviceReceive(millis() * 1000);
269 EXPECT_EQ(device.isReady, false);
270 clearResponseBuff();
271 testData.millis += minTimeout;
274 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceUnready)
276 resetRCDeviceStatus();
278 // test correct response
279 waitingResponseQueue.headPos = 0;
280 waitingResponseQueue.tailPos = 0;
281 waitingResponseQueue.itemCount = 0;
282 memset(&testData, 0, sizeof(testData));
283 testData.isRunCamSplitOpenPortSupported = true;
284 testData.isRunCamSplitPortConfigurated = true;
285 testData.isAllowBufferReadWrite = true;
286 testData.maxTimesOfRespDataAvailable = 0;
287 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBC }; // wrong response
288 addResponseData(responseData, sizeof(responseData), true);
289 rcdeviceInit();
290 testData.millis += 3001;
291 rcdeviceReceive(millis() * 1000);
292 testData.millis += minTimeout;
293 testData.responseDataReadPos = 0;
294 testData.indexOfCurrentRespBuf = 0;
295 rcdeviceReceive(millis() * 1000);
296 testData.millis += minTimeout;
297 EXPECT_EQ(camDevice->isReady, false);
299 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
300 for (uint8_t i = 0; i <= (BOXCAMERA3 - BOXCAMERA1); i++) {
301 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
304 // bind aux1 to wifi button with range [900,1600]
305 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
306 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
307 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
308 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
310 // bind aux2 to power button with range [1900, 2100]
311 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
312 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
313 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
314 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
316 // bind aux3 to change mode with range [1300, 1600]
317 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
318 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
319 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1300);
320 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
322 analyzeModeActivationConditions();
324 // make the binded mode inactive
325 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1800;
326 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
327 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
329 updateActivatedModes();
331 // runn process loop
332 rcdeviceUpdate(0);
334 // remove all request from queue
335 for (int i = 0; i < 10; i++) {
336 testData.millis += 500000;
337 rcdeviceReceive(millis());
340 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
341 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA2));
342 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
345 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceReady)
347 resetRCDeviceStatus();
349 // test correct response
350 memset(&testData, 0, sizeof(testData));
351 testData.isRunCamSplitOpenPortSupported = true;
352 testData.isRunCamSplitPortConfigurated = true;
353 testData.isAllowBufferReadWrite = true;
354 testData.maxTimesOfRespDataAvailable = 0;
355 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
356 addResponseData(responseData, sizeof(responseData), true);
358 camDevice->info.features = 15;
359 rcdeviceInit();
360 testData.millis += 3001;
361 rcdeviceReceive(millis() * 1000);
362 testData.millis += minTimeout;
363 testData.responseDataReadPos = 0;
364 testData.indexOfCurrentRespBuf = 0;
367 rcdeviceReceive(millis() * 1000);
368 testData.millis += minTimeout;
369 EXPECT_EQ(camDevice->isReady, true);
371 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
372 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
373 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
377 // bind aux1 to wifi button with range [900,1600]
378 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
379 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
380 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
381 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
383 // bind aux2 to power button with range [1900, 2100]
384 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
385 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
386 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
387 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
389 // bind aux3 to change mode with range [1300, 1600]
390 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
391 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
392 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
393 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
395 analyzeModeActivationConditions();
397 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
398 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
399 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
401 updateActivatedModes();
403 // runn process loop
404 int8_t randNum = rand() % 127 + 6;
405 testData.maxTimesOfRespDataAvailable = randNum;
406 rcdeviceUpdate((timeUs_t)0);
408 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
409 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
410 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
412 // remove all request from queue
413 for (int i = 0; i < 10; i++) {
414 testData.millis += 500000;
415 rcdeviceReceive(millis());
419 TEST(RCDeviceTest, TestWifiModeChangeCombine)
421 resetRCDeviceStatus();
423 memset(&testData, 0, sizeof(testData));
424 testData.isRunCamSplitOpenPortSupported = true;
425 testData.isRunCamSplitPortConfigurated = true;
426 testData.isAllowBufferReadWrite = true;
427 testData.maxTimesOfRespDataAvailable = 0;
428 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
429 addResponseData(responseData, sizeof(responseData), true);
430 rcdeviceInit();
431 testData.millis += 3001;
432 rcdeviceReceive(millis() * 1000);
433 testData.millis += minTimeout;
434 testData.responseDataReadPos = 0;
435 testData.indexOfCurrentRespBuf = 0;
436 rcdeviceReceive(millis() * 1000);
437 testData.millis += minTimeout;
438 EXPECT_EQ(true, camDevice->isReady);
440 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
441 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
442 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
446 // bind aux1 to wifi button with range [900,1600]
447 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
448 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
449 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
450 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
452 // bind aux2 to power button with range [1900, 2100]
453 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
454 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
455 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
456 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
458 // bind aux3 to change mode with range [1300, 1600]
459 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
460 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
461 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
462 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
464 analyzeModeActivationConditions();
466 // // make the binded mode inactive
467 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
468 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
469 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
470 updateActivatedModes();
472 // runn process loop
473 int8_t randNum = rand() % 127 + 6;
474 testData.maxTimesOfRespDataAvailable = randNum;
475 rcdeviceUpdate((timeUs_t)0);
477 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
478 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
479 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
482 // // make the binded mode inactive
483 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1500;
484 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1300;
485 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1900;
486 updateActivatedModes();
487 rcdeviceUpdate((timeUs_t)0);
488 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA1));
489 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA2));
490 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA3));
493 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1899;
494 updateActivatedModes();
495 rcdeviceUpdate((timeUs_t)0);
496 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
498 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2001;
499 updateActivatedModes();
500 rcdeviceUpdate((timeUs_t)0);
501 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA1));
502 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
503 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
505 // remove all request from queue
506 for (int i = 0; i < 10; i++) {
507 testData.millis += 500000;
508 rcdeviceReceive(millis());
512 TEST(RCDeviceTest, Test5KeyOSDCableSimulationProtocol)
514 resetRCDeviceStatus();
516 memset(&testData, 0, sizeof(testData));
517 testData.isRunCamSplitOpenPortSupported = true;
518 testData.isRunCamSplitPortConfigurated = true;
519 testData.isAllowBufferReadWrite = true;
520 testData.maxTimesOfRespDataAvailable = 0;
521 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
522 addResponseData(responseData, sizeof(responseData), true);
523 rcdeviceInit();
524 testData.millis += 3001;
525 rcdeviceReceive(millis() * 1000);
526 testData.millis += minTimeout;
527 testData.responseDataReadPos = 0;
528 testData.indexOfCurrentRespBuf = 0;
529 rcdeviceReceive(millis() * 1000);
530 testData.millis += minTimeout;
531 EXPECT_EQ(true, camDevice->isReady);
532 clearResponseBuff();
534 // test timeout of open connection
535 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
536 rcdeviceReceive(millis() * 1000);
537 testData.millis += 3000;
538 rcdeviceReceive(millis() * 1000);
539 testData.millis += minTimeout;
540 EXPECT_EQ(false, rcdeviceInMenu);
541 clearResponseBuff();
543 // open connection with correct response
544 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
545 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
546 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
547 rcdeviceReceive(millis() * 1000);
548 testData.millis += minTimeout;
549 EXPECT_EQ(true, rcdeviceInMenu);
550 clearResponseBuff();
552 // open connection with correct response but wrong data length
553 uint8_t incorrectResponseDataOfOpenConnection1[] = { 0xCC, 0x11, 0xe7, 0x55 };
554 addResponseData(incorrectResponseDataOfOpenConnection1, sizeof(incorrectResponseDataOfOpenConnection1), true);
555 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
556 rcdeviceReceive(millis() * 1000);
557 testData.millis += minTimeout;
558 EXPECT_EQ(true, rcdeviceInMenu);
559 clearResponseBuff();
561 // open connection with invalid crc
562 uint8_t incorrectResponseDataOfOpenConnection2[] = { 0xCC, 0x10, 0x42 };
563 addResponseData(incorrectResponseDataOfOpenConnection2, sizeof(incorrectResponseDataOfOpenConnection2), true);
564 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
565 rcdeviceReceive(millis() * 1000);
566 testData.millis += minTimeout;
567 EXPECT_EQ(true, rcdeviceInMenu); // when crc wrong won't change the menu state
568 clearResponseBuff();
570 // test timeout of close connection
571 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
572 rcdeviceReceive(millis() * 1000);
573 testData.millis += 3000;
574 rcdeviceReceive(millis() * 1000);
575 testData.millis += minTimeout;
576 EXPECT_EQ(true, rcdeviceInMenu); // close menu timeout won't change the menu state
577 clearResponseBuff();
579 // close connection with correct response
580 uint8_t responseDataOfCloseConnection[] = { 0xCC, 0x21, 0x11 };
581 addResponseData(responseDataOfCloseConnection, sizeof(responseDataOfCloseConnection), true);
582 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
583 rcdeviceReceive(millis() * 1000);
584 testData.millis += minTimeout;
585 EXPECT_EQ(false, rcdeviceInMenu);
586 clearResponseBuff();
588 // close connection with correct response but wrong data length
589 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
590 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
591 rcdeviceReceive(millis() * 1000);
592 testData.millis += minTimeout;
593 EXPECT_EQ(true, rcdeviceInMenu);
594 clearResponseBuff();
596 uint8_t responseDataOfCloseConnection1[] = { 0xCC, 0x21, 0x11, 0xC1 };
597 addResponseData(responseDataOfCloseConnection1, sizeof(responseDataOfCloseConnection1), true);
598 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
599 rcdeviceReceive(millis() * 1000);
600 testData.millis += minTimeout;
601 EXPECT_EQ(false, rcdeviceInMenu);
602 clearResponseBuff();
604 // close connection with response that invalid crc
605 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
606 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
607 rcdeviceReceive(millis() * 1000);
608 testData.millis += minTimeout;
609 EXPECT_EQ(true, rcdeviceInMenu);
610 clearResponseBuff();
612 uint8_t responseDataOfCloseConnection2[] = { 0xCC, 0x21, 0xA1 };
613 addResponseData(responseDataOfCloseConnection2, sizeof(responseDataOfCloseConnection2), true);
614 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
615 rcdeviceReceive(millis() * 1000);
616 testData.millis += minTimeout;
617 EXPECT_EQ(true, rcdeviceInMenu);
618 clearResponseBuff();
620 // release button first
621 uint8_t responseDataOfSimulation4[] = { 0xCC, 0xA5 };
622 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
623 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
624 rcdeviceReceive(millis() * 1000);
625 testData.millis += minTimeout;
626 EXPECT_EQ(false, isButtonPressed);
627 clearResponseBuff();
629 // simulate press button with no response
630 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
631 testData.millis += 2000;
632 rcdeviceReceive(millis() * 1000);
633 testData.millis += minTimeout;
634 EXPECT_EQ(false, isButtonPressed);
635 clearResponseBuff();
637 // simulate press button with correct response
638 uint8_t responseDataOfSimulation1[] = { 0xCC, 0xA5 };
639 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true);
640 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
641 rcdeviceReceive(millis() * 1000);
642 testData.millis += minTimeout;
643 EXPECT_EQ(true, isButtonPressed);
644 clearResponseBuff();
646 // simulate press button with correct response but wrong data length
647 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true); // release first
648 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
649 rcdeviceReceive(millis() * 1000);
650 testData.millis += minTimeout;
651 EXPECT_EQ(false, isButtonPressed);
652 clearResponseBuff();
654 uint8_t responseDataOfSimulation2[] = { 0xCC, 0xA5, 0x22 };
655 addResponseData(responseDataOfSimulation2, sizeof(responseDataOfSimulation2), true);
656 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
657 rcdeviceReceive(millis() * 1000);
658 testData.millis += minTimeout;
659 EXPECT_EQ(true, isButtonPressed);
660 clearResponseBuff();
662 // simulate press button event with incorrect response
663 uint8_t responseDataOfSimulation3[] = { 0xCC, 0xB5, 0x22 };
664 addResponseData(responseDataOfSimulation3, sizeof(responseDataOfSimulation3), true);
665 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
666 rcdeviceReceive(millis() * 1000);
667 testData.millis += minTimeout;
668 EXPECT_EQ(true, isButtonPressed);
669 clearResponseBuff();
671 // simulate release button with correct response
672 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
673 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
674 rcdeviceReceive(millis() * 1000);
675 testData.millis += minTimeout;
676 EXPECT_EQ(false, isButtonPressed);
677 clearResponseBuff();
679 // simulate release button with correct response but wrong data length
680 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true); // press first
681 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
682 rcdeviceReceive(millis() * 1000);
683 testData.millis += minTimeout;
684 EXPECT_EQ(true, isButtonPressed);
685 clearResponseBuff();
687 uint8_t responseDataOfSimulation5[] = { 0xCC, 0xA5, 0xFF };
688 addResponseData(responseDataOfSimulation5, sizeof(responseDataOfSimulation5), true);
689 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
690 rcdeviceReceive(millis() * 1000);
691 testData.millis += minTimeout;
692 EXPECT_EQ(false, isButtonPressed);
693 clearResponseBuff();
695 // simulate release button with incorrect response
696 uint8_t responseDataOfSimulation6[] = { 0xCC, 0x31, 0xFF };
697 addResponseData(responseDataOfSimulation6, sizeof(responseDataOfSimulation6), true);
698 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
699 rcdeviceReceive(millis() * 1000);
700 testData.millis += minTimeout;
701 EXPECT_EQ(false, isButtonPressed);
702 clearResponseBuff();
704 // remove all request from queue
705 for (int i = 0; i < 300; i++) {
706 testData.millis += 500000;
707 rcdeviceReceive(millis());
711 TEST(RCDeviceTest, Test5KeyOSDCableSimulationWithout5KeyFeatureSupport)
713 resetRCDeviceStatus();
715 // test simulation without device init
716 rcData[THROTTLE] = FIVE_KEY_JOYSTICK_MID; // THROTTLE Mid
717 rcData[ROLL] = FIVE_KEY_JOYSTICK_MID; // ROLL Mid
718 rcData[PITCH] = FIVE_KEY_JOYSTICK_MID; // PITCH Mid
719 rcData[YAW] = FIVE_KEY_JOYSTICK_MAX; // Yaw High
720 rcdeviceUpdate(millis() * 1000);
721 EXPECT_EQ(false, rcdeviceInMenu);
722 // remove all request from queue
723 for (int i = 0; i < 10; i++) {
724 testData.millis += 500000;
725 rcdeviceReceive(millis());
728 // init device that have not 5 key OSD cable simulation feature
729 memset(&testData, 0, sizeof(testData));
730 testData.isRunCamSplitOpenPortSupported = true;
731 testData.isRunCamSplitPortConfigurated = true;
732 testData.isAllowBufferReadWrite = true;
733 testData.maxTimesOfRespDataAvailable = 0;
734 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
736 rcdeviceInit();
737 testData.millis += 3001;
738 rcdeviceReceive(millis() * 1000);
739 testData.millis += 200;
740 testData.responseDataReadPos = 0;
741 testData.indexOfCurrentRespBuf = 0;
742 addResponseData(responseData, sizeof(responseData), true);
743 rcdeviceReceive(millis() * 1000);
744 testData.millis += 200;
745 EXPECT_EQ(camDevice->isReady, true);
746 clearResponseBuff();
748 // open connection, rcdeviceInMenu will be false if the codes is right
749 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
750 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), false);
751 rcdeviceUpdate(millis() * 1000);
752 EXPECT_EQ(false, rcdeviceInMenu);
753 clearResponseBuff();
755 // remove all request from queue
756 for (int i = 0; i < 10; i++) {
757 testData.millis += 500000;
758 rcdeviceReceive(millis());
762 extern "C" {
763 serialPort_t *openSerialPort(serialPortIdentifier_e identifier, serialPortFunction_e functionMask, serialReceiveCallbackPtr callback, void *callbackData, uint32_t baudRate, portMode_e mode, portOptions_e options)
765 UNUSED(identifier);
766 UNUSED(functionMask);
767 UNUSED(baudRate);
768 UNUSED(mode);
769 UNUSED(options);
771 if (testData.isRunCamSplitOpenPortSupported) {
772 static serialPort_t s;
773 s.vTable = NULL;
775 // common serial initialisation code should move to serialPort::init()
776 s.rxBufferHead = s.rxBufferTail = 0;
777 s.txBufferHead = s.txBufferTail = 0;
778 s.rxBufferSize = 0;
779 s.txBufferSize = 0;
780 s.rxBuffer = s.rxBuffer;
781 s.txBuffer = s.txBuffer;
783 // callback works for IRQ-based RX ONLY
784 s.rxCallback = callback;
785 s.rxCallbackData = callbackData;
786 s.baudRate = 0;
788 return (serialPort_t *)&s;
791 return NULL;
794 serialPortConfig_t *findSerialPortConfig(serialPortFunction_e function)
796 UNUSED(function);
797 if (testData.isRunCamSplitPortConfigurated) {
798 static serialPortConfig_t portConfig;
800 portConfig.identifier = SERIAL_PORT_USART3;
801 portConfig.msp_baudrateIndex = BAUD_115200;
802 portConfig.gps_baudrateIndex = BAUD_57600;
803 portConfig.telemetry_baudrateIndex = BAUD_AUTO;
804 portConfig.blackbox_baudrateIndex = BAUD_115200;
805 portConfig.functionMask = FUNCTION_MSP;
807 return &portConfig;
810 return NULL;
813 uint32_t serialRxBytesWaiting(const serialPort_t *instance)
815 UNUSED(instance);
817 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
818 uint8_t leftDataLen = 0;
819 if (testData.responseDataReadPos + 1 > testData.responseBufsLen[bufIndex]) {
820 return 0;
821 } else {
822 leftDataLen = testData.responseBufsLen[bufIndex] - (testData.responseDataReadPos);
825 if (leftDataLen) {
826 return leftDataLen;
829 return 0;
832 uint8_t serialRead(serialPort_t *instance)
834 UNUSED(instance);
836 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
837 uint8_t *buffer = NULL;
838 uint8_t leftDataLen = 0;
839 if (testData.responseDataReadPos >= testData.responseBufsLen[bufIndex]) {
840 leftDataLen = 0;
841 } else {
842 buffer = testData.responesBufs[bufIndex];
843 leftDataLen = testData.responseBufsLen[bufIndex] - testData.responseDataReadPos;
846 if (leftDataLen) {
847 return buffer[testData.responseDataReadPos++];
850 return 0;
853 void sbufWriteString(sbuf_t *dst, const char *string)
855 UNUSED(dst); UNUSED(string);
857 if (testData.isAllowBufferReadWrite) {
858 sbufWriteData(dst, string, strlen(string));
861 void sbufWriteU8(sbuf_t *dst, uint8_t val)
863 UNUSED(dst); UNUSED(val);
865 if (testData.isAllowBufferReadWrite) {
866 *dst->ptr++ = val;
870 void sbufWriteData(sbuf_t *dst, const void *data, int len)
872 UNUSED(dst); UNUSED(data); UNUSED(len);
874 if (testData.isAllowBufferReadWrite) {
875 memcpy(dst->ptr, data, len);
876 dst->ptr += len;
881 // modifies streambuf so that written data are prepared for reading
882 void sbufSwitchToReader(sbuf_t *buf, uint8_t *base)
884 UNUSED(buf); UNUSED(base);
886 if (testData.isAllowBufferReadWrite) {
887 buf->end = buf->ptr;
888 buf->ptr = base;
892 uint8_t sbufReadU8(sbuf_t *src)
894 if (testData.isAllowBufferReadWrite) {
895 return *src->ptr++;
898 return 0;
901 void sbufAdvance(sbuf_t *buf, int size)
903 if (testData.isAllowBufferReadWrite) {
904 buf->ptr += size;
908 int sbufBytesRemaining(sbuf_t *buf)
910 if (testData.isAllowBufferReadWrite) {
911 return buf->end - buf->ptr;
913 return 0;
916 const uint8_t* sbufConstPtr(const sbuf_t *buf)
918 return buf->ptr;
921 void sbufReadData(sbuf_t *src, void *data, int len)
923 if (testData.isAllowBufferReadWrite) {
924 memcpy(data, src->ptr, len);
928 uint16_t sbufReadU16(sbuf_t *src)
930 uint16_t ret;
931 ret = sbufReadU8(src);
932 ret |= sbufReadU8(src) << 8;
933 return ret;
936 void sbufWriteU16(sbuf_t *dst, uint16_t val)
938 sbufWriteU8(dst, val >> 0);
939 sbufWriteU8(dst, val >> 8);
942 void sbufWriteU16BigEndian(sbuf_t *dst, uint16_t val)
944 sbufWriteU8(dst, val >> 8);
945 sbufWriteU8(dst, (uint8_t)val);
948 bool featureIsEnabled(uint32_t) { return false; }
950 void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count)
952 UNUSED(instance); UNUSED(data); UNUSED(count);
954 // reset the input buffer
955 testData.responseDataReadPos = 0;
956 testData.indexOfCurrentRespBuf++;
957 if (testData.indexOfCurrentRespBuf >= testData.responseBufCount) {
958 testData.indexOfCurrentRespBuf = 0;
960 // testData.maxTimesOfRespDataAvailable = testData.responseDataLen + 1;
963 serialPortConfig_t *findNextSerialPortConfig(serialPortFunction_e function)
965 UNUSED(function);
967 return NULL;
970 void closeSerialPort(serialPort_t *serialPort)
972 UNUSED(serialPort);
975 uint8_t* sbufPtr(sbuf_t *buf)
977 return buf->ptr;
980 uint32_t sbufReadU32(sbuf_t *src)
982 uint32_t ret;
983 ret = sbufReadU8(src);
984 ret |= sbufReadU8(src) << 8;
985 ret |= sbufReadU8(src) << 16;
986 ret |= sbufReadU8(src) << 24;
987 return ret;
990 uint32_t millis(void) { return testData.millis++; }
991 uint32_t micros(void) { return millis() * 1000; }
992 void beeper(beeperMode_e mode) { UNUSED(mode); }
993 uint8_t armingFlags = 0;
994 bool cmsInMenu;
995 uint32_t resumeRefreshAt = 0;
996 int getArmingDisableFlags(void) {return 0;}