您好!欢迎来到默认站点! 请登录 注册有礼
首页 新闻资讯 > 研发日志 > 物联网

物联网RFID开发六:解析上报数据

2020-4-3 23:53:00 人评论

上一章的SocketHelper.cs是通用型的Socket监听管理类,不包含解析数据功能,将以事件的方式将接收的原始字节数据发布到调用类,编写ReaderDeviceHelper.cs读头设备管理类,在开启监听方法中注册SocketHelper管理类的ReceiveDataEvent接收数据事件,并在事件方法中解析上报数据…

ReaderDeviceHelper.cs读头设备管理类,通过复写SocketReceiveData虚方法编写代码解析上报数据,获取EPC标识代码,对于解析方法,如果用正则表达式应该会比较简便,但是性能没有保障,所以采用匹配byte字节方式处理,监听端口数据可以绑定多种RFID卡型号,不同型号的卡标志位可能不同,解析数据代码可以匹配多种类型卡的标志位,并获取卡号数据。


/// <summary>
/// 覆写SocketHelper管理类接收数据方法,针对WYUAN读头设备处理数据
/// </summary>
/// <param name="socketClient"></param>
/// <param name="receiveData"></param>
public override void SocketReceiveData(SocketClient socketClient, SocketReceiveData receiveData) {
    base.SocketReceiveData(socketClient, receiveData);
    Models.IOT.listen_port model_port = new BLL.IOT.listen_port().GetFirstModel("port=" + receiveData.LocalPort);
    if (model_port != null) {
        List<string> list_cardno = new List<string>();
        //Socket接收到的数据(包含多条卡号数据的标志位、卡号数据、CRC-16结束数据位)
        byte[] receiveBytes = receiveData.ReceiveBytes;
        int index = 0;//接收数据检索索引值,不是单向递增1,如果与卡型匹配失败会回退起始位置重新匹配下一个卡类型标志位
        int type_index = 0;//设置
        while (index < receiveBytes.Length) {
            Entities.IOT.card_type entity = model_port.list_card_type[type_index];//设置当前匹配的卡类型
            byte[] flag_bit = Utils.HexStringToByte(entity.flag_bit);//转换十六进制字符串标志位为字节数组
            byte[] buffer = new byte[entity.data_length];//设置卡号字节数组缓冲区
            //完整卡数据长度=标志位长度+卡号数据位长度+效验位长度
            int total_length = flag_bit.Length + entity.data_length + entity.crc_length;
            bool ismatch = false;//是否已经成功匹配到了当前卡类型标志位
            int flag_index = 0;//匹配标志位进行中的索引值
            int buffer_index = 0;
            int end_index = 0;//上一个卡号数据匹配结束时的索引值
            while (index < receiveBytes.Length) {
                if (ismatch) {//读取卡号数据中
                    buffer[buffer_index] = receiveBytes[index];//保存卡号字节数据到卡号字节数组
                    buffer_index++;
                    if (buffer_index == buffer.Length) {//读取了一条完整的EPC卡号数据,进行下一条数据匹配
                        //保存接收到卡号数据(忽略重复卡号)
                        string epc = Utils.ByteToHexString(buffer);
                        if (!list_cardno.Contains(epc)) {
                            list_cardno.Add(epc);
                        }
                        ismatch = false;//重新匹配下一个卡号数据
                        buffer_index = 0;//缓冲区索引重置为0
                        end_index = index;//设置上一个卡号成功匹配的结束索引值
                        flag_index = 0;//标志位索引设置为0
                        type_index = 0;//类型索引归零,重新开始匹配
                    }
                }
                else {//匹配标志位中
                    if (receiveBytes[index] == flag_bit[flag_index]) {//成功匹配标志位中,需要判断是否所有标志位都匹配成功
                        flag_index++;
                        if (flag_index == flag_bit.Length) {
                            //标志位匹配成功,开始读取卡号数据
                            ismatch = true;
                            flag_index = 0;
                            index++;
                            continue;
                        }
                    }
                    else {
                        if (flag_index > 0) {//标志位索引值大于0,说明有部分标志匹配成功,当前标志位匹配失败
                            flag_index = 0;//标志位索引值设置为0,重新开始匹配标志位
                        }
                    }
                    if ((index - end_index) > total_length) {//匹配的数据长度超出单条卡数据长度
                        type_index++;//设置匹配下一个卡类型标志位
                        if (type_index < model_port.list_card_type.Count) {
                            //后续还有卡类型需要匹配
                            index = end_index;//接收数据索引值重置为上一次成功匹配的结束索引
                            break;
                        }
                        else {
                            //所有卡类型的标志位匹配失败
                            type_index = 0;
                            end_index = index;//设置结束索引值为当前索引,忽略当前区段的数据
                            flag_index = 0;//重置标志位索引值
                        }
                    }
                }//end if(ismatch)
                index++;
            }//end for
        }
        //分析接收数据结束,处理获取的卡号数据
        ReaderReceiveData model = new ReaderReceiveData(receiveData);
        model.EPC = list_cardno.ToArray();
        list_readerReceiveData.Add(model);
    }
}

涉及到16进制数据格式转换,为Utils.cs类增加了相应静态方法

#region 十六进制数据格式转换操作
/// <summary>
/// 字节数组转换为16进制字符串
/// </summary>
/// <param name="bytes">字节数组</param>
/// <param name="separator">分隔字符</param>
/// <returns></returns>
public static string ByteToHexString(byte[] bytes, string separator) {
    return BitConverter.ToString(bytes, 0).Replace("-", separator);
}

/// <summary>
/// 字节数组转换为16进制字符串
/// </summary>
/// <param name="bytes">字节数据</param>
/// <returns></returns>
public static string ByteToHexString(byte[] bytes) {
    return ByteToHexString(bytes, string.Empty);
}

/// <summary>
/// 16进制字符串转换为字节数组
/// </summary>
/// <param name="hexString">16进制字符串</param>
/// <param name="separator">分隔符</param>
/// <returns></returns>
public static byte[] HexStringToByte(string hexString, string separator) {
    if (!string.IsNullOrEmpty(separator)) {
        //移除分隔字符
        hexString = hexString.Replace(separator, "");
    }
    if ((hexString.Length % 2) != 0)
        hexString += " ";
    byte[] returnBytes = new byte[hexString.Length / 2];
    for (int i = 0; i < returnBytes.Length; i++) {
        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
    }
    return returnBytes;
}

/// <summary>
/// 16进制字符串转换为字节数组
/// </summary>
/// <param name="hexString">16进制字符串</param>
/// <returns></returns>
public static byte[] HexStringToByte(string hexString) {
    return HexStringToByte(hexString, string.Empty);
}
#endregion

解析数据获取到RFID卡EPC标识号后,就可以进行发卡管理了,后续可以进入业务逻辑功能代码的编写了

图片.png

相关资讯

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?
    会员登陆
    18004549898
    QQ
    Mvcms网站管理系统客服QQ:
    返回顶部