static int rtcfg_client_get_frag(int ifindex, struct rt_proc_call *call) { struct rtcfg_device *rtcfg_dev = &device[ifindex]; struct rtcfg_cmd *cmd_event; cmd_event = rtpc_get_priv(call, struct rtcfg_cmd); if ((rtcfg_dev->flags & RTCFG_FLAG_STAGE_2_DATA) == 0) { rtos_res_unlock(&rtcfg_dev->dev_lock); return -EINVAL; } rtcfg_send_ack(ifindex); if (rtcfg_dev->spec.clt.cfg_offs >= rtcfg_dev->spec.clt.cfg_len) { if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtpc_complete_call(call, 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_queue_blocking_call(ifindex, call); } } else rtcfg_queue_blocking_call(ifindex, call); rtos_res_unlock(&rtcfg_dev->dev_lock); return -CALL_PENDING; }
static int rtcfg_client_get_frag(int ifindex, struct rt_proc_call *call) { struct rtcfg_device *rtcfg_dev = &device[ifindex]; if (test_bit(RTCFG_FLAG_STAGE_2_DATA, &rtcfg_dev->flags) == 0) { rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); return -EINVAL; } rtcfg_send_ack(ifindex); if (rtcfg_dev->spec.clt.cfg_offs >= rtcfg_dev->spec.clt.cfg_len) { if (rtcfg_dev->stations_found == rtcfg_dev->other_stations) { rtpc_complete_call(call, 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_queue_blocking_call(ifindex, call); } } else rtcfg_queue_blocking_call(ifindex, call); rtdm_mutex_unlock(&rtcfg_dev->dev_mutex); return -CALL_PENDING; }
static void rtcfg_client_recv_stage_2_frag(int ifindex, struct rtskb *rtskb) { struct rtcfg_frm_stage_2_cfg_frag *stage_2_frag; struct rtcfg_device *rtcfg_dev = &device[ifindex]; size_t data_len; if (rtskb->len < sizeof(struct rtcfg_frm_stage_2_cfg_frag)) { rtos_res_unlock(&rtcfg_dev->dev_lock); RTCFG_DEBUG(1, "RTcfg: received invalid stage_2_cfg_frag frame\n"); kfree_rtskb(rtskb); return; } stage_2_frag = (struct rtcfg_frm_stage_2_cfg_frag *)rtskb->data; __rtskb_pull(rtskb, sizeof(struct rtcfg_frm_stage_2_cfg_frag)); data_len = MIN(rtcfg_dev->spec.clt.cfg_len - rtcfg_dev->spec.clt.cfg_offs, rtskb->len); if ((rtcfg_dev->flags & RTCFG_FLAG_STAGE_2_DATA) == 0) { RTCFG_DEBUG(1, "RTcfg: unexpected stage 2 fragment, we did not " "request any data!\n"); } else if (rtcfg_dev->spec.clt.cfg_offs != ntohl(stage_2_frag->frag_offs)) { RTCFG_DEBUG(1, "RTcfg: unexpected stage 2 fragment (expected: %d, " "received: %d)\n", rtcfg_dev->spec.clt.cfg_offs, ntohl(stage_2_frag->frag_offs)); rtcfg_send_ack(ifindex); rtcfg_dev->spec.clt.packet_counter = 0; } else { rtcfg_client_queue_frag(ifindex, rtskb, data_len); rtskb = NULL; } 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)) { 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); }