/*------------------------------------------------------------------------------ -- 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 rmapplugin::rmapplugin(QWidget *parent) :lppmonplugin(parent,false) { this->UI = new rmapPluginUI(); this->setWindowTitle(tr("RMAP and SPW Communication")); this->setWidget((QWidget*)this->UI); RMAPSend_SOCKET = new QTcpSocket; RMAPReceive_SOCKET = new QTcpSocket; GRESBStatusQuery_SOCKET = new QTcpSocket; spwPacketReceiverOBJECT = new spwpacketreceiver; spwPacketReceiverOBJECT->gresbReceptionSocket = RMAPReceive_SOCKET; timeCode = 0; time_COARSE = 0; time_FINE = 0; /*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(UI->rmapOpenCommunicationButton, SIGNAL(clicked()), this, SLOT(RMAP_CONNECT())); connect(UI->rmapCloseCommunicationButton, SIGNAL(clicked()), this, SLOT(RMAP_DISCONNECT())); connect(RMAPSend_SOCKET, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(RMAPSendConnectionState(QAbstractSocket::SocketState))); connect(RMAPReceive_SOCKET, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(RMAPReceiveConnectionState(QAbstractSocket::SocketState))); connect(GRESBStatusQuery_SOCKET, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(GRESBConnectionState(QAbstractSocket::SocketState))); connect(UI->gresbStatusQueryRetryButton, SIGNAL(clicked()), this, SLOT(reTestSPWLink())); connect(this->UI->spwLinkStatusEnquiry->readSPWStatusButton, SIGNAL(clicked()), this, SLOT(GRESBStatusQuery())); connect(this->RMAPReceive_SOCKET, SIGNAL(readyRead()), this->spwPacketReceiverOBJECT, SLOT(receiveSPWPacket())); // 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())); // CONSOLE connect(this->spwPacketReceiverOBJECT, SIGNAL(sendMessage(QString)), this, SLOT(displayOnConsole(QString))); connect(this->UI->starDundee, SIGNAL(sendMessage(QString)), this, SLOT(displayOnConsole(QString))); // 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))); } rmapplugin::~rmapplugin() { if (!RMAPSend_SOCKET->isOpen()) RMAPSend_SOCKET->disconnectFromHost(); if (!RMAPReceive_SOCKET->isOpen()) RMAPReceive_SOCKET->disconnectFromHost(); if (!GRESBStatusQuery_SOCKET->isOpen()) GRESBStatusQuery_SOCKET->disconnectFromHost(); } unsigned int rmapplugin::Write(unsigned int *Value, unsigned int count, unsigned int address) { unsigned int remainingCount = count; unsigned int iOffset = 0; QString console_message; char* data; unsigned char command = 0x08; // initialize command at 0b00001000 for write if(spwPacketReceiverOBJECT->rmapPacketSEMAPHORE->available()!=0) { APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** RMAP request already running, WRITE access stopped"); return 1; } if (UI->RMAP_write_verify->isChecked()) command = command + (1<<2); if (UI->RMAP_write_reply->isChecked()) command = command + (1<<1); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: unavailable"); data = (char*) malloc(READ_WRITE_MAX_COUNTS*4); APPENDTOLOG(QString("*** START *** WRITE ")+ QString::number(count) + QString(" word(s) @0x")+ QString::number(address,16)); while (remainingCount > READ_WRITE_MAX_COUNTS) { for (int i = 0; i>8); data[i*4+1] = (char) ((unsigned int) Value[i+iOffset]>>16); data[i*4+0] = (char) ((unsigned int) Value[i+iOffset]>>24); } console_message.sprintf("remainingCount: %d => ", remainingCount); APPENDTOLOG(console_message + QString("Write ")+ QString::number(READ_WRITE_MAX_COUNTS*4) + QString(" byte(s) @0x")+ QString::number(address,16)); if(WriteBLOCK(data, READ_WRITE_MAX_COUNTS*4, address)==0) { APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** RMAP write command failed"); return 1; } remainingCount = remainingCount - READ_WRITE_MAX_COUNTS; address = address + READ_WRITE_MAX_COUNTS * 4; iOffset = iOffset + READ_WRITE_MAX_COUNTS; } if (remainingCount > 0) { for (unsigned int i = 0; i>8); data[i*4+1] = (char) ((unsigned int) Value[i+iOffset]>>16); data[i*4+0] = (char) ((unsigned int) Value[i+iOffset]>>24); } console_message.sprintf("remainingCount: %d => ", remainingCount); APPENDTOLOG(console_message + QString("Write ")+ QString::number(remainingCount*4) + QString(" byte(s) @0x")+ QString::number(address,16)); if (WriteBLOCK(data, remainingCount*4, address)==0) { APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** RMAP write command failed"); return 1; } } APPENDTOLOG(QString("*** STOP *** WRITE")); free(data); return count; } unsigned int rmapplugin::Read(unsigned int *Value, unsigned int count, unsigned int address) { unsigned int remainingCount = count; unsigned int iOffset = 0; QString console_message; if(spwPacketReceiverOBJECT->rmapPacketSEMAPHORE->available()!=0) { APPENDTOLOG("WARNING === in function READ of rmapplugin *** RMAP request already running, READ access stopped"); return 1; } APPENDTOLOG(QString("*** START *** READ ")+ QString::number(count) + QString(" word(s) @0x")+ QString::number(address,16)); while (remainingCount > READ_WRITE_MAX_COUNTS) { console_message.sprintf("remainingCount: %d => ", remainingCount); APPENDTOLOG(console_message + QString("Read ")+ QString::number(4*READ_WRITE_MAX_COUNTS) + QString(" byte(s) @0x")+ QString::number(address,16)); if (ReadBLOCK(READ_WRITE_MAX_COUNTS*4, address)==0) { APPENDTOLOG("WARNING === in function READ of rmapplugin *** RMAP packet not received"); return 1; } for(int i=0;irmapPacket[i*4+RMAP_READ_REPLY_HEADER_LENGTH]; for(int j=1;j<4;j++) { Value[i+iOffset]= ((unsigned char)(spwPacketReceiverOBJECT->rmapPacket[i*4+j+RMAP_READ_REPLY_HEADER_LENGTH])) + Value[i+iOffset]*256; } } remainingCount = remainingCount - READ_WRITE_MAX_COUNTS; address = address + READ_WRITE_MAX_COUNTS * 4; iOffset = iOffset + READ_WRITE_MAX_COUNTS; spwPacketReceiverOBJECT->acquireRMAPSemaphore(); } if (remainingCount > 0) { console_message.sprintf("remainingCount: %d => ", remainingCount); APPENDTOLOG(console_message + QString("Read ")+ QString::number(4*remainingCount) + QString(" byte(s) @0x")+ QString::number(address,16)); if (ReadBLOCK(4*remainingCount, address)==0) { APPENDTOLOG("WARNING === in function READ of rmapplugin *** RMAP packet not received"); return 1; } for(unsigned int i=0;irmapPacket[i*4+RMAP_READ_REPLY_HEADER_LENGTH]; for(int j=1;j<4;j++) { Value[i+iOffset]= ((unsigned char)(spwPacketReceiverOBJECT->rmapPacket[i*4+j+RMAP_READ_REPLY_HEADER_LENGTH])) + Value[i+iOffset]*256; } } spwPacketReceiverOBJECT->acquireRMAPSemaphore(); } APPENDTOLOG(QString("*** STOP *** READ ")); return count; } unsigned int rmapplugin::ReadBLOCK(unsigned int nbBytes, unsigned int address) { int errorCode; RMAP *RMAPCommand; QTime RMAPTimeout; unsigned int dataLength; if (GRESBStatusQueryRequest(LinkStatus, UI->spwLinkSpinBox->value()) == 1) { RMAP_DISCONNECT(); return 1; } if (nbBytes > 4) { RMAPCommand = new RMAP(read_Inc, UI->rmapTargetLogicalAddressSpinBox->value(), UI->rmapSourceLogicalAddressSpinBox->value(), address, nbBytes, NULL); } else { RMAPCommand = new RMAP(read_Single, UI->rmapTargetLogicalAddressSpinBox->value(), UI->rmapSourceLogicalAddressSpinBox->value(), address, nbBytes, NULL); } // SEND THE GRESB HEADER FOR THE RMAP READ COMMAND RMAPSend_SOCKET->write((char*) ((void*) &RMAPCommand->GRESBHeader), 4); // SEND THE SPACEWIRE PACKET FOR THE RMAP READ COMMAND RMAPSend_SOCKET->write((char*) ((void*) &RMAPCommand->RMAPHeader), sizeof(RMAPCommand->RMAPHeader)); RMAPSend_SOCKET->waitForBytesWritten(100); RMAPTimeout.start(); // write timeout while(RMAPSend_SOCKET->bytesToWrite() > 0) { RMAPSend_SOCKET->waitForBytesWritten(100); if(RMAPTimeout.elapsed()>1000) { APPENDTOLOG("WARNING === in function READ of rmapplugin *** sending Read RMAP Command timeout\n"); return 0; } } // RECEIVE THE INCOMING RMAP PACKET errorCode = spwPacketReceiverOBJECT->receiveSPWPacket(1); // request ID 1 is for RMAP packet if (errorCode<=0) { APPENDTOLOG("WARNING === in function ReadBLOCK of rmapplugin *** RMAP packet reception failed with code " + QString::number(errorCode)); return 0; } dataLength = spwPacketReceiverOBJECT->rmapPacketSize - RMAP_READ_REPLY_HEADER_LENGTH - RMAP_DATA_CRC_LENGTH; if(dataLength != nbBytes) { APPENDTOLOG("WARNING === in function READ of rmapplugin *** number of data received (" +QString::number(dataLength) +") not equal to number of data requested (" +QString::number(READ_WRITE_MAX_COUNTS*4) +")"); return 0; } return dataLength; } unsigned int rmapplugin::WriteBLOCK(char *data, unsigned int nbBytes, unsigned int address) { QTime RMAPTimeout; RMAP *RMAPCommand; int errorCode; QString console_message; if (GRESBStatusQueryRequest(LinkStatus, UI->spwLinkSpinBox->value()) == 1) { RMAP_DISCONNECT(); return 1; } RMAPCommand = new RMAP(UI->getCommandCode(), UI->rmapTargetLogicalAddressSpinBox->value(), UI->rmapSourceLogicalAddressSpinBox->value(), address, nbBytes, data); // SEND GRESB HEADER RMAPSend_SOCKET->write((char*) ((void*) &RMAPCommand->GRESBHeader), 4); // SEND SPACEWIRE PACKET HEADER RMAPSend_SOCKET->write((char*) ((void*) &RMAPCommand->RMAPHeader), sizeof(RMAPCommand->RMAPHeader)); // SEND DATA RMAPSend_SOCKET->write( data, nbBytes); // SEND DATA CRC RMAPSend_SOCKET->write((char*) ((void*) &RMAPCommand->dataCRC), 1); RMAPTimeout.start(); while(RMAPSend_SOCKET->bytesToWrite() > 0) { RMAPSend_SOCKET->waitForBytesWritten(100); if(RMAPTimeout.elapsed()>1000) { APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** sending Write RMAP Command timeout"); return 0; } } if (UI->RMAP_write_reply->isChecked()) { // WAIT FOR THE RMAP REPLY PACKET errorCode = spwPacketReceiverOBJECT->receiveSPWPacket(1); if (errorCode<=0) { APPENDTOLOG("WARNING === in function WriteBLOCK of rmapplugin *** RMAP packet reception failed with code " + QString::number(errorCode)); return 0; } if(spwPacketReceiverOBJECT->rmapPacketSize != 8) { console_message.sprintf("WARNING === in function WRITE (with reply) of rmapplugin *** write reply format not compliant\n"); APPENDTOLOG(console_message); return 0; } switch (spwPacketReceiverOBJECT->rmapPacket[3]) // byte 4 is the status byte in the reply { case 0: UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 0 Successfull"); break; case 1: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** General error code"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 1 General error code"); break; case 2: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Unused RMAP packet type or command code"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 2 Unused RMAP packet type or command code"); break; case 3: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid key"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 3 Invalid key"); break; case 4: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid data CRC"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 4 Invalid data CRC"); break; case 5: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Early EOP"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 5 Early EOP"); break; case 6: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Too much data"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 6 Too much data"); break; case 7: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** EEP"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 7 EEP"); break; case 8: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Reserved"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 8 Reserved"); break; case 9: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Verify buffer overrun"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 9 Verify buffer overrun"); break; case 10: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** RMAP command not implemented or not authorised"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 10 RMAP command not implemented or not authorised"); break; case 11: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** RMW data length error"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 11 RMAP RMW data length error"); break; case 12: APPENDTOLOG("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid target logical address"); UI->RMAP_write_reply->setText("reply to the write command required\nlast reply status: 12 Invalid target logical address"); break; } spwPacketReceiverOBJECT->acquireRMAPSemaphore(); } return nbBytes; } //////// // SLOTS unsigned int rmapplugin::WriteSPW(char *Value, unsigned int count, char targetLogicalAddress, char userApplication) // SLOT { char protocoleIdentifier = 0x02; char reserved = 0x00; char gresbProtocole = 0x00; unsigned char size[3]; unsigned int spwPacketSize = count + 4; QTime SPWTimeout; if (count>248) { APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** CCSDS packet size > 248 bytes\n"); return 1; } APPENDTOLOG(QString("*** START *** Send CCSDS packet of ")+ QString::number(count) + QString(" byte(s)")); if (GRESBStatusQueryRequest(LinkStatus, UI->spwLinkSpinBox->value()) == 1) { RMAP_DISCONNECT(); APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** SPW link not running\n"); return 1; } // SEND GRESB HEADER size[0] = (unsigned char) ((unsigned int) spwPacketSize>>16); size[1] = (unsigned char) ((unsigned int) spwPacketSize>>8); size[2] = (unsigned char) ((unsigned int) spwPacketSize); RMAPSend_SOCKET->write(&gresbProtocole, 1); RMAPSend_SOCKET->write((char*) size, 3); // SEND SPW HEADER RMAPSend_SOCKET->write(&targetLogicalAddress, 1); RMAPSend_SOCKET->write(&protocoleIdentifier, 1); RMAPSend_SOCKET->write(&reserved, 1); RMAPSend_SOCKET->write(&userApplication, 1); // SEND CCSDS PACKET RMAPSend_SOCKET->write(Value, count); SPWTimeout.start(); while(RMAPSend_SOCKET->bytesToWrite() > 0) { RMAPSend_SOCKET->waitForBytesWritten(100); if(SPWTimeout.elapsed()>1000) { APPENDTOLOG("WARNING === in function WRITE of rmapplugin *** sending CCSDS packet timeout\n"); return 1; } } APPENDTOLOG(QString("*** CCSDS packet sent")); return count; } 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::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_CONNECT() // SLOT { bool spwRunning = true; RMAPSend_SOCKET->connectToHost( QHostAddress(UI->gresbBridgeIPDialogBox->getGRESBIP()), 3000 + UI->gresbVirtualLinkSpinBox->value()*2, QIODevice::WriteOnly); RMAPReceive_SOCKET->connectToHost( QHostAddress(UI->gresbBridgeIPDialogBox->getGRESBIP()), 3000 + UI->gresbVirtualLinkSpinBox->value()*2+1, QIODevice::ReadOnly); GRESBStatusQuery_SOCKET->connectToHost( QHostAddress(UI->gresbBridgeIPDialogBox->getGRESBIP()), 3010, QIODevice::ReadWrite); GRESBStatusQuery_SOCKET->waitForConnected(10000); RMAPReceive_SOCKET->readAll(); // read all remaining data from the reception socket // initialize SPW packet semaphores while (spwPacketReceiverOBJECT->rmapPacketSEMAPHORE->available()!=0) spwPacketReceiverOBJECT->rmapPacketSEMAPHORE->acquire(); while (spwPacketReceiverOBJECT->ccsdsPacketSEMAPHORE->available()!=0) spwPacketReceiverOBJECT->ccsdsPacketSEMAPHORE->acquire(); if (GRESBStatusQueryRequest(LinkStatus, UI->spwLinkSpinBox->value()) != 0) { spwRunning = UI->gresbStatusQueryDialog->exec(); } if (spwRunning == false) RMAP_DISCONNECT(); else { APPENDTOLOG(QString("SpaceWire running on virtual link ")+ QString::number(UI->spwLinkSpinBox->value())); emit this->activateSig(true); } } void rmapplugin::RMAP_DISCONNECT() // SLOT { RMAPSend_SOCKET->disconnectFromHost(); RMAPReceive_SOCKET->disconnectFromHost(); GRESBStatusQuery_SOCKET->disconnectFromHost(); emit this->activateSig(false); } void rmapplugin::RMAPSendConnectionState(QAbstractSocket::SocketState socketState) // SLOT { UI->rmapSendStateLabel->setText(""); QString socketMessage = "RMAP Send Socket State: "; switch(socketState) { case QAbstractSocket::UnconnectedState : socketMessage.append("0 => Unconnected"); UI->rmapOpenCommunicationButton->setEnabled(true); UI->rmapCloseCommunicationButton->setEnabled(false); emit this->activateSig(false); break; case 1: socketMessage.append("1 => HostLookup"); break; case 2: socketMessage.append("2 => Connecting"); break; case 3: socketMessage.append("3 => Connected"); UI->rmapOpenCommunicationButton->setEnabled(false); UI->rmapCloseCommunicationButton->setEnabled(true); break; case 4: socketMessage.append("4 => Bound"); break; case 5: socketMessage.append("5 => Closing"); break; case 6: socketMessage.append("6 => Listening"); break; } UI->rmapSendStateLabel->setText(socketMessage); APPENDTOLOG(socketMessage); } void rmapplugin::RMAPReceiveConnectionState(QAbstractSocket::SocketState socketState) // SLOT { UI->rmapReceiveStateLabel->setText(""); QString socketMessage = "RMAP Receive Socket State: "; switch(socketState) { case QAbstractSocket::UnconnectedState : socketMessage.append("0 => Unconnected"); break; case 1: socketMessage.append("1 => HostLookup"); break; case 2: socketMessage.append("2 => Connecting"); break; case 3: socketMessage.append("3 => Connected"); break; case 4: socketMessage.append("4 => Bound"); break; case 5: socketMessage.append("5 => Closing"); break; case 6: socketMessage.append("6 => Listening"); break; } UI->rmapReceiveStateLabel->setText(socketMessage); APPENDTOLOG(socketMessage); } void rmapplugin::GRESBConnectionState(QAbstractSocket::SocketState socketState) // SLOT { UI->gresbStatusQueryLabel->setText(""); QString socketMessage = "GRESB status query socket (port 3010): "; switch(socketState) { case QAbstractSocket::UnconnectedState : socketMessage.append("0 => Unconnected"); break; case 1: socketMessage.append("1 => HostLookup"); break; case 2: socketMessage.append("2 => Connecting"); break; case 3: socketMessage.append("3 => Connected"); break; case 4: socketMessage.append("4 => Bound"); break; case 5: socketMessage.append("5 => Closing"); break; case 6: socketMessage.append("6 => Listening"); break; } UI->gresbStatusQueryLabel->setText(socketMessage); } void rmapplugin::reTestSPWLink() // SLOT { if (GRESBStatusQueryRequest(LinkStatus, UI->spwLinkSpinBox->value()) == 0) { UI->gresbStatusQueryDialog->accept(); } } int rmapplugin::GRESBStatusQuery() // SLOT { GRESBStatusQueryRequest(LinkStatus, 0); GRESBStatusQueryRequest(LinkStatus, 1); GRESBStatusQueryRequest(LinkStatus, 2); GRESBStatusQueryRequest(LinkStatistics, 0); GRESBStatusQueryRequest(LinkStatistics, 1); GRESBStatusQueryRequest(LinkStatistics, 2); return 0; } void rmapplugin::displayOnConsole(QString message) { this->UI->console->append(message); } ///////////////////// // INTERNAL FUNCTIONS int rmapplugin::GRESBStatusQueryRequest(GresbStatusQueryOption option, char link) { gresb_status_query_t statusQueryCommand; gresb_link_status_reply_t linkStatusReply; gresb_link_statistics_reply_t linkStatisticsReply; QTime statusQueryTimeout; QString console_message; statusQueryCommand.protocolIdentifier = (char) 0x02; statusQueryCommand.reserved1 = (char) 0x00; statusQueryCommand.reserved0 = (char) 0x00; statusQueryCommand.option = (char) option; statusQueryCommand.value3 = (char) 0x00; statusQueryCommand.value2 = (char) 0x00; statusQueryCommand.value1 = (char) 0x00; statusQueryCommand.value0 = (char) link; GRESBStatusQuery_SOCKET->write((char*) ((void*) &statusQueryCommand), sizeof(statusQueryCommand)); GRESBStatusQuery_SOCKET->flush(); GRESBStatusQuery_SOCKET->waitForBytesWritten(1000); statusQueryTimeout.start(); while(GRESBStatusQuery_SOCKET->bytesToWrite() > 0) { GRESBStatusQuery_SOCKET->waitForBytesWritten(100); if(statusQueryTimeout.elapsed()>1000) { APPENDTOLOG("WARNING === in function GRESBStatusQueryRequest of rmapplugin *** sending StatusQueryCommand timeout"); return 1; } } switch (option) { case LinkStatus: { statusQueryTimeout.start(); while(GRESBStatusQuery_SOCKET->bytesAvailable() < (int) sizeof(linkStatusReply)) { GRESBStatusQuery_SOCKET->waitForReadyRead(100); if(statusQueryTimeout.elapsed()>1000) { console_message.sprintf("GRESBStatusQueryRequest / LinkStatus => error timeout bytesAvailable()\n"); APPENDTOLOG(console_message); return 1; } } GRESBStatusQuery_SOCKET->read((char*) ((void*) &linkStatusReply), (int) sizeof(linkStatusReply)); console_message.sprintf("%x", linkStatusReply.byte0); UI->spwLinkStatusEnquiry->statusQueryTable->item(0, link)->setText(console_message); console_message.sprintf("%d", linkStatusReply.byte1); UI->spwLinkStatusEnquiry->statusQueryTable->item(1, link)->setText(console_message); if (linkStatusReply.byte0 == 0) return 1; break; } case LinkStatistics: { statusQueryTimeout.start(); while(GRESBStatusQuery_SOCKET->bytesAvailable() < (int) sizeof(linkStatisticsReply)) { GRESBStatusQuery_SOCKET->waitForReadyRead(100); if(statusQueryTimeout.elapsed()>1000) { console_message.sprintf("GRESBStatusQueryRequest / LinkStatistics => error timeout bytesAvailable()\n"); APPENDTOLOG(console_message); return 1; } } GRESBStatusQuery_SOCKET->read((char*) ((void*) &linkStatisticsReply), sizeof(linkStatisticsReply)); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.sizeOfDataTransmitted)); UI->spwLinkStatusEnquiry->statusQueryTable->item(9, link)->setText(console_message); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.numberOfPacketsTransmitted)); UI->spwLinkStatusEnquiry->statusQueryTable->item(8, link)->setText(console_message); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.numberOfTruncatedPacketsReceived)); UI->spwLinkStatusEnquiry->statusQueryTable->item(6, link)->setText(console_message); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.numberOfPacketsWithEEPReceived)); UI->spwLinkStatusEnquiry->statusQueryTable->item(5, link)->setText(console_message); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.sizeOfDataReceived)); UI->spwLinkStatusEnquiry->statusQueryTable->item(4, link)->setText(console_message); console_message.sprintf("%d", charTab_TO_int(linkStatisticsReply.numberOfPacketsReceived)); UI->spwLinkStatusEnquiry->statusQueryTable->item(3, link)->setText(console_message); break; } case NodeAddressStatistics: { break; } case GetRoute: { break; } } return 0; } int rmapplugin::charTab_TO_int(char *charTab) { int result = 0; result = (charTab[0]<<24) +(charTab[1]<<16) +(charTab[2]<<8) + charTab[3]; return result; }