#include #include #include #include "common_api.h" #include "PacketAnalizer.h" #include "ContainerDevice.h" #include "ImagePool.h" //#include "logger.h" using namespace std::placeholders; ContainerDevice::ContainerDevice() { m_ImagePool = new ImagePoolEx(); m_DisconnectEvt = 0; //m_pMqttClient = NULL; } ContainerDevice::~ContainerDevice() { CompleteUnInit(); delete m_ImagePool; } bool ConverCmdType_IoLevel2Ccos(ATTRACTION iocmd, PACKET_CMD &ccoscmd) { if (iocmd == ATTRACTION_GET) { ccoscmd = PACKET_CMD_GET; } else if (iocmd == ATTRACTION_SET) { ccoscmd = PACKET_CMD_UPDATE; } else if (iocmd == ATTRACTION_ADD) { ccoscmd = PACKET_CMD_ADD; } else if (iocmd == ATTRACTION_DEL) { ccoscmd = PACKET_CMD_DEL; } else if (iocmd == ATTRACTION_UPDATE) { ccoscmd = PACKET_CMD_PART_UPDATE; } else if (iocmd == ATTRACTION_DATA) { ccoscmd = PACKET_CMD_DATA; } else if (iocmd == ATTRACTION_MSG) { ccoscmd = PACKET_CMD_MSG; } else { //wtf?? //mLog::FERROR("unknown iocmd:%d,packetcmd:%d", (int)iocmd, (int)ccoscmd); return false; } return true; } bool ConverCmdType_Ccos2IoLevel(PACKET_CMD ccoscmd, ATTRACTION &iocmd) { if (ccoscmd == PACKET_CMD_GET) { iocmd = ATTRACTION_GET; } else if (ccoscmd == PACKET_CMD_UPDATE) { iocmd = ATTRACTION_SET; } else if (ccoscmd == PACKET_CMD_ADD) { iocmd = ATTRACTION_ADD; } else if (ccoscmd == PACKET_CMD_DEL) { iocmd = ATTRACTION_DEL; } else if (ccoscmd == PACKET_CMD_PART_UPDATE) { iocmd = ATTRACTION_UPDATE; } else if (ccoscmd == PACKET_CMD_DATA) { iocmd = ATTRACTION_DATA; } else if (ccoscmd == PACKET_CMD_MSG) { iocmd = ATTRACTION_MSG; } else { //wtf?? //mLog::FERROR("unknown iocmd:%d,packetcmd:%d", (int)iocmd, (int)ccoscmd); return false; } return true; } void ContainerDevice::SubscribeSelf() { LogicDevice::SubscribeSelf(); //委托IODevice订阅 //m_pMidObject->SubscribeSelf(); } void ContainerDevice::Init(CCOS_DEVICE_OBJ* ccosDeviceModule, DEVICE_HANDLE hDevice, /*std::unique_ptr &&pMid,*/std::shared_ptr DisconnectEvt) { //m_pMidObject = std::move(pMid); CompleteInit(); //g_pDPCDeviceObject = this; //auto a = std::bind(&ContainerDevice::NotifyCallBackEntry, this, _1, _2, _3); //m_pMidObject->EventCenter->OnNotify.Push(this,&ContainerDevice::NotifyCallBackEntry); ////auto b = std::bind(&ContainerDevice::RawDataNotifyCallBackEntry, this, _1, _2, _3, _4, _5, _6); //m_pMidObject->EventCenter->OnDataNotify.Push(this, &ContainerDevice::RawDataNotifyCallBackEntry); ////auto c = std::bind(&ContainerDevice::NotifyCallBackSetBlockSize, this, _1, _2, _3, _4, _5); //m_pMidObject->EventCenter->OnMaxBlockSize.Push(this, &ContainerDevice::NotifyCallBackSetBlockSize); //m_pMidObject->EventCenter->OnSystemLog.Push(this, &ContainerDevice::OnSystemLog); //m_pMidObject->EventCenter->OnLog.Push(this, &ContainerDevice::OnLog); //m_pMidObject->Prepare(); m_DisconnectEvt = DisconnectEvt; } #define CcosImageFul ("ImageFull") #define CcosImagePrev ("ImagePrev") #define CcosImageId ("Sharememid") void DEVICE_ACTION ContainerDevice::NotifyCallBackSetBlockSize(string QueName, DWORD BlockSize, DWORD FulBlockCount, DWORD PrevBlockSize, DWORD PrevBlockCount) { //Logger *pDevLog = GetLogHandle (); //mLog::FINFO (pDevLog, "SetBlockSize. Que:%s,BlockSize:%d,BlockCount:%d,PrevBlockSize:%d,PrevBlockCount:%d", QueName.c_str(),BlockSize,FulBlockCount,PrevBlockSize,PrevBlockCount); if (((ImagePoolEx*) m_ImagePool)->SetMaxBlockSize (QueName.c_str (), BlockSize, FulBlockCount, PrevBlockSize, PrevBlockCount) == false) { //mLog::FERROR( "SetMaxBlockSize Callback Failed"); } else { //mLog::FINFO( "SetMaxBlockSize Callback Succeed"); } } void DEVICE_ACTION ContainerDevice::RawDataNotifyCallBackEntry(int cmdType, string keyType, string Context,string Head,char *pRawData,int DataLength) { PACKET_CMD ccoscmd = PACKET_CMD_DATA; //Logger *pDevLog = GetLogHandle(); //if (ConverCmdType_IoLevel2Ccos((ATTRACTION)cmdType, ccoscmd)) { BLOCK_IMAGE_TYPE imgType; if (cmdType == 0) { imgType = FULL_BLOCK_IMG; } else if (cmdType == 1 || cmdType == 2) { imgType = PREV_BLOCK_IMG; } else { //mLog::FERROR( "wrong callback for data notify. cmdtype:%d", cmdType); return; } //UnvalidSMBid unsigned long Id = ((ImagePoolEx*)m_ImagePool)->AddFrameWithHead(imgType, Head, pRawData, DataLength); if (Id != UnvalidSMBid) { ResDataObject NotifyData; ResDataObject NotifyContext; //mLog::FINFO(pDevLog, "Data Notify. key:%s,Context:%s,Head:%s", keyType.c_str(), Context.c_str(), Head.c_str()); NotifyContext.decode(Context.c_str()); NotifyContext [CcosImageId] = Id; PacketAnalizer::MakeNotify(NotifyData, ccoscmd, keyType.c_str(), NotifyContext); //CmdFromLogicDev(&NotifyData); PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); PublishAction(&NotifyData, (m_strCCOSRoot + "/Notify").c_str(), m_pMqttConntion); //mLog::FINFO(pDevLog, "Data Notify res packet done"); } else { //mLog::FERROR("can't save frame 2 sharememory.keyType:%s.Head:%s.Context:%s.DataLen:%d", keyType.c_str(), Head.c_str(), Context.c_str(), DataLength); } } //else //{ // //mLog::FERROR("wrong notify type:%d", cmdType); //} } void DEVICE_ACTION ContainerDevice::NotifyCallBackEntry(int cmdType, string keyType, string Context) { std::cout << "--------------NotifyCallBackEntry " << std::endl; //3. Notify PACKET_CMD ccoscmd; //Logger* pDevLog = GetLogHandle(); if (ConverCmdType_IoLevel2Ccos((ATTRACTION)cmdType, ccoscmd)) { /* try { if (keyType == "SubscribeTopic") { // 去MQTT Broker 订阅 std::cout << "--------------SubscribeTopic " << keyType << std::endl; //mLog::FINFO(pDevLog, "SubscribeTopic.cmd:%d key:%s,Context:%s", cmdType, keyType.c_str(), Context.c_str()); ResDataObject topics; topics.decode(Context.c_str()); for (size_t i = 0; i < topics.size(); i++) { SubscribeOne((const char*)topics[i]); } } else if (keyType == "Unsubscribe") { // 取消订阅 //mLog::FINFO(pDevLog, "Unsubscribe.cmd:%d key:%s,Context:%s", cmdType, keyType.c_str(), Context.c_str()); ResDataObject topics; topics.decode(Context.c_str()); for (size_t i = 0; i < topics.size(); i++) { SubscribeOne((const char*)topics[i], true); } } else { // 那就是事件通知,往主题上publish 内容 //mLog::FINFO(pDevLog, "Notify to MQTT .cmd:%d key:%s,Context:%s", cmdType, keyType.c_str(), Context.c_str()); ostringstream ostopic; ostopic << TOPIC_PREFIX << "Notify/" << keyType; //mLog::FINFO(pDevLog, "PUBLISH TO MQTT TOPIC :%s,Context:%s", ostopic.str().c_str(), Context.c_str()); if (m_pMqttClient->is_connected()) { m_pMqttClient->publish(ostopic.str(), Context); } else { //mLog::FERROR( "MQTT Server Still not Connected ", cmdType); std::cout << "MQTT Server Still not Connected, Try Publish" << cmdType << " keytype: " << keyType << "Context : " << Context << std::endl; } } } catch (const mqtt::exception& exc) { //mLog::FERROR( "MQTT Server Still not Connected %s", exc.what()); }*/ if (ccoscmd != PACKET_CMD_DATA) { //raw data ResDataObject NotifyData; ResDataObject NotifyContext; //mLog::FINFO(pDevLog, "Notify.cmd:%d key:%s,Context:%s", cmdType, keyType.c_str(), Context.c_str()); std::cout << "[DeviceLog] Notify.cmd:" << cmdType << " key:" << keyType.c_str() << ",Context:" << Context.c_str() << std::endl; NotifyContext.decode(Context.c_str()); if (keyType == "ErrorList" && NotifyContext.size() > 0) { ResDataObject errorObj = NotifyContext[0]; if (ccoscmd == PACKET_CMD_ADD) { //if (errorObj.size() > 0 && errorObj[0].GetFirstOf("Type") >= 0) //{ // // Type是0表示Error // if (atoi((const char*)errorObj[0]["Type"]) == 0) // { // string strGUID = NotifyContext.GetKey(0); // if (m_pResErrorList->GetFirstOf(strGUID.c_str()) < 0) // m_pResErrorList->add(strGUID.c_str(), errorObj); // else // (*m_pResErrorList)[strGUID.c_str()].add(errorObj.GetKey(0), errorObj[0]); // PRINTA_INFO(pDevLog, "Add ErrorList %s", m_pResErrorList->encode()); // } //} string strSenderId = ""; int nSenderIdNum = errorObj.GetKeyCount("SenderId"); if (nSenderIdNum > 0) { strSenderId = (string)errorObj["SenderId"]; } string strCodeID = (string)errorObj["CodeID"]; int nLevel = (int)errorObj["Level"]; string strInfo = (string)errorObj["Resouceinfo"]; int nType = (int)errorObj["Type"]; LogicDevice::AddErrorMessage(strCodeID.c_str(), nLevel, strInfo.c_str(), nType, strSenderId.c_str()); ////mLog::FINFO(pDevLog, "AddErrorMessage:%s over", errorObj.encode()); return; } else if (ccoscmd == PACKET_CMD_DEL) { //if (errorObj.size() > 0 && errorObj[0].GetFirstOf("CodeID") >= 0) //{ // string CodeParam = errorObj[0]["CodeID"]; // if (CodeParam.size() == 0 || CodeParam == "0" || CodeParam == "") // { // m_pResErrorList->clear(); // PRINTA_INFO(pDevLog, "Clear all ErrorList"); // } // else // { // for (size_t n = 0; n < m_pResErrorList->size(); n++) // { // for (size_t i = 0; i < (*m_pResErrorList)[n].size(); i++) // { // string strCodekey = (*m_pResErrorList)[n].GetKey(i); // if ((*m_pResErrorList)[n][strCodekey.c_str()].GetFirstOf("Type") >= 0) // { // string strtype = (*m_pResErrorList)[n][strCodekey.c_str()]["Type"]; // if (strCodekey == CodeParam && atoi(strtype.c_str()) == 0) // { // (*m_pResErrorList)[n].eraseOneOf(CodeParam.c_str()); // PRINTA_INFO(pDevLog, "Clear ErrorList %s", m_pResErrorList->encode()); // break; // } // } // } // } // } //} string strCodeID = (string)errorObj["CodeID"]; int nLevel = (int)errorObj["Level"]; string strInfo = (string)errorObj["Resouceinfo"]; int nType = (int)errorObj["Type"]; LogicDevice::DelErrorMessage(strCodeID.c_str(), nLevel, strInfo.c_str(), nType); ////mLog::FINFO(pDevLog, "DelErrorMessage:%s over", errorObj.encode()); return; } } PacketAnalizer::MakeNotify(NotifyData, ccoscmd, keyType.c_str(), NotifyContext); //CmdFromLogicDev(&NotifyData); PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); PublishAction(&NotifyData, (m_strCCOSRoot + "/Notify").c_str(), m_pMqttConntion); //mLog::FINFO(pDevLog, "Notify res packet done"); } else { //mLog::FERROR("wrong callback for raw data notify"); } } else { std::cout << "--------------wrong notify type " << cmdType << std::endl; //mLog::FERROR("wrong notify type:%d", cmdType); } } void DEVICE_ACTION ContainerDevice::OnSystemLog(int LogLevel, string Code, string Context, string SenderId) { IoSystemLog(LogLevel, Code.c_str(), Context.c_str(),Context.size(),SenderId.c_str()); } void DEVICE_ACTION ContainerDevice::OnLog(int LogLevel, string Context) { //PrintA_IOLOG(m_pLogger, LogLevel, Context.c_str(), Context.size()); //mLog::FINFO("OnLog LEVEL : {$} Context: {$}", LogLevel, Context); } void DEVICE_ACTION ContainerDevice::OnPassiveDisconnected() { if (m_DisconnectEvt) { m_DisconnectEvt->SetEvent(); } } bool SYSTEM_CALL ContainerDevice::GetDeviceType(GUID &DevType) { //string lDevType = m_pMidObject->GetGUID(); ////if (m_pMidObject->GetDeviceType(lDevType)) //{ // return string_2_guid(lDevType.c_str(), DevType); //} return false; } //get device resource RET_STATUS SYSTEM_CALL ContainerDevice::GetDeviceResource(ResDataObject PARAM_OUT *pDeviceResource) { bool ret = true; string DevRes = ""; // m_pMidObject->GetResource(); //if (m_pMidObject->GetDeviceResource(DevRes)) { GUID DrvType; string guidstr; GetDeviceType(DrvType); guid_2_string(DrvType, guidstr); ret &= pDeviceResource->add("DeviceType", guidstr.c_str()); //make device type ret &= pDeviceResource->add("ClientType", DPC_UnitClient); ResDataObject LowLayerRes; if (LowLayerRes.decode(DevRes.c_str())) { //attr int Idx = LowLayerRes.GetFirstOf("Attribute"); if (Idx >= 0) { pDeviceResource->add("Attribute", LowLayerRes[Idx]); int erroridx = (*pDeviceResource)["Attribute"].GetFirstOf("ErrorList"); if (erroridx < 0) { (*pDeviceResource)["Attribute"].add("ErrorList", *m_pResErrorList); } else { (*pDeviceResource)["Attribute"]["ErrorList"] = *m_pResErrorList; } } else { ResDataObject Attribute; Attribute.add("ErrorList", *m_pResErrorList); pDeviceResource->add("Attribute", Attribute); } //action Idx = LowLayerRes.GetFirstOf("Action"); if (Idx >= 0) { pDeviceResource->add("Action", LowLayerRes[Idx]); } else { pDeviceResource->add("Action", ""); } return RET_SUCCEED; } } return RET_FAILED; } //normal sync routine,Request to device and response from device RET_STATUS SYSTEM_CALL ContainerDevice::Request(ResDataObject PARAM_IN *pRequest, ResDataObject PARAM_OUT *pResponse) { INT ret = RET_NOSUPPORT; //1. analize request PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pRequest); string keystr = PacketAnalizer::GetPacketKey(pRequest); ResDataObject Context; if (PacketAnalizer::GetPacketContext(pRequest, Context) == false) { return RET_FAILED; } //Logger *pDevLog = GetLogHandle(); if (cmd == PACKET_CMD_EXE) { string req, res; req = (const char *)Context.encode(); //mLog::FINFO( "Action[%s].req:%s",keystr.c_str(), req.c_str()); ret = 2;// (INT)m_pMidObject->Action(keystr, req, res); if (ret >= RET_SUCCEED) { Context.clear(); //mLog::FINFO( "Action[%s].res:%s", keystr.c_str(), res.c_str()); bool bObject = false; for (size_t i = 0; i < res.size(); i++) { char cValue = res[i]; if (cValue != ' ' && cValue != '\t' && cValue != '\r' && cValue != '\n') { if (cValue == '{' && res.find(':') != std::string::npos) { bObject = true; } break; } } if (bObject) { ResDataObject resp; resp.decode(res.c_str()); Context.add("P0", resp); } else { Context.add("P0", res.c_str()); } pResponse->update("CONTEXT", Context); //mLog::FINFO(pDevLog, "Action res packet done"); } } else if (cmd == PACKET_CMD_GET) { string res; //ret = m_pMidObject->AttributeAction(ATTRACTION_GET, keystr, res); //mLog::FINFO(pDevLog, "get req:%s", keystr.c_str()); assert(0);//not finished yet //ret = m_pMidObject->Get(keystr, res); if (ret >= RET_SUCCEED) { Context.clear(); //mLog::FINFO(pDevLog, "get res:%s", res.c_str()); bool bObject = false; for (size_t i = 0; i < res.size(); i++) { char cValue = res[i]; if (cValue != ' ' && cValue != '\t' && cValue != '\r' && cValue != '\n') { if (cValue == '{' && res.find(':') != std::string::npos) { bObject = true; } break; } } if (bObject) { ResDataObject resp; resp.decode(res.c_str()); Context.add("P0", resp); } else { Context.add("P0", res.c_str()); } pResponse->update("CONTEXT", Context); //mLog::FINFO(pDevLog, "Get res packet done"); } } //else if (cmd == PACKET_CMD_UPDATE) //{ // string res; // ret = m_pMidObject->AttributeAction(ATTRACTION_SET, keystr, res); // if (ret >= RET_SUCCEED) // { // pResponse->update("CONTEXT", res.c_str()); // } //} //else if (cmd == PACKET_CMD_ADD) //{ // string res; // ret = m_pMidObject->AttributeAction(ATTRACTION_ADD, keystr, res); // if (ret >= RET_SUCCEED) // { // pResponse->update("CONTEXT", res.c_str()); // } //} //else if (cmd == PACKET_CMD_DEL) //{ // string res; // ret = m_pMidObject->AttributeAction(ATTRACTION_DEL, keystr, res); // if (ret >= RET_SUCCEED) // { // pResponse->update("CONTEXT", res.c_str()); // } //} //else if (cmd == PACKET_CMD_PART_UPDATE) //{ // string res; // ret = m_pMidObject->AttributeAction(ATTRACTION_UPDATE, keystr, res); // if (ret >= RET_SUCCEED) // { // pResponse->update("CONTEXT", res.c_str()); // } //} else { //wtf?? } PacketAnalizer::MakeRetCode((RET_STATUS)ret, pResponse); return (RET_STATUS)ret; } //notify to lower layer RET_STATUS SYSTEM_CALL ContainerDevice::CmdToLogicDev(ResDataObject PARAM_IN *pCmd) { assert(0);//not happening return RET_FAILED; } void ContainerDevice::OnSetClientID() { //m_pMidObject->SetClientRootID((m_strClientID+"_IODevice").c_str(), ""); }