一:nfc实现文本、电话、网址等标签(NDEF协议)

如果对您有用记得点赞哦

ndef数据主要分为几个部分;
分为头,type长度(类型,也就是type占几个字节),pyload长度(数据,也就是数据占几个字节),type数据,type进一步分类,pyload数据。
整体的数据结构如下:

	Bit     7     6     5    4     3      2 1 0
第一字节:[ MB ][ ME ][ CF ][ SR ][ IL ][   TNF   ]

第二字节:[         TYPE  LENGTH                   ]

第三字节:[         PAYLOAD  LENGTH                ]

第四字节:[         ID  LENGTH                     ] 
.......................TYPE .......................
........................ID.........................
..................... PYLOAD.......................

举例说明:
加入想要写的文本为 hello word!
0xd1 0x01 0X0d 0X54 0x7a 0x68
0x68 , 0x65 ,0x6c , 0x6c ,0x6f , 0x20 , 0x77 ,0x6f , 0x72 ,0x64 , 0xef ,0xbc , 0x81
首先介绍第一字节:0xd1 (1101 0001)
bit 0:MB = 1 表明这是NDEF消息的第1个记录
bit 1:ME = 1 表明这是NDEF消息的最后一个记录,如果 ME = 0,后面还有记录
bit 2:CF = 0 表明这不是分块消息
bit 3: SR = 1 表明内容长度域是一个八位组。短记录的布局是用来为长度不到255个八位组的内容做精简封装
bit 4: IL = 1,则 ID_LEN 域出现在头部,长度为1个八位组。如果 IL = 0,ID_LEN 域就从记录头部忽略
bit 5-7: TNF 指示了 TYPE 域值的结构。0x01这个值是NFC论坛已知值
type长度: 0x01
pyload长度: 0X0d
ID长度: 忽略
type(1 bit): 0X54 (T)
ID:忽略
文本进一步描述 0x7a 0x68
TYPE(进一步分类):
pload: (hello word! )
0x68 , 0x65 ,0x6c , 0x6c ,0x6f , 0x20 , 0x77 ,0x6f , 0x72 ,0x64 , 0xef ,0xbc , 0x81

上代码
定义结构体类型

// NDEF NTF类型
typedef enum{
    TNF_NULL = 0,        // 空
    TNF_INSIDE_RTD = 1,  // NFC 论坛知名类型,包括UTF8、ASCII、URI...
    TNF_RFC2406 = 2,     // 定义于RFC 2046[RFC 2046]的媒体类型
    TNF_RFC3986 = 3,     // 定义于 RFC 3986[RFC 3986]的绝对 URI
    TNF_OUTSIDE_RTD = 4, // NFC 论坛外部自定义类型
    TNF_UNKNOW = 5,      // 未知
    TNF_STATIC = 6,      // 不可更改(参考2.3.3节)
    TNF_DEFAULT = 7      // 保留
} TnfType;

// NDEF TNF_INSIDE_RTD类型
typedef enum{
    RTD_UTF8 = 'T', // UTF8类型
    RTD_URI = 'U',  // URI类型
} RtdType;

typedef enum{
    START_PACK,     // 分包开始包
    MIDDLE_PACK,    // 分包中间包
    END_PACK,       // 分包结束包
    START_END_PACK  // 不分包,开始包也是结束包
}PackType;

// NDEF URI
typedef enum{
    RTD_URI_freeForm,     // 0x00     No prepending is done ... the entire URI is
                          // contained in the URI Field
    RTD_URI_httpWWW,      // 0x01     http://www.
    RTD_URI_httpsWWW,     // 0x02     https://www.
    RTD_URI_http,         // 0x03     http://
    RTD_URI_https,        // 0x04     https://
    RTD_URI_tel,          // 0x05     tel:
    RTD_URI_mailto,       // 0x06     mailto:
    RTD_URI_ftpAnonymous, // 0x07     ftp://anonymous:anonymous@
    RTD_URI_ftpFtp,       // 0x08     ftp://ftp.
    RTD_URI_ftps,         // 0x09     ftps://
    RTD_URI_sftp,         // 0x0A     sftp://
    RTD_URI_smb,          // 0x0B     smb://
    RTD_URI_nfs,          // 0x0C     nfs://
    RTD_URI_ftp,          // 0x0D     ftp://
    RTD_URI_dav,          // 0x0E     dav://
    RTD_URI_news,         // 0x0F     news:
    RTD_URI_telnet,       // 0x10     telnet://
    RTD_URI_imap,         // 0x11     imap:
    RTD_URI_rtps,         // 0x12     rtsp://
    RTD_URI_urn,          // 0x13     urn:
} UriVal;
// NDEF首字节解码
typedef struct{
    unsigned char TNF : 3; // TNF标志是 3-bit 字段,指示TYPE字段值的结构
    unsigned char IL : 1;  // IL 标志是 1-bit 字段,置 1 表示在首部存在一个单字节ID_LENGTH字段
    unsigned char SR : 1;  // SR 标志是 1-bit 字段,置 1 表示PAYLOAD_LENGTH字段为单字节
    unsigned char CF : 1;  // CF 标志是 1-bit 字段,置 1 表示 NDEF 消息分块传输
    unsigned char ME : 1;  // ME 标志是 1-bit 字段,置 1 表示 NDEF 消息的结束
    unsigned char MB : 1;  // MB 标志是 1-bit 字段,置 1 表示 NDEF 消息的开始
} NdefHead;
// NDEF 参数  文本类结构体
typedef struct{
    PackType packtype;      //是否分包
    RtdType dataType;       //数据类型
    UriVal uriVal;          //uri类型
} NdefFrame;

