##// END OF EJS Templates
GRESB Read/Write ops are working but Read has a memory leak.
Jeandet Alexis -
r76:630afd0dda2f GRESB
parent child
Show More
@@ -1,434 +1,512
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 vlink = vlink.section("Virtual link",0,0);
88 //vlink = vlink.section(,0,0);
89 vlink.remove("Virtual link");
89 90 bool success;
90 91 int vlinkTmp = vlink.toInt(&success);
91 92 if(success)
92 93 {
93 94 setVirtualLink(vlinkTmp);
94 95 }
95 96 }
96 97
97 98 void GR_ESB_bridge::setVirtualLink(qint32 vlink)
98 99 {
99 100 if(vlink<6 && vlink>=0)
100 101 {
101 102 this->manager->virtualLinkIndex = vlink;
102 103 }
103 104 }
104 105
105 106
106 107 unsigned int GR_ESB_bridge::Write(unsigned int *Value, unsigned int count, unsigned int address)
107 108 {
108 109 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))];
109 110 char *RMAPAckBuff;
110 111 int transactionID = 0;
111 112 int written=0;
112 113 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
113 114 QProgressBar* progress=NULL;
114 115 SocExplorerAutoProgressBar autopb;
115 116 if(count>RMAP_MAX_XFER_SIZE)
116 117 {
117 118 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
118 119 autopb.setProgressBar(progress);
119 120 }
120 121 //Quite stupide loop, I guess that I always get the number of byte I asked for!
121 122 while(count>=RMAP_MAX_XFER_SIZE)
122 123 {
123 124 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
124 125 {
125 126 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
126 127 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
127 128 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
128 129 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
129 130 }
130 131 transactionID=manager->getRMAPtransactionID();
131 132 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
132 133 RMAP_build_tx_request_header(
133 134 this->manager->destinationLogicalAddress,
134 135 this->manager->destinationKey,
135 136 this->manager->sourceLogicalAddress,
136 137 transactionID,
137 138 address+(written*4),
138 139 RMAP_MAX_XFER_SIZE*4,
139 140 writeBuffer);
140 141 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4));
141 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
142 int len = manager->getRMAPanswer(transactionID,&RMAPAckBuff);
142 143 free(RMAPAckBuff);
143 144 written+=RMAP_MAX_XFER_SIZE;
144 145 count-=RMAP_MAX_XFER_SIZE;
145 146 progress->setValue(written);
146 147 qApp->processEvents();
147 148 }
148 149 if(count>0)
149 150 {
150 151 for(int i=0;i<((int)count);i++)
151 152 {
152 153 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+0] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
153 154 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
154 155 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
155 156 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written])&0xFF);
156 157 }
157 158 transactionID=manager->getRMAPtransactionID();
158 159 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
159 160 RMAP_build_tx_request_header(
160 161 this->manager->destinationLogicalAddress,
161 162 this->manager->destinationKey,
162 163 this->manager->sourceLogicalAddress,
163 164 transactionID,
164 165 address+(written*4),
165 166 count*4,
166 167 writeBuffer);
167 168 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4));
168 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
169 int len = manager->getRMAPanswer(transactionID,&RMAPAckBuff);
169 170 free(RMAPAckBuff);
170 171 written+=count;
171 172 if(progress!=NULL)
172 173 {
173 174 progress->setValue(written);
174 175 qApp->processEvents();
175 176 }
176 177 }
177 178 return written;
178 179 }
179 180
180 181 unsigned int GR_ESB_bridge::Read(unsigned int *Value, unsigned int count, unsigned int address)
181 182 {
182 183 char requestBuffer[RMAP_READ_HEADER_MIN_SZ];
183 184 char* RMAP_AnswerBuffer;
184 185 requestBuffer[0]=this->manager->linkNumber;//Link number
185 186 int transactionID = 0;
186 187 int read=0;
187 188 QProgressBar* progress=NULL;
188 189 SocExplorerAutoProgressBar autopb;
189 190 if(count>RMAP_MAX_XFER_SIZE)
190 191 {
191 192 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
192 193 autopb.setProgressBar(progress);
193 194 }
194 195 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
196 197 //Quite stupide loop, I guess that I always get the number of byte I asked for!
197 198 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
198 199 {
199 200 transactionID = manager->getRMAPtransactionID();
200 201 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
201 202 RMAP_build_rx_request_header(
202 203 this->manager->destinationLogicalAddress,
203 204 this->manager->destinationKey,
204 205 this->manager->sourceLogicalAddress,
205 206 transactionID,
206 207 address+(read*4),
207 208 RMAP_MAX_XFER_SIZE*4,
208 209 requestBuffer);
209 210 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
210 211 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
211 212 if(len==-1)
212 213 {
213 214 this->toggleBridgeConnection();
214 215 return 0;
215 216 }
216 217 for(int i=0;i<((len-13)/4);i++)
217 218 {
218 219 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
219 220 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
220 221 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
221 222 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
222 223 }
223 224 free(RMAP_AnswerBuffer);
224 225 read+=RMAP_MAX_XFER_SIZE;
225 226 count-=RMAP_MAX_XFER_SIZE;
226 227 progress->setValue(read);
227 228 qApp->processEvents();
228 229 }
229 230 if((int)count>0)
230 231 {
231 232 transactionID = manager->getRMAPtransactionID();
232 233 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
233 234 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
234 235 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
235 236 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
236 237 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
237 238 RMAP_build_rx_request_header(
238 239 this->manager->destinationLogicalAddress,
239 240 this->manager->destinationKey,
240 241 this->manager->sourceLogicalAddress,
241 242 transactionID,
242 243 address+(read*4),
243 244 count*4,
244 245 requestBuffer);
245 246 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ);
246 247 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
247 248 if(len==-1)
248 249 {
249 250 this->toggleBridgeConnection();
250 251 return 0;
251 252 }
252 253 for(int i=0;i<((len-13)/4);i++)
253 254 {
254 255 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
255 256 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
256 257 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
257 258 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
258 259 }
259 260 free(RMAP_AnswerBuffer);
260 261 read+=count;
261 262 if(progress!=NULL)
262 263 {
263 264 progress->setValue(read);
264 265 qApp->processEvents();
265 266 }
266 267 }
267 268 return read;
268 269 }
269 270
270 271 int GR_ESB_bridge::pushRMAPPacket(char *packet, int size)
271 272 {
272 273 return this->manager->sendPacket(packet,size);
273 274 }
274 275
275 276
276 277 GR_ESB_Manager::GR_ESB_Manager(socexplorerplugin *plugin, QObject *parent)
277 278 :abstractSpwManager(plugin, parent)
278 279 {
279 this->Read_soc = new QTcpSocket(this);
280 this->Write_soc = new QTcpSocket(this);
280 // this->Read_soc = new QTcpSocket(this);
281 // this->Write_soc = new QTcpSocket(this);
281 282 this->sourceLogicalAddress=32;
282 283 this->destinationLogicalAddress=254;
283 284 this->destinationKey=2;
285 connect(&(this->Read_soc),SIGNAL(readyRead()),this,SLOT(readyRead()));
284 286 }
285 287
286 288 GR_ESB_Manager::~GR_ESB_Manager()
287 289 {
288 290 }
289 291
292 void GR_ESB_Manager::__processPacket(packetBuffer_t *packet)
293 {
294 if(packet->complete)
295 {
296 if(packet->buffer[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
297 {
298 RMAP_Answer* RMapPacket;
299 //SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
300 //SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(packet->PacketLen),2);
301 char* packetbuffer = (char*)malloc(packet->PacketLen);
302 if(packetbuffer)
303 {
304 memcpy(packetbuffer,packet->buffer,packet->PacketLen);
305 this->handleMutex->unlock();
306 if(packet->PacketLen==8)
307 {
308 RMapPacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer),packetbuffer,packet->PacketLen);
309 }
310 else
311 {
312 RMapPacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer),packetbuffer,packet->PacketLen);
313 }
314 RMAP_AnswersMtx->lock();
315 RMAP_Answers.append(RMapPacket);
316 RMAP_AnswersMtx->unlock();
317 RMAP_AnswersSem->release();
318 }
319 }
320 else //any non-rmap packet will be pushed to the network
321 {
322 char* packetbuffer = (char*)malloc(packet->PacketLen);
323 if(packetbuffer)
324 {
325 //memcpy(packetbuffer,packet->buffer,packet->PacketLen);
326 //emit emitPacket(packetbuffer,packet->PacketLen);
327 //SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
328 }
329 }
330 }
331
332 }
333
334 QByteArray GR_ESB_Manager::__processData(const QByteArray &data, packetBuffer_t *buffer)
335 {
336 if(buffer->complete)
337 {
338 if(Q_UNLIKELY(data.size()<=4))
339 return data;
340 buffer->PacketLen= ((int)data.at(3)& 0x0FF) + (((int)data.at(2)& 0x0FF)<<8) + (((int)data.at(1)& 0x0FF)<<16);
341 if(buffer->PacketLen>(data.size()-4))
342 {
343 memcpy(buffer->buffer,data.data()+4,data.size()-4);
344 buffer->complete=false;
345 buffer->index=data.size()-4;
346 }
347 else
348 {
349 memcpy(buffer->buffer,data.data()+4,data.size()-4);
350 buffer->PacketLen = data.size()-4;
351 buffer->index=data.size()-4;
352 buffer->complete=true;
353 __processPacket(buffer);
354 int len = buffer->PacketLen;
355 buffer->PacketLen = 0;
356 buffer->index=0;
357 if((data.size()-4-len))
358 {
359 return __processData(data.right((data.size()-4-len)),buffer);
360 }
361 }
362
363 }
364 else
365 {
366 if(buffer->PacketLen>(data.size()+buffer->index))
367 {
368 memcpy(buffer->buffer+buffer->index,data.data(),data.size());
369 buffer->complete=false;
370 buffer->index+=data.size();
371 }
372 else
373 {
374 memcpy(buffer->buffer+buffer->index,data.data(),buffer->PacketLen-buffer->index);
375 buffer->complete=true;
376 buffer->index+=data.size();
377 __processPacket(buffer);
378 int len = buffer->PacketLen;
379 buffer->PacketLen = 0;
380 buffer->index=0;
381 if((data.size()-len))
382 {
383 return __processData(data.right((data.size()-len)),buffer);
384 }
385 }
386 }
387 return QByteArray();
388 }
389
290 390 void GR_ESB_Manager::run()
291 391 {
292 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
293 SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1);
392 char bufferData[(RMAP_MAX_XFER_SIZE*4)+50];
393 packetBuffer_t buffer={bufferData,0,0,true};
394 //SocExplorerEngine::message(this->plugin,"Starting GRESB pooling thread",1);
395 QByteArray data;
294 396 while (!this->isInterruptionRequested())
295 397 {
296 398 if(this->connected)
297 399 {
298 handleMutex->lock();
299 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",5);
300 if(Read_soc->waitForReadyRead(100))
400 //SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",8);
401 if(!incomingPackets.isEmpty())
301 402 {
302 QByteArray data = Read_soc->readAll();
303 int PacketLen= ((int)data.at(2)& 0x0FF) + (((int)data.at(3)& 0x0FF)<<8) + (((int)data.at(4)& 0x0FF)<<16);
304 if(data[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
305 {
306 RMAP_Answer* packet;
307 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
308 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(PacketLen),2);
309 char* packetbuffer = (char*)malloc(PacketLen);
310 memcpy(packetbuffer,data.data(),PacketLen);
311 this->handleMutex->unlock();
312 if(PacketLen==8)
313 {
314 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,PacketLen);
315 }
316 else
317 {
318 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,PacketLen);
319 }
320 RMAP_AnswersMtx->lock();
321 RMAP_Answers.append(packet);
322 RMAP_AnswersMtx->unlock();
323 RMAP_AnswersSem->release();
324 }
325 else //any non-rmap packet will be pushed to the network
326 {
327 char* packetbuffer = (char*)malloc(PacketLen);
328 memcpy(packetbuffer,data.data(),PacketLen);
329 emit emitPacket(packetbuffer,PacketLen);
330 this->handleMutex->unlock();
331 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
332 }
333
334 }
335 else
336 {
337 handleMutex->unlock();
403 incomingPacketsMutex.lock();
404 data.append(incomingPackets.dequeue());
405 this->incomingPacketsMutex.unlock();
406 data = __processData(data,&buffer);
338 407 }
339 408
340 409 }
341 410 else
342 411 {
343 412 //do some sanity checks!
344
345 413 usleep(RMAPtimeout/2);
346 414 }
347 415 usleep(1000);
348 416 }
349 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
417 //SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
350 418 }
351 419
352 420 bool GR_ESB_Manager::connectBridge()
353 421 {
354 422 int timeout=60;
355 if(this->Read_soc->state()==QTcpSocket::UnconnectedState)
423 this->connected = false;
424 if(this->Read_soc.state()==QTcpSocket::UnconnectedState)
356 425 {
357 this->Read_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Receive_port);
358 this->Read_soc->waitForConnected(30000);
426 this->Read_soc.connectToHost(IP,gresb_Conf[virtualLinkIndex].Receive_port);
427 this->Read_soc.waitForConnected(30000);
359 428 }
360 if(this->Write_soc->state()==QTcpSocket::UnconnectedState)
429 if(this->Write_soc.state()==QTcpSocket::UnconnectedState)
361 430 {
362 this->Write_soc->connectToHost(IP,gresb_Conf[virtualLinkIndex].Transmit_port);
363 this->Write_soc->waitForConnected(30000);
431 this->Write_soc.connectToHost(IP,gresb_Conf[virtualLinkIndex].Transmit_port);
432 this->Write_soc.waitForConnected(30000);
364 433 }
365 while((this->Read_soc->state()!=QTcpSocket::ConnectedState) && (this->Write_soc->state()!=QTcpSocket::ConnectedState))
434 while((this->Read_soc.state()!=QTcpSocket::ConnectedState) && (this->Write_soc.state()!=QTcpSocket::ConnectedState))
366 435 {
367 436 usleep(100000);
368 437 if(timeout--==0)return false;
369 438 }
439 this->connected = true;
370 440 return true;
371 441
372 442 }
373 443
374 444 bool GR_ESB_Manager::disconnectBridge()
375 445 {
376 446 int timeout=60;
377 if(this->Read_soc->state()!=QTcpSocket::UnconnectedState)
447 if(this->Read_soc.state()!=QTcpSocket::UnconnectedState)
378 448 {
379 this->Read_soc->disconnectFromHost();
380 this->Read_soc->waitForDisconnected(30000);
449 this->Read_soc.disconnectFromHost();
450 this->Read_soc.waitForDisconnected(30000);
381 451 }
382 if(this->Write_soc->state()!=QTcpSocket::UnconnectedState)
452 if(this->Write_soc.state()!=QTcpSocket::UnconnectedState)
383 453 {
384 this->Write_soc->disconnectFromHost();
385 this->Write_soc->waitForDisconnected(30000);
454 this->Write_soc.disconnectFromHost();
455 this->Write_soc.waitForDisconnected(30000);
386 456 }
387 while((this->Read_soc->state()!=QTcpSocket::UnconnectedState) && (this->Write_soc->state()!=QTcpSocket::UnconnectedState))
457 while((this->Read_soc.state()!=QTcpSocket::UnconnectedState) && (this->Write_soc.state()!=QTcpSocket::UnconnectedState))
388 458 {
389 459 usleep(100000);
390 460 if(timeout--==0)return false;
391 461 }
392 462 return true;
393 463 }
394 464
395 465
396 466 bool GR_ESB_Manager::sendPacket(char *packet, int size)
397 467 {
398 468 bool result = false;
399 469 char protocoleIdentifier;
400 470 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
401 if(Q_UNLIKELY(this->Write_soc->state()!=QAbstractSocket::ConnectedState))
471 if(Q_UNLIKELY(this->Write_soc.state()!=QAbstractSocket::ConnectedState))
402 472 {
403 473 SocExplorerEngine::message(this->plugin,"Socket closed",2);
404 474 //TODO handle disconnection
405 475 }
406 476 char* SPWpacket = (char*)malloc(size+4);
407 477 if(SPWpacket!=NULL)
408 478 {
409 479 SPWpacket[0]=0; //Protocol = spw
410 480 memcpy(SPWpacket+4,packet,size);
411 481 SPWpacket[1]=(size>>16) & 0x0FF;
412 482 SPWpacket[2]=(size>>8) & 0x0FF;
413 483 SPWpacket[3]=size & 0x0FF;
414 484 }
415 485 this->handleMutex->lock();
416 result = ((size+4) == this->Write_soc->write(SPWpacket,size+4));
486 result = ((size+4) == this->Write_soc.write(SPWpacket,size+4));
487 this->Write_soc.flush();
417 488 this->handleMutex->unlock();
418 489 if (Q_UNLIKELY(!result))
419 490 {
420 491 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
421 492 return false;
422 493 }
423 494 else
424 495 {
425 496 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
426 497 // read the protocole identifier
427 498 protocoleIdentifier = packet[2];
428 499 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
429 emit ccsdsPacketTransmittedToSpw();
500 emit ccsdsPacketTransmittedToSpw();
430 501 SocExplorerEngine::message(this->plugin,"Packet sent",2);
431 502 }
432 503 return true;
433 504 }
434 505
506 void GR_ESB_Manager::readyRead()
507 {
508 incomingPacketsMutex.lock();
509 incomingPackets.append(Read_soc.readAll());
510 incomingPacketsMutex.unlock();
511 }
512
@@ -1,79 +1,96
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 #include <QQueue>
8 9
9 10 struct gresb_Conf_str
10 11 {
11 12 qint32 Transmit_port;
12 13 qint32 Receive_port;
13 14 };
14 15
15 16
16 17 const struct gresb_Conf_str gresb_Conf[]=
17 18 {
18 {3000,3001}, //Virtual link 0
19 {3002,3003}, //Virtual link 1
20 {3004,3005}, //Virtual link 2
21 {3006,3007}, //Virtual link 3
22 {3008,3009}, //Virtual link 4
23 {3010,3011} //Virtual link 5
19 {3000,3001}, //Virtual link 0
20 {3002,3003}, //Virtual link 1
21 {3004,3005}, //Virtual link 2
22 {3006,3007}, //Virtual link 3
23 {3008,3009}, //Virtual link 4
24 {3010,3011} //Virtual link 5
24 25 };
25 26
26 27
27 28 class GR_ESB_Manager: public abstractSpwManager
28 29 {
29 30 Q_OBJECT
31
32 typedef struct packetBuffer_t
33 {
34 char* buffer;
35 int PacketLen;
36 int index;
37 bool complete;
38 }packetBuffer_t;
39
30 40 public:
31 41 explicit GR_ESB_Manager(socexplorerplugin *plugin = 0,QObject* parent=0);
32 42 ~GR_ESB_Manager();
33 43 void run();
34 44 bool connectBridge();
35 45 bool disconnectBridge();
36 46 bool sendPacket(char* packet,int size);
37 47
38 48 signals:
39 49 void emitPacket(char* packet,int size);
40 50 private:
41 51 void pushRmapPacket(char* packet,int len);
42 52 char* SPWPacketBuff;
43 53
54 void __processPacket(packetBuffer_t *packet);
55 QByteArray __processData(const QByteArray &data, packetBuffer_t* buffer);
56 private slots:
57 void readyRead();
58
44 59 public:
45 QTcpSocket* Read_soc;
46 QTcpSocket* Write_soc;
60 QTcpSocket Read_soc;
61 QTcpSocket Write_soc;
62 QMutex incomingPacketsMutex;
63 QQueue<QByteArray> incomingPackets;
47 64 QString IP;
48 65 int virtualLinkIndex;
49 66 };
50 67
51 68
52 69 class GR_ESB_bridge : public abstractSpwBridge
53 70 {
54 71 Q_OBJECT
55 72 public:
56 73 explicit GR_ESB_bridge(socexplorerplugin *parent = 0);
57 74 ~GR_ESB_bridge();
58 75 signals:
59 76
60 77
61 78 public slots:
62 79 void toggleBridgeConnection();
63 80 bool connectBridge();
64 81 bool disconnectBridge();
65 82 void setIP(QString ip);
66 83 void setVirtualLink(QString vlink);
67 84 void setVirtualLink(qint32 vlink);
68 85 unsigned int Write(unsigned int *Value,unsigned int count, unsigned int address=0);
69 86 unsigned int Read(unsigned int *Value,unsigned int count, unsigned int address=0);
70 87 int pushRMAPPacket(char* packet,int size);
71 88 void packetReceived();
72 89
73 90 private:
74 91
75 92 GR_ESB_Manager* manager;
76 93
77 94 };
78 95
79 96 #endif // GR_ESB_BRIDGE_H
@@ -1,176 +1,178
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 23 #include <QTime>
24 24 #include <socexplorerengine.h>
25 25
26 26 abstractSpwBridge::abstractSpwBridge(socexplorerplugin *parent)
27 27 :QObject((QObject*)parent)
28 28 {
29 29 this->plugin = parent;
30 30 this->p_GUI=NULL;
31 31 }
32 32
33 33 abstractSpwBridge::~abstractSpwBridge()
34 34 {
35 35 // delete this->p_GUI;
36 36 }
37 37
38 38 QWidget *abstractSpwBridge::getGUI()
39 39 {
40 40 return this->p_GUI;
41 41 }
42 42
43 43 bool abstractSpwBridge::connectBridge()
44 44 {
45 45 return false;
46 46 }
47 47
48 48 bool abstractSpwBridge::disconnectBridge()
49 49 {
50 50 return false;
51 51 }
52 52
53 53
54 54
55 55
56 56
57 57
58 58
59 59
60 60
61 61 abstractSpwManager::abstractSpwManager(socexplorerplugin *plugin, QObject *parent)
62 62 :QThread((QObject*)parent)
63 63 {
64 64 this->RMAPtimeout = 2000;
65 65 this->handleMutex = new QMutex(QMutex::NonRecursive);
66 66 this->RMAP_AnswersSem = new QSemaphore(0);
67 67 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
68 68 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
69 69 this->plugin = plugin;
70 70 connected = false;
71 71 }
72 72
73 73 abstractSpwManager::~abstractSpwManager()
74 74 {
75 75 this->terminate();
76 76 while (!this->isFinished())
77 77 {
78 78 this->usleep(1000);
79 79 }
80 80 }
81 81
82 82 int abstractSpwManager::getRMAPtransactionID()
83 83 {
84 84 this->RMAP_pending_transaction_IDsMtx->lock();
85 85 int ID=0;
86 86 bool found=true;
87 87 while(ID<511)
88 88 {
89 89 for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
90 90 {
91 91 if(RMAP_pending_transaction_IDs[i]==ID)found=false;
92 92 }
93 93 if(found==true)break;
94 94 ID++;
95 95 found = true;
96 96 }
97 97 if(found)
98 98 {
99 99 RMAP_pending_transaction_IDs.append(ID);
100 100 }
101 101 this->RMAP_pending_transaction_IDsMtx->unlock();
102 102 return ID;
103 103 }
104 104
105 105 int abstractSpwManager::getRMAPanswer(int transactionID, char **buffer)
106 106 {
107 107
108 108 QTime timeout;
109 109 *buffer=NULL;
110 110 int count=0;
111 111 SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
112 qApp->processEvents();
112 113 timeout.start();
113 114 while (*buffer==NULL)
114 115 {
115 116 this->RMAP_AnswersMtx->lock();
116 117 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
117 118 SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
118 119 for(int i=0;i<RMAP_Answers.count();i++)
119 120 {
120 121 SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
121 122 if(RMAP_Answers[i]->transactionID==transactionID)
122 123 {
123 124 this->RMAP_pending_transaction_IDsMtx->lock();
124 125 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
125 126 for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
126 127 {
127 128 if(RMAP_pending_transaction_IDs[j]==transactionID)
128 129 {
129 130 RMAP_pending_transaction_IDs.removeAt(j);
130 131 }
131 132 }
132 133 this->RMAP_pending_transaction_IDsMtx->unlock();
133 134 *buffer = RMAP_Answers[i]->data;
134 135 count = RMAP_Answers[i]->len;
135 136 RMAP_Answer* tmp=RMAP_Answers[i];
136 137 RMAP_Answers.removeAt(i);
137 138 delete tmp;
138 139 }
139 140 }
140 141 this->RMAP_AnswersMtx->unlock();
141 142 //if no answer found in the stack wait until a new packet is pushed
142 143 SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
143 144 if(*buffer==NULL)
144 145 {
145 146 while (0==this->RMAP_AnswersSem->available())
146 147 {
147 148 SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
148 149 if(timeout.elapsed()>=RMAPtimeout)
149 150 {
150 151 SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
151 152 return -1;
152 153 }
153 154 usleep(1000);
155 qApp->processEvents();
154 156 }
155 157 this->RMAP_AnswersSem->acquire();
156 158 }
157 159 }
158 160 return count;
159 161 }
160 162
161 163 int abstractSpwManager::getLinkNumber()
162 164 {
163 165 return this->linkNumber;
164 166 }
165 167
166 168 void abstractSpwManager::pushRmapPacket(char *packet, int len)
167 169 {
168 170 char* packetbuffer = (char*)malloc(len);
169 171 memcpy(packetbuffer,packet,len);
170 172 RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
171 173 RMAP_AnswersMtx->lock();
172 174 RMAP_Answers.append(RMPAPpacket);
173 175 RMAP_AnswersMtx->unlock();
174 176 }
175 177
176 178
General Comments 0
You need to be logged in to leave comments. Login now