throw std::runtime_error(str.str().c_str());
}
- // Remove extra spaces from string, in place.
+ // Remove redundant elements from string.
static char *
clean_string(char * string)
{
- char * s = string;
+ // Remove trailing space.
+ std::size_t length = strlen(string);
+ char * s = string;
+ // Remove extra spaces from string, in place.
while ( *s != 0 ) {
if ( *s == ' ' && s[1] == ' ' ) {
s++;
s++;
}
- const std::size_t length = strlen(string);
-
+ // Remove trailing space.
+ length = strlen(string);
if ( length > 1 && string[length - 1] == ' ' )
string[length - 1] = '\0';
+ // If a segment of a string ending with a space or tab is repeated
+ // immediately afterward, as with the Manufacturer field and the
+ // Product field containing the same initial string, remove the
+ // initial part. This gets rid of repeated manufacturer names.
+ for ( unsigned int i = 1; i < length; i++ ) {
+ if ( string[i] == ' ' || string[i] == '\t' && string[i+1] != '\0' ) {
+ if ( strncmp(string, &string[i + 1], i + 1) == 0 ) {
+ memmove(string, &string[i + 1], length - i);
+ length = (length - i) - 1;
+ i = 0;
+ }
+ }
+ }
+
return string;
}
bool add_poll_device(IODevice * device);
NORETURN void do_throw(int error, const char * message);
- void receive();
void reset();
+
+ bool drain_digital();
+ bool drain_ssb();
+ void key();
+ void receive();
+ void start_receive();
+ void start_transmit_digital();
+ void start_transmit_ssb();
+ void stop_receive();
void transmit_digital();
void transmit_ssb();
+ void un_key();
public:
/// Construct the context for the main loop of FreeDV.
/// \param interfaces the address of an Interfaces instance containing
&poll_fds[poll_fd_count],
space - poll_fd_count);
- if ( result > 0 )
+ if ( result > 0 ) {
poll_fd_count += result;
+ return true;
+ }
else if ( result < 0 ) {
std::ostringstream str;
device->print(str);
do_throw(result, str.str().c_str());
}
+ return false;
}
NORETURN void
out_fifo.reset();
}
+ bool
+ Run::drain_digital()
+ {
+ static bool done = false;
+ if ( !done ) {
+ done = true;
+ return false;
+ }
+ else {
+ done = false;
+ return true;
+ }
+ }
+
+ bool
+ Run::drain_ssb()
+ {
+ static bool done = false;
+ if ( !done ) {
+ done = true;
+ return false;
+ }
+ else {
+ done = false;
+ return true;
+ }
+ }
+
+ void
+ Run::key()
+ {
+ }
+
// FIX: Parallelize the modem and codec into their own threads. Make the
// FIFO do locking.
void
Run::receive()
{
+ return;
+
// Fill any data that the receiver can provide.
const std::size_t in_samples = min(
i->receiver->ready(),
void
Run::run()
{
+ enum TRState {
+ DrainDigital,
+ DrainSSB,
+ Receive,
+ StartReceive,
+ TransmitDigital,
+ TransmitSSB,
+ UnKey
+ };
+
+ TRState state = StartReceive;
+ bool ptt_digital = false;
+ bool ptt_ssb = false;
+
add_poll_device(i->ptt_input_digital);
add_poll_device(i->ptt_input_ssb);
poll_fds[j].revents = 0;
poll_fds[j].events = POLLIN;
}
-
const int result = IODevice::poll(poll_fds, poll_fd_count, 1000);
if ( result < 0 )
do_throw(result, "Poll");
- if ( i->ptt_input_digital->ready() ) {
- std::cerr << "Digital: " << i->ptt_input_digital->state() << std::endl;
- }
- if ( i->ptt_input_ssb->ready() ) {
- std::cerr << "SSB: " << i->ptt_input_ssb->state() << std::endl;
+ if ( i->ptt_input_digital->ready() )
+ ptt_digital = i->ptt_input_digital->state();
+ if ( i->ptt_input_ssb->ready() )
+ ptt_ssb = i->ptt_input_ssb->state();
+
+ switch ( state ) {
+ case DrainDigital:
+ if ( drain_digital() )
+ state = UnKey;
+ break;
+ case DrainSSB:
+ if ( drain_ssb() )
+ state = UnKey;
+ break;
+ case Receive:
+ case StartReceive:
+ if ( ptt_digital || ptt_ssb ) {
+ if ( state == Receive )
+ stop_receive();
+
+ key();
+ if ( ptt_digital ) {
+ state = TransmitDigital;
+ start_transmit_digital();
+ }
+ else {
+ state = TransmitSSB;
+ start_transmit_ssb();
+ }
+ }
+ else {
+ switch ( state ) {
+ case StartReceive:
+ start_receive();
+ state = Receive;
+ break;
+ case Receive:
+ receive();
+ break;
+ default:
+ throw std::runtime_error("Bad case in switch.");
+ }
+ }
+ break;
+ case TransmitDigital:
+ if ( ptt_digital == false )
+ state = DrainDigital;
+ else
+ transmit_digital();
+ break;
+ case TransmitSSB:
+ if ( ptt_ssb == false )
+ state = DrainSSB;
+ else
+ transmit_ssb();
+ break;
+ case UnKey:
+ if ( ptt_digital || ptt_ssb ) {
+ if ( ptt_digital ) {
+ state = TransmitDigital;
+ start_transmit_digital();
+ }
+ else {
+ state = TransmitSSB;
+ start_transmit_ssb();
+ }
+ }
+ else {
+ un_key();
+ state = StartReceive;
+ }
}
}
}
+ void
+ Run::start_receive()
+ {
+ }
+
+ void
+ Run::start_transmit_digital()
+ {
+ }
+
+ void
+ Run::start_transmit_ssb()
+ {
+ }
+
+ void
+ Run::stop_receive()
+ {
+ }
+
void
Run::transmit_digital()
{
{
}
+ void
+ Run::un_key()
+ {
+ }
+
int
run(Interfaces * i)
{