npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ctsy/iot-protocol

v1.0.8

Published

## 协议设计描述文档

Downloads

17

Readme

IoT应用二进制通信协议设计及编解码库

协议设计描述文档

0x68 起始
0x00 协议版本号 0-255
3 字节厂商代码
0000 0000 00控制码 1024个,0-100为系统定义的功能码,200-1023为应用码
10 0000 高1位发送方地址类型,0逻辑地址,1物理地址
01 0000 高2位接受方地址类型,0逻辑地址,1物理地址
00 1000 高3位是否需要接受确认,0不需要,1需要
00 0100 高4位数据是否加密,0不加密,1加密
00 0010 高5位,带4字节时间戳,从2000年起计,秒级
00 0001 高6位,是否有后续内容,0无1有

0000 0000 0数据帧序号 512个
0 一个字节:0结束,1有后续分包
00 0000 该该数据帧若分包,分包号 0-63,0表示不分包,1-63表示具体的分包序号,接收方需要接收到该控制码+序号的各个分包后组合好再使用
如果时间标识位为1则有这4字节时间 4字节时间戳

2字节逻辑地址或4字节物理地址

1字节 数据协议类型

2字节数据区长度

n字节数据

1字节 校验位

示例: 68 00[协议版本号0] 00 01 01[厂商代码] 00 00[0000 0000 0000 0000
控制码:0000 00 》 0,
发送方地址:逻辑地址
接收方地址:逻辑地址
接收确认:不需要
数据加密:不加密
] 00 00[0000 0000 0000 0000
帧序号:0000 0 》0
结束帧:0 》 0 结束
分包号:0 》 0 ] 01 0A[发送方逻辑地址] 05 08[接收方逻辑地址] 00[数据区数据协议:645?3761?....] 01 00[小端模式:00 01 数据区长度为1] 00[数据内容] 19[累加和校验位 从68后面开始计算到校验位前]

68 01[协议版本号 1] 00 01 01[厂商代码] 00 78[0000 0000 0111 1000
控制码二进制:00 0000 0001,控制码为1
发送方地址:1,物理地址,后续4字节
接收方地址:1,物理地址:后续4字节
是否需要确认:需要
是否加密:不加密] 78 56 34 12[4字节发送方物理地址] 98 76 54 32[4字节接收方物理地址] 00[数据区协议类型] 05 00[小端模式 数据区长度 00 05》5字节长度] 01 02 03 04 05[数据区:长度为5] 34[校验和]

68 00 00 01 01 00 02[控制码:0000 0000 0000 0010
控制码:0,逻辑地址,逻辑地址,无需确认,不加密,带时间戳] 01 00 00 00[换算:00 00 00 01,1秒
实际时间:2000-01-01 00:00:01]
加密算法:
3字节 厂商代码,协议中携带 3字节 厂商密码,出厂内置
3字节 加密后秘钥 = 代码 xor 密码 xor [年后2位+月,日+时,精确到5分钟的分]

如 代码:010101,密码:101010,时间:2019-09-28 12:21:00
为保证数据被正确解密传输,可以算3个秘钥尝试解密,即每次加密15分钟有效
0x010101 xor 0x101010 xor 0x284015 = 395104
0x010101 xor 0x101010 xor 0x284020 =
0x010101 xor 0x101010 xor 0x284025 =

对数据区加密算法
所有数据按每3个字节与秘钥进行xor运算,不足3字节部分按实际长度计算,
或 将3字节的秘钥长度填充至数据区长度,做xor运算
如 数据区 内容为 0x01890203

帮助文档,其它语言可以参考这个定义来翻译

/**
 * 帧序号缓存
 */
export declare var ID: number;
/**
 * 获取下一个ID
 */
export declare function get_next_id(): number;
/**
 * 错误类型
 */
export declare enum ErrorType {
    /**
     * 数据区太长
     */
    DATA_TOO_LARGE = "DataTooLarge",
    /**
     * CRC校验错误
     */
    CRC_ERROR = "CRCError",
    /**
     * 数据不足,该数据包未接受完成
     */
    NOT_ENOUGH = "NotEnough"
}
/**
 * 基础对象
 */
export declare class Base {
    /**
     * 版本号
     */
    Version: number;
    buf: Buffer;
    /**
     * 编码
     */
    encode(): Buffer;
    /**
     * CRC校验计算
     * @param buf
     */
    crc(pos?: number): number;
    /**
     * 解码
     */
    decode(): void;
}
/**
 * 地址类型
 */
export declare enum AddressType {
    /**
     * 逻辑地址,2字节
     */
    Logic = 0,
    /**
     * 物理地址,4字节
     */
    Phy = 1
}
/**
 * 地址对象
 */
export declare class Address {
    Type: AddressType;
    Value: string;
    constructor(Type?: AddressType, Value?: string);
}
/**
 * 0版本协议
 */
export declare class V0 extends Base {
    /**
     * 厂商代码
     */
    protected _CompanyID: string;
    /**
     * 厂商代码
     */
    CompanyID: string;
    /**
     * 控制码
     */
    Control: number;
    /**
     * 发送方地址
     */
    From: Address;
    /**
     * 接收方地址
     */
    To: Address;
    /**
     * 是否需要确认
     */
    Confirm: boolean;
    /**
     * 加密
     */
    Encrypted: boolean;
    /**
     * 是否携带4字节时间戳,从2010年起
     */
    WithTime: boolean;
    /**
     * 携带时间的情况下的时间值
     */
    Time: Date;
    /**
     * 帧序号
     */
    ID: number;
    /**
     * 第几帧
     */
    No: number;
    /**
     * 是否结束帧
     */
    End: boolean;
    DataType: number;
    Data: Buffer;
    encode(): Buffer;
    decode(): this;
}

使用实例

import { V0, ID, AddressType } from './'
import { buffer2hex } from '@ctsy/buffer'
let v = new V0()
v.Data = Buffer.from('0a1f5c1b', 'hex');
v.WithTime = true;
v.From.Value = '0508'
v.To.Value = '0A08'
v.From.Type = AddressType.Phy
v.Confirm = true;
v.Encrypted = true;
// v.WithTime = false;
v.DataType = 5
let hex1 = buffer2hex(v.encode());
v.decode()

let hex2 = buffer2hex(v.encode());
console.log(hex1); // 68 00 00 00 00 00 2E 80 00 D3 72 63 12 00 00 08 05 08 0A 05 04 00 0A 1F 5C 1B 30
console.log(hex2); // 68 00 00 00 00 00 2E 80 00 D3 72 63 12 00 00 08 05 08 0A 05 04 00 0A 1F 5C 1B 30
console.log(hex1 == hex2); // true ,测试通过
// debugger