##// END OF EJS Templates
GRESB WIP.
Jeandet Alexis -
r71:81feb673e028 GRESB
parent child
Show More
@@ -1,242 +1,431
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "gr_esb_bridge.h"
23 23 #include "gr_esb_ui.h"
24 24 #include <unistd.h>
25 25 #include "spw.h"
26 26 #include <socexplorerengine.h>
27 27
28 28 GR_ESB_bridge::GR_ESB_bridge(socexplorerplugin *parent) :
29 29 abstractSpwBridge(parent)
30 30 {
31 31 this->p_GUI = new GR_ESB_ui();
32 32 this->manager = new GR_ESB_Manager(parent,this);
33 33
34 34 connect((GR_ESB_ui*)(this->p_GUI),SIGNAL(ipchanged(QString)),this,SLOT(setIP(QString)));
35 35 connect((GR_ESB_ui*)(this->p_GUI),SIGNAL(vlinkchanged(QString)),this,SLOT(setVirtualLink(QString)));
36 36 connect((GR_ESB_ui*)(this->p_GUI),SIGNAL(connectClicked()),this,SLOT(toggleBridgeConnection()));
37 37 this->manager->virtualLinkIndex = 0;
38 38 this->manager->start();
39 39 }
40 40
41 41 GR_ESB_bridge::~GR_ESB_bridge()
42 42 {
43 43 this->manager->requestInterruption();
44 44 while(this->manager->isRunning());
45 45 }
46 46
47 47 void GR_ESB_bridge::toggleBridgeConnection()
48 48 {
49 49 if(this->plugin->isConnected())
50 50 {
51 51 this->disconnectBridge();
52 52 }
53 53 else
54 54 {
55 55 this->connectBridge();
56 56 }
57 57 }
58 58
59 59 bool GR_ESB_bridge::connectBridge()
60 60 {
61 61 if(this->manager->connectBridge())
62 62 {
63 63 ((GR_ESB_ui*)this->p_GUI)->lock(true);
64 64 emit setConnected(true);
65 65 return true;
66 66 }
67 67 return false;
68 68 }
69 69
70 70 bool GR_ESB_bridge::disconnectBridge()
71 71 {
72 72 if(this->manager->disconnectBridge())
73 73 {
74 74 ((GR_ESB_ui*)this->p_GUI)->lock(false);
75 75 emit setConnected(false);
76 76 return true;
77 77 }
78 78 return false;
79 79 }
80 80
81 81 void GR_ESB_bridge::setIP(QString ip)
82 82 {
83 83 this->manager->IP = ip;
84 84 }
85 85
86 86 void GR_ESB_bridge::setVirtualLink(QString vlink)
87 87 {
88 88 vlink = vlink.section("Virtual link",0,0);
89 89 bool success;
90 90 int vlinkTmp = vlink.toInt(&success);
91 91 if(success)
92 92 {
93 93 setVirtualLink(vlinkTmp);
94 94 }
95 95 }
96 96
97 97 void GR_ESB_bridge::setVirtualLink(qint32 vlink)
98 98 {
99 99 if(vlink<6 && vlink>=0)
100 100 {
101 101 this->manager->virtualLinkIndex = vlink;
102 102 }
103 103 }
104 104
105 105
106 106 unsigned int GR_ESB_bridge::Write(unsigned int *Value, unsigned int count, unsigned int address)
107 107 {
108 // TODO write ME!
109 Q_UNUSED(count)
110 Q_UNUSED(Value)
111 Q_UNUSED(address)
112 return 0;
108 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))];
109 char *RMAPAckBuff;
110 int transactionID = 0;
111 int written=0;
112 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
113 QProgressBar* progress=NULL;
114 SocExplorerAutoProgressBar autopb;
115 if(count>RMAP_MAX_XFER_SIZE)
116 {
117 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
118 autopb.setProgressBar(progress);
119 }
120 //Quite stupide loop, I guess that I always get the number of byte I asked for!
121 while(count>=RMAP_MAX_XFER_SIZE)
122 {
123 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
124 {
125 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
126 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
127 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
128 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
129 }
130 transactionID=manager->getRMAPtransactionID();
131 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
132 RMAP_build_tx_request_header(
133 this->manager->destinationLogicalAddress,
134 this->manager->destinationKey,
135 this->manager->sourceLogicalAddress,
136 transactionID,
137 address+(written*4),
138 RMAP_MAX_XFER_SIZE*4,
139 writeBuffer);
140 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4));
141 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
142 free(RMAPAckBuff);
143 written+=RMAP_MAX_XFER_SIZE;
144 count-=RMAP_MAX_XFER_SIZE;
145 progress->setValue(written);
146 qApp->processEvents();
147 }
148 if(count>0)
149 {
150 for(int i=0;i<((int)count);i++)
151 {
152 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
153 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
154 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
155 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
156 }
157 transactionID=manager->getRMAPtransactionID();
158 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
159 RMAP_build_tx_request_header(
160 this->manager->destinationLogicalAddress,
161 this->manager->destinationKey,
162 this->manager->sourceLogicalAddress,
163 transactionID,
164 address+(written*4),
165 count*4,
166 writeBuffer);
167 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4));
168 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
169 free(RMAPAckBuff);
170 written+=count;
171 if(progress!=NULL)
172 {
173 progress->setValue(written);
174 qApp->processEvents();
175 }
176 }
177 return written;
113 178 }
114 179
115 180 unsigned int GR_ESB_bridge::Read(unsigned int *Value, unsigned int count, unsigned int address)
116 181 {
117 // TODO write ME!
118 Q_UNUSED(Value)
119 Q_UNUSED(count)
120 Q_UNUSED(address)
121 return 0;
182 char requestBuffer[RMAP_READ_HEADER_MIN_SZ];
183 char* RMAP_AnswerBuffer;
184 requestBuffer[0]=this->manager->linkNumber;//Link number
185 int transactionID = 0;
186 int read=0;
187 QProgressBar* progress=NULL;
188 SocExplorerAutoProgressBar autopb;
189 if(count>RMAP_MAX_XFER_SIZE)
190 {
191 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
192 autopb.setProgressBar(progress);
193 }
194 SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2);
195
196 //Quite stupide loop, I guess that I always get the number of byte I asked for!
197 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
198 {
199 transactionID = manager->getRMAPtransactionID();
200 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
201 RMAP_build_rx_request_header(
202 this->manager->destinationLogicalAddress,
203 this->manager->destinationKey,
204 this->manager->sourceLogicalAddress,
205 transactionID,
206 address+(read*4),
207 RMAP_MAX_XFER_SIZE*4,
208 requestBuffer);
209 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
210 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
211 if(len==-1)
212 {
213 this->toggleBridgeConnection();
214 return 0;
215 }
216 for(int i=0;i<((len-13)/4);i++)
217 {
218 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
219 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
220 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
221 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
222 }
223 free(RMAP_AnswerBuffer);
224 read+=RMAP_MAX_XFER_SIZE;
225 count-=RMAP_MAX_XFER_SIZE;
226 progress->setValue(read);
227 qApp->processEvents();
228 }
229 if((int)count>0)
230 {
231 transactionID = manager->getRMAPtransactionID();
232 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
233 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
234 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
235 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
236 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
237 RMAP_build_rx_request_header(
238 this->manager->destinationLogicalAddress,
239 this->manager->destinationKey,
240 this->manager->sourceLogicalAddress,
241 transactionID,
242 address+(read*4),
243 count*4,
244 requestBuffer);
245 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
246 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
247 if(len==-1)
248 {
249 this->toggleBridgeConnection();
250 return 0;
251 }
252 for(int i=0;i<((len-13)/4);i++)
253 {
254 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
255 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
256 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
257 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
258 }
259 free(RMAP_AnswerBuffer);
260 read+=count;
261 if(progress!=NULL)
262 {
263 progress->setValue(read);
264 qApp->processEvents();
265 }
266 }
267 return read;
122 268 }
123 269
124 270 int GR_ESB_bridge::pushRMAPPacket(char *packet, int size)
125 271 {
126 272 return this->manager->sendPacket(packet,size);
127 273 }
128 274
129 275
130 276 GR_ESB_Manager::GR_ESB_Manager(socexplorerplugin *plugin, QObject *parent)
131 :QThread((QObject*)parent)
277 :abstractSpwManager(plugin, parent)
132 278 {
133 279 this->Read_soc = new QTcpSocket(this);
134 280 this->Write_soc = new QTcpSocket(this);
135 this->RMAPtimeout = 2000;
136 this->handleMutex = new QMutex(QMutex::NonRecursive);
137 this->RMAP_AnswersSem = new QSemaphore(0);
138 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
139 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
140 this->plugin = plugin;
141 connected = false;
142 this->moveToThread(this);
143 281 }
144 282
145 283 GR_ESB_Manager::~GR_ESB_Manager()
146 284 {
147
148 285 }
149 286
150 287 void GR_ESB_Manager::run()
151 288 {
289 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
152 290 SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1);
153 291 while (!this->isInterruptionRequested())
154 292 {
155 293 if(this->connected)
156 294 {
157 295 handleMutex->lock();
158 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4);
296 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",5);
297 if(Read_soc->waitForReadyRead(100))
298 {
299 QByteArray data = Read_soc->readAll();
300 int PacketLen= ((int)data.at(2)& 0x0FF) + (((int)data.at(3)& 0x0FF)<<8) + (((int)data.at(4)& 0x0FF)<<16);
301 if(data[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
302 {
303 RMAP_Answer* packet;
304 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
305 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(PacketLen),2);
306 char* packetbuffer = (char*)malloc(PacketLen);
307 memcpy(packetbuffer,data.data(),PacketLen);
308 this->handleMutex->unlock();
309 if(PacketLen==8)
310 {
311 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,PacketLen);
312 }
313 else
314 {
315 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,PacketLen);
316 }
317 RMAP_AnswersMtx->lock();
318 RMAP_Answers.append(packet);
319 RMAP_AnswersMtx->unlock();
320 RMAP_AnswersSem->release();
321 }
322 else //any non-rmap packet will be pushed to the network
323 {
324 char* packetbuffer = (char*)malloc(PacketLen);
325 memcpy(packetbuffer,data.data(),PacketLen);
326 emit emitPacket(packetbuffer,PacketLen);
327 this->handleMutex->unlock();
328 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
329 }
330
331 }
332 else
333 {
334 handleMutex->unlock();
335 }
159 336
160 337 }
161 338 else
162 339 {
163 340 //do some sanity checks!
164 341
165 342 usleep(RMAPtimeout/2);
166 343 }
167 344 usleep(1000);
168 345 }
169 346 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
170 347 }
171 348
172 349 bool GR_ESB_Manager::connectBridge()
173 350 {
174 351 int timeout=60;
175 352 if(this->Read_soc->state()==QTcpSocket::UnconnectedState)
176 353 {
177 354 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Read_port);
178 355 this->Read_soc->waitForConnected(30000);
179 356 }
180 357 if(this->Write_soc->state()==QTcpSocket::UnconnectedState)
181 358 {
182 359 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Write_port);
183 360 this->Write_soc->waitForConnected(30000);
184 361 }
185 362 while((this->Read_soc->state()!=QTcpSocket::ConnectedState) && (this->Write_soc->state()!=QTcpSocket::ConnectedState))
186 363 {
187 364 usleep(100000);
188 365 if(timeout--==0)return false;
189 366 }
190 367 return true;
191 368
192 369 }
193 370
194 371 bool GR_ESB_Manager::disconnectBridge()
195 372 {
196 373 int timeout=60;
197 374 if(this->Read_soc->state()!=QTcpSocket::UnconnectedState)
198 375 {
199 376 this->Read_soc->disconnectFromHost();
200 377 this->Read_soc->waitForDisconnected(30000);
201 378 }
202 379 if(this->Write_soc->state()!=QTcpSocket::UnconnectedState)
203 380 {
204 381 this->Write_soc->disconnectFromHost();
205 382 this->Write_soc->waitForDisconnected(30000);
206 383 }
207 384 while((this->Read_soc->state()!=QTcpSocket::UnconnectedState) && (this->Write_soc->state()!=QTcpSocket::UnconnectedState))
208 385 {
209 386 usleep(100000);
210 387 if(timeout--==0)return false;
211 388 }
212 389 return true;
213 390 }
214 391
215 int GR_ESB_Manager::getRMAPtransactionID()
216 {
217 // TODO write ME!
218 return -1;
219 }
220
221 int GR_ESB_Manager::getRMAPanswer(int transactionID, char **buffer)
222 {
223 // TODO write ME!
224 Q_UNUSED(transactionID)
225 Q_UNUSED(buffer)
226 return -1;
227 }
228 392
229 393 bool GR_ESB_Manager::sendPacket(char *packet, int size)
230 394 {
231 // TODO write ME!
232 Q_UNUSED(packet)
233 Q_UNUSED(size)
234 return false;
395 bool result = false;
396 char protocoleIdentifier;
397 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
398 if(Q_UNLIKELY(this->Write_soc->state()!=QAbstractSocket::ConnectedState))
399 {
400 SocExplorerEngine::message(this->plugin,"Socket closed",2);
401 //TODO handle disconnection
402 }
403 char* SPWpacket = (char*)malloc(size+4);
404 if(SPWpacket!=NULL)
405 {
406 SPWpacket[0]=0; //Protocol = spw
407 memcpy(SPWpacket+4,packet,size);
408 SPWpacket[1]=size & 0x0FF;
409 SPWpacket[2]=(size>>8) & 0x0FF;
410 SPWpacket[3]=(size>>16) & 0x0FF;
411 }
412 this->handleMutex->lock();
413 result = ((size+4) == this->Write_soc->write(SPWpacket,size+4));
414 this->handleMutex->unlock();
415 if (Q_UNLIKELY(!result))
416 {
417 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
418 return false;
419 }
420 else
421 {
422 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
423 // read the protocole identifier
424 protocoleIdentifier = packet[2];
425 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
426 emit ccsdsPacketTransmittedToSpw();
427 SocExplorerEngine::message(this->plugin,"Packet sent",2);
428 }
429 return true;
235 430 }
236 431
237 void GR_ESB_Manager::pushRmapPacket(char *packet, int len)
238 {
239 // TODO write ME!
240 Q_UNUSED(packet)
241 Q_UNUSED(len)
242 }
@@ -1,88 +1,79
1 1 #ifndef GR_ESB_BRIDGE_H
2 2 #define GR_ESB_BRIDGE_H
3 3 #include "abstractspwbridge.h"
4 4 #include <QTcpSocket>
5 5 #include <QThread>
6 6 #include <QMutex>
7 7 #include <QSemaphore>
8 8
9 9 struct gresb_Conf_str
10 10 {
11 11 qint32 Read_port;
12 12 qint32 Write_port;
13 13 };
14 14
15 15
16 16 const struct gresb_Conf_str gresb_Conf[]=
17 17 {
18 18 {3000,3001}, //Virtual link 0
19 19 {3002,3003}, //Virtual link 1
20 20 {3004,3005}, //Virtual link 2
21 21 {3006,3007}, //Virtual link 3
22 22 {3008,3009}, //Virtual link 4
23 23 {3010,3011} //Virtual link 5
24 24 };
25 25
26 26
27 class GR_ESB_Manager: public QThread
27 class GR_ESB_Manager: public abstractSpwManager
28 28 {
29 29 Q_OBJECT
30 30 public:
31 31 explicit GR_ESB_Manager(socexplorerplugin *plugin = 0,QObject* parent=0);
32 32 ~GR_ESB_Manager();
33 33 void run();
34 34 bool connectBridge();
35 35 bool disconnectBridge();
36 int getRMAPtransactionID();
37 int getRMAPanswer(int transactionID,char** buffer);
38 36 bool sendPacket(char* packet,int size);
39 37
40 38 signals:
41 39 void emitPacket(char* packet,int size);
42 40 private:
43 QMutex* handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx;
44 QSemaphore* RMAP_AnswersSem;
45 41 void pushRmapPacket(char* packet,int len);
46 socexplorerplugin* plugin;
47 bool connected;
48 42 char* SPWPacketBuff;
49 QList<RMAP_Answer*> RMAP_Answers;
50 QList<int> RMAP_pending_transaction_IDs;
51 43
52 44 public:
53 45 QTcpSocket* Read_soc;
54 46 QTcpSocket* Write_soc;
55 47 QString IP;
56 48 int virtualLinkIndex;
57 int RMAPtimeout;
58 49 };
59 50
60 51
61 52 class GR_ESB_bridge : public abstractSpwBridge
62 53 {
63 54 Q_OBJECT
64 55 public:
65 56 explicit GR_ESB_bridge(socexplorerplugin *parent = 0);
66 57 ~GR_ESB_bridge();
67 58 signals:
68 59
69 60
70 61 public slots:
71 62 void toggleBridgeConnection();
72 63 bool connectBridge();
73 64 bool disconnectBridge();
74 65 void setIP(QString ip);
75 66 void setVirtualLink(QString vlink);
76 67 void setVirtualLink(qint32 vlink);
77 68 unsigned int Write(unsigned int *Value,unsigned int count, unsigned int address=0);
78 69 unsigned int Read(unsigned int *Value,unsigned int count, unsigned int address=0);
79 70 int pushRMAPPacket(char* packet,int size);
80 71 void packetReceived();
81 72
82 73 private:
83 74
84 75 GR_ESB_Manager* manager;
85 76
86 77 };
87 78
88 79 #endif // GR_ESB_BRIDGE_H
@@ -1,1108 +1,1009
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22
23 23 #include "stardundeespw_usb.h"
24 24 #include "fakestardundeespwusb_lib.h"
25 25 #include <socexplorerengine.h>
26 26 #include <qhexedit.h>
27 27
28 28 const QString dwLinkStatusQString[6] = {
29 29 "CFG_SPACEWIRE_ERROR_RESET",
30 30 "CFG_SPACEWIRE_ERROR_WAIT",
31 31 "CFG_SPACEWIRE_READY",
32 32 "CFG_SPACEWIRE_STARTED",
33 33 "CFG_SPACEWIRE_CONNECTING",
34 34 "CFG_SPACEWIRE_RUN"
35 35 };
36 36
37 37 stardundeeSPW_USB::stardundeeSPW_USB(socexplorerplugin *parent) :
38 38 abstractSpwBridge(parent)
39 39 {
40 40 Q_UNUSED(parent)
41 41 this->manager = new stardundeeSPW_USB_Manager(parent,this);
42 42 makeGUI(parent);
43 this->manager->start();
44 43 connect(this->manager,SIGNAL(emitPacket(char*,int)),this,SIGNAL(pushPacketOverTCP(char*,int)));
45 44 connect(this->manager, SIGNAL(bytesReceivedFromSpw(uint)), this, SIGNAL(BytesReceivedFromSpw(uint)));
46 45 connect(this->manager, SIGNAL(bytesTransmittedToSpw(uint)), this, SIGNAL(BytesTransmittedToSpw(uint)));
47 46 connect(this->manager, SIGNAL(ccsdsPacketTransmittedToSpw()), this, SIGNAL(CCSDSPacketTransmittedToSpw()));
47 this->manager->start();
48 48 }
49 49
50 50 stardundeeSPW_USB::~stardundeeSPW_USB()
51 51 {
52 52 this->manager->requestInterruption();
53 53 while(this->manager->isRunning());
54 54 }
55 55
56 56 void stardundeeSPW_USB::toggleBridgeConnection()
57 57 {
58 58 if(this->plugin->isConnected())
59 59 {
60 60 this->disconnectBridge();
61 61 }
62 62 else
63 63 {
64 64 this->connectBridge();
65 65 }
66 66 }
67 67
68 68 bool stardundeeSPW_USB::connectBridge()
69 69 {
70 70 if(this->manager->connectBridge())
71 71 {
72 72 this->timecodeFrequencyChanged( ((StarDundeeGUI*)this->p_GUI)->getTimecodeFrequency());
73 73 this->startSendingTimecodes( ((StarDundeeGUI*)this->p_GUI)->getStartSendingTimecodes());
74 74 ((StarDundeeGUI*)this->p_GUI)->lock(true);
75 75 emit setConnected(true);
76 76 return true;
77 77 }
78 78 return false;
79 79 }
80 80
81 81 bool stardundeeSPW_USB::disconnectBridge()
82 82 {
83 83 if(this->manager->disconnectBridge())
84 84 {
85 85 ((StarDundeeGUI*)this->p_GUI)->lock(false);
86 86 emit setConnected(false);
87 87 return true;
88 88 }
89 89 return false;
90 90 }
91 91
92 92 int stardundeeSPW_USB::pushRMAPPacket(char *packet, int size)
93 93 {
94 94 return this->manager->sendPacket(packet,size);
95 95 }
96 96
97 97 unsigned int stardundeeSPW_USB::Write(unsigned int *Value, unsigned int count, unsigned int address)
98 98 {
99 99 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))+1];
100 100 char *RMAPAckBuff;
101 101 writeBuffer[0]=this->manager->linkNumber;//Link number
102 102 int transactionID = 0;
103 103 int written=0;
104 104 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
105 105 QProgressBar* progress=NULL;
106 106 SocExplorerAutoProgressBar autopb;
107 107 if(count>RMAP_MAX_XFER_SIZE)
108 108 {
109 109 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
110 110 autopb.setProgressBar(progress);
111 111 }
112 112 //Quite stupide loop, I guess that I always get the number of byte I asked for!
113 113 while(count>=RMAP_MAX_XFER_SIZE)
114 114 {
115 115 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
116 116 {
117 117 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
118 118 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
119 119 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
120 120 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
121 121 }
122 122 transactionID=manager->getRMAPtransactionID();
123 123 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
124 124 RMAP_build_tx_request_header(
125 125 this->manager->destinationLogicalAddress,
126 126 this->manager->destinationKey,
127 127 this->manager->sourceLogicalAddress,
128 128 transactionID,
129 129 address+(written*4),
130 130 RMAP_MAX_XFER_SIZE*4,
131 131 writeBuffer+1);
132 132 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4)+1);
133 133 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
134 134 free(RMAPAckBuff);
135 135 written+=RMAP_MAX_XFER_SIZE;
136 136 count-=RMAP_MAX_XFER_SIZE;
137 137 progress->setValue(written);
138 138 qApp->processEvents();
139 139 }
140 140 if(count>0)
141 141 {
142 142 for(int i=0;i<((int)count);i++)
143 143 {
144 144 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
145 145 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
146 146 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
147 147 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
148 148 }
149 149 transactionID=manager->getRMAPtransactionID();
150 150 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
151 151 RMAP_build_tx_request_header(
152 152 this->manager->destinationLogicalAddress,
153 153 this->manager->destinationKey,
154 154 this->manager->sourceLogicalAddress,
155 155 transactionID,
156 156 address+(written*4),
157 157 count*4,
158 158 writeBuffer+1);
159 159 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4) +1);
160 160 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
161 161 free(RMAPAckBuff);
162 162 written+=count;
163 163 if(progress!=NULL)
164 164 {
165 165 progress->setValue(written);
166 166 qApp->processEvents();
167 167 }
168 168 }
169 169 return written;
170 170 }
171 171
172 172 unsigned int stardundeeSPW_USB::Read(unsigned int *Value, unsigned int count, unsigned int address)
173 173 {
174 174 char requestBuffer[RMAP_READ_HEADER_MIN_SZ+1];
175 175 char* RMAP_AnswerBuffer;
176 176 requestBuffer[0]=this->manager->linkNumber;//Link number
177 177 int transactionID = 0;
178 178 int read=0;
179 179 QProgressBar* progress=NULL;
180 180 SocExplorerAutoProgressBar autopb;
181 181 if(count>RMAP_MAX_XFER_SIZE)
182 182 {
183 183 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
184 184 autopb.setProgressBar(progress);
185 185 }
186 186 SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2);
187 187
188 188 //Quite stupide loop, I guess that I always get the number of byte I asked for!
189 189 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
190 190 {
191 191 transactionID = manager->getRMAPtransactionID();
192 192 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
193 193 RMAP_build_rx_request_header(
194 194 this->manager->destinationLogicalAddress,
195 195 this->manager->destinationKey,
196 196 this->manager->sourceLogicalAddress,
197 197 transactionID,
198 198 address+(read*4),
199 199 RMAP_MAX_XFER_SIZE*4,
200 200 requestBuffer+1);
201 201 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
202 202 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
203 203 if(len==-1)
204 204 {
205 205 this->toggleBridgeConnection();
206 206 return 0;
207 207 }
208 208 for(int i=0;i<((len-13)/4);i++)
209 209 {
210 210 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
211 211 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
212 212 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
213 213 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
214 214 }
215 215 free(RMAP_AnswerBuffer);
216 216 read+=RMAP_MAX_XFER_SIZE;
217 217 count-=RMAP_MAX_XFER_SIZE;
218 218 progress->setValue(read);
219 219 qApp->processEvents();
220 220 }
221 221 if((int)count>0)
222 222 {
223 223 transactionID = manager->getRMAPtransactionID();
224 224 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
225 225 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
226 226 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
227 227 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
228 228 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
229 229 RMAP_build_rx_request_header(
230 230 this->manager->destinationLogicalAddress,
231 231 this->manager->destinationKey,
232 232 this->manager->sourceLogicalAddress,
233 233 transactionID,
234 234 address+(read*4),
235 235 count*4,
236 236 requestBuffer+1);
237 237 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
238 238 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
239 239 if(len==-1)
240 240 {
241 241 this->toggleBridgeConnection();
242 242 return 0;
243 243 }
244 244 for(int i=0;i<((len-13)/4);i++)
245 245 {
246 246 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
247 247 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
248 248 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
249 249 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
250 250 }
251 251 free(RMAP_AnswerBuffer);
252 252 read+=count;
253 253 if(progress!=NULL)
254 254 {
255 255 progress->setValue(read);
256 256 qApp->processEvents();
257 257 }
258 258 }
259 259 return read;
260 260 }
261 261
262 262 void stardundeeSPW_USB::brickSelectionChanged(int brickIndex)
263 263 {
264 264 this->manager->selectedBrick = brickIndex-1;
265 265 SocExplorerEngine::message(plugin,QString("Changing brick index: %1").arg(manager->selectedBrick),1);
266 266 }
267 267
268 268 void stardundeeSPW_USB::linkNumberSelectionChanged(int linkIndex)
269 269 {
270 270 this->manager->linkNumber = linkIndex + 1;
271 271 SocExplorerEngine::message(plugin,QString("Changing Link Number: %1").arg(manager->linkNumber),1);
272 272 }
273 273
274 274 void stardundeeSPW_USB::linkSpeedSelectionChanged(const QString &linkSpeed)
275 275 {
276 276 this->manager->linkSpeed = linkSpeed.toInt();
277 277
278 278 SocExplorerEngine::message(plugin,QString("Changing Link Speed: %1").arg(manager->linkSpeed),1);
279 279 }
280 280
281 281 void stardundeeSPW_USB::sourceLogicalAddressChanged(const QString &sourceAddress)
282 282 {
283 283 this->manager->sourceLogicalAddress = sourceAddress.toInt();
284 284 SocExplorerEngine::message(plugin,QString("Changing Destination Key: %1").arg(manager->sourceLogicalAddress),1);
285 285 }
286 286
287 287 void stardundeeSPW_USB::destinationAddressChanged(const QString &rmapaddress)
288 288 {
289 289 this->manager->destinationLogicalAddress = rmapaddress.toInt();
290 290 SocExplorerEngine::message(plugin,QString("Changing RMAP address: %1").arg(manager->destinationLogicalAddress),1);
291 291 }
292 292
293 293 void stardundeeSPW_USB::destinationKeyChanged(const QString &key)
294 294 {
295 295 this->manager->destinationKey = key.toInt();
296 296 SocExplorerEngine::message(plugin,QString("Changing RMAP Key: %1").arg(manager->destinationKey),1);
297 297 }
298 298
299 299 void stardundeeSPW_USB::brickModeChanged( bool interfaceMode )
300 300 {
301 301 this->manager->interfaceMode = interfaceMode;
302 302 }
303 303
304 304 void stardundeeSPW_USB::timecodeFrequencyChanged(const QString &frequency)
305 305 {
306 306 this->manager->timecodeFrequency = frequency.toDouble();
307 307 this->manager->setTimecodeFrequency( this->manager->timecodeFrequency);
308 308 SocExplorerEngine::message(plugin,QString("Changing timecode frequency: %1").arg(manager->timecodeFrequency),1);
309 309 }
310 310
311 311 void stardundeeSPW_USB::startSendingTimecodes(bool onOff )
312 312 {
313 313 this->manager->sendTimecodePeriodically( onOff );
314 314 }
315 315
316 316 void stardundeeSPW_USB::rmapTimeoutChanged(const QString &timeout)
317 317 {
318 318 int tim=timeout.toInt();
319 319 if(tim<50)
320 320 {
321 321 tim = 50;
322 322 ((StarDundeeGUI*)this->p_GUI)->setRmapTimeout(QString("%1").arg(tim));
323 323 }
324 324 this->manager->RMAPtimeout = tim;
325 325 SocExplorerEngine::message(plugin,QString("Changing RMAP Timeout: %1").arg(manager->RMAPtimeout),1);
326 326 }
327 327
328 328 void stardundeeSPW_USB::makeGUI(socexplorerplugin *parent)
329 329 {
330 330 Q_UNUSED(parent)
331 331 this->p_GUI = new StarDundeeGUI();
332 332 // this->mainLayout = new QGridLayout(this->p_GUI);
333 333 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(connectClicked()),this,SLOT(toggleBridgeConnection()));
334 334 connect(this->manager,SIGNAL(updateAvailableBrickCount(int)),((StarDundeeGUI*)this->p_GUI),SLOT(updateAvailableBrickCount(int)));
335 335 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickSelectionChanged(int)),this,SLOT(brickSelectionChanged(int)));
336 336 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkNumberSelectionChanged(int)),this,SLOT(linkNumberSelectionChanged(int)));
337 337 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkSpeedSelectionChanged(QString)),this,SLOT(linkSpeedSelectionChanged(QString)));
338 338 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(sourceLogicalAddressChanged(QString)),this,SLOT(sourceLogicalAddressChanged(QString)));
339 339 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapAddressChanged(QString)),this,SLOT(destinationAddressChanged(QString)));
340 340 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(destinationKeyChanged(QString)),this,SLOT(destinationKeyChanged(QString)));
341 341 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapTimeoutChanged(QString)),this,SLOT(rmapTimeoutChanged(QString)));
342 342 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickModeChanged(bool)), this, SLOT(brickModeChanged(bool)));
343 343 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(timecodeFrequencyChange(QString)), this, SLOT(timecodeFrequencyChanged(QString)));
344 344 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(startSendingTimecode(bool)), this, SLOT(startSendingTimecodes(bool)));
345 345
346 346 this->brickSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getBrickSelection());
347 347 this->linkNumberSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkNumberSelection());
348 348 this->linkSpeedSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkSpeedSelection());
349 349 this->sourceLogicalAddressChanged(((StarDundeeGUI*)this->p_GUI)->getSourceAddress());
350 350 this->destinationAddressChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationAddress());
351 351 this->destinationKeyChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationKey());
352 352 this->rmapTimeoutChanged( ((StarDundeeGUI*)this->p_GUI)->getRmapTimeout());
353 353 this->brickModeChanged( ((StarDundeeGUI*)this->p_GUI)->isBrickSetAsAnInterface());
354 354
355 355 connect(this,SIGNAL(SelectBrick(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectBrick(int)));
356 356 connect(this,SIGNAL(SelectLinkNumber(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkNumber(int)));
357 357 connect(this,SIGNAL(SelectLinkSpeed(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkSpeed(int)));
358 358 connect(this,SIGNAL(SetDestinationKey(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationKey(QString)));
359 359 connect(this,SIGNAL(SetDestinationAddress(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationAddress(QString)));
360 360 connect(this,SIGNAL(SetSourceAddress(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setSourceAddress(QString)));
361 361 connect(this,SIGNAL(SetRmapTimeout(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setRmapTimeout(QString)));
362 362 connect(this,SIGNAL(GetAvailableBrickCount()), ((StarDundeeGUI*)this->p_GUI),SLOT(getAvailableBrickCount()));
363 363 connect(this,SIGNAL(GetNbPacketsTransmittedToSpw()),((StarDundeeGUI*)this->p_GUI),SLOT(getNbPacketsTransmittedToSpw()));
364 364 connect(this,SIGNAL(GetNbCCSDSPacketsTransmittedToSpw()),
365 365 ((StarDundeeGUI*)this->p_GUI),SLOT(getNbCCSDSPacketsTransmittedToSpw()));
366 366 connect(this,SIGNAL(SetBrickAsAnInterface(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsAnInterface(bool)));
367 367 connect(this,SIGNAL(SetBrickAsARouter(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsARouter(bool)));
368 368 connect(this,SIGNAL(BytesReceivedFromSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbReceivedBytesFromSpw(uint)));
369 369 connect(this,SIGNAL(BytesTransmittedToSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbTransmittedBytesToSpw(uint)));
370 370 connect(this,SIGNAL(CCSDSPacketTransmittedToSpw()), ((StarDundeeGUI*)this->p_GUI),SLOT(updateCCSDSPacketTransmittedToSpw()));
371 371 connect(this,SIGNAL(SetTimecodeFrequency(double)), ((StarDundeeGUI*)this->p_GUI),SLOT(setTimecodeFrequency(double)));
372 372 connect(this,SIGNAL(StartSendingTimecodes(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setStartSendingTimecodes(bool)));
373 373
374 374 connect(this,SIGNAL(SendOneTimecode(unsigned char)),this->manager, SLOT(sendOneTimecode(unsigned char)));
375 375 connect(this,SIGNAL(GetLinkNumber()), this->manager, SLOT(getLinkNumber()));
376 376 }
377 377
378 378 void stardundeeSPW_USB::sendPacketComingFromTCPServer(char *packet, int size)
379 379 {
380 380 char* data;
381 381 int i;
382 382
383 383 data = (char *) malloc( size + 5 );
384 384
385 385 data[0] = this->manager->linkNumber;
386 386 data[1] = this->manager->destinationLogicalAddress; // target logical address
387 387 data[2] = SPW_PROTO_ID_CCSDS; // protocol identifier
388 388 data[3] = 0x00; // reserved
389 389 data[4] = 0x00; // user application
390 390
391 391 for ( i=0; i<size; i++ )
392 392 {
393 393 data[i+5] = packet[i];
394 394 }
395 395
396 396 this->manager->sendPacket( data, size + 5);
397 397
398 398 free(data);
399 399 free(packet);
400 400 }
401 401
402 402 stardundeeSPW_USB_Manager::stardundeeSPW_USB_Manager(socexplorerplugin *plugin, QObject *parent)
403 :QThread((QObject*)parent)
403 :abstractSpwManager(plugin, parent)
404 404 {
405 this->RMAPtimeout = 2000;
406 this->handleMutex = new QMutex(QMutex::NonRecursive);
407 // this->handleMutex = new QMutex(QMutex::Recursive);
408 this->RMAP_AnswersSem = new QSemaphore(0);
409 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
410 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
411 this->plugin = plugin;
412 connected = false;
413 405 // TODO remove this crap!
414 406 this->initDialog();
415 407 // this->moveToThread(this);
416 408 }
417 409
418 410 stardundeeSPW_USB_Manager::~stardundeeSPW_USB_Manager()
419 411 {
420 this->terminate();
421 while (!this->isFinished()) {
422 this->usleep(1000);
423 }
424 412 }
425 413
426 414 void stardundeeSPW_USB_Manager::run()
427 415 {
428 416 USB_SPACEWIRE_PACKET_PROPERTIES properties;
429 417 USB_SPACEWIRE_ID pIdentifier=NULL;
430 418 USB_SPACEWIRE_STATUS stat;
431 419 SocExplorerEngine::message(this->plugin,"Starting Startdundee USB pooling thread",1);
432 420 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
433 421 while (!this->isInterruptionRequested())
434 422 {
435 423 if(this->connected)
436 424 {
437 425 this->handleMutex->lock();
438 426 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4);
439 427 if(USBSpaceWire_WaitOnReadPacketAvailable(hDevice,0.01))
440 428 {
441 429 SocExplorerEngine::message(this->plugin,"Got packet",2);
442 430 stat = USBSpaceWire_ReadPackets(hDevice, buffer, (RMAP_MAX_XFER_SIZE*4)+50,1, 1, &properties, &pIdentifier);
443 431 if (stat == TRANSFER_SUCCESS)
444 432 {
445 433 if(USBSpaceWire_GetReadTrafficType(&properties, 0) ==SPACEWIRE_TRAFFIC_PACKET)
446 434 {
447 435 SocExplorerEngine::message(this->plugin,"It's a SPW packet",2);
448 436 if(USBSpaceWire_GetReadEOPStatus(&properties, 0)== SPACEWIRE_USB_EOP)
449 437 {
450 438 SocExplorerEngine::message(this->plugin,"Got end of packet",2);
451 439 emit bytesReceivedFromSpw( properties.len );
452 440 if(buffer[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
453 441 {
454 442 RMAP_Answer* packet;
455 443 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
456 444 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(properties.len),2);
457 445 char* packetbuffer = (char*)malloc(properties.len);
458 446 memcpy(packetbuffer,buffer,properties.len);
459 447 USBSpaceWire_FreeRead(hDevice, pIdentifier);
460 448 pIdentifier = NULL;
461 449 this->handleMutex->unlock();
462 450 if(properties.len==8)
463 451 {
464 452 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,properties.len);
465 453 }
466 454 else
467 455 {
468 456 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,properties.len);
469 457 }
470 458 RMAP_AnswersMtx->lock();
471 459 RMAP_Answers.append(packet);
472 460 RMAP_AnswersMtx->unlock();
473 461 RMAP_AnswersSem->release();
474 462 }
475 463 else //any non-rmap packet will be pushed to the network
476 464 {
477 465 char* packetbuffer = (char*)malloc(properties.len);
478 466 memcpy(packetbuffer,buffer,properties.len);
479 467 emit emitPacket(packetbuffer,properties.len);
480 468 USBSpaceWire_FreeRead(hDevice, pIdentifier);
481 469 this->handleMutex->unlock();
482 470 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
483 471 }
484 472 }
485 473 else
486 474 {
487 475 SocExplorerEngine::message(this->plugin,"No EOP received",2);
488 476 this->handleMutex->unlock();
489 477 }
490 478 }
491 479
492 480 }
493 481 else
494 482 {
495 483 USBSpaceWire_FreeRead(hDevice, pIdentifier);
496 484 this->handleMutex->unlock();
497 485 }
498 486 }
499 487 else
500 488 {
501 489 USBSpaceWire_FreeRead(hDevice, pIdentifier);
502 490 this->handleMutex->unlock();
503 491 }
504 492 }
505 493 else
506 494 {
507 495 //do some sanity checks!
508 496 int list = USBSpaceWire_ListDevices();
509 497 if(this->brickList!=list)
510 498 {
511 499 this->brickList = list;
512 500 emit updateAvailableBrickCount(this->brickList);
513 501 }
514 502 usleep(RMAPtimeout/2);
515 503 }
516 504 usleep(1000);
517 505 }
518 506 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
519 507 }
520 508
521 509 bool stardundeeSPW_USB_Manager::connectBridge()
522 510 {
523 511 bool ret;
524 512
525 513 if (this->interfaceMode == BRICK_IS_SET_AS_AN_INTERFACE)
526 514 {
527 515 ret = connectBridgeAsInterface();
528 516 }
529 517 else if (this->interfaceMode == BRICK_IS_SET_AS_A_ROUTER)
530 518 {
531 519 ret = connectBridgeAsRouter();
532 520 }
533 521 else
534 522 {
535 523 ret = false;
536 524 }
537 525
538 526 return ret;
539 527 }
540 528
541 529 bool stardundeeSPW_USB_Manager::connectBridgeAsInterface()
542 530 {
543 531 this->handleMutex->lock();
544 532 int status;
545 533 U32 statusControl;
546 534 this->connected = false;
547 535 if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
548 536 {
549 537 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))",0);
550 538 this->handleMutex->unlock();
551 539 return false;
552 540 }
553 541 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful",0);
554 542
555 543 USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode
556 544 CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration
557 545 CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices
558 546
559 547 // Set the path and return path to the device
560 548 CFGSpaceWire_StackClear();
561 549 CFGSpaceWire_AddrStackPush(0);
562 550 CFGSpaceWire_AddrStackPush(254);
563 551 CFGSpaceWire_RetAddrStackPush(254);
564 552 // set the base transmit rate to 100 MHz
565 553 status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff);
566 554 if (status != CFG_TRANSFER_SUCCESS)
567 555 {
568 556 SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate",1);
569 557 this->handleMutex->unlock();
570 558 return false;
571 559 }
572 560 else
573 561 {
574 562 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz",1);
575 563 }
576 564
577 565 // read the link status
578 566 if (CFGSpaceWire_GetLinkStatusControl(hDevice, this->linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
579 567 {
580 568 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(this->linkNumber),1);
581 569 this->handleMutex->unlock();
582 570 return false;
583 571 }
584 572 else
585 573 {
586 574 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(this->linkNumber),1);
587 575
588 576 // Set the link status control register properties
589 577 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
590 578 CFGSpaceWire_LSEnableStart(&statusControl, 1);
591 579 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
592 580 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
593 581 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
594 582
595 583 // Set the link status control register
596 584 if (CFGSpaceWire_SetLinkStatusControl(hDevice, this->linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
597 585 {
598 586 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(this->linkNumber),1);
599 587 this->handleMutex->unlock();
600 588 return false;
601 589 }
602 590 else
603 591 {
604 592 SocExplorerEngine::message(this->plugin,"Set the link status control for link " + QString::number(this->linkNumber),1);
605 593 }
606 594 }
607 595
608 596 if (CFGSpaceWire_SetAsInterface(hDevice, 1, 0) != CFG_TRANSFER_SUCCESS)
609 597 {
610 598 SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface",1);
611 599 this->handleMutex->unlock();
612 600 return false;
613 601 }
614 602 else
615 603 {
616 604 SocExplorerEngine::message(this->plugin,"Device set to be an interface",1);
617 605 }
618 606
619 607 USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports
620 608 USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
621 609 USBSpaceWire_SetTimeout(hDevice,1.0);
622 610 this->handleMutex->unlock();
623 611 SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes",1);
624 612 SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes",1);
625 613 SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)),1);
626 614 this->connected = true;
627 615 return true;
628 616 }
629 617
630 618 bool stardundeeSPW_USB_Manager::connectBridgeAsRouter()
631 619 {
632 620 // QMutexLocker mlock(&this->handleMutex);
633 621 this->handleMutex->lock();
634 622 int status;
635 623 U32 statusControl;
636 624 unsigned int linkStatus1;
637 625 unsigned int linkStatus2;
638 626 unsigned char linkNumber;
639 627 unsigned char deviceIsAnInterface;
640 628
641 629 if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
642 630 {
643 631 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))");
644 632 this->handleMutex->unlock();
645 633 return false;
646 634 }
647 635 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful, device number: "
648 636 + QString::number(this->selectedBrick));
649 637
650 638 USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode
651 639 CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration
652 640 CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices
653 641
654 642 // Set the path and return path to the device
655 643 // This affects just the operations performed by the Configuration Library and does not affect the packets
656 644 // sent and received using the driver API.
657 645 CFGSpaceWire_StackClear();
658 646 CFGSpaceWire_AddrStackPush(0);
659 647 CFGSpaceWire_AddrStackPush(254);
660 648 CFGSpaceWire_RetAddrStackPush(254);
661 649
662 650 // set the base transmit rate to 100 MHz
663 651 status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff);
664 652 if (status != CFG_TRANSFER_SUCCESS)
665 653 {
666 654 SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate");
667 655 }
668 656 else SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz");
669 657
670 658 //*********************
671 659 // LINK 1 CONFIGURATION
672 660 linkNumber = 1;
673 661 if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
674 662 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
675 663 else
676 664 {
677 665 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber));
678 666
679 667 // Set the link status control register properties
680 668 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
681 669 CFGSpaceWire_LSEnableStart(&statusControl, 1);
682 670 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
683 671 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
684 672 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
685 673
686 674 // Set the link status control register
687 675 if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
688 676 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
689 677 else
690 678 SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(0x01) + " is set");
691 679 }
692 680
693 681 //*********************
694 682 // LINK 2 CONFIGURATION
695 683 linkNumber = 2;
696 684 if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
697 685 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
698 686 else
699 687 {
700 688 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber));
701 689
702 690 // Set the link status control register properties
703 691 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
704 692 CFGSpaceWire_LSEnableStart(&statusControl, 1);
705 693 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
706 694 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
707 695 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
708 696
709 697 // Set the link status control register
710 698 if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
711 699 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
712 700 else
713 701 SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(linkNumber) + " is set");
714 702 }
715 703
716 704 //***************************
717 705 // SET THE DEVICE AS A ROUTER
718 706 deviceIsAnInterface = 0; // 0 = router, 1 = interface
719 707 if (CFGSpaceWire_SetAsInterface(hDevice, deviceIsAnInterface, 0) != CFG_TRANSFER_SUCCESS)
720 708 SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface");
721 709 else
722 710 SocExplorerEngine::message(this->plugin,"Device is an interface: " + QString::number(deviceIsAnInterface) + " (1 => true, 0 => false)");
723 711
724 712 setRoutingTableEntry(0xfe, 0x02, 0); // [0010] => route 0xfe on port 1
725 713 setRoutingTableEntry(32 , 0x08, 0); // [1000] => route 32 on port 3
726 714
727 715 USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on port 1 only
728 716 USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
729 717
730 718 SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes");
731 719 SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes");
732 720 SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)));
733 721
734 722 //************
735 723 // test Link 1 and Link 2
736 724 linkStatus1 = getLinkStatus(0x01);
737 725 linkStatus2 = getLinkStatus(0x02);
738 726 this->handleMutex->unlock();
739 727
740 728 if ((linkStatus1==1) || (linkStatus2==1))
741 729 {
742 730 initializeTimecodeGeneration();
743 731 this->connected=true;
744 732 return true;
745 733 }
746 734 else
747 735 {
748 736 statusLink1->setText("Link 1 status code: " + QString::number(linkStatus1));
749 737 statusLink2->setText("Link 2 status code: " + QString::number(linkStatus2));
750 738 starDundeeStatusQueryDialog->exec();
751 739 this->connected = false;
752 740 return false;
753 741 }
754 742 }
755 743
756 744 void stardundeeSPW_USB_Manager::initDialog( void )
757 745 {
758 746 // STAR DUNDEE STATUS QUERY DIALOG
759 747 starDundeeStatusQueryDialog = new QDialog;
760 748 starDundeeStatusQueryDialogLayout = new QGridLayout;
761 749 starDundeeStatusQueryDialogLabel = new QLabel(tr("SpaceWire links state"));
762 750 starDundeeStatusQueryContinueButton = new QPushButton(tr("Continue"));
763 751 starDundeeStatusQueryRetryButton = new QPushButton(tr("Retry"));
764 752 starDundeeStatusQueryAbortButton = new QPushButton(tr("Abort"));
765 753 statusLink1 = new QLabel(tr("Link 1 status code: -"));
766 754 statusLink2 = new QLabel(tr("Link 2 status code: -"));
767 755
768 756 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryDialogLabel, 0, 0, 1, 2);
769 757 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryContinueButton, 1, 0, 0);
770 758 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryRetryButton, 1, 1, 0);
771 759 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryAbortButton, 1, 2, 0);
772 760 starDundeeStatusQueryDialogLayout->addWidget(statusLink1, 2, 0, 0);
773 761 starDundeeStatusQueryDialogLayout->addWidget(statusLink2, 3, 0, 0);
774 762 starDundeeStatusQueryDialog->setLayout(starDundeeStatusQueryDialogLayout);
775 763 }
776 764
777 765 unsigned char stardundeeSPW_USB_Manager::setRoutingTableEntry(int tableEntry, U32 dwOutputPorts, char bDelHead)
778 766 {
779 767 U32 routingTableEntry;
780 768 // SET THE ROUTING TABLE ENTRY FOR LOGICAL ADDRESSING, TARGET entryNumber
781 769 if (CFGSpaceWire_ClearRoutingTableEntry(hDevice, tableEntry) != CFG_TRANSFER_SUCCESS)
782 770 {
783 771 SocExplorerEngine::message(this->plugin,"Could not clear routing table entry " + QString::number(tableEntry));
784 772 }
785 773 // Build the routing table entry
786 774 CFGSpaceWire_RTBuildRoutingTableEntry(&routingTableEntry,
787 775 dwOutputPorts, // route out of port dwOutputPorts
788 776 bDelHead, // header deletion is enabled [1] or disabled [0]
789 777 0); // priority normal
790 778 // Set the routing table entry for logical address tableEntry
791 779 if (CFGSpaceWire_SetRoutingTableEntry(hDevice, tableEntry, routingTableEntry) != CFG_TRANSFER_SUCCESS)
792 780 {
793 781 SocExplorerEngine::message(this->plugin,"Could not set routing table entry [" + QString::number(tableEntry) + "]");
794 782 }
795 783 else SocExplorerEngine::message(this->plugin,"Routing table entry [" + QString::number(tableEntry) + "] set" );
796 784 return 1;
797 785 }
798 786
799 787 unsigned int stardundeeSPW_USB_Manager::getRoutingTableEntry(int tableEntry)
800 788 {
801 789 U32 routingTableEntry, outputPorts;
802 790 char enabled, delHead, priority;
803 791 int portNum;
804 792
805 793 SocExplorerEngine::message(this->plugin,"GetRoutingTableEntry [" + QString::number(tableEntry) + "]");
806 794 // Read the routing table entry
807 795 if (CFGSpaceWire_GetRoutingTableEntry(hDevice, tableEntry, &routingTableEntry) != CFG_TRANSFER_SUCCESS)
808 796 {
809 797 SocExplorerEngine::message(this->plugin,"Could not read routing table entry [" + QString::number(tableEntry) + "]");
810 798 }
811 799 else
812 800 {
813 801 // Display the routing table entry properties
814 802 CFGSpaceWire_RTIsEnabled(routingTableEntry, &enabled);
815 803 CFGSpaceWire_RTIsDelHead(routingTableEntry, &delHead);
816 804 CFGSpaceWire_RTIsPriority(routingTableEntry, &priority);
817 805 CFGSpaceWire_RTGetOutputPorts(routingTableEntry, &outputPorts);
818 806 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsEnabled : " + QString::number(enabled));
819 807 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsDelHead : " + QString::number(delHead));
820 808 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsPriority : " + QString::number(priority));
821 809 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTGetOutputPorts : ");
822 810 for (portNum = 0; portNum < 32; portNum++)
823 811 {
824 812 if (outputPorts & (1 << portNum))
825 813 {
826 814 SocExplorerEngine::message(this->plugin,QString::number(portNum));
827 815 }
828 816 }
829 817 }
830 818
831 819 return 1;
832 820 }
833 821
834 822 void stardundeeSPW_USB_Manager::initializeTimecodeGeneration()
835 823 {
836 824 U32 dwTickEnableStatus;
837 825 U32 rtr_clk_freq;
838 826
839 827 // (1) RESET
840 828 if (!USBSpaceWire_TC_Reset(hDevice))
841 829 SocExplorerEngine::message(this->plugin,"ERR *** in Open *** Could not reset timecodes\n");
842 830
843 831 // (2) Clear the tick enable register
844 832 if (CFGSpaceWire_SetTickEnableStatus(hDevice, 6) != CFG_TRANSFER_SUCCESS)
845 833 SocExplorerEngine::message(this->plugin,"Could not clear the tick enable register");
846 834 else
847 835 SocExplorerEngine::message(this->plugin,"Cleared the tick enable register");
848 836
849 837 // (3) get the tick status
850 838 CFGSpaceWire_GetTickEnableStatus(hDevice, &dwTickEnableStatus);
851 839 SocExplorerEngine::message(this->plugin,"OK *** in Open *** CFGSpaceWire_GetTickEnableStatus, code is " + QString::number(dwTickEnableStatus, 2));
852 840
853 841 // (4) enable external timecode selection
854 842 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0))
855 843 SocExplorerEngine::message(this->plugin,"ERR *** disable external timecode selection");
856 844
857 845 rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
858 846
859 847 SocExplorerEngine::message(this->plugin,"clock frequency = " + QString::number(rtr_clk_freq) );
860 848
861 849 //**************************************************
862 850 // auto _ tick _ freq = rtr _ clk _ freq / freqCount
863 851 if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, rtr_clk_freq) )
864 852 SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
865 853 }
866 854
867 855 unsigned int stardundeeSPW_USB_Manager::getLinkStatus(unsigned char link)
868 856 {
869 857 U32 statusControl, errorStatus, portType;
870 858 U32 linkStatus, operatingSpeed, outputPortConnection;
871 859 char isLinkRunning, isAutoStart, isStart, isDisabled, isTristate;
872 860
873 861 // Read the link status control register
874 862 if (CFGSpaceWire_GetLinkStatusControl(hDevice, link, &statusControl) != CFG_TRANSFER_SUCCESS)
875 863 {
876 864 SocExplorerEngine::message(this->plugin,"Could not read link status control for link" + QString::number(link));
877 865 }
878 866 else
879 867 {
880 868 // Display the link status control register properties
881 869 CFGSpaceWire_LSPortType(statusControl, &portType);
882 870 if (portType == CFG_CONFIGURATION_PORT)
883 871 {
884 872 CFGSpaceWire_LSConfigErrorStatus(statusControl, &errorStatus);
885 873 }
886 874 else if (portType == CFG_SPACEWIRE_EXTERNAL_PORT)
887 875 {
888 876 CFGSpaceWire_LSExternalErrorStatus(statusControl, &errorStatus);
889 877 }
890 878 else
891 879 {
892 880 CFGSpaceWire_LSErrorStatus(statusControl, &errorStatus);
893 881 }
894 882 CFGSpaceWire_LSLinkState(statusControl, &linkStatus);
895 883 CFGSpaceWire_LSIsLinkRunning(statusControl, &isLinkRunning);
896 884 CFGSpaceWire_LSIsAutoStart(statusControl, &isAutoStart);
897 885 CFGSpaceWire_LSIsStart(statusControl, &isStart);
898 886 CFGSpaceWire_LSIsDisabled(statusControl, &isDisabled);
899 887 CFGSpaceWire_LSIsTristate(statusControl, &isTristate);
900 888 CFGSpaceWire_LSOperatingSpeed(statusControl, &operatingSpeed);
901 889 CFGSpaceWire_LSOutputPortConnection(statusControl, &outputPortConnection);
902 890 }
903 891 SocExplorerEngine::message(this->plugin,"status of link " + QString::number(link)
904 892 +" is " + dwLinkStatusQString[linkStatus]);
905 893 if (linkStatus == 5)
906 894 {
907 895 return 1;
908 896 }
909 897 else return 0;
910 898 }
911 899
912 900 bool stardundeeSPW_USB_Manager::disconnectBridge()
913 901 {
914 902 this->handleMutex->lock();
915 903 USBSpaceWire_Close(hDevice); // Close the device
916 904 SocExplorerEngine::message(this->plugin,"stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(0),0);
917 905 USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports
918 906 this->handleMutex->unlock();
919 907 this->RMAP_pending_transaction_IDsMtx->lock();
920 908 this->RMAP_pending_transaction_IDs.clear();
921 909 this->RMAP_pending_transaction_IDsMtx->unlock();
922 910 this->RMAP_AnswersMtx->lock();
923 911 this->RMAP_Answers.clear();
924 912 this->RMAP_AnswersMtx->unlock();
925 913 this->RMAP_AnswersSem->acquire(this->RMAP_AnswersSem->available());
926 914 return true;
927 915 }
928 916
929 int stardundeeSPW_USB_Manager::getRMAPtransactionID()
930 {
931 this->RMAP_pending_transaction_IDsMtx->lock();
932 int ID=0;
933 bool found=true;
934 while(ID<511)
935 {
936 for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
937 {
938 if(RMAP_pending_transaction_IDs[i]==ID)found=false;
939 }
940 if(found==true)break;
941 ID++;
942 found = true;
943 }
944 if(found)
945 {
946 RMAP_pending_transaction_IDs.append(ID);
947 }
948 this->RMAP_pending_transaction_IDsMtx->unlock();
949 return ID;
950 }
951
952 int stardundeeSPW_USB_Manager::getRMAPanswer(int transactionID, char **buffer)
953 {
954 QTime timeout;
955 *buffer=NULL;
956 int count=0;
957 SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
958 timeout.start();
959 while (*buffer==NULL)
960 {
961 this->RMAP_AnswersMtx->lock();
962 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
963 SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
964 for(int i=0;i<RMAP_Answers.count();i++)
965 {
966 SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
967 if(RMAP_Answers[i]->transactionID==transactionID)
968 {
969 this->RMAP_pending_transaction_IDsMtx->lock();
970 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
971 for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
972 {
973 if(RMAP_pending_transaction_IDs[j]==transactionID)
974 {
975 RMAP_pending_transaction_IDs.removeAt(j);
976 }
977 }
978 this->RMAP_pending_transaction_IDsMtx->unlock();
979 *buffer = RMAP_Answers[i]->data;
980 count = RMAP_Answers[i]->len;
981 RMAP_Answer* tmp=RMAP_Answers[i];
982 RMAP_Answers.removeAt(i);
983 delete tmp;
984 }
985 }
986 this->RMAP_AnswersMtx->unlock();
987 //if no answer found in the stack wait until a new packet is pushed
988 SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
989 if(*buffer==NULL)
990 {
991 while (0==this->RMAP_AnswersSem->available())
992 {
993 SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
994 if(timeout.elapsed()>=RMAPtimeout)
995 {
996 SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
997 return -1;
998 }
999 usleep(1000);
1000 }
1001 this->RMAP_AnswersSem->acquire();
1002 }
1003 }
1004 return count;
1005 }
1006
1007 917 bool stardundeeSPW_USB_Manager::sendPacket(char *packet, int size)
1008 918 {
1009 919 char protocoleIdentifier;
1010 920 USB_SPACEWIRE_STATUS result=TRANSFER_ERROR_NOT_FOUND;
1011 921 USB_SPACEWIRE_ID pIdentifier;
1012 922 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
1013 923 this->handleMutex->lock();
1014 924 result = USBSpaceWire_SendPacket(hDevice,packet,size,1, &pIdentifier);
1015 925 USBSpaceWire_FreeSend(hDevice, pIdentifier);
1016 926 this->handleMutex->unlock();
1017 927 if (result != TRANSFER_SUCCESS)
1018 928 {
1019 929 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
1020 930 return false;
1021 931 }
1022 932 else
1023 933 {
1024 934 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
1025 935 // read the protocole identifier
1026 936 protocoleIdentifier = packet[2];
1027 937 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
1028 938 emit ccsdsPacketTransmittedToSpw();
1029 939
1030 940 SocExplorerEngine::message(this->plugin,"Packet sent",2);
1031 941 }
1032 942 return true;
1033 943 }
1034 944
1035 void stardundeeSPW_USB_Manager::pushRmapPacket(char *packet, int len)
1036 {
1037 char* packetbuffer = (char*)malloc(len);
1038 memcpy(packetbuffer,packet,len);
1039 RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
1040 RMAP_AnswersMtx->lock();
1041 RMAP_Answers.append(RMPAPpacket);
1042 RMAP_AnswersMtx->unlock();
1043 }
1044 945
1045 946 void stardundeeSPW_USB_Manager::sendTimecodePeriodically( bool onOff )
1046 947 {
1047 948 this->handleMutex->lock();
1048 949 if (onOff == true)
1049 950 {
1050 951 if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1))
1051 952 SocExplorerEngine::message(this->plugin,"Could not enable auto tick-in");
1052 953 }
1053 954 else
1054 955 {
1055 956 if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0))
1056 957 SocExplorerEngine::message(this->plugin,"Could not disable auto tick-in");
1057 958 }
1058 959 this->handleMutex->unlock();
1059 960 }
1060 961
1061 962 int stardundeeSPW_USB_Manager::getLinkNumber( void )
1062 963 {
1063 964 return this->linkNumber;
1064 965 }
1065 966
1066 967 void stardundeeSPW_USB_Manager::setTimecodeFrequency(double requestedFrequency)
1067 968 {
1068 969 U32 rtr_clk_freq=0;
1069 970 U32 freqCount=0;
1070 971 double freqCountInDouble=0.0;
1071 972 double currentFrequency=0.0;
1072 973
1073 974 this->handleMutex->lock();
1074 975 rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
1075 976 freqCountInDouble = ((double) rtr_clk_freq) / requestedFrequency;
1076 977 freqCount = (unsigned int) freqCountInDouble;
1077 978
1078 979 currentFrequency = ((double) rtr_clk_freq) / ((double) freqCount);
1079 980
1080 981 //**************************************************
1081 982 // auto _ tick _ freq = rtr _ clk _ freq / freqCount
1082 983 if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, freqCount) )
1083 984 SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
1084 985 else
1085 986 SocExplorerEngine::message(this->plugin,"tick frequency set to " + QString::number(currentFrequency) +" Hz"
1086 987 + " (freqCount set to " + QString::number(freqCount) + ")" );
1087 988 this->handleMutex->unlock();
1088 989 }
1089 990
1090 991 void stardundeeSPW_USB_Manager::sendOneTimecode( unsigned char nTimein )
1091 992 {
1092 993 this->handleMutex->lock();
1093 994 // enable external timecode selection
1094 995 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,1))
1095 996 SocExplorerEngine::message(this->plugin,"sendOneTimecode *** ERR *** enable external timecode selection");
1096 997
1097 998 if (!USBSpaceWire_TC_PerformTickIn( hDevice, nTimein) )
1098 999 SocExplorerEngine::message( this->plugin,"sendOneTimecode *** ERR *** Could not send the requested timecode: " + QString::number(nTimein) );
1099 1000 else
1100 1001 SocExplorerEngine::message( this->plugin,"sendOneTimecode *** OK *** timecode sent " + QString::number(nTimein) );
1101 1002
1102 1003 // disable external timecode selection
1103 1004 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0))
1104 1005 SocExplorerEngine::message(this->plugin,"sendOneTimecode *** ERR *** disable external timecode selection");
1105 1006 this->handleMutex->unlock();
1106 1007 }
1107 1008
1108 1009
@@ -1,163 +1,149
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #ifndef STARDUNDEESPW_USB_H
23 23 #define STARDUNDEESPW_USB_H
24 24
25 25 #include <QObject>
26 26 //#include <spw_usb_api.h>
27 27 //#include <spw_config_library.h>
28 28
29 29 #include "fakestardundeespwusb_lib.h"
30 30 #include <socexplorerplugin.h>
31 31 #include <abstractspwbridge.h>
32 32 #include <QThread>
33 33 #include <QMutex>
34 34 #include <QSemaphore>
35 35 #include <QGridLayout>
36 36 #include <QPushButton>
37 37 #include <QComboBox>
38 38 #include <QLabel>
39 39 #include "stardundeegui.h"
40 40
41 41 #define BRICK_IS_SET_AS_AN_INTERFACE true
42 42 #define BRICK_IS_SET_AS_A_ROUTER false
43 43
44 class stardundeeSPW_USB_Manager: public QThread
44 class stardundeeSPW_USB_Manager: public abstractSpwManager
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 explicit stardundeeSPW_USB_Manager(socexplorerplugin *plugin = 0,QObject* parent=0);
49 49 ~stardundeeSPW_USB_Manager();
50 50 void run();
51 51 bool connectBridge();
52 52 bool connectBridgeAsInterface();
53 53 bool connectBridgeAsRouter();
54 54 void initDialog( void );
55 55 unsigned char setRoutingTableEntry(int tableEntry, U32 dwOutputPorts, char bDelHead);
56 56 unsigned int getRoutingTableEntry(int tableEntry);
57 57 void initializeTimecodeGeneration();
58 58 void setTimecodeFrequency(double requestedFrequency);
59 59 unsigned int getLinkStatus(unsigned char link);
60 60 bool disconnectBridge();
61 int getRMAPtransactionID();
62 int getRMAPanswer(int transactionID,char** buffer);
63 61 bool sendPacket(char* packet,int size);
64 62
65 63 signals:
66 64 void updateAvailableBrickCount(int count);
67 65 void emitPacket(char* packet,int size);
68 66 void bytesReceivedFromSpw( unsigned int );
69 67 void bytesTransmittedToSpw( unsigned int);
70 68 void ccsdsPacketTransmittedToSpw( void );
71 69
72 70 public slots:
73 71 void sendTimecodePeriodically( bool onOff );
74 72 void sendOneTimecode(unsigned char nTimein);
75 73 int getLinkNumber( void );
76 74
77 75 private:
78 QMutex *handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx;
79 76 QSemaphore* RMAP_AnswersSem;
80 void pushRmapPacket(char* packet,int len);
81 77 star_device_handle hDevice;
82 socexplorerplugin* plugin;
83 bool connected;
84 char* SPWPacketBuff;
85 QList<RMAP_Answer*> RMAP_Answers;
86 QList<int> RMAP_pending_transaction_IDs;
87 78
88 79 QLabel *starDundeeStatusQueryDialogLabel;
89 80 QPushButton *starDundeeStatusQueryRetryButton;
90 81 QPushButton *starDundeeStatusQueryAbortButton;
91 82 QLabel *statusLink1;
92 83 QLabel *statusLink2;
93 84 QPushButton *starDundeeStatusQueryContinueButton;
94 85 QDialog *starDundeeStatusQueryDialog;
95 86 QGridLayout *starDundeeStatusQueryDialogLayout;
96 87
97 88 public:
98 89 int selectedBrick;
99 int linkNumber;
100 90 int brickList;
101 91 int linkSpeed;
102 int sourceLogicalAddress;
103 int destinationLogicalAddress;
104 int destinationKey;
105 int RMAPtimeout;
106 92 double timecodeFrequency;
107 93 bool interfaceMode; // 1 => interface mode, 0 => router mode
108 94 };
109 95
110 96 class stardundeeSPW_USB : public abstractSpwBridge
111 97 {
112 98 Q_OBJECT
113 99 public:
114 100 explicit stardundeeSPW_USB(socexplorerplugin *parent = 0);
115 101 ~stardundeeSPW_USB();
116 102
117 103 signals:
118 104
119 105 void setRmapTimeout(const QString & timeout);
120 106 void SelectBrick(int brickIndex);
121 107 void SelectLinkNumber(int linkIndex);
122 108 void SelectLinkSpeed(int linkSpeed);
123 109 void SetDestinationKey(const QString & destKey);
124 110 void SetSourceAddress(const QString & address);
125 111 void SetDestinationAddress(const QString & address);
126 112 void SetRmapTimeout(const QString & timeout);
127 113 void SetTimecodeFrequency( double );
128 114 void SetBrickAsAnInterface( bool );
129 115 void SetBrickAsARouter( bool );
130 116 int GetAvailableBrickCount( void );
131 117 unsigned int GetNbPacketsTransmittedToSpw( void );
132 118 unsigned int GetNbCCSDSPacketsTransmittedToSpw( void );
133 119 void BytesReceivedFromSpw( unsigned int );
134 120 void BytesTransmittedToSpw( unsigned int );
135 121 void CCSDSPacketTransmittedToSpw( void );
136 122 void StartSendingTimecodes( bool );
137 123 void SendOneTimecode( unsigned char );
138 124 int GetLinkNumber();
139 125
140 126 public slots:
141 127 void toggleBridgeConnection();
142 128 bool connectBridge();
143 129 bool disconnectBridge();
144 130 int pushRMAPPacket(char* packet,int size);
145 131 unsigned int Write(unsigned int *Value,unsigned int count, unsigned int address=0);
146 132 unsigned int Read(unsigned int *Value,unsigned int count, unsigned int address=0);
147 133 void brickSelectionChanged(int brickIndex);
148 134 void linkNumberSelectionChanged(int linkIndex);
149 135 void linkSpeedSelectionChanged(const QString & linkSpeed);
150 136 void sourceLogicalAddressChanged(const QString & destKey);
151 137 void destinationAddressChanged(const QString & rmapaddress);
152 138 void brickModeChanged( bool interfaceMode );
153 139 void destinationKeyChanged(const QString & key);
154 140 void rmapTimeoutChanged(const QString & timeout);
155 141 void sendPacketComingFromTCPServer(char *packet, int size);
156 142 void timecodeFrequencyChanged(const QString &frequency);
157 143 void startSendingTimecodes( bool onOff );
158 144 private:
159 145 void makeGUI(socexplorerplugin *parent);
160 146 stardundeeSPW_USB_Manager* manager;
161 147 };
162 148
163 149 #endif // STARDUNDEESPW_USB_H
@@ -1,56 +1,176
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "abstractspwbridge.h"
23 #include <QTime>
24 #include <socexplorerengine.h>
23 25
24 26 abstractSpwBridge::abstractSpwBridge(socexplorerplugin *parent)
25 27 :QObject((QObject*)parent)
26 28 {
27 29 this->plugin = parent;
28 30 this->p_GUI=NULL;
29 31 }
30 32
31 33 abstractSpwBridge::~abstractSpwBridge()
32 34 {
33 35 // delete this->p_GUI;
34 36 }
35 37
36 38 QWidget *abstractSpwBridge::getGUI()
37 39 {
38 40 return this->p_GUI;
39 41 }
40 42
41 43 bool abstractSpwBridge::connectBridge()
42 44 {
43 45 return false;
44 46 }
45 47
46 48 bool abstractSpwBridge::disconnectBridge()
47 49 {
48 50 return false;
49 51 }
50 52
51 53
52 54
53 55
54 56
55 57
56 58
59
60
61 abstractSpwManager::abstractSpwManager(socexplorerplugin *plugin, QObject *parent)
62 :QThread((QObject*)parent)
63 {
64 this->RMAPtimeout = 2000;
65 this->handleMutex = new QMutex(QMutex::NonRecursive);
66 this->RMAP_AnswersSem = new QSemaphore(0);
67 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
68 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
69 this->plugin = plugin;
70 connected = false;
71 }
72
73 abstractSpwManager::~abstractSpwManager()
74 {
75 this->terminate();
76 while (!this->isFinished())
77 {
78 this->usleep(1000);
79 }
80 }
81
82 int abstractSpwManager::getRMAPtransactionID()
83 {
84 this->RMAP_pending_transaction_IDsMtx->lock();
85 int ID=0;
86 bool found=true;
87 while(ID<511)
88 {
89 for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
90 {
91 if(RMAP_pending_transaction_IDs[i]==ID)found=false;
92 }
93 if(found==true)break;
94 ID++;
95 found = true;
96 }
97 if(found)
98 {
99 RMAP_pending_transaction_IDs.append(ID);
100 }
101 this->RMAP_pending_transaction_IDsMtx->unlock();
102 return ID;
103 }
104
105 int abstractSpwManager::getRMAPanswer(int transactionID, char **buffer)
106 {
107
108 QTime timeout;
109 *buffer=NULL;
110 int count=0;
111 SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
112 timeout.start();
113 while (*buffer==NULL)
114 {
115 this->RMAP_AnswersMtx->lock();
116 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
117 SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
118 for(int i=0;i<RMAP_Answers.count();i++)
119 {
120 SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
121 if(RMAP_Answers[i]->transactionID==transactionID)
122 {
123 this->RMAP_pending_transaction_IDsMtx->lock();
124 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
125 for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
126 {
127 if(RMAP_pending_transaction_IDs[j]==transactionID)
128 {
129 RMAP_pending_transaction_IDs.removeAt(j);
130 }
131 }
132 this->RMAP_pending_transaction_IDsMtx->unlock();
133 *buffer = RMAP_Answers[i]->data;
134 count = RMAP_Answers[i]->len;
135 RMAP_Answer* tmp=RMAP_Answers[i];
136 RMAP_Answers.removeAt(i);
137 delete tmp;
138 }
139 }
140 this->RMAP_AnswersMtx->unlock();
141 //if no answer found in the stack wait until a new packet is pushed
142 SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
143 if(*buffer==NULL)
144 {
145 while (0==this->RMAP_AnswersSem->available())
146 {
147 SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
148 if(timeout.elapsed()>=RMAPtimeout)
149 {
150 SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
151 return -1;
152 }
153 usleep(1000);
154 }
155 this->RMAP_AnswersSem->acquire();
156 }
157 }
158 return count;
159 }
160
161 int abstractSpwManager::getLinkNumber()
162 {
163 return this->linkNumber;
164 }
165
166 void abstractSpwManager::pushRmapPacket(char *packet, int len)
167 {
168 char* packetbuffer = (char*)malloc(len);
169 memcpy(packetbuffer,packet,len);
170 RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
171 RMAP_AnswersMtx->lock();
172 RMAP_Answers.append(RMPAPpacket);
173 RMAP_AnswersMtx->unlock();
174 }
175
176
@@ -1,68 +1,110
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #ifndef ABSTRACTSPWBRIDGE_H
23 23 #define ABSTRACTSPWBRIDGE_H
24 24
25 25 #include <QObject>
26 #include <QThread>
27 #include <QMutex>
28 #include <QSemaphore>
26 29 #include <socexplorerplugin.h>
27 30 #define RMAP_MAX_XFER_SIZE 4000 //slightly less than 16kBytes
28 31 #include <spw.h>
29 32
30 33 class RMAP_Answer
31 34 {
32 35 public:
33 36 RMAP_Answer(int ID,char* data,int len)
34 37 {
35 38 transactionID = ID;
36 39 this->data = data;
37 40 this->len = len;
38 41 }
39 42 int transactionID;
40 43 char* data;
41 44 int len;
42 45 };
43 46
44 47 class abstractSpwBridge : public QObject
45 48 {
46 49 Q_OBJECT
47 50 public:
48 51 explicit abstractSpwBridge(socexplorerplugin *parent);
49 52 ~abstractSpwBridge();
50 53 QWidget *getGUI();
51 54
52 55 public slots:
53 56 virtual bool connectBridge();
54 57 virtual bool disconnectBridge();
55 58 virtual unsigned int Write(unsigned int *Value,unsigned int count, unsigned int address=0)=0;
56 59 virtual unsigned int Read(unsigned int *Value,unsigned int count, unsigned int address=0)=0;
57 60 virtual int pushRMAPPacket(char* packet,int size)=0;
58 61 signals:
59 62 void setConnected(bool connected);
60 63 void pushPacketOverTCP(char* packet,int size);
61 64 protected:
62 65 socexplorerplugin* plugin;
63 66 QWidget* p_GUI;
64 67 private:
65 68
66 69 };
67 70
71 class abstractSpwManager: public QThread
72 {
73 Q_OBJECT
74 public:
75 explicit abstractSpwManager(socexplorerplugin *plugin = 0,QObject* parent=0);
76 ~abstractSpwManager();
77 virtual void run(){}
78 virtual bool connectBridge()=0;
79 virtual bool disconnectBridge()=0;
80 int getRMAPtransactionID();
81 int getRMAPanswer(int transactionID,char** buffer);
82 virtual bool sendPacket(char* packet,int size)=0;
83 int RMAPtimeout;
84 int linkNumber;
85 int sourceLogicalAddress;
86 int destinationLogicalAddress;
87 int destinationKey;
88 signals:
89 void emitPacket(char* packet,int size);
90 void bytesReceivedFromSpw( unsigned int );
91 void bytesTransmittedToSpw( unsigned int);
92 void ccsdsPacketTransmittedToSpw( void );
93
94 public slots:
95 int getLinkNumber();
96
97 protected:
98 QList<RMAP_Answer*> RMAP_Answers;
99 QList<int> RMAP_pending_transaction_IDs;
100 QMutex *handleMutex,*RMAP_AnswersMtx,*RMAP_pending_transaction_IDsMtx;
101 QSemaphore* RMAP_AnswersSem;
102 socexplorerplugin* plugin;
103 bool connected;
104 void pushRmapPacket(char* packet,int len);
105
106 };
107
108
109
68 110 #endif // ABSTRACTSPWBRIDGE_H
General Comments 0
You need to be logged in to leave comments. Login now