控制协议
KY_SendIOCtrlToChannel
- 功能描述:
- 向设备发送指定Command的数据。需要在 KY_Connect 连线成功之后进行调用。设备回复参考 KY_registerSDKListener。
接口定义
public abstract void KY_SendIOCtrlToChannel(int channel, int type, byte[] data);
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| channel | int | 设备连线的channel,默认0 |
| type | int | command指令值 |
| data | byte[] | command对应指令的结构体数据 |
回调说明
暂无
返回码
暂无
代码示例
以下举例说明,在Android项目中,如何将bytes转成一个java对象:
private class People {
int age = 0; // 4 bytes means data[0] ~ data[3]
long birthday = 1612330883993L; // 8 bytes means data[4] ~ data[11]
String name = ""; // custom bytes ex: 32 bytes
}
/**
* byte to people
*
* @param data src bytes length & 44
* @return people
*/
private People byteToPeople(byte[] data) {
if (data.length < 44) {
return null;
}
People p = new People();
p.age = byteArrayToInt(data, 0);
p.birthday = byteArrayToLong(data, 4);
byte[] name = new byte[32];
System.arraycopy(data, 12, name, 0, 32);
p.name = new String(name);
return p;
}
private short byteArrayToShort(byte[] bytes, int beginPos) {
return (short) ((0xff & bytes[beginPos]) | ((0xff & bytes[beginPos + 1]) << 8));
}
private int byteArrayToInt(byte[] bytes, int beginPos) {
return (0xff & bytes[beginPos]) |
(0xff & bytes[beginPos + 1]) << 8 |
(0xff & bytes[beginPos + 2]) << 16 |
(0xff & bytes[beginPos + 3]) << 24;
}
private long byteArrayToLong(byte[] bytes, int beginPos) {
long l = 0;
for (int i = 0; i < 4; i++) {
l = l | ((0xffL & bytes[beginPos + i]) << (8 * i));
}
return l;
}
协议封装示例
定义协议及结构体
// APP发送Command获取灯控开关状态
#define IOTYPE_GET_LED_REQ 0x30000001
typedef struct {
unsigned int channel; // 当前通道号
unsigned char reserved[4]; // 保留位
} SMsgAVIoctrlGetLedReq;
// 设备端回复灯控开关状态
#define IOTYPE_GET_LED_RESP 0x30000002
typedef struct {
int result; // 0:成功, 其他失败
unsigned char isOnOff; // 0:开启; 1:关闭
unsigned char reserved[3]; // 保留位
} SMsgAVIoctrlGetLedResp;
结构体封装与发送
// 在结构体SMsgAVIoctrlGetLedReq中,因为int占4个字节,char占一个字节,
// 所以发送出去的bytes大小为4 + 1*4 = 8字节
byte[] request = new byte[8];
// 将int类型的channel数据转换为byte并复制数据到request数组中
byte[] channelBytes = Packet.intToByteArray_Little(channel); // 假设使用小端序
System.arraycopy(channelBytes, 0, request, 0, 4);
// 保留位可以不用处理,默认为0
// 将封装好的byte[]数据通过api发送给设备
camera.KY_SendIOCtrlToChannel(Camera.DEFAULT_AV_CHANNEL, IOTYPE_GET_LED_REQ, request);
注:`Packet.intToByteArray_Little` 是一个自定义的工具函数,用于将整数转换为小端序的字节数组。实际项目中需根据设备端约定的字节序(大端/小端)来实现。
数据接收与解析
camera.KY_registerSDKListener(new InterfaceCtrl.SimpleIRegisterKalaySDKListener() {
@Override
public void KY_DidReceiveIOCtrlWithUid(String uid, int channel, int type, byte[] data, int dataSize) {
// 判断是否是我们请求的LED状态回复
if (type == IOTYPE_GET_LED_RESP) {
// 在结构体SMsgAVIoctrlGetLedResp中,因为int占4个字节,char占一个字节,
// 所以接收到的bytes大小为4 + 1 + 1*3 = 8字节
// 1、解析result信息 (4字节)
int result = Packet.byteArrayToInt_Little(data, 0); // 假设使用小端序解析
// 2、解析isOnOff信息 (1字节)
int isOnOff = (int) data[4]; // 直接取第5个字节 (索引为4)
// 后续可以根据result和isOnOff的值进行UI更新等操作
if (result == 0) {
Log.d("LED Status", "Current state: " + (isOnOff == 0 ? "ON" : "OFF"));
} else {
Log.e("LED Status", "Failed to get status, error code: " + result);
}
}
}
});
注:`Packet.byteArrayToInt_Little` 同样需要根据约定的字节序来实现。`dataSize` 参数可以用来校验接收到的数据长度是否符合预期。
