Example #1
0
TIEXPORT3 int TICALL dusb_send_data(CalcHandle *handle, DUSBVirtualPacket *vtl)
{
	DUSBRawPacket raw;
	int i, r, q;
	long offset;
	int ret;

	VALIDATE_HANDLE(handle);
	VALIDATE_NONNULL(vtl);
	if (vtl->size && !vtl->data)
	{
		return ERR_INVALID_PARAMETER;
	}

	memset(&raw, 0, sizeof(raw));

	do
	{
		if (vtl->size <= handle->priv.dusb_rpkt_maxlen - DUSB_DH_SIZE)
		{
			// we have a single packet which is the last one, too
			raw.size = vtl->size + DUSB_DH_SIZE;
			raw.type = DUSB_RPKT_VIRT_DATA_LAST;

			raw.data[0] = MSB(MSW(vtl->size));
			raw.data[1] = LSB(MSW(vtl->size));
			raw.data[2] = MSB(LSW(vtl->size));
			raw.data[3] = LSB(LSW(vtl->size));
			raw.data[4] = MSB(vtl->type);
			raw.data[5] = LSB(vtl->type);
			if (vtl->data)
			{
				memcpy(&raw.data[DUSB_DH_SIZE], vtl->data, vtl->size);
			}

			ret = dusb_send(handle, &raw);
			if (ret)
			{
				break;
			}
#if (VPKT_DBG == 2)
			ticalcs_info("  PC->TI: Virtual Packet Data Final\n\t\t(size = %08x, type = %s)", vtl->size, dusb_vpkt_type2name(vtl->type));
#elif (VPKT_DBG == 1)
			ticalcs_info("  PC->TI: %s", dusb_vpkt_type2name(vtl->type));
#endif
			workaround_send(handle, &raw, vtl);
			ret = dusb_recv_acknowledge(handle);
			if (ret)
			{
				break;
			}
		}
		else
		{
			// we have more than one packet: first packet has data header
			raw.size = handle->priv.dusb_rpkt_maxlen;
			raw.type = DUSB_RPKT_VIRT_DATA;

			raw.data[0] = MSB(MSW(vtl->size));
			raw.data[1] = LSB(MSW(vtl->size));
			raw.data[2] = MSB(LSW(vtl->size));
			raw.data[3] = LSB(LSW(vtl->size));
			raw.data[4] = MSB(vtl->type);
			raw.data[5] = LSB(vtl->type);
			memcpy(&raw.data[DUSB_DH_SIZE], vtl->data, handle->priv.dusb_rpkt_maxlen - DUSB_DH_SIZE);
			offset = handle->priv.dusb_rpkt_maxlen - DUSB_DH_SIZE;

			ret = dusb_send(handle, &raw);
			if (ret)
			{
				break;
			}
#if (VPKT_DBG == 2)
			ticalcs_info("  PC->TI: Virtual Packet Data with Continuation\n\t\t(size = %08x, type = %s)", vtl->size, dusb_vpkt_type2name(vtl->type));
#elif (VPKT_DBG == 1)
			ticalcs_info("  PC->TI: %s", dusb_vpkt_type2name(vtl->type));
#endif
			ret = dusb_recv_acknowledge(handle);
			if (ret)
			{
				break;
			}

			// other packets doesn't have data header but last one has a different type
			q = (vtl->size - offset) / handle->priv.dusb_rpkt_maxlen;
			r = (vtl->size - offset) % handle->priv.dusb_rpkt_maxlen;

			// send full chunks (no header)
			for (i = 1; i <= q; i++)
			{
				raw.size = handle->priv.dusb_rpkt_maxlen;
				raw.type = DUSB_RPKT_VIRT_DATA;
				memcpy(raw.data, vtl->data + offset, handle->priv.dusb_rpkt_maxlen);
				offset += handle->priv.dusb_rpkt_maxlen;

				ret = dusb_send(handle, &raw);
				if (ret)
				{
					goto end;
				}
#if (VPKT_DBG == 2)
				ticalcs_info("  PC->TI: Virtual Packet Data with Continuation");
#endif
				ret = dusb_recv_acknowledge(handle);
				if (ret)
				{
					goto end;
				}

				handle->updat->max1 = vtl->size;
				handle->updat->cnt1 += handle->priv.dusb_rpkt_maxlen;
				handle->updat->pbar();
			}

			// send last chunk (type)
			raw.size = r;
			raw.type = DUSB_RPKT_VIRT_DATA_LAST;
			memcpy(raw.data, vtl->data + offset, r);
			offset += r;

			ret = dusb_send(handle, &raw);
			if (ret)
			{
				break;
			}

#if (VPKT_DBG == 2)
			ticalcs_info("  PC->TI: Virtual Packet Data Final");
#endif
			// XXX is that workaround necessary on 83PCE/84+CE/84+CE-T ?
			if (handle->model != CALC_TI84P_USB && handle->model != CALC_TI84PC_USB && handle->model != CALC_TI82A_USB && handle->model != CALC_TI84PT_USB)
			{
				workaround_send(handle, &raw, vtl);
			}
			ret = dusb_recv_acknowledge(handle);
			if (ret)
			{
				break;
			}
		}
	} while(0);
end:

	return ret;
}
Example #2
0
TIEXPORT3 int TICALL dusb_send_data(CalcHandle *h, DUSBVirtualPacket *vtl)
{
	DUSBRawPacket raw;
	int i, r, q;
	long offset;

	if (h == NULL)
	{
		ticalcs_critical("%s: h is NULL", __FUNCTION__);
		return ERR_INVALID_HANDLE;
	}
	if (vtl == NULL)
	{
		ticalcs_critical("%s: vtl is NULL", __FUNCTION__);
		return ERR_INVALID_PACKET;
	}

	memset(&raw, 0, sizeof(raw));

	if(vtl->size <= DATA_SIZE - DUSB_DH_SIZE)
	{
		// we have a single packet which is the last one, too
		raw.size = vtl->size + DUSB_DH_SIZE;
		raw.type = DUSB_RPKT_VIRT_DATA_LAST;

		raw.data[0] = MSB(MSW(vtl->size));
		raw.data[1] = LSB(MSW(vtl->size));
		raw.data[2] = MSB(LSW(vtl->size));
		raw.data[3] = LSB(LSW(vtl->size));
		raw.data[4] = MSB(vtl->type);
		raw.data[5] = LSB(vtl->type);
		memcpy(&raw.data[DUSB_DH_SIZE], vtl->data, vtl->size);

		TRYF(dusb_send(h, &raw));
#if (VPKT_DBG == 2)
		ticalcs_info("  PC->TI: Virtual Packet Data Final\n\t\t(size = %08x, type = %s)", 
			vtl->size, dusb_vpkt_type2name(vtl->type));
#elif (VPKT_DBG == 1)
		ticalcs_info("  PC->TI: %s", dusb_vpkt_type2name(vtl->type));
#endif
		workaround_send(h, &raw, vtl);
		TRYF(dusb_recv_acknowledge(h));
	}
	else
	{
		// we have more than one packet: first packet has data header
		raw.size = DATA_SIZE;
		raw.type = DUSB_RPKT_VIRT_DATA;

		raw.data[0] = MSB(MSW(vtl->size));
		raw.data[1] = LSB(MSW(vtl->size));
		raw.data[2] = MSB(LSW(vtl->size));
		raw.data[3] = LSB(LSW(vtl->size));
		raw.data[4] = MSB(vtl->type);
		raw.data[5] = LSB(vtl->type);
		memcpy(&raw.data[DUSB_DH_SIZE], vtl->data, DATA_SIZE - DUSB_DH_SIZE);
		offset = DATA_SIZE - DUSB_DH_SIZE;

		TRYF(dusb_send(h, &raw));
#if (VPKT_DBG == 2)
		ticalcs_info("  PC->TI: Virtual Packet Data with Continuation\n\t\t(size = %08x, type = %s)", 
			vtl->size, dusb_vpkt_type2name(vtl->type));
#elif (VPKT_DBG == 1)
		ticalcs_info("  PC->TI: %s", dusb_vpkt_type2name(vtl->type));
#endif
		//workaround_send(h, &raw, vtl);
		TRYF(dusb_recv_acknowledge(h));

		// other packets doesn't have data header but last one has a different type
		q = (vtl->size - offset) / DATA_SIZE;
		r = (vtl->size - offset) % DATA_SIZE;

		// send full chunks (no header)
		for(i = 1; i <= q; i++)
		{
			raw.size = DATA_SIZE;
			raw.type = DUSB_RPKT_VIRT_DATA;
			memcpy(raw.data, vtl->data + offset, DATA_SIZE);
			offset += DATA_SIZE;

			TRYF(dusb_send(h, &raw));
#if (VPKT_DBG == 2)
			ticalcs_info("  PC->TI: Virtual Packet Data with Continuation");
#endif
			TRYF(dusb_recv_acknowledge(h));

			h->updat->max1 = vtl->size;
			h->updat->cnt1 += DATA_SIZE;
			h->updat->pbar();
		}

		// send last chunk (type)
		//if(r)
		{
			raw.size = r;
			raw.type = DUSB_RPKT_VIRT_DATA_LAST;
			memcpy(raw.data, vtl->data + offset, r);
			offset += r;

			TRYF(dusb_send(h, &raw));

#if (VPKT_DBG == 2)
			ticalcs_info("  PC->TI: Virtual Packet Data Final");
#endif
			if (h->model != CALC_TI84P_USB)
			{
				workaround_send(h, &raw, vtl);
			}
			TRYF(dusb_recv_acknowledge(h));
		}
	}

	return 0;
}