Browse Source

Add mp4 parser

master
Jeroen Vreeken 3 years ago
parent
commit
8bae33a42e
13 changed files with 380 additions and 98 deletions
  1. +1
    -1
      Makefile.am
  2. +5
    -3
      dml_stream_client_codec2.c
  3. +80
    -17
      dml_stream_client_simple.c
  4. +6
    -0
      dml_stream_client_simple.h
  5. +13
    -24
      dml_streamer.c
  6. +35
    -0
      fileparse.h
  7. +162
    -0
      isom.c
  8. +29
    -0
      isom.h
  9. +13
    -11
      matroska.c
  10. +4
    -10
      matroska.h
  11. +10
    -8
      ogg.c
  12. +4
    -10
      ogg.h
  13. +18
    -14
      trx_dv.c

+ 1
- 1
Makefile.am View File

@ -62,7 +62,7 @@ dml_trx_LDADD = libdml.la
dml_trx_LDFLAGS = -lasound -lcodec2 -leth_ar -lm
dml_streamer_SOURCES = $(DML_SRCS) dml_streamer.c matroska.c ogg.c
dml_streamer_SOURCES = $(DML_SRCS) dml_streamer.c matroska.c ogg.c isom.c
dml_streamer_LDADD = libdml.la


+ 5
- 3
dml_stream_client_codec2.c View File

