main.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <poll.h>
  6. #include <gfa/gfasitarautils.h>
  7. #include <gfa/gfaipc.h>
  8. #include "../src/defines.h"
  9. #include "app.h"
  10. /////////////////////////////////////////////////////////////////////////////
  11. #define _APPNAME_MQTTCL "MQTTCL"
  12. #define _APPNAME_REMANENT "Remanent"
  13. #define _APPNAME_REST "REST"
  14. #define _CTRL_MSG_DELAY 8
  15. #define _HANG_DELAY 10
  16. /////////////////////////////////////////////////////////////////////////////
  17. #define UNUSED(v) (void)v
  18. static volatile bool g_fRun = false;
  19. static volatile bool g_fPause = false;
  20. static volatile bool g_fHang = false;
  21. /////////////////////////////////////////////////////////////////////////////
  22. static const char *g_pszStateNames[] =
  23. {
  24. "Not running",
  25. "Initializing",
  26. "Running",
  27. "Paused",
  28. "Hanging",
  29. "Terminating",
  30. "Invalid"
  31. };
  32. /////////////////////////////////////////////////////////////////////////////
  33. static void _SigHandler(int sig)
  34. {
  35. UNUSED(sig);
  36. g_fPause = false;
  37. g_fRun = false;
  38. }
  39. /////////////////////////////////////////////////////////////////////////////
  40. static int _InputAvailable(void)
  41. {
  42. static struct pollfd poIn[1] = {{0, POLLIN, 0}};
  43. int n = poll(poIn, 1, 0);
  44. return n;
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. static void _DoHang(time_t nSec)
  48. {
  49. time_t t = time(NULL) + nSec;
  50. do
  51. {
  52. if(t < time(NULL))
  53. break;
  54. }
  55. while(true);
  56. }
  57. /////////////////////////////////////////////////////////////////////////////
  58. static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
  59. {
  60. ctrlmsg_t nCtrlMsg;
  61. while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
  62. {
  63. switch(nCtrlMsg)
  64. {
  65. case GFA_APPCTRL_CTRLMSG_STOP:
  66. g_fRun = false;
  67. TRACE("Received Message: STOP!\n");
  68. break;
  69. case GFA_APPCTRL_CTRLMSG_PAUSE:
  70. if(!g_fPause)
  71. {
  72. g_fPause = true;
  73. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  74. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  75. }
  76. break;
  77. case GFA_APPCTRL_CTRLMSG_RESUME:
  78. if(g_fPause)
  79. {
  80. g_fPause = false;
  81. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  82. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  83. }
  84. break;
  85. case _CTRL_MSG_DELAY:
  86. TRACE("Hanging %d seconds.\n", _HANG_DELAY);
  87. g_fHang = true;
  88. _DoHang(_HANG_DELAY);
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. }
  95. /////////////////////////////////////////////////////////////////////////////
  96. static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
  97. {
  98. appid_t nAppIdSrc;
  99. char szDispName[128];
  100. while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
  101. {
  102. GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
  103. GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
  104. TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
  105. switch(nAppIdSrc)
  106. {
  107. case GFA_APPCTRL_APPID_REMANENT:
  108. if(state == GIAS_Running)
  109. {
  110. if(g_fPause)
  111. {
  112. g_fPause = false;
  113. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  114. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  115. }
  116. }
  117. else
  118. {
  119. if(!g_fPause)
  120. {
  121. g_fPause = true;
  122. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  123. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  124. }
  125. }
  126. break;
  127. case GFA_APPCTRL_APPID_REST:
  128. break;
  129. case GFA_APPCTRL_APPID_MQTTCL:
  130. break;
  131. }
  132. }
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. static void _ProcessInput(HAPPCTRL hAC)
  136. {
  137. if(_InputAvailable())
  138. {
  139. ctrlmsg_t msg = 0;
  140. appid_t aiTarget = 0;
  141. int nRet = scanf("%llu %llu", &aiTarget, &msg);
  142. if(nRet == 2)
  143. {
  144. ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
  145. }
  146. }
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. static int _DoWork(void)
  150. {
  151. int i, j = 0;
  152. int k = g_fHang ? 1000000000 : 100000;
  153. for(i = 0; i < k; ++i)
  154. {
  155. j += 4;
  156. j -= 2;
  157. j += 1;
  158. j -= 3;
  159. }
  160. g_fHang = false;
  161. return j;
  162. }
  163. /////////////////////////////////////////////////////////////////////////////
  164. /////////////////////////////////////////////////////////////////////////////
  165. /////////////////////////////////////////////////////////////////////////////
  166. int main(void)
  167. {
  168. HAPPCTRL hAC = NULL;
  169. HAPPINFO hAI;
  170. /////////////////////////////////////////////////////////////////////////
  171. /////////////////////////////////////////////////////////////////////////
  172. /////////////////////////////////////////////////////////////////////////
  173. // signal handling
  174. struct sigaction sa;
  175. memset(&sa, 0, sizeof(sa));
  176. // handle signals
  177. sa.sa_handler = _SigHandler;
  178. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  179. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  180. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  181. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  182. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  183. // ignore signals
  184. sa.sa_handler = SIG_IGN;
  185. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  186. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  187. sigaction(0, &sa, NULL); // ignores shell termination
  188. /////////////////////////////////////////////////////////////////////////
  189. /////////////////////////////////////////////////////////////////////////
  190. /////////////////////////////////////////////////////////////////////////
  191. // initialize
  192. do
  193. {
  194. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
  195. break;
  196. ;;GfaIpcDumpSHMROT();
  197. ::GfaIpcAppCtrlPresetDisplayName(hAC, GFA_APPCTRL_APPID_USER_01, "qmlApp");
  198. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  199. if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2 | GFA_APPCTRL_APPID_USER_01))
  200. break;
  201. TRACE("My Name: %s\n", _APPNAME_0);
  202. TRACE("My AppID: %llu\n", _APPID_0);
  203. TRACE("My PID: %d\n", getpid());
  204. TRACE("My Cycle: %d\n", _CYCLE_INTV);
  205. g_fRun = true;
  206. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  207. }
  208. while(false);
  209. /////////////////////////////////////////////////////////////////////////
  210. /////////////////////////////////////////////////////////////////////////
  211. /////////////////////////////////////////////////////////////////////////
  212. // run
  213. CCycleTimer ct(_CYCLE_INTV);
  214. cy_time_t wStart, wEnd, wCur = 0;
  215. while(g_fRun)
  216. {
  217. /////////////////////////////////////////////////////////////////////
  218. // trigger cycle timer
  219. ct.Trigger();
  220. /////////////////////////////////////////////////////////////////////
  221. // test input
  222. _ProcessInput(hAC);
  223. /////////////////////////////////////////////////////////////////////
  224. // update app control info
  225. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
  226. {
  227. _ProcessCtrlMessages(hAC, hAI);
  228. _ProcessStateEvents(hAC, hAI);
  229. }
  230. /////////////////////////////////////////////////////////////////////
  231. // if not paused, do work
  232. if(!g_fPause && g_fRun)
  233. {
  234. wStart = ct.GetMicroTick();
  235. _DoWork();
  236. wEnd = ct.GetMicroTick();
  237. wCur = wEnd - wStart;
  238. }
  239. /////////////////////////////////////////////////////////////////////
  240. // if running, sleep
  241. if(g_fRun)
  242. ct.Sleep1();
  243. }
  244. /////////////////////////////////////////////////////////////////////////
  245. /////////////////////////////////////////////////////////////////////////
  246. /////////////////////////////////////////////////////////////////////////
  247. // terminate
  248. if(hAC)
  249. {
  250. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  251. ::GfaIpcAppCtrlRelease(hAC);
  252. }
  253. return 0;
  254. }