GAIA全称:Generic Application Interface Architecture,实现了端到端,主机无关的生态系统,支持主机应用程序访问设备功能
底层的数据包由8个字节组成,这个框架支持基于ble上的GATT包传输或者基于SPP上的 stream传输。长度超过8位的数字字段首先打包最重要的八位字节。 文本字符串使用UTF-8编码。设备既可以是GAIA的server端,也可以是client端。
格式如下图:
1.vendor ID:为供应商ID,高通的ID为 0x000a
2.command ID:为命令本身的ID
3.Payload :为命令需要传输的信息,大小取决于命令的需求
格式如下图:
1.Start:一个固定的8位字节,为:0xff
2.Version:8字节,指示当期协议的版本,当前为1
3.Flags:8字节,BIT[0]设置为1的话,frame尾部会存在一个8字节的check,为0的话就是不check,BIT[1:7]
保留字段,必须全部为0
4.Length:payload的长度,取决于实际所需的大小
5.vendor ID,command ID,和Payload 和pack传输一样
6.check:8字节,如果存在该字段,则使用该值与前面的所有的8字节进行异或,check value=前面所有8字节的和
命令编码表:
代码实现如下:
static uint16 build_packet(uint8 *buffer, uint8 flags,
uint16 vendor_id, uint16 command_id, uint16 status,
uint8 payload_length, uint8 *payload)
{
uint8 *data = buffer;
uint16 packet_length = GAIA_OFFS_PAYLOAD + payload_length;
if (status != GAIA_STATUS_NONE)
++packet_length;
if (flags & GAIA_PROTOCOL_FLAG_CHECK)
++packet_length;
if (packet_length > GAIA_MAX_PACKET)
return 0;
/* Build the header. It's that diagram again ...
* 0 bytes 1 2 3 4 5 6 7 8 9 len+8 len+9
* +--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--/ /---+ +--------+
* | SOF |VERSION | FLAGS | LENGTH | VENDOR ID | COMMAND ID | | PAYLOAD ... | | CHECK |
* +--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--/ /---+ +--------+
*/
*data++ = GAIA_SOF;
*data++ = GAIA_VERSION;
*data++ = flags;
*data++ = payload_length;
*data++ = HIGH(vendor_id);
*data++ = LOW(vendor_id);
*data++ = HIGH(command_id);
*data++ = LOW(command_id);
if (status != GAIA_STATUS_NONE)
{
/* Insert status-cum-event byte and increment payload length */
*data++ = status;
++buffer[GAIA_OFFS_PAYLOAD_LENGTH];
}
/* Copy in the payload */
while (payload_length--)
*data++ = *payload++;
if (flags & GAIA_PROTOCOL_FLAG_CHECK)
{
/* Compute the checksum */
uint8 check = 0;
data = buffer;
while (--packet_length)
check ^= *data++;
*data++ = check;
}
return data - buffer;
}
每个命令都应该被确认,应答包的结构和命令包的结构相同,commend ID字段为接收到的命令ID最高位设置为1,example:命令为:0x0001,二进制为:0000 0000 0000 0001 应答包的commend id:二进制为:1000 0000 0000 0001,十六进制:0x8001。
代码:
static void send_ack_16(gaia_transport *transport, uint16 vendor_id, uint16 command_id,
uint8 status, uint16 payload_length, uint16 *payload)
{
#ifdef GAIA_TRANSPORT_GATT
if (transport->type == gaia_transport_gatt)
{
gaiaTransportGattSend(transport, vendor_id, command_id | GAIA_ACK_MASK, status, payload_length, payload, TRUE);
}
else
#endif
{
uint16 packet_length;
uint8 *packet;
uint8 flags = transport->flags;
packet_length = GAIA_OFFS_PAYLOAD + 2 * payload_length + 1;
if (flags & GAIA_PROTOCOL_FLAG_CHECK)
++packet_length;
packet = malloc(packet_length);
if (packet)
{
packet_length = build_packet_16(packet, flags, vendor_id, command_id | GAIA_ACK_MASK,
status, payload_length, payload);
send_packet(NULL, transport, packet_length, packet);
}
}
}
每个ACK的Payload字段的第一个8字节,为状态码,用来表示的命令的成功接收或者失败的原因,
编码图如下:
相关文档地址:https://download.csdn.net/download/qq_31208451/10696288