initial checkin of some c-language code to parse Sierra Wireless HAPC
This commit is contained in:
commit
a915c1c944
|
@ -0,0 +1,17 @@
|
|||
OSMO_CFLAGS:=`pkg-config --cflags libosmocore`
|
||||
OSMO_LDFLAGS:=`pkg-config --libs libosmocore`
|
||||
|
||||
CFLAGS=-g -Wall $(OSMO_CFLAGS)
|
||||
LDFLAGS=$(OSMO_LDFLAGS)
|
||||
|
||||
all: hapc_test
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
hapc_test: hapc_test.o hapc_frame.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f hapc_test *.o || true
|
|
@ -0,0 +1,49 @@
|
|||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "hapc_frame.h"
|
||||
|
||||
const struct value_string hapc_flow_names[30] = {
|
||||
{ HAPC_FLOW_STATUS, "status" },
|
||||
{ HAPC_FLOW_DEBUG, "debug" },
|
||||
{ HAPC_FLOW_INIT, "init" },
|
||||
{ HAPC_FLOW_WI2C, "wi2c" },
|
||||
{ HAPC_FLOW_TRACE, "trace" },
|
||||
{ HAPC_FLOW_RI2C, "ri2c" },
|
||||
{ HAPC_FLOW_MSG, "msg" },
|
||||
{ HAPC_FLOW_GDB, "gdb" },
|
||||
{ HAPC_FLOW_READ, "read" },
|
||||
{ HAPC_FLOW_READ_PACK, "read-pack" },
|
||||
{ HAPC_FLOW_WRITE, "write" },
|
||||
{ HAPC_FLOW_OBJECT, "object" },
|
||||
{ HAPC_FLOW_RESET, "reset" },
|
||||
{ HAPC_FLOW_PROTOCOL, "protocol" },
|
||||
{ HAPC_FLOW_EEPROM, "eeprom" },
|
||||
{ HAPC_FLOW_EEPROM2, "eeprom2" },
|
||||
{ HAPC_FLOW_FS, "filesystem" },
|
||||
{ HAPC_FLOW_MSG2, "msg2" },
|
||||
{ HAPC_FLOW_KBD, "kbd" },
|
||||
{ HAPC_FLOW_WATCH, "watch" },
|
||||
{ HAPC_FLOW_DIAG, "diag" },
|
||||
{ HAPC_FLOW_RTK, "rtk" },
|
||||
{ HAPC_FLOW_RPC2, "rpc2" },
|
||||
{ HAPC_FLOW_PROD, "prod" },
|
||||
{ HAPC_FLOW_RADIO, "radio" },
|
||||
{ HAPC_FLOW_AT, "at" },
|
||||
{ HAPC_FLOW_TRACE_TSTP, "trace" },
|
||||
{ HAPC_FLOW_DUMP, "dump" },
|
||||
{ HAPC_FLOW_ATENCAP, "atencap" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const struct value_string hapc_obj_status_names[9] = {
|
||||
{ HAPC_OBJ_READ_REQ, "read-req" },
|
||||
{ HAPC_OBJ_READ_RESP, "read-resp" },
|
||||
{ HAPC_OBJ_WRITE_REQ, "write-req" },
|
||||
{ HAPC_OBJ_WRITE_RESP, "write-resp" },
|
||||
{ HAPC_OBJ_ID_LIST_REQ, "id-list-req" },
|
||||
{ HAPC_OBJ_ID_LIST_RESP,"id-list-resp" },
|
||||
{ HAPC_OBJ_DEL_REQ, "delete-req" },
|
||||
{ HAPC_OBJ_DEL_RESP, "delete-resp" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum hapc_flow_id {
|
||||
HAPC_FLOW_STATUS = 0x00,
|
||||
HAPC_FLOW_DEBUG = 0x01,
|
||||
HAPC_FLOW_INIT = 0x02,
|
||||
HAPC_FLOW_WI2C = 0x03,
|
||||
HAPC_FLOW_TRACE = 0x04,
|
||||
HAPC_FLOW_RI2C = 0x05,
|
||||
HAPC_FLOW_MSG = 0x06,
|
||||
HAPC_FLOW_GDB = 0x07,
|
||||
HAPC_FLOW_READ = 0x08,
|
||||
HAPC_FLOW_READ_PACK = 0x09,
|
||||
HAPC_FLOW_WRITE = 0x0A,
|
||||
HAPC_FLOW_OBJECT = 0x0B,
|
||||
HAPC_FLOW_RESET = 0x0C,
|
||||
HAPC_FLOW_PROTOCOL = 0x0D,
|
||||
HAPC_FLOW_EEPROM = 0x0E,
|
||||
HAPC_FLOW_EEPROM2 = 0x0F,
|
||||
HAPC_FLOW_FS = 0x10,
|
||||
HAPC_FLOW_MSG2 = 0x11,
|
||||
HAPC_FLOW_KBD = 0x12,
|
||||
HAPC_FLOW_WATCH = 0x14,
|
||||
HAPC_FLOW_DIAG = 0x16,
|
||||
HAPC_FLOW_RTK = 0x18,
|
||||
HAPC_FLOW_RPC2 = 0x19,
|
||||
HAPC_FLOW_PROD = 0x1A,
|
||||
HAPC_FLOW_RADIO = 0x1C,
|
||||
HAPC_FLOW_AT = 0x1D,
|
||||
HAPC_FLOW_TRACE_TSTP = 0x1E,
|
||||
HAPC_FLOW_DUMP = 0x20,
|
||||
HAPC_FLOW_ATENCAP = 0x9F,
|
||||
};
|
||||
|
||||
/* HAPC frame format:
|
||||
* first byte: 0xAA
|
||||
* 2nd byte: LSB of length
|
||||
* 3rd byte: MSB of length (3 lower bits) + flow-id (5 upper bits)
|
||||
* N bytes payload
|
||||
* 2 bytes of checksum
|
||||
*/
|
||||
|
||||
/* common HAPC header */
|
||||
struct hapc_msg_hdr {
|
||||
uint8_t aa;
|
||||
uint8_t lsb_len;
|
||||
uint8_t msb_len:3,
|
||||
flow_id:5;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define hapc_payload_len(x) ((x)->msb_len << 8 | (x)->lsb_len)
|
||||
|
||||
static inline uint8_t hapc_frame_csum(const struct hapc_msg_hdr *mh)
|
||||
{
|
||||
unsigned int payload_len = hapc_payload_len(mh);
|
||||
|
||||
return mh->data[payload_len];
|
||||
}
|
||||
|
||||
enum hapc_obj_status_id {
|
||||
HAPC_OBJ_READ_REQ = 0x01,
|
||||
HAPC_OBJ_READ_RESP = 0x02,
|
||||
HAPC_OBJ_READ_RESP2 = 0x82,
|
||||
HAPC_OBJ_WRITE_REQ = 0x03,
|
||||
HAPC_OBJ_WRITE_RESP = 0x04,
|
||||
HAPC_OBJ_WRITE_RESP2 = 0x84,
|
||||
HAPC_OBJ_ID_LIST_REQ = 0x05,
|
||||
HAPC_OBJ_ID_LIST_RESP = 0x06,
|
||||
HAPC_OBJ_ID_LIST_RESP2 = 0x86,
|
||||
HAPC_OBJ_DEL_REQ = 0x07,
|
||||
HAPC_OBJ_DEL_RESP = 0x08,
|
||||
HAPC_OBJ_DEL_RESP2 = 0x88,
|
||||
};
|
||||
|
||||
/* uses HAPC_FLOW_OBJECT */
|
||||
struct hapc_flash_obj_hdr {
|
||||
uint32_t obj_id;
|
||||
uint32_t mask;
|
||||
uint16_t total_size;
|
||||
uint16_t block_size;
|
||||
uint16_t offset_block;
|
||||
uint8_t obj_status;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* uses HAPC_FLOW_READ_PACK */
|
||||
struct hapc_ram_read {
|
||||
uint32_t start_addr;
|
||||
uint16_t len;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* uses HAPC_FLOW_WRITE */
|
||||
struct hapc_ram_write {
|
||||
uint8_t pad0[8];
|
||||
uint32_t start_addr;
|
||||
uint16_t len;
|
||||
uint8_t pad1[2];
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
extern const struct value_string hapc_flow_names[30];
|
||||
const struct value_string hapc_obj_status_names[9];
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "hapc_frame.h"
|
||||
|
||||
const uint8_t test_frame[] = { 0xAA, 0x10, 0x58, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13 };
|
||||
const uint8_t resp_frame[] = { 0xAA, 0x20, 0x58, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x82,
|
||||
0x18, 0x81, 0x00, 0x00, 0x20, 0x03, 0x00, 0x09, 0x08, 0x91, 0x94, 0x58, 0x16, 0x89, 0x63, 0x07, 0xf2, 0x0d };
|
||||
|
||||
static void dump_frame_object(const struct hapc_flash_obj_hdr *foh, unsigned int len)
|
||||
{
|
||||
unsigned int payload_len = len - sizeof(*foh);
|
||||
printf("obj_id=0x%08x, mask=0x%08x, total_size=%d, block_size=%d, offset_block=%d, status=%s, data=%s\n",
|
||||
foh->obj_id, foh->mask, foh->total_size, foh->block_size, foh->offset_block,
|
||||
get_value_string(hapc_obj_status_names, foh->obj_status & 0x7f), osmo_hexdump(foh->data, payload_len));
|
||||
}
|
||||
|
||||
static uint8_t compute_checksum(const uint8_t *data, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
checksum += data[i];
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
void dump_frame(const struct hapc_msg_hdr *hdr)
|
||||
{
|
||||
unsigned int len = hapc_payload_len(hdr);
|
||||
|
||||
printf("len=%4u, flow_id=%s: ", len,
|
||||
get_value_string(hapc_flow_names, hdr->flow_id));
|
||||
|
||||
printf("checksum=0x%02x, computed=0x%02x\n",
|
||||
hapc_frame_csum(hdr), compute_checksum((const uint8_t *) hdr, sizeof(*hdr)+len));
|
||||
|
||||
switch (hdr->flow_id) {
|
||||
case HAPC_FLOW_OBJECT:
|
||||
dump_frame_object((const struct hapc_flash_obj_hdr *) hdr->data, len - sizeof(*hdr));
|
||||
break;
|
||||
default:
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const struct hapc_msg_hdr *hdr = (const struct hapc_msg_hdr *) test_frame;
|
||||
dump_frame(hdr);
|
||||
|
||||
hdr = (const struct hapc_msg_hdr *) resp_frame;
|
||||
dump_frame(hdr);
|
||||
}
|
Loading…
Reference in New Issue