static int foo(void) { struct osmo_fsm_inst *fi; LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n"); fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL); OSMO_ASSERT(fi); OSMO_ASSERT(fi->fsm == &fsm); OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name))); OSMO_ASSERT(fi->state == ST_NULL); OSMO_ASSERT(fi->log_level == LOGL_DEBUG); /* Try invalid state transition */ osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_NULL); /* Legitimate state transition */ osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23); OSMO_ASSERT(fi->state == ST_ONE); /* Legitimate transition with timer */ fsm.timer_cb = test_fsm_tmr_cb; osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42); OSMO_ASSERT(fi->state == ST_TWO); return 0; }
/*! \brief allocate a new instance of a specified FSM as child of * other FSM instance * * This is like \ref osmo_fsm_inst_alloc but using the parent FSM as * talloc context, and inheriting the log level of the parent. * * \param[in] fsm Descriptor of the to-be-allocated FSM * \param[in] parent Parent FSM instance * \param[in] parent_term_event Event to be sent to parent when terminating * \returns newly-allocated, initialized and registered FSM instance */ struct osmo_fsm_inst *osmo_fsm_inst_alloc_child(struct osmo_fsm *fsm, struct osmo_fsm_inst *parent, uint32_t parent_term_event) { struct osmo_fsm_inst *fi; fi = osmo_fsm_inst_alloc(fsm, parent, NULL, parent->log_level, parent->id); if (!fi) { /* indicate immediate termination to caller */ osmo_fsm_inst_dispatch(parent, parent_term_event, NULL); return NULL; } LOGPFSM(fi, "is child of %s\n", osmo_fsm_inst_name(parent)); fi->proc.parent = parent; fi->proc.parent_term_event = parent_term_event; llist_add(&fi->proc.child, &parent->proc.children); return fi; }