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 void rtcfg_conn_check_cfg_timeout(struct rtcfg_connection *conn) { struct rtcfg_device *rtcfg_dev; if (!conn->cfg_timeout) return; if (rtdm_clock_read() >= conn->last_frame + conn->cfg_timeout) { rtcfg_dev = &device[conn->ifindex]; rtcfg_dev->stations_found--; if (conn->state == RTCFG_CONN_STAGE_2) rtcfg_dev->spec.srv.clients_configured--; rtcfg_next_conn_state(conn, RTCFG_CONN_SEARCHING); conn->cfg_offs = 0; conn->flags = 0; #ifdef CONFIG_RTNET_RTIPV4 if (conn->addr_type == RTCFG_ADDR_IP) { struct rtnet_device *rtdev; /* MAC address yet unknown -> use broadcast address */ rtdev = rtdev_get_by_index(conn->ifindex); if (rtdev == NULL) return; memcpy(conn->mac_addr, rtdev->broadcast, MAX_ADDR_LEN); rtdev_dereference(rtdev); } #endif /* CONFIG_RTNET_RTIPV4 */ } }
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; }
static int rtcfg_conn_state_searching(struct rtcfg_connection *conn, RTCFG_EVENT event_id, void* event_data) { switch (event_id) { case RTCFG_FRM_ANNOUNCE_NEW: rtcfg_next_conn_state(conn, RTCFG_CONN_1); rtcfg_send_stage_2(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_conn_1(struct rtcfg_connection *conn, RTCFG_EVENT event_id, void* event_data) { switch (event_id) { case RTCFG_FRM_ACK_CFG: /* ... */ rtcfg_next_conn_state(conn, RTCFG_CONN_ESTABLISHED); device[conn->ifindex].clients_found++; 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 void rtcfg_conn_check_heartbeat(struct rtcfg_connection *conn) { u64 timeout; struct rtcfg_device *rtcfg_dev; timeout = device[conn->ifindex].spec.srv.heartbeat_timeout; if (!timeout) return; if (rtdm_clock_read() >= conn->last_frame + timeout) { rtcfg_dev = &device[conn->ifindex]; rtcfg_dev->stations_found--; rtcfg_dev->stations_ready--; rtcfg_dev->spec.srv.clients_configured--; rtcfg_send_dead_station(conn); rtcfg_next_conn_state(conn, RTCFG_CONN_DEAD); conn->cfg_offs = 0; conn->flags = 0; #ifdef CONFIG_RTNET_RTIPV4 if ((conn->addr_type & RTCFG_ADDR_MASK) == RTCFG_ADDR_IP) { struct rtnet_device *rtdev = rtdev_get_by_index(conn->ifindex); rt_ip_route_del_host(conn->addr.ip_addr, rtdev); if (rtdev == NULL) return; if (!(conn->addr_type & FLAG_ASSIGN_ADDR_BY_MAC)) /* MAC address yet unknown -> use broadcast address */ memcpy(conn->mac_addr, rtdev->broadcast, MAX_ADDR_LEN); rtdev_dereference(rtdev); } #endif /* CONFIG_RTNET_RTIPV4 */ } }
static void rtcfg_conn_recv_announce_new(struct rtcfg_connection *conn, struct rtskb *rtskb) { struct rtcfg_device *rtcfg_dev = &device[conn->ifindex]; struct rtcfg_frm_announce *announce_new; int packets; conn->last_frame = rtskb->time_stamp; announce_new = (struct rtcfg_frm_announce *)rtskb->data; conn->flags = announce_new->flags; if (announce_new->burstrate < conn->burstrate) conn->burstrate = announce_new->burstrate; rtcfg_next_conn_state(conn, RTCFG_CONN_STAGE_1); rtcfg_dev->stations_found++; if ((conn->flags & RTCFG_FLAG_READY) != 0) rtcfg_dev->stations_ready++; if (((conn->flags & RTCFG_FLAG_STAGE_2_DATA) != 0) && (conn->stage2_file != NULL)) { packets = conn->burstrate - 1; rtcfg_send_stage_2(conn, 1); while ((conn->cfg_offs < conn->stage2_file->size) && (packets > 0)) { rtcfg_send_stage_2_frag(conn); packets--; } } else { rtcfg_send_stage_2(conn, 0); conn->flags &= ~RTCFG_FLAG_STAGE_2_DATA; } }