test_fsm.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * Copyright (C) 2009 Mamadou Diop.
  3. *
  4. * Contact: Mamadou Diop <diopmamadou(at)doubango.org>
  5. *
  6. * This file is part of Open Source Doubango Framework.
  7. *
  8. * DOUBANGO is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * DOUBANGO is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with DOUBANGO.
  20. *
  21. */
  22. #ifndef _TEST_FSM_H_
  23. #define _TEST_FSM_H_
  24. typedef struct test_fsm_ctx_s {
  25. unsigned unsubscribing:1;
  26. }
  27. test_fsm_ctx_t;
  28. /* ======================== actions ======================== */
  29. typedef enum test_fsm_action_e {
  30. test_fsm_action_send,
  31. test_fsm_action_1xx,
  32. test_fsm_action_2xx,
  33. test_fsm_action_401_407_421_494,
  34. test_fsm_action_423,
  35. test_fsm_action_300_to_699,
  36. test_fsm_action_cancel,
  37. test_fsm_action_notify,
  38. test_fsm_action_unsubscribe,
  39. test_fsm_action_refresh,
  40. test_fsm_action_transporterror,
  41. test_fsm_action_error,
  42. }
  43. test_fsm_action_t;
  44. /* ======================== execs ======================== */
  45. int test_fsm_exec_Started_2_Trying_X_send(va_list *app)
  46. {
  47. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  48. const void* message = va_arg(*app, const void *);
  49. return 0;
  50. }
  51. int test_fsm_exec_Trying_2_Trying_X_1xx(va_list *app)
  52. {
  53. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  54. const void* message = va_arg(*app, const void *);
  55. return 0;
  56. }
  57. int test_fsm_exec_Trying_2_Terminated_X_2xx(va_list *app)
  58. {
  59. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  60. const void* message = va_arg(*app, const void *);
  61. return 0;
  62. }
  63. int test_fsm_exec_Trying_2_Connected_X_2xx(va_list *app)
  64. {
  65. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  66. const void* message = va_arg(*app, const void *);
  67. return 0;
  68. }
  69. int test_fsm_exec_Trying_2_Trying_X_401_407_421_494(va_list *app)
  70. {
  71. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  72. const void* message = va_arg(*app, const void *);
  73. return 0;
  74. }
  75. int test_fsm_exec_Trying_2_Trying_X_423(va_list *app)
  76. {
  77. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  78. const void* message = va_arg(*app, const void *);
  79. return 0;
  80. }
  81. int test_fsm_exec_Trying_2_Terminated_X_300_to_699(va_list *app)
  82. {
  83. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  84. const void* message = va_arg(*app, const void *);
  85. return 0;
  86. }
  87. int test_fsm_exec_Trying_2_Terminated_X_cancel(va_list *app)
  88. {
  89. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  90. const void* message = va_arg(*app, const void *);
  91. return 0;
  92. }
  93. int test_fsm_exec_Trying_2_Trying_X_NOTIFY(va_list *app)
  94. {
  95. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  96. const void* message = va_arg(*app, const void *);
  97. return 0;
  98. }
  99. int test_fsm_exec_Connected_2_Trying_X_unsubscribe(va_list *app)
  100. {
  101. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  102. const void* message = va_arg(*app, const void *);
  103. return 0;
  104. }
  105. int test_fsm_exec_Connected_2_Trying_X_refresh(va_list *app)
  106. {
  107. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  108. const void* message = va_arg(*app, const void *);
  109. return 0;
  110. }
  111. int test_fsm_exec_Connected_2_Connected_X_NOTIFY(va_list *app)
  112. {
  113. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  114. const void* message = va_arg(*app, const void *);
  115. return 0;
  116. }
  117. int test_fsm_exec_Connected_2_Terminated_X_NOTIFY(va_list *app)
  118. {
  119. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  120. const void* message = va_arg(*app, const void *);
  121. return 0;
  122. }
  123. int test_fsm_exec_Any_2_Trying_X_hangup(va_list *app)
  124. {
  125. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  126. const void* message = va_arg(*app, const void *);
  127. return 0;
  128. }
  129. int test_fsm_exec_Any_2_Terminated_X_transportError(va_list *app)
  130. {
  131. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  132. const void* message = va_arg(*app, const void *);
  133. return 0;
  134. }
  135. int test_fsm_exec_Any_2_Terminated_X_Error(va_list *app)
  136. {
  137. const test_fsm_ctx_t* ctx = va_arg(*app, const test_fsm_ctx_t *);
  138. const void* message = va_arg(*app, const void *);
  139. return 0;
  140. }
  141. /* ======================== conds ======================== */
  142. int test_fsm_cond_unsubscribing(test_fsm_ctx_t* ctx, void* data)
  143. {
  144. return ctx->unsubscribing ? 1 : 0;
  145. }
  146. int test_fsm_cond_subscribing(test_fsm_ctx_t* ctx, void* data)
  147. {
  148. return !test_fsm_cond_unsubscribing(ctx, data);
  149. }
  150. int test_fsm_cond_notify_terminated(test_fsm_ctx_t* ctx, void* sipmessage)
  151. {
  152. return 0;
  153. }
  154. int test_fsm_cond_notify_not_terminated(test_fsm_ctx_t* ctx, void* sipmessage)
  155. {
  156. return !test_fsm_cond_notify_terminated(ctx, sipmessage);
  157. }
  158. typedef enum test_fsm_state_e {
  159. __nil = 0,
  160. Started,
  161. Trying,
  162. Connected,
  163. Terminated
  164. }
  165. test_fsm_state_t;
  166. int test_fsm_onterminated(const test_fsm_ctx_t* ctx)
  167. {
  168. TSK_DEBUG_INFO("FSM in terminal state.");
  169. return 0;
  170. }
  171. #define TEST_FSM_ACTIONS_COUNT 5
  172. test_fsm_action_t test_fsm_tests[TEST_FSM_ACTIONS_COUNT][TEST_FSM_ACTIONS_COUNT] = {
  173. { test_fsm_action_send, test_fsm_action_300_to_699 },
  174. { test_fsm_action_send, test_fsm_action_401_407_421_494, test_fsm_action_2xx, test_fsm_action_refresh, test_fsm_action_300_to_699},
  175. { test_fsm_action_send, test_fsm_action_401_407_421_494, test_fsm_action_2xx, test_fsm_action_refresh, test_fsm_action_2xx},
  176. { test_fsm_action_send, test_fsm_action_2xx, test_fsm_action_2xx, test_fsm_action_refresh, test_fsm_action_2xx},
  177. { test_fsm_action_send, test_fsm_action_423, test_fsm_action_2xx, test_fsm_action_refresh, test_fsm_action_401_407_421_494},
  178. };
  179. void test_fsm()
  180. {
  181. size_t i;
  182. for(i=0; i<TEST_FSM_ACTIONS_COUNT; i++) {
  183. size_t j;
  184. tsk_fsm_t* fsm = tsk_fsm_create(Started, Terminated);
  185. test_fsm_ctx_t ctx;
  186. ctx.unsubscribing = 0;
  187. tsk_fsm_set_callback_terminated(fsm, test_fsm_onterminated, &ctx);
  188. tsk_fsm_set(fsm,
  189. /*=======================
  190. * === Any ===
  191. */
  192. // Any -> (transport error) -> Terminated
  193. TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, test_fsm_action_transporterror, Terminated, test_fsm_exec_Any_2_Terminated_X_transportError, "test_fsm_exec_Any_2_Terminated_X_transportError"),
  194. // Any -> (transport error) -> Terminated
  195. TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, test_fsm_action_error, Terminated, test_fsm_exec_Any_2_Terminated_X_Error, "test_fsm_exec_Any_2_Terminated_X_Error"),
  196. // Any -> (hangup) -> Terminated
  197. // Any -> (hangup) -> Trying
  198. /*=======================
  199. * === Started ===
  200. */
  201. // Started -> (Send) -> Trying
  202. TSK_FSM_ADD_ALWAYS(Started, test_fsm_action_send, Trying, test_fsm_exec_Started_2_Trying_X_send, "test_fsm_exec_Started_2_Trying_X_send"),
  203. // Started -> (Any) -> Started
  204. TSK_FSM_ADD_ALWAYS_NOTHING(Started, "test_fsm_exec_Started_2_Started_X_any"),
  205. /*=======================
  206. * === Trying ===
  207. */
  208. // Trying -> (1xx) -> Trying
  209. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_1xx, Trying, test_fsm_exec_Trying_2_Trying_X_1xx, "test_fsm_exec_Trying_2_Trying_X_1xx"),
  210. // Trying -> (2xx) -> Terminated
  211. TSK_FSM_ADD(Trying, test_fsm_action_2xx, test_fsm_cond_unsubscribing, Terminated, test_fsm_exec_Trying_2_Terminated_X_2xx, "test_fsm_exec_Trying_2_Terminated_X_2xx"),
  212. // Trying -> (2xx) -> Connected
  213. TSK_FSM_ADD(Trying, test_fsm_action_2xx, test_fsm_cond_subscribing, Connected, test_fsm_exec_Trying_2_Connected_X_2xx, "test_fsm_exec_Trying_2_Connected_X_2xx"),
  214. // Trying -> (401/407/421/494) -> Trying
  215. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_401_407_421_494, Trying, test_fsm_exec_Trying_2_Trying_X_401_407_421_494, "test_fsm_exec_Trying_2_Trying_X_401_407_421_494"),
  216. // Trying -> (423) -> Trying
  217. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_423, Trying, test_fsm_exec_Trying_2_Trying_X_423, "test_fsm_exec_Trying_2_Trying_X_423"),
  218. // Trying -> (300_to_699) -> Terminated
  219. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_300_to_699, Terminated, test_fsm_exec_Trying_2_Terminated_X_300_to_699, "test_fsm_exec_Trying_2_Terminated_X_300_to_699"),
  220. // Trying -> (cancel) -> Terminated
  221. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_cancel, Terminated, test_fsm_exec_Trying_2_Terminated_X_cancel, "test_fsm_exec_Trying_2_Terminated_X_cancel"),
  222. // Trying -> (Notify) -> Trying
  223. TSK_FSM_ADD_ALWAYS(Trying, test_fsm_action_notify, Trying, test_fsm_exec_Trying_2_Trying_X_NOTIFY, "test_fsm_exec_Trying_2_Trying_X_NOTIFY"),
  224. // Trying -> (Any) -> Trying
  225. TSK_FSM_ADD_ALWAYS_NOTHING(Trying, "test_fsm_exec_Trying_2_Trying_X_any"),
  226. /*=======================
  227. * === Connected ===
  228. */
  229. // Connected -> (unsubscribe) -> Trying
  230. TSK_FSM_ADD_ALWAYS(Connected, test_fsm_action_unsubscribe, Trying, test_fsm_exec_Connected_2_Trying_X_unsubscribe, "test_fsm_exec_Connected_2_Trying_X_unsubscribe"),
  231. // Connected -> (refresh) -> Trying
  232. TSK_FSM_ADD_ALWAYS(Connected, test_fsm_action_refresh, Trying, test_fsm_exec_Connected_2_Trying_X_refresh, "test_fsm_exec_Connected_2_Trying_X_refresh"),
  233. // Connected -> (NOTIFY) -> Connected
  234. TSK_FSM_ADD(Connected, test_fsm_action_notify, test_fsm_cond_notify_not_terminated, Connected, test_fsm_exec_Connected_2_Connected_X_NOTIFY, "test_fsm_exec_Connected_2_Connected_X_NOTIFY"),
  235. // Connected -> (NOTIFY) -> Terminated
  236. TSK_FSM_ADD(Connected, test_fsm_action_notify, test_fsm_cond_notify_terminated, Terminated, test_fsm_exec_Connected_2_Terminated_X_NOTIFY, "test_fsm_exec_Connected_2_Terminated_X_NOTIFY"),
  237. // Connected -> (Any) -> Connected
  238. TSK_FSM_ADD_ALWAYS_NOTHING(Connected, "test_fsm_exec_Connected_2_Connected_X_any"),
  239. TSK_FSM_ADD_NULL());
  240. for(j=0; j<TEST_FSM_ACTIONS_COUNT; j++) {
  241. tsk_fsm_act(fsm, test_fsm_tests[i][j], &ctx, tsk_null, &ctx, tsk_null /*message*/);
  242. }
  243. TSK_OBJECT_SAFE_FREE(fsm);
  244. printf("\n\n");
  245. }
  246. }
  247. #endif /* _TEST_FSM_H_ */