
# PCP协议介绍
平台升级协议（PCP协议）规定了设备和平台之间升级的通信内容与格式。
本协议规定设备和IoT平台（以下简称"平台"）之间的应用层升级协议（简称"PCP协议"），用于实现设备的升级。
#### 通讯方式
1. PCP协议运行在应用层，底层可以是LwM2M/CoAP/MQTT或者其他非流式协议。
2. 由于PCP协议消息没有使用单独的端口号，并且不依赖于底层协议，为了和设备业务消息区分，PCP协议固定以0XFFFE作为起始字节。因此要求设备的业务消息的前两个字节不能是0XFFFE，更多细节参考附录[PCP消息识别]。
3. 本协议消息采用一问一答模式，所有请求消息都有一个响应消息。
 
#### 消息结构
| **字段名** | **字段类型**  | **描述和要求**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|:---|:---|:---|
| 起始标识    | WORD      | 起始标识，固定为0XFFFE。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| 版本号     | BYTE      | 高四位预留；低四位表示协议版本号，当前为1。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 消息码     | BYTE      | 标识物联网平台与设备之间的请求消息类型，应答消息的消息码和请求消息相同。消息码的定义为： - 0-18：预留消息码，暂未使用。  - 19：查询设备版本。  - 20：下载新版本软件包通知。  - 21：请求下载升级包。  - 22：上报升级包下载结果。  - 23：执行软件升级。  - 24：上报升级结果。  - 25-127：预留消息码，暂未使用。   |
| 校验码     | WORD      | 从起始标识到数据区的最后一个字节的CRC16校验值，计算前先把校验码字段置为0，计算完成后把结果写到校验码字段。 说明： CRC16算法：CRC16/CCITT x16+x12+x5+1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| 数据区长度   | WORD      | 数据区的长度。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| 数据区     | BYTE\[n\] | 可变长度，具体由各个指令定义，可参考下面介绍的各个指令对应的请求消息和应答消息定义。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   
#### 数据类型
| **数据类型**  | **描述**    |
|:---|:---|
| BYTE      | 无符号一字节整数  |
| WORD      | 无符号二字节整数  |
| DWORD     | 无符号四字节整数  |
| BYTE\[n\] | n字节的十六进制数 |
| STRING    | 字符串       |
   
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
本协议采用网络序来传输WORD和DWORD。
#### 查询设备版本消息
请求消息：
方向：平台-\>设备
| **字段** | **数据类型** | **描述及要求** |
|:---|:---|:---|
| 无数据区                        |||
   
响应消息：
方向：设备-\>平台
| **字段** | **数据类型**   | **描述及要求**                        |
|:---|:---|:---|
| 结果码    | BYTE       | "0X00"处理成功                       |
| 当前版本号  | BYTE\[16\] | 当前版本号，由ASCII字符组成，位数不足时，后补"0X00"。 |
   
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
- 正常处理：平台根据版本号判断设备是否需要升级，如果需要，下发请求升级。
- 异常处理：如果响应超时，平台中止升级任务。
 
#### 新版本通知消息
请求消息：
方向：平台-\>设备
| **字段**  | **数据类型**   | **描述及要求**                        |
|:---|:---|:---|
| 目的版本号   | BYTE\[16\] | 目的版本号，由ASCII字符组成，位数不足时，后补"0X00"。 |
| 升级包分片大小 | WORD       | 每个分片的大小                          |
| 升级包分片总数 | WORD       | 升级包分片总数                          |
| 升级包校验码  | WORD       | 固定为：0000                         |
   
应答消息：
方向：设备-\>平台
| **字段** | **数据类型** | **描述及要求**                                                                                                                                                                                                                                                                                                                                                                                                                             |
|:---|:---|:---|
| 结果码    | BYTE     | "0X00"允许升级 "0X01"设备使用中 "0X02"信号质量差 "0X03"已经是最新版本 "0X04"电量不足 "0X05"剩余空间不足 "0X09"内存不足 "0X7F"内部异常 |
   
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
- 正常处理：如果设备不允许升级，平台中止升级任务。
- 异常处理：如果响应超时，而且没收到请求升级包消息，平台中止升级任务。
 
