TETRA (1) uplink (päätelaitteesta tukiasemaan) kanavien digitaalista aikajakoista (TDMA-kanavointi) radioliikennettä voi havaita tavallisella radioskannerilla, esim. Uniden UBC-3300XLT skannerilla (2). Uplink kanavien taajuudet kannattaa tallentaa muistipaikkoihin ja lähetelajiksi laittaa WFM tai AM. Häiriöiden vähentämiseksi kannattaa käyttää TETRA bandille tarkoitettua antennia (3). Kaupunkialueilla skannaus voi tökkiä häiriöihin vähän väliä vaikka olisi bandille viritetty antenni.
TETRA uplink lähete kuuluu skannerin kaiuttimesta "napsutus" äänenä.
Signaalien havainnoinnissa voi käyttää myös softaa ja UBC-3300XLT:n tietokoneohjaus (COM, sarjaportti) protokollan SG komentoa (5). SG (Signal stength) komennolla saadaan 3300 skannerista signaalinvoimakkuustieto tarkemmalla tasolla kuin skannerin näytöllä näkyvistä S-mittarin palkeista. Artikkelin lopussa oleva (5. kuvaan liittyvä) koodi on kirjoitettu Borland C++ Builderillä (Windows) ja se käyttää ilmaista TComPort sarjaportti komponenttia (4). SG komennon lisäksi signaalin tasosta saa tietoa lähettämällä skanneriin WI (Windows voltage level) komennon. SG ja WI palauttavat arvon 0-255 ja ne toimivat ainakin UBC-3300XLT, UBC-780XLT ja UBC-785XLT skannerien tietokoneohjaus protokollassa.
1. http://fi.wikipedia.org/wiki/TETRA
2. http://www.rigpix.com/bearcat/ubc3300xlt.htm
3. http://www.antennaexperts.in/product-detail.asp?id=35
4. http://sourceforge.net/projects/comport/
5.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <exception>
#include <iostream>
#pragma hdrstop
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CPort"
#pragma resource "*.dfm"
TfrmMain *frmMain;
int nCmd = 0;
int nPos = 125;
bool bBA = false;
bool bBEEP = false;
bool bLOG = false;
int nFileHandle = -1;
int nStatFile = -1;
AnsiString sRx("");
int nMin = 999;
int nMax = -1;
int nAMin = 999;
int nAMax = -1;
Cardinal nCount = 0;
Cardinal nACount = 0;
Cardinal nCountSum = 0;
Cardinal nACountSum = 0;
Cardinal *sg_stat;
const int SG_STAT_SIZE = 256;
const char *KModuleName = "TetraMeter3300C";
const char *KModuleDesc = "Tetra (TDMA) signal interceptor for the Uniden Bearcat UBC-3300XLT";
const char *KModuleNote = "";
const char *KVersion = "version 1.05";
const char *KCopyright = "";
const char *KDeveloped = "TetraMeter3300C is developed with Borland C++ Builder Personal version 6.0";
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::ComPortRxChar(TObject *Sender, int Count)
{
AnsiString buf = "";
int nSG;
if (ComPort->ReadStr(buf, Count));
{
sRx.operator +=(buf);
if (sRx.Length() > 13)
{
switch (nCmd)
{
case 2:
{
AnsiString sSG = sRx.SubString(2, 3);
nSG = sSG.ToInt();
sg_stat[nSG] = sg_stat[nSG] + 1;
if (nSG > nPos)
{
nACountSum += nSG;
nACount++;
lbACntVal->Caption = IntToStr(nACount);
lbAAvgVal->Caption = FormatFloat("0.00", nACountSum / nACount);
if (nSG > nAMax) { nAMax = nSG; lbAMaxVal->Caption = sSG; }
if (nSG < nAMin) { nAMin = nSG; lbAMinVal->Caption = sSG; }
lbAlert->Caption = sSG.operator +("\t").operator +
(sRx.SubString(7, 4).operator +(".").operator +(sRx.SubString(11, 4))).operator +("\t").operator +(Now());
lbLastAlert->Caption = lbAlert->Caption;
if ((bBA) && (!bBEEP))
{
MessageBeep(0xFFFFFFFF);
bBEEP = true;
}
if (bLOG)
{
sRx = lbAlert->Caption +("\r\n");
FileWrite(nFileHandle, sRx.c_str(), sRx.Length());
}
}
else
{
nCount++;
nCountSum += nSG;
lbGAvgVal->Caption = FormatFloat("0.00", nCountSum / nCount);
if (nSG > nMax) { nMax = nSG; lbGMaxVal->Caption = sSG; }
if (nSG < nMin) { nMin = nSG; lbGMinVal->Caption = sSG; }
lbGCntVal->Caption = IntToStr(nCount);
lbAlert->Caption = "";
bBEEP = false;
}
sRx = "";
ComPort->WriteStr("SG\r\n");
break;
}
case 1:
{
stMain->Panels->Items[0]->Text = sRx.SubString(4, 10);
pbStart->Enabled = true;
pbConnect->Enabled = false;
pbStop->Enabled = false;
nCmd = 0;
break;
}
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::itemExitClick(TObject *Sender)
{
frmMain->Close();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
if (ComPort->Connected)
{
ComPort->Close();
}
if (nFileHandle >= 0)
{
FileClose(nFileHandle);
}
if (nStatFile >= 0)
{
FileClose(nStatFile);
}
if (sg_stat != NULL) delete[] sg_stat;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::itemAboutClick(TObject *Sender)
{
AnsiString aboutText;
aboutText.sprintf("%s %s\n%s\n%s\n%s", KModuleName, KVersion, KModuleDesc, KModuleNote, KCopyright);
MessageDlg(aboutText, mtInformation, TMsgDlgButtons() << mbOK, 0);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormShow(TObject *Sender)
{
ComPort->Close();
stMain->Panels->Items[0]->Text = "NO CONNECTION";
stMain->Panels->Items[1]->Text = "";
InitValues();
sg_stat = NULL;
try
{
sg_stat = new Cardinal[SG_STAT_SIZE];
}
catch (std::bad_alloc)
{
sg_stat = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::tbSGChange(TObject *Sender)
{
nPos = tbSG->Position;
lbSG->Caption = IntToStr(tbSG->Position);
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::pbConnectClick(TObject *Sender)
{
ComPort->ShowSetupDialog();
try
{
ComPort->Open();
}
catch (Exception &ex)
{
MessageDlg(ex.Message, mtError, TMsgDlgButtons() << mbOK, 0);
return;
}
nCmd = 1;
sRx = "";
ComPort->WriteStr("SI\r\n");
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::pbStartClick(TObject *Sender)
{
if (FileExists("SG_STATS.TXT"))
nStatFile = FileOpen("SG_STATS.TXT", fmOpenWrite);
else
nStatFile = FileCreate("SG_STATS.TXT");
if (nStatFile >= 0)
stMain->Panels->Items[1]->Text = ExtractFilePath(ParamStr(0)).operator +("SG_STATS.TXT");
if (FileExists("ALERTLOG.TXT"))
nFileHandle = FileOpen("ALERTLOG.TXT", fmOpenWrite);
else
nFileHandle = FileCreate("ALERTLOG.TXT");
if (nFileHandle < 0)
bLOG = false;
else
bLOG = cbLOG->Checked;
pbStart->Enabled = false;
pbStop->Enabled = true;
bBEEP = false;
InitValues();
sRx = "";
nCmd = 2;
ComPort->WriteStr("SG\r\n");
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::cbBAClick(TObject *Sender)
{
bBA = cbBA->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::pbStopClick(TObject *Sender)
{
AnsiString sStatRow;
nCmd = 0;
if (nFileHandle >= 0)
{
FileClose(nFileHandle);
nFileHandle = -1;
}
if (nStatFile >= 0)
{
for (int n = 0; n < SG_STAT_SIZE; n++)
{
sStatRow = IntToStr(n).operator +("\t").operator +(IntToStr(sg_stat[n])).operator +("\r\n");
if (sg_stat[n] > 0) FileWrite(nStatFile, sStatRow.c_str(), sStatRow.Length());
}
sStatRow = "\r\n\r\n";
FileWrite(nStatFile, sStatRow.c_str(), sStatRow.Length());
FileClose(nStatFile);
nStatFile = -1;
}
pbStart->Enabled = true;
pbStop->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::cbLOGClick(TObject *Sender)
{
bLOG = cbLOG->Checked;
}
void TfrmMain::InitValues(void)
{
lbGMinVal->Caption = "";
lbGMaxVal->Caption = "";
lbGCntVal->Caption = "";
lbGAvgVal->Caption = "";
lbAMinVal->Caption = "";
lbAMaxVal->Caption = "";
lbACntVal->Caption = "";
lbAAvgVal->Caption = "";
lbAlert->Caption = "";
lbLastAlert->Caption = "";
nMin = 999;
nMax = -1;
nAMin = 999;
nAMax = -1;
nCount = 0;
nACount = 0;
nCountSum = 0;
nACountSum = 0;
if (sg_stat != NULL)
{
for (int n = 0; n < SG_STAT_SIZE; n++) sg_stat[n] = 0;
}
}
//---------------------------------------------------------------------------
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.