#include "stdafx.h" #include "CSM315ProtocolEx.h" string CCSM315ProtocolEx::ToString(LPVOID buf, int len, int dir/* = 1*/) { size_t sz = 5 + 1 + 1 + 1 + 4; if (sz > (unsigned)len) return ""; LPBYTE pos = (LPBYTE)buf; StFrame data; memcpy_s(&data, sz, pos, sz); if (data.datalen == 0) { data.datalen = len - 16; } pos += sz; sz = 5 + 1 + 1 + 1 + 4 + data.datalen + 4; if (sz != (unsigned)len)//严格一点 return ""; string strMsg; //这里pos指向数据部分 if (data.datalen > 0) { switch (data.ftype) { case FRAME_TYPE_HEARTBEAT: { StHeartBeat315* lpdata = (StHeartBeat315*)pos; CTime t(lpdata->hbtime); strMsg = t.Format("[心跳包]%Y-%m-%d %H:%M:%S"); pos += data.datalen; break; } case FRAME_TYPE_DATA: { strMsg = ParseDataFrm(data, (LPVOID*)&pos, data.datalen, dir); pos += data.datalen; break; } default: break; } }//if memcpy_s(&data.ftail, 4, pos, 4); pos += 4; if (data.ftail != 0xFFFFFFFF || pos != (LPBYTE)buf + len) { //CCSM315ProtocolEx::Release(data, dir); return ""; } return strMsg; } ////将buf解析为StFrame, 内部包含包的类别 命令还是应答等 //BOOL CCSM315ProtocolEx::Parse(StFrame& data, LPVOID buf, int len, int dir) //{ // ZeroMemory(&data, sizeof(data)); // data.e_frmKind = GENERAL; // LPBYTE pos = (LPBYTE)buf; // // size_t sz = 5 + 1 + 1 + 1 + 4; // if (sz > (unsigned)len) // return FALSE; // memcpy_s(&data, sz, pos, sz); // if (data.datalen == 0) // { // data.datalen = len - 16; // } // pos += sz; // // sz = 5 + 1 + 1 + 1 + 4 + data.datalen + 4; // if (sz != (unsigned)len)//严格一点 // return FALSE; // // //这里pos指向数据部分 // if (data.datalen > 0) // { // switch (data.ftype) // { // // case FRAME_TYPE_HEARTBEAT: // { // StHeartBeat315* lpdata = new StHeartBeat315; // if (CCSM315Protocol::Parse(*lpdata, pos, data.datalen)) // { // data.lpdata = lpdata; // pos += data.datalen; // } // else // { // delete lpdata; // return FALSE; // } // break; // } // case FRAME_TYPE_DATA: // { // if (!ParseDataFrm(data, (LPVOID*)&pos, data.datalen, dir)) { //pos传地址用于在内部更新最新位置,失败了内部释放内存 // return false; // }; // break; // } // default: // break; // } // }//if // // memcpy_s(&data.ftail, 4, pos, 4); // pos += 4; // // if (data.ftail != 0xFFFFFFFF || pos != (LPBYTE)buf + len) // { // CCSM315ProtocolEx::Release(data, dir); // return FALSE; // } // // return TRUE; //} string CCSM315ProtocolEx::GetOptDirDesc(int direct) { switch (direct) { case 0: return _T("定到反"); case 1: return _T("反到定"); case 2: return _T("定到定"); case 3: return _T("反到反"); case 4: return _T("定位到故障位"); case 5: return _T("反位到故障位"); case 6: return _T("故障到定位"); case 7: return _T("故障到反位"); case 8: return _T("故障到故障位"); case 9: return _T("定位过车"); case 10: return _T("反位过车"); default: return _T("无效[") + to_string(direct) + "]"; break; } return _T(""); } string CCSM315ProtocolEx::GetAcqTypeDesc(int acqtype) { switch (acqtype) { case 0x101: return "定位测力值"; case 0x102: return "反位测力值"; case 0x103: return "转换阻力测力值"; case 0x104: return "温度"; case 0x105: return "湿度"; default: break; } return "未知"; } string CCSM315ProtocolEx::GetAlarmTypeDesc(int alarmID) { switch (alarmID) { case 0x101: return "定位瞬时冲击力超限预警"; case 0x102: return "反位瞬时冲击力超限预警"; case 0x103: return "定位锁闭力最小值超限预警"; case 0x104: return "定位锁闭力最小值超限报警"; case 0x105: return "反位锁闭力最小值超限预警"; case 0x106: return "反位锁闭力最小值超限报警"; case 0x107: return "定位锁闭力最大值超限预警"; case 0x108: return "定位锁闭力最大值超限报警"; case 0x109: return "反位锁闭力最大值超限预警"; case 0x110: return "反位锁闭力最大值超限报警"; case 0x111: return "定扳反转换阻力超限预警"; case 0x112: return "定扳反转换阻力超限报警"; case 0x113: return "反扳定转换阻力超限预警"; case 0x114: return "反扳定转换阻力超限报警"; case 0x115: return "定位保持力下降预警"; case 0x116: return "定位保持力下降报警"; case 0x117: return "牵引点离线报警"; default: break; } return "未知报警"; } //曲线类型 string CCSM315ProtocolEx::GetCurveTypeDesc(int curvetype) { switch (curvetype) { case 0x1010: return "定位测力曲线"; case 0x1020: return "反位测力曲线"; case 0x1030: return "转换阻力曲线"; case 0x1040: return "温度曲线"; case 0x1050: return "湿度曲线"; default: break; } return "未知"; } //buf指向数据内容 len数据内容的长度 返回data 和 最新位置的buf LPVOID*只是为了方便返回最新位置 string CCSM315ProtocolEx::ParseDataFrm(StFrame& data, LPVOID* buf, int len, int dir) { LPBYTE pos = (LPBYTE)(*buf); StDataBasic* basic = (StDataBasic*)pos; auto protol = (E_315_PROTOCOL_TYPE)basic->cmdid; int idx = 1; switch (protol) { //case E_315_PROTOCOL_TYPE::ACTIVE_KEEP: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x23: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x26: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x27: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x29: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x32: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2A: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2E: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2F: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x22: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x25: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x24: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x30: // break; //case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x31: // break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x50: { WORD size = *(WORD*)(pos + idx); idx += 2; string strMsg = "[0x50配置]个数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { BYTE len = *(BYTE*)(pos + idx); idx += 1; CString strText((char*)pos + idx, len); idx += len; strMsg += "名称:"; strMsg += (LPCSTR)strText; WORD id = *(WORD*)(pos + idx); idx += 2; strMsg += ", ID:" + to_string(id); BYTE cnt = *(BYTE*)(pos + idx); idx += 1; strMsg += ", 采集类型数量:" + to_string(cnt) + "["; for (BYTE j = 0; j < cnt; j++) { WORD acqtype = *(WORD*)(pos + idx); idx += 2; strText.Format("%s,", GetAcqTypeDesc(acqtype).c_str()); strMsg += (LPCSTR)strText; } strMsg += "]\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x51: { CString strText; BYTE bPush = *(BYTE*)(pos + idx); idx += 1; string strMsg = "[0x51最新值]"; if (bPush == 0) strMsg += "主动推送"; else strMsg += "请求回执"; WORD size = *(WORD*)(pos + idx); idx += 2; strMsg += ", 个数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { DWORD st = *(DWORD*)(pos + idx); idx += 4; CTime t(st); strMsg += t.Format("采集时间:%Y-%m-%d %H:%M:%S, "); WORD id = *(WORD*)(pos + idx); idx += 2; strMsg += ", ID:" + to_string(id) + ",位置:"; BYTE dir = *(BYTE*)(pos + idx); idx += 1; strMsg += (dir == 0 ? "定位" : (dir == 1 ? "反位" : "未知")); BYTE cnt = *(BYTE*)(pos + idx); idx += 1; strMsg += ", 采集类型数量:" + to_string(cnt); for (BYTE j = 0; j < cnt; j++) { WORD acqtype = *(WORD*)(pos + idx); idx += 2; BYTE acqsta = *(BYTE*)(pos + idx); idx += 1; TIEDA_ACQ_VALUE *val = (TIEDA_ACQ_VALUE*)(pos + idx); idx += 3; strText.Format("[类型:%s,状态:%s, 值:%s],", GetAcqTypeDesc(acqtype).c_str(), acqsta == 0 ? "故障" : "正常", val->tostring().c_str()); strMsg += (LPCSTR)strText; } strMsg += "]\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x52: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x53: { BYTE bPush = *(BYTE*)(pos + idx); idx += 1; string strMsg = "[0x53预报警]"; if (bPush == 0) strMsg += "主动推送"; else strMsg += "请求回执"; BYTE no = *(BYTE*)(pos + idx); idx += 1; strMsg += ", 流水号:" + to_string(no); WORD size = *(WORD*)(pos + idx); idx += 2; strMsg += ",个数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { stAlarmItem* it = (stAlarmItem*)(pos + idx); idx += sizeof(stAlarmItem); strMsg += "[ID:" + to_string(it->wNodeID); strMsg += ", 报警类型:" + GetAlarmTypeDesc(it->wAlarmType) + ", 报警状态:"; strMsg += it->byAlarmType == 1 ? "报警" : "恢复"; CTime t(it->time); strMsg += t.Format(", 报警时间:%Y-%m-%d %H:%M:%S, 报警值:"); strMsg += it->sAlarmValue.tostring(); strMsg += ", 参考值:" + it->sRefValue.tostring(); if (it->byAlarmType != 1) { t = CTime(it->dwRestoreTime); strMsg += t.Format(", 恢复时间:%Y-%m-%d %H:%M:%S"); } strMsg += ", 报警建议:" + to_string(it->wSuggestID); strMsg += "]\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x54: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x55: { WORD size = *(WORD*)(pos + idx); idx += 2; string strMsg = "[0x55历史数据]个数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { WORD id = *(WORD*)(pos + idx); idx += 2; strMsg += ", ID:" + to_string(id); WORD acqtype = *(WORD*)(pos + idx); idx += 2; strMsg += ", 采集类型:" + GetAcqTypeDesc(acqtype); DWORD time = *(DWORD*)(pos + idx); idx += 4; CTime t(time); strMsg += t.Format(", 起始时间:%Y-%m-%d %H:%M:%S"); WORD cnt = *(WORD*)(pos + idx); idx += 2; strMsg += ", 值数据:" + to_string(cnt) + "{"; for (WORD j = 0; j < cnt; j++) { WORD offset = *(WORD*)(pos + idx); idx += 2; strMsg += "[偏移:" + to_string(offset) + ", 值:"; TIEDA_ACQ_VALUE* val = (TIEDA_ACQ_VALUE*)(pos + idx); idx += 3; strMsg += val->tostring() + "]"; } strMsg += "}\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x56: { WORD size = *(WORD*)(pos + idx); idx += 2; string strMsg = "[0x56历史曲线列表]个数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { WORD id = *(WORD*)(pos + idx); idx += 2; strMsg += "ID:" + to_string(id); WORD cnt = *(WORD*)(pos + idx); idx += 2; strMsg += ", 条数:" + to_string(cnt) + "["; for (WORD j = 0; j < cnt; j++) { DWORD time = *(DWORD*)(pos + idx); idx += 4; CTime t(time); strMsg += t.Format("%Y-%m-%d %H:%M:%S,"); } strMsg += "]\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x57: { BYTE bPush = *(BYTE*)(pos + idx); idx += 1; string strMsg = "[0x57曲线数据]"; if (bPush == 0) strMsg += "主动推送"; else strMsg += "请求回执"; BYTE no = *(BYTE *)(pos + idx); idx += 1; strMsg += ", 流水号:" + to_string(no); WORD id = *(WORD*)(pos + idx); idx += 2; strMsg += ", ID:" + to_string(id); DWORD time = *(DWORD*)(pos + idx); idx += 4; CTime t(time); strMsg += t.Format(", 曲线时间:%Y-%m-%d %H:%M:%S"); BYTE size = *(BYTE*)(pos + idx); idx += 1; strMsg += ",条数:" + to_string(size) + "\r\n"; for (WORD i = 0; i < size; i++) { WORD curvetype = *(WORD*)(pos + idx); idx += 2; strMsg += "[曲线类型:" + GetCurveTypeDesc(curvetype); BYTE dir = *(BYTE*)(pos + idx); idx += 1; strMsg += ", 曲线方向:" + GetOptDirDesc(dir); WORD offset = *(WORD*)(pos + idx); idx += 2; strMsg += ", 偏移:" + to_string(offset); WORD frq = *(WORD*)(pos + idx); idx += 2; strMsg += ", 频率:" + to_string(frq); int cnt = *(int*)(pos + idx); idx += 4; strMsg += ", 点数:" + to_string(cnt)+"["; for (int j = 0; j < cnt; j++) { TIEDA_ACQ_VALUE* val = (TIEDA_ACQ_VALUE*)(pos + idx); idx += 3; strMsg += val->tostring() + ","; } strMsg += "]\r\n"; } return strMsg; } break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x58: break; default: break; } *buf = pos; return ""; } //释放内存,dir: 数据包方向 0-微机监测->JHD 1-JHD->微机监测 BOOL CCSM315ProtocolEx::Release(StFrame& data, int dir) { if (data.datalen != 0 && data.lpdata != NULL) { switch (data.ftype) { case FRAME_TYPE_HEARTBEAT: break; case FRAME_TYPE_DATA: { StDataBasic* basic = (StDataBasic*)data.lpdata; switch ((E_315_PROTOCOL_TYPE)basic->cmdid) { case E_315_PROTOCOL_TYPE::ACTIVE_KEEP: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x23: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x26: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x27: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x29: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x32: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2A: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2E: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x2F: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x22: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x25: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x24: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x30: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x31: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x50: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x51: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x52: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x53: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x54: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x55: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x56: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x57: break; case E_315_PROTOCOL_TYPE::E_315_PROTOCOL_0x58: break; default: break; } break; } default: break; } delete data.lpdata; } return TRUE; } int CCSM315ProtocolEx::GetDaysOfMonth(int y, int m) { int d; int day[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (m == 2) d = (((0 == y % 4) && (0 != y % 100) || (0 == y % 400)) ? 29 : 28); else d = day[m - 1]; return d; } bool CCSM315ProtocolEx::IsValid(const SYSTEMTIME& sDT) { if (sDT.wYear < 2000) return false; if ((sDT.wMonth > 12) || (sDT.wMonth == 0)) return false; if (sDT.wHour > 23) return false; if (sDT.wMinute > 59) return false; if (sDT.wSecond > 59) return false; WORD wDays = GetDaysOfMonth(sDT.wYear, sDT.wMonth); if ((sDT.wDay == 0) || (sDT.wDay > wDays)) return false; return true; } int CCSM315ProtocolEx::CalcTimePassSecond(SYSTEMTIME* stLast, SYSTEMTIME* stNow, BOOL bReturnOriginalVal) { SYSTEMTIME stNowTime; if (stNow) { stNowTime = *stNow; } else { GetLocalTime(&stNowTime); } if (!IsValid(*stLast)) memset(stLast, 0, sizeof(SYSTEMTIME)); CTime dTimeNow(stNowTime); CTime dTimeLast(*stLast); CTimeSpan dTimeSpan = dTimeNow - dTimeLast; int iSecnonSpan = dTimeSpan.GetTotalSeconds(); //处理毫秒时差 { //低位不足,就要借位 if (stNowTime.wMilliseconds < stLast->wMilliseconds) { iSecnonSpan--; } } if (bReturnOriginalVal)//返回原始值 { return iSecnonSpan; } return abs(iSecnonSpan); }