void handle_control_packet (ArvFakeGvCamera *gv_camera, GSocket *socket, GSocketAddress *remote_address, ArvGvcpPacket *packet, size_t size) { ArvGvcpPacket *ack_packet = NULL; size_t ack_packet_size; guint32 block_address; guint32 block_size; guint16 packet_id; guint32 register_address; guint32 register_value; gboolean write_access; if (gv_camera->controller_address != NULL) { struct timespec time; guint64 elapsed_ms; clock_gettime (CLOCK_MONOTONIC, &time); elapsed_ms = 1000 * (time.tv_sec - gv_camera->controller_time.tv_sec) + (time.tv_nsec - gv_camera->controller_time.tv_nsec) / 1000000; if (elapsed_ms > arv_fake_camera_get_heartbeat_timeout (gv_camera->camera)) { g_object_ref (gv_camera->controller_address); gv_camera->controller_address = NULL; write_access = TRUE; arv_warning_device ("[FakeGvCamera::handle_control_packet] Heartbeat timeout"); arv_fake_camera_set_control_channel_privilege (gv_camera->camera, 0); } else write_access = _g_inet_socket_address_is_equal (G_INET_SOCKET_ADDRESS (remote_address), G_INET_SOCKET_ADDRESS (gv_camera->controller_address)); } else write_access = TRUE; arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); packet_id = arv_gvcp_packet_get_packet_id (packet); switch (g_ntohs (packet->header.command)) { case ARV_GVCP_COMMAND_DISCOVERY_CMD: ack_packet = arv_gvcp_packet_new_discovery_ack (&ack_packet_size); arv_debug_device ("[FakeGvCamera::handle_control_packet] Discovery command"); arv_fake_camera_read_memory (gv_camera->camera, 0, ARV_GVBS_DISCOVERY_DATA_SIZE, &ack_packet->data); break; case ARV_GVCP_COMMAND_READ_MEMORY_CMD: arv_gvcp_packet_get_read_memory_cmd_infos (packet, &block_address, &block_size); arv_debug_device ("[FakeGvCamera::handle_control_packet] Read memory command %d (%d)", block_address, block_size); ack_packet = arv_gvcp_packet_new_read_memory_ack (block_address, block_size, packet_id, &ack_packet_size); arv_fake_camera_read_memory (gv_camera->camera, block_address, block_size, arv_gvcp_packet_get_read_memory_ack_data (ack_packet)); break; case ARV_GVCP_COMMAND_WRITE_MEMORY_CMD: if (!write_access) break; arv_gvcp_packet_get_write_memory_cmd_infos (packet, &block_address, &block_size); arv_debug_device ("[FakeGvCamera::handle_control_packet] Write memory command %d (%d)", block_address, block_size); arv_fake_camera_write_memory (gv_camera->camera, block_address, block_size, arv_gvcp_packet_get_write_memory_cmd_data (packet)); ack_packet = arv_gvcp_packet_new_write_memory_ack (block_address, packet_id, &ack_packet_size); break; case ARV_GVCP_COMMAND_READ_REGISTER_CMD: arv_gvcp_packet_get_read_register_cmd_infos (packet, ®ister_address); arv_fake_camera_read_register (gv_camera->camera, register_address, ®ister_value); arv_debug_device ("[FakeGvCamera::handle_control_packet] Read register command %d -> %d", register_address, register_value); ack_packet = arv_gvcp_packet_new_read_register_ack (register_value, packet_id, &ack_packet_size); if (register_address == ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_OFFSET) clock_gettime (CLOCK_MONOTONIC, &gv_camera->controller_time); break; case ARV_GVCP_COMMAND_WRITE_REGISTER_CMD: if (!write_access) break; arv_gvcp_packet_get_write_register_cmd_infos (packet, ®ister_address, ®ister_value); arv_fake_camera_write_register (gv_camera->camera, register_address, register_value); arv_debug_device ("[FakeGvCamera::handle_control_packet] Write register command %d -> %d", register_address, register_value); ack_packet = arv_gvcp_packet_new_write_register_ack (register_value, packet_id, &ack_packet_size); break; default: arv_warning_device ("[FakeGvCamera::handle_control_packet] Unknown command"); } if (ack_packet != NULL) { g_socket_send_to (socket, remote_address, (char *) ack_packet, ack_packet_size, NULL, NULL); arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); g_free (ack_packet); } if (gv_camera->controller_address == NULL && arv_fake_camera_get_control_channel_privilege (gv_camera->camera) != 0) { g_object_ref (remote_address); gv_camera->controller_address = remote_address; clock_gettime (CLOCK_MONOTONIC, &gv_camera->controller_time); } }
gboolean handle_control_packet (ArvGvFakeCamera *gv_fake_camera, GSocket *socket, GSocketAddress *remote_address, ArvGvcpPacket *packet, size_t size) { ArvGvcpPacket *ack_packet = NULL; size_t ack_packet_size; guint32 block_address; guint32 block_size; guint16 packet_id; guint16 packet_type; guint32 register_address; guint32 register_value; gboolean write_access; gboolean success = FALSE; if (gv_fake_camera->priv->controller_address != NULL) { gint64 time; guint64 elapsed_ms; time = g_get_real_time (); elapsed_ms = (time - gv_fake_camera->priv->controller_time) / 1000; if (elapsed_ms > arv_fake_camera_get_heartbeat_timeout (gv_fake_camera->priv->camera)) { g_object_unref (gv_fake_camera->priv->controller_address); gv_fake_camera->priv->controller_address = NULL; write_access = TRUE; arv_warning_device ("[GvFakeCamera::handle_control_packet] Heartbeat timeout"); arv_fake_camera_set_control_channel_privilege (gv_fake_camera->priv->camera, 0); } else write_access = _g_inet_socket_address_is_equal (G_INET_SOCKET_ADDRESS (remote_address), G_INET_SOCKET_ADDRESS (gv_fake_camera->priv->controller_address)); } else write_access = TRUE; arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); packet_id = arv_gvcp_packet_get_packet_id (packet); packet_type = arv_gvcp_packet_get_packet_type (packet); if (packet_type != ARV_GVCP_PACKET_TYPE_CMD) { arv_warning_device ("[GvFakeCamera::handle_control_packet] Unknown packet type"); return FALSE; } switch (g_ntohs (packet->header.command)) { case ARV_GVCP_COMMAND_DISCOVERY_CMD: ack_packet = arv_gvcp_packet_new_discovery_ack (&ack_packet_size); arv_debug_device ("[GvFakeCamera::handle_control_packet] Discovery command"); arv_fake_camera_read_memory (gv_fake_camera->priv->camera, 0, ARV_GVBS_DISCOVERY_DATA_SIZE, &ack_packet->data); break; case ARV_GVCP_COMMAND_READ_MEMORY_CMD: arv_gvcp_packet_get_read_memory_cmd_infos (packet, &block_address, &block_size); arv_debug_device ("[GvFakeCamera::handle_control_packet] Read memory command %d (%d)", block_address, block_size); ack_packet = arv_gvcp_packet_new_read_memory_ack (block_address, block_size, packet_id, &ack_packet_size); arv_fake_camera_read_memory (gv_fake_camera->priv->camera, block_address, block_size, arv_gvcp_packet_get_read_memory_ack_data (ack_packet)); break; case ARV_GVCP_COMMAND_WRITE_MEMORY_CMD: arv_gvcp_packet_get_write_memory_cmd_infos (packet, &block_address, &block_size); if (!write_access) { arv_warning_device("[GvFakeCamera::handle_control_packet] Ignore Write memory command %d (%d) not controller", block_address, block_size); break; } arv_debug_device ("[GvFakeCamera::handle_control_packet] Write memory command %d (%d)", block_address, block_size); arv_fake_camera_write_memory (gv_fake_camera->priv->camera, block_address, block_size, arv_gvcp_packet_get_write_memory_cmd_data (packet)); ack_packet = arv_gvcp_packet_new_write_memory_ack (block_address, packet_id, &ack_packet_size); break; case ARV_GVCP_COMMAND_READ_REGISTER_CMD: arv_gvcp_packet_get_read_register_cmd_infos (packet, ®ister_address); arv_fake_camera_read_register (gv_fake_camera->priv->camera, register_address, ®ister_value); arv_debug_device ("[GvFakeCamera::handle_control_packet] Read register command %d -> %d", register_address, register_value); ack_packet = arv_gvcp_packet_new_read_register_ack (register_value, packet_id, &ack_packet_size); if (register_address == ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_OFFSET) gv_fake_camera->priv->controller_time = g_get_real_time (); break; case ARV_GVCP_COMMAND_WRITE_REGISTER_CMD: arv_gvcp_packet_get_write_register_cmd_infos (packet, ®ister_address, ®ister_value); if (!write_access) { arv_warning_device("[GvFakeCamera::handle_control_packet] Ignore Write register command %d (%d) not controller", register_address, register_value); break; } arv_fake_camera_write_register (gv_fake_camera->priv->camera, register_address, register_value); arv_debug_device ("[GvFakeCamera::handle_control_packet] Write register command %d -> %d", register_address, register_value); ack_packet = arv_gvcp_packet_new_write_register_ack (1, packet_id, &ack_packet_size); break; default: arv_warning_device ("[GvFakeCamera::handle_control_packet] Unknown command"); } if (ack_packet != NULL) { g_socket_send_to (socket, remote_address, (char *) ack_packet, ack_packet_size, NULL, NULL); arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); g_free (ack_packet); success = TRUE; } if (gv_fake_camera->priv->controller_address == NULL && arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) != 0) { g_object_ref (remote_address); arv_debug_device("[GvFakeCamera::handle_control_packet] New controller"); gv_fake_camera->priv->controller_address = remote_address; gv_fake_camera->priv->controller_time = g_get_real_time (); } else if (gv_fake_camera->priv->controller_address != NULL && arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) == 0) { g_object_unref (gv_fake_camera->priv->controller_address); arv_debug_device("[GvFakeCamera::handle_control_packet] Controller releases"); gv_fake_camera->priv->controller_address = NULL; gv_fake_camera->priv->controller_time = g_get_real_time (); } return success; }