Cut off power supply.

This commit is contained in:
Fancy code 2024-02-08 04:18:47 -08:00
parent f56defee42
commit 92a62a1db6
15 changed files with 303 additions and 75 deletions

View File

@ -22,6 +22,7 @@ enum class McuAskBlock
{ {
BLOCK = 0, BLOCK = 0,
NOT_BLOCK, NOT_BLOCK,
UNRELATED,
END END
}; };
enum class McuAskReply enum class McuAskReply
@ -42,7 +43,7 @@ public:
void ReplyFinished(const bool result) override; void ReplyFinished(const bool result) override;
bool IfTimeout(const unsigned int &integrationTimeMs) override; bool IfTimeout(const unsigned int &integrationTimeMs) override;
private: protected:
sem_t mSem; sem_t mSem;
McuAskBlock mIsBlock; McuAskBlock mIsBlock;
McuAskReply mNeedReply; McuAskReply mNeedReply;

View File

@ -76,7 +76,11 @@ public:
{ {
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
} }
virtual const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> ask) virtual const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> &ask)
{
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
}
virtual const StatusCode CutOffPowerSupply(std::shared_ptr<VMcuAsk> &ask)
{ {
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
} }

View File

@ -70,7 +70,7 @@ const StatusCode McuDevice::UnInit(void)
IUartDeviceFree(mUartDevice); IUartDeviceFree(mUartDevice);
} }
mUartDevice = nullptr; mUartDevice = nullptr;
mAllAsk.clear(); DeleteAllAsk();
return CreateStatusCode(STATUS_CODE_OK); return CreateStatusCode(STATUS_CODE_OK);
} }
size_t McuDevice::WriteData(const void *buff, const size_t buffLength, std::shared_ptr<VProtocolContext> &context, size_t McuDevice::WriteData(const void *buff, const size_t buffLength, std::shared_ptr<VProtocolContext> &context,
@ -89,10 +89,7 @@ size_t McuDevice::WriteData(const void *buff, const size_t buffLength, std::shar
size_t length = IUartSend(mUartDevice, buff, buffLength); size_t length = IUartSend(mUartDevice, buff, buffLength);
mMutex.unlock(); mMutex.unlock();
if (ask->NeedReply() == true) { if (ask->NeedReply() == true) {
ASK_RESULT result = ask->Blocking(); ask->Blocking();
if (ASK_RESULT::SUCCEED == result) {
DeleteMcuAsk(ask);
}
} }
return length; return length;
} }
@ -109,6 +106,7 @@ void McuDevice::GetIpcMissionReply(const unsigned int &serialNumber, const unsig
else { else {
ask->ReplyFinished(false); ask->ReplyFinished(false);
} }
DeleteMcuAsk(ask);
} }
} }
void McuDevice::DeviceRecvThread(void) void McuDevice::DeviceRecvThread(void)
@ -208,12 +206,22 @@ void McuDevice::DeleteMcuAsk(std::shared_ptr<VMcuAsk> &ask)
std::lock_guard<std::mutex> locker(mMutex); std::lock_guard<std::mutex> locker(mMutex);
auto searchMcuAsk = [&ask](std::shared_ptr<VMcuAsk> &askList) -> bool { auto searchMcuAsk = [&ask](std::shared_ptr<VMcuAsk> &askList) -> bool {
if (ask->mSerialNumber == askList->mSerialNumber) { if (ask->mSerialNumber == askList->mSerialNumber) {
// LogInfo("DeleteMcuAsk mSerialNumber = %d\n", askList->mSerialNumber);
return REMOVE_THE_ASK; return REMOVE_THE_ASK;
} }
return KEEP_THE_ASK; return KEEP_THE_ASK;
}; };
mAllAsk.remove_if(searchMcuAsk); mAllAsk.remove_if(searchMcuAsk);
} }
void McuDevice::DeleteAllAsk(void)
{
std::lock_guard<std::mutex> locker(mMutex);
auto deleteAllAsk = [](std::shared_ptr<VMcuAsk> &askList) -> bool {
askList->ReplyFinished(false);
return REMOVE_THE_ASK;
};
mAllAsk.remove_if(deleteAllAsk);
}
void McuDevice::TraverseCheckAllAsk(void) void McuDevice::TraverseCheckAllAsk(void)
{ {
std::lock_guard<std::mutex> locker(mMutex); std::lock_guard<std::mutex> locker(mMutex);

View File

@ -44,6 +44,7 @@ private:
void AddMcuAsk(std::shared_ptr<VMcuAsk> &ask); void AddMcuAsk(std::shared_ptr<VMcuAsk> &ask);
void SearchMcuAsk(const unsigned int &serialNumber, std::shared_ptr<VMcuAsk> &ask); void SearchMcuAsk(const unsigned int &serialNumber, std::shared_ptr<VMcuAsk> &ask);
void DeleteMcuAsk(std::shared_ptr<VMcuAsk> &ask); void DeleteMcuAsk(std::shared_ptr<VMcuAsk> &ask);
void DeleteAllAsk(void);
void TraverseCheckAllAsk(void); void TraverseCheckAllAsk(void);
private: private:

View File

@ -26,10 +26,15 @@ const StatusCode McuManagerImpl::UnInit(void)
McuProtocol::UnInit(); McuProtocol::UnInit();
return CreateStatusCode(STATUS_CODE_OK); return CreateStatusCode(STATUS_CODE_OK);
} }
const StatusCode McuManagerImpl::GetIpcMission(std::shared_ptr<VMcuAsk> ask) const StatusCode McuManagerImpl::GetIpcMission(std::shared_ptr<VMcuAsk> &ask)
{ {
std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask); std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask);
McuProtocol::GetIpcMission(context); McuProtocol::GetIpcMission(context);
// IpcMission mission = static_cast<IpcMission>(data); return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuManagerImpl::CutOffPowerSupply(std::shared_ptr<VMcuAsk> &ask)
{
std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask);
McuProtocol::CutOffPowerSupply(context);
return CreateStatusCode(STATUS_CODE_OK); return CreateStatusCode(STATUS_CODE_OK);
} }

