From 74fc96eb687853900151ccf05ceee8bb2d9759cd Mon Sep 17 00:00:00 2001 From: bruceperens Date: Tue, 22 Apr 2014 00:17:58 +0000 Subject: [PATCH] Write PTT logic. git-svn-id: https://svn.code.sf.net/p/freetel/code@1537 01035d8c-6547-0410-b346-abe4f91aad63 --- freedv-server/source/platform/linux/evdev.cpp | 25 ++- .../source/platform/linux/ptt_evdev.cpp | 3 + freedv-server/source/run.cpp | 167 +++++++++++++++++- 3 files changed, 183 insertions(+), 12 deletions(-) diff --git a/freedv-server/source/platform/linux/evdev.cpp b/freedv-server/source/platform/linux/evdev.cpp index ec38dcf2..39dafda6 100644 --- a/freedv-server/source/platform/linux/evdev.cpp +++ b/freedv-server/source/platform/linux/evdev.cpp @@ -50,12 +50,15 @@ namespace FreeDV { 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++; @@ -67,11 +70,25 @@ namespace FreeDV { 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; } diff --git a/freedv-server/source/platform/linux/ptt_evdev.cpp b/freedv-server/source/platform/linux/ptt_evdev.cpp index 864ac16c..9c1ce917 100644 --- a/freedv-server/source/platform/linux/ptt_evdev.cpp +++ b/freedv-server/source/platform/linux/ptt_evdev.cpp @@ -127,6 +127,9 @@ namespace FreeDV { for ( std::size_t i = 0; i < count; i++ ) { const input_event * const event = &events[i]; + if ( event->type == EV_KEY ) { + std::cerr << event->code << std::endl; + } if ( event->type == EV_KEY && event->code == button_index ) { switch ( event->value ) { case 0: diff --git a/freedv-server/source/run.cpp b/freedv-server/source/run.cpp index 5d94066a..7a029e0c 100644 --- a/freedv-server/source/run.cpp +++ b/freedv-server/source/run.cpp @@ -41,10 +41,19 @@ namespace FreeDV { 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 @@ -78,14 +87,17 @@ namespace FreeDV { &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 @@ -112,11 +124,46 @@ namespace FreeDV { 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(), @@ -220,6 +267,20 @@ namespace FreeDV { 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); @@ -228,22 +289,107 @@ namespace FreeDV { 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() { @@ -254,6 +400,11 @@ namespace FreeDV { { } + void + Run::un_key() + { + } + int run(Interfaces * i) { -- 2.25.1