mirror of
https://github.com/zhaojh329/rtty.git
synced 2026-02-27 09:53:17 +08:00
144 lines
2.4 KiB
C
Executable File
144 lines
2.4 KiB
C
Executable File
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <libubox/ulog.h>
|
|
#include <libubox/utils.h>
|
|
|
|
#include "protocol.h"
|
|
|
|
struct rtty_packet *rtty_packet_new(int size)
|
|
{
|
|
struct rtty_packet *pkt = calloc(1, sizeof(struct rtty_packet));
|
|
if (!pkt) {
|
|
ULOG_ERR("malloc failed:%s\n", strerror(errno));
|
|
return NULL;
|
|
}
|
|
|
|
pkt->data = malloc(size);
|
|
if (!pkt->data) {
|
|
free(pkt);
|
|
ULOG_ERR("malloc failed:%s\n", strerror(errno));
|
|
return NULL;
|
|
}
|
|
|
|
pkt->size = size;
|
|
|
|
return pkt;
|
|
}
|
|
|
|
int rtty_packet_grow(struct rtty_packet *pkt, int size)
|
|
{
|
|
uint8_t *data = realloc(pkt->data, pkt->size + size);
|
|
if (!data) {
|
|
ULOG_ERR("rtty_packet_grow failed:%s\n", strerror(errno));
|
|
return -1;
|
|
}
|
|
pkt->data = data;
|
|
pkt->size += size;
|
|
return 0;
|
|
}
|
|
|
|
void rtty_packet_free(struct rtty_packet *pkt)
|
|
{
|
|
if (pkt) {
|
|
if (pkt->data)
|
|
free(pkt->data);
|
|
free(pkt);
|
|
}
|
|
}
|
|
|
|
int rtty_packet_init(struct rtty_packet *pkt, enum rtty_packet_type type)
|
|
{
|
|
uint8_t *data = pkt->data;;
|
|
|
|
if (pkt->size < 2 || !data) {
|
|
ULOG_ERR("rtty_packet_init failed\n");
|
|
return -1;
|
|
}
|
|
|
|
data[0] = RTTY_PROTOCOL_VERSION;
|
|
data[1] = type;
|
|
pkt->len = 2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtty_attr_put(struct rtty_packet *pkt, enum rtty_attr_type type, uint16_t len, const void *data)
|
|
{
|
|
uint8_t *p = pkt->data + pkt->len;
|
|
|
|
if (pkt->len + len + 3 > pkt->size) {
|
|
if (rtty_packet_grow(pkt, len) < 0) {
|
|
ULOG_ERR("rtty_packet_grow failed\n");
|
|
return -1;
|
|
}
|
|
p = pkt->data + pkt->len;
|
|
}
|
|
|
|
pkt->len += 3 + len;
|
|
|
|
p[0] = type;
|
|
|
|
memcpy(p + 3, data, len);
|
|
|
|
len = htons(len);
|
|
memcpy(p + 1, &len, sizeof(len));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rtty_packet_parse(const uint8_t *data, int pktlen, struct rtty_packet_info *pi)
|
|
{
|
|
const uint8_t *p;
|
|
|
|
memset(pi, 0, sizeof(struct rtty_packet_info));
|
|
|
|
pi->version = data[0];
|
|
pi->type = data[1];
|
|
|
|
p = data + 2;
|
|
|
|
while(p < data + pktlen) {
|
|
uint8_t type;
|
|
uint16_t len;
|
|
|
|
type = p[0];
|
|
memcpy(&len, p + 1, 2);
|
|
|
|
len = ntohs(len);
|
|
|
|
p += 3;
|
|
|
|
/* Check if len is invalid */
|
|
if (p + len > data + pktlen)
|
|
break;
|
|
|
|
switch (type) {
|
|
case RTTY_ATTR_SID:
|
|
pi->sid = (const char *)p;
|
|
break;
|
|
case RTTY_ATTR_DATA:
|
|
pi->data = p;
|
|
pi->data_len = len;
|
|
break;
|
|
case RTTY_ATTR_CODE:
|
|
pi->code = *p;
|
|
break;
|
|
case RTTY_ATTR_NAME:
|
|
pi->name = (const char *)p;
|
|
break;
|
|
case RTTY_ATTR_SIZE:
|
|
memcpy(&pi->size, p, 4);
|
|
pi->size = ntohl(pi->size);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
p += len;
|
|
}
|
|
|
|
return 0;
|
|
} |