ndef制作

/**  application/vnd.wfa.wsc[23]=0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x76,0x6e,0x64,0x2e,0x77,0x66,0x61,0x2e,0x77,0x73,0x63
 * @brief NDEF包制作函数
 * @param ndef 传入NDEF相关参数
 * @param mem 保存根据NDEF参数制作的NDEF数据
 * @return 返回TRUE表示NDEF数据制作成功
 */
BOOL TWNdefPackMake(NdefFrame *ndef, MemFrame *mem)
{

    if (ndef->payloadLen > NDEF_RECORD_SIZE) //数据超出存储范围
    {
        return FALSE;
    }
        switch (ndef->packtype)
        {
        case START_PACK:
            mem->data[0] = 0x91;
            break;
        case MIDDLE_PACK:
            mem->data[0] = 0x11;
            break;
        case END_PACK:
            mem->data[0] = 0x51;
            break;
        case START_END_PACK:
            mem->data[0] = 0xD1;
            break;
        default:
            return FALSE;
        }
        mem->data[1] = 0x01;
        switch (ndef->dataType)
        {
        case RTD_UTF8:
            ndef->payloadLen += 3;
            break;

        case RTD_URI:
            ndef->payloadLen += 1;
            break;

        default:
            return FALSE;
        }
        mem->data[2] = ndef->payloadLen; // PLlen
        mem->data[3] = ndef->dataType;   // type
        mem->len = ndef->payloadLen + 4;

        if (ndef->dataType == RTD_UTF8)
        {
            mem->data[4] = 2;
            mem->data[5] = 'z';
            mem->data[6] = 'h';
            memcpy(&mem->data[7], ndef->payload, ndef->payloadLen);
        }
        else
        {
            mem->data[4] = ndef->uriVal;
            memcpy(&mem->data[5],  ndef->payload, ndef->payloadLen);
        }

        return TRUE;
 
}

ndef解析

/**
 * @brief NDEF包解析函数
 * @param ndef 保存解析后的NDEF相关参数
 * @param mem 被解析的NDEF数据
 * @return 返回TRUE表示NDEF数据解析成功
 */
BOOL TWNdefPackParsing(NdefFrame *ndef, unsigned char *mem)
{
    NdefHead head;
    memcpy(&head, &mem[0], 1);

        ndef->payloadLen = mem[2];
        if (ndef->payloadLen > NDEF_RECORD_SIZE) //数据域过长
        {
            return FALSE;
        }
        ndef->dataType = mem[3];
        unsigned char type = (head.MB << 2) | (head.ME << 1) | head.CF;
        switch (type) //分包类型
        {
        case 0:
            ndef->packtype = MIDDLE_PACK;
            break;
        case 2:
            ndef->packtype = END_PACK;
            break;
        case 4:
            ndef->packtype = START_PACK;
            break;
        case 6:
            ndef->packtype = START_END_PACK;
            break;
        default:
            return FALSE;
        }

        if (ndef->dataType == RTD_UTF8)
        {
            ndef->payloadLen -= 3;
            memcpy(ndef->payload, &mem[4 + 3], ndef->payloadLen);
        }
        else
        {
            ndef->uriVal = mem[4];
            ndef->payloadLen -= 1;
            memcpy(ndef->payload,  &mem[4 + 1], ndef->payloadLen);
        }
        ndef->dataType = 1;
        return TRUE;
}

以后更新,碰一碰实现打开APP,碰一碰WiFi配网等功能。
如有错误,请多多指正

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点灯大神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值