Browse Source

Get basic reception from DML working

master
Jeroen Vreeken 4 years ago
parent
commit
30e8544f32
2 changed files with 59 additions and 44 deletions
  1. +56
    -41
      dml_dmr.c
  2. +3
    -3
      dml_dmr.conf

+ 56
- 41
dml_dmr.c View File

@ -36,7 +36,8 @@ static struct ccs7db *db;
uint64_t prev_timestamp = 0;
#define DML_DATA_KEEPALIVE 10
static struct timespec dml_data_ts_keepalive = { 10, 0 };
static struct timespec dml_data_ts_off = { 0, 100*1000*1000 };
static int watchdog(void *arg);
@ -58,18 +59,25 @@ static void stream_data_cb(struct dml_host *host, struct dml_stream *ds, uint64_
if (data_size < 8)
return;
// uint8_t *datab = data;
uint8_t *datab = data;
uint8_t *mac = data;
// uint8_t *voice = &datab[8];
// size_t voice_size = data_size - 8;
// int mode = datab[6];
// bool state = datab[7] & 0x1;
uint8_t *voice = &datab[8];
size_t voice_size = data_size - 8;
int mode = datab[6];
bool state = datab[7] & 0x1;
unsigned long id;
if (ccs7db_mac2id(db, &id, mac))
{
/* Search for alias? */
id = 0;
/* If call cannot be matched to an id use the alias of the
stream, it should be a valid ID as well.
*/
char *alias = dml_stream_alias_get(ds);
if (alias) {
id = atol(alias);
} else {
id = 0;
}
}
if (id != last_id) {
@ -77,40 +85,53 @@ static void stream_data_cb(struct dml_host *host, struct dml_stream *ds, uint64_
printf("Voice from id: %lu\n", id);
}
/* Do something with voice data */
/* TODO: Do something with voice data */
/* Probably first some decoding based on mode
(could be a codec2 mode, a-law, u-law or signed 16bit,
but currently always 8000Hz samplerate)
*/
printf("Got mode %d voice data: %zu bytes @ %p, state: %d\n",
mode, voice_size, voice, state);
}
void send_data(void *data, size_t size, uint64_t timestamp)
void send_data(uint8_t mac[6], void *voice_data, size_t voice_size, int mode, bool state)
{
size_t size = voice_size + 8;
uint8_t data[size];
struct timespec ts;
uint64_t tmax;
uint64_t timestamp;
uint16_t packet_id = dml_stream_data_id_get(stream_dv);
dml_poll_timeout(&watchdog,
&(struct timespec){ DML_DATA_KEEPALIVE, 0});
if (!packet_id)
return;
memcpy(data, mac, 6);
data[6] = mode;
data[7] = state;
if (voice_size)
memcpy(data + 8, voice_data, voice_size);
clock_gettime(CLOCK_REALTIME, &ts);
timestamp = dml_ts2timestamp(&ts);
if (timestamp <= prev_timestamp) {
fprintf(stderr, "Dropping packet %"PRId64"\n", timestamp);
return;
timestamp = prev_timestamp + 1;
}
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 2;
ts.tv_nsec = 0;
tmax = dml_ts2timestamp(&ts);
if (timestamp > tmax)
return;
prev_timestamp = timestamp;
struct dml_connection *con = dml_host_connection_get(host);
if (con)
dml_packet_send_data(con, packet_id, data, size, timestamp, dk);
dml_poll_timeout(&watchdog, &dml_data_ts_off);
}
/* TODO: On reception of data:
- Use ccs7db_id2mac to retrieve a encoded call for the id
(Use multicast address on failure)
- Transcode in DML supported mode (any codec2 mode, a-law, u-law or le16)
- call send_data.
*/
static void stream_req_reverse_connect_cb(struct dml_host *host, struct dml_stream *ds, struct dml_stream *ds_rev, int status, void *arg)
{
bool do_connect = true;
@ -119,10 +140,13 @@ static void stream_req_reverse_connect_cb(struct dml_host *host, struct dml_stre
printf("Received reverse connect request (status=%d)\n", status);
if (do_connect) {
struct dml_crypto_key *key = dml_stream_crypto_get(ds_rev);
if (dml_host_mime_filter(host, ds_rev) && key) {
bool mime_match = dml_host_mime_filter(host, ds_rev);
if (mime_match && key) {
printf("Respond with connect\n");
dml_host_connect(host, ds_rev);
} else {
printf("Reject: key %p, mime_match: %d\n",
key, mime_match);
do_reject = true;
}
} else {
@ -148,22 +172,13 @@ static void stream_req_reverse_disconnect_cb(struct dml_host *host, struct dml_s
static int watchdog(void *arg)
{
struct timespec ts;
uint64_t timestamp;
printf("No activity, sending state off packet\n");
uint8_t data[8];
memset(data, 0xff, 6);
data[6] = 0;
data[7] = false;
send_data(
(uint8_t[6]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
NULL, 0, 0, false);
clock_gettime(CLOCK_REALTIME, &ts);
timestamp = dml_ts2timestamp(&ts);
if (timestamp <= prev_timestamp)
timestamp = prev_timestamp + 1;;
send_data(data, 8, timestamp);
dml_poll_timeout(&watchdog, &dml_data_ts_keepalive);
return 0;
}
@ -241,9 +256,9 @@ int main(int argc, char **argv)
dml_poll_add(&watchdog, NULL, NULL, watchdog);
dml_poll_timeout(&watchdog,
&(struct timespec){ DML_DATA_KEEPALIVE, 0});
dml_poll_timeout(&watchdog, &dml_data_ts_keepalive);
//TODO: hook up DMR reception into the main loop
dml_poll_loop();
ccs7db_destroy(db);


+ 3
- 3
dml_dmr.conf View File

@ -1,6 +1,6 @@
name = 0.brandmeister.network
alias = 0
description = Talkgroup 0
name = tg1234.brandmeister.network
alias = 1234
description = Talkgroup 1234
server = localhost
certificate = cert.pem
key = k.pem


Loading…
Cancel
Save