mirror of
https://github.com/n5ac/smartsdr-dsp.git
synced 2026-04-21 06:03:49 +00:00
Handle ThumbDV being unplugged gracefully.
When the ThumbDV is unplugged the serial read thread stops and tries to re-connect. All writes to the serial port also stop.
This commit is contained in:
parent
09cca8a92d
commit
2f828cf2ac
4 changed files with 103 additions and 72 deletions
|
|
@ -340,6 +340,11 @@ void sched_waveform_setOwnCall2(uint32 slice , const char * owncall2 )
|
|||
dstar_dumpHeader(&(_dstar->outgoing_header));
|
||||
}
|
||||
|
||||
void sched_waveform_setFD(int fd)
|
||||
{
|
||||
_dv_serial_fd = fd;
|
||||
}
|
||||
|
||||
static void* _sched_waveform_thread(void* param)
|
||||
{
|
||||
int nout;
|
||||
|
|
@ -376,7 +381,7 @@ static void* _sched_waveform_thread(void* param)
|
|||
|
||||
// ======================= Initialization Section =========================
|
||||
|
||||
thumbDV_init("/dev/ttyUSB0", &_dv_serial_fd);
|
||||
thumbDV_init(&_dv_serial_fd);
|
||||
|
||||
// Initialize the Circular Buffers
|
||||
|
||||
|
|
|
|||
|
|
@ -48,4 +48,5 @@ void sched_waveform_setOwnCall1( uint32 slice , const char * owncall1 );
|
|||
void sched_waveform_setOwnCall2(uint32 slice , const char * owncall2 );
|
||||
|
||||
void sched_waveform_sendStatus(uint32 slice);
|
||||
void sched_waveform_setFD(int fd);
|
||||
#endif /* SCHED_WAVEFORM_H_ */
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
#include "vita_output.h"
|
||||
#include "thumbDV.h"
|
||||
#include "sched_waveform.h"
|
||||
|
||||
|
||||
#define DV3000_TTY "/dev/ttyAMA0"
|
||||
|
|
@ -87,6 +88,8 @@ static BufferDescriptor _decoded_root;
|
|||
static BOOL _decoded_buffering = TRUE;
|
||||
static uint32 _decoded_count = 0;
|
||||
|
||||
static void* _thumbDV_readThread(void* param);
|
||||
|
||||
static BufferDescriptor _thumbDVEncodedList_UnlinkHead(void)
|
||||
{
|
||||
BufferDescriptor buf_desc = NULL;
|
||||
|
|
@ -441,7 +444,7 @@ int thumbDV_processSerial(int serial_fd)
|
|||
errno = 0;
|
||||
len = read(serial_fd, buffer, 1);
|
||||
if (len != 1) {
|
||||
output(ANSI_RED "ThumbDV: error when reading from the serial port, len = %d, errno=%d\n" ANSI_WHITE, len, errno);
|
||||
output(ANSI_RED "ThumbDV: Process serial. error when reading from the serial port, len = %d, errno=%d\n" ANSI_WHITE, len, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -507,7 +510,7 @@ int thumbDV_decode(int serial_fd, unsigned char * packet_in, short * speech_out,
|
|||
uint32 i = 0;
|
||||
|
||||
unsigned char full_packet[15] = {0};
|
||||
if ( packet_in != NULL ) {
|
||||
if ( packet_in != NULL && serial_fd > 0 ) {
|
||||
full_packet[0] = 0x61;
|
||||
full_packet[1] = 0x00;
|
||||
full_packet[2] = 0x0B;
|
||||
|
|
@ -600,8 +603,8 @@ int thumbDV_encode(int serial_fd, short * speech_in, unsigned char * packet_out,
|
|||
idx[0] = speech_in[i] >> 8;
|
||||
idx[1] = (speech_in[i] & 0x00FF) ;
|
||||
}
|
||||
|
||||
thumbDV_writeSerial(serial_fd, packet, length + AMBE3000_HEADER_LEN);
|
||||
if ( serial_fd > 0 )
|
||||
thumbDV_writeSerial(serial_fd, packet, length + AMBE3000_HEADER_LEN);
|
||||
|
||||
int32 samples_returned = 0;
|
||||
BufferDescriptor desc = _thumbDVEncodedList_UnlinkHead();
|
||||
|
|
@ -620,65 +623,20 @@ int thumbDV_encode(int serial_fd, short * speech_in, unsigned char * packet_out,
|
|||
|
||||
}
|
||||
|
||||
static void* _thumbDV_readThread(void* param)
|
||||
|
||||
static void _connectSerial(int * serial_fd)
|
||||
{
|
||||
int topFd;
|
||||
fd_set fds;
|
||||
int ret;
|
||||
|
||||
int serial_fd = *(int*)param;
|
||||
topFd = serial_fd + 1;
|
||||
|
||||
output("Serial FD = %d in thumbDV_readThread(). TopFD = %d\n", serial_fd, topFd);
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
while ( !_readThreadAbort ) {
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(serial_fd, &fds);
|
||||
|
||||
errno = 0;
|
||||
ret = select(topFd, &fds, NULL, NULL, &timeout);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ThumbDV: error from select, errno=%d\n", errno);
|
||||
}
|
||||
|
||||
if (FD_ISSET(serial_fd, &fds)) {
|
||||
ret = thumbDV_processSerial(serial_fd);
|
||||
}
|
||||
}
|
||||
|
||||
output(ANSI_YELLOW "thumbDV_readThread has exited\n" ANSI_WHITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thumbDV_init(const char * serial_device_name, int * serial_fd)
|
||||
{
|
||||
pthread_rwlock_init(&_encoded_list_lock, NULL);
|
||||
pthread_rwlock_init(&_decoded_list_lock, NULL);
|
||||
|
||||
pthread_rwlock_wrlock(&_encoded_list_lock);
|
||||
_encoded_root = (BufferDescriptor)safe_malloc(sizeof(buffer_descriptor));
|
||||
memset(_encoded_root, 0, sizeof(buffer_descriptor));
|
||||
_encoded_root->next = _encoded_root;
|
||||
_encoded_root->prev = _encoded_root;
|
||||
pthread_rwlock_unlock(&_encoded_list_lock);
|
||||
|
||||
pthread_rwlock_wrlock(&_decoded_list_lock);
|
||||
_decoded_root = (BufferDescriptor)safe_malloc(sizeof(buffer_descriptor));
|
||||
memset(_decoded_root, 0, sizeof(buffer_descriptor));
|
||||
_decoded_root->next = _decoded_root;
|
||||
_decoded_root->prev = _decoded_root;
|
||||
pthread_rwlock_unlock(&_decoded_list_lock);
|
||||
|
||||
|
||||
int i = 0 ;
|
||||
char device[256] = {0} ;
|
||||
do {
|
||||
*serial_fd = thumbDV_openSerial("/dev/ttyUSB0");
|
||||
if ( *serial_fd < 0 )
|
||||
*serial_fd = thumbDV_openSerial("/dev/ttyUSB1");
|
||||
for ( i = 0 ; i < 25 ; i++ ) {
|
||||
sprintf(device, "/dev/ttyUSB%d", i);
|
||||
*serial_fd =thumbDV_openSerial(device);
|
||||
if ( *serial_fd > 0 ) {
|
||||
/* We opened a valid port */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( * serial_fd < 0 )
|
||||
{
|
||||
|
|
@ -700,20 +658,11 @@ void thumbDV_init(const char * serial_device_name, int * serial_fd)
|
|||
thumbDV_writeSerial(*serial_fd, disable_parity, 6);
|
||||
thumbDV_processSerial(*serial_fd);
|
||||
|
||||
pthread_create(&_read_thread, NULL, &_thumbDV_readThread, serial_fd);
|
||||
|
||||
struct sched_param fifo_param;
|
||||
fifo_param.sched_priority = 30;
|
||||
pthread_setschedparam(_read_thread, SCHED_FIFO, &fifo_param);
|
||||
|
||||
|
||||
unsigned char get_prodID[5] = {0x61, 0x00, 0x01, 0x00, 0x30 };
|
||||
unsigned char get_version[5] = {0x61, 0x00, 0x01, 0x00, 0x31};
|
||||
unsigned char read_cfg[5] = {0x61, 0x00, 0x01, 0x00, 0x37};
|
||||
unsigned char dstar_mode[17] = {0x61, 0x00, 0x0D, 0x00, 0x0A, 0x01, 0x30, 0x07, 0x63, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48};
|
||||
|
||||
|
||||
|
||||
thumbDV_writeSerial(*serial_fd, get_prodID, 5 );
|
||||
thumbDV_writeSerial(*serial_fd, get_version, 5);
|
||||
thumbDV_writeSerial(*serial_fd, read_cfg, 5);
|
||||
|
|
@ -739,3 +688,79 @@ void thumbDV_init(const char * serial_device_name, int * serial_fd)
|
|||
thumbDV_writeSerial(*serial_fd, pkt_fmt, 7);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void* _thumbDV_readThread(void* param)
|
||||
{
|
||||
int topFd;
|
||||
fd_set fds;
|
||||
int ret;
|
||||
|
||||
int serial_fd = *(int*)param;
|
||||
topFd = serial_fd + 1;
|
||||
|
||||
output("Serial FD = %d in thumbDV_readThread(). TopFD = %d\n", serial_fd, topFd);
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
while ( !_readThreadAbort ) {
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(serial_fd, &fds);
|
||||
|
||||
errno = 0;
|
||||
ret = select(topFd, &fds, NULL, NULL, &timeout);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ThumbDV: error from select, errno=%d\n", errno);
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(serial_fd, &fds)) {
|
||||
ret = thumbDV_processSerial(serial_fd);
|
||||
if ( ret != 0 ) {
|
||||
/* Set invalid FD in sched_waveform so we don't call write functions */
|
||||
sched_waveform_setFD(-1);
|
||||
/* This function hangs until a new connection is made */
|
||||
_connectSerial(&serial_fd);
|
||||
/* Update the sched_waveform to new valid serial */
|
||||
sched_waveform_setFD(serial_fd);
|
||||
topFd = serial_fd + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output(ANSI_YELLOW "thumbDV_readThread has exited\n" ANSI_WHITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thumbDV_init(int * serial_fd)
|
||||
{
|
||||
pthread_rwlock_init(&_encoded_list_lock, NULL);
|
||||
pthread_rwlock_init(&_decoded_list_lock, NULL);
|
||||
|
||||
pthread_rwlock_wrlock(&_encoded_list_lock);
|
||||
_encoded_root = (BufferDescriptor)safe_malloc(sizeof(buffer_descriptor));
|
||||
memset(_encoded_root, 0, sizeof(buffer_descriptor));
|
||||
_encoded_root->next = _encoded_root;
|
||||
_encoded_root->prev = _encoded_root;
|
||||
pthread_rwlock_unlock(&_encoded_list_lock);
|
||||
|
||||
pthread_rwlock_wrlock(&_decoded_list_lock);
|
||||
_decoded_root = (BufferDescriptor)safe_malloc(sizeof(buffer_descriptor));
|
||||
memset(_decoded_root, 0, sizeof(buffer_descriptor));
|
||||
_decoded_root->next = _decoded_root;
|
||||
_decoded_root->prev = _decoded_root;
|
||||
pthread_rwlock_unlock(&_decoded_list_lock);
|
||||
|
||||
_connectSerial(serial_fd);
|
||||
|
||||
pthread_create(&_read_thread, NULL, &_thumbDV_readThread, serial_fd);
|
||||
|
||||
struct sched_param fifo_param;
|
||||
fifo_param.sched_priority = 30;
|
||||
pthread_setschedparam(_read_thread, SCHED_FIFO, &fifo_param);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#ifndef THUMBDV_THUMBDV_
|
||||
#define THUMBDV_THUMBDV_
|
||||
|
||||
void thumbDV_init(const char * serial_device_name, int * serial_fd);
|
||||
void thumbDV_init(int * serial_fd);
|
||||
int thumbDV_openSerial(const char * tty_name);
|
||||
int thumbDV_processSerial(int serial_fd);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue