static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	gboolean rspcode, final;
	guint id;

	g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);

	id = transfer->req_id;
	transfer->req_id = 0;

	if (err != NULL) {
		transfer_complete(transfer, err);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(G_OBEX_ERROR, rspcode, "%s",
						g_obex_strerror(rspcode));
		goto failed;
	}

	if (transfer->opcode == G_OBEX_OP_GET) {
		handle_get_body(transfer, rsp, &err);
		if (err != NULL)
			goto failed;
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		transfer_complete(transfer, NULL);
		return;
	}

	if (transfer->opcode == G_OBEX_OP_PUT) {
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
	} else if (!g_obex_srm_active(transfer->obex)) {
		req = g_obex_packet_new(transfer->opcode, TRUE,
							G_OBEX_HDR_INVALID);
	} else {
		/* Keep id since request still outstanting */
		transfer->req_id = id;
		return;
	}

	transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
							transfer, &err);
failed:
	if (err != NULL) {
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
		transfer_complete(transfer, err);
		g_error_free(err);
	}
}
예제 #2
0
static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	gboolean rspcode, final;

	transfer->req_id = 0;

	if (err != NULL) {
		transfer_complete(transfer, err);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(G_OBEX_ERROR, rspcode,
					"Transfer failed (0x%02x)", rspcode);
		goto failed;
	}

	if (transfer->opcode == G_OBEX_OP_GET) {
		handle_get_body(transfer, rsp, &err);
		if (err != NULL)
			goto failed;
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		transfer_complete(transfer, NULL);
		return;
	}

	if (transfer->opcode == G_OBEX_OP_PUT) {
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
	} else {
		req = g_obex_packet_new(transfer->opcode, TRUE,
							G_OBEX_HDR_INVALID);
	}

	transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
							transfer, &err);
failed:
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}
}
예제 #3
0
static gssize put_get_data(void *buf, gsize len, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	GError *err = NULL;
	gssize ret;

	ret = transfer->data_producer(buf, len, transfer->user_data);
	if (ret >= 0)
		return ret;

	if (ret == -EAGAIN)
		return ret;

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);
	transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_abort_response,
						transfer, &err);
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}

	return ret;
}
예제 #4
0
static void transfer_abort_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;

	transfer->req_id = 0;

	/* Intentionally override error */
	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
						"Operation was aborted");
	transfer_complete(transfer, err);
	g_error_free(err);
}
예제 #5
0
static void transfer_abort_req(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *rsp;
	GError *err;

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
						"Request was aborted");
	rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, G_OBEX_HDR_INVALID);
	g_obex_send(obex, rsp, NULL);

	transfer_complete(transfer, err);
	g_error_free(err);
}
예제 #6
0
static void transfer_abort_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;

	g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);

	transfer->req_id = 0;

	/* Intentionally override error */
	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
						"Operation was aborted");
	g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
	transfer_complete(transfer, err);
	g_error_free(err);
}
예제 #7
0
static gssize put_get_data(void *buf, gsize len, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	GError *err = NULL;
	gssize ret;

	ret = transfer->data_producer(buf, len, transfer->user_data);
	if (ret == 0 || ret == -EAGAIN)
		return ret;

	if (ret > 0) {
		/* Check if SRM is active */
		if (!g_obex_srm_active(transfer->obex))
			return ret;

		/* Generate next packet */
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
		transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_response, transfer,
						&err);
		goto done;
	}

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);

	transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_abort_response,
						transfer, &err);
