##// END OF EJS Templates
GRESB: RMAP Write working.
Jeandet Alexis -
r72:597f74f8955c GRESB
parent child
Show More
@@ -1,431 +1,434
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 108 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))];
109 109 char *RMAPAckBuff;
110 110 int transactionID = 0;
111 111 int written=0;
112 112 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
113 113 QProgressBar* progress=NULL;
114 114 SocExplorerAutoProgressBar autopb;
115 115 if(count>RMAP_MAX_XFER_SIZE)
116 116 {
117 117 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
118 118 autopb.setProgressBar(progress);
119 119 }
120 120 //Quite stupide loop, I guess that I always get the number of byte I asked for!
121 121 while(count>=RMAP_MAX_XFER_SIZE)
122 122 {
123 123 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
124 124 {
125 125 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
126 126 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
127 127 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
128 128 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
129 129 }
130 130 transactionID=manager->getRMAPtransactionID();
131 131 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
132 132 RMAP_build_tx_request_header(
133 133 this->manager->destinationLogicalAddress,
134 134 this->manager->destinationKey,
135 135 this->manager->sourceLogicalAddress,
136 136 transactionID,
137 137 address+(written*4),
138 138 RMAP_MAX_XFER_SIZE*4,
139 139 writeBuffer);
140 140 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4));
141 141 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
142 142 free(RMAPAckBuff);
143 143 written+=RMAP_MAX_XFER_SIZE;
144 144 count-=RMAP_MAX_XFER_SIZE;
145 145 progress->setValue(written);
146 146 qApp->processEvents();
147 147 }
148 148 if(count>0)
149 149 {
150 150 for(int i=0;i<((int)count);i++)
151 151 {
152 152 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
153 153 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
154 154 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
155 155 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
156 156 }
157 157 transactionID=manager->getRMAPtransactionID();
158 158 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
159 159 RMAP_build_tx_request_header(
160 160 this->manager->destinationLogicalAddress,
161 161 this->manager->destinationKey,
162 162 this->manager->sourceLogicalAddress,
163 163 transactionID,
164 164 address+(written*4),
165 165 count*4,
166 166 writeBuffer);
167 167 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4));
168 168 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
169 169 free(RMAPAckBuff);
170 170 written+=count;
171 171 if(progress!=NULL)
172 172 {
173 173 progress->setValue(written);
174 174 qApp->processEvents();
175 175 }
176 176 }
177 177 return written;
178 178 }
179 179
180 180 unsigned int GR_ESB_bridge::Read(unsigned int *Value, unsigned int count, unsigned int address)
181 181 {
182 182 char requestBuffer[RMAP_READ_HEADER_MIN_SZ];
183 183 char* RMAP_AnswerBuffer;
184 184 requestBuffer[0]=this->manager->linkNumber;//Link number
185 185 int transactionID = 0;
186 186 int read=0;
187 187 QProgressBar* progress=NULL;
188 188 SocExplorerAutoProgressBar autopb;
189 189 if(count>RMAP_MAX_XFER_SIZE)
190 190 {
191 191 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
192 192 autopb.setProgressBar(progress);
193 193 }
194 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 195
196 196 //Quite stupide loop, I guess that I always get the number of byte I asked for!
197 197 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
198 198 {
199 199 transactionID = manager->getRMAPtransactionID();
200 200 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
201 201 RMAP_build_rx_request_header(
202 202 this->manager->destinationLogicalAddress,
203 203 this->manager->destinationKey,
204 204 this->manager->sourceLogicalAddress,
205 205 transactionID,
206 206 address+(read*4),
207 207 RMAP_MAX_XFER_SIZE*4,
208 208 requestBuffer);
209 209 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
210 210 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
211 211 if(len==-1)
212 212 {
213 213 this->toggleBridgeConnection();
214 214 return 0;
215 215 }
216 216 for(int i=0;i<((len-13)/4);i++)
217 217 {
218 218 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
219 219 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
220 220 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
221 221 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
222 222 }
223 223 free(RMAP_AnswerBuffer);
224 224 read+=RMAP_MAX_XFER_SIZE;
225 225 count-=RMAP_MAX_XFER_SIZE;
226 226 progress->setValue(read);
227 227 qApp->processEvents();
228 228 }
229 229 if((int)count>0)
230 230 {
231 231 transactionID = manager->getRMAPtransactionID();
232 232 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
233 233 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
234 234 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
235 235 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
236 236 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
237 237 RMAP_build_rx_request_header(
238 238 this->manager->destinationLogicalAddress,
239 239 this->manager->destinationKey,
240 240 this->manager->sourceLogicalAddress,
241 241 transactionID,
242 242 address+(read*4),
243 243 count*4,
244 244 requestBuffer);
245 245 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
246 246 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
247 247 if(len==-1)
248 248 {
249 249 this->toggleBridgeConnection();
250 250 return 0;
251 251 }
252 252 for(int i=0;i<((len-13)/4);i++)
253 253 {
254 254 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
255 255 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
256 256 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
257 257 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
258 258 }
259 259 free(RMAP_AnswerBuffer);
260 260 read+=count;
261 261 if(progress!=NULL)
262 262 {
263 263 progress->setValue(read);
264 264 qApp->processEvents();
265 265 }
266 266 }
267 267 return read;
268 268 }
269 269
270 270 int GR_ESB_bridge::pushRMAPPacket(char *packet, int size)
271 271 {
272 272 return this->manager->sendPacket(packet,size);
273 273 }
274 274
275 275
276 276 GR_ESB_Manager::GR_ESB_Manager(socexplorerplugin *plugin, QObject *parent)
277 277 :abstractSpwManager(plugin, parent)
278 278 {
279 279 this->Read_soc = new QTcpSocket(this);
280 280 this->Write_soc = new QTcpSocket(this);
281 this->sourceLogicalAddress=32;
282 this->destinationLogicalAddress=254;
283 this->destinationKey=2;
281 284 }
282 285
283 286 GR_ESB_Manager::~GR_ESB_Manager()
284 287 {
285 288 }
286 289
287 290 void GR_ESB_Manager::run()
288 291 {
289 292 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
290 293 SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1);
291 294 while (!this->isInterruptionRequested())
292 295 {
293 296 if(this->connected)
294 297 {
295 298 handleMutex->lock();
296 299 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",5);
297 300 if(Read_soc->waitForReadyRead(100))
298 301 {
299 302 QByteArray data = Read_soc->readAll();
300 303 int PacketLen= ((int)data.at(2)& 0x0FF) + (((int)data.at(3)& 0x0FF)<<8) + (((int)data.at(4)& 0x0FF)<<16);
301 304 if(data[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
302 305 {
303 306 RMAP_Answer* packet;
304 307 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
305 308 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(PacketLen),2);
306 309 char* packetbuffer = (char*)malloc(PacketLen);
307 310 memcpy(packetbuffer,data.data(),PacketLen);
308 311 this->handleMutex->unlock();
309 312 if(PacketLen==8)
310 313 {
311 314 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,PacketLen);
312 315 }
313 316 else
314 317 {
315 318 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,PacketLen);
316 319 }
317 320 RMAP_AnswersMtx->lock();
318 321 RMAP_Answers.append(packet);
319 322 RMAP_AnswersMtx->unlock();
320 323 RMAP_AnswersSem->release();
321 324 }
322 325 else //any non-rmap packet will be pushed to the network
323 326 {
324 327 char* packetbuffer = (char*)malloc(PacketLen);
325 328 memcpy(packetbuffer,data.data(),PacketLen);
326 329 emit emitPacket(packetbuffer,PacketLen);
327 330 this->handleMutex->unlock();
328 331 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
329 332 }
330 333
331 334 }
332 335 else
333 336 {
334 337 handleMutex->unlock();
335 338 }
336 339
337 340 }
338 341 else
339 342 {
340 343 //do some sanity checks!
341 344
342 345 usleep(RMAPtimeout/2);
343 346 }
344 347 usleep(1000);
345 348 }
346 349 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
347 350 }
348 351
349 352 bool GR_ESB_Manager::connectBridge()
350 353 {
351 354 int timeout=60;
352 355 if(this->Read_soc->state()==QTcpSocket::UnconnectedState)
353 356 {
354 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Read_port);
357 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Write_port);
355 358 this->Read_soc->waitForConnected(30000);
356 359 }
357 360 if(this->Write_soc->state()==QTcpSocket::UnconnectedState)
358 361 {
359 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Write_port);
362 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Read_port);
360 363 this->Write_soc->waitForConnected(30000);
361 364 }
362 365 while((this->Read_soc->state()!=QTcpSocket::ConnectedState) && (this->Write_soc->state()!=QTcpSocket::ConnectedState))
363 366 {
364 367 usleep(100000);
365 368 if(timeout--==0)return false;
366 369 }
367 370 return true;
368 371
369 372 }
370 373
371 374 bool GR_ESB_Manager::disconnectBridge()
372 375 {
373 376 int timeout=60;
374 377 if(this->Read_soc->state()!=QTcpSocket::UnconnectedState)
375 378 {
376 379 this->Read_soc->disconnectFromHost();
377 380 this->Read_soc->waitForDisconnected(30000);
378 381 }
379 382 if(this->Write_soc->state()!=QTcpSocket::UnconnectedState)
380 383 {
381 384 this->Write_soc->disconnectFromHost();
382 385 this->Write_soc->waitForDisconnected(30000);
383 386 }
384 387 while((this->Read_soc->state()!=QTcpSocket::UnconnectedState) && (this->Write_soc->state()!=QTcpSocket::UnconnectedState))
385 388 {
386 389 usleep(100000);
387 390 if(timeout--==0)return false;
388 391 }
389 392 return true;
390 393 }
391 394
392 395
393 396 bool GR_ESB_Manager::sendPacket(char *packet, int size)
394 397 {
395 398 bool result = false;
396 399 char protocoleIdentifier;
397 400 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
398 401 if(Q_UNLIKELY(this->Write_soc->state()!=QAbstractSocket::ConnectedState))
399 402 {
400 403 SocExplorerEngine::message(this->plugin,"Socket closed",2);
401 404 //TODO handle disconnection
402 405 }
403 406 char* SPWpacket = (char*)malloc(size+4);
404 407 if(SPWpacket!=NULL)
405 408 {
406 409 SPWpacket[0]=0; //Protocol = spw
407 410 memcpy(SPWpacket+4,packet,size);
408 SPWpacket[1]=size & 0x0FF;
411 SPWpacket[1]=(size>>16) & 0x0FF;
409 412 SPWpacket[2]=(size>>8) & 0x0FF;
410 SPWpacket[3]=(size>>16) & 0x0FF;
413 SPWpacket[3]=size & 0x0FF;
411 414 }
412 415 this->handleMutex->lock();
413 416 result = ((size+4) == this->Write_soc->write(SPWpacket,size+4));
414 417 this->handleMutex->unlock();
415 418 if (Q_UNLIKELY(!result))
416 419 {
417 420 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
418 421 return false;
419 422 }
420 423 else
421 424 {
422 425 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
423 426 // read the protocole identifier
424 427 protocoleIdentifier = packet[2];
425 428 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
426 429 emit ccsdsPacketTransmittedToSpw();
427 430 SocExplorerEngine::message(this->plugin,"Packet sent",2);
428 431 }
429 432 return true;
430 433 }
431 434
@@ -1,79 +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 qint32 Read_port;
12 qint32 Write_port;
11 qint32 Transmit_port;
12 qint32 Receive_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 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 36 bool sendPacket(char* packet,int size);
37 37
38 38 signals:
39 39 void emitPacket(char* packet,int size);
40 40 private:
41 41 void pushRmapPacket(char* packet,int len);
42 42 char* SPWPacketBuff;
43 43
44 44 public:
45 45 QTcpSocket* Read_soc;
46 46 QTcpSocket* Write_soc;
47 47 QString IP;
48 48 int virtualLinkIndex;
49 49 };
50 50
51 51
52 52 class GR_ESB_bridge : public abstractSpwBridge
53 53 {
54 54 Q_OBJECT
55 55 public:
56 56 explicit GR_ESB_bridge(socexplorerplugin *parent = 0);
57 57 ~GR_ESB_bridge();
58 58 signals:
59 59
60 60
61 61 public slots:
62 62 void toggleBridgeConnection();
63 63 bool connectBridge();
64 64 bool disconnectBridge();
65 65 void setIP(QString ip);
66 66 void setVirtualLink(QString vlink);
67 67 void setVirtualLink(qint32 vlink);
68 68 unsigned int Write(unsigned int *Value,unsigned int count, unsigned int address=0);
69 69 unsigned int Read(unsigned int *Value,unsigned int count, unsigned int address=0);
70 70 int pushRMAPPacket(char* packet,int size);
71 71 void packetReceived();
72 72
73 73 private:
74 74
75 75 GR_ESB_Manager* manager;
76 76
77 77 };
78 78
79 79 #endif // GR_ESB_BRIDGE_H
General Comments 0
You need to be logged in to leave comments. Login now