/* * Copyright (c) 2023 Fancy Code. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "McuProtocol.h" #include "ILog.h" #include "ProtocolHandle.h" #include std::shared_ptr &VProtocolRecv::GetInstance(std::shared_ptr *impl) { static auto instance = std::make_shared(); if (impl) { instance = *impl; } return instance; } const StatusCode McuProtocol::Init(void) { ProtocolHandle::Init(); constexpr int THREAD_SHARING = 0; constexpr int INITIAL_VALUE_OF_SEMAPHORE = 0; sem_init(&mSem, THREAD_SHARING, INITIAL_VALUE_OF_SEMAPHORE); auto dataHandleThread = [](std::shared_ptr handle) { handle->DataHandleThread(); }; std::shared_ptr handle = std::dynamic_pointer_cast(SharedFromThis()); mDataHandleThread = std::thread(dataHandleThread, handle); std::shared_ptr reply = std::dynamic_pointer_cast(SharedFromThis()); if (reply) { VProtocolRecv::GetInstance(&reply); } else { LogWarning("The VProtocolRecv class has not been overloaded, which can result in incomplete functionality.\n"); } return CreateStatusCode(STATUS_CODE_OK); } const StatusCode McuProtocol::UnInit(void) { ProtocolHandle::UnInit(); mThreadRuning = false; sem_post(&mSem); if (mDataHandleThread.joinable()) { mDataHandleThread.join(); } std::shared_ptr reply = std::make_shared(); VProtocolRecv::GetInstance(&reply); sem_destroy(&mSem); return CreateStatusCode(STATUS_CODE_OK); } const StatusCode McuProtocol::GetIpcMission(std::shared_ptr &context) { std::shared_ptr param = std::make_shared(PROTOCOL_COMMAND::ASK_IPC_MISSION); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::CutOffPowerSupply(std::shared_ptr &context) { std::shared_ptr param = std::make_shared(PROTOCOL_COMMAND::ASK_CUT_OFF_PWOER_SUPPLY); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::FeedWatchDog(std::shared_ptr &context) { std::shared_ptr param = std::make_shared(PROTOCOL_COMMAND::ASK_FEED_WATCH_DOG); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::SetFeedingCycleForWatchDog(const unsigned char &hour, const unsigned char &min, const unsigned char &second, std::shared_ptr &context) { WatchDogParam watchDogParam(hour, min, second); std::shared_ptr param = std::make_shared>(PROTOCOL_COMMAND::ASK_SET_FEEDING_CYCLE, watchDogParam); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::McuSetDateTime(const unsigned short &year, const unsigned char &mon, const unsigned char &day, const unsigned char &hour, const unsigned char &min, const unsigned char &second, std::shared_ptr &context) { SetDateTime dateTime(year, mon, day, hour, min, second); std::shared_ptr param = std::make_shared>(PROTOCOL_COMMAND::ASK_SET_DATE_TIME, dateTime); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::SetPirSensitivity(const unsigned char &sensitivity, std::shared_ptr &context) { std::shared_ptr param = std::make_shared>(PROTOCOL_COMMAND::ASK_SET_PIR_SENSITIVITY, sensitivity); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::ContorlInfraredLight(const unsigned char &control, std::shared_ptr &context) { std::shared_ptr param = std::make_shared>(PROTOCOL_COMMAND::ASK_CONTORL_INFRARED_LIGHT, control); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } const StatusCode McuProtocol::GetPhotosensitivityValue(std::shared_ptr &context) { std::shared_ptr param = std::make_shared(PROTOCOL_COMMAND::ASK_GET_PHOTOSENSITIVITY); std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } void McuProtocol::DataHandleThread(void) { mThreadRuning = true; while (mThreadRuning) { sem_wait(&mSem); mMutex.lock(); if (mMcuDataList.size() == 0) { mMutex.unlock(); continue; } SingleMcuPacket packet = mMcuDataList.front(); mMcuDataList.pop_front(); mMutex.unlock(); ProtocolHandle::ProtocolAnalysis(packet.mBuf, packet.mLength); free((void *)packet.mBuf); } } void McuProtocol::ReplyOtherSideSendIpcMission(const ReplyResult &result, const unsigned int &serialNumber) { std::shared_ptr NULL_CONTEXT; std::shared_ptr param = std::make_shared>( PROTOCOL_COMMAND::REPLY_OTHER_SIDE_ASK_SEND_IPC_MISSION, static_cast(result)); param->mSerialNumber = serialNumber; std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), NULL_CONTEXT, handle->GetSerialNumber()); } size_t McuProtocol::GetKeyHeadLength(void) { return ProtocolHandle::GetKeyHeadLength(); } StatusCode McuProtocol::GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength) { return ProtocolHandle::GetDataLength(keyHead, headLength, dataLength); } void McuProtocol::PushMcuData(const void *buf, const size_t &length) { char *data = (char *)malloc(length); if (nullptr == data) { LogError("malloc failed, PushMcuData failed.\n"); return; } LogInfo("PushMcuData\n"); memcpy(data, buf, length); ProtocolHandle::PrintHexadecimalData(data, length, "PushMcuData="); std::lock_guard locker(mMutex); SingleMcuPacket packet(data, length); mMcuDataList.push_back(packet); sem_post(&mSem); } StatusCode McuProtocol::WriteProtocolData(const void *buff, const size_t buffLength, std::shared_ptr &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); }