int mrp_lvatimer_fsm(struct mrp_database *mrp_db, int event) { int la_state; int sndmsg = MRP_SND_NONE; int tx = 0; if (NULL == mrp_db) return -1; la_state = mrp_db->lva.state; switch (event) { case MRP_EVENT_BEGIN: la_state = MRP_TIMER_PASSIVE; mrp_lvatimer_start(mrp_db); break; case MRP_EVENT_TX: if (la_state == MRP_TIMER_ACTIVE) { tx = 1; sndmsg = MRP_SND_LVA; la_state = MRP_TIMER_PASSIVE; } break; case MRP_EVENT_RLA: la_state = MRP_TIMER_PASSIVE; mrp_lvatimer_stop(mrp_db); mrp_lvatimer_start(mrp_db); break; case MRP_EVENT_LVATIMER: la_state = MRP_TIMER_ACTIVE; mrp_lvatimer_stop(mrp_db); mrp_lvatimer_start(mrp_db); break; default: #if LOG_MVRP || LOG_MSRP || LOG_MMRP printf("mrp_lvatimer_fsm:unexpected event (%d), state %s\n", event, mrp_lvatimer_state_string(la_state)); #endif return -1; break; } #if LOG_MVRP || LOG_MSRP || LOG_MMRP if (mrp_db->lva.state != la_state) { mrpd_log_printf("mrp_lvatimer_fsm event %s state %s -> %s\n", mrp_event_string(event), mrp_lvatimer_state_string(mrp_db->lva.state), mrp_lvatimer_state_string(la_state)); } else { mrpd_log_printf("mrp_lvatimer_fsm event %s state %s\n", mrp_event_string(event), mrp_lvatimer_state_string(la_state)); } #endif mrp_db->lva.state = la_state; mrp_db->lva.sndmsg = sndmsg; mrp_db->lva.tx = tx; return 0; }
int mrp_jointimer_stop(struct mrp_database *mrp_db) { #if LOG_TIMERS mrpd_log_printf("MRP stop join timer\n"); #endif mrp_db->join_timer_running = 0; return mrpd_timer_stop(mrp_db->join_timer); }
int mrp_lvatimer_stop(struct mrp_database *mrp_db) { #if LOG_TIMERS mrpd_log_printf("MRP stop leaveAll timer\n"); #endif mrp_db->lva_timer_running = 0; return mrpd_timer_stop(mrp_db->lva_timer); }
int mrp_lvtimer_start(struct mrp_database *mrp_db) { int ret; /* leavetimer has expired (10.7.5.21) * controls how long the Registrar state machine stays in the * LV state before transitioning to the MT state. */ #if LOG_TIMERS if (mrp_db->lv_timer_running) mrpd_log_printf("MRP start leave timer *ALREADY RUNNING*\n"); else mrpd_log_printf("MRP start leave timer\n"); #endif ret = mrpd_timer_start(mrp_db->lv_timer, MRP_LVTIMER_VAL); if (ret >= 0) mrp_db->lv_timer_running = 1; return ret; }
int mrp_jointimer_start(struct mrp_database *mrp_db) { int ret = 0; /* 10.7.4.1 - interval between transmit opportunities * for applicant state machine */ #if LOG_TIMERS if (mrp_db->join_timer_running) mrpd_log_printf("MRP join timer running\n"); else mrpd_log_printf("MRP join timer start \n"); #endif if (!mrp_db->join_timer_running) { ret = mrpd_timer_start(mrp_db->join_timer, MRP_JOINTIMER_VAL); } if (ret >= 0) mrp_db->join_timer_running = 1; return ret; }
int mrp_lvatimer_start(struct mrp_database *mrp_db) { int ret = 0; int timeout = 0; /* leavealltimer has expired. (10.7.5.22) * on expire, sends a LEAVEALL message * value is RANDOM in range (LeaveAllTime , 1.5xLeaveAllTime) * timer is for all attributes of a given application and port, but * expires each listed attribute individually (per application) */ timeout = MRP_LVATIMER_VAL + (random() % (MRP_LVATIMER_VAL / 2)); #if LOG_TIMERS if (mrp_db->lva_timer_running) mrpd_log_printf("MRP leaveAll timer already running \n", timeout); else mrpd_log_printf("MRP start leaveAll timer (%d ms)\n", timeout); #endif if (!mrp_db->lva_timer_running) ret = mrpd_timer_start(mrp_db->lva_timer, timeout); if (ret >= 0) mrp_db->lva_timer_running = 1; return ret; }
int mrp_registrar_fsm(mrp_registrar_attribute_t * attrib, struct mrp_database *mrp_db, int event) { int mrp_state = attrib->mrp_state; int notify = MRP_NOTIFY_NONE; switch (event) { case MRP_EVENT_BEGIN: mrp_state = MRP_MT_STATE; break; case MRP_EVENT_RLV: notify = MRP_NOTIFY_LV; /* fall thru */ case MRP_EVENT_TXLA: case MRP_EVENT_RLA: case MRP_EVENT_REDECLARE: /* * on link-status-change * trigger Applicant and Registrar state machines to re-declare * previously registered attributes. */ switch (mrp_state) { case MRP_IN_STATE: mrp_lvtimer_start(mrp_db); mrp_state = MRP_LV_STATE; default: break; } break; case MRP_EVENT_RNEW: notify = MRP_NOTIFY_NEW; switch (mrp_state) { case MRP_MT_STATE: case MRP_IN_STATE: mrp_state = MRP_IN_STATE; break; case MRP_LV_STATE: /* should stop leavetimer - but we have only 1 lvtimer * for all attributes, and recieving a LVTIMER event * is a don't-care if the attribute is in the IN state. */ mrp_state = MRP_IN_STATE; break; default: break; } break; case MRP_EVENT_RJOININ: case MRP_EVENT_RJOINMT: switch (mrp_state) { case MRP_MT_STATE: notify = MRP_NOTIFY_JOIN; mrp_state = MRP_IN_STATE; break; case MRP_IN_STATE: mrp_state = MRP_IN_STATE; break; case MRP_LV_STATE: /* should stop leavetimer - but we have only 1 lvtimer * for all attributes, and receiving a LVTIMER event * is a don't-care if the attribute is in the IN state. */ notify = MRP_NOTIFY_JOIN; mrp_state = MRP_IN_STATE; break; default: break; } break; case MRP_EVENT_LVTIMER: switch (mrp_state) { case MRP_LV_STATE: mrp_state = MRP_MT_STATE; break; case MRP_MT_STATE: mrp_state = MRP_MT_STATE; break; case MRP_IN_STATE: default: break; } break; case MRP_EVENT_FLUSH: notify = MRP_NOTIFY_LV; switch (mrp_state) { case MRP_LV_STATE: mrp_state = MRP_MT_STATE; break; case MRP_MT_STATE: case MRP_IN_STATE: mrp_state = MRP_MT_STATE; break; default: break; } break; case MRP_EVENT_RMT: /* ignore on soon to be deleted attributes */ break; default: printf("mrp_registrar_fsm:unexpected event %s (%d)\n", mrp_event_string(event), event); return -1; break; } #if LOG_MVRP || LOG_MSRP || LOG_MMRP if (attrib->mrp_state != mrp_state) { mrpd_log_printf("mrp_registrar_fsm event %s, state %s -> %s\n", mrp_event_string(event), mrp_state_string(attrib->mrp_state), mrp_state_string(mrp_state)); } else { mrpd_log_printf("mrp_registrar_fsm event %s, state %s\n", mrp_event_string(event), mrp_state_string(mrp_state)); } #endif attrib->mrp_state = mrp_state; attrib->notify = notify; return 0; }
int mrp_applicant_fsm(struct mrp_database *mrp_db, mrp_applicant_attribute_t * attrib, int event) { int tx = 0; int optional = 0; int mrp_state = attrib->mrp_state; int sndmsg = MRP_SND_NULL; (void)mrp_db; switch (event) { case MRP_EVENT_BEGIN: mrp_state = MRP_VO_STATE; break; case MRP_EVENT_NEW: /* * New declaration (publish) event as a result * of a mad_join request */ switch (mrp_state) { case MRP_VN_STATE: case MRP_AN_STATE: /* do nothing */ break; default: mrp_state = MRP_VN_STATE; break; } break; case MRP_EVENT_JOIN: /* * declaration (of interest) event as a result of * a mad_join request */ switch (mrp_state) { case MRP_LO_STATE: case MRP_VO_STATE: mrp_state = MRP_VP_STATE; break; case MRP_LA_STATE: mrp_state = MRP_AA_STATE; break; case MRP_AO_STATE: mrp_state = MRP_AP_STATE; break; case MRP_QO_STATE: mrp_state = MRP_QP_STATE; break; default: break; } break; case MRP_EVENT_LV: /* * declaration removal event as a result of a mad_leave request */ switch (mrp_state) { case MRP_VN_STATE: case MRP_AN_STATE: case MRP_AA_STATE: case MRP_QA_STATE: mrp_state = MRP_LA_STATE; break; case MRP_VP_STATE: mrp_state = MRP_VO_STATE; break; case MRP_AP_STATE: mrp_state = MRP_AO_STATE; break; case MRP_QP_STATE: mrp_state = MRP_QO_STATE; break; default: break; } break; case MRP_EVENT_TXLA: /* * transmit leaveall is signaled (overrides a TX) */ switch (mrp_state) { case MRP_VO_STATE: /* send <NULL> only if it improves encoding */ optional = 1; tx = 1; sndmsg = MRP_SND_IN; mrp_state = MRP_LO_STATE; break; case MRP_VP_STATE: tx = 1; sndmsg = MRP_SND_IN; mrp_state = MRP_AA_STATE; break; case MRP_VN_STATE: /* send NEW */ tx = 1; sndmsg = MRP_SND_NEW; mrp_state = MRP_AN_STATE; break; case MRP_AN_STATE: /* send NEW */ tx = 1; sndmsg = MRP_SND_NEW; mrp_state = MRP_QA_STATE; break; case MRP_QP_STATE: case MRP_AP_STATE: case MRP_AA_STATE: /* send JOIN */ tx = 1; sndmsg = MRP_SND_JOIN; mrp_state = MRP_QA_STATE; break; case MRP_QA_STATE: /* send JOIN */ tx = 1; sndmsg = MRP_SND_JOIN; break; case MRP_LA_STATE: case MRP_AO_STATE: case MRP_QO_STATE: /* send <NULL> only if it improves encoding */ optional = 1; tx = 1; sndmsg = MRP_SND_IN; mrp_state = MRP_LO_STATE; break; case MRP_LO_STATE: /* send <NULL> */ optional = 1; tx = 1; sndmsg = MRP_SND_IN; mrp_state = MRP_VO_STATE; break; default: break; } break; case MRP_EVENT_TXLAF: /* * transmit leaveall failure (no room) */ switch (mrp_state) { case MRP_VO_STATE: mrp_state = MRP_LO_STATE; break; case MRP_LO_STATE: case MRP_VP_STATE: case MRP_VN_STATE: /* don't advance state */ break; case MRP_AN_STATE: mrp_state = MRP_VN_STATE; break; case MRP_QP_STATE: case MRP_AP_STATE: case MRP_AA_STATE: case MRP_QA_STATE: mrp_state = MRP_VP_STATE; break; case MRP_QO_STATE: case MRP_AO_STATE: case MRP_LA_STATE: mrp_state = MRP_LO_STATE; break; default: break; } break; case MRP_EVENT_TX: /* * transmit updates unless leaveall is signaled * (then it becomes a TXLA) */ switch (mrp_state) { case MRP_VO_STATE: /* send <NULL> only if it improves encoding */ tx = 1; optional = 1; sndmsg = MRP_SND_IN; break; case MRP_VP_STATE: /* send JOIN */ tx = 1; sndmsg = MRP_SND_JOIN; mrp_state = MRP_AA_STATE; break; case MRP_VN_STATE: /* send NEW */ tx = 1; sndmsg = MRP_SND_NEW; mrp_state = MRP_AN_STATE; break; case MRP_AN_STATE: /* send NEW */ tx = 1; sndmsg = MRP_SND_NEW; mrp_state = MRP_QA_STATE; break; case MRP_AP_STATE: case MRP_AA_STATE: /* send JOIN */ tx = 1; sndmsg = MRP_SND_JOIN; mrp_state = MRP_QA_STATE; break; case MRP_QA_STATE: /* send JOIN only if it improves encoding */ tx = 1; optional = 1; sndmsg = MRP_SND_JOIN; break; case MRP_LA_STATE: /* send LV */ tx = 1; sndmsg = MRP_SND_LV; mrp_state = MRP_VO_STATE; break; case MRP_AO_STATE: case MRP_QO_STATE: case MRP_QP_STATE: /* send <NULL> only if it improves encoding */ tx = 1; optional = 1; sndmsg = MRP_SND_IN; break; case MRP_LO_STATE: /* send <NULL> */ tx = 1; sndmsg = MRP_SND_IN; mrp_state = MRP_VO_STATE; break; default: break; } break; case MRP_EVENT_RNEW: /* do nothing */ break; case MRP_EVENT_RJOININ: switch (mrp_state) { case MRP_VO_STATE: if (0 == p2pmac) mrp_state = MRP_AO_STATE; break; case MRP_VP_STATE: if (0 == p2pmac) { mrp_state = MRP_AP_STATE; } break; case MRP_AA_STATE: mrp_state = MRP_QA_STATE; break; case MRP_AO_STATE: mrp_state = MRP_QO_STATE; break; case MRP_AP_STATE: mrp_state = MRP_QP_STATE; break; default: break; } break; case MRP_EVENT_RIN: switch (mrp_state) { case MRP_AA_STATE: if (1 == p2pmac) mrp_state = MRP_QA_STATE; break; default: break; } break; case MRP_EVENT_RJOINMT: case MRP_EVENT_RMT: switch (mrp_state) { case MRP_QA_STATE: mrp_state = MRP_AA_STATE; break; case MRP_QO_STATE: mrp_state = MRP_AO_STATE; break; case MRP_QP_STATE: mrp_state = MRP_AP_STATE; break; case MRP_LO_STATE: mrp_state = MRP_VO_STATE; break; default: break; } break; case MRP_EVENT_RLV: case MRP_EVENT_RLA: case MRP_EVENT_REDECLARE: switch (mrp_state) { case MRP_VO_STATE: mrp_state = MRP_LO_STATE; break; case MRP_AN_STATE: mrp_state = MRP_VN_STATE; break; case MRP_QA_STATE: case MRP_AA_STATE: mrp_state = MRP_VP_STATE; break; case MRP_AO_STATE: case MRP_QO_STATE: mrp_state = MRP_LO_STATE; break; case MRP_AP_STATE: case MRP_QP_STATE: mrp_state = MRP_VP_STATE; break; default: break; } break; case MRP_EVENT_PERIODIC: switch (mrp_state) { case MRP_QA_STATE: mrp_state = MRP_AA_STATE; break; case MRP_QP_STATE: mrp_state = MRP_AP_STATE; break; default: break; } break; default: printf("mrp_applicant_fsm:unexpected event %s (%d)\n", mrp_event_string(event), event); return -1; break; } attrib->tx = tx; #if LOG_MVRP || LOG_MSRP || LOG_MMRP if (attrib->mrp_state != mrp_state) { mrpd_log_printf("mrp_applicant_fsm event %s, state %s -> %s\n", mrp_event_string(event), mrp_state_string(attrib->mrp_state), mrp_state_string(mrp_state)); } else { mrpd_log_printf("mrp_applicant_fsm event %s, state %s\n", mrp_event_string(event), mrp_state_string(mrp_state)); } #endif attrib->mrp_state = mrp_state; attrib->sndmsg = sndmsg; attrib->encode = (optional ? MRP_ENCODE_OPTIONAL : MRP_ENCODE_YES); return 0; }