@ -272,9 +272,11 @@ int main(int argc, char **argv)
return -1;
}
dml_str_id(req_id, req_id_str);
dss = dml_stream_client_simple_create(server, req_id, NULL, data_cb, true);
if (dml_str_id(req_id, req_id_str)) {
dss = dml_stream_client_simple_search_create(server, NULL, req_id_str, NULL, DML_MIME_DV_C2, NULL, data_cb, true);
} else {
dss = dml_stream_client_simple_create(server, req_id, NULL, data_cb, true);
}
if (!dss) {
printf("Could not create stream\n");
return -1;


+ 80
- 17
dml_stream_client_simple.c View File

@ -39,11 +39,16 @@ struct dml_stream_client_simple {
struct dml_client *client;
struct dml_connection *dc;
bool found_req_id;
uint8_t req_id[DML_ID_SIZE];
bool verify;
void *arg;
int (*data_cb)(void *arg, void *data, size_t datasize);
char *name;
char *alias;
char *mime;
};
static int keepalive_cb(void *arg)
@ -54,8 +59,12 @@ static int keepalive_cb(void *arg)
return 0;
}
fprintf(stderr, "No data for %d seconds, send keepalive connect\n", DML_STREAM_CLIENT_SIMPLE_KEEPALIVE);
dml_packet_send_connect(dss->dc, dss->req_id, DML_PACKET_DATA);
if (dss->found_req_id) {
fprintf(stderr, "No data for %d seconds, send keepalive connect\n", DML_STREAM_CLIENT_SIMPLE_KEEPALIVE);
dml_packet_send_connect(dss->dc, dss->req_id, DML_PACKET_DATA);
} else {
//TODO What is the best way to trigger discovery?
}
dml_poll_timeout(dss,
&(struct timespec){ DML_STREAM_CLIENT_SIMPLE_KEEPALIVE, 0});
@ -70,12 +79,50 @@ static void rx_packet(struct dml_connection *dc, void *arg,
// fprintf(stderr, "got id: %d\n", id);
switch(id) {
case DML_PACKET_DESCRIPTION: {
if (!dml_stream_update_description(data, len, NULL))
case DML_PACKET_ROUTE: {
if (dss->found_req_id)
break;
fprintf(stderr, "Request certificate\n");
dml_packet_send_req_certificate(dc, dss->req_id);
uint8_t id[DML_ID_SIZE];
uint8_t hops;
dml_packet_parse_route(data, len, id, &hops);
if (hops < 255) {
dml_packet_send_req_description(dc, id);
}
}
case DML_PACKET_DESCRIPTION: {
if (!dss->found_req_id) {
uint8_t desc_id[DML_ID_SIZE];
uint8_t version;
uint32_t bps;
char *mime, *name, *alias, *description;
dml_packet_parse_description(data, len, desc_id, &version,
&bps, &mime, &name, &alias, &description);
bool found = true;
if (dss->name && strcmp(name, dss->name))
found = false;
if (dss->alias && strcmp(alias, dss->alias))
found = false;
if (dss->mime && strcmp(mime, dss->mime))
found = false;
if (found) {
dss->found_req_id = true;
memcpy(dss->req_id, desc_id, DML_ID_SIZE);
}
}
if (dss->found_req_id) {
if (!dml_stream_update_description(data, len, NULL))
break;
fprintf(stderr, "Request certificate\n");
dml_packet_send_req_certificate(dc, dss->req_id);
}
break;
}
case DML_PACKET_CERTIFICATE: {
@ -221,16 +268,12 @@ static void client_connect(struct dml_client *client, void *arg)
fd = dml_client_fd_get(client);
dc = dml_connection_create(fd, arg, rx_packet, client_connection_close);
dml_packet_send_hello(dc, DML_PACKET_HELLO_LEAF, "dml_stream_client " DML_VERSION);
dml_packet_send_req_description(dc, dss->req_id);
struct dml_stream *ds = dml_stream_by_id_alloc(dss->req_id);
uint64_t timestamp;
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
timestamp = (uint64_t)(ts.tv_sec - DML_TIME_MARGIN) << 16;
dml_stream_timestamp_set(ds, timestamp);
if (dss->found_req_id) {
dml_packet_send_hello(dc, DML_PACKET_HELLO_LEAF, "dml_stream_client " DML_VERSION);
dml_packet_send_req_description(dc, dss->req_id);
} else {
dml_packet_send_hello(dc, DML_PACKET_HELLO_UPDATES, "dml_stream_client " DML_VERSION);
}
dss->dc = dc;
}
@ -240,6 +283,16 @@ struct dml_stream_client_simple *dml_stream_client_simple_create(
void *arg,
int (*data_cb)(void *arg, void *, size_t),
bool verify)
{
return dml_stream_client_simple_search_create(
server, req_id, NULL, NULL, NULL, arg, data_cb, verify);
}
struct dml_stream_client_simple *dml_stream_client_simple_search_create(
char *server, uint8_t req_id[DML_ID_SIZE], char *name, char *alias, char *mime,
void *arg,
int (*data_cb)(void *arg, void *, size_t),
bool verify)
{
struct dml_stream_client_simple *dss;
struct dml_client *client;
@ -248,7 +301,17 @@ struct dml_stream_client_simple *dml_stream_client_simple_create(
if (!dss)
goto err_calloc;
memcpy(dss->req_id, req_id, DML_ID_SIZE);
if (req_id) {
memcpy(dss->req_id, req_id, DML_ID_SIZE);
dss->found_req_id = true;
} else {
if (name)
dss->name = strdup(name);
if (alias)
dss->alias = strdup(alias);
if (mime)
dss->mime = strdup(mime);
}
dss->data_cb = data_cb;
dss->verify = verify;
dss->arg = arg;


+ 6
- 0
dml_stream_client_simple.h View File

@ -26,5 +26,11 @@ struct dml_stream_client_simple *dml_stream_client_simple_create(
int (*data_cb)(void *arg, void *, size_t),
bool verify);
struct dml_stream_client_simple *dml_stream_client_simple_search_create(
char *server, uint8_t req_id[DML_ID_SIZE], char *name, char *alias, char *mime,
void *arg,
int (*data_cb)(void *arg, void *, size_t),
bool verify);
#endif /* _INCLUDE_DML_STREAM_CLIENT_SIMPLE_H_ */

+ 13
- 24
dml_streamer.c View File

@ -25,6 +25,7 @@
#include "dml_config.h"
#include "ogg.h"
#include "isom.h"
#include "matroska.h"
#include <stdlib.h>
@ -190,9 +191,9 @@ ssize_t data_cb(void *data, size_t size)
return size;
}
int trigger_cb_m(enum matroska_trigger trig)
int trigger_cb(enum fileparse_trigger trig)
{
if (trig == MATROSKA_TRIGGER_HEADER_COMPLETE) {
if (trig == FILEPARSE_TRIGGER_HEADER_COMPLETE) {
header_done = true;
} else {
send_data(pkt_data, pkt_size);
@ -204,22 +205,8 @@ int trigger_cb_m(enum matroska_trigger trig)
return 0;
}
int trigger_cb_o(enum ogg_trigger trig)
{
if (trig == OGG_TRIGGER_HEADER_COMPLETE) {
header_done = true;
} else {
send_data(pkt_data, pkt_size);
free(pkt_data);
pkt_data = NULL;
pkt_size = 0;
}
return 0;
}
struct ogg *ogg;
struct matroska *mat;
struct fileparse *fileparse;
int (*parse)(struct fileparse *ogg, void *buffer, size_t size);
int fd_in(void *arg)
{
@ -229,10 +216,7 @@ int fd_in(void *arg)
r = read(fd_ogg, buffer, sizeof(buffer));
if (r > 0) {
if (mat)
return matroska_parse(mat, buffer, r);
else
return ogg_parse(ogg, buffer, r);
return parse(fileparse, buffer, r);
}
return 0;
@ -247,6 +231,7 @@ int main(int argc, char **argv)
char *key;
char *server;
bool use_ogg = true;
bool use_isom = false;
if (argc > 1)
file = argv[1];
@ -258,6 +243,8 @@ int main(int argc, char **argv)
mime = dml_config_value("mime", NULL, "application/ogg");
if (strcmp(mime + strlen(mime) - 3, "ogg"))
use_ogg = false;
if (!strcmp(mime + strlen(mime) - 3, "mp4"))
use_isom = true;
name = dml_config_value("name", NULL, "example");
alias = dml_config_value("alias", NULL, "");
description = dml_config_value("description", NULL, "Test stream");
@ -293,9 +280,11 @@ int main(int argc, char **argv)
if (use_ogg)
ogg = ogg_create(data_cb, trigger_cb_o);
fileparse = ogg_create(data_cb, trigger_cb, &parse);
else if (use_isom)
fileparse = isom_create(data_cb, trigger_cb, &parse);
else
mat = matroska_create(data_cb, trigger_cb_m);
fileparse = matroska_create(data_cb, trigger_cb, &parse);
dml_poll_add(&fd_ogg, fd_in, NULL, NULL);
dml_poll_fd_set(&fd_ogg, 0);


+ 35
- 0
fileparse.h View File

@ -0,0 +1,35 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INCLUDE_FILEPARSE_H_
#define _INCLUDE_FILEPARSE_H_
struct fileparse;
enum fileparse_trigger {
FILEPARSE_TRIGGER_HEADER_COMPLETE,
FILEPARSE_TRIGGER_PACKET_COMPLETE,
};
struct fileparse *fileparse_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *mat, void *buffer, size_t size)
);
#endif /* _INCLUDE_FILEPARSE_H_ */

+ 162
- 0
isom.c View File

@ -0,0 +1,162 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#undef TESTMAIN
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdbool.h>
#include "isom.h"
struct fileparse {
uint8_t box_header[8];
size_t box_header_pos;
size_t box_size;
bool header_done;
ssize_t (*data_cb)(void *data, size_t size);
int (*trigger_cb)(enum fileparse_trigger trig);
};
int isom_parse(struct fileparse *isom, void *buffer, size_t size)
{
uint8_t *cbuffer = buffer;
while (size) {
if (isom->box_header_pos < 8) {
isom->box_header[isom->box_header_pos] = cbuffer[0];
isom->box_header_pos++;
if (isom->box_header_pos == 8) {
isom->box_size =
(isom->box_header[0] << 24) |
(isom->box_header[1] << 16) |
(isom->box_header[2] << 8) |
(isom->box_header[3] << 0);
if (0) printf("box: %zd: %02x%02x%02x%02x %c%c%c%c\n", isom->box_size,
isom->box_header[4],
isom->box_header[5],
isom->box_header[6],
isom->box_header[7],
isom->box_header[4],
isom->box_header[5],
isom->box_header[6],
isom->box_header[7]);
if (isom->box_size >= 8) {
isom->box_size -= 8;
}
if (isom->box_size == 0) {
isom->box_header_pos = 0;
}
if (isom->box_header[4] == 'm' &&
isom->box_header[5] == 'o' &&
isom->box_header[6] == 'o' &&
isom->box_header[7] == 'f') {
if (isom->header_done) {
isom->trigger_cb(FILEPARSE_TRIGGER_PACKET_COMPLETE);
} else {
isom->header_done = true;
isom->trigger_cb(FILEPARSE_TRIGGER_HEADER_COMPLETE);
}
}
isom->data_cb(isom->box_header, 8);
}
cbuffer++;
size--;
} else {
size_t data_size = size;
if (data_size > isom->box_size) {
data_size = isom->box_size;
}
isom->box_size -= data_size;
size -= data_size;
isom->data_cb(cbuffer, data_size);
cbuffer += data_size;
if (isom->box_size == 0) {
isom->box_header_pos = 0;
}
}
}
return 0;
}
struct fileparse *isom_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *mat, void *buffer, size_t size))
{
struct fileparse *isom;
isom = calloc(sizeof(struct fileparse), 1);
if (!isom)
goto err;
*parse = isom_parse;
isom->data_cb = data_cb;
isom->trigger_cb = trigger_cb;
err:
return isom;
}
#ifdef TESTMAIN
static ssize_t data_cb(void *data, size_t size)
{
printf("data: %zd\n", size);
return size;
}
static int trigger_cb(enum fileparse_trigger trig)
{
printf("Trigger: %d\n", trig);
return 0;
}
int main(int argc, char **argv)
{
char buffer[1000];
ssize_t r;
int (*parse)(struct fileparse *mat, void *buffer, size_t size);
struct fileparse *isom = isom_create(data_cb, trigger_cb, &parse);
do {
r = read(0, buffer, 1000);
if (r > 0) {
printf("read: %zd\n", r);
isom_parse(isom, buffer, r);
}
} while (r > 0);
return 0;
}
#endif

+ 29
- 0
isom.h View File

@ -0,0 +1,29 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INCLUDE_ISOM_H_
#define _INCLUDE_ISOM_H_
#include "fileparse.h"
struct fileparse *isom_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *mat, void *buffer, size_t size)
);
#endif /* _INCLUDE_ISOM_H_ */

+ 13
- 11
matroska.c View File

@ -48,15 +48,15 @@ struct matroska_element {
uint64_t pos;
};
struct matroska {
struct fileparse {
int level;
struct matroska_element level_state[MATROSKA_LEVEL_MAX+1];
ssize_t (*data_cb)(void *data, size_t size);
int (*trigger_cb)(enum matroska_trigger trig);
int (*trigger_cb)(enum fileparse_trigger trig);
};
bool matroska_element_dive(struct matroska *mat)
bool matroska_element_dive(struct fileparse *mat)
{
struct matroska_element *em = &mat->level_state[mat->level];
@ -68,7 +68,7 @@ bool matroska_element_dive(struct matroska *mat)
return false;
}
int matroska_element_trigger(struct matroska *mat)
int matroska_element_trigger(struct fileparse *mat)
{
struct matroska_element *em = &mat->level_state[mat->level];
@ -76,20 +76,20 @@ int matroska_element_trigger(struct matroska *mat)
em->id[1] == 0x54 &&
em->id[2] == 0xae &&
em->id[3] == 0x6b)
mat->trigger_cb(MATROSKA_TRIGGER_HEADER_COMPLETE);
mat->trigger_cb(FILEPARSE_TRIGGER_HEADER_COMPLETE);
if (em->id[0] == 0x1f &&
em->id[1] == 0x43 &&
em->id[2] == 0xb6 &&
em->id[3] == 0x75)
mat->trigger_cb(MATROSKA_TRIGGER_PACKET_COMPLETE);
mat->trigger_cb(FILEPARSE_TRIGGER_PACKET_COMPLETE);
return 0;
}
#define PUSH(d) do { mat->data_cb(bufo + pos, (d)); pos += (d); } while(0)
int matroska_parse(struct matroska *mat, void *buffer, size_t size)
int matroska_parse(struct fileparse *mat, void *buffer, size_t size)
{
uint8_t *bufo = buffer;
size_t pos = 0;
@ -224,19 +224,21 @@ int matroska_parse(struct matroska *mat, void *buffer, size_t size)
return 0;
}
struct matroska *matroska_create(
struct fileparse *matroska_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum matroska_trigger trig)
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *mat, void *buffer, size_t size)
)
{
struct matroska *mat;
struct fileparse *mat;
mat = calloc(1, sizeof(struct matroska));
mat = calloc(1, sizeof(struct fileparse));
if (!mat)
goto err_calloc;
mat->data_cb = data_cb;
mat->trigger_cb = trigger_cb;
*parse = matroska_parse;
return mat;


+ 4
- 10
matroska.h View File

@ -18,18 +18,12 @@
#ifndef _INCLUDE_MATROSKA_H_
#define _INCLUDE_MATROSKA_H_
struct matroska;
#include "fileparse.h"
enum matroska_trigger {
MATROSKA_TRIGGER_HEADER_COMPLETE,
MATROSKA_TRIGGER_PACKET_COMPLETE,
};
int matroska_parse(struct matroska *mat, void *buffer, size_t size);
struct matroska *matroska_create(
struct fileparse *matroska_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum matroska_trigger trig)
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *mat, void *buffer, size_t size)
);
#endif /* _INCLUDE_MATROSKA_H_ */

