Browse Source

Exclude our own stream when not in fullduplex

Make tx guard generic (dml_trx and dml_reflector)
master
Jeroen Vreeken 1 month ago
parent
commit
32cfa66c72
5 changed files with 122 additions and 49 deletions
  1. +1
    -1
      Makefile.am
  2. +3
    -33
      dml_reflector.c
  3. +12
    -15
      dml_trx.c
  4. +78
    -0
      dml_voice_data.c
  5. +28
    -0
      dml_voice_data.h

+ 1
- 1
Makefile.am View File

@ -26,7 +26,7 @@ libdml_la_LDFLAGS= -shared -fPIC -version-info 0:0:0 @LIB_LDFLAGS@ @GLIB_LIBS@
bin_PROGRAMS = dmld dml_list dml_streamer dml_stream_client dml_stream_client_codec2 dml_fprs_db
DML_SRCS = \
dml_stream_client_simple.c
dml_stream_client_simple.c dml_voice_data.c
ALAW_SRCS = alaw.c


+ 3
- 33
dml_reflector.c View File

@ -24,6 +24,7 @@
#include <dml/dml_crypto.h>
#include "dml_config.h"
#include <dml/dml_stream.h>
#include "dml_voice_data.h"
#include <eth_ar/eth_ar.h>
#include "alaw.h"
@ -41,7 +42,6 @@
#define DML_REFLECTOR_PARROT_MAX (60*60*50)
#define DML_REFLECTOR_DATA_KEEPALIVE 10
#define DML_REFLECTOR_GUARD_TIME_MS (200)
uint8_t ref_id[DML_ID_SIZE];
char *name;
@ -238,19 +238,6 @@ void parrot_queue_add(void *data, size_t size, int duration)
}
static uint8_t tx_level = 0;
static char tx_call[ETH_AR_MAC_SIZE] = {0};
static gboolean guard_cb(void *arg)
{
printf("No incomming activity, releasing guard\n");
tx_level = 0;
return G_SOURCE_REMOVE;
}
static void stream_data_cb(struct dml_host *host, struct dml_stream *ds, uint64_t timestamp, void *data, size_t data_size, void *arg)
{
int duration;
@ -267,25 +254,8 @@ static void stream_data_cb(struct dml_host *host, struct dml_stream *ds, uint64_
printf("mode %d level %d duration: %d: ", mode, level, duration);
if (level > tx_level) {
char call[ETH_AR_CALL_SIZE];
int ssid;
bool multicast;
eth_ar_mac2call(call, &ssid, &multicast, data);
tx_level = level;
memcpy(tx_call, data, ETH_AR_MAC_SIZE);
printf("State changed to %s (level=%d) by %s-%d\n", level ? "ON":"OFF", level, multicast ? "MULTICAST" : call, ssid);
} else {
if (memcmp(data, tx_call, ETH_AR_MAC_SIZE)) {
printf("Dropped due to tx guard\n");
return;
}
tx_level = level;
printf("Accepted\n");
g_source_remove_by_user_data(&tx_level);
g_timeout_add(DML_REFLECTOR_GUARD_TIME_MS, guard_cb, &tx_level);
}
if (dml_voice_data_level_check(data, data_size))
return;
if (!parrot)
send_data(data, data_size, timestamp);


+ 12
- 15
dml_trx.c View File

@ -28,6 +28,7 @@
#include <dml/dml_stream.h>
#include "fprs_db.h"
#include "fprs_parse.h"
#include "dml_voice_data.h"
#include "trx_dv.h"
#include "soundlib.h"
@ -79,7 +80,6 @@ static void recv_data(void *data, size_t size);
static void recv_data_fprs(void *data, size_t size, uint64_t timestamp);
static uint8_t rx_state = false;
static uint8_t tx_state = false;
static char command[100];
static int command_len = 0;
@ -581,23 +581,16 @@ static void recv_data(void *data, size_t size)
uint8_t *datab = data;
uint8_t mode = datab[6];
uint8_t state = datab[7];
uint8_t level = datab[7];
// printf("mode %d state %d\n", mode, state);
if (dml_voice_data_level_check(data, size))
return;
if (!rx_state || fullduplex) {
if (state != tx_state) {
char call[ETH_AR_CALL_SIZE];
int ssid;
bool multicast;
eth_ar_mac2call(call, &ssid, &multicast, data);
tx_state = state;
printf("State changed to %s by %s-%d\n", state ? "ON":"OFF", multicast ? "MULTICAST" : call, ssid);
}
if (size > 8) {
trx_dv_send(data, mac_bcast, mode, datab + 8, size - 8, state);
trx_dv_send(data, mac_bcast, mode, datab + 8, size - 8, level);
}
}
}
@ -676,10 +669,14 @@ static int dv_in_cb(void *arg, uint8_t from[6], uint8_t to[6], uint8_t *dv, size
fprs_update_mac(from);
g_source_remove_by_user_data(&rx_state);
if (rx_state)
if (rx_state) {
if (!fullduplex) {
dml_voice_data_exclude(from, level);
}
g_timeout_add(RXSTATE_CHECK_TIMER_NS/1000000, rx_watchdog, &rx_state);
else
} else {
g_timeout_add_seconds(DML_TRX_DATA_KEEPALIVE, rx_watchdog, &rx_state);
}
return 0;
}


+ 78
- 0
dml_voice_data.c View File

@ -0,0 +1,78 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2020
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/>.
*/
#include <dml/dml.h>
#include <eth_ar/eth_ar.h>
#include <stdio.h>
#define DML_GUARD_TIME_MS (200)
static uint8_t tx_level = 0;
static uint8_t tx_call[ETH_AR_MAC_SIZE] = {0};
static uint8_t ex_call[ETH_AR_MAC_SIZE] = {0};
static uint8_t ex_level = 0;
static gboolean guard_cb(void *arg)
{
printf("No incomming activity, releasing guard\n");
tx_level = 0;
return G_SOURCE_REMOVE;
}
int dml_voice_data_level_check(void *data, size_t data_size)
{
unsigned char *datab = data;
uint8_t level = datab[7];
if (level > tx_level) {
char call[ETH_AR_CALL_SIZE];
int ssid;
bool multicast;
if (!memcmp(data, ex_call, ETH_AR_MAC_SIZE) && level == ex_level) {
printf("Dropped due to rx loop guard\n");
return -1;
}
eth_ar_mac2call(call, &ssid, &multicast, data);
tx_level = level;
memcpy(tx_call, data, ETH_AR_MAC_SIZE);
printf("State changed to %s (level=%d) by %s-%d\n", level ? "ON":"OFF", level, multicast ? "MULTICAST" : call, ssid);
} else {
if (memcmp(data, tx_call, ETH_AR_MAC_SIZE)) {
printf("Dropped due to tx guard\n");
return -1;
}
tx_level = level;
printf("Accepted\n");
g_source_remove_by_user_data(&tx_level);
g_timeout_add(DML_GUARD_TIME_MS, guard_cb, &tx_level);
}
return 0;
}
void dml_voice_data_exclude(char call[ETH_AR_MAC_SIZE], uint8_t level)
{
memcpy(ex_call, call, ETH_AR_MAC_SIZE);
ex_level = level;
}

+ 28
- 0
dml_voice_data.h View File

@ -0,0 +1,28 @@
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2020
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_DML_VOICE_DATA_H_
#define _INCLUDE_DML_VOICE_DATA_H_
#include <eth_ar/eth_ar.h>
int dml_voice_data_level_check(void *data, size_t data_size);
void dml_voice_data_exclude(uint8_t ex_call[ETH_AR_MAC_SIZE], uint8_t level);
#endif // _INCLUDE_DML_VOICE_DATA_H_

Loading…
Cancel
Save