KY_SendIOCtrlToChannel
功能描述:向設(shè)備發(fā)送指定Command的數(shù)據(jù)。需要在 KY_Connect 連線成功之后進(jìn)行調(diào)用。設(shè)備回復(fù)參考 KY_registerSDKListener。
接口定義
public abstract void KY_SendIOCtrlToChannel(int channel, int type, byte[] data);
參數(shù)說明
| 參數(shù) | 類型 | 說明 |
|---|---|---|
| channel | int | 設(shè)備連線的channel,默認(rèn)0 |
| type | int | command指令值 |
| data | byte[] | command對(duì)應(yīng)指令的結(jié)構(gòu)體數(shù)據(jù) |
回調(diào)說明
暫無
返回碼
暫無
代碼示例
以下舉例說明,在Android項(xiàng)目中,如何將bytes轉(zhuǎn)成一個(gè)java對(duì)象:
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;
}
協(xié)議封裝示例
定義協(xié)議及結(jié)構(gòu)體
// APP發(fā)送Command獲取燈控開關(guān)狀態(tài)
#define IOTYPE_GET_LED_REQ 0x30000001
typedef struct {
unsigned int channel; // 當(dāng)前通道號(hào)
unsigned char reserved[4]; // 保留位
} SMsgAVIoctrlGetLedReq;
// 設(shè)備端回復(fù)燈控開關(guān)狀態(tài)
#define IOTYPE_GET_LED_RESP 0x30000002
typedef struct {
int result; // 0:成功, 其他失敗
unsigned char isOnOff; // 0:開啟; 1:關(guān)閉
unsigned char reserved[3]; // 保留位
} SMsgAVIoctrlGetLedResp;
結(jié)構(gòu)體封裝與發(fā)送
// 在結(jié)構(gòu)體SMsgAVIoctrlGetLedReq中,因?yàn)閕nt占4個(gè)字節(jié),char占一個(gè)字節(jié),
// 所以發(fā)送出去的bytes大小為4 + 1*4 = 8字節(jié)
byte[] request = new byte[8];
// 將int類型的channel數(shù)據(jù)轉(zhuǎn)換為byte并復(fù)制數(shù)據(jù)到request數(shù)組中
byte[] channelBytes = Packet.intToByteArray_Little(channel); // 假設(shè)使用小端序
System.arraycopy(channelBytes, 0, request, 0, 4);
// 保留位可以不用處理,默認(rèn)為0
// 將封裝好的byte[]數(shù)據(jù)通過api發(fā)送給設(shè)備
camera.KY_SendIOCtrlToChannel(Camera.DEFAULT_AV_CHANNEL, IOTYPE_GET_LED_REQ, request);
注:`Packet.intToByteArray_Little` 是一個(gè)自定義的工具函數(shù),用于將整數(shù)轉(zhuǎn)換為小端序的字節(jié)數(shù)組。實(shí)際項(xiàng)目中需根據(jù)設(shè)備端約定的字節(jié)序(大端/小端)來實(shí)現(xiàn)。數(shù)據(jù)接收與解析
camera.KY_registerSDKListener(new InterfaceCtrl.SimpleIRegisterKalaySDKListener() {
@Override
public void KY_DidReceiveIOCtrlWithUid(String uid, int channel, int type, byte[] data, int dataSize) {
// 判斷是否是我們請(qǐng)求的LED狀態(tài)回復(fù)
if (type == IOTYPE_GET_LED_RESP) {
// 在結(jié)構(gòu)體SMsgAVIoctrlGetLedResp中,因?yàn)閕nt占4個(gè)字節(jié),char占一個(gè)字節(jié),
// 所以接收到的bytes大小為4 + 1 + 1*3 = 8字節(jié)
// 1、解析result信息 (4字節(jié))
int result = Packet.byteArrayToInt_Little(data, 0); // 假設(shè)使用小端序解析
// 2、解析isOnOff信息 (1字節(jié))
int isOnOff = (int) data[4]; // 直接取第5個(gè)字節(jié) (索引為4)
// 后續(xù)可以根據(jù)result和isOnOff的值進(jìn)行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` 同樣需要根據(jù)約定的字節(jié)序來實(shí)現(xiàn)。`dataSize` 參數(shù)可以用來校驗(yàn)接收到的數(shù)據(jù)長度是否符合預(yù)期。