Skip to content

Commit

Permalink
Work on radio protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
kantooon committed Jan 16, 2018
1 parent 254927d commit 05ad59b
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 44 deletions.
41 changes: 22 additions & 19 deletions gr/gr_modem.cpp
Expand Up @@ -372,6 +372,26 @@ void gr_modem::textData(QString text, int frame_type)
transmit(frames);
}

void gr_modem::binData(QByteArray bin_data, int frame_type)
{
QVector<std::vector<unsigned char>*> frames;
for( int k=0;k<bin_data.length();k+=_tx_frame_length)
{
QByteArray d = bin_data.mid(k,_tx_frame_length);
int copy = _tx_frame_length;
if(d.size() < _tx_frame_length)
copy = d.size();
char * c = d.data();
unsigned char *data = new unsigned char[_tx_frame_length];
memset(data, 0, _tx_frame_length);
memcpy(data, c, copy);
std::vector<unsigned char> *one_frame = frame(data,_tx_frame_length, frame_type);

frames.append(one_frame);
}
transmit(frames);
}

void gr_modem::processPCMAudio(std::vector<float> *audio_data)
{

Expand Down Expand Up @@ -736,25 +756,8 @@ void gr_modem::processReceivedData(unsigned char *received_data, int current_fra
{
emit dataFrameReceived();
_last_frame_type = FrameTypeRepeaterInfo;
char *text_data = new char[_rx_frame_length];
memcpy(text_data, received_data, _rx_frame_length);
quint8 string_length = _rx_frame_length;

for(int ii=_rx_frame_length-1;ii>=0;ii--)
{
QChar x(text_data[ii]);
if(x.unicode()==0)
{
string_length--;
}
else
{
break;
}
}
QString text = QString::fromLocal8Bit(text_data,string_length);
emit repeaterInfoReceived(text);
delete[] text_data;
QByteArray data((const char*)received_data, _rx_frame_length);
emit repeaterInfoReceived(data);
}
else if (current_frame_type == FrameTypeCallsign)
{
Expand Down
4 changes: 3 additions & 1 deletion gr/gr_modem.h
Expand Up @@ -24,6 +24,7 @@
#include <QDateTime>
#include <QtEndian>
#include <QMutex>
#include <QByteArray>
#include <QCoreApplication>
#include <string>
#include "ext/utils.h"
Expand Down Expand Up @@ -86,7 +87,7 @@ class gr_modem : public QObject
void netData(unsigned char *net_data, int size);
void demodulated_audio(short *pcm, short size);
void textReceived(QString text);
void repeaterInfoReceived(QString text);
void repeaterInfoReceived(QByteArray data);
void callsignReceived(QString text);
void audioFrameReceived();
void dataFrameReceived();
Expand All @@ -102,6 +103,7 @@ public slots:
void startTransmission(QString callsign);
void endTransmission(QString callsign);
void textData(QString text, int frame_type = FrameTypeText);
void binData(QByteArray bin_data, int frame_type = FrameTypeRepeaterInfo);
void initTX(int modem_type, std::string device_args, std::string device_antenna, int freq_corr);
void initRX(int modem_type, std::string device_args, std::string device_antenna, int freq_corr);
void deinitTX(int modem_type);
Expand Down
1 change: 1 addition & 0 deletions main.cpp
Expand Up @@ -280,6 +280,7 @@ int main(int argc, char *argv[])
QObject::connect(radio_op, SIGNAL(voipData(short*,int)), client, SLOT(processAudio(short*,int)));

QObject::connect(client,SIGNAL(onlineStations(StationList)),w,SLOT(updateOnlineStations(StationList)));
QObject::connect(client,SIGNAL(onlineStations(StationList)),radio_op,SLOT(setStations(StationList)));
QObject::connect(client,SIGNAL(textMessage(QString)),w,SLOT(displayText(QString)));
QObject::connect(client,SIGNAL(newChannel(Channel*)),w,SLOT(newChannel(Channel*)));
QObject::connect(client,SIGNAL(newChannel(Channel*)),radio_op,SLOT(addChannel(Channel*)));
Expand Down
41 changes: 36 additions & 5 deletions radioop.cpp
Expand Up @@ -74,7 +74,7 @@ RadioOp::RadioOp(Settings *settings, gr::qtgui::sink_c::sptr fft_gui, gr::qtgui:
_modem = new gr_modem(_settings, fft_gui,const_gui, rssi_gui);

QObject::connect(_modem,SIGNAL(textReceived(QString)),this,SLOT(textReceived(QString)));
QObject::connect(_modem,SIGNAL(repeaterInfoReceived(QString)),this,SLOT(repeaterInfoReceived(QString)));
QObject::connect(_modem,SIGNAL(repeaterInfoReceived(QByteArray)),this,SLOT(repeaterInfoReceived(QByteArray)));
QObject::connect(_modem,SIGNAL(callsignReceived(QString)),this,SLOT(callsignReceived(QString)));
QObject::connect(_modem,SIGNAL(audioFrameReceived()),this,SLOT(audioFrameReceived()));
QObject::connect(_modem,SIGNAL(dataFrameReceived()),this,SLOT(dataFrameReceived()));
Expand Down Expand Up @@ -350,7 +350,8 @@ void RadioOp::sendEndBeep()

void RadioOp::sendChannels()
{

QByteArray data = _radio_protocol->buildRepeaterInfo();
sendBinData(data,gr_modem::FrameTypeRepeaterInfo);
}

void RadioOp::startTx()
Expand Down Expand Up @@ -428,6 +429,31 @@ void RadioOp::sendTextData(QString text, int frame_type)
}
}

void RadioOp::sendBinData(QByteArray data, int frame_type)
{
if(_tx_inited)
{
if(!_tx_modem_started)
{
stopTx();
startTx();
}
else
{
startTx();
}
_tx_modem_started = true;
_modem->binData(data, frame_type);
_modem->endTransmission(_callsign);
}
if(!_repeat_text)
{
_mutex->lock();
_process_text = false;
_mutex->unlock();
}
}

void RadioOp::run()
{

Expand Down Expand Up @@ -456,7 +482,7 @@ void RadioOp::run()
emit pingServer();
last_ping_time = time;
}
if((time - last_channel_broadcast_time) > 60)
if((time - last_channel_broadcast_time) > 10)
{
last_channel_broadcast_time = time;
if(_voip_forwarding && !transmitting && !ptt_activated)
Expand Down Expand Up @@ -732,9 +758,9 @@ void RadioOp::textReceived(QString text)
emit printText(text);
}

void RadioOp::repeaterInfoReceived(QString text)
void RadioOp::repeaterInfoReceived(QByteArray data)
{
emit printText(text);
_radio_protocol->dataIn(data);
}

void RadioOp::callsignReceived(QString callsign)
Expand Down Expand Up @@ -787,6 +813,11 @@ void RadioOp::addChannel(Channel *chan)
_radio_protocol->addChannel(chan);
}

void RadioOp::setStations(StationList list)
{
_radio_protocol->setStations(list);
}

void RadioOp::toggleRX(bool value)
{

Expand Down
8 changes: 6 additions & 2 deletions radioop.h
Expand Up @@ -22,6 +22,7 @@
#include <QTimer>
#include <QMutex>
#include <QDir>
#include <QByteArray>
#include <QFileInfo>
#include <QDebug>
#include <QCoreApplication>
Expand All @@ -35,6 +36,7 @@
#include "settings.h"
#include "channel.h"
#include "radioprotocol.h"
#include "station.h"
#include "audio/audioencoder.h"
#include "video/videoencoder.h"
#include "audio/alsaaudio.h"
Expand All @@ -45,7 +47,7 @@
#include <gnuradio/qtgui/number_sink.h>
#include <libconfig.h++>


typedef QVector<Station> StationList;
namespace radio_type
{
enum
Expand Down Expand Up @@ -87,7 +89,7 @@ public slots:
void textData(QString text, bool repeat = false);
void stop();
void textReceived(QString text);
void repeaterInfoReceived(QString text);
void repeaterInfoReceived(QByteArray data);
void callsignReceived(QString callsign);
void audioFrameReceived();
void dataFrameReceived();
Expand Down Expand Up @@ -124,6 +126,7 @@ public slots:
void updateFrequency();
void toggleRepeat(bool value);
void addChannel(Channel* chan);
void setStations(StationList list);

private:
bool _stop;
Expand Down Expand Up @@ -190,6 +193,7 @@ public slots:
void sendEndBeep();
void sendChannels();
void sendTextData(QString text, int frame_type);
void sendBinData(QByteArray data, int frame_type);

};

Expand Down
149 changes: 134 additions & 15 deletions radioprotocol.cpp
@@ -1,31 +1,74 @@
// Written by Adrian Musceac YO8RZZ , started December 2017.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

#include "radioprotocol.h"

RadioProtocol::RadioProtocol(QObject *parent) :
QObject(parent)
{
_voip_channels = new QVector<Channel*>;
_voip_users = new QVector<Station>;
_buffer = new QByteArray;
}


QByteArray RadioProtocol::buildChannelList()
QByteArray RadioProtocol::buildRepeaterInfo()
{
QString repeater_info = "";
QXmlStreamWriter stream(&repeater_info);
stream.setAutoFormatting(true);
stream.writeStartElement("i");
stream.writeStartElement("channels");
QByteArray data;

for(int i=0;i <_voip_channels->size();i++)
{
stream.writeStartElement("channel");
stream.writeAttribute("id",QString::number(_voip_channels->at(i)->id));
stream.writeAttribute("parent_id",QString::number(_voip_channels->at(i)->parent_id));
stream.writeAttribute("name",_voip_channels->at(i)->name);
stream.writeAttribute("description",_voip_channels->at(i)->description);
stream.writeEndElement();
data.append(0xCF);
data.append(0x77);
data.append(0x07);
data.append(0xAB);
data.append(0x1); // TODO: msg type channel
QRadioLink::Channel ch;
ch.set_channel_id(_voip_channels->at(i)->id);
ch.set_parent_id(_voip_channels->at(i)->parent_id);
ch.set_name(_voip_channels->at(i)->name.toStdString().c_str());
ch.set_description(_voip_channels->at(i)->description.toStdString().c_str());
char bin[ch.ByteSize()];
ch.SerializeToArray(bin,ch.ByteSize());
data.append(bin, ch.ByteSize());
data.append(0xAB);
data.append(0x07);
data.append(0x77);
data.append(0xCF);
}
for(int i=0;i <_voip_users->size();i++)
{
data.append(0xCF);
data.append(0x77);
data.append(0x07);
data.append(0xAB);
data.append(0x2); // TODO: msg type user
QRadioLink::User u;
u.set_user_id(_voip_users->at(i).id);
u.set_channel_id(_voip_users->at(i).channel_id);
u.set_name(_voip_users->at(i).callsign.toStdString().c_str());
char bin[u.ByteSize()];
u.SerializeToArray(bin,u.ByteSize());
data.append(bin, u.ByteSize());
data.append(0xAB);
data.append(0x07);
data.append(0x77);
data.append(0xCF);
}
stream.writeEndElement();
stream.writeEndElement();
return repeater_info.toLocal8Bit();
return data;
}

void RadioProtocol::addChannel(Channel *chan)
Expand All @@ -34,4 +77,80 @@ void RadioProtocol::addChannel(Channel *chan)
_voip_channels->push_back(chan);
}

void RadioProtocol::setStations(QVector<Station> list)
{
delete _voip_users;
_voip_users = new QVector<Station>(list);
}

void RadioProtocol::dataIn(QByteArray data)
{
_buffer->append(data);
QByteArray tail;
tail.append(0xAB);
tail.append(0x07);
tail.append(0x77);
tail.append(0xCF);
QByteArray head;
head.append(0xCF);
head.append(0x77);
head.append(0x07);
head.append(0xAB);
int t = _buffer->indexOf(tail);
int h = _buffer->indexOf(head);
if((t != -1) && (h != -1) && (t < h))
{
QByteArray payload = _buffer->left(t);
QByteArray rest = _buffer->mid(t+4);
processPayload(payload);
_buffer->clear();
dataIn(rest);
}
else if((t != -1) && (h == -1))
{
QByteArray payload = _buffer->left(t);
processPayload(payload);
QByteArray rest = _buffer->mid(t+4);
_buffer->clear();
_buffer->append(rest);
}
else if((t != -1) && (h != -1) && (t > h))
{
QByteArray rest = _buffer->mid(h+4);
_buffer->clear();
dataIn(rest);
}
else if((t == -1) && (h != -1))
{
QByteArray rest = _buffer->mid(h+4);
_buffer->clear();
_buffer->append(rest);
}

}

void RadioProtocol::processPayload(QByteArray data)
{

int msg_type = data.at(0);
data = data.mid(1);
switch(msg_type)
{
case 1:
{
QRadioLink::Channel ch;
ch.ParseFromArray(data,data.size());
qDebug() << QString::fromStdString(ch.name());
break;
}
case 2:
{
QRadioLink::User u;
u.ParseFromArray(data,data.size());
qDebug() << QString::fromStdString(u.name());
break;
}
}
}


0 comments on commit 05ad59b

Please sign in to comment.