+ 10
- 8
ogg.c View File

@ -22,9 +22,9 @@
#include <stdlib.h>
#include <string.h>
static struct ogg {
static struct fileparse {
ssize_t (*data_cb)(void *data, size_t size);
int (*trigger_cb)(enum ogg_trigger trig);
int (*trigger_cb)(enum fileparse_trigger trig);
} ogg;
@ -120,7 +120,7 @@ int ogg_in(ssize_t r)
printf("First vorbis data\n");
vorbis_header = 0;
if (!theora_header)
ogg.trigger_cb(OGG_TRIGGER_HEADER_COMPLETE);
ogg.trigger_cb(FILEPARSE_TRIGGER_HEADER_COMPLETE);
} else {
printf("Vorbis header\n");
ogg.data_cb(ogg_page, ogg_pos);
@ -132,7 +132,7 @@ int ogg_in(ssize_t r)
printf("First theora data\n");
theora_header = 0;
if (!vorbis_header)
ogg.trigger_cb(OGG_TRIGGER_HEADER_COMPLETE);
ogg.trigger_cb(FILEPARSE_TRIGGER_HEADER_COMPLETE);
} else {
printf("Theora header\n");
ogg.data_cb(ogg_page, ogg_pos);
@ -145,7 +145,7 @@ int ogg_in(ssize_t r)
if (size > 1024)
size = 1024;
ogg.data_cb(ogg_page + i, size);
ogg.trigger_cb(OGG_TRIGGER_PACKET_COMPLETE);
ogg.trigger_cb(FILEPARSE_TRIGGER_PACKET_COMPLETE);
}
memmove(ogg_page, ogg_page + ogg_total_segments, ogg_pos - ogg_total_segments);
@ -161,7 +161,7 @@ int ogg_in(ssize_t r)
return 0;
}
int ogg_parse(struct ogg *ogg, void *buffer, size_t size)
int ogg_parse(struct fileparse *ogg, void *buffer, size_t size)
{
char *bufb = buffer;
@ -177,13 +177,15 @@ int ogg_parse(struct ogg *ogg, void *buffer, size_t size)
return 0;
}
struct ogg *ogg_create(
struct fileparse *ogg_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum ogg_trigger trig)
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *ogg, void *buffer, size_t size)
)
{
ogg.data_cb = data_cb;
ogg.trigger_cb = trigger_cb;
*parse = ogg_parse;
return &ogg;
}


