private byte[] CreateDefaultC0() { byte[] _buff = new byte[19]; _buff[0] = 0x89; _buff[1] = 0xc0; System.DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0); System.DateTime _dateTime = System.DateTime.Now; System.TimeSpan ts = _dateTime - dt; int t = (int)ts.TotalSeconds; _buff[2] = (byte)((t & 0xff000000) >> 32); _buff[3] = (byte)((t & 0x00ff0000) >> 16); _buff[4] = (byte)((t & 0x0000ff00) >> 8); _buff[5] = (byte)((t & 0x000000ff)); string temp = _dateTime.ToString("yyyyMMddHHmmss"); Array.Copy(ViaHere.HexStringToByteArray(temp), 0, _buff, 6, 7); _buff[13] = 0XFF; _buff[14] = 0XFF; _buff[15] = 0XFF; _buff[16] = 0XFF; _buff[17] = 0XFF; return(_buff); }
/// <summary> /// 向下封装PC-RSU数据帧,返回的是FF转义后的STX||RSCTL||DATA||BCC||ETX /// </summary> /// <param name="src">PC-RSU数据帧,RSCTL||DATA||BCC</param> /// <param name="offSet">起始位置</param> /// <param name="size">长度</param> /// <param name="dest">返回的是FF转义后的STX||RSCTL||DATA||BCC||ETX</param> protected void PcRsuFrameDown(byte[] src, int offSet, int size, out byte[] dest) { List <byte> _pcrsu_frame_down_temp = new List <byte>(); _pcrsu_frame_down_temp.Add(0XFF); _pcrsu_frame_down_temp.Add(0XFF); //矫正BCC src[offSet + size - 1] = ViaHere.BccCalc(src, offSet, size - 1); for (int i = offSet; i < offSet + size; i++) { switch (src[i]) { case 0xFF: _pcrsu_frame_down_temp.Add(0xfe); _pcrsu_frame_down_temp.Add(0x01); break; case 0xFE: _pcrsu_frame_down_temp.Add(0xfe); _pcrsu_frame_down_temp.Add(0x00); break; default: _pcrsu_frame_down_temp.Add(src[i]); break; } } _pcrsu_frame_down_temp.Add(0XFF); dest = _pcrsu_frame_down_temp.ToArray(); }
public override void StateWorker() { byte[] recvBuffer = null; byte[] c1 = new byte[15]; _ktl.PcRsu_CommIO.ReceiveTimeOut = 1000; _ktl.PcRsu_CommIO.SendTimeOut = 120; _ktl.PcRsu_CommIO.Receive(out recvBuffer); if (!BxFrameCheck(recvBuffer)) { //接收到无效帧,进入B2状态 _ktl.Jiaoyi_jieguo_message = "接收到无效帧"; return; } if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x80) { //心跳帧 _ktl.Jiaoyi_jieguo_message = "接收到心跳帧"; return; } _ktl.JiaoyiData.Add(recvBuffer); if (recvBuffer[1] == 0xB3 && recvBuffer[6] == 0x0) { //组织C1 c1[0] = ViaHere.ConverterHL(recvBuffer[0]); c1[1] = 0xc1; Array.Copy(recvBuffer, 2, c1, 2, 4); Array.Copy(_ktl.obuDivFactor, 0, c1, 6, 8); //进入B4状态 _ktl.TS = _ktl.StateB4; } else { //进入到B2状态 _ktl.TS = _ktl.StateB2; //交易失败 _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "STATE-B3"; //交易结果的描述 } _ktl.PcRsu_CommIO.Send(c1, 0, c1.Length); _ktl.JiaoyiData.Add(c1); }
public override void StateWorker() { byte[] recvBuffer = null; byte[] c1 = new byte[15]; _ktl.PcRsu_CommIO.ReceiveTimeOut = -1; _ktl.PcRsu_CommIO.SendTimeOut = 120; _ktl.Jiaoyi_jieguo_message = "等待车辆信息(B2)"; _ktl.PcRsu_CommIO.Receive(out recvBuffer); _ktl.Jiaoyi_jieguo_message = "接收到数据(B2)"; if (!BxFrameCheck(recvBuffer)) { //接收到无效帧,进入B2状态 _ktl.Jiaoyi_jieguo_message = "接收到无效帧"; return; } if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x80) { //心跳帧 _ktl.Jiaoyi_jieguo_message = "接收到心跳帧"; return; } if (recvBuffer[1] == 0xb0) { //进入B0状态 _ktl.Jiaoyi_jieguo_message = "接收到RSU上电信息帧"; _ktl.TS = _ktl.StateB0; return; } if (recvBuffer[1] != 0xB2) { _ktl.Jiaoyi_jieguo_message = "接收到不期待的信息帧(B2)"; return; } _ktl.Jiaoyi_jieguo = 0; //开始交易 _ktl.Jiaoyi_jieguo_message = "开始交易"; _ktl.JiaoyiData.Clear(); _ktl.JiaoyiData.Add(recvBuffer); if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x0) { //组织C1 c1[0] = ViaHere.ConverterHL(recvBuffer[0]); c1[1] = 0xc1; Array.Copy(recvBuffer, 2, c1, 2, 4); Array.Copy(recvBuffer, 7, c1, 6, 8); Array.Copy(recvBuffer, 7, _ktl.obuDivFactor, 0, 8); //OBUstatus 检查无卡 锁 卡出错状态 byte obustatusMask = 0x8c; byte obustatusA = recvBuffer[32]; int iM = obustatusA & obustatusMask; if (iM == 0) { //进入B3状态 _ktl.TS = _ktl.StateB3; } else { //进入到B2状态 _ktl.TS = _ktl.StateB2; //交易失败:标签无卡,锁 卡错 等等 _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "OBU状态"; //交易结果的描述 } } else { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "STATE-B2"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 } _ktl.PcRsu_CommIO.Send(c1, 0, c1.Length); _ktl.JiaoyiData.Add(c1); }
public override void StateWorker() { byte[] recvBuffer = null; byte[] cx; _ktl.PcRsu_CommIO.Receive(out recvBuffer); if (!BxFrameCheck(recvBuffer)) { //接收到无效帧,进入B2状态 _ktl.Jiaoyi_jieguo_message = "接收到无效帧"; return; } if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x80) { //心跳帧 _ktl.Jiaoyi_jieguo_message = "接收到心跳帧"; return; } _ktl.JiaoyiData.Add(recvBuffer); if (recvBuffer[1] != 0xB5) { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "B5(接收到不是B5帧)"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } if (recvBuffer[6] != 0x00) { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "B5(帧状态异常)"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } #region 交易成功 cx = new byte[15]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc1; Array.Copy(recvBuffer, 2, cx, 2, 4); Array.Copy(recvBuffer, 7, _ktl.obuDivFactor, 0, 8); _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 2; //交易结果:成功 _ktl.Jiaoyi_jieguo_message = "交易成功"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); _ktl.JiaoyiData.Add(cx); #endregion }
public override void StateWorker() { byte[] recvBuffer = null; _ktl.PcRsu_CommIO.ReceiveTimeOut = 2000; _ktl.PcRsu_CommIO.SendTimeOut = 120; byte[] c0 = CreateDefaultC0(); c0[13] = _ktl.c0_LaneMode; c0[14] = _ktl.c0_WaitTime; c0[15] = _ktl.c0_TxPower; c0[16] = _ktl.c0_PLLChannelID; c0[17] = _ktl.c0_TransClass; _ktl.PcRsu_CommIO.ClearReceiveBuffer(); _ktl.PcRsu_CommIO.Send(c0, 0, c0.Length); _ktl.Jiaoyi_jieguo_message = "等待RSU信息(B0)"; _ktl.PcRsu_CommIO.Receive(out recvBuffer); _ktl.Jiaoyi_jieguo_message = "接收到信息(B0)"; if (!BxFrameCheck(recvBuffer)) { //接收到无效帧 _ktl.Jiaoyi_jieguo_message = "接收到无效帧"; return; } _ktl.JiaoyiData.Clear(); _ktl.JiaoyiData.Add(recvBuffer); if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x80) { //心跳帧 _ktl.Jiaoyi_jieguo_message = "接收到心跳帧"; return; } if (recvBuffer[1] == 0xB0 && (recvBuffer[2] == 0x0 || recvBuffer[2] == 0x80) ) { //发送C1 指示继续交易 byte[] c1 = new byte[15]; c1[0] = ViaHere.ConverterHL(recvBuffer[0]); c1[1] = 0xc1; _ktl.PcRsu_CommIO.Send(c1, 0, c1.Length); //进入B2状态 _ktl.TS = _ktl.StateB2; _ktl.Jiaoyi_jieguo_message = "初始化交易参数OK"; } else { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 3; //交易结果:初始化RSU失败 _ktl.Jiaoyi_jieguo_message = "初始化RSU失败"; //交易结果的描述 _ktl.TS = _ktl.StateB0; return; } }
/// <summary> /// 返回FALSE,表示该帧无效 /// </summary> /// <param name="bx"></param> /// <returns></returns> protected bool BxFrameCheck(byte[] bx) { if (bx == null) { return(false); } if (bx.Length <= 2) { return(false); } bool rt = true; //帧长度以及帧头标识的检查 switch (bx[1]) { case 0xB0: if (bx.Length != 29 && bx.Length != 28) { rt = false; } break; case 0xB1: if (bx.Length != 5) { rt = false; } break; case 0xB2: if (bx.Length >= 7 && bx[6] == 0x80) { break; } else if (bx.Length != 35) { rt = false; } break; case 0xB3: if (bx.Length != 24) { rt = false; } break; case 0xB4: if (bx.Length != 98 && bx.Length != 101) { rt = false; } break; case 0xB5: if (bx.Length != 18 && bx.Length != 40 && bx.Length < 8 //仅检查到status字段 ) { rt = false; } break; default: rt = false; break; } //BCC CHECK if (bx[bx.Length - 1] != ViaHere.BccCalc(bx, 0, bx.Length - 1)) { rt = false; } return(rt); }
public override void StateWorker() { byte[] recvBuffer = null; byte[] cx; _ktl.PcRsu_CommIO.Receive(out recvBuffer); if (!BxFrameCheck(recvBuffer)) { //接收到无效帧,进入B2状态 _ktl.Jiaoyi_jieguo_message = "接收到无效帧"; return; } if (recvBuffer[1] == 0xB2 && recvBuffer[6] == 0x80) { //心跳帧 _ktl.Jiaoyi_jieguo_message = "接收到心跳帧"; return; } _ktl.JiaoyiData.Add(recvBuffer); if (recvBuffer[1] != 0xB4) { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "STATE-B4"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } if (recvBuffer[6] != 0x00) { _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "STATE-B4"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } #region 判断是复合还是传统消费 byte laneMode = _ktl.c0_LaneMode; byte transClass = _ktl.c0_TransClass; byte cmdType = 0; if (laneMode == 3) { if (transClass == 0) { cmdType = 0xc3; //msg = "chuantongjiaoyi"; } else if (transClass == 2 && recvBuffer[26] == 23) { cmdType = 0xc3; //msg = "jizhang chuantong jiaoyi"; } else { cmdType = 0xc6; //msg = "fuhe jiaoyi"; } } else { cmdType = 0xc6; //msg = "fuhe jiaoyi"; } #endregion #region 获取发行方 byte[] card_network = new byte[2]; byte[] card_divFacotr = null; Array.Copy(recvBuffer, 28, card_network, 0, 2); byte[] _card_divFactor_id = new byte[8]; Array.Copy(recvBuffer, 18, _card_divFactor_id, 0, 8); int _t = _card_divFactor_id[0] + _card_divFactor_id[1] + _card_divFactor_id[2] + _card_divFactor_id[3]; if (_t == 0) { //如果RSU没有提供发行方(数据为全0,北京车道问题),那么走另一套流程确定分散因子 if (_ktl.CardDivFactor.ContainsKey(card_network[0])) { card_divFacotr = _ktl.CardDivFactor[card_network[0]]; } else { card_divFacotr = null; } } else { //如果RSU提供发行方(数据为非全0),那么走标准流程确定分散因子 card_divFacotr = new byte[8]; Array.Copy(_card_divFactor_id, 0, card_divFacotr, 0, 4); Array.Copy(_card_divFactor_id, 0, card_divFacotr, 4, 4); } #endregion #region 判断无效发行方 if (card_divFacotr == null) { //无效发行方,交易失败 cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "无效发行方:" + ViaHere.ByteArraryToHexString(card_network); //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } #endregion #region 判断不支持的交易类型 if (cmdType != 0xc3 && cmdType != 0xc6) { cx = new byte[8]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc2; Array.Copy(recvBuffer, 2, cx, 2, 4); cx[6] = 1; _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "不支持的交易类型"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } #endregion #region 余额不足 if (cmdType == 0xc6) { uint cardresetmoney = 0; //卡余额 uint consumeMoney = 0; //应扣款 for (int i = 0; i < 4; i++) { cardresetmoney <<= 8; cardresetmoney += recvBuffer[10 + i]; consumeMoney <<= 8; consumeMoney += _ktl.ConsumeMoney[i]; } if (cardresetmoney < consumeMoney) { cx = new byte[15]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = 0xc1; Array.Copy(recvBuffer, 2, cx, 2, 4); Array.Copy(recvBuffer, 7, _ktl.obuDivFactor, 0, 8); _ktl.Jiaoyi = false; //交易结束 _ktl.Jiaoyi_jieguo = 1; //交易结果:失败 _ktl.Jiaoyi_jieguo_message = "卡余额不足"; //交易结果的描述 _ktl.TS = _ktl.StateB2; //进入到B2状态 _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); return; } } #endregion #region 继续交易 if (cmdType == 0xc3) { cx = new byte[62]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = cmdType; Array.Copy(recvBuffer, 2, cx, 2, 4); Array.Copy(card_divFacotr, 0, cx, 6, 8); Array.Copy(_ktl.TransSerial, 0, cx, 14, 4); string temp = DateTime.Now.ToString("yyyyMMddHHmmss"); Array.Copy(ViaHere.HexStringToByteArray(temp), 0, cx, 18, 7); Array.Copy(_ktl.Station, 0, cx, 25, 36); _ktl.TS = _ktl.StateB5s; //进入到B5s状态 } else { cx = new byte[66]; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = cmdType; cx[0] = ViaHere.ConverterHL(recvBuffer[0]); cx[1] = cmdType; Array.Copy(recvBuffer, 2, cx, 2, 4); Array.Copy(card_divFacotr, 0, cx, 6, 8); Array.Copy(_ktl.TransSerial, 0, cx, 14, 4); Array.Copy(_ktl.ConsumeMoney, 0, cx, 18, 4); string temp = DateTime.Now.ToString("yyyyMMddHHmmss"); Array.Copy(ViaHere.HexStringToByteArray(temp), 0, cx, 22, 7); Array.Copy(_ktl.Station, 0, cx, 29, 36); _ktl.TS = _ktl.StateB5; //进入到B5状态 } _ktl.PcRsu_CommIO.Send(cx, 0, cx.Length); _ktl.JiaoyiData.Add(cx); #endregion }