You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

120 lines
2.2 KiB

#include <fcntl.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "freedv_eth.h"
#include "freedv_eth_rx.h"
static bool modem_tx;
static int nr_sym;
static signed char *rx_sym = NULL;
static int rx_sym_cur;
struct txbuffer {
signed char *buffer;
size_t size;
struct txbuffer *next;
};
static struct txbuffer *txq = NULL;
int freedv_eth_modem_init(char *modem_file, struct freedv *freedv)
{
modem_tx = false;
#if defined(FREEDV_MODE_6000)
int fd_modem = open(modem_file, O_RDWR);
if (fd_modem < 0) {
printf("Could not open modem: %s\n", modem_file);
return -1;
}
fcntl(fd_modem, F_SETFL, O_NONBLOCK);
//set: TIOCMBIS
//clear: TIOCMBIC
ioctl(fd_modem, TIOCMBIC, &(int){TIOCM_DTR});
ioctl(fd_modem, TIOCMBIC, &(int){TIOCM_RTS});
nr_sym = freedv_get_n_modem_symbols(freedv);
rx_sym = realloc(rx_sym, nr_sym);
return fd_modem;
#else
return -1;
#endif
}
void freedv_eth_modem_poll(short *events)
{
*events = POLLIN | (txq ? POLLOUT : 0);
}
void freedv_eth_modem_rx(int fd_modem)
{
ssize_t r = read(fd_modem, rx_sym + rx_sym_cur, nr_sym - rx_sym_cur);
if (r > 0) {
rx_sym_cur += r;
}
if (rx_sym_cur == nr_sym) {
freedv_eth_symrx(rx_sym);
rx_sym_cur = 0;
}
}
void freedv_eth_modem_tx(int fd_modem)
{
ssize_t r = write(fd_modem, txq->buffer, txq->size);
if (r > 0) {
if (r < txq->size) {
size_t newsize = txq->size - r;
memmove(txq->buffer, &txq->buffer[r], newsize);
txq->buffer = realloc(txq->buffer, newsize);
} else {
struct txbuffer *old = txq;
txq = txq->next;
free(old->buffer);
free(old);
}
}
}
void freedv_eth_modem_tx_add(signed char *tx_sym, size_t nr)
{
struct txbuffer *entry = malloc(sizeof(struct txbuffer));
if (entry) {
entry->buffer = malloc(nr);
if (entry->buffer) {
entry->next = NULL;
entry->size = nr;
memcpy(entry->buffer, tx_sym, nr);
struct txbuffer **q = &txq;
while(*q)
q = &(*q)->next;
*q = entry;
} else {
free(entry);
}
}
}
bool freedv_eth_modem_tx_empty(int fd_modem)
{
int outq = 0;
bool empty = false;
if (!ioctl(fd_modem, TIOCOUTQ, &outq))
{
empty = (outq == 0);
}
return empty;
}