【问题标题】:MICROS 8700 Returned Fixed Message Format not loggedMICROS 8700 返回的固定消息格式未记录
【发布时间】:2019-04-13 08:01:53
【问题描述】:

我正在研究通过串行 com 端口发送 MICROS 8700 固定消息的 POS 与我们的 PMS 之间的接口。 我的经验是 C#、MVC、AJAX、webapp 端和更现代的技术。我对所有的 COM 串行端口通信和 Micros 仿真很迷茫,但我已经做了我能做的。

我创建了一个 C# windows 服务,它接收消息并(据我所见)返回一条消息。 POS 软件通过串行 COM 端口发送其消息。 我在中间有 3rd 方软件将其转换为 TCP。(我可以看到数据从 POS 传递到 POS 在这个 3rd 方软件上。)

我的软件正在侦听特定的 TCP 端口。

它接收字节流很好。

转换为 ASCII 字符串。

根据响应字符串创建校验和,但不包括 SOH,直到并包括 ETX 字符。 Link

使用 ASCII 编码将响应转换为字节数组。

它回复,我认为是正确的格式,但它没有被 POS 软件记录。

我正在研究我的校验和计算不正确的理论,但在更改校验和的确定方式时我没有取得任何进展。

我以 SOH (\u0001) 字符开始每条消息,并以 EOT (\u0004) 结束。我还用 STX (\u0002) 和 ETX (\u0003) 分隔消息

我什至无法获得要记录的基本错误消息。

为了让我看起来不懒惰/不称职,我所要做的只是一个示例日志文件以及我可以在互联网上找到的内容。

我想我需要“1000/2000/4700/8700 pms 接口规范手册”,但我无法获得这份副本。

我的程序收到消息

1Rev 1 1 120 2001069B

这是

SOH 1Rev 1 STX 1 120 2001ETX069BEOT

我的程序会响应

1Rev 1 1/无效条目 0AC5

这是

SOH 1Rev 1 STX 1/无效条目 ETX0AC5EOT

SOH 终端 ID STX 1/INVALID ENTRY ETXchecksumEOT

有时,当 POS 端的连接超时时,每隔 30 秒,回复的第一个字符就会出现在 POS 日志中,但我认为这与缓冲区有关。

也许我发送了一些非常错误的东西,而 POS 软件没有达到预期的效果,因此它没有记录/处理它。

我正在发送 EOT,我相信它会告诉 POS 消息已完成,并且 Windows 服务也会关闭流。所以我不认为 POS 正在等待消息结束。

我已经阅读了一些可能有用的帖子 Link Link

真的,我想要一些关于如何生成校验和的建议,或者关于我的问题可能是什么的任何其他建议。 请查看我尝试过的两个不同的校验和代码块。

来自Link “校验和是所有的 16 位二进制加法(不包括奇偶校验,如果适用) SOH 之后的字符,直到并包括 ETX 字符。校验和是 初始设置为零。对于传输,校验和表示为四个 ASCII-Hex 字符。”

        private static string GetChecksum(string s)
    {
        int checksum = 0;

        byte[] binary = Encoding.ASCII.GetBytes(s);

        foreach (byte b in binary)
        {
            checksum = ((checksum + b) & 0xFF);
        }
        checksum = (((checksum ^ 0xFF) + 1) & 0xFF);
        return checksum.ToString("X4");
    }

 private static string GetChecksum(string data)
    {
        short checksum = 0;
        int byteCount = data.Length;
        int index = 0;
        char current;
        byte intOffset = 48;
        byte alphaOffset = 55;
        byte scale = 16;

        if (byteCount < 2) // bad string
            return "Error";

        while (index < byteCount - 1)
        {
            current = data[index++];
            if (current < 'A')
            {
                checksum += (byte)(((byte)current - intOffset) * scale);
            }
            else
            {
                checksum += (byte)(((byte)current - alphaOffset) * 16);
            }
            current = data[index++];
            if (current < 'A')
            {
                checksum += (byte)(((byte)current - intOffset));
            }
            else
            {
                checksum += (byte)(((byte)current - alphaOffset));
            }
            index++;
        }
        return checksum.ToString("X4");
    }

【问题讨论】:

    标签: c# pos


    【解决方案1】:

    原来我需要在回复消息之前回复 ACK。

    十进制八进制十六进制二进制字符

    006 006 0x06 00000110 ACK(确认)

    或者对于 C#

    static char ACK = '\u0006';
    
    
    byte[] ackMsg = System.Text.Encoding.ASCII.GetBytes(ACK.ToString());
                                stream.Write(ackMsg, 0, ackMsg.Length);
    

    校验和计算如下

    现在我的回答已被软件验证并显示。

    "ASCII 字符,代表校验和。有 总是4个数字。它们是十六进制(0 到 9 是 由十六进制 0x30 .. 0x39 表示,而 A-F 由 十六进制 0x41 到 0x46)。校验和由最初计算 将其设置为 0,然后添加所有字符开始 with (but NOT INCLUDING) 和 through (and INCLUDING) 特点。然后表示得到的数字 使用 ASCII 字符并放置在消息中 "

     private static string GetChecksum(string s)
            {//this gives matching checksums
                int checksum = 0;
    
                byte[] binary = Encoding.ASCII.GetBytes(s);
    
                foreach (byte b in binary)
                {
                    checksum = ((checksum + b));
                }
                return checksum.ToString("X4");
            }
    

    我希望这可以帮助那些被困在旧技术上的人。

    【讨论】:

      猜你喜欢
      • 2016-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 2020-06-12
      • 1970-01-01
      相关资源
      最近更新 更多