Loading [MathJax]/extensions/tex2jax.js
iCub-main
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
firmwareupdatercore.cpp
Go to the documentation of this file.
2#include <qdebug.h>
3#include <EoUpdaterProtocol.h>
4
6
7
8static void updateProgressCallback(float fraction)
9{
10 self->updateProgress(fraction);
11}
12
13// 09/2020 davide.tome@iit.it - address and port configurable in firmwareupdater.ini
14bool FirmwareUpdaterCore::isValidIpAddress(QString addr)
15{
16 QStringList ipFields;
17
18 ipFields = addr.split(".");
19 if(ipFields.count() == 4 && ipFields[3].contains(":"))
20 {
21 QString address_,port_;
22 int ipv0, ipv1, ipv2, ipv3;
23
24 address_ = addr.split(":")[0];
25 port_ = ipFields[3].split(":")[1];
26
27 QRegExp re("\\d*"); // a digit (\d), zero or more times (*)
28 if (!re.exactMatch(port_)) return false;
29 for(int k=0; k<4; k++)
30 {
31 if (!re.exactMatch(address_.split(".")[k])) return false;
32 }
33
34 ipv0 = address_.split(".")[0].toInt();
35 ipv1 = address_.split(".")[1].toInt();
36 ipv2 = address_.split(".")[2].toInt();
37 ipv3 = address_.split(".")[3].toInt();
38
39 if(ipv0 == 10 && 0 < ipv1 < 255 && 0 < ipv2 < 255 && 0 < ipv3 < 255 && 0 < port_.toInt() < 255)
40 {
41 hostIPaddress = EO_COMMON_IPV4ADDR(ipv0, ipv1, ipv2, ipv3);
42 return true;
43 }
44 else return false;
45 }
46 else return false;
47}
48
49FirmwareUpdaterCore::FirmwareUpdaterCore(QObject *parent) : QObject(parent), mutex(QMutex::Recursive)
50{
51 self = this;
52}
53
54bool FirmwareUpdaterCore::init(Searchable& config, int port, QString address, int VerbositY)
55{
56 verbosity = VerbositY;
57
58 mutex.lock();
59
60 setVerbosity(verbosity);
61
62 Bottle sensorSetConfig=config.findGroup("DRIVERS").tail();
63
64 for (int t=0; t<sensorSetConfig.size(); ++t){
65 yarp::os::Bottle sensorConfig(sensorSetConfig.get(t).toString());
66
67 QString type = QString("%1").arg(sensorConfig.get(0).asString().c_str());
68 QString line = QString("%1").arg(sensorConfig.get(1).asString().c_str());
69 if(verbosity>0) qDebug() << type << "-" << line;
70
71 bool ok;
72 int num = QString("%1").arg(line).toInt(&ok);
73 if(ok){
74 devices.append(QPair<QString,QVariant>(type,num));
75 }else{
76 devices.append(QPair<QString,QVariant>(type,line));
77 }
78
79
80 // 09/2020 davide.tome@iit.it - address and port configurable in firmwareupdater.ini
81 if(type == "ETH") {
82
83 if(isValidIpAddress(line))
84 {
85 port = line.split(":")[1].toInt();
86 qDebug() << "IP address FOUND in .ini file, Using :" << line.split(":")[0];
87 qDebug() << "Port Number FOUND in .ini file, Using :" << line.split(":")[1];
88 }
89 else
90 {
91 int ipv0, ipv1, ipv2, ipv3;
92
93 ipv0 = address.split(".")[0].toInt();
94 ipv1 = address.split(".")[1].toInt();
95 ipv2 = address.split(".")[2].toInt();
96 ipv3 = address.split(".")[3].toInt();
97
98 hostIPaddress = EO_COMMON_IPV4ADDR(ipv0, ipv1, ipv2, ipv3);
99
100 qDebug() << "Missing or invalid IP address found in .ini file (format is 10.0.X.Y:Z , 0 < X,Y < 255 , Z port number)";
101 qDebug() << "Skipped, using defaults:";
102 if(verbosity >= 1)
103 {
104 qInfo() << " - IP address:" << DEFAULT_IP_ADDRESS;
105 qInfo() << " - IP port: " << DEFAULT_IP_PORT;
106 }
107
108 }
109 }
110
111 }
112
113 if(!gMNT.open(hostIPaddress, port))
114 {
115 if(verbosity>0) qDebug("Can't open socket, aborting.");
116 mutex.unlock();
117 return false;
118 }
119
120 mutex.unlock();
121 return true;
122}
123
125{
126 verbosity = verb;
127 bool lowers_are_verbose = (verb >= 1) ? true : false;
128 gMNT.verbose(lowers_are_verbose);
129 downloader.set_verbose(lowers_are_verbose);
130
131 return true;
132}
133
135{
136 mutex.lock();
137 QStringList names;
138 for(int i=0;i<devices.count();i++){
139 QPair<QString,QVariant> p = devices.at(i);
140 names.append(p.first);
141 }
142 mutex.unlock();
143
144 return names;
145}
146
148{
149 mutex.lock();
150 bool ret = gMNT.go2maintenance(EthMaintainer::ipv4OfAllSelected, true, 5, 1.0);;
151 mutex.unlock();
152 return ret;
153}
154
159
164
165
166
168{
169 mutex.lock();
171 mutex.unlock();
172 return ret;
173}
174
175QList<QPair<QString,QVariant> > FirmwareUpdaterCore::getDevices()
176{
177 return devices;
178}
179
180void FirmwareUpdaterCore::disconnectFrom(QString device, QString id)
181{
182 // if(!device.isEmpty() && !id.isEmpty() && device.contains("ETH")){
183 // gMNT.boards_get().clear();
184 // yDebug() << "empty eth devices";
185 // qDebug() << "empty eth devices";
186 // }
187 // //connectTo(device,id);
188}
189
190int FirmwareUpdaterCore::connectTo(QString device, QString id)
191{
192 mutex.lock();
193 if(!device.isEmpty() && !id.isEmpty()){
194 if(device.contains("ETH")){
195 int num = gMNT.discover(true, 2, 1.0).size();
196 if(verbosity>0)
197 {
198 yDebug() << "FirmwareUpdaterCore::connectTo() has found " << num << " ETH boards";
199 }
200 mutex.unlock();
201 return num;
202 }else{
203 QString result;
204 QList<sBoard> s = getCanBoardsFromDriver(device,id.toInt(),&result,true);
205 mutex.unlock();
206 return s.count();
207 }
208 }
209 mutex.unlock();
210 return 0;
211}
212
214{
215 for(int i=0;i<gMNT.boards_get().size();i++){
216 QString boardIp = QString("%1").arg(gMNT.boards_get()[i].getIPV4string().c_str());
217 if(boardIp == ip){
218 return gMNT.boards_get()[i].isInMaintenance();
219 }
220 }
221 return false;
222}
223
228
229void FirmwareUpdaterCore::setSelectedEthBoard(int index,bool selected)
230{
231 mutex.lock();
232 if(gMNT.boards_get().size() > index){
233 gMNT.boards_get()[index].setSelected(selected);
234 }
235 mutex.unlock();
237}
238
239void FirmwareUpdaterCore::setSelectedEthBoard(QString boardIp,bool selected)
240{
241 mutex.lock();
242 for(int i=0;i<gMNT.boards_get().size();i++){
243 if(QString("%1").arg(gMNT.boards_get()[i].getIPV4string().c_str()) == boardIp){
244 gMNT.boards_get()[i].setSelected(selected);
245 break;
246 }
247 }
248 mutex.unlock();
250}
251
252void FirmwareUpdaterCore::setSelectedCanBoards(QList <sBoard> selectedBoards,QString address, int deviceId)
253{
254 mutex.lock();
255 QString res;
256 if(!address.isEmpty() && deviceId == -1){
257 getCanBoardsFromEth(address,&res);
258 }else{
259 getCanBoardsFromDriver(address,deviceId,&res);
260 }
261
262 this->canBoards = selectedBoards;
263
264 foreach (sBoard b, selectedBoards) {
265 for(int i=0;i<downloader.board_list_size;i++){
266 if(downloader.board_list[i].bus == b.bus &&
267 downloader.board_list[i].pid == b.pid){
268 downloader.board_list[i].selected = b.selected;
269 downloader.board_list[i].eeprom = b.eeprom;
270 }
271 }
272 }
273
274 mutex.unlock();
276}
277
282
283void FirmwareUpdaterCore::setSelectedCanBoard(int index,bool selected,QString address, int deviceId)
284{
285 mutex.lock();
286// if(!ethAddress.isEmpty()){
287// if(currentAddress != ethAddress){
288// if(downloader.connected){
289// downloader.stopdriver();
290// }
291// QString res;
292// getCanBoardsFromEth(ethAddress,&res);
293// }
294// }
295 QString res;
296 if(!address.isEmpty() && deviceId == -1){
297 getCanBoardsFromEth(address,&res);
298 }else{
299 getCanBoardsFromDriver(address,deviceId,&res);
300 }
301 downloader.board_list[index].selected=selected;
302 mutex.unlock();
304}
305
306
307boardInfo2_t FirmwareUpdaterCore::getMoreDetails(int boardNum,QString *infoString,eOipv4addr_t *address)
308{
309 mutex.lock();
310 boardInfo2_t info = gMNT.boards_get()[boardNum].getInfo();
311 if(address){
312 *address = gMNT.boards_get()[boardNum].getIPV4();
313 if(infoString && info.protversion == 0){
314 *infoString = QString("%1").arg(gMNT.moreinformation(*address, false).c_str());
315 }
316 }
317 mutex.unlock();
318
319 return info;
320
321}
322
323QString FirmwareUpdaterCore::getProcessFromUint(uint8_t id, bool isMultiCore, eObrd_ethtype_t boardtype)
324{
325 switch (id) {
326 case uprot_proc_Loader:
327 return "eLoader";
328 case uprot_proc_Updater:
329 return "eUpdater";
330 case uprot_proc_Application00:
331 if ((boardtype == eobrd_ethtype_amc) && isMultiCore)
332 return "eApplication_core_0";
333 else if ((boardtype == eobrd_ethtype_amcfoc) && isMultiCore)
334 return "app.yri" ;
335 else
336 return "eApplication";
337 case uprot_proc_Application01:
338 if ((boardtype == eobrd_ethtype_amc) && isMultiCore)
339 return "eApplication_core_1";
340 else if ((boardtype == eobrd_ethtype_amcfoc) && isMultiCore)
341 return "app.mot" ;
342 else
343 return "eApplication_core_1";
344 case uprot_proc_ApplPROGupdater:
345 return "eApplPROGupdater";
346 default:
347 return "None";
348 break;
349 }
350}
351
352QList<sBoard> FirmwareUpdaterCore::getCanBoardsFromDriver(QString driver, int networkId, QString *retString, bool force)
353{
354 mutex.lock();
355
356 if(force){
357 downloader.stopdriver();
358 }else{
359 if(downloader.connected && (!currentAddress.isEmpty() || (currentDriver != driver || currentId != networkId ))){
360 downloader.stopdriver();
361 }
362 if(currentDriver == driver && currentId == networkId){
363 mutex.unlock();
364 return canBoards;
365 }
366 }
367
368 canBoards.clear();
369 yarp::os::Property params;
370 QString networkType;
371 if(driver.contains("CFW2",Qt::CaseInsensitive)){
372 networkType="cfw2can";
373 } else if(driver.contains("ECAN",Qt::CaseInsensitive)){
374 networkType = "ecan";
375 } else if(driver.contains("PCAN",Qt::CaseInsensitive)){
376 networkType = "pcan";
377 } else if(driver.contains("SOCKET",Qt::CaseInsensitive)){
378 networkType="socketcan";
379 }
380 params.put("device", networkType.toLatin1().data());
381 params.put("canDeviceNum", networkId);
382 params.put("canTxQueue", 64);
383 params.put("canRxQueue", 64);
384 params.put("canTxTimeout", 2000);
385 params.put("canRxTimeout", 2000);
386
387 //try to connect to the driver
388 int ret = downloader.initdriver(params, (verbosity>1) ? true : false);
389
390 if (0 != ret){
391 if(-2 == ret){
392 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromDriver(): Init ETH driver - The ETH board has just jumped to eUpdater\n Connect again";
393 *retString = "FirmwareUpdaterCore::getCanBoardsFromDriver(): Init ETH driver - The ETH board has just jumped to eUpdater\n Connect again";
394 // TODO DIALOG
395 } else {
396 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromDriver(): Init driver failed - Hardware busy or not connected?!";
397 *retString = "Cannot init driver " + driver + "<" + QString::number(networkId) + "> ... HW is busy or not connected";
398 // TODO DIALOG
399 }
400 mutex.unlock();
401 return canBoards;
402 }
403
404
405 ret = downloader.initschede();
406
407 if (ret == -1)
408 {
409 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromDriver(): No answer received from CAN boards after a successful driver init.";
410 *retString = "No CAN boards found beneath " + driver + "<" + QString::number(networkId) + ">";
411 downloader.stopdriver();
412 currentAddress = "";
413 //not_connected_status();
414 mutex.unlock();
415 return canBoards;
416 }
417
418 for(int i=0; i<downloader.board_list_size;i++){
419 canBoards.append(downloader.board_list[i]);
420 }
421 currentAddress = "";
422 currentDriver = driver;
423 currentId = networkId;
424
425 //downloader.stopdriver();
426 mutex.unlock();
427 return canBoards;
428
429}
430
431QList<sBoard > FirmwareUpdaterCore::getCanBoardsFromEth(QString address, QString *retString, int canID, bool force)
432{
433 mutex.lock();
434
435 if(force){
436 downloader.stopdriver();
437 }else{
438 if(downloader.connected && address != currentAddress && !currentAddress.isEmpty() || (currentAddress.isEmpty() && !currentDriver.isEmpty())){
439 downloader.stopdriver();
440 }
441
442 if(currentAddress == address){
443 mutex.unlock();
444 return canBoards;
445 }
446 }
447
448
449 canBoards.clear();
450 unsigned int remoteAddr;
451 unsigned int localAddr;
452
453
454
455 if (!compile_ip_addresses(address.toLatin1().data(),&remoteAddr,&localAddr)){
456 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromEth(): Init driver failed - Could not find network interface";
457 // TODO DIALOG
458 *retString = "Init driver failed - Could not find network interface";
459 address = "";
460 mutex.unlock();
461 return canBoards;
462 }
463
464
465 yarp::os::Property params;
466 params.put("device", "ETH");
467 params.put("local", int( localAddr));
468 params.put("remote",int(remoteAddr));
469 params.put("canid",canID);
470
471
472 //try to connect to the driver
473 int ret = downloader.initdriver(params, (verbosity>1) ? true : false);
474
475 if (0 != ret){
476 if(-2 == ret){
477 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromEth((): Init ETH driver - The ETH board has just jumped to eUpdater\n Connect again";
478 *retString = "FirmwareUpdaterCore::getCanBoardsFromEth((): Init ETH driver - The ETH board has just jumped to eUpdater\n Connect again";
479 // TODO DIALOG
480 } else {
481 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromEth((): Init driver failed - Hardware busy or not connected?!";
482 *retString = "FirmwareUpdaterCore::getCanBoardsFromEth(): Init driver failed - Hardware busy or not connected?!";
483 // TODO DIALOG
484 }
485 mutex.unlock();
486 return canBoards;
487 }
488
489
490 ret = downloader.initschede();
491
492 if (ret == -1)
493 {
494 if(verbosity>0) qDebug() << "FirmwareUpdaterCore::getCanBoardsFromEth(): No CAN boards found beneath " << address << " after a successful driver init.";
495 *retString = "No CAN boards found beneath " + address;
496 downloader.stopdriver();
497 address = "";
498 //not_connected_status();
499 mutex.unlock();
500 return canBoards;
501 }
502
503 for(int i=0; i<downloader.board_list_size;i++){
504 canBoards.append(downloader.board_list[i]);
505 }
506 currentAddress = address;
507
508 //downloader.stopdriver();
509 mutex.unlock();
510 return canBoards;
511
512}
513
514
515QList<sBoard> FirmwareUpdaterCore::discoverSingleCanBoardViaEth(QString address, int canID, int canAddress, QString *retString)
516{
517 QList<sBoard> result;
518
519 // Create a yarp::os::Property to pass to initdriver
520 yarp::os::Property params;
521 params.put("device", "ETH");
522 params.put("remote", address.toStdString().c_str());
523
524
525 if (!downloader.initdriver(params, true))
526 {
527 *retString = "Failed to initialize driver";
528 return result;
529 }
530
531 if (downloader.initSINGLEBOARD(canID, canAddress) == 0)
532 {
533 for (int i = 0; i < downloader.board_list_size; ++i)
534 {
535 if (downloader.board_list[i].pid == canAddress)
536 {
537 result.append(downloader.board_list[i]);
538 break;
539 }
540 }
541 }
542 else
543 {
544 *retString = "Board not found";
545 }
546
547 return result;
548}
549
550
551
552bool FirmwareUpdaterCore::compile_ip_addresses(const char* addr,unsigned int *remoteAddr,unsigned int *localAddr)
553{
554 ACE_UINT32 ip1,ip2,ip3,ip4;
555 sscanf(addr,"%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);
556 *remoteAddr=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
557
558 size_t count=0;
559 ACE_INET_Addr* addr_array=NULL;
560 int ret=ACE::get_ip_interfaces(count,addr_array);
561
562 if (ret || count<=0)
563 {
564 mutex.unlock();
565 return false;
566 }
567
568 *localAddr=addr_array[0].get_ip_address();
569
570 for (unsigned int a=1; a<count; ++a)
571 {
572 if ((*remoteAddr & 0xFFFF0000)==(addr_array[a].get_ip_address() & 0xFFFF0000))
573 {
574 *localAddr=addr_array[a].get_ip_address();
575 break;
576 }
577 }
578
579 return true;
580}
581
583{
584 mutex.lock();
586 mutex.unlock();
587}
588
590{
591 mutex.lock();
592 QString ret = QString("%1").arg(gMNT.boards_get()[index].getInfoOnEEPROM().c_str());
593 mutex.unlock();
594 return ret;
595}
596
598{
599 mutex.lock();
600 char board_ipaddr[16];
601 ACE_UINT32 ip = ipv4toace(gMNT.boards_get()[index].getIPV4());
602 sprintf(board_ipaddr,"%d.%d.%d.%d",(ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,ip&0xFF);
603 mutex.unlock();
604 return QString("%1").arg(board_ipaddr);
605}
606
607bool FirmwareUpdaterCore::setEthBoardInfo(int index, QString newInfo)
608{
609 mutex.lock();
610 eOipv4addr_t address = gMNT.boards_get()[index].getIPV4();
611 bool ret = gMNT.command_info32_set(address, newInfo.toLatin1().data());
612 if(!ret){
613 if(verbosity>0) qDebug() << "setEthBoardInfo failed";
614 }
615
616
617 vector<string> vv = gMNT.command_info32_get(address);
618 foreach (string v, vv) {
619 if(verbosity>0) qDebug() << v.c_str();
620 }
621 // TODO chiedere
622 // it already sets it internally to commandInfo32Get()
623 if(vv.size() > 0){
624 if(verbosity>0) qDebug() << gMNT.boards_get()[index].getInfoOnEEPROM().c_str();
625 }
626 mutex.unlock();
627 return true;
628}
629
630void FirmwareUpdaterCore::setCanBoardInfo(int bus, int id, QString newInfo,QString address, int deviceId,QString *resultString)
631{
632 mutex.lock();
633 QString res;
634 if(!address.isEmpty() && deviceId == -1){
635 getCanBoardsFromEth(address,&res);
636 }else{
637 getCanBoardsFromDriver(address,deviceId,&res);
638 }
639 downloader.change_board_info(bus, id, newInfo.toLatin1().data());
640
641// if(!ethAddress.isEmpty()){
642// if(currentAddress != ethAddress){
643// if(downloader.connected){
644// downloader.stopdriver();
645// }
646// getCanBoardsFromEth(ethAddress,resultString);
647// }
648// downloader.change_board_info(bus, id, newInfo.toLatin1().data());
649// }
650 mutex.unlock();
651}
652
653bool FirmwareUpdaterCore::setCanBoardAddress(int bus, int id, int canType,QString newAddress,QString address,int deviceId,QString *resultString)
654{
655 mutex.lock();
656 QString res;
657 if(!address.isEmpty() && deviceId == -1){
658 getCanBoardsFromEth(address,&res);
659 }else{
660 getCanBoardsFromDriver(address,deviceId,&res);
661 }
662
663 int new_val = newAddress.toInt();
664 if (new_val <=0 || new_val> 15){
665 if(verbosity>0) qDebug() << "Error, new address out of range 0 - 15";
666 return false;
667 }
668
669 if (new_val == id){
670 if(verbosity>0) qDebug() << "Error, same address set";
671 return false;
672 }
673
674 downloader.change_card_address(bus, id, new_val,canType);
675
676// if(!ethAddress.isEmpty()){
677// if(currentAddress != ethAddress){
678// if(downloader.connected){
679// downloader.stopdriver();
680// }
681// getCanBoardsFromEth(ethAddress,resultString);
682// }
683
684// int new_val = newAddress.toInt();
685// if (new_val <=0 || new_val> 15){
686// if(verbosity>0) qDebug() << "Error, new address out of range 0 - 15";
687// return false;
688// }
689
690// if (new_val == id){
691// if(verbosity>0) qDebug() << "Error, same address set";
692// return false;
693// }
694
695// downloader.change_card_address(bus, id, new_val,canType);
696// }
697 mutex.unlock();
698
699 return true;
700}
701
702bool FirmwareUpdaterCore::setEthBoardAddress(int index, QString newAddress)
703{
704
705 mutex.lock();
706 int ip1,ip2,ip3,ip4;
707 sscanf(newAddress.toLatin1().data(),"%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);
708 if (ip1<0 || ip1>255 || ip2<0 || ip2>255 || ip3<0 || ip3>255 || ip4<0 || ip4>255){
709 mutex.unlock();
710 return false;
711 }
712 ACE_UINT32 iNewAddress=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
713
714
715 ACE_UINT32 address = ipv4toace(gMNT.boards_get()[index].getIPV4());
716 ACE_UINT32 mask = 0xFFFFFF00;
717
718 if(iNewAddress == (iNewAddress & mask)){ // checks new ip address is not a network address . For example x.y.z.w/24 x.y.z.0
719 if(verbosity>0) qDebug() << "Error Setting address";
720 mutex.unlock();
721 return false;
722 }
723
724 if((~mask) == (iNewAddress & (~mask))){ // checks new ip address is not a broadcast address . For example x.y.z.w/24 x.y.z.255
725 if(verbosity>0) qDebug() << "Error Setting address";
726 mutex.unlock();
727 return false;
728 }
729
730 if (iNewAddress == address){
731 if(verbosity>0) qDebug() << "Error, same address set";
732 mutex.unlock();
733 return false;
734 }
735 char old_addr[16];
736 sprintf(old_addr,"%d.%d.%d.%d",(address>>24)&0xFF,(address>>16)&0xFF,(address>>8)&0xFF,address&0xFF);
737
738 bool ret = gMNT.command_changeaddress(acetoipv4(address), acetoipv4(iNewAddress), true, true, true, true);
739 mutex.unlock();
740 return ret;
741
742
743
744}
745
746
747bool FirmwareUpdaterCore::uploadLoader(QString filename,QString *resultString)
748{
749 mutex.lock();
750 FILE *programFile=fopen(filename.toLatin1().data(),"r");
751 if (!programFile){
752 //TODO ERROR
753 if(verbosity>0) qDebug() << "Error opening the selected file!";
754 mutex.unlock();
755 return false;
756 }
757 eOipv4addr_t ipv4 = 0; // all selected
758 eObrd_ethtype_t type = eobrd_ethtype_none;
759 eOversion_t ver;
760 ver.major = 0;
761 ver.minor = 0;
762 std::string result;
763 bool ok = gMNT.program(ipv4, type, eLoader, ver, programFile, false, updateProgressCallback, false);
764
765 fclose(programFile);
766
767 *resultString = QString("%1").arg(result.c_str());
768 if(ok){
769 mutex.unlock();
770 return true;
771 }
772 mutex.unlock();
773 return false;
774}
775
776
777bool FirmwareUpdaterCore::uploadUpdater(QString filename,QString *resultString)
778{
779 mutex.lock();
780 FILE *programFile=fopen(filename.toLatin1().data(),"r");
781 if (!programFile){
782 //TODO ERROR
783 if(verbosity>0) qDebug() << "Error opening the selected file!";
784 mutex.unlock();
785 return false;
786 }
787 eOipv4addr_t ipv4 = 0; // all selected
788 eObrd_ethtype_t type = eobrd_ethtype_none;
789 eOversion_t ver;
790 ver.major = 0;
791 ver.minor = 0;
792 std::string result;
793 bool ok = gMNT.program(ipv4, type, eUpdater, ver, programFile, false, updateProgressCallback, false);
794
795 fclose(programFile);
796
797 *resultString = QString("%1").arg(result.c_str());
798 if(ok){
799 mutex.unlock();
800 return true;
801 }
802 mutex.unlock();
803 return false;
804}
805
806
807#ifdef SERIALMETHOD
808bool FirmwareUpdaterCore::uploadCanApplication(QString filename,QString *resultString, QString ethAddress)
809{
810 mutex.lock();
811 if(!ethAddress.isEmpty()){
812 if(currentAddress != ethAddress){
813 if(downloader.connected){
814 downloader.stopdriver();
815 }
816 getCanBoardsFromEth(ethAddress,resultString);
817 }
818
819 }
820 double timer_start =0;
821 double timer_end =0;
822
823 if (downloader.connected == false){
824 *resultString ="Driver not running";
825 mutex.unlock();
826 return false;
827 }
828
829 //check if at least one board was selected
830 bool at_least_one_board_selected = false;
831
832 for (int i=0; i<downloader.board_list_size; i++){
833 if (downloader.board_list[i].status==BOARD_RUNNING &&
834 downloader.board_list[i].selected==true)
835 at_least_one_board_selected = true;
836 }
837
838 if (!at_least_one_board_selected){
839 *resultString = "No Boards selected! - Select one or more boards to update the firmware";
840 mutex.unlock();
841 return false;
842 }
843
844 QMap<int,int> canDevices;
845 for (int i=0; i<downloader.board_list_size; i++)
846 {
847 if (downloader.board_list[i].selected==true)
848 {
849 canDevices.insertMulti(downloader.board_list[i].bus,i);
850 downloader.board_list[i].selected = false;
851 if(verbosity>0) qDebug() << "FOUND SELECTED SCHEDA " << i << " ON BUS " << downloader.board_list[i].bus;
852 }
853 }
854
855 int ret = 0;
856 int finished = 0;
857 int busCount = canDevices.uniqueKeys().count();
858 for(int k=0;k<busCount;k++){
859
860 int bus = canDevices.uniqueKeys().at(k);
861
862 if (downloader.open_file(filename.toLatin1().data())!=0){
863 *resultString = "Error opening the selected file!";
864 mutex.unlock();
865 return false;
866 }
867 if(verbosity>0) qDebug() << "FILE " << filename << " OPENED";
868 //TODO
869 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
870 // if (strstr (buffer, "calibrationDataSN") != 0)
871 // {
872 // load_calibration (buffer);
873 // return ALL_OK;
874 // }
875 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
876
877 // Get an identification of the firmware fot the file that you have selected
878 // int firmware_board_type=0;
879 // int firmware_version=0;
880 // int firmware_revision=0;
881
882 //indentify download type from the type of the selected boards
883 int download_type = icubCanProto_boardType__unknown;
884 bool download_eeprom =false;
885
886
887 QList<int> indexes = canDevices.values(bus);
888// foreach (int index, indexes) {
889// downloader.board_list[index].selected = true;
890// if(verbosity>0) qDebug() << "SELECTING BOARD " << index << " OF BUS " << k;
891// }
892
893
894 for(int i=0;i<indexes.count();i++){
895 int index = indexes.at(i);
896 downloader.board_list[index].selected = true;
897 if(verbosity>0) qDebug() << "SELECTING BOARD " << index << " OF BUS " << bus;
898 if (downloader.board_list[index].status==BOARD_RUNNING){
899 if (downloader.startscheda(bus,
900 downloader.board_list[index].pid,
901 downloader.board_list[index].eeprom,
902 downloader.board_list[index].type)!=0){
903 *resultString = "Unable to start the board - Unable to send message 'start' or no answer received";
904 mutex.unlock();
905 return false;
906 } else {
907 if(verbosity>0) qDebug() << "START SCHEDA " << index << " ON BUS " << bus << " OK";
908 downloader.board_list[index].status=BOARD_WAITING;
909 }
910 download_type = downloader.board_list[index].type;
911 download_eeprom = downloader.board_list[index].eeprom;
912 }
913 }
914
915
916
917// // Start the download for the selected boards
918// for (int i=0; i<downloader.board_list_size; i++){
919// if (downloader.board_list[i].status==BOARD_RUNNING && downloader.board_list[i].selected==true){
920// if (downloader.startscheda(downloader.board_list[i].bus,
921// downloader.board_list[i].pid,
922// downloader.board_list[i].eeprom,
923// downloader.board_list[i].type)!=0){
924// *resultString = "Unable to start the board - Unable to send message 'start' or no answer received";
925// return false;
926// } else {
927// if(verbosity>0) qDebug() << "START SCHEDA " << i << " OK";
928// downloader.board_list[i].status=BOARD_WAITING;
929// }
930// download_type = downloader.board_list[i].type;
931// download_eeprom = downloader.board_list[i].eeprom;
932// }
933// }
934
935
936
937 timer_start= yarp::os::Time::now();
938 finished = 0;
939 bool print00 = false, print25 = false, print50 = false, print75 = false, print99 = false;
940 // Start the download for the selected boards
941 do
942 {
943 ret = downloader.download_file(bus, 0x0F, download_type,download_eeprom);
944 if (float(downloader.progress)/downloader.file_length/busCount >0.0 && print00==false) {if(verbosity>0) qDebug("downloading %s, 1%% done\n",filename.toLatin1().data()); print00=true;}
945 if (float(downloader.progress)/downloader.file_length/busCount >0.25 && print25==false) {if(verbosity>0) qDebug("downloading %s, 25%% done\n",filename.toLatin1().data()); print25=true;}
946 if (float(downloader.progress)/downloader.file_length/busCount >0.50 && print50==false) {if(verbosity>0) qDebug("downloading %s, 50%% done\n",filename.toLatin1().data()); print50=true;}
947 if (float(downloader.progress)/downloader.file_length/busCount >0.75 && print75==false) {if(verbosity>0) qDebug("downloading %s, 75%% done\n",filename.toLatin1().data()); print75=true;}
948 if (float(downloader.progress)/downloader.file_length/busCount >0.99 && print99==false) {if(verbosity>0) qDebug("downloading %s, finished!\n",filename.toLatin1().data()); print99=true;}
949
950 if (ret==1){
951 updateProgress(float(downloader.progress)/downloader.file_length/busCount);
952 }
953 if (ret==-1){
954 if(verbosity>0) qDebug() << "Fatal Error during download, terminate";
955 *resultString = "Fatal Error during download, terminate";
956 finished = 1;
957 }
958 if (ret==0){
959 if(verbosity>0) qDebug() << "Download terminated";
960 *resultString = "Download terminated";
961 finished = 1;
962 }
963
964 }
965 while (finished!=1);
966
967 // End the download for the selected boards
968
969 if(downloader.stopscheda(bus, 15) != 0){
970 if(verbosity>0) qDebug() << "ERROR STOPPING SCHEDA";
971 }else{
972 if(verbosity>0) qDebug() << "scheda stopped";
973 }
974
975 foreach (int index, indexes) {
976 downloader.board_list[index].selected = false;
977 if(verbosity>0) qDebug() << "DE-SELECTING BOARD " << index << " OF BUS " << bus;
978 }
979
980
981
982 }
983 timer_end= yarp::os::Time::now();
984
985
986
987
988 //Display result message
989 if (ret == 0)
990 {
991 char time_text [50];
992 double download_time = (timer_end-timer_start) ;
993 sprintf (time_text, "All Board OK! Download Time (s): %.2f", download_time);
994
995 *resultString = QString("Download Finished. %1").arg(time_text);
996
997 updateProgress(1.0);
998 mutex.unlock();
999 return true;
1000 }
1001 else
1002 {
1003 //*resultString = "Error during file transfer";
1004
1005 updateProgress(1.0);
1006 mutex.unlock();
1007 return false;
1008 }
1009
1010 mutex.unlock();
1011 return true;
1012}
1013
1014#else
1015bool FirmwareUpdaterCore::uploadCanApplication(QString filename, QString *resultString, bool ee, QString address, int deviceId, QList<sBoard> *resultCanBoards)
1016{
1017 // Always refresh the board list from ETH
1018 QList<sBoard> boards = getCanBoardsFromEth(address, resultString, deviceId, false);
1019 if (boards.isEmpty()) {
1020 *resultString = "No boards found.";
1021 return false;
1022 }
1023 *resultCanBoards = boards;
1024
1025 // Count selected boards
1026 int selectedCount = 0;
1027 int selectedIndex = -1;
1028 for (int i = 0; i < boards.size(); ++i) {
1029 if (boards[i].selected) {
1030 selectedCount++;
1031 selectedIndex = i;
1032 }
1033 }
1034
1035 // If exactly one board is selected, use unicast discovery
1036 if (selectedCount == 1 && selectedIndex != -1) {
1037 int canID = boards[selectedIndex].bus;
1038 int canAddress = boards[selectedIndex].pid;
1039 QList<sBoard> singleBoard = discoverSingleCanBoardViaEth(address, canID, canAddress, resultString);
1040 if (singleBoard.isEmpty()) {
1041 *resultString = QString("Board not found at CAN ID: %1, Address: %2").arg(canID).arg(canAddress);
1042 return false; // Board not found
1043 }
1044 *resultCanBoards = singleBoard;
1045 }
1046 // else: keep using the boards list as is (broadcast)
1047
1048 double timer_start =0;
1049 double timer_end =0;
1050
1051 if (downloader.connected == false){
1052 *resultString ="Driver not running";
1053 return false;
1054 }
1055
1056 //check if at least one board was selected
1057 bool at_least_one_board_selected = false;
1058 int i = 0;
1059
1060 for (i=0; i<downloader.board_list_size; i++){
1061 if (downloader.board_list[i].status==BOARD_RUNNING &&
1062 downloader.board_list[i].selected==true)
1063 at_least_one_board_selected = true;
1064 }
1065
1066 if (!at_least_one_board_selected){
1067 *resultString = "No Boards selected! - Select one or more boards to update the firmware";
1068 return false;
1069 }
1070 if (downloader.open_file(filename.toLatin1().data())!=0){
1071 *resultString = "Error opening the selected file!";
1072 return false;
1073 }
1074 //TODO
1075//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1076 // if (strstr (buffer, "calibrationDataSN") != 0)
1077 // {
1078 // load_calibration (buffer);
1079 // return ALL_OK;
1080 // }
1081//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1082
1083 // Get an identification of the firmware fot the file that you have selected
1084 int firmware_board_type=0;
1085 int firmware_version=0;
1086 int firmware_revision=0;
1087
1088 //indentify download type from the type of the selected boards
1089 int download_type = icubCanProto_boardType__unknown;
1090 bool download_eeprom =false;
1091 for (i=0; i<downloader.board_list_size; i++)
1092 {
1093 if (downloader.board_list[i].selected==true)
1094 {
1095 download_type = downloader.board_list[i].type;
1096 download_eeprom = downloader.board_list[i].eeprom;
1097 }
1098
1099 }
1100 download_eeprom = ee;
1101
1102 // Start the download for the selected boards
1103 for (i=0; i<downloader.board_list_size; i++){
1104 if (downloader.board_list[i].status==BOARD_RUNNING && downloader.board_list[i].selected==true){
1105 //bool EE = downloader.board_list[i].eeprom;
1106 bool EE = ee;
1107 if (downloader.startscheda(downloader.board_list[i].bus, downloader.board_list[i].pid, EE, downloader.board_list[i].type)!=0){
1108 *resultString = "Unable to start the board - Unable to send message 'start' or no answer received";
1109 return false;
1110 } else {
1111 downloader.board_list[i].status=BOARD_WAITING;
1112 }
1113 }
1114 }
1115
1116 int ret = 0;
1117 int finished = 0;
1118
1119 timer_start= yarp::os::Time::now();
1120
1121// bool acemortest_notyetstopped = true;
1122// const float acemortest_progress = 0.10;
1123
1124 bool print00 = false, print25 = false, print50 = false, print75 = false, print99 = false;
1125 // Start the download for the selected boards
1126 do
1127 {
1128 ret = downloader.download_file(CanPacket::everyCANbus, 0x0F, download_type,download_eeprom);
1129 if (float(downloader.progress)/downloader.file_length >0.0 && print00==false) {if(verbosity>0) qDebug("programming %s: 1%% done",filename.toLatin1().data()); print00=true;}
1130 if (float(downloader.progress)/downloader.file_length >0.25 && print25==false) {if(verbosity>0) qDebug("programming %s: 25%% done",filename.toLatin1().data()); print25=true;}
1131 if (float(downloader.progress)/downloader.file_length >0.50 && print50==false) {if(verbosity>0) qDebug("programming %s: 50%% done",filename.toLatin1().data()); print50=true;}
1132 if (float(downloader.progress)/downloader.file_length >0.75 && print75==false) {if(verbosity>0) qDebug("programming %s: 75%% done",filename.toLatin1().data()); print75=true;}
1133 if (float(downloader.progress)/downloader.file_length >0.99 && print99==false) {if(verbosity>0) qDebug("programming %s: finished!",filename.toLatin1().data()); print99=true;}
1134
1135// if ((float(downloader.progress)/downloader.file_length > acemortest_progress) && (acemortest_notyetstopped))
1136// {
1137// // place you breakpoint in here.
1138// acemortest_notyetstopped = false;
1139// }
1140
1141 if (ret==1)
1142 {
1143 updateProgress(float(downloader.progress)/downloader.file_length);
1144 }
1145 if (ret==-1)
1146 {
1147 *resultString = "Fatal Error during download, terminate";
1148 finished = 1;
1149 }
1150 if (ret==0)
1151 {
1152 *resultString = "Download terminated";
1153 finished = 1;
1154 }
1155
1156 }
1157 while (finished!=1);
1158 timer_end= yarp::os::Time::now();
1159
1160 // End the download for the selected boards
1161 int errors =0;
1162 downloader.stopscheda(CanPacket::everyCANbus, 15);
1163
1164
1165
1166 yarp::os::Time::delay(3.0);
1167 //Display result message
1168 if (ret == 0)
1169 {
1170 char time_text [50];
1171 double download_time = (timer_end-timer_start) ;
1172 sprintf (time_text, "All Board OK! Download Time (s): %.2f", download_time);
1173
1174 *resultString = QString("Download Finished. %1").arg(time_text);
1175
1176 updateProgress(1.0);
1177 downloader.initschede();
1178
1179 canBoards.clear();
1180 for(int i=0; i<downloader.board_list_size;i++){
1181 canBoards.append(downloader.board_list[i]);
1182 }
1183 if(resultCanBoards){
1184 *resultCanBoards = canBoards;
1185 }
1186 return true;
1187 }
1188 else
1189 {
1190 //*resultString = "Error during file transfer";
1191
1192 updateProgress(1.0);
1193 downloader.initschede();
1194 return false;
1195 }
1196 downloader.initschede();
1197
1198 canBoards.clear();
1199 for(int i=0; i<downloader.board_list_size;i++){
1200 canBoards.append(downloader.board_list[i]);
1201 }
1202 *resultCanBoards = canBoards;
1203 return true;
1204}
1205#endif
1206
1207bool FirmwareUpdaterCore::uploadEthApplication(QString filename,QString *resultString)
1208{
1209 mutex.lock();
1210 FILE *programFile=fopen(filename.toLatin1().data(),"r");
1211// if(verbosity>0) qDebug() << "attempting opening the selected file:" << filename << "or .." << filename.toLatin1().data();
1212 if (!programFile){
1213 //TODO ERROR
1214 if(verbosity>0) qDebug() << "Error opening the selected file:" << filename << "or .." << filename.toLatin1().data();
1215 mutex.unlock();
1216 return false;
1217 }
1218 eOipv4addr_t ipv4 = 0; // all selected
1219 eObrd_ethtype_t type = eobrd_ethtype_none;
1220 eOversion_t ver;
1221 ver.major = 0;
1222 ver.minor = 0;
1223 std::string result;
1224 bool ok = gMNT.program(ipv4, type, eApplication, ver, programFile, false, updateProgressCallback, false);
1225
1226 fclose(programFile);
1227
1228 *resultString = QString("%1").arg(result.c_str());
1229 if(ok){
1230 mutex.unlock();
1231 return true;
1232 }
1233 mutex.unlock();
1234 return false;
1235}
1236
1237
1238
1240{
1241 return &downloader;
1242}
1243
1244
1245
1247{
1248 mutex.lock();
1250 mutex.unlock();
1251}
1252
1253
1255{
1256 mutex.lock();
1257 gMNT.command_def2run(EthMaintainer::ipv4OfAllSelected, eApplication, false, false);
1258 mutex.unlock();
1259}
1260
1262{
1263 mutex.lock();
1264 gMNT.command_def2run(EthMaintainer::ipv4OfAllSelected, eUpdater, false, false);
1265 mutex.unlock();
1266}
eOipv4addr_t acetoipv4(ACE_UINT32 address)
ACE_UINT32 ipv4toace(eOipv4addr_t ipv4)
@ everyCANbus
Definition driver.h:51
std::string moreinformation(eOipv4addr_t ipv4, bool forcemaintenance=false)
bool command_jump2updater(eOipv4addr_t ipv4)
EthBoardList discover(bool clearbeforediscovery=true, int numberofdiscoveries=1, double waittimeout=1.0)
static const eOipv4addr_t ipv4OfAllSelected
bool open(eOipv4addr_t ipv4=hostIPaddress, eOipv4port_t port=mainIPport)
bool command_def2run(eOipv4addr_t ipv4, eOuprot_process_t process, bool forcemaintenance=true, bool verify=true)
bool go2application(eOipv4addr_t ipv4, bool checkdef2runapplication=true, double bootstraptime=10.0, bool verify=true)
EthBoardList & boards_get(void)
void verbose(bool on)
bool go2maintenance(eOipv4addr_t ipv4, bool verify=true, int retries=6, double timegap=1.0)
bool command_info32_set(eOipv4addr_t ipv4, const string &info32)
vector< string > command_info32_get(eOipv4addr_t ipv4)
bool command_blink(eOipv4addr_t ipv4)
bool program(eOipv4addr_t ipv4, eObrd_ethtype_t type, eOuprot_process_t process, eOversion_t targetversion, FILE *fp, bool forcemaintenance=true, void progress(float)=NULL, bool restart2application=true)
bool command_eeprom_erase(eOipv4addr_t ipv4)
bool command_restart(eOipv4addr_t ipv4)
bool command_changeaddress(eOipv4addr_t ipv4, eOipv4addr_t ipv4new, bool checkifnewispresent=true, bool forcemaintenance=true, bool restart=false, bool verify=false)
QList< sBoard > discoverSingleCanBoardViaEth(QString address, int canID, int canAddress, QString *retString)
QList< sBoard > getCanBoardsFromDriver(QString driver, int networkId, QString *retString, bool force=false)
int connectTo(QString device, QString id)
void setSelectedCanBoards(QList< sBoard > selectedBoards, QString address, int deviceId=-1)
bool setEthBoardAddress(int index, QString newAddress)
bool uploadCanApplication(QString filename, QString *resultString, bool ee, QString address="", int deviceId=-1, QList< sBoard > *resultCanBoards=NULL)
QString getEthBoardInfo(int index)
QList< sBoard > getCanBoardsFromEth(QString address, QString *retString, int canID=CanPacket::everyCANbus, bool force=false)
void setSelectedEthBoard(int index, bool selected)
void disconnectFrom(QString device, QString id)
FirmwareUpdaterCore(QObject *parent=0)
void setSelectedCanBoard(int index, bool selected, QString ethAddress="", int deviceId=-1)
QString getProcessFromUint(uint8_t id, bool isMultiCore=false, eObrd_ethtype_t boardtype=eobrd_ethtype_unknown)
QString getEthBoardAddress(int index)
boardInfo2_t getMoreDetails(int boardNum=EthMaintainer::ipv4OfAllSelected, QString *infoString=NULL, eOipv4addr_t *address=NULL)
QList< QPair< QString, QVariant > > getDevices()
void updateProgress(float)
bool setEthBoardInfo(int index, QString newInfo)
bool uploadUpdater(QString filename, QString *resultString)
bool isBoardInMaintenanceMode(QString ip)
void setCanBoardInfo(int bus, int id, QString newInfo, QString ethAddress="", int deviceId=-1, QString *resultString=NULL)
bool setCanBoardAddress(int bus, int id, int canType, QString newAddress, QString ethAddress="", int deviceId=-1, QString *resultString=NULL)
bool uploadEthApplication(QString filename, QString *resultString)
bool uploadLoader(QString filename, QString *resultString)
bool init(Searchable &config, int port, QString address, int VerbositY)
int open_file(std::string file)
int change_card_address(int bus, int target_id, int new_id, int board_type)
int initSINGLEBOARD(int canbus, int canaddress)
int startscheda(int bus, int board_pid, bool board_eeprom, int download_type)
int stopscheda(int bus, int board_pid)
void set_verbose(bool verbose)
int change_board_info(int bus, int target_id, char *board_info)
int initdriver(yarp::os::Searchable &config, bool verbose=true)
sBoard * board_list
Definition downloader.h:150
int board_list_size
Definition downloader.h:151
int download_file(int bus, int board_pid, int download_type, bool eeprom)
#define BOARD_RUNNING
Definition downloader.h:45
#define BOARD_WAITING
Definition downloader.h:46
FirmwareUpdaterCore * self
static void updateProgressCallback(float fraction)
#define DEFAULT_IP_ADDRESS
#define DEFAULT_IP_PORT
int canID
Definition main.cpp:152
std::string networkType
Definition main.cpp:156
unsigned int remoteAddr
Definition main.cpp:154
unsigned int localAddr
Definition main.cpp:153
int networkId
Definition main.cpp:151
fclose(fileID)
bool eeprom
Definition downloader.h:39
int bus
Definition downloader.h:25
int type
Definition downloader.h:27
int pid
Definition downloader.h:26
int status
Definition downloader.h:37
bool selected
Definition downloader.h:38