static void hard_drive_handle_connection (ata_drive_type *ata_drive, mailbox_id_type reply_mailbox_id) { message_parameter_type message_parameter; ipc_structure_type ipc_structure; bool done = FALSE; u32 *data; unsigned int data_size = 1024; memory_allocate ((void **) &data, data_size); /* Accept the connection. */ ipc_structure.output_mailbox_id = reply_mailbox_id; ipc_connection_establish (&ipc_structure); message_parameter.block = TRUE; while (!done) { message_parameter.protocol = IPC_PROTOCOL_BLOCK; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; message_parameter.data = data; if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { case IPC_BLOCK_READ: { ipc_block_read_type *ipc_block_read = (ipc_block_read_type *) data; /* FIXME: Do some boundary checking. */ #ifdef DEBUG log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Reading blocks %u-%u data.", ipc_block_read->start_block_number, ipc_block_read->start_block_number + ipc_block_read->number_of_blocks); #endif ata_read_block (ata_drive, ipc_block_read->start_block_number, message_parameter.data, ipc_block_read->number_of_blocks); message_parameter.length = ipc_block_read->number_of_blocks; message_parameter.block = TRUE; ipc_send (ipc_structure.output_mailbox_id, &message_parameter); break; } case IPC_BLOCK_WRITE: { break; } case IPC_BLOCK_GET_INFO: { break; } } } }
void handle_connection(mailbox_id_type *reply_mailbox_id) { system_thread_name_set("Handling connection"); message_parameter_type message_parameter; bool done = FALSE; bool mounted = FALSE; fat_info_type fat_info; ipc_structure_type ipc_structure; uint8_t *data; uint8_t **data_pointer = &data; unsigned int data_size = 16384; memory_allocate((void **) data_pointer, data_size); // Accept the connection. ipc_structure.output_mailbox_id = *reply_mailbox_id; if (ipc_connection_establish(&ipc_structure) != IPC_RETURN_SUCCESS) { return; } message_parameter.block = TRUE; while (!done) { message_parameter.data = data; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive(ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { // Read one or more directory entries. case IPC_FILE_DIRECTORY_ENTRY_READ: { if (mounted) { file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data; if (!fat_directory_entry_read(directory_entry_read, &fat_info)) { directory_entry_read->entries = 0; } message_parameter.length = sizeof(file_directory_entry_read_type) + sizeof(file_directory_entry_type) * directory_entry_read->entries ; // log_print_formatted (0, PACKAGE, "Successfully read %u entries", // directory_entry_read->entries); // log_print_formatted (0, PACKAGE, "max: %u\n", directory_entry_read->entries); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_GET_INFO: { if (mounted) { file_verbose_directory_entry_type *directory_entry = (file_verbose_directory_entry_type *) data; if (!fat_file_get_info(&fat_info, directory_entry)) { return_type return_value = FILE_RETURN_FILE_ABSENT; log_print_formatted(&log_structure, LOG_URGENCY_ERROR, "IPC_FILE_GET_INFO failed"); message_parameter.message_class = IPC_FILE_RETURN_VALUE; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_MOUNT_VOLUME: { mailbox_id_type *mailbox = (mailbox_id_type *) data; fat_info.block_structure.output_mailbox_id = *mailbox; if (ipc_service_connection_request(&fat_info.block_structure) != IPC_RETURN_SUCCESS) { break; } // Check if we have a FAT file system at this location. if (!detect_fat(&fat_info)) { log_print(&log_structure, LOG_URGENCY_ERROR, "No FAT filesystem detected."); break; } mounted = TRUE; break; } case IPC_FILE_OPEN: { ipc_file_open_type *open = (ipc_file_open_type *) data; if (!fat_file_open(&fat_info, open)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to open file."); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } case IPC_FILE_READ: { file_read_type *read = (file_read_type *) data; uint8_t *read_buffer; uint8_t **read_buffer_pointer = &read_buffer; memory_allocate((void **) read_buffer_pointer, read->bytes); if (!fat_file_read(&fat_info, read->file_handle, read_buffer, read->bytes)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to read from file."); } message_parameter.data = read_buffer; message_parameter.length = read->bytes; #ifdef DEBUG log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "Sending %lu", read->bytes); #endif ipc_send(ipc_structure.output_mailbox_id, &message_parameter); memory_deallocate((void **) read_buffer_pointer); break; } // Unsupported functions. case IPC_FILE_CLOSE: case IPC_FILE_SEEK: case IPC_FILE_WRITE: case IPC_FILE_ACL_READ: case IPC_FILE_ACL_WRITE: case IPC_FILE_UNMOUNT_VOLUME: default: { return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } } } }
static void handle_connection (mailbox_id_type reply_mailbox_id, realtek_device_type *device) { message_parameter_type message_parameter; ipc_structure_type ipc_structure; bool done = FALSE; unsigned int data_size = 1024; u32 *data; memory_allocate ((void **) &data, data_size); /* Accept the connection. */ ipc_structure.output_mailbox_id = reply_mailbox_id; ipc_connection_establish (&ipc_structure); message_parameter.data = data; message_parameter.block = TRUE; message_parameter.protocol = IPC_PROTOCOL_ETHERNET; while (!done) { message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive (ipc_structure.input_mailbox_id, &message_parameter, &data_size) != STORM_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { case IPC_ETHERNET_REGISTER_TARGET: { /* FIXME: Check if the protocol is already registered */ device->target[device->number_of_targets].mailbox_id = ipc_structure.output_mailbox_id; device->target[device->number_of_targets].protocol_type = system_byte_swap_u16 (data[0]); device->number_of_targets++; break; } case IPC_ETHERNET_PACKET_SEND: { if (!realtek_start_transmit ((u8 *) data, message_parameter.length, device)) { log_print (&log_structure, LOG_URGENCY_ERROR, "Failed to send an ethernet packet."); /* FIXME: Do something. */ } break; } case IPC_ETHERNET_ADDRESS_GET: { memory_copy (data, &device->ethernet_address, 6); message_parameter.length = 6; system_call_mailbox_send (ipc_structure.output_mailbox_id, &message_parameter); break; } default: { log_print (&log_structure, LOG_URGENCY_ERROR, "Unknown IPC command received."); break; } } } }