Browse Source

Merge branch 'master' of http://dmlinking.net/~pe1rxq/dml

master
Jeroen Vreeken 2 years ago
parent
commit
7ac37a1f5c
11 changed files with 310 additions and 136 deletions
  1. +3
    -3
      dml_client.c
  2. +9
    -1
      dml_httpd.c
  3. +1
    -1
      dml_stream_client.c
  4. +20
    -12
      dml_stream_client_simple.c
  5. +2
    -1
      dml_streamer.c
  6. +18
    -16
      dml_trx.c
  7. +18
    -22
      htdocs/index.html
  8. +68
    -0
      htdocs/le16_be16.js
  9. +132
    -61
      isom.c
  10. +37
    -17
      trx_dv.c
  11. +2
    -2
      trx_dv.h

+ 3
- 3
dml_client.c View File

@ -87,7 +87,7 @@ int dml_client_connect(struct dml_client *dc)
struct addrinfo *result;
struct addrinfo *entry;
struct addrinfo hints = { 0 };
int error, i;
int error;
int sock = -1;
char *port;
@ -110,8 +110,8 @@ int dml_client_connect(struct dml_client *dc)
close(sock);
sock = -1;
} else {
i = 1;
setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (int));
setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &(int){1}, sizeof (int));
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &(int){1}, sizeof (int));
break;
}
}


+ 9
- 1
dml_httpd.c View File

@ -398,7 +398,9 @@ static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
break;
}
case LWS_CALLBACK_RECEIVE: {
uint8_t *rcv = in;
uint8_t rcv[len+1];
memcpy(rcv, in, len);
rcv[len] = 0;
struct ws_client *ws_client;
// printf("lws receive: %zd\n", len);
@ -478,6 +480,11 @@ static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
break;
}
case LWS_CALLBACK_HTTP_FILE_COMPLETION:
/* kill the connection after we sent one file */
r = -1;
break;
case LWS_CALLBACK_ADD_POLL_FD: {
struct lws_pollargs *args = in;
dml_poll_add(wsi, wsi_in_cb, wsi_out_cb, NULL);
@ -518,6 +525,7 @@ static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
break;
}
return r;
}


+ 1
- 1
dml_stream_client.c View File

