#include "LocalConfig.h"
#include "PacketCommon.h"
#include "PacketAnalizer.h"
#include "DrvTree.h"
//#include "DevBusManager.h"
#include "DeviceBus.h"
#include "HandleManager.h"
//#include "ClientManager.h"
#include "DriverManager.h"
//#include "shareMemWR.h"
//#include "CCOSLogicDeviceStructure.h"
//#include "sysif.h"
//ShareMemWR g_SM;
PacketCommon::PacketCommon()
{
}
PacketCommon::~PacketCommon()
{
}
///
/// 通过Bus发送Ccos包,包携带数据通过共享内存
///
/// 要发送的包
/// 是否本地
/// 目标BusId
/// 共享内存ID
///
bool SendSMpacket(ResDataObject &packet, bool Local, string &TargetbusId, unsigned long long nShareMemID)
{
if (BusSendSMPacket(packet, Local, TargetbusId, nShareMemID) == false)
{
//log here
//NOT FINISHED YET
//11.21版本为止,不添加功能
//应该反馈错误,并进行对应的后续处理
return false;
}
return true;
}
///
/// 通过Bus发走Ccos包
///
/// 要处理的包
/// 是否本地
/// 目标BusId
/// 消息块数据,默认NULL
/// 块数据长度,默认0
///
bool Sendpacket(ResDataObject &packet, bool Local, string &TargetbusId, char* pBlockData, DWORD Size)
{
if (BusSendPacket(packet, Local, TargetbusId, pBlockData,Size) == false)
{
//log here
//NOT FINISHED YET
//11.21版本为止,不添加功能
//应该反馈错误,并进行对应的后续处理
return false;
}
return true;
}
CMD_ECHO DoSendPacket(ResDataObject &packet, bool Local,bool Block, string &TargetbusId)
{
//do send
//block or packet
//if (Block)
//{
// //get context
// ResDataObject resImg;
// ImgDataInfo ImgData;
// string MachineId;
// if (PacketAnalizer::GetDestinationMachineId(packet, MachineId) == false)
// {
// return CMD_ECHO_IGNORE;
// }
// //printf("Got Req of PACKET_CMD_DATA!!!---------------------\n");
// if (MachineId != (const char*)getLocalMachineId())
// {
// PacketAnalizer::GetPacketContext(&packet, resImg);
// ImgData.SetResDataObject(resImg);
// //printf("Going to send SMPacket!!!---------------------\n");
// //target is not in this machine
// if (SendSMpacket(packet, Local, TargetbusId, ImgData.nShareMemID) == false)
// {
// //failed to send
// return CMD_ECHO_NOTARGET;
// }
// return CMD_ECHO_OK;
// }
// //same machineId,just send it as normal packet
//}
//if (Sendpacket(packet, Local, TargetbusId) == false)
//{
// //failed to send
// return CMD_ECHO_NOTARGET;
//}
return CMD_ECHO_OK;
}
///当前eBusId的CcosProc的包
CMD_ECHO DoThisProcDispatchPacket(ResDataObject &packet)
{
//packet cmd
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
PACKET_TYPE type = PacketAnalizer::GetPacketType(&packet);
if (cmd == PACKET_CMD_OPEN && type == PACKET_TYPE_REQ)
{
//open packet
//find driver tree
string path = PacketAnalizer::GetPacketKey(&packet);
if (path.size() > 0)
{
DrvTreeNode Node;
if (g_DrvTree.GetTreeNode(path.c_str(), Node))
{
//fill up
if (Node.m_ProcId != (UINT64)getpid())
{
//going to sub proc
BaseJsonDataObject translator;
translator = (UINT64)Node.m_ProcId;//bug fix
string TargetbusId = translator.GetVal();
//this machine
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
//mLog::FERROR("Failed send ebus.req dev:{$}", path.c_str());
g_DrvTree.PrintExistTree();
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;//dispatch it
}
else
{
return CMD_ECHO_NG;//to this proc
}
}
else
{
//mLog::FERROR("req dev:{$}", path.c_str());
g_DrvTree.PrintExistTree();
return CMD_ECHO_NOTARGET;
}
}
else
{
return CMD_ECHO_IGNORE;
}
}
else
{
//normal packet
UINT64 ProcId = 0;
if (PacketAnalizer::GetDestinationProcId(packet, ProcId) == false)
{
return CMD_ECHO_IGNORE;
}
UINT64 CurProcId = (UINT64)getpid();
//sub proc
if (ProcId != CurProcId)
{
BaseJsonDataObject translator;
translator = ProcId;
string TargetbusId = translator.GetVal();
//dispatch it
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
return CMD_ECHO_NG;//to this proc
}
return CMD_ECHO_NOTARGET;
}
//-1:ignore,0:Fail,1:local,2:Dispatch
CMD_ECHO DispatchPacket(ResDataObject &packet)
{
CCOS_PACKET_ROUTE Route;
CMD_ECHO ret = CMD_ECHO_IGNORE;
try {
//get destination Busid
string DesBusId;
if (PacketAnalizer::GetDestinationBusId(packet, DesBusId) == false)
{
return ret;
}
if (DesBusId == (const char*)getLocalEbusId())
{
//target is this proc
return DoThisProcDispatchPacket(packet);
}
//below is not this proc
//get target route
if (PacketAnalizer::GetPacketRoute(&packet, Route) == false)
{
return ret;
}
bool sendtoLocalMachine = false;
bool sendBlockData = false;
//packet cmd
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
if (cmd == PACKET_CMD_DATA)
{
sendBlockData = true;
}
//Precaculate direction
if (Route == CCOS_PACKET_ROUTE_ANY)
{
//choose one
Route = GetBusIdDirection(DesBusId);
//if still any direction,then try local and try eth
}
//caculate again
if (Route == CCOS_PACKET_ROUTE_LOCAL)
{
//target in this machine
sendtoLocalMachine = true;
}
else if (Route == CCOS_PACKET_ROUTE_ETH)
{
//target is not in this machine
}
else if (Route == CCOS_PACKET_ROUTE_ANY)
{
//if still any direction,then try local and try eth
//local first
if (DoSendPacket(packet, true, sendBlockData, DesBusId) == CMD_ECHO_OK)
{
return CMD_ECHO_OK;
}
//try eth
return DoSendPacket(packet, false, sendBlockData, DesBusId);
}
else
{
//ignore
return CMD_ECHO_IGNORE;
}
//do send
return DoSendPacket(packet, sendtoLocalMachine, sendBlockData, DesBusId);
}
catch (...)
{
}
return ret;
}
/*
//request target is device
//Dispatch those packets of none match busId&procId
CMD_ECHO From_RequestProcedure(ResDataObject &packet)
{
UINT64 ProcId;
string TargetbusId;
string DevMachineId;
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
if (PacketAnalizer::GetPacketHandleBusId(&packet, TargetbusId, true) == false)
{
return CMD_ECHO_IGNORE;
}
//target is not this proc
if ((TargetbusId != (const char*)getLocalEbusId()))
{
CCOS_PACKET_ROUTE route = Get_TargetDirection(packet);
switch (route) {
case CCOS_PACKET_ROUTE_NOTARGET:
{
return CMD_ECHO_NOTARGET;
}
break;
case CCOS_PACKET_ROUTE_ANY:
{
//1.try local
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
//2.try eth
if (Sendpacket(packet, false, TargetbusId) == true)
{
return CMD_ECHO_OK;
}
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
break;
case CCOS_PACKET_ROUTE_LOCAL:
{
//just try local
if (Sendpacket(packet, true, TargetbusId) == true)
{
//failed to send
return CMD_ECHO_OK;
}
return CMD_ECHO_NOTARGET;
}
break;
case CCOS_PACKET_ROUTE_ETH:
{
//just try eth
if (Sendpacket(packet, false, TargetbusId) == true)
{
return CMD_ECHO_OK;
}
return CMD_ECHO_NOTARGET;
}
break;
default:
return CMD_ECHO_NOTARGET;
break;
}
}
else
{
//find driver tree
string path = PacketAnalizer::GetPacketKey(&packet);
if (path.size() > 0)
{
DrvTreeNode Node;
if (g_DrvTree.GetTreeNode(path.c_str(), Node))
{
//fill up
if (Node.m_ProcId != (UINT64)GetCurrentProcessId())
{
//going to sub proc
BaseJsonDataObject translator;
translator = (UINT64)GetCurrentProcessId();
string TargetbusId = translator.GetVal();
//this machine
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;//dispatch it
}
else
{
return CMD_ECHO_NG;//to this proc
}
}
}
return CMD_ECHO_IGNORE;//ignore
}
//new change end---------------
//below it's not open packet..so mid must exist!!!
if (PacketAnalizer::GetPacketHandleMachineId(&packet, DevMachineId, true) == false)
{
return CMD_ECHO_IGNORE;
}
//target is not this proc
if ((TargetbusId != (const char*)getLocalEbusId()))
{
//dispatch it
if (cmd == PACKET_CMD_DATA)
{
//get context
ResDataObject resImg;
ImgDataInfo ImgData;
printf("Got Req of PACKET_CMD_DATA!!!---------------------\n");
if (DevMachineId != (const char*)getLocalMachineId())
{
PacketAnalizer::GetPacketContext(&packet, resImg);
ImgData.SetResDataObject(resImg);
printf("Going to send SMPacket!!!---------------------\n");
//target is not in this machine
if (SendSMpacket(packet, false, TargetbusId, ImgData.nShareMemID) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
//target in this machine
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
else
{
//normal packet to diffrent ebusid
//remote machine
if (DevMachineId != (const char*)getLocalMachineId())
{
if (Sendpacket(packet, false, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
//target in this machine
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
}
//This Proc
if (PacketAnalizer::GetPacketHandleProcId(&packet, ProcId, true) == false)
{
return CMD_ECHO_IGNORE;
}
//sub proc
if (ProcId != (UINT64)GetCurrentProcessId())
{
BaseJsonDataObject translator;
translator = ProcId;
TargetbusId = translator.GetVal();
//dispatch it
if (Sendpacket(packet, true, TargetbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
return CMD_ECHO_NG;//to this proc
}
//response target is client(owner)
//Dispatch those packets of none match busId&procId
CMD_ECHO From_ResponseProcedure(ResDataObject &packet)
{
string Temp;
string OwnerbusId;
UINT64 ProcId;
if (PacketAnalizer::GetPacketHandleBusId(&packet, OwnerbusId, false) == false)
{
return CMD_ECHO_IGNORE;
}
//for test
//if (Temp == "ccosChannel")
//{
// ret = ret;
//}
string OwnerMachineId;
if (PacketAnalizer::GetPacketHandleMachineId(&packet, OwnerMachineId, false) == false)
{
printf("CMD_DATA:Ignore RES of PACKET_CMD_DATA!!!---------------------\n");
return CMD_ECHO_IGNORE;
}
if ((OwnerbusId != (const char*)getLocalEbusId()))
{
//Dispatch here
//dispatch it
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
if (cmd == PACKET_CMD_DATA)
{
//for test
//mLog::FDEBUG("SendEthBlock");
//get context
ResDataObject resImg;
ImgDataInfo ImgData;
printf("CMD_DATA:Got RES of PACKET_CMD_DATA!!!\n");
if (OwnerMachineId == (const char*)getLocalMachineId())
{
printf("CMD_DATA:Normal send!!!\n");
//same machine,diffrent busid,send to local
if (Sendpacket(packet, true, OwnerbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
printf("CMD_DATA:OwnerMID:%s,LocalMID:%s\n", OwnerMachineId.c_str(), (const char*)getLocalMachineId());
PacketAnalizer::GetPacketContext(&packet, resImg);
ImgData.SetResDataObject(resImg);
printf("CMD_DATA:Send SMPacket!!!---------------------\n");
if (SendSMpacket(packet, false, OwnerbusId, ImgData.nShareMemID) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
else
{
//normal packet
//same machine,diffrent busid,send local
if (OwnerMachineId == (const char*)getLocalMachineId())
{
if (Sendpacket(packet, true, OwnerbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
//diffrent machine,send eth
if (Sendpacket(packet, false, OwnerbusId) == false)
{
//failed to send
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
}
//This Proc
//for test
//mLog::FDEBUG("LocalMsg");
if (PacketAnalizer::GetPacketHandleProcId(&packet, ProcId, false) == false)
{
return CMD_ECHO_IGNORE;
}
//sub proc
if (ProcId != (UINT64)GetCurrentProcessId())
{
//for test
//mLog::FDEBUG("Send Local");
BaseJsonDataObject translator;
translator = ProcId;
OwnerbusId = translator.GetVal();
//dispatch it
if (Sendpacket(packet, true, OwnerbusId) == false)
{
return CMD_ECHO_NOTARGET;
}
return CMD_ECHO_OK;
}
//for test
//mLog::FDEBUG("Send ThisProc");
return CMD_ECHO_NG;//this proc
}
//response target is client(owner)
//Dispatch those packets of none match busId&procId
CMD_ECHO From_NotifyProcedure(ResDataObject &packet)
{
return From_ResponseProcedure(packet);
}
*/
//suppose the packet is targeting this process
///
/// 本驱动的命令请求处理
///
///
///
/*
CMD_ECHO Do_LocalReqProcedure(ResDataObject &packet)
{
UINT64 Addr = 0;
CMD_ECHO ret = g_HandleManager.CheckReqPacketValidity(packet, Addr);
if (ret == CMD_ECHO_OK)
{
if (Addr && g_DrvManager.RequestToDevice(packet, Addr) >= RET_SUCCEED)
{
ret = CMD_ECHO_OK;
}
else
{
ret = CMD_ECHO_NOTARGET;
}
}
return ret;
}
*/
/*
CMD_ECHO Do_LocalResProcedure(ResDataObject &packet)
{
UINT64 Addr;
CMD_ECHO ret = CMD_ECHO_IGNORE;
//find driver tree
//printf("Driver Thread:%d,Do_LocalResProcedure Entry\n", GetCurrentThreadId());
if (PacketAnalizer::GetPacketHandleAddr(&packet, Addr, false))
{
if (g_ClientManager.ResToClient(packet, Addr) >= RET_SUCCEED)
{
ret = CMD_ECHO_OK;
}
else
{
ret = CMD_ECHO_NOTARGET;
}
}
return ret;
}
CMD_ECHO Do_LocalNotifyProcedure(ResDataObject &packet)
{
return Do_LocalResProcedure(packet);
}*/
///
/// 本驱动的Open命令处理
///
///
///
/*
CMD_ECHO Do_LocalOpenReqProcedure(ResDataObject &packet)
{
CMD_ECHO ret = CMD_ECHO_IGNORE;//ignore
bool Exist = false;
//find driver tree
string path = PacketAnalizer::GetPacketKey(&packet);
if (path.size() > 0)
{
DrvTreeNode Node;
//need lock strategy
g_DrvTree.Thread_Lock();
Exist = g_DrvTree.GetTreeNode(path.c_str(), Node);
g_DrvTree.Thread_UnLock();
if (Exist)
{
//update request
if (PacketAnalizer::UpdateOpenRequest(packet, getLocalMachineId(), getLocalEbusId(), Node.m_ProcId, Node.m_Address))
{
if (Node.m_Address && g_DrvManager.RequestToDevice(packet, Node.m_Address) >= RET_SUCCEED)
{
ret = CMD_ECHO_OK;
}
else
{
//mLog::FERROR("Dev exist.RequestToDevice Failed.:{$}", path.c_str());
ret = CMD_ECHO_NOTARGET;//no exist
}
}
}
else
{
//mLog::FERROR("Dev not exist:{$}", path.c_str());
g_DrvTree.PrintExistTree();
ret = CMD_ECHO_NOTARGET;//no exist
}
}
//failed status is returned by driverthread.so ignore 1 failed
return ret;
}*/
///
/// 本驱动的请求处理过程
///
///
///
///
/*
CMD_ECHO To_Local_RequestProcedure(ResDataObject &packet)
{
CMD_ECHO ret = CMD_ECHO_IGNORE;//ignore
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
switch (cmd)
{
case PACKET_CMD_OPEN:
return Do_LocalOpenReqProcedure(packet);
break;
case PACKET_CMD_CLOSE:
case PACKET_CMD_GET:
case PACKET_CMD_EXE:
return Do_LocalReqProcedure(packet);
break;
default:
break;
}
return ret;
}*/
/*
CMD_ECHO To_Local_ResponseProcedure(ResDataObject &packet)
{
CMD_ECHO ret = CMD_ECHO_IGNORE;//ignore
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
switch (cmd)
{
case PACKET_CMD_OPEN:
case PACKET_CMD_CLOSE:
case PACKET_CMD_GET:
case PACKET_CMD_EXE:
return Do_LocalResProcedure(packet);
break;
default:
break;
}
return ret;
}
CMD_ECHO To_Local_NotifyProcedure(ResDataObject &packet)
{
CMD_ECHO ret = CMD_ECHO_IGNORE;//ignore
PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(&packet);
switch (cmd)
{
case PACKET_CMD_CLOSE:
case PACKET_CMD_PART_UPDATE:
case PACKET_CMD_UPDATE:
case PACKET_CMD_ADD:
case PACKET_CMD_DEL:
case PACKET_CMD_EXE:
case PACKET_CMD_DATA:
case PACKET_CMD_MSG:
return Do_LocalNotifyProcedure(packet);
break;
default:
break;
}
return ret;
}
*/