main.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. g_fPause = true;
  57. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  58. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  59. break;
  60. case GFA_APPCTRL_CTRLMSG_RESUME:
  61. g_fPause = false;
  62. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  63. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  64. break;
  65. case _CTRL_MSG_DELAY:
  66. TRACE("Delaying 2 seconds.\n");
  67. sleep(2);
  68. break;
  69. default:
  70. break;
  71. }
  72. }
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. static void _ProcessStateEvents(HAPPCTRL hAC, HAPPINFO hAI)
  76. {
  77. appid_t nAppIdSrc;
  78. char szDispName[128];
  79. while(g_fRun && (nAppIdSrc = ::GfaIpcAppCtrlGetNextStateEvtSrc(hAI)))
  80. {
  81. GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(hAC, nAppIdSrc);
  82. GfaIpcAppCtrlGetDisplayName(hAC, nAppIdSrc, szDispName, sizeof(szDispName));
  83. TRACE("%-8s: State: %s\n", szDispName, g_pszStateNames[state]);
  84. switch(nAppIdSrc)
  85. {
  86. case GFA_APPCTRL_APPID_REMANENT:
  87. if(state == GIAS_Running)
  88. {
  89. if(g_fPause)
  90. {
  91. g_fPause = false;
  92. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  93. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  94. }
  95. }
  96. else
  97. {
  98. if(!g_fPause)
  99. {
  100. g_fPause = true;
  101. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  102. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  103. }
  104. }
  105. break;
  106. case GFA_APPCTRL_APPID_REST:
  107. break;
  108. case GFA_APPCTRL_APPID_MQTTCL:
  109. break;
  110. }
  111. }
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. static void _ProcessInput(HAPPCTRL hAC)
  115. {
  116. if(_InputAvailable())
  117. {
  118. ctrlmsg_t msg = 0;
  119. appid_t aiTarget = 0;
  120. int nRet = scanf("%llu %llu", &aiTarget, &msg);
  121. if(nRet == 2)
  122. {
  123. ::GfaIpcAppCtrlSendCtrlMsg(hAC, aiTarget, msg);
  124. }
  125. }
  126. }
  127. /////////////////////////////////////////////////////////////////////////////
  128. static int _DoWork(void)
  129. {
  130. static int nCounter = 0;
  131. return ++nCounter;
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. /////////////////////////////////////////////////////////////////////////////
  135. /////////////////////////////////////////////////////////////////////////////
  136. int main(void)
  137. {
  138. HAPPCTRL hAC = NULL;
  139. HAPPINFO hAI;
  140. /////////////////////////////////////////////////////////////////////////
  141. /////////////////////////////////////////////////////////////////////////
  142. /////////////////////////////////////////////////////////////////////////
  143. // signal handling
  144. struct sigaction sa;
  145. memset(&sa, 0, sizeof(sa));
  146. // handle signals
  147. sa.sa_handler = _SigHandler;
  148. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  149. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  150. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  151. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  152. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  153. // ignore signals
  154. sa.sa_handler = SIG_IGN;
  155. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  156. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  157. sigaction(0, &sa, NULL); // ignores shell termination
  158. /////////////////////////////////////////////////////////////////////////
  159. /////////////////////////////////////////////////////////////////////////
  160. /////////////////////////////////////////////////////////////////////////
  161. // initialize
  162. do
  163. {
  164. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID_0, _APPNAME_0, _USLEEP_DELAY * 5)))
  165. break;
  166. ;;GfaIpcDumpSHMROT();
  167. ::GfaIpcAppCtrlPresetDisplayName(hAC, _APPID_1, _APPNAME_1);
  168. ::GfaIpcAppCtrlPresetDisplayName(hAC, _APPID_2, _APPNAME_2);
  169. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  170. if(!::GfaIpcAppCtrlSubscribeStateEvents(hAC, _APPID_1 | _APPID_2))
  171. break;
  172. TRACE("My Name: %s\n", _APPNAME_0);
  173. TRACE("My AppID: %llu\n", _APPID_0);
  174. g_fRun = true;
  175. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  176. }
  177. while(false);
  178. /////////////////////////////////////////////////////////////////////////
  179. /////////////////////////////////////////////////////////////////////////
  180. /////////////////////////////////////////////////////////////////////////
  181. // run
  182. while(g_fRun)
  183. {
  184. do
  185. {
  186. /////////////////////////////////////////////////////////////////
  187. // test input
  188. _ProcessInput(hAC);
  189. /////////////////////////////////////////////////////////////////
  190. // update app control info
  191. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, !g_fPause)))
  192. {
  193. _ProcessCtrlMessages(hAC, hAI);
  194. _ProcessStateEvents(hAC, hAI);
  195. }
  196. /////////////////////////////////////////////////////////////////
  197. ::usleep(_USLEEP_DELAY);
  198. }
  199. while(g_fRun && g_fPause);
  200. /////////////////////////////////////////////////////////////////////
  201. if(g_fRun)
  202. {
  203. _DoWork();
  204. }
  205. /////////////////////////////////////////////////////////////////////
  206. }
  207. /////////////////////////////////////////////////////////////////////////
  208. /////////////////////////////////////////////////////////////////////////
  209. /////////////////////////////////////////////////////////////////////////
  210. // terminate
  211. if(hAC)
  212. {
  213. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  214. ::GfaIpcAppCtrlRelease(hAC);
  215. }
  216. return 0;
  217. }