done:
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}

	return ret;
}
예제 #8
0
/* USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2,
USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5,
USB_TRCPT1_6, USB_TRCPT1_7 */
void USB_3_Handler(void) {
    transfer_complete(TUSB_DIR_IN);
}
예제 #9
0
/* USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2,
USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5,
USB_TRCPT0_6, USB_TRCPT0_7 */
void USB_2_Handler(void) {
    transfer_complete(TUSB_DIR_OUT);
}
예제 #10
0
void MegaFuseApp::transfer_update(int td, m_off_t bytes, m_off_t size, dstime starttime)
{
	std::string remotename = "";
	if(model->cacheManager.findByTransfer(td,file_cache_row::UPLOADING ) != model->cacheManager.end()) {
		printf("\033[2KUPLOAD TD %d: Update: %lld KB of %lld KB, %0.2f KB/s\r", td, bytes/1024, size/1024, float(1.0*bytes*10/(1024*(client->httpio->ds-starttime)+1)));
		fflush(stdout);
		return;
	}
	
	auto it = model->cacheManager.findByTransfer(td,file_cache_row::DOWNLOADING );
	if(it == model->cacheManager.end())
	{
		//no file found
		client->tclose(td);
		return;
	}

	int startChunk = CacheManager::numChunks(it->second.startOffset);
	it->second.available_bytes = ChunkedHash::chunkfloor(ChunkedHash::chunkfloor(it->second.startOffset) + bytes);
	int endChunk = CacheManager::numChunks(ChunkedHash::chunkfloor(it->second.available_bytes));
	if(it->second.startOffset + bytes >= size)
	{
		it->second.available_bytes = size;
		endChunk = it->second.availableChunks.size();
	}

	for(int i = startChunk; i < endChunk; i++) {
		try {
			if(!it->second.availableChunks[i]) {
				it->second.availableChunks[i] = true;
			}
		} catch(...) {
			printf("\033[2KError while reading block %d\n", i);
			fflush(stdout);
			abort();
		}
	}
	{
		std::string r;
		size_t n = it->second.availableChunks.size();
		for(size_t i=0; i<n; ++i)
			r.append(it->second.availableChunks[i]?"#":"-");
		std::string t;
		unsigned char c;
		while(r.length() > 60)
		{
			t = "";
			n = r.length();
			for(size_t i=0; i<n; i += 3)
			{
				c = 0;
				for(unsigned short z=0; z<3; ++z)
					if(i+z >= n || r.at(i+z) == '#')
						c++;
				t.append(c>1?"#":"-");
			}
			r = t;
		}

		//static time_t last_update = time(NULL);
		//if(last_update < time(NULL))
		//{
			printf("\033[2K[%s] %0.2f/%0.2f MB, %lld KB/s\r", r.c_str(), float(1.0*(it->second.startOffset+bytes)/1024/1024), float(1.0*size/1024/1024), 10*bytes/(1024*(client->httpio->ds-starttime)+1));
			fflush(stdout);
		//	last_update = time(NULL);
		//}
	}

	model->eh.notifyEvent(EventsHandler::TRANSFER_UPDATE,0);
	if(it->second.n_clients <= 0)
	{
		client->tclose(it->second.td);
		it->second.status =file_cache_row::DOWNLOAD_PAUSED;
		it->second.td = -1;
		printf("\033[2KDownload paused\n");
	}

	//WORKAROUNDS
	if(it->second.startOffset && it->second.available_bytes>= it->second.size)
	{ // Workaround #1 - have to call manually if the download didn't start at 0
		transfer_complete(td, NULL, NULL);
	} else if(endChunk > startChunk && endChunk < it->second.availableChunks.size() && it->second.availableChunks[endChunk]) {
		printf("\033[2KEncountered already available data at block %d. Stopping...\n", endChunk);
		transfer_complete(td, NULL, NULL);
	}
}
예제 #11
0
void MegaFuseApp::transfer_update(int td, m_off_t bytes, m_off_t size, dstime starttime)
{
	std::string remotename = "";
	if(model->cacheManager.findByTransfer(td,file_cache_row::UPLOADING ) != model->cacheManager.end()) {
		cout << '\r'<<"UPLOAD TD " << td << ": Update: " << bytes/1024 << " KB of " << size/1024 << " KB, " << bytes*10/(1024*(client->httpio->ds-starttime)+1) << " KB/s" ;
		fflush(stdout);
		return;
	}
	
	auto it = model->cacheManager.findByTransfer(td,file_cache_row::DOWNLOADING );
	if(it == model->cacheManager.end())
	{
		//no file found
		client->tclose(td);
		return;
	}
	
	

	int startChunk = CacheManager::numChunks(it->second.startOffset);

	it->second.available_bytes = ChunkedHash::chunkfloor(ChunkedHash::chunkfloor(it->second.startOffset) + bytes);

	int endChunk = CacheManager::numChunks(ChunkedHash::chunkfloor(it->second.available_bytes));
	if(it->second.startOffset + bytes >= size)
	{
		it->second.available_bytes = size;
		endChunk = it->second.availableChunks.size();
	}

	for(int i = startChunk; i < endChunk; i++) {
		try {
			if(!it->second.availableChunks[i]) {
				it->second.availableChunks[i] = true;
				
				printf("block %d/%d available\n",i,(int)it->second.availableChunks.size());

			}

		} catch(...) {
			printf("errore, ho provato a leggere il blocco %d\n",i);
			fflush(stdout);
			abort();
		}
	}


	/*	cout << remotename << td << ": Update: " << bytes/1024 << " KB of " << size/1024 << " KB, " << bytes*10/(1024*(client->httpio->ds-starttime)+1) << " KB/s" << endl;
		cout << "scaricato fino al byte " <<(it->second.startOffset+bytes) << " di: "<<size<<endl;
    */
	{
		std::string rigaDownload = "\r[";
		
		int numero = it->second.availableChunks.size();
		for(int i = 0;i<50;i++)
		{
			if(it->second.availableChunks[i*numero/50])
				rigaDownload.append("#");
			else
				rigaDownload.append("-");
		}
		rigaDownload.append("] ");
		
		
		
		//std::cout << "readable bytes: " <<  ChunkedHash::chunkfloor(ChunkedHash::chunkfloor(it->second.startOffset) + bytes) <<std::endl;
		static time_t last_update= time(NULL);
		if(last_update < time(NULL))
		{
		std::cout << rigaDownload << size/1024/1024 << " MB, " << bytes*10/(1024*(client->httpio->ds-starttime)+1) << " KB/s, available_b/size " <<it->second.available_bytes<<"/"<<it->second.size<< " "<<(it->second.startOffset+bytes)<< "/" <<size<<"            ";
		last_update = time(NULL);
		}
	}
	
	

	model->eh.notifyEvent(EventsHandler::TRANSFER_UPDATE,0);

	if( it->second.n_clients<=0) {
		client->tclose(it->second.td);
		it->second.status =file_cache_row::DOWNLOAD_PAUSED;
		it->second.td = -1;
		printf("pausing download\n");
	}

	//WORKAROUNDS

	if(it->second.startOffset && it->second.available_bytes>= it->second.size) {
		printf("workaround 1\n"); //have to call manually if the download didn't start at 0
		transfer_complete(td,NULL,NULL);
	} else if(endChunk > startChunk && endChunk < it->second.availableChunks.size() && it->second.availableChunks[endChunk]) {
		printf("----Downloading already available data at block %d. stopping...\n",endChunk);
		transfer_complete(td,NULL,NULL);
	}
}