##// END OF EJS Templates
Sync
Jeandet Alexis -
r75:00101d966436 GRESB
parent child
Show More
@@ -1,434 +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 281 this->sourceLogicalAddress=32;
282 282 this->destinationLogicalAddress=254;
283 283 this->destinationKey=2;
284 284 }
285 285
286 286 GR_ESB_Manager::~GR_ESB_Manager()
287 287 {
288 288 }
289 289
290 290 void GR_ESB_Manager::run()
291 291 {
292 292 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
293 293 SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1);
294 294 while (!this->isInterruptionRequested())
295 295 {
296 296 if(this->connected)
297 297 {
298 298 handleMutex->lock();
299 299 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",5);
300 300 if(Read_soc->waitForReadyRead(100))
301 301 {
302 302 QByteArray data = Read_soc->readAll();
303 303 int PacketLen= ((int)data.at(2)& 0x0FF) + (((int)data.at(3)& 0x0FF)<<8) + (((int)data.at(4)& 0x0FF)<<16);
304 304 if(data[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
305 305 {
306 306 RMAP_Answer* packet;
307 307 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
308 308 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(PacketLen),2);
309 309 char* packetbuffer = (char*)malloc(PacketLen);
310 310 memcpy(packetbuffer,data.data(),PacketLen);
311 311 this->handleMutex->unlock();
312 312 if(PacketLen==8)
313 313 {
314 314 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,PacketLen);
315 315 }
316 316 else
317 317 {
318 318 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,PacketLen);
319 319 }
320 320 RMAP_AnswersMtx->lock();
321 321 RMAP_Answers.append(packet);
322 322 RMAP_AnswersMtx->unlock();
323 323 RMAP_AnswersSem->release();
324 324 }
325 325 else //any non-rmap packet will be pushed to the network
326 326 {
327 327 char* packetbuffer = (char*)malloc(PacketLen);
328 328 memcpy(packetbuffer,data.data(),PacketLen);
329 329 emit emitPacket(packetbuffer,PacketLen);
330 330 this->handleMutex->unlock();
331 331 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
332 332 }
333 333
334 334 }
335 335 else
336 336 {
337 337 handleMutex->unlock();
338 338 }
339 339
340 340 }
341 341 else
342 342 {
343 343 //do some sanity checks!
344 344
345 345 usleep(RMAPtimeout/2);
346 346 }
347 347 usleep(1000);
348 348 }
349 349 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
350 350 }
351 351
352 352 bool GR_ESB_Manager::connectBridge()
353 353 {
354 354 int timeout=60;
355 355 if(this->Read_soc->state()==QTcpSocket::UnconnectedState)
356 356 {
357 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Write_port);
357 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Receive_port);
358 358 this->Read_soc->waitForConnected(30000);
359 359 }
360 360 if(this->Write_soc->state()==QTcpSocket::UnconnectedState)
361 361 {
362 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Read_port);
362 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Transmit_port);
363 363 this->Write_soc->waitForConnected(30000);
364 364 }
365 365 while((this->Read_soc->state()!=QTcpSocket::ConnectedState) && (this->Write_soc->state()!=QTcpSocket::ConnectedState))
366 366 {
367 367 usleep(100000);
368 368 if(timeout--==0)return false;
369 369 }
370 370 return true;
371 371
372 372 }
373 373
374 374 bool GR_ESB_Manager::disconnectBridge()
375 375 {
376 376 int timeout=60;
377 377 if(this->Read_soc->state()!=QTcpSocket::UnconnectedState)
378 378 {
379 379 this->Read_soc->disconnectFromHost();
380 380 this->Read_soc->waitForDisconnected(30000);
381 381 }
382 382 if(this->Write_soc->state()!=QTcpSocket::UnconnectedState)
383 383 {
384 384 this->Write_soc->disconnectFromHost();
385 385 this->Write_soc->waitForDisconnected(30000);
386 386 }
387 387 while((this->Read_soc->state()!=QTcpSocket::UnconnectedState) && (this->Write_soc->state()!=QTcpSocket::UnconnectedState))
388 388 {
389 389 usleep(100000);
390 390 if(timeout--==0)return false;
391 391 }
392 392 return true;
393 393 }
394 394
395 395
396 396 bool GR_ESB_Manager::sendPacket(char *packet, int size)
397 397 {
398 398 bool result = false;
399 399 char protocoleIdentifier;
400 400 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
401 401 if(Q_UNLIKELY(this->Write_soc->state()!=QAbstractSocket::ConnectedState))
402 402 {
403 403 SocExplorerEngine::message(this->plugin,"Socket closed",2);
404 404 //TODO handle disconnection
405 405 }
406 406 char* SPWpacket = (char*)malloc(size+4);
407 407 if(SPWpacket!=NULL)
408 408 {
409 409 SPWpacket[0]=0; //Protocol = spw
410 410 memcpy(SPWpacket+4,packet,size);
411 411 SPWpacket[1]=(size>>16) & 0x0FF;
412 412 SPWpacket[2]=(size>>8) & 0x0FF;
413 413 SPWpacket[3]=size & 0x0FF;
414 414 }
415 415 this->handleMutex->lock();
416 416 result = ((size+4) == this->Write_soc->write(SPWpacket,size+4));
417 417 this->handleMutex->unlock();
418 418 if (Q_UNLIKELY(!result))
419 419 {
420 420 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
421 421 return false;
422 422 }
423 423 else
424 424 {
425 425 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
426 426 // read the protocole identifier
427 427 protocoleIdentifier = packet[2];
428 428 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
429 429 emit ccsdsPacketTransmittedToSpw();
430 430 SocExplorerEngine::message(this->plugin,"Packet sent",2);
431 431 }
432 432 return true;
433 433 }
434 434
General Comments 0
You need to be logged in to leave comments. Login now