Exemple #1
0
TIEXPORT3 int TICALL dusb_recv(CalcHandle* handle, DUSBRawPacket* pkt)
{
	uint8_t buf[5];
	int ret;

	VALIDATE_HANDLE(handle);
	VALIDATE_NONNULL(pkt);

	// Any packet has always an header of 5 bytes (size & type)
	ticables_progress_reset(handle->cable);
	ret = ticables_cable_recv(handle->cable, buf, 5);
	while (!ret)
	{

		pkt->size = buf[3] | (((uint32_t)buf[2]) << 8) | (((uint32_t)buf[1]) << 16) | (((uint32_t)buf[0]) << 24);
		pkt->type = buf[4];

		if (   (handle->model == CALC_TI84P_USB || handle->model == CALC_TI84PC_USB || handle->model == CALC_TI82A_USB || handle->model == CALC_TI84PT_USB)
		    && pkt->size > 250)
		{
			ticalcs_warning("Raw packet is unexpectedly large: %u bytes", pkt->size);
		}
		else if (   (handle->model == CALC_TI83PCE_USB || handle->model == CALC_TI84PCE_USB)
		         && pkt->size > 1018)
		{
			ticalcs_warning("Raw packet is unexpectedly large: %u bytes", pkt->size);
		}
		else if (handle->model == CALC_TI89T_USB)
		{
			// Fall through.
		}
		// else do nothing for now.

		if (pkt->size > sizeof(pkt->data))
		{
			ticalcs_critical("Raw packet is too large: %u bytes", pkt->size);
			ret = ERR_INVALID_PACKET;
			break;
		}

		//printf("dusb_send: pkt->size=%d\n", pkt->size);
		// Next, follows data
		ret = ticables_cable_recv(handle->cable, pkt->data, pkt->size);
		if (!ret)
		{
			if (pkt->size >= 128)
			{
				ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
			}

			if (handle->updat->cancel)
			{
				ret = ERR_ABORT;
			}
		}
		break;
	}

	return ret;
}
Exemple #2
0
// Work around TI's OS behaviour: extra bulk read of 0 size required after the last raw packet in a transfer,
// when some conditions are met.
static void workaround_recv(CalcHandle *handle, DUSBRawPacket * raw, DUSBVirtualPacket * vtl)
{
	uint8_t buf[64];

	ticalcs_info("workaround_recv: vtl->size=%d\traw->size=%d", vtl->size, raw->size);

	if (handle->model == CALC_TI89T_USB)
	{
		if ((raw->size % 64) == 0)
		{
			ticalcs_info("XXX triggering an extra bulk read\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_recv(handle->cable, buf, 0);
		}
	}
	else if (handle->model == CALC_TI84P_USB || handle->model == CALC_TI84PC_USB || handle->model == CALC_TI82A_USB || handle->model == CALC_TI84PT_USB)
	{
		if (((raw->size + 5) % 64) == 0)
		{
			ticalcs_info("XXX triggering an extra bulk read\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_recv(handle->cable, buf, 0);
		}
	}
	else if (handle->model == CALC_TI83PCE_USB || handle->model == CALC_TI84PCE_USB)
	{
		// These models don't seem to need receive workarounds.
	}
	else
	{
		ticalcs_warning("XXX unhandled model in workaround_recv");
	}
}
Exemple #3
0
TIEXPORT3 int TICALL dusb_send_buf_size_alloc(CalcHandle* handle, uint32_t size)
{
	DUSBRawPacket raw;
	int ret;

	VALIDATE_HANDLE(handle);

	if (size > sizeof(raw.data) + 1)
	{
		ticalcs_warning("Clamping dubious large DUSB buffer size request");
		size = sizeof(raw.data) + 1;
	}

	memset(&raw, 0, sizeof(raw));
	raw.size = 4;
	raw.type = DUSB_RPKT_BUF_SIZE_ALLOC;
	raw.data[0] = (size >> 24) & 0xFF;
	raw.data[1] = (size >> 16) & 0xFF;
	raw.data[2] = (size >>  8) & 0xFF;
	raw.data[3] = (size      ) & 0xFF;

	ret = dusb_send(handle, &raw);
	if (!ret)
	{
		ticalcs_info("  PC->TI: Buffer Size Allocation (%i bytes)", size);
	}

	handle->priv.dusb_rpkt_maxlen = size;

	return ret;
}
Exemple #4
0
static int err_code(uint8_t code)
{
	int i;

	for(i = 0; i < (int)(sizeof(usb_errors) / sizeof(usb_errors[0])); i++)
		if(usb_errors[i] == code)
			return i+1;

	ticalcs_warning("Nspire error code 0x%02x not found in list. Please report it at <*****@*****.**>.", (int)code);

	return 0;
}
Exemple #5
0
static int err_code(uint8_t *data)
{
    int i;
    int code = data[2];

    ticalcs_info(" TI->PC: SKP (%02x)", data[0]);
    for(i = 0; i < (int)(sizeof(dbus_errors) / sizeof(dbus_errors[0])); i++)
        if(dbus_errors[i] == code)
            return i+1;

    ticalcs_warning("D-BUS error code not found in list. Please report it at <*****@*****.**>.");

    return 0;
}
Exemple #6
0
static int err_code(uint16_t code)
{
	unsigned int i;

	for (i = 0; i < sizeof(usb_errors) / sizeof(usb_errors[0]); i++)
	{
		if (usb_errors[i] == code)
		{
			return i + 1;
		}
	}

	ticalcs_warning("USB error code 0x%02x not found in list. Please report it at <*****@*****.**>.", code);

	return 0;
}
Exemple #7
0
TIEXPORT3 int TICALL dusb_recv_data(CalcHandle* handle, DUSBVirtualPacket* vtl)
{
	uint32_t declared_size;
	int ret;

	VALIDATE_HANDLE(handle);
	VALIDATE_NONNULL(vtl);

	ret = dusb_recv_data_varsize(handle, vtl, &declared_size, 0);
	if (!ret)
	{
		if (declared_size != vtl->size)
		{
			ticalcs_warning("invalid packet (declared size = %d, actual size = %d)", declared_size, vtl->size);
			ret = ERR_INVALID_PACKET;
		}
	}

	return ret;
}
Exemple #8
0
// Work around TI's OS behaviour: extra bulk write of 0 size required after the last raw packet in a transfer,
// when some conditions are met.
static void workaround_send(CalcHandle *handle, DUSBRawPacket *raw, DUSBVirtualPacket *vtl)
{
	uint8_t buf[64];

	ticalcs_info("workaround_send: vtl->size=%d\traw->size=%d", vtl->size, raw->size);

	if (handle->model == CALC_TI89T_USB)
	{
		// A 1076-byte (string) variable doesn't require this workaround, but bigger (string) variables do.
		if (vtl->size > 1076 && ((raw->size + 5) % 64) == 0)
		{
			ticalcs_info("XXX triggering an extra bulk write\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_send(handle->cable, buf, 0);
		}
	}
	else if (handle->model == CALC_TI84P_USB || handle->model == CALC_TI84PC_USB || handle->model == CALC_TI82A_USB || handle->model == CALC_TI84PT_USB)
	{
		// A 244-byte (program) variable doesn't require this workaround, but bigger (program) variables do.
		if (raw->type == DUSB_RPKT_VIRT_DATA_LAST && vtl->size > 244 && (vtl->size % 250) == 244)
		{
			ticalcs_info("XXX triggering an extra bulk write\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_send(handle->cable, buf, 0);
		}
	}
	else if (handle->model == CALC_TI83PCE_USB || handle->model == CALC_TI84PCE_USB)
	{
		if (raw->type == DUSB_RPKT_VIRT_DATA_LAST && ((raw->size + 5) % 64) == 0)
		{
			ticalcs_info("XXX triggering an extra bulk write\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_send(handle->cable, buf, 0);
		}
	}
	else
	{
		ticalcs_warning("XXX unhandled model in workaround_send");
	}
}
Exemple #9
0
// 0x0010: modify/rename/delete variable
TIEXPORT3 int TICALL dusb_cmd_s_var_modify(CalcHandle *handle,
                     const char *src_folder, const char *src_name,
                     unsigned int n_src_attrs, const DUSBCalcAttr **src_attrs,
                     const char *dst_folder, const char *dst_name,
                     unsigned int n_dst_attrs, const DUSBCalcAttr **dst_attrs)
{
	DUSBVirtualPacket* pkt;
	unsigned int i;
	unsigned int j = 0;
	unsigned int pks;
	int retval = 0;

	VALIDATE_HANDLE(handle);
	VALIDATE_NONNULL(src_folder);
	VALIDATE_NONNULL(src_name);
	VALIDATE_NONNULL(src_attrs);
	VALIDATE_NONNULL(dst_folder);
	VALIDATE_NONNULL(dst_name);
	VALIDATE_ATTRS(n_dst_attrs, dst_attrs);

	pks = 2 + strlen(src_name)+1 + 2;
	if (strlen(src_folder))
	{
		pks += strlen(src_folder)+1;
	}
	for (i = 0; i < n_src_attrs; i++)
	{
		pks += 4 + src_attrs[i]->size;
	}

	pks += 5;

	if (strlen(dst_folder))
	{
		pks += strlen(dst_folder)+1;
	}
	if (strlen(dst_name))
	{
		pks += strlen(dst_name)+1;
	}
	for (i = 0; i < n_dst_attrs; i++)
	{
		pks += 4 + dst_attrs[i]->size;
	}

	pkt = dusb_vtl_pkt_new_ex(handle, pks, DUSB_VPKT_MODIF_VAR, dusb_vtl_pkt_alloc_data(pks));

	if (strlen(src_folder))
	{
		pkt->data[j++] = strlen(src_folder);
		memcpy(pkt->data + j, src_folder, strlen(src_folder)+1);
		j += strlen(src_folder)+1;
	}
	else
	{
		pkt->data[j++] = 0;
	}

	pkt->data[j++] = strlen(src_name);
	memcpy(pkt->data + j, src_name, strlen(src_name)+1);
	j += strlen(src_name)+1;

	pkt->data[j++] = MSB(n_src_attrs);
	pkt->data[j++] = LSB(n_src_attrs);
	for (i = 0; i < n_src_attrs; i++)
	{
		pkt->data[j++] = MSB(src_attrs[i]->id);
		pkt->data[j++] = LSB(src_attrs[i]->id);
		pkt->data[j++] = MSB(src_attrs[i]->size);
		pkt->data[j++] = LSB(src_attrs[i]->size);
		memcpy(pkt->data + j, src_attrs[i]->data, src_attrs[i]->size);
		j += src_attrs[i]->size;
	}

	pkt->data[j++] = 0x01; /* ??? */

	if (strlen(dst_folder))
	{
		pkt->data[j++] = strlen(dst_folder);
		memcpy(pkt->data + j, dst_folder, strlen(dst_folder)+1);
		j += strlen(dst_folder)+1;
	}
	else
	{
		pkt->data[j++] = 0;
	}

	if (strlen(dst_name))
	{
		pkt->data[j++] = strlen(dst_name);
		memcpy(pkt->data + j, dst_name, strlen(dst_name)+1);
		j += strlen(dst_name)+1;
	}
	else
	{
		pkt->data[j++] = 0;
	}

	pkt->data[j++] = MSB(n_dst_attrs);
	pkt->data[j++] = LSB(n_dst_attrs);
	for (i = 0; i < n_dst_attrs; i++)
	{
		pkt->data[j++] = MSB(dst_attrs[i]->id);
		pkt->data[j++] = LSB(dst_attrs[i]->id);
		pkt->data[j++] = MSB(dst_attrs[i]->size);
		pkt->data[j++] = LSB(dst_attrs[i]->size);
		memcpy(pkt->data + j, dst_attrs[i]->data, dst_attrs[i]->size);
		j += dst_attrs[i]->size;
	}

	if (j == pks)
	{
		retval = dusb_send_data(handle, pkt);
	}
	else
	{
		// Really shouldn't occur.
		ticalcs_warning("Discrepancy in packet generation, not sending it");
		retval = ERR_INVALID_PACKET;
	}

	ticalcs_info("   src_folder=%s, name=%s, nattrs=%i", src_folder, src_name, n_src_attrs);
	ticalcs_info("   dst_folder=%s, name=%s, nattrs=%i", dst_folder, dst_name, n_dst_attrs);

	dusb_vtl_pkt_del(handle, pkt);
	return retval;
}