blob: 29b31efc65f7311e91ee185273cc035725613515 [file] [log] [blame]
Harald Welte136e7372016-05-29 10:53:17 +09001#include <stdlib.h>
2#include <stdio.h>
3#include <stdarg.h>
4#include <unistd.h>
5#include <string.h>
6
7#include <osmocom/core/utils.h>
8#include <osmocom/core/select.h>
9#include <osmocom/core/logging.h>
10#include <osmocom/core/fsm.h>
11
12enum {
13 DMAIN,
14};
15
16static void *g_ctx;
17
18
19enum test_fsm_states {
20 ST_NULL = 0,
21 ST_ONE,
22 ST_TWO,
23};
24
25enum test_fsm_evt {
26 EV_A,
27 EV_B,
28};
29
30static void test_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
31{
32 switch (event) {
33 case EV_A:
34 OSMO_ASSERT(data == (void *) 23);
35 osmo_fsm_inst_state_chg(fi, ST_ONE, 0, 0);
36 break;
37 default:
38 OSMO_ASSERT(0);
39 break;
40 }
41}
42
43static void test_fsm_one(struct osmo_fsm_inst *fi, uint32_t event, void *data)
44{
45 switch (event) {
46 case EV_B:
47 OSMO_ASSERT(data == (void *) 42);
48 osmo_fsm_inst_state_chg(fi,ST_TWO, 1, 2342);
49 break;
50 default:
51 OSMO_ASSERT(0);
52 break;
53 }
54}
55
56static void test_fsm_tmr_cb(struct osmo_fsm_inst *fi)
57{
58 OSMO_ASSERT(fi->T == 2342);
59 OSMO_ASSERT(fi->state == ST_TWO);
60 LOGP(DMAIN, LOGL_INFO, "Timer\n");
61
62 exit(0);
63}
64
65static struct osmo_fsm_state test_fsm_states[] = {
66 [ST_NULL] = {
67 .in_event_mask = (1 << EV_A),
68 .out_state_mask = (1 << ST_ONE),
69 .name = "NULL",
70 .action = test_fsm_null,
71 },
72 [ST_ONE]= {
73 .in_event_mask = (1 << EV_B),
74 .out_state_mask = (1 << ST_TWO),
75 .name = "ONE",
76 .action= test_fsm_one,
77 },
78 [ST_TWO]= {
79 .in_event_mask = 0,
80 .name = "TWO",
81 .action = NULL,
82 },
83};
84
85static struct osmo_fsm fsm = {
86 .name = "Test FSM",
87 .states = test_fsm_states,
88 .num_states = ARRAY_SIZE(test_fsm_states),
89 .log_subsys = DMAIN,
90};
91
92static int foo(void)
93{
94 struct osmo_fsm_inst *fi;
95
96 LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n");
97 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
98 OSMO_ASSERT(fi);
99 OSMO_ASSERT(fi->fsm == &fsm);
100 OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name)));
101 OSMO_ASSERT(fi->state == ST_NULL);
102 OSMO_ASSERT(fi->log_level == LOGL_DEBUG);
103
104 /* Try invalid state transition */
105 osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42);
106 OSMO_ASSERT(fi->state == ST_NULL);
107
108 /* Legitimate state transition */
109 osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23);
110 OSMO_ASSERT(fi->state == ST_ONE);
111
112 /* Legitimate transition with timer */
113 fsm.timer_cb = test_fsm_tmr_cb;
114 osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42);
115 OSMO_ASSERT(fi->state == ST_TWO);
116
117
118 return 0;
119}
120
121static const struct log_info_cat default_categories[] = {
122 [DMAIN] = {
123 .name = "DMAIN",
124 .description = "Main",
125 .enabled = 1, .loglevel = LOGL_DEBUG,
126 },
127};
128
129static const struct log_info log_info = {
130 .cat = default_categories,
131 .num_cat = ARRAY_SIZE(default_categories),
132};
133
134int main(int argc, char **argv)
135{
136 struct log_target *stderr_target;
137
138 osmo_fsm_log_addr(false);
139
140 log_init(&log_info, NULL);
141 stderr_target = log_target_create_stderr();
142 log_add_target(stderr_target);
143 log_set_print_filename(stderr_target, 0);
144
145 g_ctx = NULL;
146 osmo_fsm_register(&fsm);
147
148 foo();
149
150 while (1) {
151 osmo_select_main(0);
152 }
153
Max8b25a3f2016-11-01 11:02:17 +0100154 osmo_fsm_unregister(&fsm);
Harald Welte136e7372016-05-29 10:53:17 +0900155 exit(0);
156}