# HG changeset patch # User Jeandet Alexis # Date 2015-09-28 18:04:29 # Node ID 81feb673e028e6a30bc3950aa125a024ae7a99fc # Parent a16dfc6c4bebac956d4740ad41b058b0dbbe05ef GRESB WIP. diff --git a/spwplugin/GR-ESB/gr_esb_bridge.cpp b/spwplugin/GR-ESB/gr_esb_bridge.cpp --- a/spwplugin/GR-ESB/gr_esb_bridge.cpp +++ b/spwplugin/GR-ESB/gr_esb_bridge.cpp @@ -105,20 +105,166 @@ void GR_ESB_bridge::setVirtualLink(qint3 unsigned int GR_ESB_bridge::Write(unsigned int *Value, unsigned int count, unsigned int address) { - // TODO write ME! - Q_UNUSED(count) - Q_UNUSED(Value) - Q_UNUSED(address) - return 0; + char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))]; + char *RMAPAckBuff; + int transactionID = 0; + int written=0; + SocExplorerEngine::message(this->plugin,"Enter Write function",2); + QProgressBar* progress=NULL; + SocExplorerAutoProgressBar autopb; + if(count>RMAP_MAX_XFER_SIZE) + { + progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); + autopb.setProgressBar(progress); + } + //Quite stupide loop, I guess that I always get the number of byte I asked for! + while(count>=RMAP_MAX_XFER_SIZE) + { + for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++) + { + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF); + } + transactionID=manager->getRMAPtransactionID(); + SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2); + RMAP_build_tx_request_header( + this->manager->destinationLogicalAddress, + this->manager->destinationKey, + this->manager->sourceLogicalAddress, + transactionID, + address+(written*4), + RMAP_MAX_XFER_SIZE*4, + writeBuffer); + manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4)); + manager->getRMAPanswer(transactionID,&RMAPAckBuff); + free(RMAPAckBuff); + written+=RMAP_MAX_XFER_SIZE; + count-=RMAP_MAX_XFER_SIZE; + progress->setValue(written); + qApp->processEvents(); + } + if(count>0) + { + for(int i=0;i<((int)count);i++) + { + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF); + writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF); + } + transactionID=manager->getRMAPtransactionID(); + SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2); + RMAP_build_tx_request_header( + this->manager->destinationLogicalAddress, + this->manager->destinationKey, + this->manager->sourceLogicalAddress, + transactionID, + address+(written*4), + count*4, + writeBuffer); + manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4)); + manager->getRMAPanswer(transactionID,&RMAPAckBuff); + free(RMAPAckBuff); + written+=count; + if(progress!=NULL) + { + progress->setValue(written); + qApp->processEvents(); + } + } + return written; } unsigned int GR_ESB_bridge::Read(unsigned int *Value, unsigned int count, unsigned int address) { - // TODO write ME! - Q_UNUSED(Value) - Q_UNUSED(count) - Q_UNUSED(address) - return 0; + char requestBuffer[RMAP_READ_HEADER_MIN_SZ]; + char* RMAP_AnswerBuffer; + requestBuffer[0]=this->manager->linkNumber;//Link number + int transactionID = 0; + int read=0; + QProgressBar* progress=NULL; + SocExplorerAutoProgressBar autopb; + if(count>RMAP_MAX_XFER_SIZE) + { + progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); + autopb.setProgressBar(progress); + } + SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2); + + //Quite stupide loop, I guess that I always get the number of byte I asked for! + while((int)count>=(int)RMAP_MAX_XFER_SIZE) + { + transactionID = manager->getRMAPtransactionID(); + SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2); + RMAP_build_rx_request_header( + this->manager->destinationLogicalAddress, + this->manager->destinationKey, + this->manager->sourceLogicalAddress, + transactionID, + address+(read*4), + RMAP_MAX_XFER_SIZE*4, + requestBuffer); + manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ); + int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer); + if(len==-1) + { + this->toggleBridgeConnection(); + return 0; + } + for(int i=0;i<((len-13)/4);i++) + { + Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13])); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14])); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15])); + } + free(RMAP_AnswerBuffer); + read+=RMAP_MAX_XFER_SIZE; + count-=RMAP_MAX_XFER_SIZE; + progress->setValue(read); + qApp->processEvents(); + } + if((int)count>0) + { + transactionID = manager->getRMAPtransactionID(); + SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2); + SocExplorerEngine::message(this->plugin,QString("Building request with:"),2); + SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2); + SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2); + SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2); + RMAP_build_rx_request_header( + this->manager->destinationLogicalAddress, + this->manager->destinationKey, + this->manager->sourceLogicalAddress, + transactionID, + address+(read*4), + count*4, + requestBuffer); + manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ); + int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer); + if(len==-1) + { + this->toggleBridgeConnection(); + return 0; + } + for(int i=0;i<((len-13)/4);i++) + { + Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13])); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14])); + Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15])); + } + free(RMAP_AnswerBuffer); + read+=count; + if(progress!=NULL) + { + progress->setValue(read); + qApp->processEvents(); + } + } + return read; } int GR_ESB_bridge::pushRMAPPacket(char *packet, int size) @@ -128,34 +274,65 @@ int GR_ESB_bridge::pushRMAPPacket(char * GR_ESB_Manager::GR_ESB_Manager(socexplorerplugin *plugin, QObject *parent) - :QThread((QObject*)parent) + :abstractSpwManager(plugin, parent) { this->Read_soc = new QTcpSocket(this); this->Write_soc = new QTcpSocket(this); - this->RMAPtimeout = 2000; - this->handleMutex = new QMutex(QMutex::NonRecursive); - this->RMAP_AnswersSem = new QSemaphore(0); - this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive); - this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive); - this->plugin = plugin; - connected = false; - this->moveToThread(this); } GR_ESB_Manager::~GR_ESB_Manager() { - } void GR_ESB_Manager::run() { + char buffer[(RMAP_MAX_XFER_SIZE*4)+50]; SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1); while (!this->isInterruptionRequested()) { if(this->connected) { handleMutex->lock(); - SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4); + SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",5); + if(Read_soc->waitForReadyRead(100)) + { + QByteArray data = Read_soc->readAll(); + int PacketLen= ((int)data.at(2)& 0x0FF) + (((int)data.at(3)& 0x0FF)<<8) + (((int)data.at(4)& 0x0FF)<<16); + if(data[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet + { + RMAP_Answer* packet; + SocExplorerEngine::message(this->plugin,"Got RMAP packet",2); + SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(PacketLen),2); + char* packetbuffer = (char*)malloc(PacketLen); + memcpy(packetbuffer,data.data(),PacketLen); + this->handleMutex->unlock(); + if(PacketLen==8) + { + packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,PacketLen); + } + else + { + packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,PacketLen); + } + RMAP_AnswersMtx->lock(); + RMAP_Answers.append(packet); + RMAP_AnswersMtx->unlock(); + RMAP_AnswersSem->release(); + } + else //any non-rmap packet will be pushed to the network + { + char* packetbuffer = (char*)malloc(PacketLen); + memcpy(packetbuffer,data.data(),PacketLen); + emit emitPacket(packetbuffer,PacketLen); + this->handleMutex->unlock(); + SocExplorerEngine::message(this->plugin,"Got SPW packet",2); + } + + } + else + { + handleMutex->unlock(); + } } else @@ -212,31 +389,43 @@ bool GR_ESB_Manager::disconnectBridge() return true; } -int GR_ESB_Manager::getRMAPtransactionID() -{ - // TODO write ME! - return -1; -} - -int GR_ESB_Manager::getRMAPanswer(int transactionID, char **buffer) -{ - // TODO write ME! - Q_UNUSED(transactionID) - Q_UNUSED(buffer) - return -1; -} bool GR_ESB_Manager::sendPacket(char *packet, int size) { - // TODO write ME! - Q_UNUSED(packet) - Q_UNUSED(size) - return false; + bool result = false; + char protocoleIdentifier; + SocExplorerEngine::message(this->plugin,"Sending SPW packet",2); + if(Q_UNLIKELY(this->Write_soc->state()!=QAbstractSocket::ConnectedState)) + { + SocExplorerEngine::message(this->plugin,"Socket closed",2); + //TODO handle disconnection + } + char* SPWpacket = (char*)malloc(size+4); + if(SPWpacket!=NULL) + { + SPWpacket[0]=0; //Protocol = spw + memcpy(SPWpacket+4,packet,size); + SPWpacket[1]=size & 0x0FF; + SPWpacket[2]=(size>>8) & 0x0FF; + SPWpacket[3]=(size>>16) & 0x0FF; + } + this->handleMutex->lock(); + result = ((size+4) == this->Write_soc->write(SPWpacket,size+4)); + this->handleMutex->unlock(); + if (Q_UNLIKELY(!result)) + { + SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2); + return false; + } + else + { + emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link + // read the protocole identifier + protocoleIdentifier = packet[2]; + if (protocoleIdentifier == SPW_PROTO_ID_CCSDS) + emit ccsdsPacketTransmittedToSpw(); + SocExplorerEngine::message(this->plugin,"Packet sent",2); + } + return true; } -void GR_ESB_Manager::pushRmapPacket(char *packet, int len) -{ - // TODO write ME! - Q_UNUSED(packet) - Q_UNUSED(len) -} diff --git a/spwplugin/GR-ESB/gr_esb_bridge.h b/spwplugin/GR-ESB/gr_esb_bridge.h --- a/spwplugin/GR-ESB/gr_esb_bridge.h +++ b/spwplugin/GR-ESB/gr_esb_bridge.h @@ -24,7 +24,7 @@ const struct gresb_Conf_str gresb_Conf[] }; -class GR_ESB_Manager: public QThread +class GR_ESB_Manager: public abstractSpwManager { Q_OBJECT public: @@ -33,28 +33,19 @@ public: void run(); bool connectBridge(); bool disconnectBridge(); - int getRMAPtransactionID(); - int getRMAPanswer(int transactionID,char** buffer); bool sendPacket(char* packet,int size); signals: void emitPacket(char* packet,int size); private: - QMutex* handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx; - QSemaphore* RMAP_AnswersSem; void pushRmapPacket(char* packet,int len); - socexplorerplugin* plugin; - bool connected; char* SPWPacketBuff; - QList RMAP_Answers; - QList RMAP_pending_transaction_IDs; public: QTcpSocket* Read_soc; QTcpSocket* Write_soc; QString IP; int virtualLinkIndex; - int RMAPtimeout; }; diff --git a/spwplugin/StarDundee/stardundeespw_usb.cpp b/spwplugin/StarDundee/stardundeespw_usb.cpp --- a/spwplugin/StarDundee/stardundeespw_usb.cpp +++ b/spwplugin/StarDundee/stardundeespw_usb.cpp @@ -40,11 +40,11 @@ stardundeeSPW_USB::stardundeeSPW_USB(soc Q_UNUSED(parent) this->manager = new stardundeeSPW_USB_Manager(parent,this); makeGUI(parent); - this->manager->start(); connect(this->manager,SIGNAL(emitPacket(char*,int)),this,SIGNAL(pushPacketOverTCP(char*,int))); connect(this->manager, SIGNAL(bytesReceivedFromSpw(uint)), this, SIGNAL(BytesReceivedFromSpw(uint))); connect(this->manager, SIGNAL(bytesTransmittedToSpw(uint)), this, SIGNAL(BytesTransmittedToSpw(uint))); connect(this->manager, SIGNAL(ccsdsPacketTransmittedToSpw()), this, SIGNAL(CCSDSPacketTransmittedToSpw())); + this->manager->start(); } stardundeeSPW_USB::~stardundeeSPW_USB() @@ -400,16 +400,8 @@ void stardundeeSPW_USB::sendPacketComing } stardundeeSPW_USB_Manager::stardundeeSPW_USB_Manager(socexplorerplugin *plugin, QObject *parent) - :QThread((QObject*)parent) + :abstractSpwManager(plugin, parent) { - this->RMAPtimeout = 2000; - this->handleMutex = new QMutex(QMutex::NonRecursive); -// this->handleMutex = new QMutex(QMutex::Recursive); - this->RMAP_AnswersSem = new QSemaphore(0); - this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive); - this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive); - this->plugin = plugin; - connected = false; // TODO remove this crap! this->initDialog(); // this->moveToThread(this); @@ -417,10 +409,6 @@ stardundeeSPW_USB_Manager::stardundeeSPW stardundeeSPW_USB_Manager::~stardundeeSPW_USB_Manager() { - this->terminate(); - while (!this->isFinished()) { - this->usleep(1000); - } } void stardundeeSPW_USB_Manager::run() @@ -926,84 +914,6 @@ bool stardundeeSPW_USB_Manager::disconne return true; } -int stardundeeSPW_USB_Manager::getRMAPtransactionID() -{ - this->RMAP_pending_transaction_IDsMtx->lock(); - int ID=0; - bool found=true; - while(ID<511) - { - for(int i=0;iRMAP_pending_transaction_IDsMtx->unlock(); - return ID; -} - -int stardundeeSPW_USB_Manager::getRMAPanswer(int transactionID, char **buffer) -{ - QTime timeout; - *buffer=NULL; - int count=0; - SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2); - timeout.start(); - while (*buffer==NULL) - { - this->RMAP_AnswersMtx->lock(); - SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2); - SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2); - for(int i=0;iplugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2); - if(RMAP_Answers[i]->transactionID==transactionID) - { - this->RMAP_pending_transaction_IDsMtx->lock(); - SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2); - for(int j=0;jRMAP_pending_transaction_IDsMtx->unlock(); - *buffer = RMAP_Answers[i]->data; - count = RMAP_Answers[i]->len; - RMAP_Answer* tmp=RMAP_Answers[i]; - RMAP_Answers.removeAt(i); - delete tmp; - } - } - this->RMAP_AnswersMtx->unlock(); - //if no answer found in the stack wait until a new packet is pushed - SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2); - if(*buffer==NULL) - { - while (0==this->RMAP_AnswersSem->available()) - { - SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2); - if(timeout.elapsed()>=RMAPtimeout) - { - SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2); - return -1; - } - usleep(1000); - } - this->RMAP_AnswersSem->acquire(); - } - } - return count; -} - bool stardundeeSPW_USB_Manager::sendPacket(char *packet, int size) { char protocoleIdentifier; @@ -1032,15 +942,6 @@ bool stardundeeSPW_USB_Manager::sendPack return true; } -void stardundeeSPW_USB_Manager::pushRmapPacket(char *packet, int len) -{ - char* packetbuffer = (char*)malloc(len); - memcpy(packetbuffer,packet,len); - RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len); - RMAP_AnswersMtx->lock(); - RMAP_Answers.append(RMPAPpacket); - RMAP_AnswersMtx->unlock(); -} void stardundeeSPW_USB_Manager::sendTimecodePeriodically( bool onOff ) { diff --git a/spwplugin/StarDundee/stardundeespw_usb.h b/spwplugin/StarDundee/stardundeespw_usb.h --- a/spwplugin/StarDundee/stardundeespw_usb.h +++ b/spwplugin/StarDundee/stardundeespw_usb.h @@ -41,7 +41,7 @@ #define BRICK_IS_SET_AS_AN_INTERFACE true #define BRICK_IS_SET_AS_A_ROUTER false -class stardundeeSPW_USB_Manager: public QThread +class stardundeeSPW_USB_Manager: public abstractSpwManager { Q_OBJECT public: @@ -58,8 +58,6 @@ public: void setTimecodeFrequency(double requestedFrequency); unsigned int getLinkStatus(unsigned char link); bool disconnectBridge(); - int getRMAPtransactionID(); - int getRMAPanswer(int transactionID,char** buffer); bool sendPacket(char* packet,int size); signals: @@ -75,15 +73,8 @@ public slots: int getLinkNumber( void ); private: - QMutex *handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx; QSemaphore* RMAP_AnswersSem; - void pushRmapPacket(char* packet,int len); star_device_handle hDevice; - socexplorerplugin* plugin; - bool connected; - char* SPWPacketBuff; - QList RMAP_Answers; - QList RMAP_pending_transaction_IDs; QLabel *starDundeeStatusQueryDialogLabel; QPushButton *starDundeeStatusQueryRetryButton; @@ -96,13 +87,8 @@ private: public: int selectedBrick; - int linkNumber; int brickList; int linkSpeed; - int sourceLogicalAddress; - int destinationLogicalAddress; - int destinationKey; - int RMAPtimeout; double timecodeFrequency; bool interfaceMode; // 1 => interface mode, 0 => router mode }; diff --git a/spwplugin/abstractspwbridge.cpp b/spwplugin/abstractspwbridge.cpp --- a/spwplugin/abstractspwbridge.cpp +++ b/spwplugin/abstractspwbridge.cpp @@ -20,6 +20,8 @@ -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ #include "abstractspwbridge.h" +#include +#include abstractSpwBridge::abstractSpwBridge(socexplorerplugin *parent) :QObject((QObject*)parent) @@ -54,3 +56,121 @@ bool abstractSpwBridge::disconnectBridge + + +abstractSpwManager::abstractSpwManager(socexplorerplugin *plugin, QObject *parent) + :QThread((QObject*)parent) +{ + this->RMAPtimeout = 2000; + this->handleMutex = new QMutex(QMutex::NonRecursive); + this->RMAP_AnswersSem = new QSemaphore(0); + this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive); + this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive); + this->plugin = plugin; + connected = false; +} + +abstractSpwManager::~abstractSpwManager() +{ + this->terminate(); + while (!this->isFinished()) + { + this->usleep(1000); + } +} + +int abstractSpwManager::getRMAPtransactionID() +{ + this->RMAP_pending_transaction_IDsMtx->lock(); + int ID=0; + bool found=true; + while(ID<511) + { + for(int i=0;iRMAP_pending_transaction_IDsMtx->unlock(); + return ID; +} + +int abstractSpwManager::getRMAPanswer(int transactionID, char **buffer) +{ + + QTime timeout; + *buffer=NULL; + int count=0; + SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2); + timeout.start(); + while (*buffer==NULL) + { + this->RMAP_AnswersMtx->lock(); + SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2); + SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2); + for(int i=0;iplugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2); + if(RMAP_Answers[i]->transactionID==transactionID) + { + this->RMAP_pending_transaction_IDsMtx->lock(); + SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2); + for(int j=0;jRMAP_pending_transaction_IDsMtx->unlock(); + *buffer = RMAP_Answers[i]->data; + count = RMAP_Answers[i]->len; + RMAP_Answer* tmp=RMAP_Answers[i]; + RMAP_Answers.removeAt(i); + delete tmp; + } + } + this->RMAP_AnswersMtx->unlock(); + //if no answer found in the stack wait until a new packet is pushed + SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2); + if(*buffer==NULL) + { + while (0==this->RMAP_AnswersSem->available()) + { + SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2); + if(timeout.elapsed()>=RMAPtimeout) + { + SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2); + return -1; + } + usleep(1000); + } + this->RMAP_AnswersSem->acquire(); + } + } + return count; +} + +int abstractSpwManager::getLinkNumber() +{ + return this->linkNumber; +} + +void abstractSpwManager::pushRmapPacket(char *packet, int len) +{ + char* packetbuffer = (char*)malloc(len); + memcpy(packetbuffer,packet,len); + RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len); + RMAP_AnswersMtx->lock(); + RMAP_Answers.append(RMPAPpacket); + RMAP_AnswersMtx->unlock(); +} + + diff --git a/spwplugin/abstractspwbridge.h b/spwplugin/abstractspwbridge.h --- a/spwplugin/abstractspwbridge.h +++ b/spwplugin/abstractspwbridge.h @@ -23,6 +23,9 @@ #define ABSTRACTSPWBRIDGE_H #include +#include +#include +#include #include #define RMAP_MAX_XFER_SIZE 4000 //slightly less than 16kBytes #include @@ -65,4 +68,43 @@ private: }; +class abstractSpwManager: public QThread +{ + Q_OBJECT +public: + explicit abstractSpwManager(socexplorerplugin *plugin = 0,QObject* parent=0); + ~abstractSpwManager(); + virtual void run(){} + virtual bool connectBridge()=0; + virtual bool disconnectBridge()=0; + int getRMAPtransactionID(); + int getRMAPanswer(int transactionID,char** buffer); + virtual bool sendPacket(char* packet,int size)=0; + int RMAPtimeout; + int linkNumber; + int sourceLogicalAddress; + int destinationLogicalAddress; + int destinationKey; +signals: + void emitPacket(char* packet,int size); + void bytesReceivedFromSpw( unsigned int ); + void bytesTransmittedToSpw( unsigned int); + void ccsdsPacketTransmittedToSpw( void ); + +public slots: + int getLinkNumber(); + +protected: + QList RMAP_Answers; + QList RMAP_pending_transaction_IDs; + QMutex *handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx; + QSemaphore* RMAP_AnswersSem; + socexplorerplugin* plugin; + bool connected; + void pushRmapPacket(char* packet,int len); + +}; + + + #endif // ABSTRACTSPWBRIDGE_H