#### 请求消息包消息
请求消息：
方向：设备-\>平台
| **字段** | **数据类型**   | **描述及要求**                                                                              |
|:---|:---|:---|
| 目的版本号  | BYTE\[16\] | 目的版本号，由ASCII字符组成，位数不足时，后补"0X00"。                                                       |
| 分片序号   | WORD       | 表示请求获取的分片序号，从0开始计算，分片的总数为软件包大小除以每个分片的大小并向上取整获得。设备可以保存已经收到的分片，下次直接从缺失的分片开始请求，达到断点续传的效果。 |
   
响应消息：
方向：平台-\>设备
| **字段** | **数据类型**  | **描述及要求**                                                                                                                         |
|:---|:---|:---|
| 结果码    | BYTE      | 0X00处理成功。 0X80升级任务不存在。 0X81指定的分片不存在。 |
| 分片序号   | WORD      | 表示返回的分片序号。                                                                                                                        |
| 分片数据   | BYTE\[n\] | 分片的内容，n为实际的分片大小。如果结果码不为0，则不带此字段。                                                                                                  |
   
#### 上报升级包下载状态消息
请求消息：
方向：设备-\>平台
| **字段** | **数据类型** | **描述及要求**                                                                                                                                                                                                                                                |
|:---|:---|:---|
| 下载状态   | BYTE     | 0X00下载成功。 0X05剩余空间不足。 0X06下载超时。 0X07升级包校验失败。 0X08升级包类型不支持。 |
   
响应消息：
方向：平台-\>设备
| **字段** | **数据类型** | **描述及要求**                                                             |
|:---|:---|:---|
| 结果码    | BYTE     | 0X00处理成功。 0X80升级任务不存在。 |
   
#### 执行升级消息
请求消息：
方向：平台-\>设备
| **字段** | **数据类型** | **描述及要求** |
|:---|:---|:---|
| 无数据区                        |||
   
响应消息：
方向：设备-\>平台
| **字段** | **数据类型** | **描述及要求**                                                                                                                                                                                                                                             |
|:---|:---|:---|
| 结果码    | BYTE     | 0X00处理成功。 0X01设备使用中。 0X04电量不足。 0X05剩余空间不足。 0X09内存不足。 |
   
#### 上报升级结果消息
请求消息：
方向：设备-\>平台
| **字段** | **数据类型**   | **描述及要求**                                                                                                                                                                                                                                                                                                                                                           |
|:---|:---|:---|
| 结果码    | BYTE       | 0X00升级成功。 0X01设备使用中。 0X04电量不足。 0X05剩余空间不足。 0X09内存不足。 0X0A安装升级包失败。 0X7F内部异常。 |
| 当前版本号  | BYTE\[16\] | 设备当前版本号。                                                                                                                                                                                                                                                                                                                                                            |
   
响应消息：
方向：平台-\>设备
| **字段** | **数据类型** | **描述及要求**                                                               |
|:---|:---|:---|
| 结果码    | BYTE     | 0X00处理成功。 0X80升级任务不存在。 |
   
 #### PCP消息识别
由于PCP协议消息和设备业务消息共用一个端口和URL通讯，平台收到设备的消息时，按照如下步骤判断是PCP协议消息还是业务消息：
1. 检查设备是否支持软件升级（根据设备profile的omCapability.upgradeCapability定义），如果不支持，则认为是业务消息。
2. 检查设备软件升级协议是否是PCP，如果不是，则认为是业务消息。
3. 检查消息前两个字节是否为0XFFFE，如果不是，则认为是业务消息。
4. 检查版本号是否合法，如果不合法，则认为是业务消息。
5. 检查消息码是否合法，如果不合法，则认为是业务消息。
6. 检查校验码是否正确，如果不正确，则认为是业务消息。
7. 检查数据区长度是否正确，如果不正确，则认为是业务消息。
8. 如果以上检查都通过，认为是PCP协议消息。
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
对设备的要求：需要设备保证业务消息的起始字节不是0XFFFE。
