|
|
/*------------------------------------------------------------------------------
|
|
|
-- This file is a part of the LPPMON Software
|
|
|
-- Copyright (C) 2012, Laboratory of Plasma Physics - CNRS
|
|
|
--
|
|
|
-- This program is free software; you can redistribute it and/or modify
|
|
|
-- it under the terms of the GNU General Public License as published by
|
|
|
-- the Free Software Foundation; either version 3 of the License, or
|
|
|
-- (at your option) any later version.
|
|
|
--
|
|
|
-- This program is distributed in the hope that it will be useful,
|
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
-- GNU General Public License for more details.
|
|
|
--
|
|
|
-- You should have received a copy of the GNU General Public License
|
|
|
-- along with this program; if not, write to the Free Software
|
|
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
-------------------------------------------------------------------------------*/
|
|
|
/*-- Author : Paul LEROY
|
|
|
-- Mail : paul.leroy@lpp.polytechnique.fr
|
|
|
----------------------------------------------------------------------------*/
|
|
|
#include "rmapplugin.h"
|
|
|
#include <QHostAddress>
|
|
|
#include <QIODevice>
|
|
|
#include <QApplication>
|
|
|
#include <rmappluginpythonwrapper.h>
|
|
|
#include <PythonQt.h>
|
|
|
#include <QTimer>
|
|
|
|
|
|
rmapplugin::rmapplugin(QWidget *parent)
|
|
|
:lppmonplugin(parent,false)
|
|
|
{
|
|
|
this->UI = new rmapPluginUI();
|
|
|
this->setWindowTitle(tr("RMAP and SPW Communication"));
|
|
|
this->setWidget((QWidget*)this->UI);
|
|
|
|
|
|
timeCode = 0;
|
|
|
time_COARSE = 0;
|
|
|
time_FINE = 0;
|
|
|
currentBridge = selectedBridgeIsUnknown;
|
|
|
|
|
|
//**************
|
|
|
//Python wrapper
|
|
|
this->pyObject = new rmappluginPythonWrapper();
|
|
|
connect(this->pyObject,SIGNAL(ReadSig(uint*,uint,uint)),this,SLOT(Read(uint*,uint,uint)));
|
|
|
connect(this->pyObject,SIGNAL(WriteSig(uint*,uint,uint)),this,SLOT(Write(uint*,uint,uint)));
|
|
|
//**
|
|
|
connect( (rmappluginPythonWrapper*)this->pyObject, SIGNAL( WriteSPWSig(char*,uint,char,char) ),
|
|
|
this, SLOT( WriteSPW(char*,uint,char,char)), Qt::DirectConnection );
|
|
|
//**
|
|
|
connect( (rmappluginPythonWrapper*)this->pyObject, SIGNAL( updateTargetAddress(unsigned char) ),
|
|
|
this, SLOT( setValueTargetAddress(unsigned char)) );
|
|
|
//**
|
|
|
connect( (rmappluginPythonWrapper*)this->pyObject, SIGNAL( updateSourceAddress(unsigned char) ),
|
|
|
this, SLOT( setValueSourceAddress(unsigned char)) );
|
|
|
//**
|
|
|
connect( (rmappluginPythonWrapper*)this->pyObject, SIGNAL(sendMessage(QString)),
|
|
|
this, SLOT(displayOnConsole(QString)) );
|
|
|
//**
|
|
|
connect( (rmappluginPythonWrapper*)this->pyObject, SIGNAL(fetchPacketSig()),
|
|
|
this, SLOT(fetchPacket()), Qt::DirectConnection );
|
|
|
//**************
|
|
|
|
|
|
//**************
|
|
|
// get a smart pointer to the __main__ module of the Python interpreter
|
|
|
PythonQtObjectPtr context = PythonQt::self()->getMainModule();
|
|
|
// add a QObject as variable of name "BUTTON_rmapOpenCommunication" to the namespace of the __main__ module
|
|
|
context.addObject("BUTTON_rmapOpenCommunication", UI->rmapOpenCommunicationButton);
|
|
|
context.addObject("BUTTON_rmapCloseCommunication", UI->rmapCloseCommunicationButton);
|
|
|
context.addObject("BUTTON_selectStarDundee", UI->selectStarDundee_BUTTON);
|
|
|
context.addObject("BUTTON_selectGRESB", UI->selectGRESB_BUTTON);
|
|
|
context.addObject("GRESB_Bridge", UI->gresbBridge);
|
|
|
//**************
|
|
|
|
|
|
connect(UI->rmapOpenCommunicationButton, SIGNAL(clicked()), this, SLOT(openBridge()));
|
|
|
connect(UI->rmapCloseCommunicationButton, SIGNAL(clicked()), this, SLOT(closeBridge()));
|
|
|
|
|
|
// CCSDS
|
|
|
connect(this->UI->sendCCSDSCommandButton, SIGNAL(clicked()), this, SLOT(sendCCSDS()));
|
|
|
connect(this->UI->send_TC_LFR_UPDATE_TIME_Button, SIGNAL(clicked()), this, SLOT(send_TC_LFR_UPDATE_TIME()));
|
|
|
connect(this->UI->reset_TC_LFR_UPDATE_TIME_Button, SIGNAL(clicked()), this, SLOT(reset_TC_LFR_UPDATE_TIME()));
|
|
|
|
|
|
// spectralMAtricesDMASimulator
|
|
|
connect(this->UI->spectralMatricesDMASimulator, SIGNAL(rmapplugginRead(uint*,uint,uint)), this, SLOT(Read(uint*,uint,uint)));
|
|
|
connect(this->UI->spectralMatricesDMASimulator, SIGNAL(rmapplugginWrite(uint*,uint,uint)), this, SLOT(Write(uint*,uint,uint)));
|
|
|
connect(this->UI->spectralMatricesDMASimulator, SIGNAL(sendMessage(QString)), this, SLOT(displayOnConsole(QString)));
|
|
|
|
|
|
// GRESB
|
|
|
connect(this->UI->gresbBridge, SIGNAL(sendMessage(QString)), this, SLOT(displayOnConsole(QString)));
|
|
|
connect(this->UI->gresbBridge, SIGNAL(isOpen(bool)), this, SLOT(activatePlugin(bool)));
|
|
|
connect(this->UI->gresbBridge, SIGNAL(RMAP_write_reply_setText(QString)), this, SLOT(RMAP_write_reply_setText(QString)));
|
|
|
connect(this->UI->gresbBridge, SIGNAL(appendToLog(QString)), this, SLOT(appendToLog(QString)));
|
|
|
connect(this->UI->gresbBridge, SIGNAL(ccsdsPacketAvailable(unsigned char*,uint)),
|
|
|
this, SLOT(processCCSDSPacket(unsigned char*,uint)));
|
|
|
connect(this, SIGNAL(ccsdsPacketIsProcessed()), this->UI->gresbBridge, SLOT(ccsdsPacketIsProcessed()));
|
|
|
connect(this->UI->rmapTargetLogicalAddressSpinBox, SIGNAL(valueChanged(int)),
|
|
|
this->UI->gresbBridge, SLOT(targetHasChanged(int)));
|
|
|
connect(this->UI->rmapSourceLogicalAddressSpinBox, SIGNAL(valueChanged(int)),
|
|
|
this->UI->gresbBridge, SLOT(sourceHasChanged(int)));
|
|
|
connect(this->UI->gresbBridge, SIGNAL(packetStoreNotEmpty()),
|
|
|
this, SLOT(processPacketStore()));
|
|
|
|
|
|
// Star Dundee
|
|
|
connect(this->UI->starDundee, SIGNAL(sendMessage(QString)), this, SLOT(displayOnConsole(QString)));
|
|
|
connect(this->UI->starDundee, SIGNAL(isOpen(bool)), this, SLOT(activatePlugin(bool)));
|
|
|
connect(this->UI->starDundee, SIGNAL(RMAP_write_reply_setText(QString)), this, SLOT(RMAP_write_reply_setText(QString)));
|
|
|
connect(this->UI->starDundee, SIGNAL(appendToLog(QString)), this, SLOT(appendToLog(QString)));
|
|
|
connect(this->UI->starDundee, SIGNAL(ccsdsPacketAvailable(unsigned char*,uint)),
|
|
|
this, SLOT(processCCSDSPacket(unsigned char*,uint)));
|
|
|
connect(this, SIGNAL(ccsdsPacketIsProcessed()), this->UI->starDundee, SLOT(ccsdsPacketIsProcessed()));
|
|
|
connect(this->UI->rmapTargetLogicalAddressSpinBox, SIGNAL(valueChanged(int)),
|
|
|
this->UI->starDundee, SLOT(targetHasChanged(int)));
|
|
|
connect(this->UI->rmapSourceLogicalAddressSpinBox, SIGNAL(valueChanged(int)),
|
|
|
this->UI->starDundee, SLOT(sourceHasChanged(int)));
|
|
|
connect(this->UI->starDundee, SIGNAL(packetStoreNotEmpty()),
|
|
|
this, SLOT(processPacketStore()));
|
|
|
|
|
|
connect(this->UI, SIGNAL(bridgeHasChanged(selectedBridge)), this, SLOT(bridgeHasChanged(selectedBridge)));
|
|
|
connect(this->UI, SIGNAL(bridgeHasChanged(selectedBridge)), this, SLOT(updatePacketStore()));
|
|
|
|
|
|
}
|
|
|
|
|
|
rmapplugin::~rmapplugin()
|
|
|
{
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
if (RMAPSend_SOCKET->isOpen()) RMAPSend_SOCKET->disconnectFromHost();
|
|
|
if (RMAPReceive_SOCKET->isOpen()) RMAPReceive_SOCKET->disconnectFromHost();
|
|
|
if (GRESBStatusQuery_SOCKET->isOpen()) GRESBStatusQuery_SOCKET->disconnectFromHost();
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
unsigned int rmapplugin::Write(unsigned int *Value, unsigned int count, unsigned int address)
|
|
|
{
|
|
|
unsigned int result;
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
result = UI->gresbBridge->Write(Value, count, address);
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
result = UI->starDundee->Write(Value, count, address);
|
|
|
break;
|
|
|
default:
|
|
|
result = 1;
|
|
|
break;
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
unsigned int rmapplugin::Read(unsigned int *Value, unsigned int count, unsigned int address)
|
|
|
{
|
|
|
unsigned int result;
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
result = UI->gresbBridge->Read(Value, count, address);
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
result = UI->starDundee->Read(Value, count, address);
|
|
|
break;
|
|
|
default:
|
|
|
result = 1;
|
|
|
break;
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
////////
|
|
|
// SLOTS
|
|
|
|
|
|
unsigned int rmapplugin::WriteSPW(char *Value, unsigned int count, char targetLogicalAddress, char userApplication) // SLOT
|
|
|
{
|
|
|
unsigned int result;
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
result = UI->gresbBridge->WriteSPW(Value, count, targetLogicalAddress, userApplication);
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
result = UI->starDundee->WriteSPW(Value, count, targetLogicalAddress, userApplication);
|
|
|
break;
|
|
|
default:
|
|
|
result = 1;
|
|
|
break;
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
void rmapplugin::sendCCSDS() // SLOT
|
|
|
{
|
|
|
unsigned int nbBYTES_application_data = 8;
|
|
|
unsigned int count;
|
|
|
char *tab;
|
|
|
unsigned char packetErrorControl1 = 0xaa;
|
|
|
unsigned char packetErrorControl0 = 0xbb;
|
|
|
|
|
|
ccsds_command = new ccsds(1, 0, 0, nbBYTES_application_data+12, 0, 0, 0, 0, 0); // +12 => packet header 6 bytes + data field header 4 bytes + packet error control 2 bytes
|
|
|
/* unsigned char data_field_header,
|
|
|
unsigned char processID,
|
|
|
unsigned int sequence_count,
|
|
|
unsigned int packet_length,
|
|
|
unsigned char acceptance,
|
|
|
unsigned int completion,
|
|
|
unsigned char service_type,
|
|
|
unsigned char service_subtype,
|
|
|
unsigned char sourceID*/
|
|
|
|
|
|
count = nbBYTES_application_data+12; // 12 is the size in bytes of the header
|
|
|
tab = (char*) malloc(count);
|
|
|
tab[0] = ccsds_command->ccsds_header->packetId1;
|
|
|
tab[1] = ccsds_command->ccsds_header->packetId0;
|
|
|
tab[2] = ccsds_command->ccsds_header->packetSequenceControl1;
|
|
|
tab[3] = ccsds_command->ccsds_header->packetSequenceControl0;
|
|
|
tab[4] = ccsds_command->ccsds_header->packetLength1;
|
|
|
tab[5] = ccsds_command->ccsds_header->packetLength0;
|
|
|
tab[6] = ccsds_command->ccsds_header->dataFieldHeader3;
|
|
|
tab[7] = ccsds_command->ccsds_header->dataFieldHeader2;
|
|
|
tab[8] = ccsds_command->ccsds_header->dataFieldHeader1;
|
|
|
tab[9] = ccsds_command->ccsds_header->dataFieldHeader0;
|
|
|
tab[10]=0x00;
|
|
|
tab[11]=0x00;
|
|
|
tab[12]=0x00;
|
|
|
tab[13]=0x00;
|
|
|
tab[14]=0x00;
|
|
|
tab[15]=0x00;
|
|
|
tab[nbBYTES_application_data+10] = packetErrorControl1;
|
|
|
tab[nbBYTES_application_data+11] = packetErrorControl0;
|
|
|
|
|
|
WriteSPW(tab, count, UI->CCSDSTargetLogicalAddressSpinBox->value(), 0x00);
|
|
|
|
|
|
free(tab);
|
|
|
}
|
|
|
|
|
|
void rmapplugin::openBridge()
|
|
|
{
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
this->UI->gresbBridge->Open();
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
this->UI->starDundee->Open();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void rmapplugin::closeBridge()
|
|
|
{
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
this->UI->gresbBridge->Close();
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
this->UI->starDundee->Close();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void rmapplugin::send_TC_LFR_UPDATE_TIME()
|
|
|
{
|
|
|
unsigned int nbBYTES_application_data = 6; // Time at CUC format is on 48 bits / 6 bytes
|
|
|
unsigned int count;
|
|
|
char *tab;
|
|
|
unsigned char packetErrorControl1 = 0xaa;
|
|
|
unsigned char packetErrorControl0 = 0xbb;
|
|
|
|
|
|
ccsds_command = new ccsds(1, 11, 0, nbBYTES_application_data, 1, 1, 9, 129, 0);
|
|
|
/* unsigned char data_field_header,
|
|
|
unsigned char processID,
|
|
|
unsigned int sequence_count,
|
|
|
unsigned int packet_length,
|
|
|
unsigned char acceptance,
|
|
|
unsigned int completion,
|
|
|
unsigned char service_type,
|
|
|
unsigned char service_subtype,
|
|
|
unsigned char sourceID*/
|
|
|
|
|
|
count = nbBYTES_application_data+12; // +12 => packet header 6 bytes + data field header 4 bytes + packet error control 2 bytes
|
|
|
tab = (char*) malloc(count);
|
|
|
tab[0] = ccsds_command->ccsds_header->packetId1;
|
|
|
tab[1] = ccsds_command->ccsds_header->packetId0;
|
|
|
tab[2] = ccsds_command->ccsds_header->packetSequenceControl1;
|
|
|
tab[3] = ccsds_command->ccsds_header->packetSequenceControl0;
|
|
|
tab[4] = ccsds_command->ccsds_header->packetLength1;
|
|
|
tab[5] = ccsds_command->ccsds_header->packetLength0;
|
|
|
tab[6] = ccsds_command->ccsds_header->dataFieldHeader3;
|
|
|
tab[7] = ccsds_command->ccsds_header->dataFieldHeader2;
|
|
|
tab[8] = ccsds_command->ccsds_header->dataFieldHeader1;
|
|
|
tab[9] = ccsds_command->ccsds_header->dataFieldHeader0;
|
|
|
tab[10] = (unsigned char) (time_COARSE>>24);
|
|
|
tab[11] = (unsigned char) (time_COARSE>>18);
|
|
|
tab[12] = (unsigned char) (time_COARSE>>8);
|
|
|
tab[13] = (unsigned char) (time_COARSE);
|
|
|
tab[14] = (unsigned char) (time_FINE>>8);
|
|
|
tab[15] = (unsigned char) (time_FINE);
|
|
|
tab[nbBYTES_application_data+10] = packetErrorControl1;
|
|
|
tab[nbBYTES_application_data+11] = packetErrorControl0;
|
|
|
|
|
|
WriteSPW(tab, count, UI->CCSDSTargetLogicalAddressSpinBox->value(), 0x00);
|
|
|
|
|
|
time_COARSE = time_COARSE+1;
|
|
|
|
|
|
free(tab);
|
|
|
}
|
|
|
|
|
|
void rmapplugin::reset_TC_LFR_UPDATE_TIME()
|
|
|
{
|
|
|
time_COARSE = 0;
|
|
|
time_FINE = 0;
|
|
|
}
|
|
|
|
|
|
void rmapplugin::RMAP_write_reply_setText(QString text)
|
|
|
{
|
|
|
this->UI->RMAP_write_reply->setText(text);
|
|
|
}
|
|
|
|
|
|
void rmapplugin::appendToLog(QString text)
|
|
|
{
|
|
|
APPENDTOLOG(text);
|
|
|
}
|
|
|
|
|
|
void rmapplugin::setValueTargetAddress(unsigned char newAddress)
|
|
|
{
|
|
|
this->UI->rmapTargetLogicalAddressSpinBox->setValue(newAddress);
|
|
|
}
|
|
|
|
|
|
void rmapplugin::setValueSourceAddress(unsigned char newAddress)
|
|
|
{
|
|
|
this->UI->rmapSourceLogicalAddressSpinBox->setValue(newAddress);
|
|
|
}
|
|
|
|
|
|
/////////////////////
|
|
|
// INTERNAL FUNCTIONS
|
|
|
|
|
|
void rmapplugin::processCCSDSPacket(unsigned char *ccsdsPacket, unsigned int size) // SLOT
|
|
|
{
|
|
|
QString message;
|
|
|
unsigned int fine_time_value = 0;
|
|
|
fine_time_value = ((unsigned int) ccsdsPacket[7]<<24)
|
|
|
+ ((unsigned int) ccsdsPacket[6]<<16)
|
|
|
+ ((unsigned int) ccsdsPacket[5]<<8)
|
|
|
+ ((unsigned int) ccsdsPacket[4]);
|
|
|
message.append(QTime::currentTime().toString() +":" + QString::number(QTime::currentTime().msec()) + ": ");
|
|
|
message.append("size "
|
|
|
+ QString::number(size)
|
|
|
+" *** header "
|
|
|
+ QString::number(ccsdsPacket[0], 16)
|
|
|
+ " "
|
|
|
+ QString::number(ccsdsPacket[1], 16)
|
|
|
+ " "
|
|
|
+ QString::number(ccsdsPacket[2], 16)
|
|
|
+ " "
|
|
|
+ QString::number(ccsdsPacket[3], 16)
|
|
|
+ " *** coarse time "
|
|
|
+ QString::number(fine_time_value));
|
|
|
//+ QString::number(ccsdsPacket[4], 16)
|
|
|
//+" "
|
|
|
//+ QString::number(ccsdsPacket[5], 16)
|
|
|
//+" "
|
|
|
//+ QString::number(ccsdsPacket[6], 16)
|
|
|
//+" "
|
|
|
//+ QString::number(ccsdsPacket[7], 16));
|
|
|
displayOnConsole(message);
|
|
|
((rmappluginPythonWrapper*)this->pyObject)->storeCCSDSPacket(ccsdsPacket, size);
|
|
|
emit ccsdsPacketIsProcessed();
|
|
|
}
|
|
|
|
|
|
void rmapplugin::processPacketStore()
|
|
|
{
|
|
|
((rmappluginPythonWrapper*)this->pyObject)->processPacketStore();
|
|
|
}
|
|
|
|
|
|
void rmapplugin::updatePacketStore()
|
|
|
{
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
((rmappluginPythonWrapper*)this->pyObject)->ccsdsPacketStore = &(this->UI->gresbBridge->ccsdsPacketStore);
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
((rmappluginPythonWrapper*)this->pyObject)->ccsdsPacketStore = &(this->UI->starDundee->ccsdsPacketStore);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int rmapplugin::fetchPacket()
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
|
switch(currentBridge)
|
|
|
{
|
|
|
case selectedBridgeIsGRESB :
|
|
|
break;
|
|
|
case selectedBridgeIsStarDundee :
|
|
|
ret = this->UI->starDundee->receiveSPWPacketLoop();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|