View File

@ -25,6 +25,7 @@ public:
std::shared_ptr<VProtocolBase> SharedFromThis(void) override; std::shared_ptr<VProtocolBase> SharedFromThis(void) override;
const StatusCode Init(void) override; const StatusCode Init(void) override;
const StatusCode UnInit(void) override; const StatusCode UnInit(void) override;
const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> ask) override; const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> &ask) override;
const StatusCode CutOffPowerSupply(std::shared_ptr<VMcuAsk> &ask) override;
}; };
#endif #endif

View File

@ -83,6 +83,6 @@ public:
MOCK_METHOD1(IfTimeoutTrace, void(const unsigned int &)); MOCK_METHOD1(IfTimeoutTrace, void(const unsigned int &));
public: public:
static void McuAskDefaultFeatures(std::shared_ptr<McuAskBaseTestTool> &mock); void McuAskDefaultFeatures(std::shared_ptr<McuAskBaseTestTool> &mock);
}; };
#endif #endif

View File

@ -36,8 +36,23 @@ bool McuAskBaseTest::IfTimeout(const unsigned int &integrationTimeMs)
void McuAskBaseTestTool::McuAskDefaultFeatures(std::shared_ptr<McuAskBaseTestTool> &mock) void McuAskBaseTestTool::McuAskDefaultFeatures(std::shared_ptr<McuAskBaseTestTool> &mock)
{ {
constexpr int CALL_ONLY_ONCE = 1; constexpr int CALL_ONLY_ONCE = 1;
EXPECT_CALL(*mock.get(), BlockingTrace()).Times(CALL_ONLY_ONCE); constexpr int SHOULD_NOT_CALL = 0;
EXPECT_CALL(*mock.get(), NeedReplyTrace()).Times(AtLeast(1)); if (McuAskBlock::BLOCK == mIsBlock && McuAskReply::NEED_REPLY == mNeedReply) {
EXPECT_CALL(*mock.get(), ReplyFinishedTrace(_)).Times(CALL_ONLY_ONCE); EXPECT_CALL(*mock.get(), BlockingTrace()).Times(CALL_ONLY_ONCE);
EXPECT_CALL(*mock.get(), IfTimeoutTrace(_)).Times(AnyNumber()); EXPECT_CALL(*mock.get(), NeedReplyTrace()).Times(AtLeast(1));
EXPECT_CALL(*mock.get(), ReplyFinishedTrace(_)).Times(CALL_ONLY_ONCE);
EXPECT_CALL(*mock.get(), IfTimeoutTrace(_)).Times(AnyNumber());
}
if (McuAskBlock::NOT_BLOCK == mIsBlock && McuAskReply::NEED_REPLY == mNeedReply) {
EXPECT_CALL(*mock.get(), BlockingTrace()).Times(CALL_ONLY_ONCE);
EXPECT_CALL(*mock.get(), NeedReplyTrace()).Times(AtLeast(1));
EXPECT_CALL(*mock.get(), ReplyFinishedTrace(_)).Times(CALL_ONLY_ONCE);
EXPECT_CALL(*mock.get(), IfTimeoutTrace(_)).Times(AnyNumber());
}
if (McuAskBlock::UNRELATED == mIsBlock && McuAskReply::NEED_NOT_REPLY == mNeedReply) {
EXPECT_CALL(*mock.get(), BlockingTrace()).Times(SHOULD_NOT_CALL);
EXPECT_CALL(*mock.get(), NeedReplyTrace()).Times(AtLeast(1));
EXPECT_CALL(*mock.get(), ReplyFinishedTrace(_)).Times(SHOULD_NOT_CALL);
EXPECT_CALL(*mock.get(), IfTimeoutTrace(_)).Times(SHOULD_NOT_CALL);
}
} }

