6
.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
*.o
|
||||
xlxd
|
||||
ambed
|
||||
ambedtest
|
||||
src/xlxd
|
||||
ambed/ambed
|
||||
ambedtest/ambedtest
|
||||
|
|
|
|||
271
README.md
|
|
@ -1,124 +1,147 @@
|
|||
# Copyright
|
||||
|
||||
© 2016 Luc Engelmann LX1IQ
|
||||
|
||||
The XLX Multiprotocol Gateway Reflector Server is part of the software system
|
||||
for the D-Star Network.
|
||||
The sources are published under GPL Licenses.
|
||||
|
||||
# Usage
|
||||
|
||||
The packages which are described in this document are designed to install server
|
||||
software which is used for the D-Star network infrastructure.
|
||||
It requires a 24/7 internet connection which can support 20 voice streams or more
|
||||
to connect repeaters and hotspot dongles!!
|
||||
|
||||
- The server requires a fix IP-address !
|
||||
- The public IP address should have a DNS record which must be published in the
|
||||
common host files.
|
||||
|
||||
If you want to run this software please make sure that you can provide this
|
||||
service free of charge, like the developer team provides the software and the
|
||||
network infrastructure free of charge!
|
||||
|
||||
# Requirements
|
||||
|
||||
The software packages for Linux are tested on Debian7 (Wheezy) 32 and 64bit or newer.
|
||||
Raspbian will work but is not recommended.
|
||||
Please use the stable version listed above, we cannot support others.
|
||||
|
||||
# Installation
|
||||
|
||||
## Debian 7 (Wheezy) 32 and 64bit
|
||||
|
||||
###### After a clean installation of debian make sure to run update and upgrade
|
||||
```
|
||||
# apt-get update
|
||||
# apt-get upgrade
|
||||
```
|
||||
###### Install Git
|
||||
```
|
||||
# apt-get install git git-core
|
||||
```
|
||||
###### Install webserver with PHP5 support
|
||||
```
|
||||
# apt-get install apache2 php5
|
||||
```
|
||||
|
||||
###### Install g++ compiler
|
||||
```
|
||||
# apt-get install build-essential
|
||||
# apt-get install g++-4.7 (skip this step on Debian 8.x)
|
||||
```
|
||||
|
||||
###### Download and compile the XLX sources
|
||||
```
|
||||
# git clone https://github.com/LX3JL/xlxd.git
|
||||
# cd xlxd/src/
|
||||
# make clean
|
||||
# make
|
||||
# make install
|
||||
```
|
||||
|
||||
###### Copy startup script "xlxd" to /etc/init.d
|
||||
```
|
||||
# cp ~/xlxd/scripts/xlxd /etc/init.d/xlxd
|
||||
```
|
||||
|
||||
###### Adapt the default startup parameters to your needs
|
||||
```
|
||||
# pico /etc/init.d/xlxd
|
||||
```
|
||||
###### Download the dmrid.dat from the XLXAPI server to your xlxd folder
|
||||
```
|
||||
# wget -O /xlxd/dmrid.dat http://xlxapi.rlx.lu/api/exportdmr.php
|
||||
```
|
||||
|
||||
###### Check your FTDI driver and install the AMBE service according to the readme in AMBEd
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
###### Last step is to declare the service for automatic startup and shutdown
|
||||
```
|
||||
# update-rc.d xlxd defaults
|
||||
```
|
||||
|
||||
###### Start or stop the service with
|
||||
```
|
||||
# service xlxd start
|
||||
# service xlxd stop
|
||||
```
|
||||
|
||||
###### Copy dashboard to /var/www
|
||||
```
|
||||
# cp -r ~/xlxd/dashboard /var/www/db
|
||||
```
|
||||
|
||||
###### Give the dashboard read access to the server log file
|
||||
```
|
||||
# chmod +r /var/log/messages
|
||||
```
|
||||
|
||||
###### Reboot server to see if the auto-start is working
|
||||
```
|
||||
# reboot
|
||||
```
|
||||
|
||||
# Firewall settings #
|
||||
|
||||
XLX Server requires the following ports to be open and forwarded properly for in- and outgoing network traffic:
|
||||
- TCP port 80 (http) optional TCP port 443 (https)
|
||||
- TCP port 8080 (RepNet) optional
|
||||
- UDP port 10001 (json interface XLX Core)
|
||||
- UDP port 10002 (XLX interlink)
|
||||
- TCP port 22 (ssh) optional TCP port 10022
|
||||
- UDP port 30001 (DExtra protocol)
|
||||
- UPD port 20001 (DPlus protocol)
|
||||
- UDP port 30051 (DCS protocol)
|
||||
- UDP port 8880 (DMR+ DMO mode)
|
||||
- UDP port 62030 (MMDVM protocol)
|
||||
- UDP port 10100 (AMBE controller port)
|
||||
- UDP port 10101 - 10199 (AMBE transcoding port)
|
||||
|
||||
© 2016 Luc Engelmann LX1IQ
|
||||
# Copyright
|
||||
|
||||
© 2016 Jean-Luc Deltombe LX3JL and Luc Engelmann LX1IQ
|
||||
|
||||
The XLX Multiprotocol Gateway Reflector Server is part of the software system
|
||||
for the D-Star Network.
|
||||
The sources are published under GPL Licenses.
|
||||
|
||||
# Supported Protocols since XLX v2.5.x
|
||||
|
||||
- In D-Star, Icom-G3Terminal, DExtra, DPLus and DCS
|
||||
- In DMR, DMRPlus (dongle) and DMRMmdvm
|
||||
- In C4FM, YSF, Wires-X and IMRS
|
||||
- XLX Interlink protocol
|
||||
|
||||
# Usage
|
||||
|
||||
The packages which are described in this document are designed to install server
|
||||
software which is used for the D-Star network infrastructure.
|
||||
It requires a 24/7 internet connection which can support 20 voice streams or more
|
||||
to connect repeaters and hotspot dongles!!
|
||||
|
||||
- The server requires a fix IP-address !
|
||||
- The public IP address should have a DNS record which must be published in the
|
||||
common host files.
|
||||
|
||||
If you want to run this software please make sure that you can provide this
|
||||
service free of charge, like the developer team provides the software and the
|
||||
network infrastructure free of charge!
|
||||
|
||||
# Requirements
|
||||
|
||||
The software packages for Linux are tested on Debian7 (Wheezy) 32 and 64bit or newer.
|
||||
Raspbian will work but is not recommended.
|
||||
Please use the stable version listed above, we cannot support others.
|
||||
|
||||
# Installation
|
||||
|
||||
## Debian 7 (Wheezy) 32 and 64bit
|
||||
|
||||
###### After a clean installation of debian make sure to run update and upgrade
|
||||
```
|
||||
# apt-get update
|
||||
# apt-get upgrade
|
||||
```
|
||||
###### Install Git
|
||||
```
|
||||
# apt-get install git git-core
|
||||
```
|
||||
###### Install webserver with PHP5 support
|
||||
```
|
||||
# apt-get install apache2 php5
|
||||
```
|
||||
|
||||
###### Install g++ compiler
|
||||
```
|
||||
# apt-get install build-essential
|
||||
# apt-get install g++-4.7 (skip this step on Debian 8.x)
|
||||
```
|
||||
###### After downloading and before compiling, please have a look at the main.h file
|
||||
```
|
||||
# nano /xlxd/src/main.h
|
||||
|
||||
For YSF you need to define a default HotSpot frequency !!!
|
||||
|
||||
```
|
||||
###### Download and compile the XLX sources
|
||||
```
|
||||
# git clone https://github.com/LX3JL/xlxd.git
|
||||
# cd xlxd/src/
|
||||
# make clean
|
||||
# make
|
||||
# make install
|
||||
```
|
||||
|
||||
###### Copy startup script "xlxd" to /etc/init.d
|
||||
```
|
||||
# cp ~/xlxd/scripts/xlxd /etc/init.d/xlxd
|
||||
```
|
||||
|
||||
###### Adapt the default startup parameters to your needs
|
||||
```
|
||||
# pico /etc/init.d/xlxd
|
||||
```
|
||||
###### Download the dmrid.dat from the XLXAPI server to your xlxd folder
|
||||
```
|
||||
# wget -O /xlxd/dmrid.dat http://xlxapi.rlx.lu/api/exportdmr.php
|
||||
```
|
||||
|
||||
###### Check your FTDI driver and install the AMBE service according to the readme in AMBEd
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
###### Last step is to declare the service for automatic startup and shutdown
|
||||
```
|
||||
# update-rc.d xlxd defaults
|
||||
```
|
||||
|
||||
###### Start or stop the service with
|
||||
```
|
||||
# service xlxd start
|
||||
# service xlxd stop
|
||||
```
|
||||
|
||||
###### Copy dashboard to /var/www
|
||||
```
|
||||
# cp -r ~/xlxd/dashboard /var/www/db
|
||||
```
|
||||
|
||||
###### Give the dashboard read access to the server log file
|
||||
```
|
||||
# chmod +r /var/log/messages
|
||||
```
|
||||
|
||||
###### Reboot server to see if the auto-start is working
|
||||
```
|
||||
# reboot
|
||||
```
|
||||
|
||||
# Firewall settings #
|
||||
|
||||
XLX Server requires the following ports to be open and forwarded properly for in- and outgoing network traffic:
|
||||
- TCP port 80 (http) optional TCP port 443 (https)
|
||||
- TCP port 8080 (RepNet) optional
|
||||
- UDP port 10001 (json interface XLX Core)
|
||||
- UDP port 10002 (XLX interlink)
|
||||
- TCP port 22 (ssh) optional TCP port 10022
|
||||
- UDP port 42000 (YSF protocol)
|
||||
- UDP port 30001 (DExtra protocol)
|
||||
- UPD port 20001 (DPlus protocol)
|
||||
- UDP port 30051 (DCS protocol)
|
||||
- UDP port 8880 (DMR+ DMO mode)
|
||||
- UDP port 62030 (MMDVM protocol)
|
||||
- UDP port 10100 (AMBE controller port)
|
||||
- UDP port 10101 - 10199 (AMBE transcoding port)
|
||||
- UDP port 12345 - 12346 (Icom Terminal presence and request port)
|
||||
- UDP port 40000 (Icom Terminal dv port)
|
||||
- UDP port 21110 (Yaesu IMRS protocol)
|
||||
|
||||
# YSF Master Server
|
||||
|
||||
Pay attention, the XLX Server acts as an YSF Master, which provides 26 wires-x rooms.
|
||||
It has nothing to do with the regular YSFReflector network, hence you don’t need to register your XLX at ysfreflector.de !
|
||||
Nevertheless it is possible.
|
||||
|
||||
© 2016 Jean-Luc Deltombe (LX3JL) and Luc Engelmann (LX1IQ)
|
||||
|
|
|
|||
94
ambed/cagc.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// cagc.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 28/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA AGC code borrowed from Liquid DSP
|
||||
// Only took the parts we need qnd recoeded it to be close the XLX coding style
|
||||
// https://github.com/jgaeddert/liquid-dsp/blob/master/src/agc/src/agc.c
|
||||
|
||||
#include <math.h>
|
||||
#include "cagc.h"
|
||||
#include "main.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CAGC::CAGC(float initialLeveldB)
|
||||
{
|
||||
// set internal gain appropriately
|
||||
m_Gain = pow(10.0f, initialLeveldB/20.0f);
|
||||
//+- 10dB Margin, TODO Move margin to constant
|
||||
m_GainMax = pow(10.0f, (initialLeveldB + AGC_CLAMPING)/20.0f);
|
||||
m_GainMin = pow(10.0f, (initialLeveldB - AGC_CLAMPING)/20.0f);
|
||||
|
||||
m_EnergyPrime = 1.0f;
|
||||
|
||||
// We do not target full scale to avoid stauration
|
||||
m_targetEnergy = 32767.0f * pow(10.0f, (initialLeveldB - 25.0)/20.0f);//25 dB below saturation as stated in docs
|
||||
//we also substract our target gain
|
||||
|
||||
//this is the time constant of our AGC...
|
||||
m_Bandwidth = 1e-2f;//TODO : Move to parameter ?
|
||||
m_Alpha = m_Bandwidth;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get
|
||||
|
||||
float CAGC::GetGain()
|
||||
{
|
||||
return 20.0f*log10(m_Gain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// process
|
||||
|
||||
inline void CAGC::ProcessSampleBlock(uint8* voice, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i += 2)
|
||||
{
|
||||
float input = (float)(short)MAKEWORD(voice[i+1], voice[i]);
|
||||
//apply AGC
|
||||
// apply gain to input sample
|
||||
float output = input * m_Gain;
|
||||
|
||||
// compute output signal energy, scaled to 0 to 1
|
||||
float instantEnergy = abs(output) / m_targetEnergy;
|
||||
|
||||
// smooth energy estimate using single-pole low-pass filter
|
||||
m_EnergyPrime = (1.0f - m_Alpha) * m_EnergyPrime + m_Alpha * instantEnergy;
|
||||
|
||||
// update gain according to output energy
|
||||
if (m_EnergyPrime > 1e-6f)
|
||||
m_Gain *= exp( -0.5f * m_Alpha * log(m_EnergyPrime) );
|
||||
|
||||
// clamp gain
|
||||
if (m_Gain > m_GainMax)
|
||||
m_Gain = m_GainMax;
|
||||
else if(m_Gain < m_GainMin)
|
||||
m_Gain = m_GainMin;
|
||||
|
||||
//write processed sample back
|
||||
voice[i] = HIBYTE((short)output);
|
||||
voice[i+1] = LOBYTE((short)output);
|
||||
}
|
||||
}
|
||||
56
ambed/cagc.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// cagc.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA AGC code largely inspired by Liquid DSP
|
||||
// Only took the parts we need qnd recoeded it to be close the XLX coding style
|
||||
// https://github.com/jgaeddert/liquid-dsp/blob/master/src/agc/src/agc.c
|
||||
|
||||
#ifndef cagc_h
|
||||
#define cagc_h
|
||||
|
||||
#include "csampleblockprocessor.h"
|
||||
|
||||
class CAGC : CSampleBlockProcessor
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CAGC(float initialLeveldB);
|
||||
|
||||
//methods
|
||||
void ProcessSampleBlock(uint8* voice, int length) ;
|
||||
float GetGain();//gets current gain
|
||||
|
||||
private:
|
||||
float m_Gain; // current gain value
|
||||
float m_GainMax, m_GainMin; //gain clamping
|
||||
float m_targetEnergy; // scale value for target energy
|
||||
|
||||
// gain control loop filter parameters
|
||||
float m_Bandwidth; // bandwidth-time constant
|
||||
float m_Alpha; // feed-back gain
|
||||
|
||||
// signal level estimate
|
||||
float m_EnergyPrime; // filtered output signal energy estimate
|
||||
};
|
||||
|
||||
#endif /* cgc_h */
|
||||
|
|
@ -48,6 +48,9 @@ public:
|
|||
// destructor
|
||||
virtual ~CAmbePacket();
|
||||
|
||||
// identity
|
||||
bool IsAmbe(void) const { return true; }
|
||||
|
||||
// get
|
||||
uint8 GetCodec(void) const { return m_uiCodec; }
|
||||
uint8 *GetAmbe(void) { return m_uiAmbe; }
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ void CController::Task(void)
|
|||
// crack packet
|
||||
if ( IsValidOpenstreamPacket(Buffer, &Callsign, &CodecIn, &CodecOut) )
|
||||
{
|
||||
std::cout << "Stream Open from " << Callsign << std::endl;
|
||||
std::cout << "Stream Open from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
// try create the stream
|
||||
Stream = OpenStream(Callsign, Ip, CodecIn, CodecOut);
|
||||
|
|
|
|||
75
ambed/cfirfilter.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// cfirfilter.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// FIRFilter by Geoffrey Merck F4FXL / KC3FRA
|
||||
|
||||
#include "cfirfilter.h"
|
||||
#include <string.h>
|
||||
|
||||
CFIRFilter::CFIRFilter(const float* taps, int tapsLength)
|
||||
{
|
||||
m_taps = new float[tapsLength];
|
||||
m_buffer = new float[tapsLength];
|
||||
m_tapsLength = tapsLength;
|
||||
|
||||
::memcpy(m_taps, taps, tapsLength * sizeof(float));
|
||||
::memset(m_buffer, 0, tapsLength * sizeof(float));
|
||||
m_currentBufferPosition = 0;
|
||||
}
|
||||
|
||||
CFIRFilter::~CFIRFilter()
|
||||
{
|
||||
delete[] m_taps;
|
||||
delete[] m_buffer;
|
||||
}
|
||||
|
||||
inline void CFIRFilter::ProcessSampleBlock(uint8* voice, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i += 2)
|
||||
{
|
||||
float input = (float)(short)MAKEWORD(voice[i+1], voice[i]);
|
||||
float output = 0.0f;
|
||||
int iTaps = 0;
|
||||
|
||||
// Buffer latest sample into delay line
|
||||
m_buffer[m_currentBufferPosition] = input;
|
||||
|
||||
for(int i = m_currentBufferPosition; i >= 0; i--)
|
||||
{
|
||||
output += m_taps[iTaps++] * m_buffer[i];
|
||||
}
|
||||
|
||||
for(int i = m_tapsLength - 1; i > m_currentBufferPosition; i--)
|
||||
{
|
||||
output += m_taps[iTaps++] * m_buffer[i];
|
||||
}
|
||||
|
||||
m_currentBufferPosition = (m_currentBufferPosition + 1) % m_tapsLength;
|
||||
|
||||
//write processed sample back
|
||||
voice[i] = HIBYTE((short)output);
|
||||
voice[i+1] = LOBYTE((short)output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
ambed/cfirfilter.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// cfirfilter.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// FIRFilter by Geoffrey Merck F4FXL / KC3FRA
|
||||
|
||||
#ifndef cfirfilter_h
|
||||
#define cfirfilter_h
|
||||
|
||||
#include "csampleblockprocessor.h"
|
||||
|
||||
class CFIRFilter : CSampleBlockProcessor
|
||||
{
|
||||
public :
|
||||
//Constructor
|
||||
CFIRFilter(const float* taps, int tapsLength);
|
||||
|
||||
// Destructor
|
||||
~CFIRFilter();
|
||||
|
||||
// Processing
|
||||
void ProcessSampleBlock(uint8* voice, int length);
|
||||
|
||||
private:
|
||||
float* m_taps;
|
||||
int m_tapsLength;
|
||||
float* m_buffer;
|
||||
int m_currentBufferPosition;
|
||||
};
|
||||
|
||||
#endif //cfirfilter_h
|
||||
|
||||
53
ambed/cfixedgain.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// cfixedgain.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 28/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA AGC
|
||||
|
||||
#include "cfixedgain.h"
|
||||
#include <math.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CFixedGain::CFixedGain(float gaindB)
|
||||
{
|
||||
m_gaindB = gaindB;
|
||||
m_gainLinear = pow(10.0f, m_gaindB/20.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// processing
|
||||
|
||||
inline void CFixedGain::ProcessSampleBlock(uint8* voice, int length)
|
||||
{
|
||||
for(int i = 0; i < length; i += 2)
|
||||
{
|
||||
float input = (float)(short)MAKEWORD(voice[i+1], voice[i]);
|
||||
//apply gain
|
||||
float output = input * m_gainLinear;
|
||||
|
||||
//write processed sample back
|
||||
voice[i] = HIBYTE((short)output);
|
||||
voice[i+1] = LOBYTE((short)output);
|
||||
}
|
||||
}
|
||||
45
ambed/cfixedgain.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// cfixedgain.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA
|
||||
|
||||
#ifndef cfixedgain_h
|
||||
#define cfixedgain_h
|
||||
|
||||
#include "csampleblockprocessor.h"
|
||||
|
||||
class CFixedGain : CSampleBlockProcessor
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CFixedGain(float gaindB);
|
||||
|
||||
//processing
|
||||
void ProcessSampleBlock(uint8* voice, int length);
|
||||
|
||||
private:
|
||||
float m_gaindB; //gain in dB
|
||||
float m_gainLinear; //linearized gain
|
||||
};
|
||||
|
||||
#endif /* cfixedgain_h */
|
||||
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "cusb3000interface.h"
|
||||
#include "cusb3003interface.h"
|
||||
#include "cusb3003hrinterface.h"
|
||||
#include "cusb3003df2etinterface.h"
|
||||
#include "cftdidevicedescr.h"
|
||||
|
||||
|
||||
|
|
@ -56,3 +60,537 @@ CFtdiDeviceDescr::CFtdiDeviceDescr(const CFtdiDeviceDescr &descr)
|
|||
::memcpy(m_szDescription, descr.m_szDescription, sizeof(m_szDescription));
|
||||
::memcpy(m_szSerial, descr.m_szSerial, sizeof(m_szSerial));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// interface factory
|
||||
|
||||
int CFtdiDeviceDescr::CreateInterface(CFtdiDeviceDescr *descr, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int iNbChs = 0;
|
||||
|
||||
// single channel devices cannot be created alone
|
||||
// three channels devices
|
||||
if ( (::strcmp(descr->GetDescription(), "USB-3003") == 0) || // DVSI's USB-3003
|
||||
(::strcmp(descr->GetDescription(), "DF2ET-3003") == 0) || // DF2ET's USB-3003 opensource device
|
||||
(::strcmp(descr->GetDescription(), "DVstick-33") == 0) || // DVMEGA USB-3003 device
|
||||
(::strcmp(descr->GetDescription(), "ThumbDV-3") == 0) ) // ThumbDV-3
|
||||
{
|
||||
iNbChs = CreateUsb3003(descr, channels);
|
||||
}
|
||||
// six channels devices
|
||||
else if ( (::strcmp(descr->GetDescription(), "USB-3006 A") == 0) ) // LX3JL's USB-3006 opensource device
|
||||
{
|
||||
iNbChs = CreateUsb3006(descr, channels);
|
||||
}
|
||||
// twelves channels devices
|
||||
else if ( (::strcmp(descr->GetDescription(), "USB-3012 A") == 0) ) // DVSI's USB-3012
|
||||
{
|
||||
iNbChs = CreateUsb3012(descr, channels);
|
||||
}
|
||||
// done
|
||||
return iNbChs;
|
||||
}
|
||||
|
||||
int CFtdiDeviceDescr::CreateInterfacePair(CFtdiDeviceDescr *descr1, CFtdiDeviceDescr *descr2, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int iNbChs = 0;
|
||||
|
||||
// create interface objects
|
||||
if ( (descr1->GetNbChannels() == 1) && (descr2->GetNbChannels() == 1) )
|
||||
{
|
||||
// create 3000-3000 pair
|
||||
CUsb3000Interface *Usb3000A = InstantiateUsb3000(descr1);
|
||||
CUsb3000Interface *Usb3000B = InstantiateUsb3000(descr2);
|
||||
iNbChs = CreatePair(Usb3000A, Usb3000B, channels);
|
||||
}
|
||||
else if ( (descr1->GetNbChannels() == 3) && (descr2->GetNbChannels() == 1) )
|
||||
{
|
||||
// create 3003-3000 pair
|
||||
CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr1);
|
||||
CUsb3000Interface *Usb3000 = InstantiateUsb3000(descr2);
|
||||
iNbChs = CreatePair(Usb3003, Usb3000, channels);
|
||||
}
|
||||
else if ( (descr1->GetNbChannels() == 1) && (descr2->GetNbChannels() == 3) )
|
||||
{
|
||||
// create 3000-3003 pair
|
||||
CUsb3000Interface *Usb3000 = InstantiateUsb3000(descr1);
|
||||
CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr2);
|
||||
iNbChs = CreatePair(Usb3003, Usb3000, channels);
|
||||
}
|
||||
else if ( (descr1->GetNbChannels() == 3) && (descr2->GetNbChannels() == 3) )
|
||||
{
|
||||
// create 3003-3003 pair
|
||||
CUsb3003Interface *Usb3003A = InstantiateUsb3003(descr1);
|
||||
CUsb3003Interface *Usb3003B = InstantiateUsb3003(descr2);
|
||||
iNbChs = CreatePair(Usb3003A, Usb3003B, channels);
|
||||
}
|
||||
|
||||
// done
|
||||
return iNbChs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get
|
||||
|
||||
const char * CFtdiDeviceDescr::GetChannelDescription(int ch) const
|
||||
{
|
||||
static char descr[FTDI_MAX_STRINGLENGTH];
|
||||
char tag[3] = "_X";
|
||||
|
||||
::strcpy(descr, GetDescription());
|
||||
if ( ::strlen(descr) >= 2 )
|
||||
{
|
||||
descr[::strlen(descr)-2] = 0x00;
|
||||
tag[1] = (char)ch + 'A';
|
||||
::strcat(descr, tag);
|
||||
}
|
||||
return descr;
|
||||
}
|
||||
|
||||
const char * CFtdiDeviceDescr::GetChannelSerialNumber(int ch) const
|
||||
{
|
||||
static char serial[FTDI_MAX_STRINGLENGTH];
|
||||
|
||||
::strcpy(serial, GetSerialNumber());
|
||||
if ( ::strlen(serial) >= 1 )
|
||||
{
|
||||
serial[::strlen(serial)-1] = (char)ch + 'A';
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
int CFtdiDeviceDescr::GetNbChannels(void) const
|
||||
{
|
||||
int iNbChs = 0;
|
||||
|
||||
// single channel devices
|
||||
if ( (::strcmp(m_szDescription, "USB-3000") == 0) || // DVSI's USB-3000
|
||||
(::strcmp(m_szDescription, "DVstick-30") == 0) || // DVMEGA AMBE3000 device
|
||||
(::strcmp(m_szDescription, "ThumbDV") == 0) ) // ThumbDV
|
||||
{
|
||||
iNbChs = 1;
|
||||
}
|
||||
// three channels devices
|
||||
else if ( (::strcmp(m_szDescription, "USB-3003") == 0) || // DVSI's USB-3003
|
||||
(::strcmp(m_szDescription, "DF2ET-3003") == 0) || // DF2ET's USB-3003 opensource device
|
||||
(::strcmp(m_szDescription, "DVstick-33") == 0) || // DVMEGA AMBE 3003 device
|
||||
(::strcmp(m_szDescription, "ThumbDV-3") == 0) ) // ThumbDV-3
|
||||
{
|
||||
iNbChs = 3;
|
||||
}
|
||||
// six channels devices
|
||||
else if ( (::strcmp(m_szDescription, "USB-3006 A") == 0) ) // LX3JL's USB-3006 opensource device
|
||||
{
|
||||
iNbChs = 6;
|
||||
}
|
||||
// twelves channels devices
|
||||
else if ( (::strcmp(m_szDescription, "USB-3012 A") == 0) ) // DVSI's USB-3012
|
||||
{
|
||||
iNbChs = 12;
|
||||
}
|
||||
|
||||
// done
|
||||
return iNbChs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DVSI's USB-3012 factory helper
|
||||
//
|
||||
// This device uses 3 AMBE3003 connected on a single FTDI 4 channels
|
||||
// USB to serial interface. The reset mechanism is based
|
||||
// on DTR and SetBreak. Baudrate is 921600
|
||||
//
|
||||
|
||||
int CFtdiDeviceDescr::CreateUsb3012(CFtdiDeviceDescr *descr, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the four 3003 chips
|
||||
CUsb3003HRInterface *Usb3003A =
|
||||
new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(0), descr->GetChannelSerialNumber(0));
|
||||
CUsb3003HRInterface *Usb3003B =
|
||||
new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(1), descr->GetChannelSerialNumber(1));
|
||||
CUsb3003HRInterface *Usb3003C =
|
||||
new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(2), descr->GetChannelSerialNumber(2));
|
||||
CUsb3003HRInterface *Usb3003D =
|
||||
new CUsb3003HRInterface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(3), descr->GetChannelSerialNumber(3));
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) &&
|
||||
Usb3003C->Init(CODEC_AMBEPLUS) && Usb3003D->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch5
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch6
|
||||
Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch7
|
||||
Channel = new CVocodecChannel(Usb3003C, 0, Usb3003C, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
// ch8
|
||||
Channel = new CVocodecChannel(Usb3003C, 1, Usb3003C, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
// ch9
|
||||
Channel = new CVocodecChannel(Usb3003D, 0, Usb3003D, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch10
|
||||
Channel = new CVocodecChannel(Usb3003D, 1, Usb3003D, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch11
|
||||
Channel = new CVocodecChannel(Usb3003C, 2, Usb3003D, 2, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch12
|
||||
Channel = new CVocodecChannel(Usb3003D, 2, Usb3003C, 2, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
//done
|
||||
nStreams = 12;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3003B;
|
||||
delete Usb3003C;
|
||||
delete Usb3003D;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// LX3JL's USB-3006 factory helper
|
||||
//
|
||||
// This device uses 2 AMBE3003 connected on a single FTDI 2 channels
|
||||
// USB to serial interface. The reset mechanism is based
|
||||
// on DTR and software reset. Baudrate is 921600
|
||||
//
|
||||
int CFtdiDeviceDescr::CreateUsb3006(CFtdiDeviceDescr *descr, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the two 3003 chips
|
||||
CUsb3003Interface *Usb3003A =
|
||||
new CUsb3003Interface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(0), descr->GetChannelSerialNumber(0));
|
||||
CUsb3003Interface *Usb3003B =
|
||||
new CUsb3003Interface(descr->GetVid(), descr->GetPid(), descr->GetChannelDescription(1), descr->GetChannelSerialNumber(1));
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch5
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch6
|
||||
Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
//done
|
||||
nStreams = 6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3003B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// USB-3003 factory helpers
|
||||
// DVSI
|
||||
// DF2ET
|
||||
// ThumbDV
|
||||
// DVMEGA
|
||||
//
|
||||
// These devices uses a AMBE3003 connected on a single FTDI
|
||||
// USB to serial interface. The reset mechanism is based
|
||||
// on DTR and SetBreak, or software. Baudrate is 921600
|
||||
//
|
||||
int CFtdiDeviceDescr::CreateUsb3003(CFtdiDeviceDescr *descr, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the 3003 chip
|
||||
CUsb3003Interface *Usb3003 = InstantiateUsb3003(descr);
|
||||
|
||||
// init the interface
|
||||
if ( (Usb3003 != NULL) && Usb3003->Init(CODEC_NONE) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003, 0, Usb3003, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003, 1, Usb3003, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 1 ch + 1 ch pair creation
|
||||
|
||||
int CFtdiDeviceDescr::CreatePair(CUsb3000Interface *Usb3000A, CUsb3000Interface *Usb3000B, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3000A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3000A, 0, Usb3000B, 0, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3000A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3000B, 0, Usb3000A, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3000A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3000A;
|
||||
delete Usb3000B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3 ch + 3 ch pair creation
|
||||
|
||||
int CFtdiDeviceDescr::CreatePair(CUsb3003Interface *Usb3003A, CUsb3003Interface *Usb3003B, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch5
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch6
|
||||
Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3003B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3 ch + 1 ch pair creation
|
||||
|
||||
int CFtdiDeviceDescr::CreatePair(CUsb3003Interface *Usb3003A, CUsb3000Interface *Usb3000B, std::vector<CVocodecChannel *>*channels)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3000B, 0, CODECGAIN_AMBEPLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3000B, 0, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
channels->push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3000B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// interface instantiation helpers
|
||||
|
||||
CUsb3003Interface *CFtdiDeviceDescr::InstantiateUsb3003(CFtdiDeviceDescr *descr)
|
||||
{
|
||||
CUsb3003Interface *Usb3003 = NULL;
|
||||
|
||||
// intstantiate the proper version of USB-3003
|
||||
if ( (::strcmp(descr->GetDescription(), "USB-3003") == 0) ) // DVSI's USB-3003
|
||||
{
|
||||
// hardware reset, 921600 bps
|
||||
Usb3003 = new CUsb3003HRInterface
|
||||
(descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber());
|
||||
}
|
||||
else if ( (::strcmp(descr->GetDescription(), "DF2ET-3003") == 0) ) // DF2ET's USB-3003 opensource device
|
||||
{
|
||||
// specific hardware reset, 921600 bps
|
||||
Usb3003 = new CUsb3003DF2ETInterface
|
||||
(descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber());
|
||||
}
|
||||
else if ( (::strcmp(descr->GetDescription(), "ThumbDV-3") == 0) ) // ThumbDV-3
|
||||
{
|
||||
// software reset, 921600 bps
|
||||
Usb3003 = new CUsb3003Interface
|
||||
(descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber());
|
||||
}
|
||||
else if ( (::strcmp(descr->GetDescription(), "DVstick-33") == 0) ) // DVMEGA AMBE3003 device
|
||||
{
|
||||
// specific fardware reset, 921600 bps
|
||||
Usb3003 = new CUsb3003DF2ETInterface
|
||||
(descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber());
|
||||
}
|
||||
|
||||
// done
|
||||
return Usb3003;
|
||||
}
|
||||
|
||||
CUsb3000Interface *CFtdiDeviceDescr::InstantiateUsb3000(CFtdiDeviceDescr *descr)
|
||||
{
|
||||
CUsb3000Interface *Usb3000 = NULL;
|
||||
|
||||
// intstantiate the proper version of USB-3000
|
||||
if ( (::strcmp(descr->GetDescription(), "USB-3000") == 0) || // DVSI's USB-3000
|
||||
(::strcmp(descr->GetDescription(), "DVstick-30")== 0) || // DVMEGA AMBE3000 device
|
||||
(::strcmp(descr->GetDescription(), "ThumbDV") == 0) ) // ThumbDV
|
||||
{
|
||||
Usb3000 = new CUsb3000Interface
|
||||
(descr->GetVid(), descr->GetPid(), descr->GetDescription(), descr->GetSerialNumber());
|
||||
}
|
||||
// done
|
||||
return Usb3000;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "ftd2xx.h"
|
||||
#include "cvocodecchannel.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
|
@ -38,6 +39,9 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CUsb3000Interface;
|
||||
class CUsb3003Interface;
|
||||
|
||||
class CFtdiDeviceDescr
|
||||
{
|
||||
public:
|
||||
|
|
@ -48,20 +52,36 @@ public:
|
|||
|
||||
// destructor
|
||||
virtual ~CFtdiDeviceDescr() {}
|
||||
|
||||
|
||||
// interface factory
|
||||
static int CreateInterface(CFtdiDeviceDescr *, std::vector<CVocodecChannel *>*);
|
||||
static int CreateInterfacePair(CFtdiDeviceDescr *, CFtdiDeviceDescr *, std::vector<CVocodecChannel *>*);
|
||||
|
||||
// get
|
||||
bool IsUsed(void) const {return m_bUsed; }
|
||||
bool IsUsb3000(void) const { return (::strcmp(m_szDescription, "USB-3000") == 0); }
|
||||
bool IsUsb3003(void) const { return (::strcmp(m_szDescription, "USB-3003") == 0); }
|
||||
bool IsUsb3012(void) const { return (::strcmp(m_szDescription, "USB-3012 A") == 0); }
|
||||
uint32 GetVid(void) const { return m_uiVid; }
|
||||
uint32 GetPid(void) const { return m_uiPid; }
|
||||
const char *GetDescription(void) const { return m_szDescription; }
|
||||
const char *GetSerialNumber(void) const { return m_szSerial; }
|
||||
bool IsUsed(void) const { return m_bUsed; }
|
||||
int GetNbChannels(void) const;
|
||||
uint32 GetVid(void) const { return m_uiVid; }
|
||||
uint32 GetPid(void) const { return m_uiPid; }
|
||||
const char *GetDescription(void) const { return m_szDescription; }
|
||||
const char *GetSerialNumber(void) const { return m_szSerial; }
|
||||
const char * GetChannelDescription(int) const;
|
||||
const char * GetChannelSerialNumber(int) const;
|
||||
|
||||
|
||||
// set
|
||||
void SetUsed(bool used) { m_bUsed = used; }
|
||||
|
||||
|
||||
protected:
|
||||
// factory helper
|
||||
static int CreateUsb3012(CFtdiDeviceDescr *, std::vector<CVocodecChannel *>*);
|
||||
static int CreateUsb3006(CFtdiDeviceDescr *, std::vector<CVocodecChannel *>*);
|
||||
static int CreateUsb3003(CFtdiDeviceDescr *, std::vector<CVocodecChannel *>*);
|
||||
static int CreatePair(CUsb3003Interface *, CUsb3003Interface *, std::vector<CVocodecChannel *>*);
|
||||
static int CreatePair(CUsb3003Interface *, CUsb3000Interface *, std::vector<CVocodecChannel *>*);
|
||||
static int CreatePair(CUsb3000Interface *, CUsb3000Interface *, std::vector<CVocodecChannel *>*);
|
||||
static CUsb3003Interface *InstantiateUsb3003(CFtdiDeviceDescr *);
|
||||
static CUsb3000Interface *InstantiateUsb3000(CFtdiDeviceDescr *);
|
||||
|
||||
protected:
|
||||
// status
|
||||
bool m_bUsed;
|
||||
|
|
|
|||
|
|
@ -40,13 +40,17 @@ public:
|
|||
// destructor
|
||||
virtual ~CPacket() {};
|
||||
|
||||
// identity
|
||||
virtual bool IsVoice(void) const { return false; }
|
||||
virtual bool IsAmbe(void) const { return false; }
|
||||
|
||||
// get
|
||||
int GetChannel(void) const { return m_iCh; }
|
||||
uint8 GetPid(void) const { return m_uiPid; }
|
||||
int GetChannel(void) const { return m_iCh; }
|
||||
uint8 GetPid(void) const { return m_uiPid; }
|
||||
|
||||
// set
|
||||
void SetChannel(int i) { m_iCh = i; }
|
||||
void SetPid(uint8 ui) { m_uiPid = ui; }
|
||||
void SetChannel(int i) { m_iCh = i; }
|
||||
void SetPid(uint8 ui) { m_uiPid = ui; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
|
|
|
|||
38
ambed/csampleblockprocessor.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// csampleprocessor.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA
|
||||
|
||||
#ifndef csamplebloclprocessor_h
|
||||
#define csamplebloclprocessor_h
|
||||
|
||||
#include "main.h"
|
||||
|
||||
class CSampleBlockProcessor
|
||||
{
|
||||
public:
|
||||
//processing
|
||||
virtual void ProcessSampleBlock(uint8* voice, int length) = 0;
|
||||
};
|
||||
|
||||
#endif /* csampleprocessor_h */
|
||||
94
ambed/csignalprocessor.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// cagc.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 28/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA AGC
|
||||
|
||||
#include "main.h"
|
||||
#include "csignalprocessor.h"
|
||||
|
||||
#if USE_AGC == 1
|
||||
#include "cagc.h"
|
||||
#else
|
||||
#include "cfixedgain.h"
|
||||
#endif
|
||||
|
||||
#if USE_BANDPASSFILTER == 1
|
||||
#include "cfirfilter.h"
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CSignalProcessor::CSignalProcessor(float gaindB)
|
||||
{
|
||||
#if USE_BANDPASSFILTER
|
||||
m_sampleProcessors.push_back((CSampleBlockProcessor*)new CFIRFilter(FILTER_TAPS, FILTER_TAPS_LENGTH));
|
||||
#endif
|
||||
#if USE_AGC == 1
|
||||
m_sampleProcessors.push_back((CSampleBlockProcessor*)new CAGC(gaindB));
|
||||
#else
|
||||
m_sampleProcessors.push_back((CSampleBlockProcessor*)new CFixedGain(gaindB));
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// destructor
|
||||
|
||||
CSignalProcessor::~CSignalProcessor()
|
||||
{
|
||||
for(int i = 0; i < m_sampleProcessors.size(); i++)
|
||||
{
|
||||
delete m_sampleProcessors[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// processing
|
||||
|
||||
void CSignalProcessor::Process(uint8* voice, int length)
|
||||
{
|
||||
/*float sample;
|
||||
int j;*/
|
||||
auto processorsSize = m_sampleProcessors.size();
|
||||
|
||||
for(int j = 0; j < processorsSize; j++)
|
||||
{
|
||||
m_sampleProcessors[j]->ProcessSampleBlock(voice, length);
|
||||
}
|
||||
|
||||
/*for(int i = 0; i < length; i += 2)
|
||||
{
|
||||
//Get the sample
|
||||
sample = (float)(short)MAKEWORD(voice[i+1], voice[i]);
|
||||
|
||||
for(j = 0; j < processorsSize; j++)
|
||||
{
|
||||
sample = m_sampleProcessors[j]->ProcessSample(sample);
|
||||
}
|
||||
|
||||
//write processed sample back
|
||||
voice[i] = HIBYTE((short)sample);
|
||||
voice[i+1] = LOBYTE((short)sample);
|
||||
}*/
|
||||
}
|
||||
48
ambed/csignalprocessor.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// csignalprocessor.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 26/04/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Geoffrey Merck F4FXL / KC3FRA
|
||||
|
||||
#ifndef csignalprocessor_h
|
||||
#define csignalprocessor_h
|
||||
|
||||
#include <vector>
|
||||
#include "csampleblockprocessor.h"
|
||||
|
||||
class CSignalProcessor
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CSignalProcessor(float gaindB);
|
||||
|
||||
//Destructor
|
||||
~CSignalProcessor();
|
||||
|
||||
//Processing
|
||||
void Process(uint8* voice, int length);
|
||||
|
||||
private:
|
||||
std::vector<CSampleBlockProcessor *> m_sampleProcessors;
|
||||
};
|
||||
|
||||
#endif /* csignalprocessor_h */
|
||||
|
|
@ -71,18 +71,20 @@ CStream::CStream(uint16 uiId, const CCallsign &Callsign, const CIp &Ip, uint8 ui
|
|||
|
||||
CStream::~CStream()
|
||||
{
|
||||
m_Socket.Close();
|
||||
if ( m_VocodecChannel != NULL )
|
||||
{
|
||||
g_Vocodecs.CloseChannel(m_VocodecChannel);
|
||||
m_VocodecChannel = NULL;
|
||||
}
|
||||
|
||||
// stop thread first
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
// then close everything
|
||||
m_Socket.Close();
|
||||
if ( m_VocodecChannel != NULL )
|
||||
{
|
||||
m_VocodecChannel->Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +126,7 @@ bool CStream::Init(uint16 uiPort)
|
|||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << m_Ip << std::endl;
|
||||
std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_AmbeServer.GetListenIp() << std::endl;
|
||||
}
|
||||
|
||||
// done
|
||||
|
|
@ -134,13 +136,7 @@ bool CStream::Init(uint16 uiPort)
|
|||
|
||||
void CStream::Close(void)
|
||||
{
|
||||
// close everything
|
||||
m_Socket.Close();
|
||||
if ( m_VocodecChannel != NULL )
|
||||
{
|
||||
m_VocodecChannel->Close();
|
||||
}
|
||||
|
||||
// stop thread first
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
|
|
@ -148,6 +144,14 @@ void CStream::Close(void)
|
|||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
// then close everything
|
||||
m_Socket.Close();
|
||||
if ( m_VocodecChannel != NULL )
|
||||
{
|
||||
m_VocodecChannel->Close();
|
||||
}
|
||||
|
||||
|
||||
// report
|
||||
std::cout << m_iLostPackets << " of " << m_iTotalPackets << " packets lost" << std::endl;
|
||||
|
|
@ -170,7 +174,7 @@ void CStream::Thread(CStream *This)
|
|||
void CStream::Task(void)
|
||||
{
|
||||
CBuffer Buffer;
|
||||
static CIp Ip;
|
||||
CIp Ip;
|
||||
uint8 uiPid;
|
||||
uint8 Ambe[AMBE_FRAME_SIZE];
|
||||
CAmbePacket *packet;
|
||||
|
|
@ -203,7 +207,7 @@ void CStream::Task(void)
|
|||
queue->pop();
|
||||
// send it to client
|
||||
EncodeDvFramePacket(&Buffer, packet->GetPid(), packet->GetAmbe());
|
||||
m_Socket.Send(Buffer, Ip, m_uiPort);
|
||||
m_Socket.Send(Buffer, m_Ip, m_uiPort);
|
||||
// and done
|
||||
delete packet;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ bool CUsb3000Interface::ResetDevice(void)
|
|||
{
|
||||
FTDI_write_packet(m_FtdiHandle, zeropacket, sizeof(zeropacket));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// write soft-reset packet
|
||||
if ( FTDI_write_packet(m_FtdiHandle, txpacket, sizeof(txpacket)) )
|
||||
|
|
|
|||
164
ambed/cusb3003df2etinterface.cpp
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
//
|
||||
// cusb3003df2etinterface.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) and Florian Wolters (DF2ET) on 03/11/2017.
|
||||
// Copyright © 2017 Jean-Luc Deltombe (LX3JL) and Florian Wolters (DF2ET).
|
||||
// All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Created by Florian Wolters (DF2ET) on 03/11/2017.
|
||||
// Copyright © 2017 Florian Wolters (DF2ET). All rights reserved.
|
||||
|
||||
#include "main.h"
|
||||
#include "ctimepoint.h"
|
||||
#include "cambepacket.h"
|
||||
#include "cusb3003df2etinterface.h"
|
||||
#include "cvocodecs.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CUsb3003DF2ETInterface::CUsb3003DF2ETInterface(uint32 uiVid, uint32 uiPid, const char *szDeviceName, const char *szDeviceSerial)
|
||||
: CUsb3003Interface(uiVid, uiPid, szDeviceName, szDeviceSerial)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// low level
|
||||
|
||||
bool CUsb3003DF2ETInterface::OpenDevice(void)
|
||||
{
|
||||
FT_STATUS ftStatus;
|
||||
int baudrate = 921600;
|
||||
|
||||
//sets serial VID/PID for a Standard Device NOTE: This is for legacy purposes only. This can be ommitted.
|
||||
ftStatus = FT_SetVIDPID(m_uiVid, m_uiPid);
|
||||
if (ftStatus != FT_OK) {FTDI_Error((char *)"FT_SetVIDPID", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_OpenEx((PVOID)m_szDeviceSerial, FT_OPEN_BY_SERIAL_NUMBER, &m_FtdiHandle);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_OpenEx", ftStatus ); return false; }
|
||||
|
||||
CTimePoint::TaskSleepFor(50);
|
||||
FT_Purge(m_FtdiHandle, FT_PURGE_RX | FT_PURGE_TX );
|
||||
CTimePoint::TaskSleepFor(50);
|
||||
|
||||
ftStatus = FT_SetDataCharacteristics(m_FtdiHandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
|
||||
if ( ftStatus != FT_OK ) { FTDI_Error((char *)"FT_SetDataCharacteristics", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_SetFlowControl(m_FtdiHandle, FT_FLOW_RTS_CTS, 0x11, 0x13);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetFlowControl", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_SetRts (m_FtdiHandle);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetRts", ftStatus ); return false; }
|
||||
|
||||
// for DF2ET-3003 interface pull DTR low to take AMBE3003 out of reset.
|
||||
ftStatus = FT_SetDtr( m_FtdiHandle );
|
||||
CTimePoint::TaskSleepFor(50);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetDtr", ftStatus); return false; }
|
||||
|
||||
ftStatus = FT_SetBaudRate(m_FtdiHandle, baudrate );
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetBaudRate", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_SetLatencyTimer(m_FtdiHandle, 4);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetLatencyTimer", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_SetUSBParameters(m_FtdiHandle, USB3XXX_MAXPACKETSIZE, 0);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetUSBParameters", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_SetTimeouts(m_FtdiHandle, 200, 200 );
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_SetTimeouts", ftStatus ); return false; }
|
||||
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CUsb3003DF2ETInterface::ResetDevice(void)
|
||||
{
|
||||
bool ok = false;
|
||||
FT_STATUS ftStatus;
|
||||
int len, i;
|
||||
char rxpacket[100];
|
||||
|
||||
std::cout << "Trying DF2ET-3003 soft reset" << std::endl;
|
||||
|
||||
DWORD n, b;
|
||||
char txpacket[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
char reset_packet[7] = { PKT_HEADER, 0, 3, 0, PKT_RESET, PKT_PARITYBYTE, 3 ^ PKT_RESET ^ PKT_PARITYBYTE };
|
||||
char *p;
|
||||
|
||||
for (i = 0; i < 35; i++)
|
||||
{
|
||||
p = &txpacket[0];
|
||||
n = 10;
|
||||
do
|
||||
{
|
||||
ftStatus = FT_Write( m_FtdiHandle, p, n, &b);
|
||||
if (FT_OK != ftStatus)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
n -= b;
|
||||
p += b;
|
||||
} while (n > 0);
|
||||
}
|
||||
|
||||
p = &reset_packet[0];
|
||||
n = 7;
|
||||
do
|
||||
{
|
||||
ftStatus = FT_Write( m_FtdiHandle, p, n, &b);
|
||||
if (FT_OK != ftStatus)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
n -= b;
|
||||
p += b;
|
||||
} while (n > 0);
|
||||
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) );
|
||||
ok = ((len == 7) && (rxpacket[4] == PKT_READY));
|
||||
if ( ok )
|
||||
{
|
||||
std::cout << "DF2ET-3003 soft reset succeeded" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "DF2ET-3003 soft reset failed" << std::endl;
|
||||
|
||||
std::cout << "Trying DF2ET-3003 hard reset" << std::endl;
|
||||
|
||||
ftStatus = FT_ClrDtr( m_FtdiHandle );
|
||||
CTimePoint::TaskSleepFor(10);
|
||||
ftStatus = FT_SetDtr( m_FtdiHandle );
|
||||
CTimePoint::TaskSleepFor(10);
|
||||
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) );
|
||||
ok = ((len == 7) && (rxpacket[4] == PKT_READY));
|
||||
if ( ok )
|
||||
{
|
||||
std::cout << "DF2ET-3003 hard reset succeeded" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "DF2ET-3003 hard reset failed" << std::endl;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
57
ambed/cusb3003df2etinterface.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// cusb3003df2etinterface.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) and Florian Wolters (DF2ET) on 03/11/2017.
|
||||
// Copyright © 2017 Jean-Luc Deltombe (LX3JL) and Florian Wolters (DF2ET).
|
||||
// All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cusb3003df2etinterface_h
|
||||
#define cusb3003df2etinterface_h
|
||||
|
||||
|
||||
#include "ftd2xx.h"
|
||||
#include "cbuffer.h"
|
||||
#include "cusb3003interface.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CUsb3003DF2ETInterface : public CUsb3003Interface
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CUsb3003DF2ETInterface(uint32, uint32, const char *, const char *);
|
||||
|
||||
// destructor
|
||||
virtual ~CUsb3003DF2ETInterface() {}
|
||||
|
||||
protected:
|
||||
// low level
|
||||
bool OpenDevice(void);
|
||||
bool ResetDevice(void);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cusb3003df2etinterface_h */
|
||||
66
ambed/cusb3003hrinterface.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// cusb3003hrinterface.cpp
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 30/10/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include "ctimepoint.h"
|
||||
#include "cambepacket.h"
|
||||
#include "cusb3003hrinterface.h"
|
||||
#include "cvocodecs.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CUsb3003HRInterface::CUsb3003HRInterface(uint32 uiVid, uint32 uiPid, const char *szDeviceName, const char *szDeviceSerial)
|
||||
: CUsb3003Interface(uiVid, uiPid, szDeviceName, szDeviceSerial)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// low level
|
||||
|
||||
bool CUsb3003HRInterface::ResetDevice(void)
|
||||
{
|
||||
bool ok = false;
|
||||
FT_STATUS ftStatus;
|
||||
int len;
|
||||
char rxpacket[100];
|
||||
|
||||
//if the device is a USB-3003, it supports reset via UART break signal
|
||||
//printf("reset via uart break...\n");
|
||||
ftStatus = FT_SetBreakOn( m_FtdiHandle );
|
||||
CTimePoint::TaskSleepFor(10);
|
||||
ftStatus = FT_SetBreakOff( m_FtdiHandle );
|
||||
//CTimePoint::TaskSleepFor(10);
|
||||
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) );
|
||||
ok = ((len == 7) && (rxpacket[4] == PKT_READY));
|
||||
if ( !ok )
|
||||
{
|
||||
std::cout << "USB-3003 hard reset failed" << std::endl;
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
55
ambed/cusb3003hrinterface.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// cusb3003hrinterface.h
|
||||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 30/10/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
//
|
||||
// xlxd 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.
|
||||
//
|
||||
// xlxd 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cusb3003hrinterface_h
|
||||
#define cusb3003hrinterface_h
|
||||
|
||||
|
||||
#include "ftd2xx.h"
|
||||
#include "cbuffer.h"
|
||||
#include "cusb3003interface.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CUsb3003HRInterface : public CUsb3003Interface
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CUsb3003HRInterface(uint32, uint32, const char *, const char *);
|
||||
|
||||
// destructor
|
||||
virtual ~CUsb3003HRInterface() {}
|
||||
|
||||
protected:
|
||||
// low level
|
||||
bool ResetDevice(void);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cusb3003hrinterface_h */
|
||||
|
|
@ -209,9 +209,9 @@ bool CUsb3003Interface::OpenDevice(void)
|
|||
ftStatus = FT_SetVIDPID(m_uiVid, m_uiPid);
|
||||
if (ftStatus != FT_OK) {FTDI_Error((char *)"FT_SetVIDPID", ftStatus ); return false; }
|
||||
|
||||
ftStatus = FT_OpenEx((PVOID)m_szDeviceName, FT_OPEN_BY_DESCRIPTION, &m_FtdiHandle);
|
||||
ftStatus = FT_OpenEx((PVOID)m_szDeviceSerial, FT_OPEN_BY_SERIAL_NUMBER, &m_FtdiHandle);
|
||||
if (ftStatus != FT_OK) { FTDI_Error((char *)"FT_OpenEx", ftStatus ); return false; }
|
||||
|
||||
|
||||
CTimePoint::TaskSleepFor(50);
|
||||
FT_Purge(m_FtdiHandle, FT_PURGE_RX | FT_PURGE_TX );
|
||||
CTimePoint::TaskSleepFor(50);
|
||||
|
|
@ -249,22 +249,46 @@ bool CUsb3003Interface::OpenDevice(void)
|
|||
bool CUsb3003Interface::ResetDevice(void)
|
||||
{
|
||||
bool ok = false;
|
||||
FT_STATUS ftStatus;
|
||||
int len;
|
||||
char rxpacket[100];
|
||||
|
||||
//if the device is a USB-3003, it supports reset via UART break signal
|
||||
//printf("reset via uart break...\n");
|
||||
ftStatus = FT_SetBreakOn( m_FtdiHandle );
|
||||
CTimePoint::TaskSleepFor(10);
|
||||
ftStatus = FT_SetBreakOff( m_FtdiHandle );
|
||||
//CTimePoint::TaskSleepFor(10);
|
||||
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) );
|
||||
ok = ((len == 7) && (rxpacket[4] == PKT_READY));
|
||||
if ( !ok )
|
||||
char zeropacket[10] =
|
||||
{
|
||||
std::cout << "USB-3003 hard reset failed" << std::endl;
|
||||
0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
char txpacket[7] =
|
||||
{
|
||||
PKT_HEADER,
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
PKT_RESET,
|
||||
PKT_PARITYBYTE,
|
||||
3 ^ PKT_RESET ^ PKT_PARITYBYTE
|
||||
};
|
||||
|
||||
|
||||
//the chip might be in a state where it is waiting to receive bytes from a prior incomplete packet.
|
||||
//first send 350 zeros in case, the chip's receive state is still waiting for characters
|
||||
//if we send more than needed, the exta characters will just get discarded since they do not match the header byte
|
||||
//after that we send PKT_RESET to reset the device
|
||||
//As long as the AMBE3000 is able to receive via uart, this method will succeed in resetting it.
|
||||
|
||||
for ( int i = 0; i < 35 ; i++ )
|
||||
{
|
||||
FTDI_write_packet(m_FtdiHandle, zeropacket, sizeof(zeropacket));
|
||||
}
|
||||
|
||||
|
||||
// write soft-reset packet
|
||||
if ( FTDI_write_packet(m_FtdiHandle, txpacket, sizeof(txpacket)) )
|
||||
{
|
||||
// read reply
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) );
|
||||
ok = ((len == 7) && (rxpacket[4] == PKT_READY));
|
||||
if ( !ok )
|
||||
{
|
||||
std::cout << "USB-3003 soft reset failed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ protected:
|
|||
bool OpenDevice(void);
|
||||
bool ResetDevice(void);
|
||||
bool ConfigureDevice(void);
|
||||
int GetDeviceFifoSize(void) const { return 2; }
|
||||
|
||||
// data
|
||||
uint8 m_uiChCodecs[USB3003_NB_CH];
|
||||
|
|
|
|||
|
|
@ -33,18 +33,21 @@
|
|||
#define QUEUE_CHANNEL 0
|
||||
#define QUEUE_SPEECH 1
|
||||
|
||||
// timeout
|
||||
#define DEVICE_TIMEOUT 600 // in ms
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CUsb3xxxInterface::CUsb3xxxInterface(uint32 uiVid, uint32 uiPid, const char *szDeviceName, const char *szDeviceSerial)
|
||||
{
|
||||
m_FtdiHandle = NULL;
|
||||
m_iDeviceFifoLevel = 0;
|
||||
m_iActiveQueue = QUEUE_CHANNEL;
|
||||
m_uiVid = uiVid;
|
||||
m_uiPid = uiPid;
|
||||
::strcpy(m_szDeviceName, szDeviceName);
|
||||
::strcpy(m_szDeviceSerial, szDeviceSerial);
|
||||
m_iSpeechFifolLevel = 0;
|
||||
m_iChannelFifolLevel = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -52,6 +55,28 @@ CUsb3xxxInterface::CUsb3xxxInterface(uint32 uiVid, uint32 uiPid, const char *szD
|
|||
|
||||
CUsb3xxxInterface::~CUsb3xxxInterface()
|
||||
{
|
||||
// stop thread first
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
// delete m_SpeechQueues
|
||||
for ( int i = 0; i < m_SpeechQueues.size(); i++ )
|
||||
{
|
||||
delete m_SpeechQueues[i];
|
||||
}
|
||||
m_SpeechQueues.clear();
|
||||
|
||||
// delete m_ChannelQueues
|
||||
for ( int i = 0; i < m_ChannelQueues.size(); i++ )
|
||||
{
|
||||
delete m_ChannelQueues[i];
|
||||
}
|
||||
m_ChannelQueues.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -65,7 +90,7 @@ bool CUsb3xxxInterface::Init(void)
|
|||
std::cout << "Opening " << m_szDeviceName << ":" << m_szDeviceSerial << " device" << std::endl;
|
||||
if ( ok &= OpenDevice() )
|
||||
{
|
||||
// reset
|
||||
// reset
|
||||
//std::cout << "Reseting " << m_szDeviceName << "device" << std::endl;
|
||||
if ( ok &= ResetDevice() )
|
||||
{
|
||||
|
|
@ -82,6 +107,13 @@ bool CUsb3xxxInterface::Init(void)
|
|||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// create our queues
|
||||
for ( int i = 0; i < GetNbChannels(); i++ )
|
||||
{
|
||||
m_SpeechQueues.push_back(new CPacketQueue);
|
||||
m_ChannelQueues.push_back(new CPacketQueue);
|
||||
}
|
||||
|
||||
// base class
|
||||
if ( ok )
|
||||
{
|
||||
|
|
@ -118,11 +150,10 @@ void CUsb3xxxInterface::Task(void)
|
|||
{
|
||||
if ( IsValidSpeechPacket(Buffer, &iCh, &VoicePacket) )
|
||||
{
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "->Sp" << iCh << std::endl; std::cout.flush();
|
||||
#endif
|
||||
// update fifo status
|
||||
m_iDeviceFifoLevel = MAX(m_iDeviceFifoLevel-1, 0);
|
||||
// update fifo level
|
||||
// as we get a speech packet, it means that the device
|
||||
// channel fifo input decreased by 1
|
||||
m_iChannelFifolLevel = MAX(0, m_iChannelFifolLevel-1);
|
||||
|
||||
// push back to relevant channel voice queue
|
||||
// our incoming channel packet has now been through the decoder
|
||||
|
|
@ -133,20 +164,21 @@ void CUsb3xxxInterface::Task(void)
|
|||
{
|
||||
Queue = Channel->GetVoiceQueue();
|
||||
CVoicePacket *clone = new CVoicePacket(VoicePacket);
|
||||
clone->ApplyGain(Channel->GetSpeechGain());
|
||||
Channel->ProcessSignal(*clone);
|
||||
Queue->push(clone);
|
||||
Channel->ReleaseVoiceQueue();
|
||||
}
|
||||
}
|
||||
else if ( IsValidChannelPacket(Buffer, &iCh, &AmbePacket) )
|
||||
{
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "->Ch" << iCh << std::endl; std::cout.flush();
|
||||
#endif
|
||||
// update fifo status
|
||||
m_iDeviceFifoLevel = MAX(m_iDeviceFifoLevel-1, 0);
|
||||
|
||||
// update fifo level
|
||||
// as we get a channel packet, it means that the device
|
||||
// speech fifo input decreased by 1
|
||||
m_iSpeechFifolLevel = MAX(0, m_iSpeechFifolLevel-1);
|
||||
|
||||
// push back to relevant channel outcoming queue
|
||||
// we are done with this packet transcoding
|
||||
// it's final step
|
||||
Channel = GetChannelWithChannelOut(iCh);
|
||||
if ( Channel != NULL )
|
||||
{
|
||||
|
|
@ -178,9 +210,12 @@ void CUsb3xxxInterface::Task(void)
|
|||
// get packet
|
||||
CVoicePacket *Packet = (CVoicePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
// this is second step of transcoding
|
||||
// we just received from hardware a decoded speech packet
|
||||
// post it to relevant channel encoder
|
||||
Packet->SetChannel(Channel->GetChannelOut());
|
||||
m_SpeechQueue.push(Packet);
|
||||
int i = Channel->GetChannelOut();
|
||||
Packet->SetChannel(i);
|
||||
m_SpeechQueues[i]->push(Packet);
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
|
|
@ -196,9 +231,12 @@ void CUsb3xxxInterface::Task(void)
|
|||
// get packet
|
||||
CAmbePacket *Packet = (CAmbePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
// this is first step of transcoding
|
||||
// a fresh new packet to be transcoded is showing up
|
||||
// post it to relevant channel decoder
|
||||
Packet->SetChannel(Channel->GetChannelIn());
|
||||
m_ChannelQueue.push(Packet);
|
||||
int i = Channel->GetChannelIn();
|
||||
Packet->SetChannel(i);
|
||||
m_ChannelQueues[i]->push(Packet);
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
|
|
@ -207,57 +245,129 @@ void CUsb3xxxInterface::Task(void)
|
|||
}
|
||||
} while (!done);
|
||||
|
||||
// process device incoming queues
|
||||
// process device incoming queues (aka to device)
|
||||
// interlace speech and channels packets
|
||||
// and make sure that the fifo is always
|
||||
// fed.
|
||||
unsigned long iQueueLevel = m_SpeechQueue.size() + m_ChannelQueue.size();
|
||||
if ( ((m_iDeviceFifoLevel == 0) && (iQueueLevel >= 2)) || (m_iDeviceFifoLevel == 1) )
|
||||
// and post to final device queue
|
||||
do
|
||||
{
|
||||
if ( m_iActiveQueue == QUEUE_CHANNEL )
|
||||
done = true;
|
||||
// loop on all channels
|
||||
for ( int i = 0; i < GetNbChannels(); i++ )
|
||||
{
|
||||
// post next channel packet
|
||||
if ( !m_ChannelQueue.empty() )
|
||||
// speech
|
||||
if ( !m_SpeechQueues[i]->empty() )
|
||||
{
|
||||
// get packet
|
||||
CAmbePacket *Packet = (CAmbePacket *)m_ChannelQueue.front();
|
||||
m_ChannelQueue.pop();
|
||||
//Post it
|
||||
EncodeChannelPacket(&Buffer, Packet->GetChannel(), Packet);
|
||||
WriteBuffer(Buffer);
|
||||
m_iDeviceFifoLevel++;
|
||||
// and delete it
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Ch" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
delete Packet;
|
||||
}
|
||||
// and interlace
|
||||
m_iActiveQueue = QUEUE_SPEECH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// post next speech packet
|
||||
if ( !m_SpeechQueue.empty() )
|
||||
{
|
||||
// get packet
|
||||
CVoicePacket *Packet = (CVoicePacket *)m_SpeechQueue.front();
|
||||
m_SpeechQueue.pop();
|
||||
//Post it
|
||||
EncodeSpeechPacket(&Buffer, Packet->GetChannel(), Packet);
|
||||
WriteBuffer(Buffer);
|
||||
m_iDeviceFifoLevel++;
|
||||
// and delete it
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Sp" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
delete Packet;
|
||||
CPacket *Packet = m_SpeechQueues[i]->front();
|
||||
m_SpeechQueues[i]->pop();
|
||||
// and push to device queue
|
||||
m_DeviceQueue.push(Packet);
|
||||
// next
|
||||
done = false;
|
||||
}
|
||||
// ambe
|
||||
if ( !m_ChannelQueues[i]->empty() )
|
||||
{
|
||||
// get packet
|
||||
CPacket *Packet = m_ChannelQueues[i]->front();
|
||||
m_ChannelQueues[i]->pop();
|
||||
// and push to device queue
|
||||
m_DeviceQueue.push(Packet);
|
||||
// done = false;
|
||||
}
|
||||
// and interlace
|
||||
m_iActiveQueue = QUEUE_CHANNEL;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
|
||||
// process device queue to feed hardware
|
||||
// make sure that device fifo is fed all the time
|
||||
int fifoSize = GetDeviceFifoSize();
|
||||
do
|
||||
{
|
||||
done = true;
|
||||
// any packet to send ?
|
||||
if ( m_DeviceQueue.size() > 0 )
|
||||
{
|
||||
// yes, get it
|
||||
CPacket *Packet = m_DeviceQueue.front();
|
||||
|
||||
Channel = NULL;
|
||||
if ( Packet->IsVoice() )
|
||||
Channel = GetChannelWithChannelOut(Packet->GetChannel());
|
||||
else if ( Packet->IsAmbe() )
|
||||
Channel = GetChannelWithChannelIn(Packet->GetChannel());
|
||||
// if channel no longer open, drop packet, don't waste time with lagged packets
|
||||
if ( (Channel != NULL) && !Channel->IsOpen() )
|
||||
{
|
||||
m_DeviceQueue.pop();
|
||||
delete Packet;
|
||||
done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// if device fifo level is zero (device idle)
|
||||
// wait that at least 3 packets are in incoming
|
||||
// queue before restarting
|
||||
if ( ((m_iSpeechFifolLevel+m_iChannelFifolLevel) > 0) || (m_DeviceQueue.size() >= (fifoSize+1)) )
|
||||
{
|
||||
|
||||
// if too much time elapsed since last packet was sent to device and fifo level is not zero
|
||||
// then we failed to get reply(s) from device, reset device fifo level to restart communication
|
||||
if ( (m_iSpeechFifolLevel > 0) && (m_SpeechFifoLevelTimeout.DurationSinceNow() >= (DEVICE_TIMEOUT/1000.0f)) )
|
||||
{
|
||||
std::cout << "Reseting " << m_szDeviceName << ":" << m_szDeviceSerial << " device fifo level due to timeout" << std::endl;
|
||||
m_iSpeechFifolLevel = 0;
|
||||
if ( CheckIfDeviceNeedsReOpen() )
|
||||
m_iChannelFifolLevel = 0;
|
||||
}
|
||||
if ( (m_iChannelFifolLevel > 0) && (m_ChannelFifoLevelTimeout.DurationSinceNow() >= (DEVICE_TIMEOUT/1000.0f)) )
|
||||
{
|
||||
std::cout << "Reseting " << m_szDeviceName << ":" << m_szDeviceSerial << " device fifo level due to timeout" << std::endl;
|
||||
m_iChannelFifolLevel = 0;
|
||||
if ( CheckIfDeviceNeedsReOpen() )
|
||||
m_iSpeechFifolLevel = 0;
|
||||
}
|
||||
|
||||
if ( Packet->IsVoice() && (m_iSpeechFifolLevel < fifoSize) )
|
||||
{
|
||||
// encode & post
|
||||
EncodeSpeechPacket(&Buffer, Packet->GetChannel(), (CVoicePacket *)Packet);
|
||||
WriteBuffer(Buffer);
|
||||
// remove from queue
|
||||
m_DeviceQueue.pop();
|
||||
// and delete it
|
||||
delete Packet;
|
||||
// update fifo level
|
||||
m_iSpeechFifolLevel++;
|
||||
m_SpeechFifoLevelTimeout.Now();
|
||||
// next
|
||||
done = false;
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Sp" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
}
|
||||
else if ( Packet->IsAmbe() && (m_iChannelFifolLevel < fifoSize) )
|
||||
{
|
||||
// encode & post
|
||||
EncodeChannelPacket(&Buffer, Packet->GetChannel(), (CAmbePacket *)Packet);
|
||||
WriteBuffer(Buffer);
|
||||
// remove from queue
|
||||
m_DeviceQueue.pop();
|
||||
// and delete it
|
||||
delete Packet;
|
||||
// update fifo level
|
||||
m_iChannelFifolLevel++;
|
||||
m_ChannelFifoLevelTimeout.Now();
|
||||
// next
|
||||
done = false;
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Ch" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
// and wait a bit
|
||||
CTimePoint::TaskSleepFor(2);
|
||||
|
|
@ -289,10 +399,15 @@ bool CUsb3xxxInterface::ReadDeviceVersion(void)
|
|||
{
|
||||
// read reply
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) ) - 4;
|
||||
ok = (len != 0);
|
||||
ok = (len > 0);
|
||||
//we succeed in reading a packet, print it out
|
||||
std::cout << "ReadDeviceVersion : ";
|
||||
for ( i = 4; i < len+4 ; i++ )
|
||||
for ( i = 5; (i < len+4) && (rxpacket[i] != 0x00); i++ )
|
||||
{
|
||||
std::cout << (char)(rxpacket[i] & 0x00ff);
|
||||
}
|
||||
std::cout << " ";
|
||||
for ( i = i+2; (i < len+4) && (rxpacket[i] != 0x00); i++ )
|
||||
{
|
||||
std::cout << (char)(rxpacket[i] & 0x00ff);
|
||||
}
|
||||
|
|
@ -366,6 +481,46 @@ bool CUsb3xxxInterface::ConfigureChannel(uint8 pkt_ch, const uint8 *pkt_ratep, i
|
|||
|
||||
}
|
||||
|
||||
bool CUsb3xxxInterface::CheckIfDeviceNeedsReOpen(void)
|
||||
{
|
||||
bool ok = false;
|
||||
int len;
|
||||
char rxpacket[64];
|
||||
char txpacket[5] =
|
||||
{
|
||||
PKT_HEADER,
|
||||
0,
|
||||
1,
|
||||
PKT_CONTROL,
|
||||
PKT_PRODID
|
||||
};
|
||||
|
||||
// write packet
|
||||
if ( FTDI_write_packet(m_FtdiHandle, txpacket, sizeof(txpacket)) )
|
||||
{
|
||||
// read reply
|
||||
len = FTDI_read_packet( m_FtdiHandle, rxpacket, sizeof(rxpacket) ) - 4;
|
||||
ok = ((len > 0) && (rxpacket[3] == PKT_CONTROL) && (rxpacket[4] == PKT_PRODID));
|
||||
}
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
std::cout << "Device " << m_szDeviceName << ":" << m_szDeviceSerial << " is unresponsive, trying to re-open it..." << std::endl;
|
||||
FT_Close(m_FtdiHandle);
|
||||
CTimePoint::TaskSleepFor(100);
|
||||
if ( OpenDevice() )
|
||||
{
|
||||
if ( ResetDevice() )
|
||||
{
|
||||
DisableParity();
|
||||
ConfigureDevice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !ok;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// io level
|
||||
|
|
@ -403,6 +558,13 @@ int CUsb3xxxInterface::FTDI_read_packet(FT_HANDLE ftHandle, char *pkt, int maxle
|
|||
// first read 4 bytes header
|
||||
if ( FTDI_read_bytes(ftHandle, pkt, 4) )
|
||||
{
|
||||
// ensure we got a valid packet header
|
||||
if ( (pkt[0] != PKT_HEADER) || ((pkt[3] != PKT_CONTROL) && (pkt[3] != PKT_CHANNEL) && (pkt[3] != PKT_SPEECH)) )
|
||||
{
|
||||
std::cout << "FTDI_read_packet invalid packet header" << std::endl;
|
||||
FT_Purge(ftHandle, FT_PURGE_RX);
|
||||
return 0;
|
||||
}
|
||||
// get payload length
|
||||
plen = (pkt[1] & 0x00ff);
|
||||
plen <<= 8;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "cambepacket.h"
|
||||
#include "cvoicepacket.h"
|
||||
#include "cvocodecinterface.h"
|
||||
#include "ctimepoint.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
|
@ -98,12 +99,14 @@ protected:
|
|||
virtual void EncodeSpeechPacket(CBuffer *, int, CVoicePacket *) {}
|
||||
|
||||
// low level
|
||||
virtual bool OpenDevice(void) { return false; }
|
||||
virtual bool ResetDevice(void) { return false; }
|
||||
virtual bool OpenDevice(void) { return false; }
|
||||
virtual bool ResetDevice(void) { return false; }
|
||||
bool ReadDeviceVersion(void);
|
||||
bool DisableParity(void);
|
||||
virtual bool ConfigureDevice(void) { return false; }
|
||||
virtual bool ConfigureDevice(void) { return false; }
|
||||
bool ConfigureChannel(uint8, const uint8 *, int, int);
|
||||
bool CheckIfDeviceNeedsReOpen(void);
|
||||
virtual int GetDeviceFifoSize(void) const { return 1; }
|
||||
|
||||
// io level
|
||||
bool ReadBuffer(CBuffer *);
|
||||
|
|
@ -117,17 +120,20 @@ protected:
|
|||
|
||||
protected:
|
||||
// data
|
||||
uint32 m_uiVid;
|
||||
uint32 m_uiPid;
|
||||
char m_szDeviceName[FTDI_MAX_STRINGLENGTH];
|
||||
char m_szDeviceSerial[FTDI_MAX_STRINGLENGTH];
|
||||
FT_HANDLE m_FtdiHandle;
|
||||
uint32 m_uiVid;
|
||||
uint32 m_uiPid;
|
||||
char m_szDeviceName[FTDI_MAX_STRINGLENGTH];
|
||||
char m_szDeviceSerial[FTDI_MAX_STRINGLENGTH];
|
||||
FT_HANDLE m_FtdiHandle;
|
||||
|
||||
// queue
|
||||
CPacketQueue m_SpeechQueue;
|
||||
CPacketQueue m_ChannelQueue;
|
||||
int m_iDeviceFifoLevel;
|
||||
int m_iActiveQueue;
|
||||
std::vector<CPacketQueue*> m_SpeechQueues;
|
||||
std::vector<CPacketQueue*> m_ChannelQueues;
|
||||
CPacketQueue m_DeviceQueue;
|
||||
int m_iSpeechFifolLevel;
|
||||
int m_iChannelFifolLevel;
|
||||
CTimePoint m_SpeechFifoLevelTimeout;
|
||||
CTimePoint m_ChannelFifoLevelTimeout;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "cvocodecchannel.h"
|
||||
#include "cvocodecinterface.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
|
|
@ -39,6 +38,7 @@ CVocodecChannel::CVocodecChannel(CVocodecInterface *InterfaceIn, int iChIn, CVoc
|
|||
m_InterfaceOut = InterfaceOut;
|
||||
m_iChannelOut = iChOut;
|
||||
m_iSpeechGain = iSpeechGain;
|
||||
m_signalProcessor = new CSignalProcessor((float)m_iSpeechGain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,6 +47,7 @@ CVocodecChannel::CVocodecChannel(CVocodecInterface *InterfaceIn, int iChIn, CVoc
|
|||
CVocodecChannel::~CVocodecChannel()
|
||||
{
|
||||
PurgeAllQueues();
|
||||
delete m_signalProcessor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -61,8 +62,8 @@ bool CVocodecChannel::Open(void)
|
|||
ok = true;
|
||||
PurgeAllQueues();
|
||||
std::cout << "Vocodec channel " <<
|
||||
m_InterfaceIn->GetName() << ":" << (int)m_iChannelIn << " -> " <<
|
||||
m_InterfaceOut->GetName() << ":" << (int)m_iChannelOut << " open" << std::endl;
|
||||
m_InterfaceIn->GetName() << ":" << m_InterfaceIn->GetSerial() << ":" << (int)m_iChannelIn << " -> " <<
|
||||
m_InterfaceOut->GetName() << ":" << m_InterfaceOut->GetSerial() << ":" << (int)m_iChannelOut << " open" << std::endl;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
|
@ -74,8 +75,8 @@ void CVocodecChannel::Close(void)
|
|||
m_bOpen = false;
|
||||
PurgeAllQueues();
|
||||
std::cout << "Vocodec channel " <<
|
||||
m_InterfaceIn->GetName() << ":" << (int)m_iChannelIn << " -> " <<
|
||||
m_InterfaceOut->GetName() << ":" << (int)m_iChannelOut << " closed" << std::endl;
|
||||
m_InterfaceIn->GetName() << ":" << m_InterfaceIn->GetSerial() << ":" << (int)m_iChannelIn << " -> " <<
|
||||
m_InterfaceOut->GetName() << ":" << m_InterfaceOut->GetSerial() << ":" << (int)m_iChannelOut << " closed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +93,15 @@ uint8 CVocodecChannel::GetCodecOut(void) const
|
|||
return m_InterfaceOut->GetChannelCodec(m_iChannelOut);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// processing
|
||||
|
||||
void CVocodecChannel::ProcessSignal(CVoicePacket& voicePacket)
|
||||
{
|
||||
m_signalProcessor->Process(voicePacket.GetVoice(), voicePacket.GetVoiceSize());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// queues helpers
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#define cvocodecchannel_h
|
||||
|
||||
#include "cpacketqueue.h"
|
||||
#include "csignalprocessor.h"
|
||||
#include "cvoicepacket.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
|
@ -54,6 +56,9 @@ public:
|
|||
int GetChannelOut(void) const { return m_iChannelOut; }
|
||||
int GetSpeechGain(void) const { return m_iSpeechGain; }
|
||||
|
||||
//Processing
|
||||
void ProcessSignal(CVoicePacket& voicePacket);
|
||||
|
||||
// interfaces
|
||||
bool IsInterfaceIn(const CVocodecInterface *interface) { return (interface == m_InterfaceIn); }
|
||||
bool IsInterfaceOut(const CVocodecInterface *interface) { return (interface == m_InterfaceOut); }
|
||||
|
|
@ -92,6 +97,8 @@ protected:
|
|||
// settings
|
||||
int m_iSpeechGain;
|
||||
|
||||
private:
|
||||
CSignalProcessor* m_signalProcessor;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
// get
|
||||
virtual const char *GetName(void) const { return ""; }
|
||||
virtual const char *GetSerial(void) const { return ""; }
|
||||
|
||||
// manage channels
|
||||
virtual int GetNbChannels(void) const { return 0; }
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "cusb3000interface.h"
|
||||
#include "cusb3003interface.h"
|
||||
#include "cvocodecs.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -89,78 +87,162 @@ bool CVocodecs::Init(void)
|
|||
DiscoverFtdiDevices();
|
||||
|
||||
// and create interfaces for the discovered devices
|
||||
// first handle all even number of channels devices
|
||||
std::vector<CVocodecChannel *> Multi3003DevicesChs;
|
||||
for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ )
|
||||
{
|
||||
// create relevant interface
|
||||
if ( m_FtdiDeviceDescrs[i]->IsUsb3012() )
|
||||
CFtdiDeviceDescr *descr = m_FtdiDeviceDescrs[i];
|
||||
if ( !descr->IsUsed() && IsEven(descr->GetNbChannels()) )
|
||||
{
|
||||
iNbCh += InitUsb3012(*m_FtdiDeviceDescrs[i]);
|
||||
m_FtdiDeviceDescrs[i]->SetUsed(true);
|
||||
// create the object
|
||||
iNbCh += CFtdiDeviceDescr::CreateInterface(descr, &Multi3003DevicesChs);
|
||||
// and flag as used
|
||||
descr->SetUsed(true);
|
||||
}
|
||||
else if ( m_FtdiDeviceDescrs[i]->IsUsb3003() && !m_FtdiDeviceDescrs[i]->IsUsed() )
|
||||
}
|
||||
// next handle all single channel devices.
|
||||
// they must be handeled in pair, or in pair with another
|
||||
// even number of channels device.
|
||||
std::vector<CVocodecChannel *> PairsOf3000DevicesChs;
|
||||
for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ )
|
||||
{
|
||||
CFtdiDeviceDescr *descr1 = m_FtdiDeviceDescrs[i];
|
||||
CFtdiDeviceDescr *descr2 = NULL;
|
||||
if ( !descr1->IsUsed() && (descr1->GetNbChannels() == 1) )
|
||||
{
|
||||
// another unsed USB-3003 avaliable for a pair ?
|
||||
// any other single channel device to pair with ?
|
||||
bool found = false;
|
||||
int j = i+1;
|
||||
while ( !found && (j < m_FtdiDeviceDescrs.size()) )
|
||||
{
|
||||
if ( m_FtdiDeviceDescrs[j]->IsUsb3003() && !m_FtdiDeviceDescrs[i]->IsUsed() )
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
j++;
|
||||
}
|
||||
descr2 = m_FtdiDeviceDescrs[j];
|
||||
found = (!descr2->IsUsed() && (descr2->GetNbChannels() == 1));
|
||||
j++;
|
||||
}
|
||||
|
||||
// pair ?
|
||||
// found one ?
|
||||
if ( found )
|
||||
{
|
||||
// yes!
|
||||
iNbCh += InitUsb3003Pair(*m_FtdiDeviceDescrs[i], *m_FtdiDeviceDescrs[j]);
|
||||
m_FtdiDeviceDescrs[i]->SetUsed(true);
|
||||
m_FtdiDeviceDescrs[j]->SetUsed(true);
|
||||
// yes, create and pair both interfaces
|
||||
iNbCh += CFtdiDeviceDescr::CreateInterfacePair(descr1, descr2, &PairsOf3000DevicesChs);
|
||||
// and flag as used
|
||||
descr1->SetUsed(true);
|
||||
descr2->SetUsed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// now we should have only remaining the 3 channels device(s)
|
||||
// and possibly an unique single channel device
|
||||
std::vector<CVocodecChannel *> Single3003DeviceChannels;
|
||||
for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ )
|
||||
{
|
||||
CFtdiDeviceDescr *descr1 = m_FtdiDeviceDescrs[i];
|
||||
CFtdiDeviceDescr *descr2 = NULL;
|
||||
if ( !descr1->IsUsed() && (descr1->GetNbChannels() == 3) )
|
||||
{
|
||||
// any other 3 channel device to pair with ?
|
||||
bool found = false;
|
||||
int j = i+1;
|
||||
while ( !found && (j < m_FtdiDeviceDescrs.size()) )
|
||||
{
|
||||
descr2 = m_FtdiDeviceDescrs[j];
|
||||
found = (!descr2->IsUsed() && (descr2->GetNbChannels() == 3));
|
||||
j++;
|
||||
}
|
||||
// found one ?
|
||||
if ( found )
|
||||
{
|
||||
// yes, create and pair both interfaces
|
||||
iNbCh += CFtdiDeviceDescr::CreateInterfacePair(descr1, descr2, &Multi3003DevicesChs);
|
||||
// and flag as used
|
||||
descr1->SetUsed(true);
|
||||
descr2->SetUsed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// at this point we should have only remaining an unique 3 channels
|
||||
// and or a unique single channel
|
||||
std::vector<CVocodecChannel *> Combined3003And3000DeviceChannels;
|
||||
for ( int i = 0; i < m_FtdiDeviceDescrs.size(); i++ )
|
||||
{
|
||||
CFtdiDeviceDescr *descr1 = m_FtdiDeviceDescrs[i];
|
||||
CFtdiDeviceDescr *descr2 = NULL;
|
||||
// Any 3003 ?
|
||||
if ( !descr1->IsUsed() && (descr1->GetNbChannels() == 3) )
|
||||
{
|
||||
// any single channel device to pair with ?
|
||||
bool found = false;
|
||||
int j = 0;
|
||||
while ( !found && (j < m_FtdiDeviceDescrs.size()) )
|
||||
{
|
||||
descr2 = m_FtdiDeviceDescrs[j];
|
||||
found = ((descr1 != descr2) && !descr2->IsUsed() && (descr2->GetNbChannels() == 1));
|
||||
j++;
|
||||
}
|
||||
// found one ?
|
||||
if ( found )
|
||||
{
|
||||
// yes, create and pair both interfaces
|
||||
iNbCh += CFtdiDeviceDescr::CreateInterfacePair(descr1, descr2, &Combined3003And3000DeviceChannels);
|
||||
// and flag as used
|
||||
descr1->SetUsed(true);
|
||||
descr2->SetUsed(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just single
|
||||
iNbCh += InitUsb3003(*m_FtdiDeviceDescrs[i]);
|
||||
m_FtdiDeviceDescrs[i]->SetUsed(true);
|
||||
// no, just create a standalone 3003 interface
|
||||
iNbCh += CFtdiDeviceDescr::CreateInterface(descr1, &Single3003DeviceChannels);
|
||||
// and flag as used
|
||||
descr1->SetUsed(true);
|
||||
}
|
||||
}
|
||||
else if ( m_FtdiDeviceDescrs[i]->IsUsb3000() && !m_FtdiDeviceDescrs[i]->IsUsed() )
|
||||
{
|
||||
// another unsed USB-3000 avaliable for a pair ?
|
||||
bool found = false;
|
||||
int j = i+1;
|
||||
while ( !found && (j < m_FtdiDeviceDescrs.size()) )
|
||||
{
|
||||
if ( m_FtdiDeviceDescrs[j]->IsUsb3000() && !m_FtdiDeviceDescrs[i]->IsUsed() )
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
// pair ?
|
||||
if ( found )
|
||||
{
|
||||
// yes!
|
||||
iNbCh += InitUsb3000Pair(*m_FtdiDeviceDescrs[i], *m_FtdiDeviceDescrs[j]);
|
||||
m_FtdiDeviceDescrs[i]->SetUsed(true);
|
||||
m_FtdiDeviceDescrs[j]->SetUsed(true);
|
||||
}
|
||||
// otherwise anonther unused USB-3003 for a pair ?
|
||||
}
|
||||
}
|
||||
// at this point we should possible only have unique 3003 remaining
|
||||
|
||||
// now agregate channels by order of priority
|
||||
// for proper load sharing
|
||||
// pairs of 3000 devices first
|
||||
{
|
||||
for ( int i = 0; i < PairsOf3000DevicesChs.size(); i++ )
|
||||
{
|
||||
m_Channels.push_back(PairsOf3000DevicesChs.at(i));
|
||||
}
|
||||
PairsOf3000DevicesChs.clear();
|
||||
}
|
||||
// next the left-over single 3003 device
|
||||
{
|
||||
for ( int i = 0; i < Single3003DeviceChannels.size(); i++ )
|
||||
{
|
||||
m_Channels.push_back(Single3003DeviceChannels.at(i));
|
||||
}
|
||||
Single3003DeviceChannels.clear();
|
||||
}
|
||||
// finally interlace multi-3003 and pairs of 3003 devices which always
|
||||
// results to 6 channels per pair of 3003
|
||||
{
|
||||
int n = (int)Multi3003DevicesChs.size() / 6;
|
||||
for ( int i = 0; (i < 6) && (n != 0); i++ )
|
||||
{
|
||||
for ( int j = 0; j < n; j++ )
|
||||
{
|
||||
m_Channels.push_back(Multi3003DevicesChs.at((j*6) + i));
|
||||
}
|
||||
}
|
||||
Multi3003DevicesChs.clear();
|
||||
}
|
||||
// and finaly the hybrid combination of 3003 / 3000
|
||||
{
|
||||
for ( int i = 0; i < Combined3003And3000DeviceChannels.size(); i++ )
|
||||
{
|
||||
m_Channels.push_back(Combined3003And3000DeviceChannels.at(i));
|
||||
}
|
||||
Combined3003And3000DeviceChannels.clear();
|
||||
}
|
||||
|
||||
|
||||
// done
|
||||
if ( ok )
|
||||
{
|
||||
std::cout << "Codec interfaces initialized successfully : " << iNbCh << " channels availables" << std::endl;
|
||||
std::cout << "Codec interfaces initialized successfully : " << iNbCh << " channels available" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -207,6 +289,7 @@ bool CVocodecs::DiscoverFtdiDevices(void)
|
|||
list[i].Description, list[i].SerialNumber);
|
||||
m_FtdiDeviceDescrs.push_back(descr);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -222,221 +305,6 @@ bool CVocodecs::DiscoverFtdiDevices(void)
|
|||
return ok;
|
||||
}
|
||||
|
||||
int CVocodecs::InitUsb3012(const CFtdiDeviceDescr &descr)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the four 3003 chips
|
||||
CUsb3003Interface *Usb3003A = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_A", descr.GetSerialNumber());
|
||||
CUsb3003Interface *Usb3003B = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_B", descr.GetSerialNumber());
|
||||
CUsb3003Interface *Usb3003C = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_C", descr.GetSerialNumber());
|
||||
CUsb3003Interface *Usb3003D = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3012_D", descr.GetSerialNumber());
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) &&
|
||||
Usb3003C->Init(CODEC_AMBEPLUS) && Usb3003D->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch5
|
||||
Channel = new CVocodecChannel(Usb3003C, 0, Usb3003C, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
// ch6
|
||||
Channel = new CVocodecChannel(Usb3003C, 1, Usb3003C, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
// ch7
|
||||
Channel = new CVocodecChannel(Usb3003D, 0, Usb3003D, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch8
|
||||
Channel = new CVocodecChannel(Usb3003D, 1, Usb3003D, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch9
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch10
|
||||
Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch11
|
||||
Channel = new CVocodecChannel(Usb3003C, 2, Usb3003D, 2, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
// ch12
|
||||
Channel = new CVocodecChannel(Usb3003D, 2, Usb3003C, 2, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003C->AddChannel(Channel);
|
||||
Usb3003D->AddChannel(Channel);
|
||||
//done
|
||||
nStreams = 12;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3003B;
|
||||
delete Usb3003C;
|
||||
delete Usb3003D;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
int CVocodecs::InitUsb3003(const CFtdiDeviceDescr &descr)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the 3003 chip
|
||||
CUsb3003Interface *Usb3003 = new CUsb3003Interface(descr.GetVid(), descr.GetPid(), "USB-3003", descr.GetSerialNumber());
|
||||
|
||||
// init the interface
|
||||
if ( Usb3003->Init(CODEC_NONE) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003, 0, Usb3003, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003, 1, Usb3003, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
int CVocodecs::InitUsb3003Pair(const CFtdiDeviceDescr &descr1, const CFtdiDeviceDescr &descr2)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the two 3003 chips
|
||||
CUsb3003Interface *Usb3003A = new CUsb3003Interface(descr1.GetVid(), descr1.GetPid(), "USB-3003", descr1.GetSerialNumber());
|
||||
CUsb3003Interface *Usb3003B = new CUsb3003Interface(descr2.GetVid(), descr2.GetPid(), "USB-3003", descr2.GetSerialNumber());
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3003A->Init(CODEC_AMBEPLUS) && Usb3003B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3003A, 0, Usb3003A, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3003A, 1, Usb3003A, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
// ch3
|
||||
Channel = new CVocodecChannel(Usb3003B, 0, Usb3003B, 1, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch4
|
||||
Channel = new CVocodecChannel(Usb3003B, 1, Usb3003B, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch5
|
||||
Channel = new CVocodecChannel(Usb3003A, 2, Usb3003B, 2, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// ch6
|
||||
Channel = new CVocodecChannel(Usb3003B, 2, Usb3003A, 2, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3003A->AddChannel(Channel);
|
||||
Usb3003B->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3003A;
|
||||
delete Usb3003B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
int CVocodecs::InitUsb3000Pair(const CFtdiDeviceDescr &descr1, const CFtdiDeviceDescr &descr2)
|
||||
{
|
||||
int nStreams = 0;
|
||||
|
||||
// create the interfaces for the two 3000 chips
|
||||
CUsb3000Interface *Usb3000A = new CUsb3000Interface(descr1.GetVid(), descr1.GetPid(), "USB-3000", descr1.GetSerialNumber());
|
||||
CUsb3000Interface *Usb3000B = new CUsb3000Interface(descr2.GetVid(), descr2.GetPid(), "USB-3000", descr2.GetSerialNumber());
|
||||
|
||||
// init the interfaces
|
||||
if ( Usb3000A->Init(CODEC_AMBEPLUS) && Usb3000B->Init(CODEC_AMBE2PLUS) )
|
||||
{
|
||||
CVocodecChannel *Channel;
|
||||
// create all channels
|
||||
{
|
||||
// ch1
|
||||
Channel = new CVocodecChannel(Usb3000A, 0, Usb3000B, 0, CODECGAIN_AMBEPLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3000A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// ch2
|
||||
Channel = new CVocodecChannel(Usb3000B, 0, Usb3000A, 0, CODECGAIN_AMBE2PLUS);
|
||||
m_Channels.push_back(Channel);
|
||||
Usb3000A->AddChannel(Channel);
|
||||
Usb3000B->AddChannel(Channel);
|
||||
// done
|
||||
nStreams = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// cleanup
|
||||
delete Usb3000A;
|
||||
delete Usb3000B;
|
||||
}
|
||||
|
||||
// done
|
||||
return nStreams;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// manage channels
|
||||
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ public:
|
|||
protected:
|
||||
// initialisation helpers
|
||||
bool DiscoverFtdiDevices(void);
|
||||
int InitUsb3012(const CFtdiDeviceDescr &);
|
||||
int InitUsb3003(const CFtdiDeviceDescr &);
|
||||
int InitUsb3003Pair(const CFtdiDeviceDescr &, const CFtdiDeviceDescr &);
|
||||
int InitUsb3000Pair(const CFtdiDeviceDescr &, const CFtdiDeviceDescr &);
|
||||
|
||||
// helpers
|
||||
bool IsEven(int i) const { return ((i % 2) == 0); }
|
||||
bool IsOdd(int i) const { return !IsEven(i); }
|
||||
|
||||
protected:
|
||||
// array of interfaces
|
||||
|
|
|
|||
|
|
@ -69,18 +69,3 @@ void CVoicePacket::SetVoice(const uint8 *voice, int size)
|
|||
::memcpy(m_uiVoice, voice, m_iSize);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// gain
|
||||
|
||||
void CVoicePacket::ApplyGain(int dB)
|
||||
{
|
||||
float mult = pow(10, dB/20.0);
|
||||
for ( int i = 0; i < m_iSize; i += 2 )
|
||||
{
|
||||
float smp = (float)(short)MAKEWORD(m_uiVoice[i+1], m_uiVoice[i]);
|
||||
smp *= mult;
|
||||
m_uiVoice[i] = HIBYTE((short)smp);
|
||||
m_uiVoice[i+1] = LOBYTE((short)smp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ public:
|
|||
|
||||
// destructor
|
||||
virtual ~CVoicePacket();
|
||||
|
||||
|
||||
// identity
|
||||
bool IsVoice(void) const { return true; }
|
||||
|
||||
// get
|
||||
uint8 *GetVoice(void) { return m_uiVoice; }
|
||||
int GetVoiceSize(void) const { return m_iSize; }
|
||||
|
|
@ -55,9 +58,6 @@ public:
|
|||
// set
|
||||
void SetVoice(const uint8 *, int);
|
||||
|
||||
// gain
|
||||
void ApplyGain(int);
|
||||
|
||||
protected:
|
||||
// data
|
||||
int m_iSize;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ int main(int argc, const char * argv[])
|
|||
g_AmbeServer.SetListenIp(CIp(argv[1]));
|
||||
|
||||
// and let it run
|
||||
std::cout << "Starting AMBEd" << std::endl << std::endl;
|
||||
std::cout << "Starting AMBEd " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl;
|
||||
if ( !g_AmbeServer.Start() )
|
||||
{
|
||||
std::cout << "Error starting AMBEd" << std::endl;
|
||||
|
|
@ -114,8 +114,12 @@ int main(int argc, const char * argv[])
|
|||
}
|
||||
#else
|
||||
// wait any key
|
||||
for (;;);
|
||||
//std::cin.get();
|
||||
for (;;)
|
||||
{
|
||||
// sleep 60 seconds
|
||||
CTimePoint::TaskSleepFor(60000);
|
||||
//std::cin.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
// and wait for end
|
||||
|
|
|
|||
46
ambed/main.h
|
|
@ -48,8 +48,8 @@
|
|||
// version -----------------------------------------------------
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_REVISION 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 5
|
||||
|
||||
// global ------------------------------------------------------
|
||||
|
||||
|
|
@ -59,8 +59,6 @@
|
|||
|
||||
// Transcoder server --------------------------------------------
|
||||
#define TRANSCODER_PORT 10100 // UDP port
|
||||
#define TRANSCODER_KEEPALIVE_PERIOD 5 // in seconds
|
||||
#define TRANSCODER_KEEPALIVE_TIMEOUT 30 // in seconds
|
||||
|
||||
// Codecs -------------------------------------------------------
|
||||
#define CODEC_NONE 0
|
||||
|
|
@ -68,9 +66,14 @@
|
|||
#define CODEC_AMBE2PLUS 2
|
||||
|
||||
// Transcoding speech gains
|
||||
#define CODECGAIN_AMBEPLUS -10 // in dB
|
||||
#define CODECGAIN_AMBEPLUS -10 // in dB
|
||||
#define CODECGAIN_AMBE2PLUS +10 // in dB
|
||||
|
||||
// Transcoding Tweaks
|
||||
#define USE_AGC 0
|
||||
#define AGC_CLAMPING 3 //clamps the AGC gain to +- this value
|
||||
#define USE_BANDPASSFILTER 1
|
||||
|
||||
// Timeouts -----------------------------------------------------
|
||||
#define STREAM_ACTIVITY_TIMEOUT 3 // in seconds
|
||||
|
||||
|
|
@ -96,6 +99,39 @@ typedef unsigned int uint;
|
|||
#define LOWORD(dw) ((uint16)(uint32)(dw & 0x0000FFFF))
|
||||
#define HIWORD(dw) ((uint16)((((uint32)(dw)) >> 16) & 0xFFFF))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FIR Filter coefficients computed to be the closest to the recommended filter in
|
||||
// Documentation
|
||||
//
|
||||
// Following GNU Octave script was used
|
||||
/*
|
||||
pkg load signal;
|
||||
fsamp = 8000;
|
||||
fcuts = [300 400 3000 3400];
|
||||
mags = [0 1 0];
|
||||
devs = [0.2 1 0.2];
|
||||
|
||||
[n,Wn,beta,ftype] = kaiserord(fcuts,mags,devs,fsamp);
|
||||
n = n + rem(n,2);
|
||||
hh = fir1(n,Wn,ftype,kaiser(n+1,beta),'noscale');
|
||||
|
||||
freqz(hh);
|
||||
[H,f] = freqz(hh,1,1024,fsamp);
|
||||
plot(f,abs(H))
|
||||
disp(hh);
|
||||
grid
|
||||
*/
|
||||
|
||||
#if USE_BANDPASSFILTER == 1
|
||||
|
||||
const float FILTER_TAPS[] {
|
||||
-0.05063341f, -0.00060337f, -0.08892498f, -0.02026701f, -0.05940750f, -0.10977641f, 0.03244024f, -0.22304499f,
|
||||
0.11452865f, 0.72500000f, 0.11452865f, -0.22304499f, 0.03244024f, -0.10977641f, -0.05940750f, -0.02026701f,
|
||||
-0.08892498f, -0.00060337f, -0.05063341f };
|
||||
#define FILTER_TAPS_LENGTH 19
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// global objects
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ $(EXECUTABLE): $(OBJECTS)
|
|||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o
|
||||
$(RM) $(EXECUTABLE) *.o
|
||||
|
||||
install:
|
||||
mkdir -p /ambed
|
||||
cp ./ambed /ambed/
|
||||
cp $(EXECUTABLE) /ambed/
|
||||
cp ./run /ambed/
|
||||
|
|
|
|||
38
ambed/readme
|
|
@ -3,7 +3,7 @@
|
|||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/07/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2017-2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
|
|
@ -22,26 +22,36 @@
|
|||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
VERSION: 1.3.4
|
||||
|
||||
Hardware compatibility.
|
||||
======================
|
||||
This version of ambed is compatible with DVSI's USB-3000, USB-3003, USB-3012 device
|
||||
and ThumbDV
|
||||
This version of ambed is compatible with:
|
||||
- DF2ET's AMBE3003USB opensource device (https://github.com/phl0/AMBE3003USB)
|
||||
- LX3JL's USB-3006 opensource device (https://github.com/lx3jl/usb-3006)
|
||||
- DVSI's USB-3000 device
|
||||
- DVSI's USB-3003 device
|
||||
- DVSI's USB-3012 device
|
||||
- NWDR's ThumbDV device
|
||||
- NWDR's ThumbDV-3 device
|
||||
- DVMEGA AMBE3000 device
|
||||
- DVMEGA AMBE3003 device
|
||||
|
||||
Available transcoding channels per device:
|
||||
|
||||
device DMR->DSTAR DSTAR->DMR Nb Of concurrent channels
|
||||
----------------------------------------------------------------------
|
||||
USB-3000(pair) 1 1 2
|
||||
USB-3003 1 1 1
|
||||
USB-3003(pair) 3 3 not tested
|
||||
USB-3012 6 6 8
|
||||
|
||||
Multiple USB-3xxx can be used at the same time.
|
||||
You need to use USB-3000 by pairs.
|
||||
ThumbDV is recognized as USB-3000.
|
||||
ThumbDV must be programed with FT-Prog (Provided by FTDI) by modifying device description as "USB-3000".
|
||||
-------------------------------------------------------------------------
|
||||
3000(pair) 1 1 2
|
||||
3003 1 1 2
|
||||
3003(pair) 3 3 4
|
||||
3003-3000(pair) 2 2 4
|
||||
3006 3 3 6
|
||||
3012 6 6 12
|
||||
|
||||
Multiple devices can be used at the same time.
|
||||
You need to use 3000 by pairs or paired with a 3003
|
||||
Do not to use USB hubs as they have proven making
|
||||
system behaviour unreliable.
|
||||
|
||||
Instructions:
|
||||
=============
|
||||
|
|
@ -61,8 +71,8 @@ Follow FTDI provided documentation for installation and testing of the drivers.
|
|||
|
||||
# git clone https://github.com/LX3JL/xlxd.git
|
||||
# cd xlxd/ambed/
|
||||
# make
|
||||
# make clean
|
||||
# make
|
||||
# make install
|
||||
|
||||
3) configuring ambed startup script
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ CCodecStream::CCodecStream(uint16 uiId, uint8 uiCodecIn, uint8 uiCodecOut)
|
|||
m_bConnected = false;
|
||||
m_iAmbeSrcPtr = 0;
|
||||
m_iAmbeDestPtr = 0;
|
||||
m_uiNbTotalPacketSent = 0;
|
||||
m_uiNbPacketSent = 0;
|
||||
m_uiNbPacketReceived = 0;
|
||||
m_uiNbPacketBad = 0;
|
||||
|
|
@ -120,6 +121,7 @@ bool CCodecStream::Init(uint16 uiPort)
|
|||
m_pThread = new std::thread(CCodecStream::Thread, this);
|
||||
m_bConnected = true;
|
||||
m_FrameTimer.Now();
|
||||
m_uiNbTotalPacketSent = 0;
|
||||
ResetStats();
|
||||
}
|
||||
else
|
||||
|
|
@ -181,11 +183,12 @@ void CCodecStream::Task(void)
|
|||
|
||||
// and increment pointer
|
||||
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
|
||||
m_uiNbTotalPacketSent++;
|
||||
m_uiNbPacketSent++;
|
||||
}*/
|
||||
|
||||
// any packt to send to trancoder ?
|
||||
uint32 uiNbPacketToSend = (uint32)(m_FrameTimer.DurationSinceNow() * 50.0) - m_uiNbPacketSent;
|
||||
uint32 uiNbPacketToSend = (uint32)(m_FrameTimer.DurationSinceNow() * 50.0) - m_uiNbTotalPacketSent;
|
||||
if ( uiNbPacketToSend > 0 )
|
||||
{
|
||||
for ( int i = 0; i < uiNbPacketToSend; i++ )
|
||||
|
|
@ -196,6 +199,7 @@ void CCodecStream::Task(void)
|
|||
|
||||
// and increment pointer
|
||||
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
|
||||
m_uiNbTotalPacketSent++;
|
||||
m_uiNbPacketSent++;
|
||||
}
|
||||
}
|
||||
|
|
@ -283,15 +287,19 @@ void CCodecStream::ResetStats(void)
|
|||
|
||||
void CCodecStream::DisplayStats(void)
|
||||
{
|
||||
//double fps = (double)m_uiNbPacketSent / m_StatsTimer.DurationSinceNow();
|
||||
double fps = (double)m_uiNbPacketReceived / m_StatsTimer.DurationSinceNow();
|
||||
// get stats
|
||||
uint32 uiSent = m_uiNbPacketSent;
|
||||
uint32 uiReceived = m_uiNbPacketReceived;
|
||||
uint32 uiBad = m_uiNbPacketBad;
|
||||
double fps = (double)uiReceived / m_StatsTimer.DurationSinceNow();
|
||||
|
||||
std::cout << "Stream " << (int)m_uiStreamId << " (" << (int)m_uiCodecIn << "->" << (int)m_uiCodecOut << ") : ";
|
||||
std::cout << m_uiNbPacketSent << " / " << m_uiNbPacketReceived << " / " << m_uiNbPacketTimeout;
|
||||
//std::cout << " / " << m_uiNbPacketBad;
|
||||
std::cout << " ; " << fps << " fps";
|
||||
// resets
|
||||
ResetStats();
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
m_uiNbPacketBad = 0;
|
||||
// displays
|
||||
char sz[256];
|
||||
sprintf(sz, "Stream %d (%d->%d) : %u / %u / %u : %.1f fps",
|
||||
m_uiStreamId, m_uiCodecIn, m_uiCodecOut,
|
||||
uiSent, uiReceived, uiBad, fps);
|
||||
std::cout << sz << std::endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ protected:
|
|||
std::thread *m_pThread;
|
||||
CTimePoint m_TimeoutTimer;
|
||||
CTimePoint m_FrameTimer;
|
||||
uint32 m_uiNbTotalPacketSent;
|
||||
|
||||
// stats
|
||||
CTimePoint m_StatsTimer;
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ $(EXECUTABLE): $(OBJECTS)
|
|||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o
|
||||
$(RM) $(EXECUTABLE) *.o
|
||||
|
|
|
|||
17
config/xlxd.terminal
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#########################################################################################
|
||||
# XLXD terminal option file
|
||||
#
|
||||
# one line per entry
|
||||
# each entry specifies a terminal option
|
||||
#
|
||||
# Valid option:
|
||||
# address <ip> - Ip address to be used by the terminal route responder
|
||||
# By default, the request destination address is used.
|
||||
# If the system is behind a router, set it to the public IP
|
||||
# If the system runs on the public IP, leave unset.
|
||||
# modules <modules> - a string with all modules to accept a terminal connection
|
||||
# Default value is "*", meaning accept all
|
||||
#
|
||||
#########################################################################################
|
||||
#address 193.1.2.3
|
||||
#modules BCD
|
||||
|
|
@ -1,6 +1,38 @@
|
|||
xlx db v2.4.1
|
||||
|
||||
you can now hide the liveircddb menu button, if you are running your db in https.
|
||||
|
||||
- "config.inc.php
|
||||
- "index.php"
|
||||
|
||||
xlx db v2.4.0
|
||||
|
||||
- "config.inc.php"
|
||||
- "index.php"
|
||||
- "js"
|
||||
- "layout.css"
|
||||
|
||||
xlx db v2.3.9
|
||||
|
||||
redesign for the callinghome.php
|
||||
|
||||
- "config.inc.php"
|
||||
- "index.php"
|
||||
- "functions.php"
|
||||
|
||||
xlx db v2.3.8
|
||||
|
||||
add support for network traffic statistics via vnstat.
|
||||
|
||||
- "config.inc.php"
|
||||
- "index.php"
|
||||
- "functions.php"
|
||||
|
||||
add traffic.php
|
||||
|
||||
xlx db v2.3.7
|
||||
|
||||
add background button color change on active page.
|
||||
add background color change on active page.
|
||||
|
||||
- "config.inc.php"
|
||||
- "layout.css"
|
||||
|
|
@ -66,7 +98,7 @@ xlx db v2.2.2
|
|||
|
||||
This version is a major release with voluntary self-registration feature build in.
|
||||
You need to edit the conf.inc.php to your needs.
|
||||
On the first run your personal hash to access the database is place in the server’s /tmp folder.
|
||||
On the first run your personal hash to access the database is place in the server’s /tmp folder.
|
||||
Take care to make a backup of this file because this folder is cleaned up after a server reboot.
|
||||
|
||||
This version is a major release
|
||||
|
|
@ -94,7 +126,7 @@ xlx db v2.1.4
|
|||
|
||||
- "class.reflector.php" improved the flag search
|
||||
- "country.csv" added serveral prefixes
|
||||
- "flags" added Puerto Ricco and Åland Islands
|
||||
- "flags" added Puerto Ricco and Åland Islands
|
||||
|
||||
xlx db v2.1.3
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ h1 {
|
|||
font-size : 25pt;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a.tip {
|
||||
text-decoration : none;
|
||||
}
|
||||
|
|
@ -79,6 +83,7 @@ a.tip:hover span {
|
|||
.menulink {
|
||||
font-size : 14pt;
|
||||
text-decoration : none;
|
||||
white-space : nowrap;
|
||||
border : 1px #000000 solid;
|
||||
padding-left : 10px;
|
||||
padding-top : 3px;
|
||||
|
|
@ -92,6 +97,7 @@ a.tip:hover span {
|
|||
.menulinkactive {
|
||||
font-size : 14pt;
|
||||
text-decoration : none;
|
||||
white-space : nowrap;
|
||||
border : 1px #000000 solid;
|
||||
padding-left : 10px;
|
||||
padding-top : 3px;
|
||||
|
|
@ -117,18 +123,19 @@ a.tip:hover span {
|
|||
.listingtable th {
|
||||
height : 35px;
|
||||
text-align : center;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0, rgb(201, 231, 233)),
|
||||
color-stop(0.8, rgb(220, 237, 244))
|
||||
);
|
||||
background-image: -o-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -moz-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -webkit-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -ms-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: linear-gradient(to bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-color : #D5EBF0;
|
||||
background-image : -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0, rgb(201, 231, 233)),
|
||||
color-stop(0.8, rgb(220, 237, 244))
|
||||
);
|
||||
background-image: -o-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -moz-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -webkit-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -ms-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: linear-gradient(to bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
}
|
||||
|
||||
.listingtable td {
|
||||
|
|
@ -136,7 +143,7 @@ background-image: linear-gradient(to bottom, rgb(201, 231, 233) 0%, rgb(220, 237
|
|||
}
|
||||
|
||||
.listinglink {
|
||||
font-size : 12pt;
|
||||
font-size : 12pt;
|
||||
text-decoration : underline;
|
||||
color : #60A1DE;
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 371 B |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
|
@ -1 +0,0 @@
|
|||
no.png
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 788 B |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
dashboard/img/flags/en.png
Normal file
|
After Width: | Height: | Size: 233 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 566 B |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1,022 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
|
|
@ -1 +0,0 @@
|
|||
au.png
|
||||
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1,023 B |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 923 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
|
@ -1 +0,0 @@
|
|||
us.png
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -1 +0,0 @@
|
|||
fr.png
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
session_start();
|
||||
|
||||
if (file_exists("./pgs/functions.php")) { require_once("./pgs/functions.php"); } else { die("functions.php does not exist."); }
|
||||
if (file_exists("./pgs/config.inc.php")) { require_once("./pgs/config.inc.php"); } else { die("config.inc.php does not exist."); }
|
||||
if (file_exists("./pgs/functions.php")) { require_once("./pgs/functions.php"); } else { die("functions.php does not exist."); }
|
||||
if (file_exists("./pgs/config.inc.php")) { require_once("./pgs/config.inc.php"); } else { die("config.inc.php does not exist."); }
|
||||
|
||||
if (!class_exists('ParseXML')) require_once("./pgs/class.parsexml.php");
|
||||
if (!class_exists('Node')) require_once("./pgs/class.node.php");
|
||||
|
|
@ -22,34 +22,45 @@ $Reflector->LoadXML();
|
|||
if ($CallingHome['Active']) {
|
||||
|
||||
$CallHomeNow = false;
|
||||
$LastSync = 0;
|
||||
$Hash = "";
|
||||
|
||||
if (!file_exists($CallingHome['HashFile'])) {
|
||||
$Hash = CreateCode(16);
|
||||
$LastSync = 0;
|
||||
$Ressource = @fopen($CallingHome['HashFile'],"w");
|
||||
if ($Ressource) {
|
||||
@fwrite($Ressource, "<?php\n");
|
||||
@fwrite($Ressource, "\n".'$LastSync = 0;');
|
||||
@fwrite($Ressource, "\n".'$Hash = "'.$Hash.'";');
|
||||
@fwrite($Ressource, "\n\n".'?>');
|
||||
@fclose($Ressource);
|
||||
@exec("chmod 777 ".$CallingHome['HashFile']);
|
||||
$CallHomeNow = true;
|
||||
}
|
||||
$Ressource = fopen($CallingHome['HashFile'], "w+");
|
||||
if ($Ressource) {
|
||||
$Hash = CreateCode(16);
|
||||
@fwrite($Ressource, "<?php\n");
|
||||
@fwrite($Ressource, "\n".'$Hash = "'.$Hash.'";');
|
||||
@fwrite($Ressource, "\n\n".'?>');
|
||||
@fflush($Ressource);
|
||||
@fclose($Ressource);
|
||||
@chmod($HashFile, 0777);
|
||||
}
|
||||
}
|
||||
else {
|
||||
include($CallingHome['HashFile']);
|
||||
if ($LastSync < (time() - $CallingHome['PushDelay'])) {
|
||||
$Ressource = @fopen($CallingHome['HashFile'],"w");
|
||||
if ($Ressource) {
|
||||
@fwrite($Ressource, "<?php\n");
|
||||
@fwrite($Ressource, "\n".'$LastSync = '.time().';');
|
||||
@fwrite($Ressource, "\n".'$Hash = "'.$Hash.'";');
|
||||
@fwrite($Ressource, "\n\n".'?>');
|
||||
@fclose($Ressource);
|
||||
require_once($CallingHome['HashFile']);
|
||||
}
|
||||
|
||||
if (@file_exists($CallingHome['LastCallHomefile'])) {
|
||||
if (@is_readable($CallingHome['LastCallHomefile'])) {
|
||||
$tmp = @file($CallingHome['LastCallHomefile']);
|
||||
if (isset($tmp[0])) {
|
||||
$LastSync = $tmp[0];
|
||||
}
|
||||
$CallHomeNow = true;
|
||||
unset($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if ($LastSync < (time() - $CallingHome['PushDelay'])) {
|
||||
$CallHomeNow = true;
|
||||
$Ressource = @fopen($CallingHome['LastCallHomefile'], "w+");
|
||||
if ($Ressource) {
|
||||
@fwrite($Ressource, time());
|
||||
@fflush($Ressource);
|
||||
@fclose($Ressource);
|
||||
@chmod($HashFile, 0777);
|
||||
}
|
||||
}
|
||||
|
||||
if ($CallHomeNow || isset($_GET['callhome'])) {
|
||||
$Reflector->SetCallingHome($CallingHome, $Hash);
|
||||
|
|
@ -58,15 +69,14 @@ if ($CallingHome['Active']) {
|
|||
$Reflector->PrepareReflectorXML();
|
||||
$Reflector->CallHome();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$Hash = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?><!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
|
@ -84,25 +94,32 @@ else {
|
|||
|
||||
if ($PageOptions['PageRefreshActive']) {
|
||||
echo '
|
||||
<script src="./js/jquery-1.12.4.min.js"></script>
|
||||
<script>
|
||||
var PageRefresh;
|
||||
|
||||
function ReloadPage() {
|
||||
document.location.href = "./index.php';
|
||||
if (isset($_GET['show'])) {
|
||||
echo '?show='.$_GET['show'];
|
||||
}
|
||||
echo '";
|
||||
$.get("./index.php'.(isset($_GET['show'])?'?show='.$_GET['show']:'').'", function(data) {
|
||||
var BodyStart = data.indexOf("<bo"+"dy");
|
||||
var BodyEnd = data.indexOf("</bo"+"dy>");
|
||||
if ((BodyStart >= 0) && (BodyEnd > BodyStart)) {
|
||||
BodyStart = data.indexOf(">", BodyStart)+1;
|
||||
$("body").html(data.substring(BodyStart, BodyEnd));
|
||||
}
|
||||
})
|
||||
.always(function() {
|
||||
PageRefresh = setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');
|
||||
});
|
||||
}';
|
||||
|
||||
if (!isset($_GET['show']) || (($_GET['show'] != 'liveircddb') && ($_GET['show'] != 'reflectors') && ($_GET['show'] != 'interlinks'))) {
|
||||
echo '
|
||||
PageRefresh = setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');';
|
||||
PageRefresh = setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');';
|
||||
}
|
||||
echo '
|
||||
|
||||
function SuspendPageRefresh() {
|
||||
clearTimeout(PageRefresh);
|
||||
clearTimeout(PageRefresh);
|
||||
}
|
||||
</script>';
|
||||
}
|
||||
|
|
@ -113,12 +130,32 @@ else {
|
|||
<body>
|
||||
<?php if (file_exists("./tracking.php")) { include_once("tracking.php"); }?>
|
||||
<div id="top"><img src="./img/header.jpg" alt="XLX Multiprotocol Gateway Reflector" style="margin-top:15px;" />
|
||||
<br /> <?php echo $Reflector->GetReflectorName(); ?> v<?php echo $Reflector->GetVersion(); ?> - Dashboard v<?php echo $PageOptions['DashboardVersion']; ?> / Service uptime: <span id="suptime"><?php echo FormatSeconds($Reflector->GetServiceUptime()); ?></span></div>
|
||||
<br /> <?php echo $Reflector->GetReflectorName(); ?> v<?php echo $Reflector->GetVersion(); ?> - Dashboard v<?php echo $PageOptions['DashboardVersion']; ?> <?php echo $PageOptions['CustomTXT']; ?> / Service uptime: <span id="suptime"><?php echo FormatSeconds($Reflector->GetServiceUptime()); ?></span></div>
|
||||
<div id="menubar">
|
||||
<div id="menu">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td><a href="./index.php" class="menulink<?php if ($_GET['show'] == '') { echo 'active'; } ?>">Users / Modules</a></td><td><a href="./index.php?show=repeaters" class="menulink<?php if ($_GET['show'] == 'repeaters') { echo 'active'; } ?>">Repeaters / Nodes (<?php echo $Reflector->NodeCount(); ?>)</a></td><td><a href="./index.php?show=peers" class="menulink<?php if ($_GET['show'] == 'peers') { echo 'active'; } ?>">Peers (<?php echo $Reflector->PeerCount(); ?>)</a></td><td><a href="./index.php?show=reflectors" class="menulink<?php if ($_GET['show'] == 'reflectors') { echo 'active'; } ?>">Reflectorlist</a></td><td><a href="./index.php?show=liveircddb" class="menulink<?php if ($_GET['show'] == 'liveircddb') { echo 'active'; } ?>">D-Star live</a></td>
|
||||
<td><a href="./index.php" class="menulink<?php if ($_GET['show'] == '') { echo 'active'; } ?>">Users / Modules</a></td>
|
||||
<td><a href="./index.php?show=repeaters" class="menulink<?php if ($_GET['show'] == 'repeaters') { echo 'active'; } ?>">Repeaters / Nodes (<?php echo $Reflector->NodeCount(); ?>)</a></td>
|
||||
<td><a href="./index.php?show=peers" class="menulink<?php if ($_GET['show'] == 'peers') { echo 'active'; } ?>">Peers (<?php echo $Reflector->PeerCount(); ?>)</a></td>
|
||||
<td><a href="./index.php?show=modules" class="menulink<?php if ($_GET['show'] == 'modules') { echo 'active'; } ?>">Modules list</a></td>
|
||||
<td><a href="./index.php?show=reflectors" class="menulink<?php if ($_GET['show'] == 'reflectors') { echo 'active'; } ?>">Reflectors list</a></td>
|
||||
<?php
|
||||
|
||||
if ($PageOptions['Traffic']['Show']) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=traffic" class="menulink';
|
||||
if ($_GET['show'] == 'traffic') { echo 'active'; }
|
||||
echo '">Traffic statistics</a></td>';
|
||||
}
|
||||
if ($PageOptions['IRCDDB']['Show']) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=liveircddb" class="menulink';
|
||||
if ($_GET['show'] == 'liveircddb') { echo 'active'; }
|
||||
echo '">D-Star live</a></td>';
|
||||
}
|
||||
|
||||
?>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -140,7 +177,9 @@ else {
|
|||
case 'repeaters' : require_once("./pgs/repeaters.php"); break;
|
||||
case 'liveircddb' : require_once("./pgs/liveircddb.php"); break;
|
||||
case 'peers' : require_once("./pgs/peers.php"); break;
|
||||
case 'modules' : require_once("./pgs/modules.php"); break;
|
||||
case 'reflectors' : require_once("./pgs/reflectors.php"); break;
|
||||
case 'traffic' : require_once("./pgs/traffic.php"); break;
|
||||
default : require_once("./pgs/users.php");
|
||||
}
|
||||
|
||||
|
|
|
|||
5
dashboard/js/jquery-1.12.4.min.js
vendored
Normal file
|
|
@ -2,30 +2,31 @@
|
|||
|
||||
class xReflector {
|
||||
|
||||
public $Nodes = null;
|
||||
public $Stations = null;
|
||||
public $Peers = null;
|
||||
private $Flagarray = null;
|
||||
private $Flagfile = null;
|
||||
private $CallingHomeActive = null;
|
||||
private $CallingHomeHash = null;
|
||||
private $CallingHomeDashboardURL = null;
|
||||
private $CallingHomeServerURL = null;
|
||||
private $ReflectorName = null;
|
||||
private $ServiceUptime = null;
|
||||
private $ProcessIDFile = null;
|
||||
private $XMLContent = null;
|
||||
private $XMLFile = null;
|
||||
private $ServiceName = null;
|
||||
private $Version = null;
|
||||
private $CallingHomeCountry = null;
|
||||
private $CallingHomeComment = null;
|
||||
private $CallingHomeOverrideIP = null;
|
||||
private $Transferinterlink = null;
|
||||
private $Interlinkfile = null;
|
||||
public $Nodes = null;
|
||||
public $Stations = null;
|
||||
public $Peers = null;
|
||||
private $Flagarray = null;
|
||||
private $Flagarray_DXCC = null;
|
||||
private $Flagfile = null;
|
||||
private $CallingHomeActive = null;
|
||||
private $CallingHomeHash = null;
|
||||
private $CallingHomeDashboardURL = null;
|
||||
private $CallingHomeServerURL = null;
|
||||
private $ReflectorName = null;
|
||||
private $ServiceUptime = null;
|
||||
private $ProcessIDFile = null;
|
||||
private $XMLContent = null;
|
||||
private $XMLFile = null;
|
||||
private $ServiceName = null;
|
||||
private $Version = null;
|
||||
private $CallingHomeCountry = null;
|
||||
private $CallingHomeComment = null;
|
||||
private $CallingHomeOverrideIP = null;
|
||||
private $Transferinterlink = null;
|
||||
private $Interlinkfile = null;
|
||||
public $Interlinks = null;
|
||||
private $InterlinkXML = null;
|
||||
private $ReflectorXML = null;
|
||||
private $InterlinkXML = null;
|
||||
private $ReflectorXML = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->Nodes = array();
|
||||
|
|
@ -40,13 +41,14 @@ class xReflector {
|
|||
$handle = fopen($this->XMLFile, 'r');
|
||||
$this->XMLContent = fread($handle, filesize($this->XMLFile));
|
||||
fclose($handle);
|
||||
|
||||
|
||||
# XLX alphanumeric naming...
|
||||
$this->ServiceName = substr($this->XMLContent, strpos($this->XMLContent, "<XLX")+4, 3);
|
||||
if (!is_numeric($this->ServiceName)) {
|
||||
if (preg_match('/[^a-zA-Z0-9]/', $this->ServiceName) == 1) {
|
||||
$this->ServiceName = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$this->ReflectorName = "XLX".$this->ServiceName;
|
||||
|
||||
$LinkedPeersName = "XLX".$this->ServiceName." linked peers";
|
||||
|
|
@ -125,6 +127,7 @@ class xReflector {
|
|||
public function LoadFlags() {
|
||||
if ($this->Flagfile != null) {
|
||||
$this->Flagarray = array();
|
||||
$this->Flagarray_DXCC = array();
|
||||
$handle = fopen($this->Flagfile,"r");
|
||||
if ($handle) {
|
||||
$i = 0;
|
||||
|
|
@ -134,11 +137,12 @@ class xReflector {
|
|||
|
||||
if (isset($tmp[0])) { $this->Flagarray[$i]['Country'] = $tmp[0]; } else { $this->Flagarray[$i]['Country'] = 'Undefined'; }
|
||||
if (isset($tmp[1])) { $this->Flagarray[$i]['ISO'] = $tmp[1]; } else { $this->Flagarray[$i]['ISO'] = "Undefined"; }
|
||||
$this->Flagarray[$i]['DXCC'] = array();
|
||||
//$this->Flagarray[$i]['DXCC'] = array();
|
||||
if (isset($tmp[2])) {
|
||||
$tmp2 = explode("-", $tmp[2]);
|
||||
for ($j=0;$j<count($tmp2);$j++) {
|
||||
$this->Flagarray[$i]['DXCC'][] = $tmp2[$j];
|
||||
//$this->Flagarray[$i]['DXCC'][] = $tmp2[$j];
|
||||
$this->Flagarray_DXCC[ trim($tmp2[$j]) ] = $i;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
|
|
@ -236,7 +240,12 @@ class xReflector {
|
|||
$i = 0;
|
||||
while ($i < $this->NodeCount()) {
|
||||
if ($this->Nodes[$i]->GetRandomID() == $RandomId) {
|
||||
return $this->Nodes[$i]->GetCallSign().'-'.$this->Nodes[$i]->GetSuffix();
|
||||
if (trim($this->Nodes[$i]->GetSuffix()) == "") {
|
||||
return $this->Nodes[$i]->GetCallSign();
|
||||
}
|
||||
else {
|
||||
return $this->Nodes[$i]->GetCallSign().'-'.$this->Nodes[$i]->GetSuffix();
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
|
@ -256,25 +265,15 @@ class xReflector {
|
|||
|
||||
public function GetFlag($Callsign) {
|
||||
$Image = "";
|
||||
$FoundFlag = false;
|
||||
$Letters = 4;
|
||||
$Name = "";
|
||||
while (($Letters >= 2) && (!$FoundFlag)) {
|
||||
$j = 0;
|
||||
$Prefix = substr($Callsign, 0, $Letters);
|
||||
while (($j < count($this->Flagarray)) && (!$FoundFlag)) {
|
||||
|
||||
$z = 0;
|
||||
while (($z < count($this->Flagarray[$j]['DXCC'])) && (!$FoundFlag)) {
|
||||
if (trim($Prefix) == trim($this->Flagarray[$j]['DXCC'][$z])) {
|
||||
$Image = $this->Flagarray[$j]['ISO'];
|
||||
$Name = $this->Flagarray[$j]['Country'];
|
||||
$FoundFlag = true;
|
||||
while ($Letters >= 2) {
|
||||
$Prefix = substr(trim($Callsign), 0, $Letters);
|
||||
if (isset($this->Flagarray_DXCC[$Prefix])) {
|
||||
$Image = $this->Flagarray[ $this->Flagarray_DXCC[$Prefix] ]['ISO'];
|
||||
$Name = $this->Flagarray[ $this->Flagarray_DXCC[$Prefix] ]['Country'];
|
||||
break;
|
||||
}
|
||||
$z++;
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
$Letters--;
|
||||
}
|
||||
return array(strtolower($Image), $Name);
|
||||
|
|
|
|||
|
|
@ -13,54 +13,73 @@ ShowLast3ByteOfIP
|
|||
$Service = array();
|
||||
$CallingHome = array();
|
||||
$PageOptions = array();
|
||||
$VNStat = array();
|
||||
|
||||
$PageOptions['ContactEmail'] = 'your_email'; // Support E-Mail address
|
||||
$PageOptions['ContactEmail'] = 'your_email'; // Support E-Mail address
|
||||
|
||||
$PageOptions['DashboardVersion'] = '2.3.7'; // Dashboard Version
|
||||
$PageOptions['DashboardVersion'] = '2.4.2'; // Dashboard Version
|
||||
|
||||
$PageOptions['PageRefreshActive'] = true; // Activate automatic refresh
|
||||
$PageOptions['PageRefreshDelay'] = '10000'; // Page refresh time in miliseconds
|
||||
$PageOptions['PageRefreshActive'] = true; // Activate automatic refresh
|
||||
$PageOptions['PageRefreshDelay'] = '10000'; // Page refresh time in miliseconds
|
||||
|
||||
$PageOptions['NumberOfModules'] = 10; // Number of Modules enabled on reflector
|
||||
|
||||
$PageOptions['RepeatersPage'] = array();
|
||||
$PageOptions['RepeatersPage']['LimitTo'] = 99; // Number of Repeaters to show
|
||||
$PageOptions['RepeatersPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['RepeatersPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
|
||||
$PageOptions['RepeatersPage']['LimitTo'] = 99; // Number of Repeaters to show
|
||||
$PageOptions['RepeatersPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['RepeatersPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
|
||||
$PageOptions['PeerPage'] = array();
|
||||
$PageOptions['PeerPage']['LimitTo'] = 99; // Number of peers to show
|
||||
$PageOptions['PeerPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['PeerPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
$PageOptions['PeerPage']['LimitTo'] = 99; // Number of peers to show
|
||||
$PageOptions['PeerPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['PeerPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
|
||||
$PageOptions['LastHeardPage']['LimitTo'] = 39; // Number of stations to show
|
||||
$PageOptions['LastHeardPage']['LimitTo'] = 39; // Number of stations to show
|
||||
|
||||
$PageOptions['ModuleNames'] = array(); // Module nomination
|
||||
$PageOptions['ModuleNames'] = array(); // Module nomination
|
||||
$PageOptions['ModuleNames']['A'] = 'Int.';
|
||||
$PageOptions['ModuleNames']['B'] = 'Regional';
|
||||
$PageOptions['ModuleNames']['C'] = 'National';
|
||||
$PageOptions['ModuleNames']['D'] = '';
|
||||
|
||||
$PageOptions['MetaDescription'] = 'XLX is a D-Star Reflector System for Ham Radio Operators.'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaKeywords'] = 'Ham Radio, D-Star, XReflector, XLX, XRF, DCS, REF, '; // Meta Tag Values, usefull forSearch Engine
|
||||
$PageOptions['MetaAuthor'] = 'LX1IQ'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRevisit'] = 'After 30 Days'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRobots'] = 'index,follow'; // Meta Tag Values, usefull for Search Engine
|
||||
|
||||
$PageOptions['MetaDescription'] = 'XLX is a D-Star Reflector System for Ham Radio Operators.'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaKeywords'] = 'Ham Radio, D-Star, XReflector, XLX, XRF, DCS, REF, '; // Meta Tag Values, usefull forSearch Engine
|
||||
$PageOptions['MetaAuthor'] = 'LX1IQ'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRevisit'] = 'After 30 Days'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRobots'] = 'index,follow'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['UserPage']['ShowFilter'] = true; // Show Filter on Users page
|
||||
$PageOptions['Traffic']['Show'] = false; // Enable vnstat traffic statistics
|
||||
$PageOptions['IRCDDB']['Show'] = true; // Show liveircddb, set it to false if you are running your db in https
|
||||
|
||||
$PageOptions['UserPage']['ShowFilter'] = true; // Show Filter on Users page
|
||||
$PageOptions['CustomTXT'] = ''; // custom text in your header
|
||||
|
||||
$Service['PIDFile'] = '/var/log/xlxd.pid';
|
||||
$Service['XMLFile'] = '/var/log/xlxd.xml';
|
||||
|
||||
$CallingHome['Active'] = false; // xlx phone home, true or false
|
||||
$CallingHome['MyDashBoardURL'] = 'http://your_dashboard'; // dashboard url
|
||||
$CallingHome['ServerURL'] = 'http://xlxapi.rlx.lu/api.php'; // database server, do not change !!!!
|
||||
$CallingHome['PushDelay'] = 600; // push delay in seconds
|
||||
$CallingHome['Country'] = "your_country"; // Country
|
||||
$CallingHome['Comment'] = "your_comment"; // Comment. Max 100 character
|
||||
$CallingHome['HashFile'] = "/tmp/callinghome.php"; // Make sure the apache user has read and write permissions in this folder.
|
||||
$CallingHome['OverrideIPAddress'] = ""; // Insert your IP address here. Leave blank for autodetection. No need to enter a fake address.
|
||||
$CallingHome['InterlinkFile'] = "/xlxd/xlxd.interlink"; // Path to interlink file
|
||||
$CallingHome['Active'] = false; // xlx phone home, true or false
|
||||
$CallingHome['MyDashBoardURL'] = 'http://your_dashboard'; // dashboard url
|
||||
$CallingHome['ServerURL'] = 'http://xlxapi.rlx.lu/api.php'; // database server, do not change !!!!
|
||||
$CallingHome['PushDelay'] = 600; // push delay in seconds
|
||||
$CallingHome['Country'] = "your_country"; // Country
|
||||
$CallingHome['Comment'] = "your_comment"; // Comment. Max 100 character
|
||||
$CallingHome['HashFile'] = "/tmp/callinghome.php"; // Make sure the apache user has read and write permissions in this folder.
|
||||
$CallingHome['LastCallHomefile'] = "/tmp/lastcallhome.php"; // lastcallhome.php can remain in the tmp folder
|
||||
$CallingHome['OverrideIPAddress'] = ""; // Insert your IP address here. Leave blank for autodetection. No need to enter a fake address.
|
||||
$CallingHome['InterlinkFile'] = "/xlxd/xlxd.interlink"; // Path to interlink file
|
||||
|
||||
$VNStat['Interfaces'] = array();
|
||||
$VNStat['Interfaces'][0]['Name'] = 'eth0';
|
||||
$VNStat['Interfaces'][0]['Address'] = 'eth0';
|
||||
$VNStat['Binary'] = '/usr/bin/vnstat';
|
||||
|
||||
/*
|
||||
include an extra config file for people who dont like to mess with shipped config.ing.php
|
||||
this makes updating dashboard from git a little bit easier
|
||||
*/
|
||||
|
||||
if (file_exists("../config.inc.php")) {
|
||||
include ("../config.inc.php");
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ Andorra;AD;C3
|
|||
Angola;AO;D2-D3
|
||||
Anguilla;AI;VP2E
|
||||
Annobon Island;GQ;3C0
|
||||
Antarctica;AQ;CE9-KC4
|
||||
Antarctica;AQ;CE9-KC4A-KC4U
|
||||
Antigua and Barbuda;AG;V2
|
||||
Argentina;AR;LO-LP-LQ-LR-LS-LT-LU-LV-LW
|
||||
Armenia;AM;EK
|
||||
Aruba;AW;P4
|
||||
Ascension Island;SH;ZD8
|
||||
Asiatic Russia;RU;UA0-UA8-UA9-UB0-UB8-UB9-UC0-UC8-UC9-UD0-UD8-UD9-UE0-UE8-UE9-UF0-UF8-UF9-UG0-UG8-UG9-UH0-UH8-UH9-UI0-UI8-UI9-RA0-RA8-RA9-RB0-RB8-RB9-RC0-RC8-RC9-RD0-RD8-RD9-RE0-RE8-RE9-RF0-RF8-RF9-RG0-RG8-RG9-RH0-RH8-RH9-RI0-RI8-RI9-RJ0-RJ8-RJ9-RK0-RK8-RK9-RL0-RL8-RL9-RM0-RM8-RM9-RN0-RN8-RN9-RO0-RO8-RO9-RP0-RP8-RP9-RQ0-RQ8-RQ9-RR0-RR8-RR9-RS0-RS8-RS9-RT0-RT8-RT9-RU0-RU8-RU9-RV0-RV8-RV9-RW0-RW8-RW9-RX0-RX8-RX9-RY0-RY8-RY9-RZ0-RZ8-RZ9
|
||||
Asiatic Russia;RU;UA0-UA8-UA9-UB0-UB8-UB9-UC0-UC8-UC9-UD0-UD8-UD9-UE0-UE8-UE9-UF0-UF8-UF9-UG0-UG8-UG9-UH0-UH8-UH9-UI0-UI8-UI9-RA0-RA8-RA9-RB0-RB8-RB9-RC0-RC8-RC9-RD0-RD8-RD9-RE0-RE8-RE9-RF0-RF8-RF9-RG0-RG8-RG9-RH0-RH8-RH9-RI0-RI8-RI9-RJ0-RJ8-RJ9-RK0-RK8-RK9-RL0-RL8-RL9-RM0-RM8-RM9-RN0-RN8-RN9-RO0-RO8-RO9-RP0-RP8-RP9-RQ0-RQ8-RQ9-RR0-RR8-RR9-RS0-RS8-RS9-RT0-RT8-RT9-RU0-RU8-RU9-RV0-RV8-RV9-RW0-RW8-RW9-RX0-RX8-RX9-RY0-RY8-RY9-RZ0-RZ8-RZ9-R8-R9
|
||||
Australia;AU;VK-AX
|
||||
Austria;AT;OE
|
||||
Azerbaijan;AZ;4J-4K
|
||||
|
|
@ -57,7 +57,7 @@ Ceuta & Melilla;ES;EA9-EB9-EC9-ED9-EE9-EF9-EG9-EH9
|
|||
Chad;TD;TT
|
||||
Chagos Islands;;VQ9
|
||||
Chatham Islands;NZ;ZL7
|
||||
Chile;CL;CA-CB-CC-CD-CE
|
||||
Chile;CL;CA-CB-CC-CD-CE-XQ-XR
|
||||
China;CN;BA-BB-BC-BD-BE-BF-BG-BH-BI-BJ-BK-BL-BN-BP-BQ-BR-BS-BT-BY-BZ
|
||||
Christmas Island;CX;VK9X
|
||||
Cocos Island;;TI9
|
||||
|
|
@ -82,18 +82,18 @@ Djibouti;DJ;J2
|
|||
Dodecanese;GR;SV5-J45
|
||||
Dominica;DM;J7
|
||||
Dominican Republic;DO;HI
|
||||
East Malaysia;MY;9M6-9M8
|
||||
East Malaysia;MY;9M6-9M8-9W6-9W8
|
||||
Easter Island;CL;CE0
|
||||
Eastern Kiribati (Line Island);KI;T32
|
||||
Ecuador;EC;HC-HD
|
||||
Egypt;EG;SU
|
||||
El Salvador;SV;YS-HU
|
||||
England;GB;2E-M0-M1-M2-M3-M4-M5-M6-M7-M8-M9-MB-MM-G0-G1-G2-G3-G4-G5-G6-G7-G8-G9-GB-GX
|
||||
England;EN;2E-M0-M1-M2-M3-M4-M5-M6-M7-M8-M9-MB-MX-G0-G1-G2-G3-G4-G5-G6-G7-G8-G9-GB-GX
|
||||
Equatorial Guinea;GQ;3C
|
||||
Eritrea;ER;E3
|
||||
Estonia;EE;ES
|
||||
Ethiopia;ET;ET
|
||||
European Russia;RU;UA1-UA3-UA4-UA5-UA6-UA7-UB1-UB2-UB3-UB4-UB5-UB6-UB7-UC1-UC2-UC3-UC4-UC5-UC6-UC7-UD1-UD2-UD3-UD4-UD5-UD6-UD7-UE1-UE2-UE3-UE4-UE5-UE6-UE7-UF1-UF2-UF3-UF4-UF5-UF6-UF7-UG1-UG2-UG3-UG4-UG5-UG6-UG7-UH1-UH2-UH3-UH4-UH5-UH6-UH7-UI1-UI2-UI3-UI4-UI5-UI6-UI7-RA1-RA3-RA4-RA5-RA6-RA7-RB1-RB2-RB3-RB4-RB5-RB6-RB7-RC1-RC2-RC3-RC4-RC5-RC6-RC7-RD1-RD2-RD3-RD4-RD5-RD6-RD7-RE1-RE2-RE3-RE4-RE5-RE6-RE7-RF1-RF2-RF3-RF4-RF5-RF6-RF7-RG1-RG2-RG3-RG4-RG5-RG6-RG7-RH1-RH2-RH3-RH4-RH5-RH6-RH7-RI1-RI2-RI3-RI4-RI5-RI6-RI7-RJ1-RJ2-RJ3-RJ4-RJ5-RJ6-RJ7-RK1-RK2-RK3-RK4-RK5-RK6-RK7-RL1-RL2-RL3-RL4-RL5-RL6-RL7-RM1-RM2-RM3-RM4-RM5-RM6-RM7-RN1-RN2-RN3-RN4-RN5-RN6-RN7-RO1-RO2-RO3-RO4-RO5-RO6-RO7-RP1-RP2-RP3-RP4-RP5-RP6-RP7-RQ1-RQ2-RQ3-RQ4-RQ5-RQ6-RQ7-RR1-RR2-RR3-RR4-RR5-RR6-RR7-RS1-RS2-RS3-RS4-RS5-RS6-RS7-RT1-RT2-RT3-RT4-RT5-RT6-RT7-RU1-RU2-RU3-RU4-RU5-RU6-RU7-RV1-RV2-RV3-RV4-RV5-RV6-RV7-RW1-RW2-RW3-RW4-RW5-RW6-RW7-RX1-RX2-RX3-RX4-RX5-RX6-RX7-RY1-RY2-RY3-RY4-RY5-RY6-RY7-RZ1-RZ2-RZ3-RZ4-RZ5-RZ6-RZ7
|
||||
European Russia;RU;UA1-UA3-UA4-UA5-UA6-UA7-UB1-UB2-UB3-UB4-UB5-UB6-UB7-UC1-UC2-UC3-UC4-UC5-UC6-UC7-UD1-UD2-UD3-UD4-UD5-UD6-UD7-UE1-UE2-UE3-UE4-UE5-UE6-UE7-UF1-UF2-UF3-UF4-UF5-UF6-UF7-UG1-UG2-UG3-UG4-UG5-UG6-UG7-UH1-UH2-UH3-UH4-UH5-UH6-UH7-UI1-UI2-UI3-UI4-UI5-UI6-UI7-RA1-RA3-RA4-RA5-RA6-RA7-RB1-RB2-RB3-RB4-RB5-RB6-RB7-RC1-RC2-RC3-RC4-RC5-RC6-RC7-RD1-RD2-RD3-RD4-RD5-RD6-RD7-RE1-RE2-RE3-RE4-RE5-RE6-RE7-RF1-RF2-RF3-RF4-RF5-RF6-RF7-RG1-RG2-RG3-RG4-RG5-RG6-RG7-RH1-RH2-RH3-RH4-RH5-RH6-RH7-RI1-RI2-RI3-RI4-RI5-RI6-RI7-RJ1-RJ2-RJ3-RJ4-RJ5-RJ6-RJ7-RK1-RK2-RK3-RK4-RK5-RK6-RK7-RL1-RL2-RL3-RL4-RL5-RL6-RL7-RM1-RM2-RM3-RM4-RM5-RM6-RM7-RN1-RN2-RN3-RN4-RN5-RN6-RN7-RO1-RO2-RO3-RO4-RO5-RO6-RO7-RP1-RP2-RP3-RP4-RP5-RP6-RP7-RQ1-RQ2-RQ3-RQ4-RQ5-RQ6-RQ7-RR1-RR2-RR3-RR4-RR5-RR6-RR7-RS1-RS2-RS3-RS4-RS5-RS6-RS7-RT1-RT2-RT3-RT4-RT5-RT6-RT7-RU1-RU2-RU3-RU4-RU5-RU6-RU7-RV1-RV2-RV3-RV4-RV5-RV6-RV7-RW1-RW2-RW3-RW4-RW5-RW6-RW7-RX1-RX2-RX3-RX4-RX5-RX6-RX7-RY1-RY2-RY3-RY4-RY5-RY6-RY7-RZ1-RZ2-RZ3-RZ4-RZ5-RZ6-RZ7-R1-R2-R3-R4-R5-R6-R7
|
||||
Falkland Islands (Malvinas);FK;VP8
|
||||
Faroe Islands;FO;OY
|
||||
Fiji;FJ;3D2
|
||||
|
|
@ -117,7 +117,7 @@ Guadeloupe;GP;FG
|
|||
Guam;GU;KH2
|
||||
Guantanamo Bay;US;KG4
|
||||
Guatemala;GT;TG-TD
|
||||
Guernsey;GG;GU-GP
|
||||
Guernsey;GG;2U-MU-MP-GU-GP
|
||||
Guinea;GN;3X
|
||||
Guinea-Bissau;GW;J5
|
||||
Guyana;GY;8R
|
||||
|
|
@ -134,13 +134,13 @@ Indonesia;ID;YB-YC-YD-YE-YF-YG-YH
|
|||
Iran Islamic Republic of;IR;EP-EQ
|
||||
Iraq;IQ;YI
|
||||
Ireland;IE;EI-EJ
|
||||
Isle of Man;IM;GD-GT
|
||||
Isle of Man;IM;2D-MD-MT-GD-GT
|
||||
Israel;IL;4X-4Z
|
||||
Italy;IT;I0-I1-I2-I3-I4-I5-I6-I7-I8-I9-IK-IN-IQ-IR-IS-IT-IU-IV-IW-IZ
|
||||
Jamaica;JM;6Y
|
||||
Jan Mayen;NO;JX
|
||||
Japan;JP;JA-JB-JC-JD-JE-JF-JG-JH-JI-JJ-JK-JL-JM-JN-JO-JP-JQ-JR-JS-7J-7K-7L-7M-7N
|
||||
Jersey;JE;GJ-GH
|
||||
Japan;JP;JA-JB-JC-JD-JE-JF-JG-JH-JI-JJ-JK-JL-JM-JN-JO-JP-JQ-JR-JS-7J-7K-7L-7M-7N-8J-8N
|
||||
Jersey;JE;2J-MJ-MH-GJ-GH
|
||||
Johnston Island;US;KH3
|
||||
Jordan;JO;JY
|
||||
Kaliningrad;RU;UA2-RA2
|
||||
|
|
@ -148,7 +148,7 @@ Kazakhstan;KZ;UN-UO-UP-UQ
|
|||
Kenya;KE;5Y-5Z
|
||||
Kermadec Islands;NZ;ZL8
|
||||
Korea Democratic People's Republic of;KP;P5
|
||||
Korea Republic of;KR;HL-6K-6L-6M-6N
|
||||
Korea Republic of;KR;HL-6K-6L-6M-6N-DS
|
||||
Kure Island;US;KH7K
|
||||
Kuwait;KW;9K
|
||||
Kyrgyzstan;KG;EX
|
||||
|
|
@ -203,7 +203,7 @@ Niger;NE;5U
|
|||
Nigeria;NG;5N
|
||||
Niue;NU;ZK2
|
||||
Norfolk Island;NF;VK9N
|
||||
Northern Ireland;NIE;GI-GN
|
||||
Northern Ireland;NIE;2I-MI-MN-GI-GN
|
||||
Northern Mariana Islands;MP;KH0
|
||||
Norway;NO;LA-LB-LC-LD-LE-LF-LG-LH-LI-LJ-LK-LL-LM-LN
|
||||
Oman;OM;A4-YP-YQ-YR
|
||||
|
|
@ -218,7 +218,7 @@ Peru;PE;OA-OB-OC
|
|||
Philippines;PH;DU-DV-DW-DX-DY-DZ
|
||||
Pitcairn;PN;VP6
|
||||
Poland;PL;3Z6-SN-SO-SP-SQ-SR
|
||||
Portugal;PT;CQ0-CQ1-CQ2-CQ3-CQ7-CQ8-CR1-CR2-CR3-CR5-CR6-CR7-CR8-CR9-CS2-CS3-CS4-CS5-CS7-CS8-CT1-CT2-CT3-CT4-CT5-CT8-CT9-CU0-CU1-CU2-CU3-CU4-CU5-CU6-CU7-CU8-CU
|
||||
Portugal;PT;CQ0-CQ1-CQ2-CQ3-CQ7-CQ8-CR1-CR2-CR3-CR5-CR6-CR7-CR8-CR9-CS2-CS3-CS4-CS5-CS7-CS8-CT1-CT2-CT3-CT4-CT5-CT6-CT7-CT8-CT9-CU0-CU1-CU2-CU3-CU4-CU5-CU6-CU7-CU8-CU
|
||||
Pratas Islands;;BV9P
|
||||
Prince Edward & Marion Islands;ZA;ZS8
|
||||
Puerto Rico;PR;KP3-KP4
|
||||
|
|
@ -242,7 +242,7 @@ Sao Tome and Principe;ST;S9
|
|||
Sardinia;IT;IS0-IM0
|
||||
Saudi Arabia;SA;HZ
|
||||
Scarborough Reef;;BS7
|
||||
Scotland;SH;GM-GS-2M0
|
||||
Scotland;SH;2M-MM-MS-GM-GS
|
||||
Senegal;SN;6V-6W
|
||||
Serbia;RS;YT-YU
|
||||
Seychelles;SC;S7
|
||||
|
|
@ -297,9 +297,9 @@ Viet Nam;VN;3W-XV
|
|||
Virgin Islands British;VG;VP2V
|
||||
Virgin Islands U.S.;VI;KP2
|
||||
Wake Island;US;KH9
|
||||
Wales;WL;2W-GC-GW-MW
|
||||
Wales;WL;2W-MW-MC-GW-GC
|
||||
Wallis and Futuna;WF;FW
|
||||
West Malaysia;MY;9M2-9M4
|
||||
West Malaysia;MY;9M2-9M4-9W2-9W4
|
||||
Western Kiribati (Gilbert Island);KI;T30
|
||||
Western Sahara;EH;S0
|
||||
Willis Island;AU;VK9W
|
||||
|
|
|
|||
|
|
|
@ -52,7 +52,6 @@ function FormatSeconds($seconds) {
|
|||
|
||||
function CreateCode ($laenge) {
|
||||
$zeichen = "1234567890abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNAOPQRSTUVWYXZ";
|
||||
mt_srand( (double) microtime() * 1000000);
|
||||
$out = "";
|
||||
for ($i=1;$i<=$laenge;$i++){
|
||||
$out .= $zeichen[mt_rand(0,(strlen($zeichen)-1))];
|
||||
|
|
@ -60,4 +59,97 @@ function CreateCode ($laenge) {
|
|||
return $out;
|
||||
}
|
||||
|
||||
?>
|
||||
function VNStatLocalize($str) {
|
||||
global $L;
|
||||
if (isset($L[$str])) {
|
||||
return $L[$str];
|
||||
}
|
||||
else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
function VNStatGetData($iface, $vnstat_bin) {
|
||||
$vnstat_data = array();
|
||||
|
||||
$fd = @popen("$vnstat_bin --dumpdb -i $iface", "r");
|
||||
if (is_resource($fd)) {
|
||||
$buffer = '';
|
||||
while (!feof($fd)) {
|
||||
$buffer .= fgets($fd);
|
||||
}
|
||||
$vnstat_data = explode("\n", $buffer);
|
||||
pclose($fd);
|
||||
}
|
||||
|
||||
$day = array();
|
||||
$hour = array();
|
||||
$month = array();
|
||||
$top = array();
|
||||
|
||||
if (isset($vnstat_data[0]) && strpos($vnstat_data[0], 'Error') !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($vnstat_data as $line) {
|
||||
$d = explode(';', trim($line));
|
||||
if ($d[0] == 'd') {
|
||||
$day[$d[1]]['time'] = $d[2];
|
||||
$day[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$day[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$day[$d[1]]['act'] = $d[7];
|
||||
$day[$d[1]]['rx2'] = $d[5];
|
||||
$day[$d[1]]['tx2'] = $d[6];
|
||||
}
|
||||
else if ($d[0] == 'm') {
|
||||
$month[$d[1]]['time'] = $d[2];
|
||||
$month[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$month[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$month[$d[1]]['act'] = $d[7];
|
||||
$month[$d[1]]['rx2'] = $d[5];
|
||||
$month[$d[1]]['tx2'] = $d[6];
|
||||
}
|
||||
else if ($d[0] == 'h') {
|
||||
$hour[$d[1]]['time'] = $d[2];
|
||||
$hour[$d[1]]['rx'] = $d[3];
|
||||
$hour[$d[1]]['tx'] = $d[4];
|
||||
$hour[$d[1]]['act'] = 1;
|
||||
}
|
||||
else if ($d[0] == 't') {
|
||||
$top[$d[1]]['time'] = $d[2];
|
||||
$top[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$top[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$top[$d[1]]['act'] = $d[7];
|
||||
}
|
||||
else {
|
||||
$summary[$d[0]] = isset($d[1]) ? $d[1] : '';
|
||||
}
|
||||
}
|
||||
|
||||
rsort($day);
|
||||
rsort($month);
|
||||
rsort($hour);
|
||||
|
||||
return array($day, $month, $hour, $day, $month, $top, $summary);
|
||||
}
|
||||
|
||||
|
||||
function kbytes_to_string($kb) {
|
||||
$byte_notation = null;
|
||||
$units = array('TB','GB','MB','KB');
|
||||
$scale = 1024*1024*1024;
|
||||
$ui = 0;
|
||||
$custom_size = isset($byte_notation) && in_array($byte_notation, $units);
|
||||
|
||||
while ((($kb < $scale) && ($scale > 1)) || $custom_size) {
|
||||
$ui++;
|
||||
$scale = $scale / 1024;
|
||||
if ($custom_size && $units[$ui] == $byte_notation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sprintf("%0.2f %s", ($kb/$scale),$units[$ui]);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
|
|
|||
51
dashboard/pgs/modules.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<table class="listingtable">
|
||||
<tr>
|
||||
<th width="80" rowspan="2">Module</th>
|
||||
<th width="130" rowspan="2">Name</th>
|
||||
<th width="65" rowspan="2">Users</th>
|
||||
<th colspan="2">DPlus</th>
|
||||
<th colspan="2">DExtra</th>
|
||||
<th colspan="2">DCS</th>
|
||||
<th width="65" rowspan="2">DMR</th>
|
||||
<th width="65" rowspan="2">YSF<br />DG-ID</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
$ReflectorNumber = substr($Reflector->GetReflectorName(), 3, 3);
|
||||
$NumberOfModules = isset($PageOptions['NumberOfModules']) ? min(max($PageOptions['NumberOfModules'],0),26) : 26;
|
||||
|
||||
$odd = "";
|
||||
|
||||
for ($i = 1; $i <= $NumberOfModules; $i++) {
|
||||
|
||||
$module = chr(ord('A')+($i-1));
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'. $module .'</td>
|
||||
<td align="center">'. (empty($PageOptions['ModuleNames'][$module]) ? '-' : $PageOptions['ModuleNames'][$module]) .'</td>
|
||||
<td align="center">'. count($Reflector->GetNodesInModulesByID($module)) .'</td>
|
||||
<td align="center">'. 'REF' . $ReflectorNumber . $module . 'L' .'</td>
|
||||
<td align="center">'. (is_numeric($ReflectorNumber) ? '*' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. 'XRF' . $ReflectorNumber . $module . 'L' .'</td>
|
||||
<td align="center">'. (is_numeric($ReflectorNumber) ? 'B' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. 'DCS' . $ReflectorNumber . $module . 'L' .'</td>
|
||||
<td align="center">'. (is_numeric($ReflectorNumber) ? 'D' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. (4000+$i) .'</td>
|
||||
<td align="center">'. (9+$i) .'</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
|
|
@ -43,7 +43,7 @@ for ($i=0;$i<count($Reflectors);$i++) {
|
|||
<td align="center">'.($i+1).'</td>
|
||||
<td><a href="'.$DASHBOARDURL.'" target="_blank" class="listinglink" title="Visit the Dashboard of '.$NAME.'">'.$NAME.'</a></td>
|
||||
<td>'.$COUNTRY.'</td>
|
||||
<td align="center" valign="middle"><img src="./img/'; if ($LASTCONTACT<(time()-600)) { echo 'down'; } ELSE { echo 'up'; } echo '.png" height="25" /></td>
|
||||
<td align="center" valign="middle"><img src="./img/'; if ($LASTCONTACT<(time()-1800)) { echo 'down'; } ELSE { echo 'up'; } echo '.png" height="25" /></td>
|
||||
<td>'.$COMMENT.'</td>
|
||||
</tr>';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,110 @@
|
|||
<table class="listingtable">
|
||||
<?php
|
||||
|
||||
if (!isset($_SESSION['FilterCallSign'])) {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['FilterProtocol'])) {
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['FilterModule'])) {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
|
||||
if (isset($_POST['do'])) {
|
||||
if ($_POST['do'] == 'SetFilter') {
|
||||
|
||||
if (isset($_POST['txtSetCallsignFilter'])) {
|
||||
$_POST['txtSetCallsignFilter'] = trim($_POST['txtSetCallsignFilter']);
|
||||
if ($_POST['txtSetCallsignFilter'] == "") {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterCallSign'] = $_POST['txtSetCallsignFilter'];
|
||||
if (strpos($_SESSION['FilterCallSign'], "*") === false) {
|
||||
$_SESSION['FilterCallSign'] = "*".$_SESSION['FilterCallSign']."*";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['txtSetProtocolFilter'])) {
|
||||
$_POST['txtSetProtocolFilter'] = trim($_POST['txtSetProtocolFilter']);
|
||||
if ($_POST['txtSetProtocolFilter'] == "") {
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterProtocol'] = $_POST['txtSetProtocolFilter'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['txtSetModuleFilter'])) {
|
||||
$_POST['txtSetModuleFilter'] = trim($_POST['txtSetModuleFilter']);
|
||||
if ($_POST['txtSetModuleFilter'] == "") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterModule'] = $_POST['txtSetModuleFilter'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['do'])) {
|
||||
if ($_GET['do'] == "resetfilter") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<table class="listingtable"><?php
|
||||
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
echo '
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<table width="100%" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<form name="frmFilterCallSign" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.$_SESSION['FilterCallSign'].'" name="txtSetCallsignFilter" placeholder="Callsign" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>';
|
||||
if (($_SESSION['FilterModule'] != null) || ($_SESSION['FilterCallSign'] != null) || ($_SESSION['FilterProtocol'] != null)) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=repeaters&do=resetfilter" class="smalllink">Disable filters</a></td>';
|
||||
}
|
||||
echo '
|
||||
<td align="right" style="padding-right:3px;">
|
||||
<form name="frmFilterProtocol" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.$_SESSION['FilterProtocol'].'" name="txtSetProtocolFilter" placeholder="Protocol" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>
|
||||
<td align="right" style="padding-right:3px;">
|
||||
<form name="frmFilterModule" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.$_SESSION['FilterModule'].'" name="txtSetModuleFilter" placeholder="Module" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>
|
||||
</table>
|
||||
</th>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th width="25">#</th>
|
||||
<th width="60">Flag</th>
|
||||
|
|
@ -22,61 +128,86 @@ $odd = "";
|
|||
$Reflector->LoadFlags();
|
||||
|
||||
for ($i=0;$i<$Reflector->NodeCount();$i++) {
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'.($i+1).'</td>
|
||||
<td align="center">';
|
||||
list ($Flag, $Name) = $Reflector->GetFlag($Reflector->Nodes[$i]->GetCallSign());
|
||||
if (file_exists("./img/flags/".$Flag.".png")) {
|
||||
echo '<a href="#" class="tip"><img src="./img/flags/'.$Flag.'.png" height="15" alt="'.$Name.'" /><span>'.$Name.'</span></a>';
|
||||
}
|
||||
echo '</td>
|
||||
<td><a href="http://www.aprs.fi/'.$Reflector->Nodes[$i]->GetCallSign();
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") echo '-'.$Reflector->Nodes[$i]->GetSuffix();
|
||||
echo '" class="pl" target="_blank">'.$Reflector->Nodes[$i]->GetCallSign();
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") { echo '-'.$Reflector->Nodes[$i]->GetSuffix(); }
|
||||
echo '</a></td>
|
||||
<td>';
|
||||
if (($Reflector->Nodes[$i]->GetPrefix() == 'REF') || ($Reflector->Nodes[$i]->GetPrefix() == 'XRF')) {
|
||||
switch ($Reflector->Nodes[$i]->GetPrefix()) {
|
||||
case 'REF' : echo 'REF-Link'; break;
|
||||
case 'XRF' : echo 'XRF-Link'; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch ($Reflector->Nodes[$i]->GetSuffix()) {
|
||||
case 'A' : echo '23cm'; break;
|
||||
case 'B' : echo '70cm'; break;
|
||||
case 'C' : echo '2m'; break;
|
||||
case 'D' : echo 'Dongle'; break;
|
||||
case 'G' : echo 'Internet-Gateway'; break;
|
||||
default : echo '';
|
||||
}
|
||||
}
|
||||
echo '</td>
|
||||
<td>'.date("d.m.Y H:i", $Reflector->Nodes[$i]->GetLastHeardTime()).'</td>
|
||||
<td>'.FormatSeconds(time()-$Reflector->Nodes[$i]->GetConnectTime()).' s</td>
|
||||
<td>'.$Reflector->Nodes[$i]->GetProtocol().'</td>
|
||||
<td align="center">'.$Reflector->Nodes[$i]->GetLinkedModule().'</td>';
|
||||
if ($PageOptions['RepeatersPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<td>';
|
||||
$Bytes = explode(".", $Reflector->Nodes[$i]->GetIP());
|
||||
if ($Bytes !== false && count($Bytes) == 4) {
|
||||
switch ($PageOptions['RepeatersPage']['IPModus']) {
|
||||
case 'ShowLast1ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[3]; break;
|
||||
case 'ShowLast2ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]; break;
|
||||
case 'ShowLast3ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]; break;
|
||||
default : echo $Reflector->Nodes[$i]->GetIP();
|
||||
$ShowThisStation = true;
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
$CS = true;
|
||||
if ($_SESSION['FilterCallSign'] != null) {
|
||||
if (!fnmatch($_SESSION['FilterCallSign'], $Reflector->Nodes[$i]->GetCallSign(), FNM_CASEFOLD)) {
|
||||
$CS = false;
|
||||
}
|
||||
}
|
||||
echo '</td>';
|
||||
$MO = true;
|
||||
if ($_SESSION['FilterModule'] != null) {
|
||||
if (trim(strtolower($_SESSION['FilterModule'])) != strtolower($Reflector->Nodes[$i]->GetLinkedModule())) {
|
||||
$MO = false;
|
||||
}
|
||||
}
|
||||
$PR = true;
|
||||
if ($_SESSION['FilterProtocol'] != null) {
|
||||
if (trim(strtolower($_SESSION['FilterProtocol'])) != strtolower($Reflector->Nodes[$i]->GetProtocol())) {
|
||||
$PR = false;
|
||||
}
|
||||
}
|
||||
|
||||
$ShowThisStation = ($CS && $MO && $PR);
|
||||
}
|
||||
|
||||
if ($ShowThisStation) {
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'.($i+1).'</td>
|
||||
<td align="center">';
|
||||
list ($Flag, $Name) = $Reflector->GetFlag($Reflector->Nodes[$i]->GetCallSign());
|
||||
if (file_exists("./img/flags/".$Flag.".png")) {
|
||||
echo '<a href="#" class="tip"><img src="./img/flags/'.$Flag.'.png" height="15" alt="'.$Name.'" /><span>'.$Name.'</span></a>';
|
||||
}
|
||||
echo '</td>
|
||||
<td><a href="http://www.aprs.fi/'.$Reflector->Nodes[$i]->GetCallSign();
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") echo '-'.$Reflector->Nodes[$i]->GetSuffix();
|
||||
echo '" class="pl" target="_blank">'.$Reflector->Nodes[$i]->GetCallSign();
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") { echo '-'.$Reflector->Nodes[$i]->GetSuffix(); }
|
||||
echo '</a></td>
|
||||
<td>';
|
||||
if (($Reflector->Nodes[$i]->GetPrefix() == 'REF') || ($Reflector->Nodes[$i]->GetPrefix() == 'XRF')) {
|
||||
switch ($Reflector->Nodes[$i]->GetPrefix()) {
|
||||
case 'REF' : echo 'REF-Link'; break;
|
||||
case 'XRF' : echo 'XRF-Link'; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch ($Reflector->Nodes[$i]->GetSuffix()) {
|
||||
case 'A' : echo '23cm'; break;
|
||||
case 'B' : echo '70cm'; break;
|
||||
case 'C' : echo '2m'; break;
|
||||
case 'D' : echo 'Dongle'; break;
|
||||
case 'G' : echo 'Internet-Gateway'; break;
|
||||
default : echo '';
|
||||
}
|
||||
}
|
||||
echo '</td>
|
||||
<td>'.date("d.m.Y H:i", $Reflector->Nodes[$i]->GetLastHeardTime()).'</td>
|
||||
<td>'.FormatSeconds(time()-$Reflector->Nodes[$i]->GetConnectTime()).' s</td>
|
||||
<td>'.$Reflector->Nodes[$i]->GetProtocol().'</td>
|
||||
<td align="center">'.$Reflector->Nodes[$i]->GetLinkedModule().'</td>';
|
||||
if ($PageOptions['RepeatersPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<td>';
|
||||
$Bytes = explode(".", $Reflector->Nodes[$i]->GetIP());
|
||||
if ($Bytes !== false && count($Bytes) == 4) {
|
||||
switch ($PageOptions['RepeatersPage']['IPModus']) {
|
||||
case 'ShowLast1ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[3]; break;
|
||||
case 'ShowLast2ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]; break;
|
||||
case 'ShowLast3ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]; break;
|
||||
default : echo $Reflector->Nodes[$i]->GetIP();
|
||||
}
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
echo '
|
||||
</tr>';
|
||||
}
|
||||
echo '
|
||||
</tr>';
|
||||
if ($i == $PageOptions['RepeatersPage']['LimitTo']) { $i = $Reflector->NodeCount()+1; }
|
||||
}
|
||||
|
||||
|
|
|
|||
102
dashboard/pgs/traffic.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
if (!isset($_GET['iface'])) {
|
||||
if (isset($VNStat['Interfaces'][0]['Address'])) {
|
||||
$_GET['iface'] = $VNStat['Interfaces'][0]['Address'];
|
||||
}
|
||||
else {
|
||||
$_GET['iface'] = "";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$f = false;
|
||||
$i = 0;
|
||||
while ($i < count($VNStat['Interfaces']) && (!$f)) {
|
||||
if ($_GET['iface'] == $VNStat['Interfaces'][$i]['Address']) {
|
||||
$f = true;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (!$f) {
|
||||
$_GET['iface'] = "";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<table class="listingtable">
|
||||
<tr>
|
||||
<th>Network interfaces</th>
|
||||
<th>Statistics</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#F1FAFA" align="left" valign="top" style="padding-left:5px;"><?php
|
||||
|
||||
for ($i=0;$i<count($VNStat['Interfaces']);$i++) {
|
||||
echo '<a href="./index.php?show=traffic&iface='.$VNStat['Interfaces'][$i]['Address'].'" class="listinglink">'.$VNStat['Interfaces'][$i]['Name'].'</a>';
|
||||
if ($i < count($VNStat['Interfaces'])) {
|
||||
echo '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
?></td>
|
||||
<td bgcolor="#FFFFFF"><?php
|
||||
|
||||
$Data = VNStatGetData($_GET['iface'], $VNStat['Binary']);
|
||||
|
||||
echo '
|
||||
<table style="margin:10px;">
|
||||
<tr>
|
||||
<td>Day</td>
|
||||
<td>RX</td>
|
||||
<td>TX</td>
|
||||
<td>Avg Rx</td>
|
||||
<td>Avg TX</td>
|
||||
</tr>';
|
||||
|
||||
for ($i=0;$i<count($Data[0]);$i++) {
|
||||
if ($Data[0][$i]['time'] > 0) {
|
||||
echo '
|
||||
<tr>
|
||||
<td width="100">'.date("d.m.Y", $Data[0][$i]['time']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['rx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['tx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['rx2']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['tx2']).'</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
|
||||
|
||||
|
||||
|
||||
echo '
|
||||
<table style="margin:10px;">
|
||||
<tr>
|
||||
<td>Month</td>
|
||||
<td>RX</td>
|
||||
<td>TX</td>
|
||||
<td>Avg Rx</td>
|
||||
<td>Avg TX</td>
|
||||
</tr>';
|
||||
|
||||
for ($i=0;$i<count($Data[1]);$i++) {
|
||||
if ($Data[1][$i]['time'] > 0) {
|
||||
echo '
|
||||
<tr>
|
||||
<td width="100">'.date("F", $Data[1][$i]['time']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['rx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['tx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['rx2']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['tx2']).'</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
BIN
dashboard2/img/flags/aq.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
dashboard2/img/flags/en.png
Normal file
|
After Width: | Height: | Size: 233 B |
BIN
dashboard2/img/tx.gif
Normal file
|
After Width: | Height: | Size: 2.6 KiB |