stuff learned from non-blocking experiment

pull/12/head
Tom Early 7 years ago
parent 273c978a0c
commit 1fb7271f11

@ -80,6 +80,36 @@ CQnetModem::~CQnetModem()
{ {
} }
bool CQnetModem::GetBufferSize()
{
std::this_thread::sleep_for(std::chrono::seconds(2));
for (int i=0; i<6; i++) {
SMODEM frame;
frame.start = FRAME_START;
frame.length = 0x3U;
frame.type = TYPE_STATUS;
if (3 != SendToModem(&frame.start))
return true;
for (int count = 0; count < MAX_RESPONSES; count++) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
MODEM_RESPONSE resp = GetModemData(&frame.start, sizeof(SVERSION));
if (resp == STATUS_RESPONSE) {
dstarSpace = frame.status.dsrsize;
printf("D-Star buffer will hold %u voice frames\n", dstarSpace);
return false;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}
fprintf(stderr, "Unable to read the firmware version after six attempts\n");
return true;
}
bool CQnetModem::GetVersion() bool CQnetModem::GetVersion()
{ {
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
@ -141,7 +171,7 @@ bool CQnetModem::SetFrequency()
if (hardwareType == HWT_DVMEGA) if (hardwareType == HWT_DVMEGA)
frame.length = 12U; frame.length = 12U;
else { else {
frame.frequency.level = 0x0U; frame.frequency.level = 255U;
frame.frequency.ps = __builtin_bswap32(htonl(pocsagFrequency)); frame.frequency.ps = __builtin_bswap32(htonl(pocsagFrequency));
frame.length = 17U; frame.length = 17U;
@ -218,6 +248,9 @@ bool CQnetModem::Initialize(const char *cfgfile)
if (SetConfiguration()) if (SetConfiguration())
return true; return true;
if (GetBufferSize())
return true;
return false; return false;
} }
@ -329,9 +362,10 @@ MODEM_RESPONSE CQnetModem::GetModemData(unsigned char *buf, unsigned int size)
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error when reading frame start byte: %s\n", strerror(errno)); fprintf(stderr, "Error when reading frame start byte: %s\n", strerror(errno));
return ERROR_RESPONSE; return ERROR_RESPONSE;
} else if (ret == 0) } else if (ret == 0) {
printf("READ START RETURNED A ZERO!\n");
return TIMEOUT_RESPONSE; return TIMEOUT_RESPONSE;
else if (buf[0] != FRAME_START) } else if (buf[0] != FRAME_START)
return TIMEOUT_RESPONSE; return TIMEOUT_RESPONSE;
//get the length byte //get the length byte
@ -340,20 +374,21 @@ MODEM_RESPONSE CQnetModem::GetModemData(unsigned char *buf, unsigned int size)
fprintf(stderr, "Error when reading frame length: %s\n", strerror(errno)); fprintf(stderr, "Error when reading frame length: %s\n", strerror(errno));
return ERROR_RESPONSE; return ERROR_RESPONSE;
} else if (ret == 0) { } else if (ret == 0) {
printf("READ LENGTH RETURNED A ZERO!\n");
return(TIMEOUT_RESPONSE); return(TIMEOUT_RESPONSE);
} else if ((unsigned int)buf[1] > size) {
fprintf(stderr, "Error, buffer is %u bytes, but returned frame is %u bytes\n", size, (unsigned int)buf[1]);
return ERROR_RESPONSE;
} }
// is the packet size bigger than a D-Star header (44 bytes)?
unsigned int junk_count = ((unsigned int)buf[1] > size) ? (unsigned int)buf[1] - size : 0;
// get the type byte // get the type byte
ret = read(serfd, buf+2, 1U); ret = read(serfd, buf+2, 1U);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error when reading frame type: %s\n", strerror(errno)); fprintf(stderr, "Error when reading frame type: %s\n", strerror(errno));
return ERROR_RESPONSE; return ERROR_RESPONSE;
} else if (ret == 0) } else if (ret == 0) {
printf("READ TYPE RETURNED A ZERO!\n");
return(TIMEOUT_RESPONSE); return(TIMEOUT_RESPONSE);
}
// get the data // get the data
unsigned int length = buf[1]; unsigned int length = buf[1];
unsigned int offset = 3; unsigned int offset = 3;
@ -363,7 +398,23 @@ MODEM_RESPONSE CQnetModem::GetModemData(unsigned char *buf, unsigned int size)
printf("Error when reading data: %s\n", strerror(errno)); printf("Error when reading data: %s\n", strerror(errno));
return ERROR_RESPONSE; return ERROR_RESPONSE;
} }
offset += ret; if (ret == 0) {
printf("READ DATA RETURNED A ZERO!\n");
} else
offset += ret;
}
while (junk_count) {
unsigned char junk[8];
ret = read(serfd, junk, (junk_count < 8U) ? 8U : junk_count);
if (ret < 0) {
printf("Error when reading junk: %s\n", strerror(errno));
return ERROR_RESPONSE;
}
if (ret == 0) {
printf("READ junk RETURNED A ZERO!\n");
} else
junk_count -= (unsigned int)ret;
} }
switch (buf[2]) { switch (buf[2]) {
@ -473,13 +524,13 @@ void CQnetModem::Run(const char *cfgfile)
} }
if (keep_running) { if (keep_running) {
if (g2_is_active && PacketWait.time() > packet_wait) { //if (g2_is_active && PacketWait.time() > packet_wait) {
// g2 has timed out // // g2 has timed out
frame.length = 3U; // frame.length = 3U;
frame.type = TYPE_LOST; // frame.type = TYPE_LOST;
queue.push(CFrame(&frame.start)); // queue.push(CFrame(&frame.start));
g2_is_active = false; // g2_is_active = false;
} //}
if (! queue.empty()) { if (! queue.empty()) {
// send queued D-Star frames to modem // send queued D-Star frames to modem
CFrame cframe = queue.front(); CFrame cframe = queue.front();
@ -554,6 +605,11 @@ bool CQnetModem::ProcessGateway(const int len, const unsigned char *raw)
printf("Queued to %s flags=%02x:%02x:%02x ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s\n", MODEM_DEVICE.c_str(), frame.header.flag[0], frame.header.flag[1], frame.header.flag[2], frame.header.ur, frame.header.r1, frame.header.r2, frame.header.my, frame.header.nm); printf("Queued to %s flags=%02x:%02x:%02x ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s\n", MODEM_DEVICE.c_str(), frame.header.flag[0], frame.header.flag[1], frame.header.flag[2], frame.header.ur, frame.header.r1, frame.header.r2, frame.header.my, frame.header.nm);
} else { // write a voice data packet } else { // write a voice data packet
if (g2_is_active) { if (g2_is_active) {
//const unsigned char sdsync[3] = { 0x55U, 0x2DU, 0x16U };
if (0U == (0x3FU & dstr.vpkt.ctrl)) {
if (0x55U!=dstr.vpkt.vasd.text[0] || 0x2DU!=dstr.vpkt.vasd.text[1] || 0x16U!=dstr.vpkt.vasd.text[2])
printf("Warning: Voice sync frame contained text %02x:%02x:%02x!\n", dstr.vpkt.vasd.text[0], dstr.vpkt.vasd.text[1], dstr.vpkt.vasd.text[2]);
}
if (dstr.vpkt.ctrl & 0x40U) { if (dstr.vpkt.ctrl & 0x40U) {
frame.length = 3U; frame.length = 3U;
frame.type = TYPE_EOT; frame.type = TYPE_EOT;
@ -622,10 +678,19 @@ bool CQnetModem::ProcessModem(const SMODEM &frame)
if (ctrl >= 21U) if (ctrl >= 21U)
ctrl = 0U; ctrl = 0U;
if (frame.type == TYPE_DATA) { if (frame.type == TYPE_DATA) {
//const unsigned char sdsync[3] = { 0x55U, 0x2DU, 0x16U };
if (0U == (0x3FU & dstr.vpkt.ctrl)) {
if (0x55U!=frame.voice.text[0] || 0x2DU!=frame.voice.text[1] || 0x16U!=frame.voice.text[2])
printf("Warning: Voice sync frame contained text %02x:%02x:%02x!\n", frame.voice.text[0], frame.voice.text[1], frame.voice.text[2]);
}
memcpy(dstr.vpkt.vasd.voice, frame.voice.ambe, 12); memcpy(dstr.vpkt.vasd.voice, frame.voice.ambe, 12);
} else { } else {
const unsigned char silence[12] = { 0x4EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U }; const unsigned char silence[12] = { 0x4EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U };
memcpy(dstr.vpkt.vasd.voice, silence, 12); const unsigned char silsync[12] = { 0x4EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x55U,0x2DU,0x16U };
if (0U == dstr.vpkt.ctrl)
memcpy(dstr.vpkt.vasd.voice, silsync, 12);
else
memcpy(dstr.vpkt.vasd.voice, silence, 12);
dstr.vpkt.ctrl |= 0x40U; dstr.vpkt.ctrl |= 0x40U;
} }
if (29 != Modem2Gate.Write(dstr.pkt_id, 29)) { if (29 != Modem2Gate.Write(dstr.pkt_id, 29)) {
@ -639,6 +704,11 @@ bool CQnetModem::ProcessModem(const SMODEM &frame)
else else
printf("Sent lost end of streamid=%04x\n", ntohs(dstr.vpkt.streamid)); printf("Sent lost end of streamid=%04x\n", ntohs(dstr.vpkt.streamid));
} }
} else {
fprintf(stderr, "Warning! Unexpected frame type %02x", frame.start);
for (unsigned int i=0; i<frame.length; i++)
fprintf(stderr, ":%02x", *(&frame.start + i));
fprintf(stderr, "\n");
} }
return false; return false;

@ -81,7 +81,6 @@ typedef struct mmodem_tag {
// 0x12U transmission lost // 0x12U transmission lost
// 0x13U transmission end // 0x13U transmission end
union { union {
unsigned char unused[51]; // this makes room for trailing crap on the header
unsigned char ack; // the type being acknowledged unsigned char ack; // the type being acknowledged
unsigned char mode; // 0 idle, 1 dstar, 2 dmr, 3 ysf, 99 calibration unsigned char mode; // 0 idle, 1 dstar, 2 dmr, 3 ysf, 99 calibration
struct { struct {
@ -183,7 +182,7 @@ public:
} }
double time() { double time() {
std::chrono::steady_clock::duration elapsed = std::chrono::steady_clock::now() - starttime; std::chrono::steady_clock::duration elapsed = std::chrono::steady_clock::now() - starttime;
return double(elapsed.count() * std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den); return double(elapsed.count()) * std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den;
} }
private: private:
std::chrono::steady_clock::time_point starttime; std::chrono::steady_clock::time_point starttime;
@ -203,7 +202,7 @@ public:
private: private:
int assigned_module; int assigned_module;
unsigned short COUNTER; unsigned short COUNTER;
unsigned char dstarSpace; unsigned int dstarSpace;
bool g2_is_active; bool g2_is_active;
// functions // functions
@ -215,6 +214,7 @@ private:
int SendToModem(const unsigned char *buf); int SendToModem(const unsigned char *buf);
MODEM_RESPONSE GetModemData(unsigned char *buf, unsigned int size); MODEM_RESPONSE GetModemData(unsigned char *buf, unsigned int size);
bool GetVersion(); bool GetVersion();
bool GetBufferSize();
bool SetFrequency(); bool SetFrequency();
bool SetConfiguration(); bool SetConfiguration();

Loading…
Cancel
Save

Powered by TurnKey Linux.