View File

@ -42,8 +42,104 @@ public:
std::shared_ptr<LinuxTest> mLinuxTest; std::shared_ptr<LinuxTest> mLinuxTest;
}; };
// ../output_files/test/bin/McuManagerTest // ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_EXAMPLE_GetIpcMissiony // --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_EXAMPLE_GetIpcMission
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_GetIpcMissiony) /**
* @brief Construct a new test f object
* This test is an example that demonstrates how to obtain IpcMission data and add the business code after obtaining the
* data in the abstract interface.
*/
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_GetIpcMission)
{
/**
* @brief The user needs to derive a subclass of McuAskBase and add the business code after obtaining data in the
* abstract interface.
*/
class McuAskTest : public McuAsk<IpcMission>, public McuAskBase
{
public:
McuAskTest() : McuAskBase(McuAskBlock::BLOCK, McuAskReply::NEED_REPLY) {} // using McuAskBlock::BLOCK
virtual ~McuAskTest() = default;
void ReplyFinished(const bool result) override
{
McuAskBase::ReplyFinished(result);
if (result) {
LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast<int>(mDataReply));
// Do something here.
}
else {
LogError("Ask data falied.\n");
}
}
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
LogInfo("GetIpcMission will block here.\n");
IMcuManager::GetInstance()->GetIpcMission(ask);
LogInfo("GetIpcMission finished.\n");
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
IMcuManager::GetInstance()->UnInit();
}
// ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_EXAMPLE_GetIpcMission2
/**
* @brief Construct a new test f object
* This test is an example that demonstrates how to obtain IpcMission data and add the business code after obtaining the
* data in the abstract interface.
*/
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_GetIpcMission2)
{
/**
* @brief The user needs to derive a subclass of McuAskBase and add the business code after obtaining data in the
* abstract interface.
*/
class McuAskTest : public McuAsk<IpcMission>, public McuAskBase
{
public:
McuAskTest() : McuAskBase(McuAskBlock::NOT_BLOCK, McuAskReply::NEED_REPLY) {} // using McuAskBlock::NOT_BLOCK
virtual ~McuAskTest() = default;
void ReplyFinished(const bool result) override
{
McuAskBase::ReplyFinished(result);
if (result) {
LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast<int>(mDataReply));
// Do something here.
}
else {
LogError("Ask data falied.\n");
}
}
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
LogInfo("GetIpcMission will not block here.\n");
IMcuManager::GetInstance()->GetIpcMission(ask);
LogInfo("GetIpcMission finished.\n");
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
IMcuManager::GetInstance()->UnInit();
}
// ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_EXAMPLE_CutOffPowerSupply
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_CutOffPowerSupply)
{
class McuAskTest : public McuAskBase
{
public:
McuAskTest()
: McuAskBase(McuAskBlock::UNRELATED, McuAskReply::NEED_NOT_REPLY) {} // using McuAskReply::NEED_NOT_REPLY
virtual ~McuAskTest() = default;
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
StatusCode code = IMcuManager::GetInstance()->CutOffPowerSupply(ask);
if (IsCodeOK(code) == true) {
LogInfo("Write data to mcu succeed.\n");
}
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
IMcuManager::GetInstance()->UnInit();
}
// ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_GetIpcMission
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_GetIpcMission)
{ {
class McuAskTest : public McuAsk<IpcMission>, public McuAskBaseTestTool class McuAskTest : public McuAsk<IpcMission>, public McuAskBaseTestTool
{ {
@ -65,8 +161,65 @@ TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_GetIpcMissiony)
IMcuManager::GetInstance()->Init(); IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>(); std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(ask); std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(ask);
McuAskBaseTestTool::McuAskDefaultFeatures(testTool); testTool->McuAskDefaultFeatures(testTool);
IMcuManager::GetInstance()->GetIpcMission(ask); IMcuManager::GetInstance()->GetIpcMission(ask);
constexpr int NO_USER_USING_AFTER_ASK = 2; // ask and testTool
EXPECT_EQ(ask.use_count(), NO_USER_USING_AFTER_ASK);
IMcuManager::GetInstance()->UnInit();
}
// ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_GetIpcMission
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_GetIpcMission2)
{
class McuAskTest : public McuAsk<IpcMission>, public McuAskBaseTestTool
{
public:
McuAskTest() : McuAskBaseTestTool(McuAskBlock::NOT_BLOCK, McuAskReply::NEED_REPLY) {}
virtual ~McuAskTest() = default;
void ReplyFinished(const bool result) override
{
McuAskBaseTestTool::ReplyFinished(result);
if (result) {
LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast<int>(mDataReply));
// Do something here.
}
else {
LogError("Ask data falied.\n");
}
}
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(ask);
testTool->McuAskDefaultFeatures(testTool);
IMcuManager::GetInstance()->GetIpcMission(ask);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
constexpr int NO_USER_USING_AFTER_ASK = 2; // ask and testTool
EXPECT_EQ(ask.use_count(), NO_USER_USING_AFTER_ASK);
IMcuManager::GetInstance()->UnInit();
}
// ../output_files/test/bin/McuManagerTest
// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_CutOffPowerSupply
TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_CutOffPowerSupply)
{
class McuAskTest : public McuAskBaseTestTool
{
public:
McuAskTest()
: McuAskBaseTestTool(McuAskBlock::UNRELATED,
McuAskReply::NEED_NOT_REPLY) // using McuAskReply::NEED_NOT_REPLY
{
}
virtual ~McuAskTest() = default;
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(ask);
testTool->McuAskDefaultFeatures(testTool);
StatusCode code = IMcuManager::GetInstance()->CutOffPowerSupply(ask);
constexpr int NO_USER_USING_AFTER_ASK = 2; // ask and testTool
EXPECT_EQ(ask.use_count(), NO_USER_USING_AFTER_ASK);
EXPECT_EQ(code.mStatusCode, STATUS_CODE_OK); // STATUS_CODE_OK means write data to mcu succeed.
std::this_thread::sleep_for(std::chrono::milliseconds(2000)); std::this_thread::sleep_for(std::chrono::milliseconds(2000));
IMcuManager::GetInstance()->UnInit(); IMcuManager::GetInstance()->UnInit();
} }

