main.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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 <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. #define _MAX_CYCLE_DELAY (_CYCLE_INTV * 5000)
  19. static volatile bool g_fRun = false;
  20. static volatile bool g_fPause = 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. _DoHang(_HANG_DELAY);
  88. break;
  89. default:
  90. break;
  91. }
  92. }
  93. }
  94. /////////////////////////////////////////////////////////////////////////////
  95. static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
  96. {
  97. appid_t nAppIdSrc;
  98. char szDispName[128];
  99. while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
  100. {
  101. GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
  102. GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
  103. TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
  104. switch(nAppIdSrc)
  105. {
  106. case GFA_APPCTRL_APPID_REMANENT:
  107. if(state == GIAS_Running)
  108. {
  109. if(g_fPause)
  110. {
  111. g_fPause = false;
  112. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  113. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  114. }
  115. }
  116. else
  117. {
  118. if(!g_fPause)
  119. {
  120. g_fPause = true;
  121. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  122. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  123. }
  124. }
  125. break;
  126. case GFA_APPCTRL_APPID_REST:
  127. break;
  128. case GFA_APPCTRL_APPID_MQTTCL:
  129. break;
  130. }
  131. }
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. static void _ProcessInput(HAPPCTRL hAC)
  135. {
  136. if(_InputAvailable())
  137. {
  138. ctrlmsg_t msg = 0;
  139. appid_t aiTarget = 0;
  140. int nRet = scanf("%llu %llu", &aiTarget, &msg);
  141. if(nRet == 2)
  142. {
  143. ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
  144. }
  145. }
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. static int _DoWork(void)
  149. {
  150. static int nCounter = 0;
  151. return ++nCounter;
  152. }
  153. /////////////////////////////////////////////////////////////////////////////
  154. /////////////////////////////////////////////////////////////////////////////
  155. /////////////////////////////////////////////////////////////////////////////
  156. int main(void)
  157. {
  158. HAPPCTRL hAC = NULL;
  159. HAPPINFO hAI;
  160. /////////////////////////////////////////////////////////////////////////
  161. /////////////////////////////////////////////////////////////////////////
  162. /////////////////////////////////////////////////////////////////////////
  163. // signal handling
  164. struct sigaction sa;
  165. memset(&sa, 0, sizeof(sa));
  166. // handle signals
  167. sa.sa_handler = _SigHandler;
  168. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  169. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  170. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  171. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  172. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  173. // ignore signals
  174. sa.sa_handler = SIG_IGN;
  175. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  176. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  177. sigaction(0, &sa, NULL); // ignores shell termination
  178. /////////////////////////////////////////////////////////////////////////
  179. /////////////////////////////////////////////////////////////////////////
  180. /////////////////////////////////////////////////////////////////////////
  181. // initialize
  182. do
  183. {
  184. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _MAX_CYCLE_DELAY)))
  185. break;
  186. ;;GfaIpcDumpSHMROT();
  187. ::GfaIpcAppCtrlPresetDisplayName(hAC, GFA_APPCTRL_APPID_USER_01, "qmlApp");
  188. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  189. if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2 | GFA_APPCTRL_APPID_USER_01))
  190. break;
  191. TRACE("My Name: %s\n", _APPNAME_0);
  192. TRACE("My AppID: %llu\n", _APPID_0);
  193. TRACE("My PID: %d\n", getpid());
  194. TRACE("My Cycle: %d\n", _CYCLE_INTV);
  195. g_fRun = true;
  196. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  197. }
  198. while(false);
  199. /////////////////////////////////////////////////////////////////////////
  200. /////////////////////////////////////////////////////////////////////////
  201. /////////////////////////////////////////////////////////////////////////
  202. // run
  203. CCycleTimer ct(_CYCLE_INTV);
  204. while(g_fRun)
  205. {
  206. /////////////////////////////////////////////////////////////////////
  207. // trigger cycle timer
  208. ct.Trigger();
  209. /////////////////////////////////////////////////////////////////////
  210. // test input
  211. _ProcessInput(hAC);
  212. /////////////////////////////////////////////////////////////////////
  213. // update app control info
  214. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC)))
  215. {
  216. _ProcessCtrlMessages(hAC, hAI);
  217. _ProcessStateEvents(hAC, hAI);
  218. }
  219. /////////////////////////////////////////////////////////////////////
  220. // if not paused, do work
  221. if(!g_fPause && g_fRun)
  222. {
  223. _DoWork();
  224. }
  225. /////////////////////////////////////////////////////////////////////
  226. // if running, sleep
  227. if(g_fRun)
  228. ct.Sleep1();
  229. }
  230. /////////////////////////////////////////////////////////////////////////
  231. /////////////////////////////////////////////////////////////////////////
  232. /////////////////////////////////////////////////////////////////////////
  233. // terminate
  234. if(hAC)
  235. {
  236. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  237. ::GfaIpcAppCtrlRelease(hAC);
  238. }
  239. return 0;
  240. }