+ 4
- 10
ogg.h View File

@ -22,18 +22,12 @@
#include <stdbool.h>
#include <unistd.h>
struct ogg;
#include "fileparse.h"
enum ogg_trigger {
OGG_TRIGGER_HEADER_COMPLETE,
OGG_TRIGGER_PACKET_COMPLETE,
};
int ogg_parse(struct ogg *mat, void *buffer, size_t size);
struct ogg *ogg_create(
struct fileparse *ogg_create(
ssize_t (*data_cb)(void *data, size_t size),
int (*trigger_cb)(enum ogg_trigger trig)
int (*trigger_cb)(enum fileparse_trigger trig),
int (**parse)(struct fileparse *ogg, void *buffer, size_t size)
);
#endif /* _INCLUDE_OGG_H_ */

+ 18
- 14
trx_dv.c View File

@ -51,7 +51,7 @@ static int trx_dv_in_cb(void *arg)
ssize_t ret;
ret = recv(dv_sock, dv_frame, sizeof(dv_frame), 0);
if (ret >= 14) {
if (ret >= 16) {
uint16_t type = (dv_frame[12] << 8) | dv_frame[13];
int mode;
size_t datasize;
@ -100,29 +100,29 @@ static int trx_dv_in_cb(void *arg)
#endif
case ETH_P_ALAW:
mode = 'A';
datasize = ret - 14;
datasize = ret - 16;
break;
case ETH_P_ULAW:
mode = 'U';
datasize = ret - 14;
datasize = ret - 16;
break;
case ETH_P_LE16:
mode = 's';
datasize = ret - 14;
datasize = ret - 16;
break;
case ETH_P_BE16:
mode = 'S';
datasize = ret - 14;
datasize = ret - 16;
break;
case ETH_P_AR_CONTROL:
return ctrl_cb(in_cb_arg, dv_frame + 6, dv_frame, (char *)dv_frame + 14, ret - 14);
return ctrl_cb(in_cb_arg, dv_frame + 6, dv_frame, (char *)dv_frame + 16, ret - 16);
case ETH_P_FPRS:
return fprs_cb(in_cb_arg, dv_frame + 6, dv_frame + 14, ret - 14);
default:
return 0;
}
if (ret >= datasize + 14) {
in_cb(in_cb_arg, dv_frame + 6, dv_frame, dv_frame + 14, datasize, mode);
in_cb(in_cb_arg, dv_frame + 6, dv_frame, dv_frame + 16, datasize, mode);
}
} else {
printf("frame not the right size: %zd: \n", ret);
@ -205,17 +205,19 @@ int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t si
}
while (size) {
uint8_t dv_frame[6 + 6 + 2 + max_size];
uint8_t dv_frame[6 + 6 + 2 + 1 + 1 + max_size];
size_t out_size = size;
if (out_size > max_size)
out_size = max_size;
memcpy(dv_frame + 0, to, 6);
memcpy(dv_frame + 6, from, 6);
memcpy(dv_frame + 12, &type, 2);
memcpy(dv_frame + 14, dv, out_size);
dv_frame[14] = 0;
dv_frame[15] = 1;
memcpy(dv_frame + 16, dv, out_size);
ssize_t ret = send(dv_sock, dv_frame, 14 + out_size, 0);
if (ret == 14 + out_size) {
ssize_t ret = send(dv_sock, dv_frame, 16 + out_size, 0);
if (ret == 16 + out_size) {
size -= out_size;
dv += out_size;
}
@ -231,13 +233,15 @@ int trx_dv_send_control(uint8_t from[6], uint8_t to[6], char *control)
size_t control_size = strlen(control);
uint16_t type = htons(ETH_P_AR_CONTROL);
uint8_t dv_frame[6 + 6 + 2 + control_size];
uint8_t dv_frame[6 + 6 + 2 + 1 + 1 + control_size];
memcpy(dv_frame + 0, to, 6);
memcpy(dv_frame + 6, from, 6);
memcpy(dv_frame + 12, &type, 2);
memcpy(dv_frame + 14, control, control_size);
dv_frame[14] = 0;
dv_frame[15] = 1;
memcpy(dv_frame + 16, control, control_size);
ssize_t ret = send(dv_sock, dv_frame, 14 + control_size, 0);
ssize_t ret = send(dv_sock, dv_frame, 16 + control_size, 0);
if (ret == 14 + control_size)
return 0;


Loading…
Cancel
Save