main.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <poll.h>
  6. #include <vector>
  7. #include <gfa/gfasitarautils.h>
  8. #include <gfa/gfaipc.h>
  9. #include "../src/defines.h"
  10. #include "app.h"
  11. /////////////////////////////////////////////////////////////////////////////
  12. #define _APPNAME_MQTTCL "MQTTCL"
  13. #define _APPNAME_REMANENT "Remanent"
  14. #define _APPNAME_REST "REST"
  15. #define _CTRL_MSG_HANG 0x08
  16. #define _CTRL_MSG_ALLOC 0x10
  17. #define _CTRL_MSG_FREE 0x20
  18. #define _HANG_LOOPS 1000000000
  19. #define _NORMAL_LOOPS 100000
  20. #define _MEM_WASTE_SIZE 524288
  21. /////////////////////////////////////////////////////////////////////////////
  22. #define UNUSED(v) (void)v
  23. static volatile bool g_fRun = false;
  24. static volatile bool g_fPause = false;
  25. static volatile bool g_fHang = false;
  26. static volatile bool g_fAlloc = false;
  27. static volatile bool g_fFree = false;
  28. static volatile bool g_fSysInfoRunning = false;
  29. /////////////////////////////////////////////////////////////////////////////
  30. static const char *g_pszStateNames[] =
  31. {
  32. "Not running",
  33. "Initializing",
  34. "Running",
  35. "Paused",
  36. "Hanging",
  37. "Terminating",
  38. "Invalid"
  39. };
  40. static std::vector<void*> g_vP;
  41. /////////////////////////////////////////////////////////////////////////////
  42. static void _SigHandler(int sig)
  43. {
  44. UNUSED(sig);
  45. g_fPause = false;
  46. g_fRun = false;
  47. }
  48. /////////////////////////////////////////////////////////////////////////////
  49. static int _InputAvailable(void)
  50. {
  51. static struct pollfd poIn[1] = {{0, POLLIN, 0}};
  52. int n = poll(poIn, 1, 0);
  53. return n;
  54. }
  55. /////////////////////////////////////////////////////////////////////////////
  56. static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
  57. {
  58. ctrlmsg_t nCtrlMsg;
  59. while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
  60. {
  61. switch(nCtrlMsg)
  62. {
  63. case GFA_APPCTRL_CTRLMSG_STOP:
  64. g_fRun = false;
  65. TRACE("Received Message: STOP!\n");
  66. break;
  67. case GFA_APPCTRL_CTRLMSG_PAUSE:
  68. if(!g_fPause)
  69. {
  70. g_fPause = true;
  71. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  72. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  73. }
  74. break;
  75. case GFA_APPCTRL_CTRLMSG_RESUME:
  76. if(g_fPause)
  77. {
  78. g_fPause = false;
  79. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  80. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  81. }
  82. break;
  83. case _CTRL_MSG_HANG:
  84. g_fHang = true;
  85. break;
  86. case _CTRL_MSG_ALLOC:
  87. g_fAlloc = true;
  88. break;
  89. case _CTRL_MSG_FREE:
  90. g_fFree = true;
  91. break;
  92. default:
  93. break;
  94. }
  95. }
  96. }
  97. /////////////////////////////////////////////////////////////////////////////
  98. static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
  99. {
  100. appid_t nAppIdSrc;
  101. char szDispName[128];
  102. while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
  103. {
  104. GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
  105. GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
  106. TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
  107. switch(nAppIdSrc)
  108. {
  109. case GFA_APPCTRL_APPID_REMANENT:
  110. if(state == GIAS_Running)
  111. {
  112. if(g_fPause)
  113. {
  114. g_fPause = false;
  115. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  116. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  117. }
  118. }
  119. else
  120. {
  121. if(!g_fPause)
  122. {
  123. g_fPause = true;
  124. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  125. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  126. }
  127. }
  128. break;
  129. case GFA_APPCTRL_APPID_SYSINFO:
  130. if(!(g_fSysInfoRunning = (state == GIAS_Running)))
  131. {
  132. TRACE("SysInfo not running - System information not available!\n");
  133. }
  134. else
  135. {
  136. TRACE("SysInfo running - System information is available!\n");
  137. }
  138. break;
  139. }
  140. }
  141. }
  142. /////////////////////////////////////////////////////////////////////////////
  143. static void _ProcessSystemEvents(HAPPCTRL hAC, HAPPINFO hAI)
  144. {
  145. int nIndex;
  146. sysevt_t nEvent;
  147. GFA_SYSINFO_DISK disk;
  148. GFA_SYSINFO_PARTITION part;
  149. if(!g_fSysInfoRunning)
  150. return;
  151. while(g_fRun && (nEvent = ::GfaIpcAppCtrlGetNextSysEvt(hAI)))
  152. {
  153. switch(nEvent)
  154. {
  155. case GFA_APPCTRL_SYSEVENT_DISK_EVT:
  156. while((nIndex = ::GfaIpcAppCtrlGetNextDiskRemoved(hAC, &disk)) >= 0)
  157. {
  158. TRACE("Disk [ID=%d] removed: %s [%s]\n", nIndex, disk.szDevNode, *disk.szName ? disk.szName : "Unnamed");
  159. }
  160. while((nIndex = ::GfaIpcAppCtrlGetNextDiskAdded(hAC, &disk)) >= 0)
  161. {
  162. TRACE("Disk [ID=%d] added: %s [%s]\n", nIndex, disk.szDevNode, *disk.szName ? disk.szName : "Unnamed");
  163. }
  164. break;
  165. case GFA_APPCTRL_SYSEVENT_PART_EVT:
  166. while((nIndex = ::GfaIpcAppCtrlGetNextPartitionRemoved(hAC, &part)) >= 0)
  167. {
  168. TRACE("Partition [ID=%zd:%d] removed: %s [%s]\n", part.nDiskIdx, nIndex, part.szDevNode, *part.szFsLabel ? part.szFsLabel : "Unnamed");
  169. }
  170. while((nIndex = ::GfaIpcAppCtrlGetNextPartitionAdded(hAC, &part)) >= 0)
  171. {
  172. TRACE("Partition [ID=%zd:%d] added: %s [%s]\n", part.nDiskIdx, nIndex, part.szDevNode, *part.szFsLabel ? part.szFsLabel : "Unnamed");
  173. }
  174. break;
  175. case GFA_APPCTRL_SYSEVENT_MOUNT_EVT:
  176. while((nIndex = ::GfaIpcAppCtrlGetNextMountRemoved(hAC, &part)) >= 0)
  177. {
  178. TRACE("Mountpoint [ID=%zd:%d] removed: %s\n", part.nDiskIdx, nIndex, part.szDevNode);
  179. }
  180. while((nIndex = ::GfaIpcAppCtrlGetNextMountAdded(hAC, &part)) >= 0)
  181. {
  182. TRACE("Mountpoint [ID=%zd:%d] added: %s -> %s\n", part.nDiskIdx, nIndex, part.szDevNode, part.szMntPoint);
  183. }
  184. break;
  185. }
  186. }
  187. }
  188. /////////////////////////////////////////////////////////////////////////////
  189. static void _ProcessInput(HAPPCTRL hAC)
  190. {
  191. if(_InputAvailable())
  192. {
  193. ctrlmsg_t msg = 0;
  194. appid_t aiTarget = 0;
  195. int nRet = scanf("%llu %llu", &aiTarget, &msg);
  196. if(nRet == 2)
  197. {
  198. ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
  199. }
  200. }
  201. }
  202. /////////////////////////////////////////////////////////////////////////////
  203. static int _DoWork(void)
  204. {
  205. int i, j = 0, k = _NORMAL_LOOPS;
  206. if(g_fAlloc)
  207. {
  208. TRACE("Allocating %d KiB of memory.\n", _MEM_WASTE_SIZE >> 10);
  209. void *p = malloc(_MEM_WASTE_SIZE);
  210. g_vP.push_back(p);
  211. g_fAlloc = false;
  212. UNUSED(p);
  213. }
  214. if(g_fFree)
  215. {
  216. TRACE("Freeing memory.\n");
  217. for(auto i = g_vP.begin(); i != g_vP.end(); i++)
  218. {
  219. free(*i);
  220. }
  221. g_vP.clear();
  222. g_fFree = false;
  223. }
  224. if(g_fHang)
  225. {
  226. k = _HANG_LOOPS;
  227. TRACE("Performing %d nonsense loops.\n", k);
  228. g_fHang = false;
  229. }
  230. for(i = 0; i < k; ++i)
  231. {
  232. j += 4;
  233. j -= 2;
  234. j += 1;
  235. j -= 3;
  236. }
  237. return j;
  238. }
  239. /////////////////////////////////////////////////////////////////////////////
  240. /////////////////////////////////////////////////////////////////////////////
  241. /////////////////////////////////////////////////////////////////////////////
  242. int main(void)
  243. {
  244. HAPPCTRL hAC = NULL;
  245. HAPPINFO hAI;
  246. /////////////////////////////////////////////////////////////////////////
  247. /////////////////////////////////////////////////////////////////////////
  248. /////////////////////////////////////////////////////////////////////////
  249. // signal handling
  250. struct sigaction sa;
  251. memset(&sa, 0, sizeof(sa));
  252. // handle signals
  253. sa.sa_handler = _SigHandler;
  254. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  255. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  256. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  257. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  258. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  259. // ignore signals
  260. sa.sa_handler = SIG_IGN;
  261. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  262. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  263. sigaction(0, &sa, NULL); // ignores shell termination
  264. /////////////////////////////////////////////////////////////////////////
  265. /////////////////////////////////////////////////////////////////////////
  266. /////////////////////////////////////////////////////////////////////////
  267. // initialize
  268. do
  269. {
  270. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
  271. break;
  272. ;;GfaIpcDumpSHMROT();
  273. ::GfaIpcAppCtrlPresetDisplayName(hAC, GFA_APPCTRL_APPID_USER_01, "qmlApp");
  274. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  275. if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2 | GFA_APPCTRL_APPID_USER_01 | GFA_APPCTRL_APPID_SYSINFO))
  276. break;
  277. if(!::GfaIpcAppCtrlSubscribeSysEvents(hAC, GFA_APPCTRL_SYSEVENT_ALL_STG_DEV))
  278. break;
  279. TRACE("My Name: %s\n", _APPNAME_0);
  280. TRACE("My AppID: %llu\n", _APPID_0);
  281. TRACE("My PID: %d\n", getpid());
  282. TRACE("My Cycle: %d\n", _CYCLE_INTV);
  283. g_fRun = true;
  284. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  285. }
  286. while(false);
  287. /////////////////////////////////////////////////////////////////////////
  288. /////////////////////////////////////////////////////////////////////////
  289. /////////////////////////////////////////////////////////////////////////
  290. // run
  291. CCycleTimer ct(_CYCLE_INTV);
  292. cy_time_t wStart, wEnd, wCur = 0;
  293. while(g_fRun)
  294. {
  295. /////////////////////////////////////////////////////////////////////
  296. // trigger cycle timer
  297. ct.Trigger();
  298. /////////////////////////////////////////////////////////////////////
  299. // test input
  300. _ProcessInput(hAC);
  301. /////////////////////////////////////////////////////////////////////
  302. // update app control info
  303. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
  304. {
  305. _ProcessCtrlMessages(hAC, hAI);
  306. _ProcessStateEvents(hAC, hAI);
  307. _ProcessSystemEvents(hAC, hAI);
  308. }
  309. /////////////////////////////////////////////////////////////////////
  310. // if not paused, do work
  311. if(!g_fPause && g_fRun)
  312. {
  313. wStart = ct.GetMicroTick();
  314. _DoWork();
  315. wEnd = ct.GetMicroTick();
  316. wCur = wEnd - wStart;
  317. }
  318. /////////////////////////////////////////////////////////////////////
  319. // if running, sleep
  320. if(g_fRun)
  321. ct.Sleep1();
  322. }
  323. /////////////////////////////////////////////////////////////////////////
  324. /////////////////////////////////////////////////////////////////////////
  325. /////////////////////////////////////////////////////////////////////////
  326. // terminate
  327. if(hAC)
  328. {
  329. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  330. ::GfaIpcAppCtrlRelease(hAC);
  331. }
  332. return 0;
  333. }