View File

@ -19,10 +19,30 @@
#include <string.h> #include <string.h>
#include <thread> #include <thread>
constexpr size_t PROTOCOL_DATA_KEY_HEAD_LENGTH = 10; constexpr size_t PROTOCOL_DATA_KEY_HEAD_LENGTH = 10;
const unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88};
const unsigned char REPLY_IPC_MISSION[] = {
0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89};
const unsigned char ASK_CUT_OFF_POWER_SUPPLY[] = {
0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x02, 0x00, 0x0C, 0x81, 0x88};
void McuProtocolTestTool::Init(std::shared_ptr<LinuxTest> &mock, const UartInfo &uart) void McuProtocolTestTool::Init(std::shared_ptr<LinuxTest> &mock, const UartInfo &uart)
{ {
int uartFd = GetDeviceMockFd(uart); int uartFd = GetDeviceMockFd(uart);
IpcMissionProtocolInit(mock, uartFd); // IpcMissionProtocolInit(mock, uartFd);
static size_t WRITE_COUNT = -1;
auto api_write = [=, &mock](int fd, const void *buf, size_t count) {
McuProtocolTestTool::PrintHexadecimalData(buf, count, WRITE_PRINT);
if (sizeof(ASK_IPC_MISSION) == count && memcmp(ASK_IPC_MISSION, buf, count) == 0) {
LogInfo("Set REPLY_IPC_MISSION\n");
IpcMissionProtocolInit(mock, uartFd);
}
if (sizeof(ASK_CUT_OFF_POWER_SUPPLY) == count && memcmp(ASK_CUT_OFF_POWER_SUPPLY, buf, count) == 0) {
LogInfo("Set ASK_CUT_OFF_POWER_SUPPLY\n");
// IpcMissionProtocolInit(mock, uartFd);
}
};
EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _))
.WillRepeatedly(
DoAll(SaveArg<2>(&WRITE_COUNT), WithArgs<0, 1, 2>(Invoke(api_write)), ReturnPointee(&WRITE_COUNT)));
} }
void McuProtocolTestTool::UnInit(void) void McuProtocolTestTool::UnInit(void)
{ {
@ -30,46 +50,33 @@ void McuProtocolTestTool::UnInit(void)
} }
void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd) void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd)
{ {
const unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x0C, 0x3D, 0x68}; auto selectReadable =
const unsigned char REPLY_IPC_MISSION[] = { [=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89}; FD_ZERO(readfds);
static size_t WRITE_COUNT = -1; FD_SET(uartFd, readfds);
auto api_write = [=, &mock](int fd, const void *buf, size_t count) { };
McuProtocolTestTool::PrintHexadecimalData(buf, count, WRITE_PRINT); auto selectTimeOut =
if (sizeof(ASK_IPC_MISSION) == count && memcmp(ASK_IPC_MISSION, buf, count) == 0) { [=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
LogInfo("Set REPLY_IPC_MISSION\n"); long long timeMs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
auto selectReadable = std::this_thread::sleep_for(std::chrono::milliseconds(timeMs));
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { };
FD_ZERO(readfds); EXPECT_CALL(*mock.get(), fx_select(uartFd + 1, _, _, _, _))
FD_SET(uartFd, readfds); .WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1)))
}; .WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1)))
auto selectTimeOut = .WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT)));
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_IPC_MISSION) - PROTOCOL_DATA_KEY_HEAD_LENGTH;
long long timeMs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; auto apiReadKeyHead = [=](int fd, void *buf, size_t count) {
std::this_thread::sleep_for(std::chrono::milliseconds(timeMs)); memcpy(buf, REPLY_IPC_MISSION, PROTOCOL_DATA_KEY_HEAD_LENGTH);
}; McuProtocolTestTool::PrintHexadecimalData(buf, PROTOCOL_DATA_KEY_HEAD_LENGTH, READ_PRINT);
EXPECT_CALL(*mock.get(), fx_select(uartFd + 1, _, _, _, _))
.WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1)))
.WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1)))
.WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT)));
constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_IPC_MISSION) - PROTOCOL_DATA_KEY_HEAD_LENGTH;
auto apiReadKeyHead = [=](int fd, void *buf, size_t count) {
memcpy(buf, REPLY_IPC_MISSION, PROTOCOL_DATA_KEY_HEAD_LENGTH);
McuProtocolTestTool::PrintHexadecimalData(buf, PROTOCOL_DATA_KEY_HEAD_LENGTH, READ_PRINT);
};
auto apiReadLeftData = [=](int fd, void *buf, size_t count) {
memcpy(buf, REPLY_IPC_MISSION + PROTOCOL_DATA_KEY_HEAD_LENGTH, LEFT_DATA_LENGTH);
McuProtocolTestTool::PrintHexadecimalData(buf, LEFT_DATA_LENGTH, READ_PRINT);
};
EXPECT_CALL(*mock.get(), fx_read(uartFd, _, _))
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadKeyHead)), Return(PROTOCOL_DATA_KEY_HEAD_LENGTH)))
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH)))
.WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING)));
}
}; };
EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _)) auto apiReadLeftData = [=](int fd, void *buf, size_t count) {
.WillRepeatedly( memcpy(buf, REPLY_IPC_MISSION + PROTOCOL_DATA_KEY_HEAD_LENGTH, LEFT_DATA_LENGTH);
DoAll(SaveArg<2>(&WRITE_COUNT), WithArgs<0, 1, 2>(Invoke(api_write)), ReturnPointee(&WRITE_COUNT))); McuProtocolTestTool::PrintHexadecimalData(buf, LEFT_DATA_LENGTH, READ_PRINT);
};
EXPECT_CALL(*mock.get(), fx_read(uartFd, _, _))
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadKeyHead)), Return(PROTOCOL_DATA_KEY_HEAD_LENGTH)))
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH)))
.WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING)));
} }
void McuProtocolTestTool::PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event) void McuProtocolTestTool::PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event)
{ {

View File

@ -91,6 +91,7 @@ public:
const StatusCode Init(void); const StatusCode Init(void);
const StatusCode UnInit(void); const StatusCode UnInit(void);
const StatusCode GetIpcMission(std::shared_ptr<VProtocolContext> &context); const StatusCode GetIpcMission(std::shared_ptr<VProtocolContext> &context);
const StatusCode CutOffPowerSupply(std::shared_ptr<VProtocolContext> &context);
void DataHandleThread(void); void DataHandleThread(void);
protected: protected:
@ -98,6 +99,10 @@ protected:
StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength) override; StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength) override;
void PushMcuData(const void *buf, const size_t &length) override; void PushMcuData(const void *buf, const size_t &length) override;
private:
StatusCode WriteProtocolData(const void *buff, const size_t buffLength, std::shared_ptr<VProtocolContext> &context,
const unsigned int &serialNumber);
private: private:
std::mutex mMutex; std::mutex mMutex;
sem_t mSem; sem_t mSem;

