vtx: fix VTX_SETTINGS_POWER_COUNT and add dummy entries to saPowerNames
[inav.git] / src / test / unit / rcdevice_unittest.cc
blob7968233c9f5094c8bb189ecc9a2a89a24472834d
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 "drivers/serial.h"
35 #include "fc/rc_controls.h"
36 #include "fc/rc_modes.h"
40 #include "io/beeper.h"
41 #include "io/serial.h"
43 #include "scheduler/scheduler.h"
44 #include "io/rcdevice_cam.h"
45 #include "io/osd.h"
46 #include "io/rcdevice.h"
48 #include "config/parameter_group_ids.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 int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
57 int16_t rcCommand[4];
58 uint32_t stateFlags;
59 rcControlsConfig_t rcControlsConfig_System;
61 extern rcdeviceSwitchState_t switchStates[BOXCAMERA3 - BOXCAMERA1 + 1];
62 extern runcamDevice_t *camDevice;
63 extern bool isButtonPressed;
64 extern bool rcdeviceInMenu;
65 extern rcdeviceWaitingResponseQueue watingResponseQueue;
66 bool unitTestIsSwitchActivited(boxId_e boxId)
68 uint8_t adjustBoxID = boxId - BOXCAMERA1;
69 rcdeviceSwitchState_s switchState = switchStates[adjustBoxID];
70 return switchState.isActivated;
72 int16_t rxGetChannelValue(unsigned ch)
74 return rcData[ch];
77 uint32_t millis(void);
78 int minTimeout = 180;
80 void rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEvent_e key);
81 rcdeviceResponseParsingContext_t* rcdeviceRespCtxQueueShift(rcdeviceWaitingResponseQueue *queue);
83 const uint32_t baudRates[] = { 0, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 250000,
84 460800, 921600, 1000000, 1500000, 2000000, 2470000 }; // see baudRate_e
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 watingResponseQueue;
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(&watingResponseQueue)) {
120 static void resetRCDeviceStatus()
122 isButtonPressed = false;
123 rcdeviceInMenu = false;
124 clearResponseBuff();
127 static void addResponseData(uint8_t *data, uint8_t dataLen, bool withDataForFlushSerial)
129 UNUSED(withDataForFlushSerial);
130 memcpy(testData.responesBufs[testData.responseBufCount], data, dataLen);
131 testData.responseBufsLen[testData.responseBufCount] = dataLen;
132 testData.responseBufCount++;
135 TEST(RCDeviceTest, TestRCSplitInitWithoutPortConfigurated)
137 runcamDevice_t device;
139 resetRCDeviceStatus();
141 watingResponseQueue.headPos = 0;
142 watingResponseQueue.tailPos = 0;
143 watingResponseQueue.itemCount = 0;
144 memset(&testData, 0, sizeof(testData));
145 runcamDeviceInit(&device);
146 EXPECT_EQ(false, device.isReady);
149 TEST(RCDeviceTest, TestRCSplitInitWithoutOpenPortConfigurated)
151 runcamDevice_t device;
153 resetRCDeviceStatus();
155 watingResponseQueue.headPos = 0;
156 watingResponseQueue.tailPos = 0;
157 watingResponseQueue.itemCount = 0;
158 memset(&testData, 0, sizeof(testData));
159 testData.isRunCamSplitOpenPortSupported = false;
160 testData.isRunCamSplitPortConfigurated = true;
162 runcamDeviceInit(&device);
163 EXPECT_EQ(false, device.isReady);
166 TEST(RCDeviceTest, TestInitDevice)
168 runcamDevice_t device;
170 resetRCDeviceStatus();
172 // test correct response
173 watingResponseQueue.headPos = 0;
174 watingResponseQueue.tailPos = 0;
175 watingResponseQueue.itemCount = 0;
176 memset(&testData, 0, sizeof(testData));
177 testData.isRunCamSplitOpenPortSupported = true;
178 testData.isRunCamSplitPortConfigurated = true;
179 testData.isAllowBufferReadWrite = true;
180 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
181 addResponseData(responseData, sizeof(responseData), true);
183 runcamDeviceInit(&device);
184 rcdeviceReceive(millis() * 1000);
185 testData.millis += minTimeout;
186 testData.responseDataReadPos = 0;
187 testData.indexOfCurrentRespBuf = 0;
188 rcdeviceReceive(millis() * 1000);
189 testData.millis += minTimeout;
190 EXPECT_EQ(device.isReady, true);
193 TEST(RCDeviceTest, TestInitDeviceWithInvalidResponse)
195 runcamDevice_t device;
197 resetRCDeviceStatus();
199 // test correct response data with incorrect len
200 watingResponseQueue.headPos = 0;
201 watingResponseQueue.tailPos = 0;
202 watingResponseQueue.itemCount = 0;
203 memset(&testData, 0, sizeof(testData));
204 testData.isRunCamSplitOpenPortSupported = true;
205 testData.isRunCamSplitPortConfigurated = true;
206 testData.isAllowBufferReadWrite = true;
208 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD, 0x33 };
209 addResponseData(responseData, sizeof(responseData), true);
210 runcamDeviceInit(&device);
211 rcdeviceReceive(millis() * 1000);
212 testData.millis += minTimeout;
213 testData.responseDataReadPos = 0;
214 testData.indexOfCurrentRespBuf = 0;
215 rcdeviceReceive(millis() * 1000);
216 EXPECT_EQ(device.isReady, true);
217 clearResponseBuff();
218 testData.millis += minTimeout;
220 // invalid crc
221 uint8_t responseDataWithInvalidCRC[] = { 0xCC, 0x01, 0x37, 0x00, 0xBE };
222 addResponseData(responseDataWithInvalidCRC, sizeof(responseDataWithInvalidCRC), true);
223 runcamDeviceInit(&device);
224 rcdeviceReceive(millis() * 1000);
225 testData.millis += minTimeout;
226 testData.responseDataReadPos = 0;
227 testData.indexOfCurrentRespBuf = 0;
228 rcdeviceReceive(millis() * 1000);
229 EXPECT_EQ(device.isReady, false);
230 clearResponseBuff();
231 testData.millis += minTimeout;
233 // incomplete response data
234 uint8_t incompleteResponseData[] = { 0xCC, 0x01, 0x37 };
235 addResponseData(incompleteResponseData, sizeof(incompleteResponseData), true);
236 runcamDeviceInit(&device);
237 rcdeviceReceive(millis() * 1000);
238 testData.millis += minTimeout;
239 testData.responseDataReadPos = 0;
240 testData.indexOfCurrentRespBuf = 0;
241 rcdeviceReceive(millis() * 1000);
242 testData.millis += minTimeout;
243 EXPECT_EQ(device.isReady, false);
244 clearResponseBuff();
245 testData.millis += minTimeout;
247 // test timeout
248 memset(&testData, 0, sizeof(testData));
249 testData.isRunCamSplitOpenPortSupported = true;
250 testData.isRunCamSplitPortConfigurated = true;
251 testData.isAllowBufferReadWrite = true;
252 runcamDeviceInit(&device);
253 rcdeviceReceive(millis() * 1000);
254 testData.millis += minTimeout;
255 testData.responseDataReadPos = 0;
256 testData.indexOfCurrentRespBuf = 0;
257 rcdeviceReceive(millis() * 1000);
258 EXPECT_EQ(device.isReady, false);
259 clearResponseBuff();
260 testData.millis += minTimeout;
263 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceUnready)
265 resetRCDeviceStatus();
267 // test correct response
268 watingResponseQueue.headPos = 0;
269 watingResponseQueue.tailPos = 0;
270 watingResponseQueue.itemCount = 0;
271 memset(&testData, 0, sizeof(testData));
272 testData.isRunCamSplitOpenPortSupported = true;
273 testData.isRunCamSplitPortConfigurated = true;
274 testData.isAllowBufferReadWrite = true;
275 testData.maxTimesOfRespDataAvailable = 0;
276 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBC }; // wrong response
277 addResponseData(responseData, sizeof(responseData), true);
278 rcdeviceInit();
279 rcdeviceReceive(millis() * 1000);
280 testData.millis += minTimeout;
281 testData.responseDataReadPos = 0;
282 testData.indexOfCurrentRespBuf = 0;
283 rcdeviceReceive(millis() * 1000);
284 testData.millis += minTimeout;
285 EXPECT_EQ(camDevice->isReady, false);
287 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
288 for (uint8_t i = 0; i <= (BOXCAMERA3 - BOXCAMERA1); i++) {
289 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
292 // bind aux1 to wifi button with range [900,1600]
293 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
294 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
295 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
296 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
298 // bind aux2 to power button with range [1900, 2100]
299 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
300 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
301 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
302 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
304 // bind aux3 to change mode with range [1300, 1600]
305 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
306 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
307 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1300);
308 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
310 updateUsedModeActivationConditionFlags();
312 // make the binded mode inactive
313 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1800;
314 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
315 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 900;
317 updateUsedModeActivationConditionFlags();
318 updateActivatedModes();
320 // runn process loop
321 rcdeviceUpdate(0);
323 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
324 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA2));
325 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
328 TEST(RCDeviceTest, TestWifiModeChangeWithDeviceReady)
330 resetRCDeviceStatus();
332 // test correct response
333 memset(&testData, 0, sizeof(testData));
334 testData.isRunCamSplitOpenPortSupported = true;
335 testData.isRunCamSplitPortConfigurated = true;
336 testData.isAllowBufferReadWrite = true;
337 testData.maxTimesOfRespDataAvailable = 0;
338 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
339 addResponseData(responseData, sizeof(responseData), true);
340 camDevice->info.features = 15;
341 rcdeviceInit();
342 testData.millis += 3001;
343 rcdeviceReceive(millis() * 1000);
344 testData.millis += minTimeout;
345 testData.responseDataReadPos = 0;
346 testData.indexOfCurrentRespBuf = 0;
347 rcdeviceReceive(millis() * 1000);
348 testData.millis += minTimeout;
349 EXPECT_EQ(camDevice->isReady, true);
351 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
352 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
353 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
357 // bind aux1 to wifi button with range [900,1600]
358 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
359 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
360 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
361 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
363 // bind aux2 to power button with range [1900, 2100]
364 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
365 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
366 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
367 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
369 // bind aux3 to change mode with range [1300, 1600]
370 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
371 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
372 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
373 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
375 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
376 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
377 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
379 updateUsedModeActivationConditionFlags();
380 updateActivatedModes();
382 // runn process loop
383 int8_t randNum = rand() % 127 + 6;
384 testData.maxTimesOfRespDataAvailable = randNum;
385 rcdeviceUpdate((timeUs_t)0);
387 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
388 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
389 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
392 TEST(RCDeviceTest, TestWifiModeChangeCombine)
394 resetRCDeviceStatus();
396 memset(&testData, 0, sizeof(testData));
397 testData.isRunCamSplitOpenPortSupported = true;
398 testData.isRunCamSplitPortConfigurated = true;
399 testData.isAllowBufferReadWrite = true;
400 testData.maxTimesOfRespDataAvailable = 0;
401 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
402 addResponseData(responseData, sizeof(responseData), true);
403 rcdeviceInit();
404 rcdeviceReceive(millis() * 1000);
405 testData.millis += minTimeout;
406 testData.responseDataReadPos = 0;
407 testData.indexOfCurrentRespBuf = 0;
408 rcdeviceReceive(millis() * 1000);
409 testData.millis += minTimeout;
410 EXPECT_EQ(true, camDevice->isReady);
412 // bind aux1, aux2, aux3 channel to wifi button, power button and change mode
413 for (uint8_t i = 0; i <= BOXCAMERA3 - BOXCAMERA1; i++) {
414 memset(modeActivationConditionsMutable(i), 0, sizeof(modeActivationCondition_t));
418 // bind aux1 to wifi button with range [900,1600]
419 modeActivationConditionsMutable(0)->auxChannelIndex = 0;
420 modeActivationConditionsMutable(0)->modeId = BOXCAMERA1;
421 modeActivationConditionsMutable(0)->range.startStep = CHANNEL_VALUE_TO_STEP(CHANNEL_RANGE_MIN);
422 modeActivationConditionsMutable(0)->range.endStep = CHANNEL_VALUE_TO_STEP(1600);
424 // bind aux2 to power button with range [1900, 2100]
425 modeActivationConditionsMutable(1)->auxChannelIndex = 1;
426 modeActivationConditionsMutable(1)->modeId = BOXCAMERA2;
427 modeActivationConditionsMutable(1)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
428 modeActivationConditionsMutable(1)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
430 // bind aux3 to change mode with range [1300, 1600]
431 modeActivationConditionsMutable(2)->auxChannelIndex = 2;
432 modeActivationConditionsMutable(2)->modeId = BOXCAMERA3;
433 modeActivationConditionsMutable(2)->range.startStep = CHANNEL_VALUE_TO_STEP(1900);
434 modeActivationConditionsMutable(2)->range.endStep = CHANNEL_VALUE_TO_STEP(2100);
436 // // make the binded mode inactive
437 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
438 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2000;
439 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1700;
441 updateUsedModeActivationConditionFlags();
442 updateActivatedModes();
444 // runn process loop
445 int8_t randNum = rand() % 127 + 6;
446 testData.maxTimesOfRespDataAvailable = randNum;
447 rcdeviceUpdate((timeUs_t)0);
449 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA1));
450 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
451 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
454 // // make the binded mode inactive
455 rcData[modeActivationConditions(0)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1500;
456 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1300;
457 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1900;
458 updateActivatedModes();
459 rcdeviceUpdate((timeUs_t)0);
460 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA1));
461 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA2));
462 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA3));
465 rcData[modeActivationConditions(2)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 1899;
466 updateActivatedModes();
467 rcdeviceUpdate((timeUs_t)0);
468 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
470 rcData[modeActivationConditions(1)->auxChannelIndex + NON_AUX_CHANNEL_COUNT] = 2001;
471 updateActivatedModes();
472 rcdeviceUpdate((timeUs_t)0);
473 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA1));
474 EXPECT_EQ(true, unitTestIsSwitchActivited(BOXCAMERA2));
475 EXPECT_EQ(false, unitTestIsSwitchActivited(BOXCAMERA3));
478 TEST(RCDeviceTest, Test5KeyOSDCableSimulationProtocol)
480 resetRCDeviceStatus();
482 memset(&testData, 0, sizeof(testData));
483 testData.isRunCamSplitOpenPortSupported = true;
484 testData.isRunCamSplitPortConfigurated = true;
485 testData.isAllowBufferReadWrite = true;
486 testData.maxTimesOfRespDataAvailable = 0;
487 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
488 addResponseData(responseData, sizeof(responseData), true);
489 rcdeviceInit();
490 rcdeviceReceive(millis() * 1000);
491 testData.millis += minTimeout;
492 testData.responseDataReadPos = 0;
493 testData.indexOfCurrentRespBuf = 0;
494 rcdeviceReceive(millis() * 1000);
495 testData.millis += minTimeout;
496 EXPECT_EQ(true, camDevice->isReady);
497 clearResponseBuff();
499 // test timeout of open connection
500 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
501 rcdeviceReceive(millis() * 1000);
502 testData.millis += 3000;
503 rcdeviceReceive(millis() * 1000);
504 testData.millis += minTimeout;
505 EXPECT_EQ(false, rcdeviceInMenu);
506 clearResponseBuff();
508 // open connection with correct response
509 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
510 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
511 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
512 rcdeviceReceive(millis() * 1000);
513 testData.millis += minTimeout;
514 EXPECT_EQ(true, rcdeviceInMenu);
515 clearResponseBuff();
517 // open connection with correct response but wrong data length
518 uint8_t incorrectResponseDataOfOpenConnection1[] = { 0xCC, 0x11, 0xe7, 0x55 };
519 addResponseData(incorrectResponseDataOfOpenConnection1, sizeof(incorrectResponseDataOfOpenConnection1), true);
520 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
521 rcdeviceReceive(millis() * 1000);
522 testData.millis += minTimeout;
523 EXPECT_EQ(true, rcdeviceInMenu);
524 clearResponseBuff();
526 // open connection with invalid crc
527 uint8_t incorrectResponseDataOfOpenConnection2[] = { 0xCC, 0x10, 0x42 };
528 addResponseData(incorrectResponseDataOfOpenConnection2, sizeof(incorrectResponseDataOfOpenConnection2), true);
529 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN);
530 rcdeviceReceive(millis() * 1000);
531 testData.millis += minTimeout;
532 EXPECT_EQ(true, rcdeviceInMenu); // when crc wrong won't change the menu state
533 clearResponseBuff();
535 // test timeout of close connection
536 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
537 rcdeviceReceive(millis() * 1000);
538 testData.millis += 3000;
539 rcdeviceReceive(millis() * 1000);
540 testData.millis += minTimeout;
541 EXPECT_EQ(true, rcdeviceInMenu); // close menu timeout won't change the menu state
542 clearResponseBuff();
544 // close connection with correct response
545 uint8_t responseDataOfCloseConnection[] = { 0xCC, 0x21, 0x11 };
546 addResponseData(responseDataOfCloseConnection, sizeof(responseDataOfCloseConnection), true);
547 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
548 rcdeviceReceive(millis() * 1000);
549 testData.millis += minTimeout;
550 EXPECT_EQ(false, rcdeviceInMenu);
551 clearResponseBuff();
553 // close connection with correct response but wrong data length
554 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
555 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
556 rcdeviceReceive(millis() * 1000);
557 testData.millis += minTimeout;
558 EXPECT_EQ(true, rcdeviceInMenu);
559 clearResponseBuff();
561 uint8_t responseDataOfCloseConnection1[] = { 0xCC, 0x21, 0x11, 0xC1 };
562 addResponseData(responseDataOfCloseConnection1, sizeof(responseDataOfCloseConnection1), true);
563 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
564 rcdeviceReceive(millis() * 1000);
565 testData.millis += minTimeout;
566 EXPECT_EQ(false, rcdeviceInMenu);
567 clearResponseBuff();
569 // close connection with response that invalid crc
570 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), true);
571 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_OPEN); // open menu again
572 rcdeviceReceive(millis() * 1000);
573 testData.millis += minTimeout;
574 EXPECT_EQ(true, rcdeviceInMenu);
575 clearResponseBuff();
577 uint8_t responseDataOfCloseConnection2[] = { 0xCC, 0x21, 0xA1 };
578 addResponseData(responseDataOfCloseConnection2, sizeof(responseDataOfCloseConnection2), true);
579 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_CONNECTION_CLOSE);
580 rcdeviceReceive(millis() * 1000);
581 testData.millis += minTimeout;
582 EXPECT_EQ(true, rcdeviceInMenu);
583 clearResponseBuff();
585 // release button first
586 uint8_t responseDataOfSimulation4[] = { 0xCC, 0xA5 };
587 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
588 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
589 rcdeviceReceive(millis() * 1000);
590 testData.millis += minTimeout;
591 EXPECT_EQ(false, isButtonPressed);
592 clearResponseBuff();
594 // simulate press button with no response
595 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
596 testData.millis += 2000;
597 rcdeviceReceive(millis() * 1000);
598 testData.millis += minTimeout;
599 EXPECT_EQ(false, isButtonPressed);
600 clearResponseBuff();
602 // simulate press button with correct response
603 uint8_t responseDataOfSimulation1[] = { 0xCC, 0xA5 };
604 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true);
605 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
606 rcdeviceReceive(millis() * 1000);
607 testData.millis += minTimeout;
608 EXPECT_EQ(true, isButtonPressed);
609 clearResponseBuff();
611 // simulate press button with correct response but wrong data length
612 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true); // release first
613 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
614 rcdeviceReceive(millis() * 1000);
615 testData.millis += minTimeout;
616 EXPECT_EQ(false, isButtonPressed);
617 clearResponseBuff();
619 uint8_t responseDataOfSimulation2[] = { 0xCC, 0xA5, 0x22 };
620 addResponseData(responseDataOfSimulation2, sizeof(responseDataOfSimulation2), true);
621 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
622 rcdeviceReceive(millis() * 1000);
623 testData.millis += minTimeout;
624 EXPECT_EQ(true, isButtonPressed);
625 clearResponseBuff();
627 // simulate press button event with incorrect response
628 uint8_t responseDataOfSimulation3[] = { 0xCC, 0xB5, 0x22 };
629 addResponseData(responseDataOfSimulation3, sizeof(responseDataOfSimulation3), true);
630 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
631 rcdeviceReceive(millis() * 1000);
632 testData.millis += minTimeout;
633 EXPECT_EQ(true, isButtonPressed);
634 clearResponseBuff();
636 // simulate release button with correct response
637 addResponseData(responseDataOfSimulation4, sizeof(responseDataOfSimulation4), true);
638 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
639 rcdeviceReceive(millis() * 1000);
640 testData.millis += minTimeout;
641 EXPECT_EQ(false, isButtonPressed);
642 clearResponseBuff();
644 // simulate release button with correct response but wrong data length
645 addResponseData(responseDataOfSimulation1, sizeof(responseDataOfSimulation1), true); // press first
646 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_ENTER);
647 rcdeviceReceive(millis() * 1000);
648 testData.millis += minTimeout;
649 EXPECT_EQ(true, isButtonPressed);
650 clearResponseBuff();
652 uint8_t responseDataOfSimulation5[] = { 0xCC, 0xA5, 0xFF };
653 addResponseData(responseDataOfSimulation5, sizeof(responseDataOfSimulation5), true);
654 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
655 rcdeviceReceive(millis() * 1000);
656 testData.millis += minTimeout;
657 EXPECT_EQ(false, isButtonPressed);
658 clearResponseBuff();
660 // simulate release button with incorrect response
661 uint8_t responseDataOfSimulation6[] = { 0xCC, 0x31, 0xFF };
662 addResponseData(responseDataOfSimulation6, sizeof(responseDataOfSimulation6), true);
663 rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
664 rcdeviceReceive(millis() * 1000);
665 testData.millis += minTimeout;
666 EXPECT_EQ(false, isButtonPressed);
667 clearResponseBuff();
670 TEST(RCDeviceTest, Test5KeyOSDCableSimulationWithout5KeyFeatureSupport)
672 resetRCDeviceStatus();
674 // test simulation without device init
675 rcData[THROTTLE] = FIVE_KEY_JOYSTICK_MID; // THROTTLE Mid
676 rcData[ROLL] = FIVE_KEY_JOYSTICK_MID; // ROLL Mid
677 rcData[PITCH] = FIVE_KEY_JOYSTICK_MID; // PITCH Mid
678 rcData[YAW] = FIVE_KEY_JOYSTICK_MAX; // Yaw High
679 rcdeviceUpdate(millis() * 1000);
680 EXPECT_EQ(false, rcdeviceInMenu);
681 // remove all request from queue
682 for (int i = 0; i < 10; i++) {
683 testData.millis += 500000;
684 rcdeviceReceive(millis());
687 // init device that have not 5 key OSD cable simulation feature
688 memset(&testData, 0, sizeof(testData));
689 testData.isRunCamSplitOpenPortSupported = true;
690 testData.isRunCamSplitPortConfigurated = true;
691 testData.isAllowBufferReadWrite = true;
692 testData.maxTimesOfRespDataAvailable = 0;
693 uint8_t responseData[] = { 0xCC, 0x01, 0x37, 0x00, 0xBD };
694 rcdeviceInit();
695 testData.millis += 3001;
696 rcdeviceReceive(millis() * 1000);
697 testData.millis += 200;
698 testData.responseDataReadPos = 0;
699 testData.indexOfCurrentRespBuf = 0;
700 addResponseData(responseData, sizeof(responseData), true);
701 rcdeviceReceive(millis() * 1000);
702 testData.millis += 200;
703 EXPECT_EQ(camDevice->isReady, true);
704 clearResponseBuff();
706 // open connection, rcdeviceInMenu will be false if the codes is right
707 uint8_t responseDataOfOpenConnection[] = { 0xCC, 0x11, 0xe7 };
708 addResponseData(responseDataOfOpenConnection, sizeof(responseDataOfOpenConnection), false);
709 rcdeviceUpdate(millis() * 1000);
710 EXPECT_EQ(false, rcdeviceInMenu);
711 clearResponseBuff();
714 extern "C" {
715 serialPort_t *openSerialPort(serialPortIdentifier_e identifier, serialPortFunction_e functionMask, serialReceiveCallbackPtr callback, void *callbackData, uint32_t baudRate, portMode_t mode, portOptions_t options)
717 UNUSED(identifier);
718 UNUSED(functionMask);
719 UNUSED(baudRate);
720 UNUSED(mode);
721 UNUSED(options);
723 if (testData.isRunCamSplitOpenPortSupported) {
724 static serialPort_t s;
725 s.vTable = NULL;
727 // common serial initialisation code should move to serialPort::init()
728 s.rxBufferHead = s.rxBufferTail = 0;
729 s.txBufferHead = s.txBufferTail = 0;
730 s.rxBufferSize = 0;
731 s.txBufferSize = 0;
732 s.rxBuffer = s.rxBuffer;
733 s.txBuffer = s.txBuffer;
735 // callback works for IRQ-based RX ONLY
736 s.rxCallback = callback;
737 s.rxCallbackData = callbackData;
738 s.baudRate = 0;
740 return (serialPort_t *)&s;
743 return NULL;
746 serialPortConfig_t *findSerialPortConfig(serialPortFunction_e function)
748 UNUSED(function);
749 if (testData.isRunCamSplitPortConfigurated) {
750 static serialPortConfig_t portConfig;
752 portConfig.identifier = SERIAL_PORT_USART3;
753 portConfig.msp_baudrateIndex = BAUD_115200;
754 portConfig.gps_baudrateIndex = BAUD_57600;
755 portConfig.telemetry_baudrateIndex = BAUD_AUTO;
756 portConfig.peripheral_baudrateIndex = BAUD_115200;
757 portConfig.functionMask = FUNCTION_MSP;
759 return &portConfig;
762 return NULL;
765 uint32_t serialRxBytesWaiting(const serialPort_t *instance)
767 UNUSED(instance);
769 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
770 uint8_t leftDataLen = 0;
771 if (testData.responseDataReadPos + 1 > testData.responseBufsLen[bufIndex]) {
772 return 0;
773 } else {
774 leftDataLen = testData.responseBufsLen[bufIndex] - (testData.responseDataReadPos);
777 if (leftDataLen) {
778 return leftDataLen;
781 return 0;
784 uint8_t serialRead(serialPort_t *instance)
786 UNUSED(instance);
788 uint8_t bufIndex = testData.indexOfCurrentRespBuf;
789 uint8_t *buffer = NULL;
790 uint8_t leftDataLen = 0;
791 if (testData.responseDataReadPos >= testData.responseBufsLen[bufIndex]) {
792 leftDataLen = 0;
793 } else {
794 buffer = testData.responesBufs[bufIndex];
795 leftDataLen = testData.responseBufsLen[bufIndex] - testData.responseDataReadPos;
798 if (leftDataLen) {
799 return buffer[testData.responseDataReadPos++];
802 return 0;
805 void sbufWriteString(sbuf_t *dst, const char *string)
807 UNUSED(dst);
808 UNUSED(string);
810 if (testData.isAllowBufferReadWrite) {
811 sbufWriteData(dst, string, strlen(string));
814 void sbufWriteU8(sbuf_t *dst, uint8_t val)
816 UNUSED(dst);
817 UNUSED(val);
819 if (testData.isAllowBufferReadWrite) {
820 *dst->ptr++ = val;
824 void sbufWriteData(sbuf_t *dst, const void *data, int len)
826 UNUSED(dst);
827 UNUSED(data);
828 UNUSED(len);
830 if (testData.isAllowBufferReadWrite) {
831 memcpy(dst->ptr, data, len);
832 dst->ptr += len;
836 // modifies streambuf so that written data are prepared for reading
837 void sbufSwitchToReader(sbuf_t *buf, uint8_t *base)
839 UNUSED(buf);
840 UNUSED(base);
842 if (testData.isAllowBufferReadWrite) {
843 buf->end = buf->ptr;
844 buf->ptr = base;
848 uint8_t sbufReadU8(sbuf_t *src)
850 if (testData.isAllowBufferReadWrite) {
851 return *src->ptr++;
854 return 0;
857 void sbufAdvance(sbuf_t *buf, int size)
859 if (testData.isAllowBufferReadWrite) {
860 buf->ptr += size;
864 int sbufBytesRemaining(const sbuf_t *buf)
866 if (testData.isAllowBufferReadWrite) {
867 return buf->end - buf->ptr;
869 return 0;
872 const uint8_t* sbufConstPtr(const sbuf_t *buf)
874 return buf->ptr;
877 void sbufReadData(const sbuf_t *dst, void *data, int len)
879 UNUSED(dst);
880 if (testData.isAllowBufferReadWrite) {
881 memcpy(data, data, len);
885 uint16_t sbufReadU16(sbuf_t *src)
887 uint16_t ret;
888 ret = sbufReadU8(src);
889 ret |= sbufReadU8(src) << 8;
890 return ret;
893 void sbufWriteU16(sbuf_t *dst, uint16_t val)
895 sbufWriteU8(dst, val >> 0);
896 sbufWriteU8(dst, val >> 8);
899 void sbufWriteU16BigEndian(sbuf_t *dst, uint16_t val)
901 sbufWriteU8(dst, val >> 8);
902 sbufWriteU8(dst, (uint8_t)val);
905 bool feature(uint32_t) { return false; }
907 void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count)
909 UNUSED(instance);
910 UNUSED(data);
911 UNUSED(count);
913 // reset the input buffer
914 testData.responseDataReadPos = 0;
915 testData.indexOfCurrentRespBuf++;
916 if (testData.indexOfCurrentRespBuf >= testData.responseBufCount) {
917 testData.indexOfCurrentRespBuf = 0;
919 // testData.maxTimesOfRespDataAvailable = testData.responseDataLen + 1;
922 serialPortConfig_t *findNextSerialPortConfig(serialPortFunction_e function)
924 UNUSED(function);
926 return NULL;
929 void closeSerialPort(serialPort_t *serialPort)
931 UNUSED(serialPort);
934 uint8_t* sbufPtr(sbuf_t *buf)
936 return buf->ptr;
939 uint32_t sbufReadU32(sbuf_t *src)
941 uint32_t ret;
942 ret = sbufReadU8(src);
943 ret |= sbufReadU8(src) << 8;
944 ret |= sbufReadU8(src) << 16;
945 ret |= sbufReadU8(src) << 24;
946 return ret;
949 uint32_t millis(void) { return testData.millis++; }
950 uint32_t micros(void) { return millis() * 1000; }
951 void beeper(beeperMode_e mode) { UNUSED(mode); }
952 uint8_t armingFlags = 0;
953 bool cmsInMenu;
954 uint32_t resumeRefreshAt = 0;
955 int getArmingDisableFlags(void) {return 0;}