main.cpp 6.6 KB

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