static int rtcfg_conn_state_stage_1(struct rtcfg_connection *conn, RTCFG_EVENT event_id, void* event_data) { struct rtskb *rtskb = (struct rtskb *)event_data; struct rtcfg_device *rtcfg_dev = &device[conn->ifindex]; struct rtcfg_frm_ack_cfg *ack_cfg; int packets; switch (event_id) { case RTCFG_FRM_ACK_CFG: conn->last_frame = rtskb->time_stamp; ack_cfg = (struct rtcfg_frm_ack_cfg *)rtskb->data; conn->cfg_offs = ntohl(ack_cfg->ack_len); if ((conn->flags & RTCFG_FLAG_STAGE_2_DATA) != 0) { if (conn->cfg_offs >= conn->stage2_file->size) { rtcfg_dev->spec.srv.clients_configured++; if (rtcfg_dev->spec.srv.clients_configured == rtcfg_dev->other_stations) rtcfg_complete_cmd(conn->ifindex, RTCFG_CMD_WAIT, 0); rtcfg_next_conn_state(conn, ((conn->flags & RTCFG_FLAG_READY) != 0) ? RTCFG_CONN_READY : RTCFG_CONN_STAGE_2); } else { packets = conn->burstrate; while ((conn->cfg_offs < conn->stage2_file->size) && (packets > 0)) { rtcfg_send_stage_2_frag(conn); packets--; } } } else { rtcfg_dev->spec.srv.clients_configured++; if (rtcfg_dev->spec.srv.clients_configured == rtcfg_dev->other_stations) rtcfg_complete_cmd(conn->ifindex, RTCFG_CMD_WAIT, 0); rtcfg_next_conn_state(conn, ((conn->flags & RTCFG_FLAG_READY) != 0) ? RTCFG_CONN_READY : RTCFG_CONN_STAGE_2); } break; case RTCFG_TIMER: rtcfg_conn_check_cfg_timeout(conn); break; default: RTCFG_DEBUG(1, "RTcfg: unknown event %s for conn %p in %s()\n", rtcfg_event[event_id], conn, __FUNCTION__); return -EINVAL; } return 0; }
static int rtcfg_conn_state_stage_2(struct rtcfg_connection *conn, RTCFG_EVENT event_id, void* event_data) { struct rtskb *rtskb = (struct rtskb *)event_data; struct rtcfg_device *rtcfg_dev = &device[conn->ifindex]; switch (event_id) { case RTCFG_FRM_READY: conn->last_frame = rtskb->time_stamp; rtcfg_next_conn_state(conn, RTCFG_CONN_READY); conn->flags |= RTCFG_FLAG_READY; rtcfg_dev->stations_ready++; if (rtcfg_dev->stations_ready == rtcfg_dev->other_stations) rtcfg_complete_cmd(conn->ifindex, RTCFG_CMD_READY, 0); break; case RTCFG_TIMER: rtcfg_conn_check_cfg_timeout(conn); break; default: RTCFG_DEBUG(1, "RTcfg: unknown event %s for conn %p in %s()\n", rtcfg_event[event_id], conn, __FUNCTION__); return -EINVAL; } return 0; }
static int rtcfg_conn_state_searching(struct rtcfg_connection *conn, RTCFG_EVENT event_id, void* event_data) { struct rtcfg_device *rtcfg_dev = &device[conn->ifindex]; struct rtskb *rtskb = (struct rtskb *)event_data; switch (event_id) { case RTCFG_FRM_ANNOUNCE_NEW: rtcfg_conn_recv_announce_new(conn, rtskb); break; case RTCFG_FRM_ANNOUNCE_REPLY: conn->last_frame = rtskb->time_stamp; rtcfg_next_conn_state(conn, RTCFG_CONN_READY); rtcfg_dev->stations_found++; rtcfg_dev->stations_ready++; rtcfg_dev->spec.srv.clients_configured++; if (rtcfg_dev->spec.srv.clients_configured == rtcfg_dev->other_stations) rtcfg_complete_cmd(conn->ifindex, RTCFG_CMD_WAIT, 0); break; default: RTCFG_DEBUG(1, "RTcfg: unknown event %s for conn %p in %s()\n", rtcfg_event[event_id], conn, __FUNCTION__); return -EINVAL; } return 0; }
int rtcfg_main_state_client_ready(int ifindex, RTCFG_EVENT event_id, void* event_data) { struct rtskb *rtskb = (struct rtskb *)event_data; struct rt_proc_call *call = (struct rt_proc_call *)event_data; struct rtcfg_device *rtcfg_dev; switch (event_id) { case RTCFG_CMD_DETACH: rtcfg_client_detach(ifindex, call); break; case RTCFG_FRM_READY: if (rtcfg_client_recv_ready(ifindex, rtskb) == 0) { rtcfg_dev = &device[ifindex]; if (rtcfg_dev->stations_ready == rtcfg_dev->other_stations) rtcfg_complete_cmd(ifindex, RTCFG_CMD_READY, 0); rtos_res_unlock(&rtcfg_dev->dev_lock); } break; case RTCFG_FRM_ANNOUNCE_NEW: if (rtcfg_client_recv_announce(ifindex, rtskb) == 0) { rtcfg_send_announce_reply(ifindex, rtskb->mac.ethernet->h_source); rtos_res_unlock(&device[ifindex].dev_lock); } kfree_rtskb(rtskb); break; case RTCFG_FRM_DEAD_STATION: rtcfg_client_recv_dead_station(ifindex, rtskb); break; case RTCFG_FRM_STAGE_1_CFG: rtcfg_client_update_server(ifindex, rtskb); break; default: rtos_res_unlock(&device[ifindex].dev_lock); RTCFG_DEBUG(1, "RTcfg: unknown event %s for rtdev %d in %s()\n", rtcfg_event[event_id], ifindex, __FUNCTION__); return -EINVAL; } return 0; }
static void rtcfg_client_recv_stage_2_cfg(int ifindex, struct rtskb *rtskb) { struct rtcfg_frm_stage_2_cfg *stage_2_cfg; struct rtcfg_device *rtcfg_dev = &device[ifindex]; size_t data_len; int ret; if (rtskb->len < sizeof(struct rtcfg_frm_stage_2_cfg)) { rtos_res_unlock(&rtcfg_dev->dev_lock); RTCFG_DEBUG(1, "RTcfg: received invalid stage_2_cfg frame\n"); kfree_rtskb(rtskb); return; } stage_2_cfg = (struct rtcfg_frm_stage_2_cfg *)rtskb->data; __rtskb_pull(rtskb, sizeof(struct rtcfg_frm_stage_2_cfg)); if (stage_2_cfg->heartbeat_period) { ret = rtos_task_init_periodic(&rtcfg_dev->timer_task, rtcfg_timer, (void *)ifindex, RTOS_LOWEST_RT_PRIORITY, ((nanosecs_t)ntohs(stage_2_cfg->heartbeat_period)) * 1000000); if (ret < 0) /*ERRMSG*/rtos_print("RTcfg: unable to create timer task\n"); else rtcfg_dev->flags |= FLAG_TIMER_STARTED; } /* add server to station list */ if (rtcfg_add_to_station_list(rtcfg_dev, rtskb->mac.ethernet->h_source, stage_2_cfg->flags) < 0) { rtos_res_unlock(&rtcfg_dev->dev_lock); RTCFG_DEBUG(1, "RTcfg: unable to process stage_2_cfg frage\n"); kfree_rtskb(rtskb); return; } rtcfg_dev->other_stations = ntohl(stage_2_cfg->stations); rtcfg_dev->spec.clt.cfg_len = ntohl(stage_2_cfg->cfg_len); data_len = MIN(rtcfg_dev->spec.clt.cfg_len, rtskb->len); if (((rtcfg_dev->flags & RTCFG_FLAG_STAGE_2_DATA) != 0) && (data_len > 0)) { rtcfg_client_queue_frag(ifindex, rtskb, data_len); rtskb = NULL; if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) rtcfg_next_main_state(ifindex, RTCFG_MAIN_CLIENT_ALL_KNOWN); } else { if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtcfg_complete_cmd(ifindex, RTCFG_CMD_ANNOUNCE, 0); rtcfg_next_main_state(ifindex, ((rtcfg_dev->flags & RTCFG_FLAG_READY) != 0) ? RTCFG_MAIN_CLIENT_READY : RTCFG_MAIN_CLIENT_2); } else rtcfg_next_main_state(ifindex, RTCFG_MAIN_CLIENT_ALL_FRAMES); rtcfg_send_ack(ifindex); } rtos_res_unlock(&rtcfg_dev->dev_lock); if (rtskb != NULL) kfree_rtskb(rtskb); }
static void rtcfg_client_recv_stage_2_cfg(int ifindex, struct rtskb *rtskb) { struct rtcfg_frm_stage_2_cfg *stage_2_cfg; struct rtcfg_device *rtcfg_dev = &device[ifindex]; size_t data_len; int ret; if (rtskb->len < sizeof(struct rtcfg_frm_stage_2_cfg)) { rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); RTCFG_DEBUG(1, "RTcfg: received invalid stage_2_cfg frame\n"); kfree_rtskb(rtskb); return; } stage_2_cfg = (struct rtcfg_frm_stage_2_cfg *)rtskb->data; __rtskb_pull(rtskb, sizeof(struct rtcfg_frm_stage_2_cfg)); if (stage_2_cfg->heartbeat_period) { ret = rtdm_timer_init(&rtcfg_dev->timer, rtcfg_timer, "rtcfg-timer"); if (ret == 0) { ret = rtdm_timer_start(&rtcfg_dev->timer, XN_INFINITE, (nanosecs_rel_t)ntohs(stage_2_cfg->heartbeat_period) * 1000000, RTDM_TIMERMODE_RELATIVE); if (ret < 0) rtdm_timer_destroy(&rtcfg_dev->timer); } if (ret < 0) /*ERRMSG*/rtdm_printk("RTcfg: unable to create timer task\n"); else set_bit(FLAG_TIMER_STARTED, &rtcfg_dev->flags); } /* add server to station list */ if (rtcfg_add_to_station_list(rtcfg_dev, rtskb->mac.ethernet->h_source, stage_2_cfg->flags) < 0) { rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); RTCFG_DEBUG(1, "RTcfg: unable to process stage_2_cfg frage\n"); kfree_rtskb(rtskb); return; } rtcfg_dev->other_stations = ntohl(stage_2_cfg->stations); rtcfg_dev->spec.clt.cfg_len = ntohl(stage_2_cfg->cfg_len); data_len = MIN(rtcfg_dev->spec.clt.cfg_len, rtskb->len); if (test_bit(RTCFG_FLAG_STAGE_2_DATA, &rtcfg_dev->flags) && (data_len > 0)) { rtcfg_client_queue_frag(ifindex, rtskb, data_len); rtskb = NULL; if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) rtcfg_next_main_state(ifindex, RTCFG_MAIN_CLIENT_ALL_KNOWN); } else { if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtcfg_complete_cmd(ifindex, RTCFG_CMD_ANNOUNCE, 0); rtcfg_next_main_state(ifindex, test_bit(RTCFG_FLAG_READY, &rtcfg_dev->flags) ? RTCFG_MAIN_CLIENT_READY : RTCFG_MAIN_CLIENT_2); } else rtcfg_next_main_state(ifindex, RTCFG_MAIN_CLIENT_ALL_FRAMES); rtcfg_send_ack(ifindex); } rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); if (rtskb != NULL) kfree_rtskb(rtskb); }
int rtcfg_main_state_client_all_frames(int ifindex, RTCFG_EVENT event_id, void* event_data) { struct rtskb *rtskb = (struct rtskb *)event_data; struct rt_proc_call *call = (struct rt_proc_call *)event_data; struct rtcfg_device *rtcfg_dev; switch (event_id) { case RTCFG_CMD_DETACH: rtcfg_client_detach(ifindex, call); break; case RTCFG_FRM_ANNOUNCE_NEW: if (rtcfg_client_recv_announce(ifindex, rtskb) == 0) { rtcfg_send_announce_reply(ifindex, rtskb->mac.ethernet->h_source); rtcfg_dev = &device[ifindex]; if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtcfg_complete_cmd(ifindex, RTCFG_CMD_ANNOUNCE, 0); rtcfg_next_main_state(ifindex, test_bit(RTCFG_FLAG_READY, &rtcfg_dev->flags) ? RTCFG_MAIN_CLIENT_READY : RTCFG_MAIN_CLIENT_2); } rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); } kfree_rtskb(rtskb); break; case RTCFG_FRM_ANNOUNCE_REPLY: if (rtcfg_client_recv_announce(ifindex, rtskb) == 0) { rtcfg_dev = &device[ifindex]; if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtcfg_complete_cmd(ifindex, RTCFG_CMD_ANNOUNCE, 0); rtcfg_next_main_state(ifindex, test_bit(RTCFG_FLAG_READY, &rtcfg_dev->flags) ? RTCFG_MAIN_CLIENT_READY : RTCFG_MAIN_CLIENT_2); } rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); } kfree_rtskb(rtskb); break; case RTCFG_FRM_READY: if (rtcfg_client_recv_ready(ifindex, rtskb) == 0) rtdm_mutex_unlock(&device[ifindex].dev_mutex); break; case RTCFG_FRM_DEAD_STATION: rtcfg_client_recv_dead_station(ifindex, rtskb); break; case RTCFG_FRM_STAGE_1_CFG: /* ignore */ rtdm_mutex_unlock(&device[ifindex].dev_mutex); kfree_rtskb(rtskb); break; default: rtdm_mutex_unlock(&device[ifindex].dev_mutex); RTCFG_DEBUG(1, "RTcfg: unknown event %s for rtdev %d in %s()\n", rtcfg_event[event_id], ifindex, __FUNCTION__); return -EINVAL; } return 0; }