Source avrcpSourceFromData(AVRCP *avrcp, uint8 *data, uint16 length) { /* Create a source from the data */ Source src = StreamRegionSource(data, length); /* Register a task for freeing the data and store a ptr to it */ avrcp->dataFreeTask.sent_data = data; MessageSinkTask(StreamSinkFromSource(src), &avrcp->dataFreeTask.cleanUpTask); return src; }
static uint32 read_sectors(FileInfoType *file_info, uint32 logical_address, uint32 transfer_length, uint32 area_start_sector) { uint32 start_sector; uint32 end_sector; uint32 file_end_sector = file_info->end_sector; uint16 i = 0; Sink sink = StreamUsbEndPointSink(end_point_bulk_out); /* correct end sector for FAT2, as it's otherwise treated as FAT1 */ if (area_start_sector == FAT2_SECTOR) file_end_sector += SECTORS_PER_FAT; /* find the start sector and end sector for this type of data */ start_sector = logical_address - area_start_sector; end_sector = start_sector + transfer_length - 1; if (end_sector > (file_end_sector - area_start_sector)) end_sector = file_end_sector - area_start_sector; MS_DEBUG(("FAT16: start %ld end %ld fileend %ld log %ld areastart %ld\n",start_sector,end_sector,file_info->end_sector,logical_address,area_start_sector)); /* check to see if the file read should begin at the start of the file */ if ((file_info->src == 0) || (start_sector < file_info->current_start_sector)) { if (file_info->params) file_info->src = StreamRegionSource(file_info->params, file_info->size); else file_info->src = StreamFileSource(file_info->index); file_info->current_start_sector = 0; MS_DEBUG(("FAT16: new file\n")); } /* seek through the file until the correct sector is reached */ while ((start_sector > file_info->current_start_sector) && (file_info->current_start_sector < end_sector)) { SourceDrop(file_info->src, BYTES_PER_SECTOR); file_info->current_start_sector++; MS_DEBUG(("FAT16: src drop %ld\n",file_info->current_start_sector)); } /* send the data in the sectors from start_sector to end_sector */ while (i <= (end_sector - start_sector)) { uint8 *buffer = 0; uint16 sink_slack = 0; uint16 source_size; uint16 blocks_in_sink; uint16 blocks_in_source; uint16 blocks_to_read; uint32 bytes_to_read; uint32 remaining_bytes; uint16 bytes_to_copy = 0; /* wait for free space in Sink */ Fat16_WaitAvailable(sink, BYTES_PER_SECTOR); sink_slack = SinkSlack(sink); source_size = SourceSize(file_info->src); blocks_in_sink = sink_slack / BYTES_PER_SECTOR; /* find the maximum sectors that can be sent */ if ((source_size % BYTES_PER_SECTOR) == 0) blocks_in_source = source_size / BYTES_PER_SECTOR; else blocks_in_source = source_size / BYTES_PER_SECTOR + 1; blocks_to_read = blocks_in_sink > blocks_in_source ? blocks_in_source : blocks_in_sink; if (blocks_to_read > (end_sector - i + 1)) blocks_to_read = end_sector - i + 1; bytes_to_read = blocks_to_read * BYTES_PER_SECTOR; remaining_bytes = file_info->size - (file_info->current_start_sector * BYTES_PER_SECTOR); MS_DEBUG(("FAT16: info sink_slack:%d source_size:%d blocks_to_read:%d\n",sink_slack,source_size,blocks_to_read)); if (blocks_to_read == 0) break; if (remaining_bytes < bytes_to_read) bytes_to_copy = remaining_bytes; else bytes_to_copy = bytes_to_read; if ((buffer = claimSink(sink, bytes_to_read)) != 0) { const uint8 *data_ptr = SourceMap(file_info->src); bool flush; if (bytes_to_copy < bytes_to_read) memset(buffer + bytes_to_copy, 0, bytes_to_read - bytes_to_copy); memmove(buffer, data_ptr, bytes_to_copy); SinkConfigure(sink, VM_SINK_USB_TRANSFER_LENGTH, bytes_to_read); flush = SinkFlush(sink, bytes_to_read); SourceDrop(file_info->src, bytes_to_copy); file_info->current_start_sector += blocks_to_read; i += blocks_to_read; MS_DEBUG(("FAT16: send bytes %d pos %ld i %d flush %d\n",bytes_to_copy,file_info->current_start_sector,i,flush)); } else { break; } } /* return the next logical address to process */ return logical_address + end_sector - start_sector + 1; }