C++ 将NDEF记录有效负载转换为EthernetClient打印()的字符串

C++ 将NDEF记录有效负载转换为EthernetClient打印()的字符串,c++,arduino,nfc,arduino-esp8266,ndef,C++,Arduino,Nfc,Arduino Esp8266,Ndef,我尝试使用从NDEF格式的MIFARE NFC标记读取的数据发出HTTP GET请求。我无法将标签中的字节数组数据转换为以太网客户端print()函数的格式 硬件设置为Arduino Uno,带有seeedstudio NFC屏蔽和Arduino以太网屏蔽。我使用以太网、PN532和NfcAdapter库 我尝试了几种类型的转换,使用char*和char[]代替字符串对象,但没有成功 为了找出问题所在,我选择了一个案例,其中Serial.print()给出了预期的结果,但是client.prin

我尝试使用从NDEF格式的MIFARE NFC标记读取的数据发出HTTP GET请求。我无法将标签中的字节数组数据转换为以太网客户端
print()
函数的格式

硬件设置为Arduino Uno,带有seeedstudio NFC屏蔽和Arduino以太网屏蔽。我使用以太网、PN532和NfcAdapter库

我尝试了几种类型的转换,使用
char*
char[]
代替字符串对象,但没有成功

为了找出问题所在,我选择了一个案例,其中
Serial.print()
给出了预期的结果,但是
client.print()
没有

代码基于