View File

@ -53,17 +53,18 @@ const StatusCode McuProtocol::UnInit(void)
} }
const StatusCode McuProtocol::GetIpcMission(std::shared_ptr<VProtocolContext> &context) const StatusCode McuProtocol::GetIpcMission(std::shared_ptr<VProtocolContext> &context)
{ {
char data = 0; std::shared_ptr<VProtocolParam> param = std::make_shared<VProtocolParam>(PROTOCOL_COMMAND::ASK_IPC_MISSION);
std::shared_ptr<VProtocolParam> param =
std::make_shared<ProtocolParam<char>>(PROTOCOL_COMMAND::ASK_IPC_MISSION, data);
std::shared_ptr<ProtocolHandle> handle = ProtocolHandle::CreateProtocolData(param); std::shared_ptr<ProtocolHandle> handle = ProtocolHandle::CreateProtocolData(param);
size_t length = return WriteProtocolData(
WriteData(handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber());
LogInfo("WriteData length = %d\n", length); }
if (handle->GetProtocolDataLength() == length) { const StatusCode McuProtocol::CutOffPowerSupply(std::shared_ptr<VProtocolContext> &context)
return CreateStatusCode(STATUS_CODE_OK); {
} std::shared_ptr<VProtocolParam> param =
return CreateStatusCode(STATUS_CODE_NOT_OK); std::make_shared<VProtocolParam>(PROTOCOL_COMMAND::ASK_CUT_OFF_PWOER_SUPPLY);
std::shared_ptr<ProtocolHandle> handle = ProtocolHandle::CreateProtocolData(param);
return WriteProtocolData(
handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber());
} }
void McuProtocol::DataHandleThread(void) void McuProtocol::DataHandleThread(void)
{ {
@ -102,3 +103,12 @@ void McuProtocol::PushMcuData(const void *buf, const size_t &length)
mMcuDataList.push_back(packet); mMcuDataList.push_back(packet);
sem_post(&mSem); sem_post(&mSem);
} }
StatusCode McuProtocol::WriteProtocolData(const void *buff, const size_t buffLength,
std::shared_ptr<VProtocolContext> &context, const unsigned int &serialNumber)
{
size_t length = WriteData(buff, buffLength, context, serialNumber);
if (buffLength == length) {
return CreateStatusCode(STATUS_CODE_OK);
}
return CreateStatusCode(STATUS_CODE_NOT_OK);
}

View File

@ -28,6 +28,8 @@ ProtocolHandle::ProtocolHandle(const std::shared_ptr<VProtocolParam> &param) : m
mProtocolDataLength = 0; mProtocolDataLength = 0;
mSerialNumber = 0; mSerialNumber = 0;
mMakePacketFunc[ASK_IPC_MISSION] = std::bind(&ProtocolHandle::MakeAskIpcMissionPacket, this, std::placeholders::_1); mMakePacketFunc[ASK_IPC_MISSION] = std::bind(&ProtocolHandle::MakeAskIpcMissionPacket, this, std::placeholders::_1);
mMakePacketFunc[ASK_CUT_OFF_PWOER_SUPPLY] =
std::bind(&ProtocolHandle::MakeAskCutOffPowerSupplyPacket, this, std::placeholders::_1);
} }
ProtocolHandle::ProtocolHandle(const void *data, const size_t &length) ProtocolHandle::ProtocolHandle(const void *data, const size_t &length)
{ {
@ -48,6 +50,10 @@ ProtocolHandle::~ProtocolHandle()
} }
void ProtocolHandle::MakeProtocolPacket(const std::shared_ptr<VProtocolParam> &param) void ProtocolHandle::MakeProtocolPacket(const std::shared_ptr<VProtocolParam> &param)
{ {
if (mProtocolData != nullptr) {
LogError("Something wrong happened, make packet failed.\n");
return;
}
std::map<PROTOCOL_COMMAND, MakePacketFunc>::iterator iter; std::map<PROTOCOL_COMMAND, MakePacketFunc>::iterator iter;
iter = mMakePacketFunc.find(param->mCommand); iter = mMakePacketFunc.find(param->mCommand);
if (iter != mMakePacketFunc.end()) { if (iter != mMakePacketFunc.end()) {
@ -57,12 +63,8 @@ void ProtocolHandle::MakeProtocolPacket(const std::shared_ptr<VProtocolParam> &p
LogError("Unknown command.\n"); LogError("Unknown command.\n");
} }
} }
void ProtocolHandle::MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param) void ProtocolHandle::MakeNoUserDataPacket(const std::shared_ptr<VProtocolParam> &param)
{ {
if (mProtocolData != nullptr) {
LogError("Something wrong happened, make packet failed.\n");
return;
}
size_t dataLength = KEY_HEAD_LENGTH + sizeof(short); size_t dataLength = KEY_HEAD_LENGTH + sizeof(short);
mProtocolData = (unsigned char *)malloc(dataLength); mProtocolData = (unsigned char *)malloc(dataLength);
if (nullptr == mProtocolData) { if (nullptr == mProtocolData) {
@ -73,15 +75,24 @@ void ProtocolHandle::MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolPara
packet.mHead = PROTOCOL_HEAD; packet.mHead = PROTOCOL_HEAD;
packet.mCommand = param->mCommand; packet.mCommand = param->mCommand;
packet.mLength = dataLength; packet.mLength = dataLength;
packet.mCheckCode = calculate_check_sum(mProtocolData, dataLength - sizeof(short));
packet.mSerialNumber = mSerialNumber; packet.mSerialNumber = mSerialNumber;
mProtocolSerialNumber = packet.mSerialNumber; mProtocolSerialNumber = packet.mSerialNumber;
mSerialNumber++; mSerialNumber++;
BigEndianConversion(packet); BigEndianConversion(packet);
memcpy(mProtocolData, &packet, KEY_HEAD_LENGTH); memcpy(mProtocolData, &packet, KEY_HEAD_LENGTH);
packet.mCheckCode = calculate_check_sum(mProtocolData, dataLength - sizeof(short));
packet.mCheckCode = htons(packet.mCheckCode);
memcpy(mProtocolData + KEY_HEAD_LENGTH, &packet.mCheckCode, sizeof(short)); memcpy(mProtocolData + KEY_HEAD_LENGTH, &packet.mCheckCode, sizeof(short));
mProtocolDataLength = dataLength; mProtocolDataLength = dataLength;
} }
void ProtocolHandle::MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param)
{
MakeNoUserDataPacket(param);
}
void ProtocolHandle::MakeAskCutOffPowerSupplyPacket(const std::shared_ptr<VProtocolParam> &param)
{
MakeNoUserDataPacket(param);
}
void ProtocolHandle::AnalyzeProtocolPacket(void) void ProtocolHandle::AnalyzeProtocolPacket(void)
{ {
ProtocolPacket packet = {0}; ProtocolPacket packet = {0};

View File

@ -35,6 +35,7 @@ enum PROTOCOL_COMMAND
{ {
ASK_IPC_MISSION = 0x8101, ASK_IPC_MISSION = 0x8101,
REPLY_IPC_MISSION = 0x0101, REPLY_IPC_MISSION = 0x0101,
ASK_CUT_OFF_PWOER_SUPPLY = 0x8102,
PROTOCOL_COMMAND_END PROTOCOL_COMMAND_END
}; };
class VProtocolParam class VProtocolParam
@ -77,7 +78,9 @@ public:
*/ */
private: private:
void MakeProtocolPacket(const std::shared_ptr<VProtocolParam> &param); void MakeProtocolPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeNoUserDataPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param); void MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeAskCutOffPowerSupplyPacket(const std::shared_ptr<VProtocolParam> &param);
/** /**
* @brief These function implementations parse the received frame by frame continuous data into the data required by * @brief These function implementations parse the received frame by frame continuous data into the data required by

View File

@ -42,7 +42,7 @@ const StatusCode UartDeviceImpl::UartOpen(void)
const ssize_t UartDeviceImpl::UartSend(const void *buff, const size_t &buffLength) const ssize_t UartDeviceImpl::UartSend(const void *buff, const size_t &buffLength)
{ {
constexpr ssize_t SEND_FAILED = -1; constexpr ssize_t SEND_FAILED = -1;
ssize_t writeLength = 0; ssize_t writeLength = -1;
if (nullptr == buff) { if (nullptr == buff) {
LogError("data buff is nullptr.\n"); LogError("data buff is nullptr.\n");
return SEND_FAILED; return SEND_FAILED;
@ -54,6 +54,10 @@ const ssize_t UartDeviceImpl::UartSend(const void *buff, const size_t &buffLengt
size_t writeTotal = 0; size_t writeTotal = 0;
while (writeTotal < buffLength) { while (writeTotal < buffLength) {
writeLength = fx_write(mFd, buff, buffLength - writeTotal); writeLength = fx_write(mFd, buff, buffLength - writeTotal);
if (SEND_FAILED == writeLength) {
tcflush(mFd, TCOFLUSH);
return SEND_FAILED;
}
writeTotal += writeLength; writeTotal += writeLength;
} }
if (writeTotal == buffLength) { if (writeTotal == buffLength) {