/*------------------------------------------------------------------------------ -- 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 #include #include #include #include #include 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, 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(sendPacket(TMPacketToRead*)), this, SLOT(receivePacketFromBridge(TMPacketToRead*))); //************ // 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, 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(sendPacket(TMPacketToRead*)), this, SLOT(receivePacketFromBridge(TMPacketToRead*))); connect(this->UI, SIGNAL(bridgeHasChanged(selectedBridge)), this, SLOT(bridgeHasChanged(selectedBridge))); ((rmappluginPythonWrapper*)this->pyObject)->ccsdsPacketStore = &(this->generalCCSDSPacketStore); } 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); } void rmapplugin::receivePacketFromBridge(TMPacketToRead *packet) { preProcessPacket(packet); this->generalCCSDSPacketStore.append(packet); this->UI->nbPacketInStore->setText("nb packets in store: " + QString::number(generalCCSDSPacketStore.count())); processPacketStore(); } void rmapplugin::preProcessPacket(TMPacketToRead *packet) { unsigned char typ = 0; unsigned char sub = 0; unsigned char sid = 0; unsigned char pkt_nr = 0; unsigned int blk_nr = 0; unsigned int i = 0; unsigned int j = 0; unsigned char *data; typ = packet->Value[11]; // TYPE sub = packet->Value[12]; // SUBTYPE if ( (typ == 21) & (sub == 3) ) { sid = packet->Value[20]; // SID pkt_nr = packet->Value[23]; // PKT_NR blk_nr = packet->Value[24] * 256 + packet->Value[25]; switch (sid){ case SID_NORMAL_SWF_F0: emit displayOnConsole("wf packet received, sid: " + QString::number(sid) + ", pkt_nr: " + QString::number(pkt_nr) + ", blk_nr: " + QString::number(blk_nr) ); data = &packet->Value[26]; // start of the first data block; j = (pkt_nr-1) * 340; for ( i=0; iUI->wfDisplay->displayOnPlot(normal_swf_f0_v, 0); this->UI->wfDisplay->displayOnPlot(normal_swf_f0_e1, 1); this->UI->wfDisplay->displayOnPlot(normal_swf_f0_e2, 2); this->UI->wfDisplay->displayOnPlot(normal_swf_f0_b1, 3); } break; case SID_NORMAL_SWF_F1: break; case SID_NORMAL_SWF_F2: break; case SID_NORMAL_CWF_F3: break; } } } ///////////////////// // 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(); } int rmapplugin::fetchPacket() { int ret = 0; switch(currentBridge) { case selectedBridgeIsGRESB : break; case selectedBridgeIsStarDundee : ret = this->UI->starDundee->receiveSPWPacketLoop(); break; default: break; } return ret; }