@ -79,7 +79,7 @@ int main(int argc, char **argv)
dml_str_id(req_id, req_id_str);
dss = dml_stream_client_simple_create(server, req_id, NULL, data_cb, true);
dss = dml_stream_client_simple_create(server, req_id, NULL, data_cb, false);
if (!dss) {
printf("Could not create stream\n");
return -1;


+ 20
- 12
dml_stream_client_simple.c View File

@ -131,9 +131,11 @@ static void rx_packet(struct dml_connection *dc, void *arg,
size_t size;
fprintf(stderr, "Parse certificate\n");
if (dml_packet_parse_certificate(data, len, cid, &cert, &size))
if (dml_packet_parse_certificate(data, len, cid, &cert, &size)) {
fprintf(stderr, "Failed to parse certificate\n");
break;
}
fprintf(stderr, "verify %d\n", dss->verify);
if (!dss->verify || !dml_crypto_cert_add_verify(cert, size, cid)) {
fprintf(stderr, "Request header\n");
dml_packet_send_req_header(dc, dss->req_id);
@ -149,28 +151,34 @@ static void rx_packet(struct dml_connection *dc, void *arg,
size_t header_size;
struct dml_stream *ds;
struct dml_crypto_key *dk;
bool send_connect = false;
if (dml_packet_parse_header(data, len, hid, sig, &header, &header_size))
break;
if (!dss->verify) {
dss->data_cb(dss->arg, header, header_size);
} else if ((ds = dml_stream_by_id(hid))) {
if ((dk = dml_stream_crypto_get(ds))) {
if ((ds = dml_stream_by_id(hid))) {
if (!dss->verify) {
send_connect = true;
} else if ((dk = dml_stream_crypto_get(ds))) {
bool verified = dml_crypto_verify(header, header_size, sig, dk);
if (verified) {
dss->data_cb(dss->arg, header, header_size);
dss->header_written = true;
dml_stream_data_id_set(ds, DML_PACKET_DATA);
dml_packet_send_connect(dc, dss->req_id, DML_PACKET_DATA);
fprintf(stderr, "Send connect\n");
send_connect = true;
} else {
fprintf(stderr, "Failed to verify header signature (%zd bytes)\n", header_size);
}
}
}
if (send_connect) {
dss->data_cb(dss->arg, header, header_size);
dss->header_written = true;
dml_stream_data_id_set(ds, DML_PACKET_DATA);
dml_packet_send_connect(dc, dss->req_id, DML_PACKET_DATA);
fprintf(stderr, "Send connect\n");
}
free(header);
break;


+ 2
- 1
dml_streamer.c View File

@ -33,7 +33,7 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include <openssl/pem.h>
@ -167,6 +167,7 @@ void send_data(void *data, size_t size)
timestamp = (uint64_t)ts.tv_sec << 16;
timestamp |= prev_ctr;
printf("timestamp: 0x%016"PRIx64"\n", timestamp);
dml_packet_send_data(dml_con, packet_id, data, size, timestamp, dk);
}


+ 18
- 16
dml_trx.c View File

@ -55,6 +55,8 @@
#define TIME_VALID_DOWNLINK (5*60)
#define TIME_VALID_OWN (60*60)
#define DML_TRX_LEVEL_MSG 255
#define debug(...) printf(__VA_ARGS__)
static bool fullduplex = false;
@ -77,8 +79,8 @@ static int send_data_fprs(void *data, size_t size, unsigned int link, void *arg)
static void recv_data(void *data, size_t size);
static void recv_data_fprs(void *data, size_t size, uint64_t timestamp);
static bool rx_state = false;
static bool tx_state = false;
static uint8_t rx_state = false;
static uint8_t tx_state = false;
static char command[100];
static int command_len = 0;
@ -451,7 +453,7 @@ static void stream_header_cb(struct dml_host *host, struct dml_stream *ds, void
if (ds == cur_con) {
fprintf(stderr, "Play header\n");
trx_dv_send(mac_dev, mac_bcast, 'A', header, header_size);
trx_dv_send(mac_dev, mac_bcast, 'A', header, header_size, DML_TRX_LEVEL_MSG);
} else {
fprintf(stderr, "Stream mismatch: %p %p\n", ds, cur_con);
}
@ -582,7 +584,7 @@ static void recv_data(void *data, size_t size)
uint8_t *datab = data;
uint8_t mode = datab[6];
bool state = datab[7] & 0x1;
uint8_t state = datab[7];
// printf("mode %d state %d\n", mode, state);
@ -598,7 +600,7 @@ static void recv_data(void *data, size_t size)
}
if (size > 8) {
trx_dv_send(data, mac_bcast, mode, datab + 8, size - 8);
trx_dv_send(data, mac_bcast, mode, datab + 8, size - 8, state);
}
}
}
@ -611,11 +613,11 @@ static int rx_watchdog(void *arg)
memcpy(data, rx_state ? mac_last : mac_bcast, 6);
data[6] = 0;
data[7] = false;
data[7] = 0;
send_data(data, 8, stream_dv);
rx_state = false;
rx_state = 0;
/* Flush command buffer */
command_len = 0;
@ -625,10 +627,10 @@ static int rx_watchdog(void *arg)
data = soundlib_get(SOUND_MSG_SILENCE, &size);
if (data) {
trx_dv_send(mac_dev, mac_bcast, 'A', data, size);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size, DML_TRX_LEVEL_MSG);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size, DML_TRX_LEVEL_MSG);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size, DML_TRX_LEVEL_MSG);
trx_dv_send(mac_dev, mac_bcast, 'A', data, size, DML_TRX_LEVEL_MSG);
}
struct sound_msg_e *e = sound_msg_q;
@ -640,7 +642,7 @@ static int rx_watchdog(void *arg)
if (size < sendsize)
sendsize = size;
trx_dv_send(mac_dev, mac_bcast, 'A', data, sendsize);
trx_dv_send(mac_dev, mac_bcast, 'A', data, sendsize, DML_TRX_LEVEL_MSG);
data += sendsize;
size -= sendsize;
}
@ -658,14 +660,14 @@ static int rx_watchdog(void *arg)
return 0;
}
static int dv_in_cb(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode)
static int dv_in_cb(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode, uint8_t level)
{
uint8_t data[8 + size];
if (!rx_state) {
printf("rx_state to on\n");
}
rx_state = true;
rx_state = level;
memcpy(data, from, 6);
memcpy(mac_last, from, 6);
@ -1117,7 +1119,7 @@ int main(int argc, char **argv)
memcpy(header, mac_dev, 6);
header[6] = 'A';
header[7] = 1;
header[7] = 255;
dml_stream_header_set(stream_dv, header, header_size + 8);
}
}
@ -1138,7 +1140,7 @@ int main(int argc, char **argv)
printf("Could not create command pipe\n");
return -1;
}
fd_command = open(command_pipe_name, O_RDONLY | O_NONBLOCK);
fd_command = open(command_pipe_name, O_RDWR | O_NONBLOCK);
if (fd_command < 0) {
printf("Could not open command pipe\n");
return -1;


+ 18
- 22
htdocs/index.html View File

@ -77,6 +77,7 @@ Decentralized Media Linking
<script src="aprs_symbol.js"></script>
<script src="alaw.js"></script>
<script src="ulaw.js"></script>
<script src="le16_be16.js"></script>
<script src="resample.js"></script>
<script src="libcodec2.js"></script>
<script src="codec2.js"></script>
@ -367,8 +368,9 @@ function mse()
this.data = function mse_data(newdata) {
sourceBuffer.appendBuffer(newdata);
if (video.buffered.length) {
if (video.buffered.start(0) > video.currentTime)
if (video.buffered.start(0) > video.currentTime) {
video.currentTime = video.buffered.start(0);
}
}
}
}
@ -491,9 +493,10 @@ function dmlc2()
dmlc2_this.audio_ctx = new (window.AudioContext || window.webkitAudioContext)();
dmlc2_this.rate = dmlc2_this.audio_ctx.sampleRate;
console.log("audio_ctx rate: " + dmlc2_this.rate);
dmlc2_this.resample = new resample();
dmlc2_this.queue = new Array();
dmlc2_this.scriptnode = dmlc2_this.audio_ctx.createScriptProcessor(1024, 0, 1);
dmlc2_this.scriptnode = dmlc2_this.audio_ctx.createScriptProcessor(0, 0, 1);
dmlc2_this.scriptnode.onaudioprocess = function (event) {
// console.log("event: " + event.outputBuffer.length);
var i, out, len, off;
@ -505,13 +508,15 @@ function dmlc2()
var copylen = dmlc2_this.queue[0].length;
if (copylen > len)
copylen = len;
//console.log("len: " + len + " q: " + dmlc2_this.queue[0].length +
// " "+ dmlc2_this.queue.length + " copylen " + copylen + " off "+off);
for (i = 0; i < copylen; i++) {
out[off] = dmlc2_this.queue[0][i];
off++;
}
len -= copylen;
off += copylen;
dmlc2_this.queue[0].splice(0, copylen);
if (dmlc2_this.queue[0].length == 0) {
dmlc2_this.queue.shift();
@ -532,8 +537,10 @@ function dmlc2()
}
this.disconnect = function dmlc2_disconnect()
{
dmlc2_this.scriptnode.disconnect();
dmlc2_this.scriptnode = undefined;
if (dmlc2_this.scriptnode) {
dmlc2_this.scriptnode.disconnect();
dmlc2_this.scriptnode = undefined;
}
dmlc2_this.audio_ctx = undefined;
disconnect();
document.getElementById("dmlc2_div").style.display = "none";
@ -546,13 +553,15 @@ function dmlc2()
dmlc2_this.alaw_data = new alaw();
dmlc2_this.ulaw_data = new ulaw();
dmlc2_this.le16_data = new le16();
dmlc2_this.be16_data = new be16();
dmlc2_this.c2 = new codec2();
this.data = function dmlc2_data(newdata) {
if (data.byteLength >= 8) {
if (newdata.byteLength >= 8) {
var dv = new DataView(newdata);
var newstate = dv.getUint8(7) & 0x1;
var newstate = dv.getUint8(7);
var bytemode = dv.getUint8(6);
var newmode = CODEC2.MODE[bytemode];
var newcallsign = eth_ar.call(newdata);
@ -566,22 +575,9 @@ function dmlc2()
} else if (newmode == 'u-law') {
samples = dmlc2_this.ulaw_data.decode(c2_buf);
} else if (newmode == 'le16') {
var i;
var nr = c2_buf.length / 2;
samples = new Array(nr);
var dv = new DataView(c2_buf.buffer);
for (i = 0; i < nr; i++) {
samples[i] = dv.getInt16(c2_buf.byteOffset + i*2, true) / 32768.0;
// samples[i] = Int16Array(c2_buf)[i] / 32768.0;
}
samples = dmlc2_this.le16.decode(c2_buf);
} else if (newmode == 'be16') {
var i;
var nr = c2_buf.length / 2;
samples = new Array(nr);
var dv = new DataView(c2_buf.buffer);
for (i = 0; i < nr; i++) {
samples[i] = dv.getInt16(c2_buf.byteOffset + i*2, false) / 32768.0;
}
samples = dmlc2_this.be16.decode(c2_buf);
} else {
dmlc2_this.c2.create(bytemode);
samples = dmlc2_this.c2.decode(c2_buf);


+ 68
- 0
htdocs/le16_be16.js View File

@ -0,0 +1,68 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2019
@licstart The following is the entire license notice for the
JavaScript code in this page.
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/>.
@licend The above is the entire license notice
for the JavaScript code in this page.
*/
function le16()
{
this.decode = function (arraybuffer) {
var u8_view = new Uint8Array(arraybuffer);
var i;
var s_buf = new Array(u8_view.length/2);
for (i = 0; i < u8_view.length/2; i++) {
var a_val_lo = u8_view[i*2+0];
var a_val_hi = u8_view[i*2+1];
var s_val;
s_val = a_val_hi * 256 + a_val_lo;
if (s_val >= 32768)
s_val -= 65536;
s_buf[i] = s_val / 32767;
}
return s_buf;
}
}
function be16()
{
this.decode = function (arraybuffer) {
var u8_view = new Uint8Array(arraybuffer);
var i;
var s_buf = new Array(u8_view.length/2);
for (i = 0; i < u8_view.length/2; i++) {
var a_val_lo = u8_view[i*2+1];
var a_val_hi = u8_view[i*2+0];
var s_val;
s_val = a_val_hi * 256 + a_val_lo;
if (s_val >= 32768)
s_val -= 65536;
s_buf[i] = s_val / 32767;
}
return s_buf;
}
}

+ 132
- 61
isom.c View File

@ -15,7 +15,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#undef TESTMAIN
//#define TESTMAIN
#include <string.h>
#include <stdlib.h>
@ -27,80 +27,151 @@
#include "isom.h"
struct fileparse {
uint8_t box_header[8];
size_t box_header_pos;
uint8_t *box;
size_t cur_size;
size_t box_size;
bool header_done;
ssize_t (*data_cb)(void *data, size_t size);
int (*trigger_cb)(enum fileparse_trigger trig);
};
char *subbox[] = {
"moov",
"trak",
"mdia",
"minf",
"stbl",
"moof",
"traf",
};
char *removebox[] = {
"tfdt",
};
char *dumpbox[] = {
"mvhd",
"mfhd",
"stts",
"tfdt",
// "trun",
};
void printbox(void *box, size_t *box_size, int level)
{
uint8_t *cbox = box;
uint8_t *type = &cbox[4];
char levelstr[level*2+1];
memset(levelstr, ' ', level*2);
levelstr[level*2] = 0;
printf("%sbox: %c%c%c%c %zd\n", levelstr,
type[0], type[1], type[2], type[3], *box_size);
int i;
bool has_subbox = false;
for (i = 0; i < sizeof(subbox)/sizeof(subbox[0]); i++) {
if (!memcmp(subbox[i], type, 4)) {
has_subbox = true;
}
}
bool is_removebox = false;
for (i = 0; i < sizeof(removebox)/sizeof(removebox[0]); i++) {
if (!memcmp(removebox[i], type, 4)) {
is_removebox = true;
}
}
bool is_dumpbox = false;
for (i = 0; i < sizeof(dumpbox)/sizeof(dumpbox[0]); i++) {
if (!memcmp(dumpbox[i], type, 4)) {
is_dumpbox = true;
}
}
if (is_dumpbox) {
printf("%s ", levelstr);
for (i = 0; i < *box_size; i++) {
if (i == 8)
printf(" ");
printf("%02x", cbox[i]);
}
printf("\n");
}
if (is_removebox) {
*box_size = 0;
return;
}
size_t pos;
if (has_subbox) for (pos = 8; pos < *box_size; ) {
size_t subbox_size =
(cbox[pos + 0] << 24) |
(cbox[pos + 1] << 16) |
(cbox[pos + 2] << 8) |
(cbox[pos + 3] << 0);
size_t org_size = subbox_size;
printbox(&cbox[pos], &subbox_size, level+1);
if (subbox_size < org_size) {
size_t removed = org_size - subbox_size;
memmove(&cbox[pos+subbox_size], &cbox[pos+removed], *box_size - (pos + removed));
printf("%sremoved %zd, %zd <- %zd (%zd) %zd\n", levelstr, removed, pos, pos+removed, *box_size - (pos+removed), subbox_size);
*box_size -= removed;
}
pos += subbox_size;
}
printf("%s%zd\n", levelstr, *box_size);
cbox[0] = (*box_size >> 24) & 0xff;
cbox[1] = (*box_size >> 16) & 0xff;
cbox[2] = (*box_size >> 8) & 0xff;
cbox[3] = (*box_size >> 0) & 0xff;
}
int isom_parse(struct fileparse *isom, void *buffer, size_t size)
{
uint8_t *cbuffer = buffer;
char *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) {
if (isom->cur_size < 4) {
size_t copy = 4 - isom->cur_size;
if (size < copy) {
copy = size;
}
memcpy(&isom->box[isom->cur_size], cbuffer, copy);
cbuffer += copy;
size -= copy;
isom->cur_size += copy;
if (isom->cur_size == 4) {
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);
(isom->box[0] << 24) |
(isom->box[1] << 16) |
(isom->box[2] << 8) |
(isom->box[3] << 0);
isom->box = realloc(isom->box, isom->box_size);
}
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;
size_t copy = isom->box_size - isom->cur_size;
if (size < copy) {
copy = size;
}
memcpy(&isom->box[isom->cur_size], cbuffer, copy);
cbuffer += copy;
size -= copy;
isom->cur_size += copy;
}
if (isom->cur_size == isom->box_size) {
printbox(isom->box, &isom->box_size, 0);
write(2, isom->box, isom->box_size);
isom->cur_size = 0;
}
}
@ -117,6 +188,7 @@ struct fileparse *isom_create(
isom = calloc(sizeof(struct fileparse), 1);
if (!isom)
goto err;
isom->box = malloc(4);
*parse = isom_parse;
isom->data_cb = data_cb;
@ -151,7 +223,6 @@ int main(int argc, char **argv)
do {
r = read(0, buffer, 1000);
if (r > 0) {
printf("read: %zd\n", r);
isom_parse(isom, buffer, r);
}
} while (r > 0);


+ 37
- 17
trx_dv.c View File

@ -40,7 +40,7 @@ static void (*dv_mac_cb)(uint8_t *mac) = NULL;
#define TRX_DV_WATCHDOG 5
static int (*in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode) = NULL;
static int (*in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode, uint8_t level) = NULL;
static int (*ctrl_cb)(void *arg, uint8_t from[6], uint8_t to[6], char *ctrl, size_t size) = NULL;
static int (*fprs_cb)(void *arg, uint8_t from[6], uint8_t *fprs, size_t size) = NULL;
static void *in_cb_arg = NULL;
@ -92,12 +92,20 @@ static int trx_dv_in_cb(void *arg)
mode = CODEC2_MODE_700C;
datasize = 4;
break;
#ifdef CODEC2_MODE_1300C
case ETH_P_CODEC2_1300C:
mode = CODEC2_MODE_1300C;
datasize = 7;
#if defined(CODEC2_MODE_WB)
case ETH_P_CODEC2_WB:
mode = CODEC2_MODE_WB;
datasize = 8;
break;
#endif
case ETH_P_CODEC2_450:
mode = CODEC2_MODE_450;
datasize = 3;
break;
case ETH_P_CODEC2_450PWB:
mode = CODEC2_MODE_450PWB;
datasize = 3;
break;
case ETH_P_ALAW:
mode = 'A';
datasize = ret - 16;
@ -122,7 +130,7 @@ static int trx_dv_in_cb(void *arg)
return 0;
}
if (ret >= datasize + 14) {
in_cb(in_cb_arg, dv_frame + 6, dv_frame, dv_frame + 16, datasize, mode);
in_cb(in_cb_arg, dv_frame + 6, dv_frame, dv_frame + 16, datasize, mode, dv_frame[15]);
}
} else {
printf("frame not the right size: %zd: \n", ret);
@ -136,7 +144,7 @@ static int trx_dv_in_cb(void *arg)
}
int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t size)
int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t size, uint8_t level)
{
uint16_t type;
ssize_t max_size = 0;
@ -178,12 +186,20 @@ int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t si
type = htons(ETH_P_CODEC2_700C);
max_size = 4;
break;
#ifdef CODEC2_MODE_1300C
case CODEC2_MODE_1300C:
type = htons(ETH_P_CODEC2_1300C);
max_size = 7;
#if defined(CODEC2_MODE_WB)
case CODEC2_MODE_WB:
type = htons(ETH_P_CODEC2_WB);
max_size = 8;
break;
#endif
case CODEC2_MODE_450:
type = htons(ETH_P_CODEC2_450);
max_size = 3;
break;
case CODEC2_MODE_450PWB:
type = htons(ETH_P_CODEC2_450PWB);
max_size = 3;
break;
case 'A':
type = htons(ETH_P_ALAW);
max_size = 320;
@ -212,8 +228,8 @@ int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t si
memcpy(dv_frame + 0, to, 6);
memcpy(dv_frame + 6, from, 6);
memcpy(dv_frame + 12, &type, 2);
dv_frame[14] = 0;
dv_frame[15] = 1;
dv_frame[14] = from[0] ^ from[1] ^ from[2] ^ from[3] ^ from[4] ^ from[5];
dv_frame[15] = level;
memcpy(dv_frame + 16, dv, out_size);
ssize_t ret = send(dv_sock, dv_frame, 16 + out_size, 0);
@ -286,9 +302,13 @@ int trx_dv_duration(size_t size, int mode)
return (size * 40) / 4;
case CODEC2_MODE_700C:
return (size * 40) / 4;
#ifdef CODEC2_MODE_1300C
case CODEC2_MODE_1300C:
return (size * 40) / 7;
case CODEC2_MODE_450:
return (size * 40) / 3;
case CODEC2_MODE_450PWB:
return (size * 40) / 3;
#if defined(CODEC2_MODE_WB)
case CODEC2_MODE_WB:
return (size * 20) / 8;
#endif
case 'A':
case 'U':
@ -371,7 +391,7 @@ static int trx_dv_watchdog(void *arg)
}
int trx_dv_init(char *dev,
int (*new_in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode),
int (*new_in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode, uint8_t level),
int (*new_ctrl_cb)(void *arg, uint8_t from[6], uint8_t to[6], char *ctrl, size_t size),
int (*new_fprs_cb)(void *arg, uint8_t from[6], uint8_t *fprs, size_t size),
void *arg,


+ 2
- 2
trx_dv.h View File

@ -22,12 +22,12 @@
#include <stdint.h>
int trx_dv_init(char *dev,
int (*new_in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode),
int (*new_in_cb)(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size_t size, int mode, uint8_t level),
int (*new_ctrl_cb)(void *arg, uint8_t from[6], uint8_t to[6], char *ctrl, size_t size),
int (*new_fprs_cb)(void *arg, uint8_t from[6], uint8_t *fprs, size_t size),
void *arg,
void (*new_mac_cb)(uint8_t *mac));
int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t size);
int trx_dv_send(uint8_t from[6], uint8_t to[6], int mode, uint8_t *dv, size_t size, uint8_t level);
int trx_dv_send_control(uint8_t from[6], uint8_t to[6], char *control);
int trx_dv_send_fprs(uint8_t from[6], uint8_t to[6], uint8_t *data, size_t size);
/* Duration (ms) of DV data */


Loading…
Cancel
Save