void循环(void)
{
if(nfc.tagPresent())//执行nfc扫描以查看是否存在nfc标记
{
NfcTag tag=nfc.read();//读取nfc标记
if(tag.hasNdefMessage())
{
NdefMessage=tag.getNdefMessage();
对于(int i=0;i对于(inti=0;i根据您在注释中提供的信息,标记包含一个URI记录(反过来,该记录包含您的数据)。代码中的问题是,您直接将URI记录的完整有效负载用作字符串。但是,URI记录包含的不仅仅是字符串。特别是,有效负载的第一个字节是前缀字节(通常是不可打印的字符)。因此,似乎
Serial.println()
(或者更确切地说是您的串行接收器)只需跳过该字符。
client.print()
将在HTTP请求中包含该字符,并因此创建一个无效的HTTP请求(看起来好像省略了剩余的字节)

因此,在使用有效负载之前,必须遵循URI记录类型定义将其解码为正确的URI:

NdefMessage message = tag.getNdefMessage();
for (int i = 0; i < message.getRecordCount(); ++i) {
    NdefRecord record = message.getRecord(i);
    if (record.getType() == "U") {
        String uri = "";
        int payloadLength = record.getPayloadLength();
        if (payloadLength > 0) {
            byte payload[payloadLength];
            record.getPayload(payload);
            
            switch (payload[0]) {
                case 0x000: break;
                case 0x001: uri += "http://www."; break;
                case 0x002: uri += "https://www."; break;
                case 0x003: uri += "http://"; break;
                case 0x004: uri += "https://"; break;
                case 0x005: uri += "tel:"; break;
                case 0x006: uri += "mailto:"; break;
                case 0x007: uri += "ftp://anonymous:anonymous@"; break;
                case 0x008: uri += "ftp://ftp."; break;
                case 0x009: uri += "ftps://"; break;
                case 0x00A: uri += "sftp://"; break;
                case 0x00B: uri += "smb://"; break;
                case 0x00C: uri += "nfs://"; break;
                case 0x00D: uri += "ftp://"; break;
                case 0x00E: uri += "dav://"; break;
                case 0x00F: uri += "news:"; break;
                case 0x010: uri += "telnet://"; break;
                case 0x011: uri += "imap:"; break;
                case 0x012: uri += "rtsp://"; break;
                case 0x013: uri += "urn:"; break;
                case 0x014: uri += "pop:"; break;
                case 0x015: uri += "sip:"; break;
                case 0x016: uri += "sips:"; break;
                case 0x017: uri += "tftp:"; break;
                case 0x018: uri += "btspp://"; break;
                case 0x019: uri += "btl2cap://"; break;
                case 0x01A: uri += "btgoep://"; break;
                case 0x01B: uri += "tcpobex://"; break;
                case 0x01C: uri += "irdaobex://"; break;
                case 0x01D: uri += "file://"; break;
                case 0x01E: uri += "urn:epc:id:"; break;
                case 0x01F: uri += "urn:epc:tag:"; break;
                case 0x020: uri += "urn:epc:pat:"; break;
                case 0x021: uri += "urn:epc:raw:"; break;
                case 0x022: uri += "urn:epc:"; break;
                case 0x023: uri += "urn:nfc:"; break;
                default: break;
            }
            for (int j = 1; j < payloadLength; ++j) {
                uri += (char)payload[j]; // NOTE: this is wrong since the string is UTF-8 encoded (but we translate it byte-by-byte)
            }
        }
        Serial.println(uri);
        request(uri);
    }
}
NdefMessage message=tag.getNdefMessage();
对于(int i=0;i0){
字节有效载荷[有效载荷长度];
记录。获取有效载荷(有效载荷);
交换机(有效负载[0]){
案例0x000:中断;
案例0x001:uri+=”http://www.“休息;
案例0x002:uri+=”https://www.“休息;
案例0x003:uri+=“http://”中断;
案例0x004:uri+=“https://”中断;
案例0x005:uri+=“电话:”;中断;
案例0x006:uri+=“mailto:”中断;
案例0x007:uri+=”ftp://anonymous:anonymous@“休息;
案例0x008:uri+=”ftp://ftp.“休息;
案例0x009:uri+=“ftps://”中断;
案例0x00A:uri+=“sftp:/”中断;
案例0x00B:uri+=“smb://”中断;
案例0x00C:uri+=“nfs://”中断;
案例0x00D:uri+=“ftp://”中断;
案例0x00E:uri+=“dav://”中断;
案例0x00F:uri+=“新闻:”;中断;
案例0x010:uri+=“telnet://”中断;
案例0x011:uri+=“imap:”中断;
案例0x012:uri+=“rtsp://”中断;
案例0x013:uri+=“urn:”中断;
案例0x014:uri+=“pop:”中断;
案例0x015:uri+=“sip:”中断;
案例0x016:uri+=“sips:”中断;
案例0x017:uri+=“tftp:”中断;
案例0x018:uri+=“btspp://”中断;
案例0x019:uri+=“btl2cap://”中断;
案例0x01A:uri+=“btgoep://”中断;
案例0x01B:uri+=“tcpobex://”中断;
案例0x01C:uri+=“irdaobex://”中断;
案例0x01D:uri+=“文件:/”中断;
案例0x01E:uri+=“urn:epc:id:”中断;
案例0x01F:uri+=“urn:epc:tag:”中断;
案例0x020:uri+=“urn:epc:pat:”中断;
案例0x021:uri+=“urn:epc:raw:”中断;
案例0x022:uri+=“urn:epc:”中断;
案例0x023:uri+=“urn:nfc:”中断;
默认:中断;
}
对于(int j=1;j
请注意,上述解决方案仍存在一些问题:

  • URI的字符串部分(从偏移量1开始的字节)实际上是UTF-8编码的。但是,我们在这里将其视为(或多或少)ASCII编码。不过,我还没有找到任何简单的库来正确地将字节数组转换为Arduino上的UTF-8编码字符串表示形式
  • 如果生成的URI包含在URL中具有特殊含义的字符(如“/”、“:”、“&”等),则需要在将字符串附加到GET请求之前对其进行URL编码(例如,请参见)。否则,GET请求的生成URI可能不是您所期望的
  • 就内存效率而言,
    String
    肯定不是最佳选择

您使用什么记录类型?即从
记录中获得的值是什么。getType(…)
?是否执行
串行.println(数据);
当您从
请求()
函数中调用它时,打印任何内容?
有效负载长度的值是多少?
正确打印的数据字符串值是什么?是
payloadLengthNdefMessage message = tag.getNdefMessage();
for (int i = 0; i < message.getRecordCount(); ++i) {
    NdefRecord record = message.getRecord(i);
    if (record.getType() == "U") {
        String uri = "";
        int payloadLength = record.getPayloadLength();
        if (payloadLength > 0) {
            byte payload[payloadLength];
            record.getPayload(payload);
            
            switch (payload[0]) {
                case 0x000: break;
                case 0x001: uri += "http://www."; break;
                case 0x002: uri += "https://www."; break;
                case 0x003: uri += "http://"; break;
                case 0x004: uri += "https://"; break;
                case 0x005: uri += "tel:"; break;
                case 0x006: uri += "mailto:"; break;
                case 0x007: uri += "ftp://anonymous:anonymous@"; break;
                case 0x008: uri += "ftp://ftp."; break;
                case 0x009: uri += "ftps://"; break;
                case 0x00A: uri += "sftp://"; break;
                case 0x00B: uri += "smb://"; break;
                case 0x00C: uri += "nfs://"; break;
                case 0x00D: uri += "ftp://"; break;
                case 0x00E: uri += "dav://"; break;
                case 0x00F: uri += "news:"; break;
                case 0x010: uri += "telnet://"; break;
                case 0x011: uri += "imap:"; break;
                case 0x012: uri += "rtsp://"; break;
                case 0x013: uri += "urn:"; break;
                case 0x014: uri += "pop:"; break;
                case 0x015: uri += "sip:"; break;
                case 0x016: uri += "sips:"; break;
                case 0x017: uri += "tftp:"; break;
                case 0x018: uri += "btspp://"; break;
                case 0x019: uri += "btl2cap://"; break;
                case 0x01A: uri += "btgoep://"; break;
                case 0x01B: uri += "tcpobex://"; break;
                case 0x01C: uri += "irdaobex://"; break;
                case 0x01D: uri += "file://"; break;
                case 0x01E: uri += "urn:epc:id:"; break;
                case 0x01F: uri += "urn:epc:tag:"; break;
                case 0x020: uri += "urn:epc:pat:"; break;
                case 0x021: uri += "urn:epc:raw:"; break;
                case 0x022: uri += "urn:epc:"; break;
                case 0x023: uri += "urn:nfc:"; break;
                default: break;
            }
            for (int j = 1; j < payloadLength; ++j) {
                uri += (char)payload[j]; // NOTE: this is wrong since the string is UTF-8 encoded (but we translate it byte-by-byte)
            }
        }
        Serial.println(uri);
        request(uri);
    }
}