RDK Documentation (Open Sourced RDK Components)
deviceUpdateMgrMain.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 /* * imgUpdateMgrMain.cpp
20  *
21  * Created on: Jul 23, 2014
22  * Author: tlemmons
23  */
24 
25 
26 
27 /**
28 * @defgroup iarmmgrs
29 * @{
30 * @defgroup deviceUpdateMgr
31 * @{
32 **/
33 
34 
35 #ifdef __cplusplus
36 extern "C"
37 {
38 #endif
39 #include <stdio.h>
40 #include <stdlib.h>
41 #ifdef __cplusplus
42 }
43 #endif
44 
45 #include "libIBus.h"
46 #include "iarmUtil.h"
47 #include "deviceUpdateMgr.h"
48 #include "deviceUpdateMgrInternal.h"
49 #include "jsonParser.h"
50 #include <assert.h>
51 #include <iostream>
52 #include <fstream>
53 #include <list>
54 #include <sys/stat.h>
55 #include <dirent.h>
56 #include <errno.h>
57 #include <vector>
58 #include <string>
59 #include <iostream>
60 #include <utils.h>
61 
62 #include "safec_lib.h"
63 
64 extern "C"
65 {
66 #ifdef YOCTO_BUILD
67 #include "secure_wrapper.h"
68 #endif
69 bool loadConfig();
70 pthread_mutex_t tMutexLock;
71 IARM_Result_t AcceptUpdate(void *arg);
72 void sendDownLoadInit(int id);
73 void sendLoadInit(int id);
74 bool getEventData(string filename, _IARM_Bus_DeviceUpdate_Announce_t *myData);
75 void processDeviceFile(string filePath, string);
76 void processDeviceFolder(string updatePath, string);
77 IARM_Result_t deviceUpdateStart(void);
78 void deviceUpdateRun(list<JSONParser::varVal *> *folders);
79 IARM_Result_t deviceUpdateStop(void);
80 bool initialized = false;
81 void _deviceUpdateEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
82 int nextID = 1;
83 map<string, JSONParser::varVal *> configuration;
84 
85 string serverUpdatePath= "/srv/device_update/";
86 string tempFilePath="/tmp/devUpdate/";
87 bool interactiveDownload=false;
88 bool interactiveLoad=false;
89 int loadDelayType=0;
90 int loadTimeAfterInactive=0;
91 int timeToLoad=0;
92 bool backgroundDownload=true;
93 int requestedPercentIncrement=10;
94 int recheckForUpdatesMin=0;
95 bool loadImageImmediately=false;
96 bool forceUpdate=false;
97 int loadBeforeHour=4;
98 int delayTillAnnounceTimeMin=10; // default is announce after 10 min;
99 int announceCounter=10; // counter for wait seconds
100 bool oneAnnouncePerRun=false;
101 
102 
103 
104 
105 static pthread_mutex_t mapMutex;
106 }
107 typedef struct updateInProgress_t
108 {
110  int downloadPercent;
111  bool loadComplete;
112  int errorCode;
113  string errorMsg;
114 
116 
117 map<int, updateInProgress_t *> *updatesInProgress = new map<int, updateInProgress_t *>();
118 bool running = true;
119 
120 #ifdef RDK_LOGGER_ENABLED
121 
122 int b_rdk_logger_enabled = 0;
123 
124 void logCallback(const char *buff)
125 {
126  INT_LOG("%s",buff);
127 }
128 #endif
129 int main(int argc, char *argv[])
130 {
131  const char* debugConfigFile = NULL;
132  int itr = 0;
133 
134  while (itr < argc)
135  {
136  if (strcmp(argv[itr], "--debugconfig") == 0)
137  {
138  itr++;
139  if (itr < argc)
140  {
141  debugConfigFile = argv[itr];
142  }
143  else
144  {
145  break;
146  }
147  }
148  itr++;
149  }
150 
151 #ifdef RDK_LOGGER_ENABLED
152 
153  if(rdk_logger_init(debugConfigFile) == 0) b_rdk_logger_enabled = 1;
154  IARM_Bus_RegisterForLog(logCallback);
155 
156 #endif
157 
158 
159  time_t tim=time(NULL);
160  tm *now=localtime(&tim);
161  INT_LOG("Date is %d/%02d/%02d\n", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
162  INT_LOG("Time is %02d:%02d\n", now->tm_hour, now->tm_min);
163 
164 
165  if (deviceUpdateStart() == IARM_RESULT_SUCCESS)
166  {
167  loadConfig();
168  JSONParser::varVal *folderRef=configuration["deviceFoldersToWatch"];
169  if(folderRef!=NULL){
170  list<JSONParser::varVal *> *folders = folderRef->array;
171  deviceUpdateRun(folders);
172  }else{
173  INT_LOG("NO FOLDERS IN CONFIG FILE!!!!!!!!!!");
174  }
175  }
176  deviceUpdateStop();
177  return 0;
178 }
179 
180 IARM_Result_t deviceUpdateStart()
181 {
182 
183  IARM_Result_t status = IARM_RESULT_INVALID_STATE;
184 
185  INT_LOG("Entering [%s] - [%s] - disabling io redirect buf\n", __FUNCTION__, IARM_BUS_DEVICE_UPDATE_NAME);
186  setvbuf(stdout, NULL, _IOLBF, 0);
187  int ret = pthread_mutex_init(&mapMutex, NULL);
188  if(ret != 0) {
189  INT_LOG(" pthread_mutex_init Error case: %d\n", __LINE__);
190  status = IARM_RESULT_INVALID_STATE;
191  }
192  if (!initialized)
193  {
194  IARM_Result_t rc;
195 
196  int retval = pthread_mutex_init(&tMutexLock, NULL);
197  if(retval != 0) {
198  INT_LOG(" pthread_mutex_init Error case: %d\n", __LINE__);
199  }
200  pthread_mutex_lock(&tMutexLock);
202  INT_LOG("dumMgr:I-ARM IARM_Bus_Init Mgr: %d\n", rc);
203 
204  rc = IARM_Bus_Connect();
205  INT_LOG("dumMgr:I-ARM IARM_Bus_Connect Mgr: %d\n", rc);
206 
207  rc = IARM_Bus_RegisterEvent(IARM_BUS_DEVICE_UPDATE_EVENT_MAX);
208  INT_LOG("dumMgr:I-ARM IARM_Bus_RegisterEvent Mgr: %d\n", rc);
209 
210  rc = IARM_Bus_RegisterCall( IARM_BUS_DEVICE_UPDATE_API_AcceptUpdate, AcceptUpdate); /* RPC Method Implementation*/
211  INT_LOG("dumMgr:I-ARM IARM_BUS_DEVICE_UPDATE_API_AcceptUpdate Mgr: %d\n", rc);
212 
213  IARM_Bus_RegisterEventHandler(IARM_BUS_DEVICE_UPDATE_NAME, IARM_BUS_DEVICE_UPDATE_EVENT_READY_TO_DOWNLOAD,
214  _deviceUpdateEventHandler);
215  IARM_Bus_RegisterEventHandler(IARM_BUS_DEVICE_UPDATE_NAME, IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS,
216  _deviceUpdateEventHandler);
217  IARM_Bus_RegisterEventHandler(IARM_BUS_DEVICE_UPDATE_NAME, IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_STATUS,
218  _deviceUpdateEventHandler);
219  IARM_Bus_RegisterEventHandler(IARM_BUS_DEVICE_UPDATE_NAME, IARM_BUS_DEVICE_UPDATE_EVENT_ERROR,
220  _deviceUpdateEventHandler);
221 
222  initialized = 1;
223 
224  pthread_mutex_unlock(&tMutexLock);
225  status = IARM_RESULT_SUCCESS;
226  }
227  else
228  {
229  __TIMESTAMP();
230  INT_LOG("dumMgr: I-ARM Device Update Mgr Error case: %d\n", __LINE__);
231  status = IARM_RESULT_INVALID_STATE;
232  }
233  return status;
234 }
235 
236 bool loadConfig()
237 {
238  string confName = "deviceUpdateConfig.json";
239  FILE *fp = NULL;
240  string filePath;
241 
242 // Check if file exists in /opt
243  filePath = "/opt/" + confName;
244 
245  if (!_fileExists(filePath))
246  {
247  filePath = "/mnt/nfs/env/" + confName;
248  if (!_fileExists(filePath))
249  {
250  filePath = "/etc/" + confName;
251  if (!_fileExists(filePath))
252  {
253  filePath = confName;
254  if (!_fileExists(filePath))
255  {
256  __TIMESTAMP();
257  INT_LOG(
258  "I-ARM DevUpdate Mgr: Configuration error. Configuration file(s) missing, no folders to watch!!\n");
259  return false;
260  }
261  }
262  }
263  }
264 
265  __TIMESTAMP();
266  INT_LOG("loading config file %s\n", filePath.c_str());
267  if ((fp = fopen(filePath.c_str(), "r")) != NULL)
268  {
269  string confData;
270  char buf[2048] = ""; //CID:136517 - string null
271 
272  while (!feof(fp) && confData.length() < 65535)
273  {
274  memset(buf,'\0', sizeof(buf)); //CID:136517 - checked null argument
275  if (0 >= fread(buf, 1, sizeof(buf) - 1, fp)) //cID:86017 - checked return
276  {
277  INT_LOG("dumMgr fread failed \n");
278  }
279  else
280  {
281  confData.append(buf);
282  }
283  }
284 
285  if (fp)
286  fclose(fp);
287 
288 // LOG("dumMgr: Configuration Read <%s>\n", confData.c_str());
289 
290  JSONParser parser;
291 
292  configuration = parser.parse((const unsigned char *) confData.c_str());
293 
294 // for (map<string, JSONParser::varVal *>::iterator pos = configuration.begin(); pos != configuration.end(); pos++)
295 // {
296 // if (pos->second->str.length() > 0)
297 // {
298 //// LOG("config string: %s=%s\n", pos->first.c_str(), pos->second->str.c_str());
299 // }
300 // else if (pos->second->array != NULL)
301 // {
302 // for (list<JSONParser::varVal *>::iterator arrayItr = pos->second->array->begin();
303 // arrayItr != pos->second->array->end(); arrayItr++)
304 // {
305 // if ((*arrayItr)->str.length() > 0)
306 // LOG("array:%s string: %s\n", pos->first.c_str(), (*arrayItr)->str.c_str());
307 // }
308 // }
309 // else
310 // {
311 // LOG("config string: %s=%s\n", pos->first.c_str(), pos->second->boolean ? "true" : "false");
312 // }
313 // }
314 
315  }
316 
317  if(configuration["serverUpdatePath"]!=NULL)
318  {
319  serverUpdatePath=configuration["serverUpdatePath"]->str;
320  }
321  else{
322  INT_LOG("error: no serverUpdatePath in config\n");
323  }
324  if(configuration["tempFilePath"]!=NULL)
325  {
326  tempFilePath=configuration["tempFilePath"]->str;
327  }
328  else{
329  INT_LOG("error: no tempFilePath in config\n");
330  }
331  if(configuration["forceUpdate"]!=NULL)
332  {
333  forceUpdate=configuration["forceUpdate"]->boolean;
334  }
335  else{
336  INT_LOG("error: no forceUpdate in config\n");
337  }
338  if(configuration["interactiveDownload"]!=NULL)
339  {
340  interactiveDownload=configuration["interactiveDownload"]->boolean;
341  }
342  else{
343  INT_LOG("error: no interactiveDownload in config\n");
344  }
345  if(configuration["interactiveLoad"]!=NULL)
346  {
347  interactiveLoad=configuration["interactiveLoad"]->boolean;
348  }
349  else{
350  INT_LOG("error: no interactiveLoad in config\n");
351  }
352  if(configuration["loadDelayType"]!=NULL)
353  {
354  loadDelayType=atoi(configuration["loadDelayType"]->str.c_str());
355  }
356  else{
357  INT_LOG("error: no loadDelayType in config\n");
358  }
359  if(configuration["loadTimeAfterInactive"]!=NULL)
360  {
361  loadTimeAfterInactive=atoi(configuration["loadTimeAfterInactive"]->str.c_str());
362  }
363  else{
364  INT_LOG("error: no loadTimeAfterInactive in config\n");
365  }
366  if(configuration["timeToLoad"]!=NULL)
367  {
368  timeToLoad=atoi(configuration["timeToLoad"]->str.c_str());
369  }
370  else{
371  INT_LOG("error: no timeToLoad in config\n");
372  }
373  if(configuration["backgroundDownload"]!=NULL)
374  {
375  backgroundDownload=configuration["backgroundDownload"]->boolean;
376  INT_LOG ("setting backgroundDownload=%s\n",backgroundDownload?"true":"false");
377  }
378  else{
379  INT_LOG("error: no backgroundDownload in config\n");
380  }
381 
382  if(configuration["loadImageImmediately"]!=NULL)
383  {
384  loadImageImmediately=configuration["loadImageImmediately"]->boolean;
385  INT_LOG ("setting loadImageImmediately=%s\n",loadImageImmediately?"true":"false");
386  }
387  else{
388  INT_LOG("error: no loadImageImmediately in config\n");
389  }
390 
391  if(configuration["loadBeforeHour"]!=NULL)
392  {
393  loadBeforeHour=atoi(configuration["loadBeforeHour"]->str.c_str());;
394  }
395  else{
396  INT_LOG("error: no loadBeforeHour in config\n");
397  }
398 
399  if(configuration["requestedPercentIncrement"]!=NULL)
400  {
401  requestedPercentIncrement=atoi(configuration["requestedPercentIncrement"]->str.c_str());
402  }
403  else{
404  INT_LOG("error: no requestedPercentIncrement in config\n");
405  }
406  if(configuration["recheckForUpdatesMin"]!=NULL)
407  {
408  recheckForUpdatesMin=atoi(configuration["recheckForUpdatesMin"]->str.c_str());
409  }
410  if(configuration["delayTillAnnounceTimeMin"]!=NULL)
411  {
412  delayTillAnnounceTimeMin=atoi(configuration["delayTillAnnounceTimeMin"]->str.c_str());
413  INT_LOG ("setting delayTillAnnounceTimeMin=%d\n",delayTillAnnounceTimeMin);
414  }
415  else{
416  INT_LOG("warning: no delayTillAnnounceTimeMin in config!\n");
417  }
418  if(configuration["oneAnnouncePerRun"]!=NULL)
419  {
420  oneAnnouncePerRun=configuration["oneAnnouncePerRun"]->boolean;
421  INT_LOG ("setting oneAnnouncePerRun=%s\n",oneAnnouncePerRun?"true":"false");
422  }
423  else{
424  INT_LOG("warning: no oneAnnouncePerRun in config!\n");
425  }
426 
427  __TIMESTAMP();
428  INT_LOG("running with config:\n");
429  INT_LOG (" serverUpdatePath= %s\n",serverUpdatePath.c_str());
430  INT_LOG (" tempFilePath=%s\n",tempFilePath.c_str());
431  INT_LOG (" interactiveDownload=%s\n",interactiveDownload?"true":"false");
432  INT_LOG (" interactiveLoad=%s\n",interactiveLoad?"true":"false");
433  INT_LOG (" loadDelayType=%d\n",loadDelayType);
434  INT_LOG (" loadTimeAfterInactive=%d\n",loadTimeAfterInactive);
435  INT_LOG (" timeToLoad=%d\n",timeToLoad);
436  INT_LOG (" backgroundDownload=%s\n",backgroundDownload?"true":"false");
437  INT_LOG (" loadImageImmediately=%s\n",loadImageImmediately?"true":"false");
438  INT_LOG (" loadBeforeHour=%d\n",loadBeforeHour);
439  INT_LOG (" requestedPercentIncrement=%d\n",requestedPercentIncrement);
440  INT_LOG (" recheckForUpdatesMin=%d\n",recheckForUpdatesMin);
441  INT_LOG (" delayTillAnnounceTimeMin=%d\n",delayTillAnnounceTimeMin);
442  return true;
443 }
444 
445 //bool loadTextConfig()
446 //{
447 // string confName = "deviceUpdateConfig.json";
448 // string filePath;
449 //
450 //// Check if file exists in /opt
451 // filePath = "/opt/" + confName;
452 //
453 // if (!_fileExists(filePath))
454 // {
455 // filePath = "/mnt/nfs/env/" + confName;
456 // if (!_fileExists(filePath))
457 // {
458 // filePath = confName;
459 // if (!_fileExists(filePath))
460 // {
461 // LOG(
462 // "I-ARM DevUpdate Mgr: Configuration error. Configuration file(s) missing, no folders to watch!!\n");
463 // return false;
464 // }
465 // }
466 // }
467 //
468 // LOG("loading config file %s\n", filePath.c_str());
469 // string line;
470 // std::ifstream myfile(filePath.c_str(), ios_base::in);
471 // string updatePath;
472 //// TODO decide on config format. Currently one device type to watch per line in text file
473 // if (myfile.is_open())
474 // {
475 // while (myfile.good())
476 // {
477 // getline(myfile, line);
478 // if (line.size() > 0)
479 // {
480 // updatePath = serverUpdatePath + line;
481 // LOG("I-ARM DevUpdate Mgr: checking folder location <%s>\n", updatePath.c_str());
482 // if (_folderExists(updatePath))
483 // {
484 // LOG("I-ARM DevUpdate Mgr: processing folder location <%s>\n", updatePath.c_str());
485 // processDeviceFolder(updatePath, line);
486 //
487 // }
488 // }
489 // }
490 // myfile.close();
491 // }
492 // else
493 // {
494 // LOG("I-ARM DevUpdate Mgr: Configuration error. Unable to open file\n");
495 // return false;
496 // }
497 // return true;
498 //}
499 
500 void processDeviceFolder(string updatePath, string deviceName)
501 {
502  DIR *dp;
503  struct dirent *dirp;
504  INT_LOG("dumMgr:processing device folder:%s\n", updatePath.c_str());
505  if ((dp = opendir(updatePath.c_str())) == NULL)
506  {
507  INT_LOG("dumMgr:Error(%d) opening updatePath \n", errno);
508  return;
509  }
510 
511 // loop through dir listing and get normal files
512  INT_LOG("dumMgr:checking folder files\n");
513  while ((dirp = readdir(dp)) != NULL)
514  {
515  INT_LOG("dumMgr:checking folder files:%s - type=%d\n",dirp->d_name,dirp->d_type);
516  if (dirp->d_type != DT_DIR)
517  {
518  // check for it being either a tgz or tar.gz file
519  string filename = dirp->d_name;
520  INT_LOG("dumMgr:checking file:%s\n", filename.c_str());
521  unsigned int idx = filename.rfind('.');
522  if (idx != string::npos)
523  {
524  string ext = filename.substr(idx + 1);
525  if (ext == "gz")
526  {
527  idx = filename.rfind('.', idx);
528  if (idx == string::npos)
529  {
530  continue;
531  }
532  string ext = filename.substr(idx + 1);
533  if (ext == "tar.gz")
534  {
535  processDeviceFile(updatePath + "/" + filename, deviceName);
536  continue;
537  }
538  }
539  if (ext == "tgz")
540  {
541  processDeviceFile(updatePath + "/" + filename, deviceName);
542  continue;
543  }
544  }
545 
546  }
547  }
548  closedir(dp);
549 }
550 
551 void processDeviceFile(string filePath, string deviceName)
552 {
553  INT_LOG("dumMgr:processing Device File:%s\n", filePath.c_str());
554  string cmd = "rm -rf ";
555  cmd += tempFilePath;
556 #ifdef YOCTO_BUILD
557  v_secure_system(cmd.c_str());
558 #else
559  system(cmd.c_str());
560 #endif
561  cmd = "mkdir ";
562  cmd += tempFilePath;
563 #ifdef YOCTO_BUILD
564  v_secure_system(cmd.c_str());
565 #else
566  system(cmd.c_str());
567 #endif
568  cmd = "tar -xzpf " + filePath + " -C " + tempFilePath;
569 #ifdef YOCTO_BUILD
570  v_secure_system(cmd.c_str());
571 #else
572  system(cmd.c_str());
573 #endif
574  vector<string> *myfiles = getdir(tempFilePath);
575  vector<string>::iterator itr;
576  if(myfiles != NULL)
577  {
578  INT_LOG("dumMgr: searching Device File:%s\n", filePath.c_str());
579  for (itr = myfiles->begin(); itr != myfiles->end(); itr++)
580  {
581  string filename = *itr;
582  // LOG("dumMgr:found file:%s\n", filename.c_str());
583  int idx = filename.rfind('.');
584  if (idx == string::npos)
585  {
586  continue;
587  }
588  string ext = filename.substr(idx + 1);
589  // LOG("dumMgr:extension:%s\n", ext.c_str());
590  if (ext == "xml")
591  {
593  strncpy(myData.deviceImageFilePath, filePath.c_str(), (IARM_BUS_DEVICE_UPDATE_PATH_LENGTH - 1));
594  myData.deviceImageFilePath[IARM_BUS_DEVICE_UPDATE_PATH_LENGTH - 1] = 0;
595  if (getEventData(tempFilePath + filename, &myData))
596  {
597  __TIMESTAMP();
598  INT_LOG("dumMgr:sending announce event");
599  IARM_Result_t retval = IARM_Bus_BroadcastEvent(
600  IARM_BUS_DEVICE_UPDATE_NAME, (IARM_EventId_t) IARM_BUS_DEVICE_UPDATE_EVENT_ANNOUNCE, (void *) &myData,
602  if (retval == IARM_RESULT_SUCCESS)
603  {
604  // __TIMESTAMP();
605  // LOG("dumMgr:Announce Event sent successfully\n");
606  }
607  else
608  {
609  __TIMESTAMP();
610  INT_LOG("dumMgr:Announce Event problem, %i\n", retval);
611  }
612  }
613  }
614  }
615  delete myfiles;
616  }
617  else
618  {
619  INT_LOG("dumMgr: Failed in searching Device File:[%s]. getdir returned NULL\n", filePath.c_str());;
620  }
621 
622 }
623 
624 string getXMLTagText(string xml, string tag)
625 {
626 
627 //TODO currently this assume no spaces or tabs in the tag brackets. and no leading trailing spaces in text content
628  int idx = xml.find("<" + tag);
629  if (idx == string::npos)
630  {
631  INT_LOG("dumMgr:tag <%s> not found in xml file: aborting\n", tag.c_str());
632  return "";
633  }
634 // skip past the tag and its two brackets:
635  idx += tag.length() + 2;
636 
637 // find end tag
638  int idx2 = xml.find("</" + tag);
639 
640 //grab all content between start and end tag
641  return xml.substr(idx, idx2 - idx);
642 
643 }
644 
645 bool getEventData(string filename, _IARM_Bus_DeviceUpdate_Announce_t *myData)
646 {
647  errno_t rc = -1;
648  string fileContents;
649  std::ifstream myfile;
650 
651  INT_LOG("dumMgr:--------------------Checking tar File %s\n", filename.c_str());
652  myfile.open(filename.c_str(), std::ifstream::in);
653  if (myfile.is_open())
654  {
655  myfile.seekg(0, myfile.end);
656  int length = myfile.tellg();
657  myfile.seekg(0, myfile.beg);
658  char * buffer = new char[length + 1];
659  if(buffer == NULL)
660  {
661  return false;
662  }
663  myfile.read(buffer, length);
664  myfile.close();
665  fileContents = buffer;
666  delete[] buffer;
667  }
668 
669  string text = getXMLTagText(fileContents, "image:softwareVersion");
670  if (text.length() == 0)
671  {
672  INT_LOG("dumMgr:--------------------Missing Version %s\n", filename.c_str());
673  return false;
674  }
675  rc = strcpy_s(myData->deviceImageVersion,sizeof(myData->deviceImageVersion), text.c_str());
676  if(rc!=EOK)
677  {
678  ERR_CHK(rc);
679  }
680 
681  text = getXMLTagText(fileContents, "image:type");
682  myData->deviceImageType = atoi(text.c_str());
683 
684  text = getXMLTagText(fileContents, "image:productName");
685  rc = strcpy_s(myData->deviceName,sizeof(myData->deviceName), text.c_str());
686  if(rc!=EOK)
687  {
688  ERR_CHK(rc);
689  }
690 // LOG("dumMgr:version:%s", text.c_str());
691 // LOG(" type:%s", text.c_str());
692 // LOG("product name:%s\n", text.c_str());
693 
694  myData->forceUpdate = forceUpdate;
695  INT_LOG("dumMgr:--------------------Done with tar File %s\n", filename.c_str());
696  return true;
697 }
698 
699 void deviceUpdateRun(list<JSONParser::varVal *> *folders)
700 {
701  int i=0;
702  while (running)
703  {
704  i++;
705  sleep(1);
706  if(announceCounter==(delayTillAnnounceTimeMin*60)){
707  if (folders != NULL)
708  {
709  int numFolders=folders->size();
710  INT_LOG("We have %d folders to watch\n",numFolders);
711  if(oneAnnouncePerRun){
712  // since TI boxes can only announce one update we space updates on days of month to make
713  // sure all types get updated. This is a temporary hack until control manager takes over from
714  // rfMgr
715  time_t theTime = time(NULL);
716  struct tm *aTime = localtime(&theTime);
717  int day = aTime->tm_mday;
718  int selectedUpdate=day%(numFolders);
719  INT_LOG("today is :%d, so only checking folder %d (mod %d)\n",day,selectedUpdate,numFolders);
720 
721  for (list<JSONParser::varVal *>::iterator arrayItr = folders->begin(); arrayItr != folders->end();arrayItr++)
722  {
723  string updateFolder = (*arrayItr)->str;
724  if(selectedUpdate<=0){
725  string updatePath = serverUpdatePath + updateFolder;
726  INT_LOG("checking folder:%s\n",updatePath.c_str());
727 
728  if (updatePath.length() > 0)
729  {
730  if (_folderExists(updatePath))
731  {
732  INT_LOG("I-ARM DevUpdate Mgr: processing folder location <%s>\n", updatePath.c_str());
733  processDeviceFolder(updatePath, updateFolder);
734 
735  }
736  }
737  break;
738  }else{
739  INT_LOG("skipping folder:%s\n",updateFolder.c_str()); //CID:127614 - Print args
740  }
741  selectedUpdate--;
742  }
743  }
744  else
745  {
746  for (list<JSONParser::varVal *>::iterator arrayItr = folders->begin(); arrayItr != folders->end();arrayItr++)
747  {
748  string updateFolder = (*arrayItr)->str;
749  string updatePath = serverUpdatePath + updateFolder;
750  INT_LOG("checking folder:%s\n",updatePath.c_str());
751 
752  if (updatePath.length() > 0)
753  {
754  if (_folderExists(updatePath))
755  {
756  INT_LOG("I-ARM DevUpdate Mgr: processing folder location <%s>\n", updatePath.c_str());
757  processDeviceFolder(updatePath, updateFolder);
758 
759  }
760  }
761  }
762  }
763  __TIMESTAMP();
764  INT_LOG("Done with FOLDERS TO WATCH!!! \n");
765 
766  }
767  else
768  {
769  INT_LOG("ERROR - NO FOLDERS TO WATCH!!! \n");
770  }
771  }
772 
773  announceCounter++;
774 
775 
776  if(i>60){
777  if (updatesInProgress->size() > 0)
778  {
779  __TIMESTAMP();
780  INT_LOG("deviceUpdateMgr - updates in progress:\n");
781  map<int, updateInProgress_t *>::iterator pos = updatesInProgress->begin();
782  while (pos != updatesInProgress->end())
783  {
784  INT_LOG(" UpdateID:%d deviceID:%d percentDownload:%d Loaded:%d file:%s\n", pos->first,
785  pos->second->acceptParams->deviceID, pos->second->downloadPercent, pos->second->loadComplete,
786  pos->second->acceptParams->deviceImageFilePath);
787  if (pos->second->errorCode > 0)
788  {
789  INT_LOG(" ERROR on UpdateID:%d Type:%d Message:%s\n", pos->first, pos->second->errorCode,
790  pos->second->errorMsg.c_str());
791  }
792  pos++;
793  }
794 
795  }
796 i=0;
797  }
798  fflush(stdout);
799  }
800  return;
801 }
802 
803 IARM_Result_t AcceptUpdate(void *arg)
804 {
805  errno_t rc = -1;
806  __TIMESTAMP();
807  INT_LOG("dumMgr:Accept Update recieved\n");
810  param->updateSessionID = nextID++;
811  INT_LOG("dumMgr:update Session ID=%d\n", param->updateSessionID);
812  param->interactiveDownload = interactiveDownload;
813  param->interactiveLoad = interactiveLoad;
814  rc = memcpy_s(updateParams,sizeof(_IARM_Bus_DeviceUpdate_AcceptUpdate_Param_t), param, sizeof(_IARM_Bus_DeviceUpdate_AcceptUpdate_Param_t));
815  if(rc!=EOK)
816  {
817  ERR_CHK(rc);
818  }
820  uip->acceptParams = updateParams;
821  pthread_mutex_lock(&mapMutex);
822  updatesInProgress->insert(pair<int, updateInProgress_t *>(param->updateSessionID, uip));
823  pthread_mutex_unlock(&mapMutex);
824 
825  __TIMESTAMP();
826  INT_LOG("dumMgr:Accept Update return success\n");
827  return IARM_RESULT_SUCCESS;
828 }
829 
830 IARM_Result_t deviceUpdateStop(void)
831 {
832  if (initialized)
833  {
834  pthread_mutex_lock(&tMutexLock);
835  IARM_Bus_UnRegisterEventHandler(IARM_BUS_DEVICE_UPDATE_NAME, IARM_BUS_DEVICE_UPDATE_EVENT_READY_TO_DOWNLOAD);
837  IARM_Bus_Term();
838  pthread_mutex_unlock(&tMutexLock);
839  pthread_mutex_destroy(&tMutexLock);
840  initialized = false;
841  return IARM_RESULT_SUCCESS;
842  }
843  else
844  {
845  return IARM_RESULT_INVALID_STATE;
846  }
847 }
848 
849 typedef struct
850 {
851  string mimeType;
852  string subType;
853  string language;
854 } AudioInfo;
855 
856 updateInProgress_t *getUpdateInProgress(int id)
857 {
858  pthread_mutex_lock(&mapMutex);
859  updateInProgress_t *uip = updatesInProgress->find(id)->second;
860  pthread_mutex_unlock(&mapMutex);
861  return uip;
862 
863 }
864 
865 void _deviceUpdateEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
866 {
867 
868  /*Handle only Device Update Manager Events */
869  __TIMESTAMP();
870  if (strcmp(owner, IARM_BUS_DEVICE_UPDATE_NAME) == 0)
871  {
872  pthread_mutex_lock(&tMutexLock);
873 
874  switch (eventId)
875  {
876  case IARM_BUS_DEVICE_UPDATE_EVENT_READY_TO_DOWNLOAD:
877  {
879  INT_LOG("I-ARM: got event IARM_BUS_DEVICE_UPDATE_EVENT_READY_TO_DOWNLOAD\n");
880 
881  updateInProgress_t *uip = getUpdateInProgress(eventData->updateSessionID);
882 
883  if (uip != NULL)
884  {
885  INT_LOG("I-ARM: got valid updateSessionID Details:\n");
886  INT_LOG("I-ARM: currentSWVersion:%s\n", eventData->deviceCurrentSWVersion);
887  INT_LOG("I-ARM: newSWVersion:%s\n", eventData->deviceNewSoftwareVersion);
888  INT_LOG("I-ARM: deviceHWVersion:%s\n", eventData->deviceHWVersion);
889  INT_LOG("I-ARM: deviceBootloaderVersion:%s\n", eventData->deviceBootloaderVersion);
890  INT_LOG("I-ARM: deviceName:%s\n", eventData->deviceName);
891  INT_LOG("I-ARM: totalSize:%i\n", eventData->totalSize);
892  INT_LOG("I-ARM: deviceImageType:%i\n", eventData->deviceImageType);
893 
894  if(interactiveDownload==false){
895  sendDownLoadInit(eventData->updateSessionID);
896  }else
897  {
898  INT_LOG("I-ARM: Interactive Download is true so not sending download Init message\n");
899  }
900  }
901  else
902  {
903  INT_LOG("I-ARM: did not get valid updateSessionID Got id:%d\n", eventData->updateSessionID);
904  }
905 
906  }
907  break;
908  case IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS:
909  {
911  INT_LOG("I-ARM: got event IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS\n");
912  updateInProgress_t *uip = getUpdateInProgress(eventData->updateSessionID);
913 
914  if (uip != NULL)
915  {
916  INT_LOG("I-ARM: percentComplete:%i\n", eventData->percentComplete);
917 
918  uip->downloadPercent = eventData->percentComplete;
919  if(uip->downloadPercent>=100){
920  if(interactiveLoad==false){
921  sendLoadInit(eventData->updateSessionID);
922  }
923  else{
924  INT_LOG("I-ARM: Interactive load is true so not sending load Init message\n");
925  }
926  }
927  else{
928  INT_LOG("I-ARM: Not ready to load yet:%i\n", eventData->percentComplete);
929  }
930  }
931  else
932  {
933  INT_LOG("I-ARM: IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS invalid updateSessionID Got id:%d\n",
934  eventData->updateSessionID);
935  }
936  }
937  break;
938  case IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_STATUS:
939  {
941  INT_LOG("I-ARM: got event IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_STATUS\n");
942  updateInProgress_t *uip = getUpdateInProgress(eventData->updateSessionID);
943 
944  if (uip != NULL)
945  {
946  INT_LOG("I-ARM: Complete:%s\n", eventData->loadStatus == 1 ? "true" : "false");
947  uip->loadComplete = eventData->loadStatus == 1 ? true : false;
948  if (uip->loadComplete == 1)
949  {
950  INT_LOG("I-ARM:load Complete!!!\n");
951  // TODO should remove update from list???
952  }
953 
954  }
955  else
956  {
957  INT_LOG("I-ARM: IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS invalid updateSessionID Got id:%d\n",
958  eventData->updateSessionID);
959  }
960  }
961  break;
962  case IARM_BUS_DEVICE_UPDATE_EVENT_ERROR:
963  {
965  INT_LOG("I-ARM: got event IARM_BUS_DEVICE_UPDATE_EVENT_ERROR\n");
966 
967  updateInProgress_t *uip = getUpdateInProgress(eventData->updateSessionID);
968 
969  if (uip != NULL)
970  {
971  uip->errorCode = eventData->errorType;
972  uip->errorMsg.assign((const char *) (eventData->errorMessage));
973  INT_LOG("I-ARM: errorMessage:%s\n", eventData->errorMessage);
974  INT_LOG("I-ARM: errorType:%i\n", eventData->errorType);
975  }
976  else
977  {
978  INT_LOG("I-ARM: IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_STATUS invalid updateSessionID Got id:%d\n",
979  eventData->updateSessionID);
980  }
981  }
982  break;
983  default:
984  INT_LOG("I-ARM: unknown event type \n");
985  break;
986  }
987 
988  pthread_mutex_unlock(&tMutexLock);
989  }
990  else
991  {
992  __TIMESTAMP();
993  INT_LOG("I-ARM:_DevUpdateEventHandler event type not meant for me <%s>...\n", owner);
994  }
995 }
996 
997 void sendDownLoadInit(int id)
998 {
1000  updateInProgress_t *uip = getUpdateInProgress(id);
1001 
1002  memset(&eventData, 0, sizeof(eventData));
1003  eventData.updateSessionID = id;
1004  eventData.backgroundDownload = backgroundDownload;
1005  eventData.requestedPercentIncrement = requestedPercentIncrement;
1006  eventData.loadImageImmediately=loadImageImmediately;
1008  (IARM_EventId_t) IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_INITIATE, (void *) &eventData, sizeof(eventData));
1009  if (retval == IARM_RESULT_SUCCESS)
1010  {
1011  __TIMESTAMP();
1012  INT_LOG("I-ARM:IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_INITIATE Event sent successfully");
1013  }
1014  else
1015  {
1016  __TIMESTAMP();
1017  INT_LOG("I-ARM:IARM_BUS_DEVICE_UPDATE_EVENT_DOWNLOAD_INITIATE Event problem, %i", retval);
1018  }
1019 }
1020 
1021 void sendLoadInit(int id)
1022 {
1024  updateInProgress_t *uip = getUpdateInProgress(id);
1025 
1026  memset(&eventData, 0, sizeof(eventData));
1027  eventData.updateSessionID = id;
1028  eventData.loadDelayType = (IARM_Bus_Device_Update_LoadDelayType_t)loadDelayType;
1029  eventData.timeAfterInactive = loadTimeAfterInactive;
1030 
1031  // time to load is set to immediate if we are before the time of day as we normally reboot very early
1032  // morning and time to load should also be early morning
1033  // however we do a sanity check so if we reboot later in the day we hold off till load time using time to load
1034  time_t tim=time(NULL);
1035  tm *now=localtime(&tim);
1036  INT_LOG("Time is %02d:%02d\n", now->tm_hour, now->tm_min);
1037 
1038 
1039 
1040  INT_LOG("diff time is %i hours\n",loadBeforeHour-now->tm_hour);
1041  if(loadBeforeHour>now->tm_hour){
1042  // we are before the load time so load immedialy
1043  eventData.timeToLoad = 0;
1044  __TIMESTAMP();
1045  INT_LOG("doing immediate load\n");
1046  }else
1047  {
1048  // we are after the time so load at that time tomorrow
1049  // 24 hours worth of seconds pluss the negative number of diff time
1050  eventData.timeToLoad=(24+(loadBeforeHour-now->tm_hour))*60*60;
1051  __TIMESTAMP();
1052  INT_LOG("Waiting till tomorrow - delay of %i seconds\n",eventData.timeToLoad);
1053  }
1054 
1055  // force now
1056 // eventData.timeToLoad=60;
1057 
1059  (IARM_EventId_t) IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_INITIATE, (void *) &eventData, sizeof(eventData));
1060  if (retval == IARM_RESULT_SUCCESS)
1061  {
1062 
1063  __TIMESTAMP();
1064  INT_LOG("I-ARM:IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_INITIATE Event sent successfully");
1065  }
1066  else
1067  {
1068  __TIMESTAMP();
1069  INT_LOG("I-ARM:IARM_BUS_DEVICE_UPDATE_EVENT_LOAD_INITIATE Event problem, %i", retval);
1070  }
1071 }
1072 
1073 
1074 /** @} */
1075 /** @} */
JSONParser
Definition: jsonParser.h:43
AudioInfo
Definition: deviceUpdateMgrMain.cpp:849
IARM_Bus_Term
IARM_Result_t IARM_Bus_Term(void)
This API is used to terminate the IARM-Bus library.
JSONParser::varVal
Definition: jsonParser.h:49
updateInProgress_t
Definition: deviceUpdateMgrMain.cpp:107
_IARM_Bus_Device_Update_Error_t
Definition: deviceUpdateMgr.h:450
_IARM_Bus_DeviceUpdate_DownloadInitiate_t
Definition: deviceUpdateMgr.h:350
IARM_Bus_RegisterEvent
IARM_Result_t IARM_Bus_RegisterEvent(IARM_EventId_t maxEventId)
This API is used to register all the events that are published by the application.
IARM_Bus_RegisterEventHandler
IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler)
This API register to listen to event and provide the callback function for event notification....
Definition: iarmMgrMocks.cpp:43
IARM_Bus_RegisterCall
IARM_Result_t IARM_Bus_RegisterCall(const char *methodName, IARM_BusCall_t handler)
This API is used to register an RPC method that can be invoked by other applications.
IARM_Bus_Disconnect
IARM_Result_t IARM_Bus_Disconnect(void)
This API disconnect Application from IARM Bus so the application will not receive any IARM event or R...
_IARM_Bus_DeviceUpdate_AcceptUpdate_Param_t
Definition: deviceUpdateMgr.h:175
_IARM_Bus_DeviceUpdate_DownloadStatus_t
Definition: deviceUpdateMgr.h:375
IARM_Bus_BroadcastEvent
IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len)
This API is used to publish an Asynchronous event to all IARM client registered for this perticular e...
libIBus.h
RDK IARM-Bus API Declarations.
_IARM_Bus_DeviceUpdate_LoadInitiate_t
Definition: deviceUpdateMgr.h:402
_IARM_Bus_DeviceUpdate_ReadyToDownload_t
Definition: deviceUpdateMgr.h:316
_IARM_Bus_DeviceUpdate_Announce_t
Definition: deviceUpdateMgr.h:279
_IARM_Bus_DeviceUpdate_LoadStatus_t
Definition: deviceUpdateMgr.h:426
IARM_Bus_Connect
IARM_Result_t IARM_Bus_Connect(void)
This API is used to connect application to the IARM bus daemon. After connected, the application can ...
Definition: iarmMgrMocks.cpp:33
IARM_Bus_UnRegisterEventHandler
IARM_Result_t IARM_Bus_UnRegisterEventHandler(const char *ownerName, IARM_EventId_t eventId)
This API is used to Remove ALL handlers registered for the given event. This API remove the all the e...
IARM_BUS_DEVICE_UPDATE_NAME
#define IARM_BUS_DEVICE_UPDATE_NAME
Definition: deviceUpdateMgr.h:131
rdk_logger_init
rdk_Error rdk_logger_init(const char *debugConfigFile)
Initialize the logger. Sets up the environment variable storage by parsing debug configuration file t...
Definition: rdk_logger_init.c:57
IARM_Bus_Init
IARM_Result_t IARM_Bus_Init(const char *name)
This API is used to initialize the IARM-Bus library.
Definition: iarmMgrMocks.cpp:38