Ejemplo n.º 1
0
static int		recv_cert	(CalcHandle* handle, FlashContent* content)
{
	int ret;
	int i;
	uint8_t buf[256];

	ticalcs_strlcpy(handle->updat->text, _("Receiving certificate"), sizeof(handle->updat->text));
	ticalcs_update_label(handle);

	content->model = handle->model;
	content->name[0] = 0;
	content->data_type = TI83p_CERT;
	content->device_type = 0x73;
	content->num_pages = 0;
	content->data_part = (uint8_t *)tifiles_ve_alloc_data(2 * 1024 * 1024);	// 2MB max

	ret = SEND_REQ2(handle, 0x00, TI83p_GETCERT, "\0\0\0\0\0\0\0", 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, NULL);
		if (!ret)
		{
			ret = ticables_cable_recv(handle->cable, buf, 4);	//VAR w/ no header
			if (!ret)
			{
				ticalcs_info(" TI->PC: VAR");
				ret = SEND_ACK(handle);

				for (i = 0, content->data_length = 0; !ret; i++)
				{
					uint16_t block_size;

					ret = SEND_CTS(handle);
					if (!ret)
					{
						ret = RECV_ACK(handle, NULL);
						if (!ret)
						{
							ret = RECV_XDP(handle, &block_size, content->data_part);
							if (!ret)
							{
								ret = SEND_ACK(handle);
								if (!ret)
								{
									content->data_length += block_size;

									handle->updat->cnt2 += block_size;
									ticalcs_update_pbar(handle);
								}
							}
						}
					}
				}
			}
		}
	}

	return ret;
}
Ejemplo n.º 2
0
static int		recv_idlist	(CalcHandle* handle, uint8_t* id)
{
	int ret;
	uint16_t unused;
	uint16_t varsize;
	uint8_t vartype;
	char varname[9];
	uint8_t varattr;
	uint8_t version;
	uint8_t data[16];
	int i;

	ticalcs_strlcpy(handle->updat->text, "ID-LIST", sizeof(handle->updat->text));
	ticalcs_update_label(handle);

	ret = SEND_REQ(handle, 0x0000, TI73_IDLIST, "\0\0\0\0\0\0\0", 0x00, 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, &unused);
		if (!ret)
		{
			ret = RECV_VAR(handle, &varsize, &vartype, varname, &varattr, &version);
			if (!ret)
			{
				ret = SEND_ACK(handle);
				if (!ret)
				{
					ret = SEND_CTS(handle);
					if (!ret)
					{
						ret = RECV_ACK(handle, NULL);
						if (!ret)
						{
							ret = RECV_XDP(handle, &varsize, data);
							if (!ret)
							{
								ret = SEND_ACK(handle);
								if (!ret)
								{
									i = data[9];
									data[9] = data[10];
									data[10] = i;

									for (i = 4; i < varsize; i++)
									{
										sprintf((char *)&id[2 * (i-4)], "%02x", data[i]);
									}
									id[7*2] = '\0';
								}
							}
						}
					}
				}
			}
		}
	}

	return ret;
}
Ejemplo n.º 3
0
// Helper function for get_dirlist, it does the bulk of the work.
static int enumerate_folder(CalcHandle* handle, GNode** vars, const char * folder_name)
{
	int ret;

	ticalcs_info("enumerate_folder<%s>\n", folder_name);

	do
	{
		char varname[VARNAME_MAX];

		ret = nsp_cmd_s_dir_enum_init(handle, folder_name);
		if (ret)
		{
			break;
		}
		ret = nsp_cmd_r_dir_enum_init(handle);
		if (ret)
		{
			break;
		}

		for (;;)
		{
			VarEntry *fe;
			GNode *node;
			char *ext;
			uint32_t varsize;
			uint8_t vartype;

			ret = nsp_cmd_s_dir_enum_next(handle);
			if (ret)
			{
				break;
			}
			ret = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype);

			if (ret == ERR_EOT)
			{
				ret = 0;
				break;
			}
			else if (ret != 0)
			{
				break;
			}

			fe = tifiles_ve_create();

			ticalcs_strlcpy(fe->folder, folder_name + 1, sizeof(fe->folder)); // Skip leading /
			fe->size = varsize;
			fe->type = vartype;
			fe->attr = ATTRB_NONE;

			ext = tifiles_fext_get(varname);
			// Just a sanity check
			if (ext)
			{
				// Did the file name have any non-empty extension ?
				if (*ext)
				{
					// Do we know about this file type ?
					if (fe->type < NSP_MAXTYPES)
					{
						// Then we can remove the exension.
						*(ext-1) = '\0';
					}
					// else don't remove the extension.
				}
				// else there is no extension to remove.
			}
			ticalcs_strlcpy(fe->name, varname, sizeof(fe->name));

			node = dirlist_create_append_node(fe, vars);
			if (!node)
			{
				ret = ERR_MALLOC;
				break;
			}

			ticalcs_info(_("Name: %s | Type: %8s | Attr: %i  | Size: %08X"),
				fe->name,
				tifiles_vartype2string(handle->model, fe->type),
				fe->attr,
				fe->size);
		}

		while (!ret)
		{
			int i;

			ret = nsp_cmd_s_dir_enum_done(handle);
			if (ret)
			{
				break;
			}
			ret = nsp_cmd_r_dir_enum_done(handle);
			if (ret)
			{
				break;
			}

			// Enumerate elements of root folder.
			for (i = 0; i < (int)g_node_n_children(*vars); i++) 
			{
				char new_folder_name[FLDNAME_MAX];
				const char * separator_if_any;
				GNode * folder = g_node_nth_child(*vars, i);
				uint8_t vartype = ((VarEntry *)(folder->data))->type;

				// Don't recurse into regular files (type 0, TNS or e.g. themes.csv on OS 3.0+).
				if (vartype == 0)
				{
					ticalcs_info(_("Not enumerating documents in %s because it's not a folder\n"), ((VarEntry *)(folder->data))->name);
					continue;
				}

				// Prevent names from starting with "//".
				if (strcmp(folder_name, "/"))
				{
					separator_if_any = "/";
				}
				else
				{
					separator_if_any = "";
				}

				ticalcs_slprintf(new_folder_name, sizeof(new_folder_name), "%s%s%s", folder_name, separator_if_any, ((VarEntry *)(folder->data))->name);

				ticalcs_info(_("Directory listing in <%s>...\n"), new_folder_name);

				ret = enumerate_folder(handle, &folder, new_folder_name);
				if (ret)
				{
					break;
				}
			}
			break;
		}
	} while (0);

	return ret;
}
Ejemplo n.º 4
0
/**
 * ticalcs_dirlist_ve_add:
 * @tree: source tree.
 * @entry: entry to add.
 *
 * Add an entry into the main tree (if it doesn't exist yet).
 *
 * Return value: none.
 **/
TIEXPORT3 void TICALL ticalcs_dirlist_ve_add(GNode* tree, VarEntry *entry)
{
	TreeInfo *info;
	int i, j;
	int found = 0;

	GNode *parent = NULL;
	VarEntry *fe = NULL;

	GNode *child;
	VarEntry *ve;

	const char *folder;

	if (tree == NULL || entry == NULL)
	{
		ticalcs_critical("ticalcs_dirlist_ve_add: an argument is NULL");
		return;
	}

	info = (TreeInfo *)(tree->data);
	if (info == NULL)
	{
		return;
	}

	if (strcmp(info->type, VAR_NODE_NAME) && strcmp(info->type, APP_NODE_NAME))
	{
		return;
	}

	if (!strcmp(entry->folder, "") && tifiles_has_folder(info->model))
	{
		folder = "main";
	}
	else
	{
		folder = entry->folder;
	}

	// If TI8x tree is empty, create pseudo-folder (NULL)
	if (!g_node_n_children(tree) && !tifiles_has_folder(info->model))
	{
		parent = g_node_new(NULL);
		g_node_append(tree, parent);
	}

	// Check for one folder at least...
	if (g_node_n_children(tree) > 0)
	{
		// Parse folders
		for (found = 0, i = 0; i < (int)g_node_n_children(tree); i++)
		{
			parent = g_node_nth_child(tree, i);
			fe = (VarEntry *) (parent->data);

			if (fe == NULL)
			{
				break;
			}

			if (!strcmp(fe->name, folder))
			{
				found = !0;
				break;
			}
		}
	}

	// folder doesn't exist? => create!
	if ((!found && fe) ||
	    (!g_node_n_children(tree) && tifiles_has_folder(info->model)))
	{
		fe = tifiles_ve_create();
		if (fe != NULL)
		{
			ticalcs_strlcpy(fe->name, entry->folder, sizeof(fe->name));
			fe->type = TI89_DIR;

			parent = g_node_new(fe);
			g_node_append(tree, parent);
		}
	}

	if (!strcmp(entry->name, ""))
	{
		return;
	}

	// next, add variables beneath this folder
	for (found = 0, j = 0; j < (int)g_node_n_children(parent); j++)
	{
		child = g_node_nth_child(parent, j);
		ve = (VarEntry *) (child->data);

		if (!strcmp(ve->name, entry->name))
		{
			found = !0;
			break;
		}
	}

	if (!found)
	{
		ve = tifiles_ve_dup(entry);
		if (ve != NULL)
		{
			child = g_node_new(ve);
			g_node_append(parent, child);
		}
	}

	if (fe && found)
	{
		fe->size++;
	}
}
Ejemplo n.º 5
0
static int		send_var_ns	(CalcHandle* handle, CalcMode mode, FileContent* content)
{
	unsigned int i;
	int ret = 0;
	uint8_t rej_code;
	uint16_t status;

	if ((mode & MODE_SEND_EXEC_ASM) && content->num_entries != 1)
	{
		ticalcs_critical("no variable to execute");
		return -1;
	}

	update_->cnt2 = 0;
	update_->max2 = content->num_entries;

	for (i = 0; i < content->num_entries; i++) 
	{
		VarEntry *entry = content->entries[i];
		uint16_t size;

		if (!ticalcs_validate_varentry(entry))
		{
			ticalcs_critical("%s: skipping invalid content entry #%u", __FUNCTION__, i);
			continue;
		}

		if (entry->action == ACT_SKIP)
		{
			ticalcs_info("%s: skipping variable #%u because requested", __FUNCTION__, i);
			continue;
		}

		if (entry->size >= 65536U)
		{
			ticalcs_critical("%s: oversized variable has size %u, clamping to 65535", __FUNCTION__, entry->size);
			size = 65535;
		}
		else
		{
			size = (uint16_t)entry->size;
		}

		ret = SEND_VAR(handle, size, entry->type, entry->name);
		if (!ret)
		{
			ret = RECV_ACK(handle, &status);
		}
		if (ret)
		{
			break;
		}

		ticalcs_strlcpy(update_->text, _("Waiting for user's action..."), sizeof(update_->text));
		update_label();

		do
		{
			// wait for user's action
			update_refresh();
			if (update_->cancel)
			{
				ret = ERR_ABORT;
				break;
			}

			ret = RECV_SKP(handle, &rej_code);
		}
		while (ret == ERROR_READ_TIMEOUT);

		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}

		switch (rej_code)
		{
		case DBUS_REJ_EXIT:
			ret = ERR_ABORT;
			break;
		case DBUS_REJ_SKIP:
			if (mode & MODE_SEND_EXEC_ASM)
			{
				ret = ERR_ABORT;
				break;
			}
			continue;
		case DBUS_REJ_MEMORY:
			ret = ERR_OUT_OF_MEMORY;
			// Fall through.
		case 0:                         // CTS
			break;
		default:
			ret = ERR_VAR_REJECTED;
			break;
		}

		if (ret)
		{
			break;
		}

		ticonv_varname_to_utf8_sn(handle->model, entry->name, update_->text, sizeof(update_->text), entry->type);
		update_label();

		ret = SEND_XDP(handle, size, entry->data);
		if (!ret)
		{
			ret = RECV_ACK(handle, &status);
		}
		if (ret)
		{
			break;
		}

		ticalcs_info("Sent variable #%u", i);

		update_->cnt2 = i+1;
		update_->max2 = content->num_entries;
		update_->pbar();
	}

	if (mode & MODE_SEND_EXEC_ASM)
	{
		ret = ti82_send_asm_exec(handle, content->entries[0]);
		if (!ret)
		{
			ret = RECV_ERR(handle, &status);
			if (!ret)
			{
				ret = SEND_ACK(handle);
			}
		}
	}
	else if ((mode & MODE_SEND_ONE_VAR) || (mode & MODE_SEND_LAST_VAR))
	{
		ret = SEND_EOT(handle);
		if (!ret)
		{
			ret = RECV_ACK(handle, NULL);
		}
	}

	return ret;
}
Ejemplo n.º 6
0
static int		recv_backup	(CalcHandle* handle, BackupContent* content)
{
	int ret;
	char varname[9];

	content->model = handle->model;
	ticalcs_strlcpy(content->comment, tifiles_comment_set_backup(), sizeof(content->comment));

	if (handle->model == CALC_TI83)
	{
		ret = SEND_REQ(handle, 0x0000, TI83_BKUP, "\0\0\0\0\0\0\0");
		if (!ret)
		{
			ret = RECV_ACK(handle, NULL);
		}
		if (ret)
		{
			return ret;
		}
	}
	else
	{
		ticalcs_strlcpy(update_->text, _("Waiting for backup..."), sizeof(update_->text));
		update_label();
	}

	varname[0] = 0;
	do
	{
		ret = RECV_VAR(handle, &(content->data_length1), &content->type, varname);
		if (ret)
		{
			break;
		}
		content->data_length2 = (uint8_t)varname[0] | (((uint16_t)(uint8_t)varname[1]) << 8);
		content->data_length3 = (uint8_t)varname[2] | (((uint16_t)(uint8_t)varname[3]) << 8);
		if (handle->model != CALC_TI86)
		{
			content->mem_address  = (uint8_t)varname[4] | (((uint16_t)(uint8_t)varname[5]) << 8);
		}
		else
		{
			content->data_length4 = (uint8_t)varname[4] | (((uint16_t)(uint8_t)varname[5]) << 8);
		}
		ret = SEND_ACK(handle);
		if (!ret)
		{
			ret = SEND_CTS(handle);
			if (!ret)
			{
				ret = RECV_ACK(handle, NULL);
			}
		}
		if (ret)
		{
			break;
		}

		update_->text[0] = 0;
		update_label();

		update_->cnt2 = 0;
		update_->max2 = (handle->model != CALC_TI86) ? 3 : 4;
		update_->pbar();

		content->data_part1 = tifiles_ve_alloc_data(65536);
		ret = RECV_XDP(handle, &content->data_length1, content->data_part1);
		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}
		update_->cnt2++;
		update_->pbar();

		content->data_part2 = tifiles_ve_alloc_data(65536);
		ret = RECV_XDP(handle, &content->data_length2, content->data_part2);
		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}
		update_->cnt2++;
		update_->pbar();

		if (content->data_length3)
		{
			content->data_part3 = tifiles_ve_alloc_data(65536);
			ret = RECV_XDP(handle, &content->data_length3, content->data_part3);
			if (!ret)
			{
				ret = SEND_ACK(handle);
			}
			if (ret)
			{
				break;
			}
		}
		else
		{
			content->data_part3 = NULL;
		}
		update_->cnt2++;
		update_->pbar();

		if (handle->model != CALC_TI86)
		{
			content->data_part4 = NULL;
		}
		else
		{
			content->data_part4 = tifiles_ve_alloc_data(65536);
			ret = RECV_XDP(handle, &content->data_length4, content->data_part4);
			if (!ret)
			{
				ret = SEND_ACK(handle);
			}
			if (ret)
			{
				break;
			}
			update_->cnt2++;
			update_->pbar();
		}
	} while(0);

	return ret;
}
Ejemplo n.º 7
0
static int		send_backup	(CalcHandle* handle, BackupContent* content)
{
	int ret;
	uint16_t length;
	char varname[9];
	uint8_t rej_code;
	uint16_t status;

	length = content->data_length1;
	varname[0] = LSB(content->data_length2);
	varname[1] = MSB(content->data_length2);
	varname[2] = LSB(content->data_length3);
	varname[3] = MSB(content->data_length3);
	varname[4] = LSB((handle->model != CALC_TI86) ? content->mem_address : content->data_length4);
	varname[5] = MSB((handle->model != CALC_TI86) ? content->mem_address : content->data_length4);
	varname[6] = 0;
	varname[7] = 0;
	varname[8] = 0;

	do
	{
		if (handle->model == CALC_TI83)
		{
			ret = SEND_RTS(handle, content->data_length1, TI83_BKUP, varname);
		}
		else
		{
			ret = SEND_VAR(handle, content->data_length1, (handle->model == CALC_TI82) ? TI82_BKUP : ((handle->model == CALC_TI85) ? TI85_BKUP : TI86_BKUP), varname);
		}
		if (!ret)
		{
			ret = RECV_ACK(handle, &status);
		}
		if (ret)
		{
			break;
		}

		if (handle->model == CALC_TI83)
		{
			ret = RECV_SKP(handle, &rej_code);
		}
		else
		{
			ticalcs_strlcpy(update_->text, _("Waiting for user's action..."), sizeof(update_->text));
			update_label();

			do
			{
				// wait for user's action
				update_refresh();

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

				ret = RECV_SKP(handle, &rej_code);
			}
			while (ret == ERROR_READ_TIMEOUT);
		}

		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}

		switch (rej_code)
		{
		case DBUS_REJ_EXIT:
		case DBUS_REJ_SKIP:
			ret = ERR_ABORT;
			break;
		case DBUS_REJ_MEMORY:
			ret = ERR_OUT_OF_MEMORY;
			// Fall through.
		case 0:                         // CTS
			break;
		default:
			ret = ERR_VAR_REJECTED;
			break;
		}

		if (ret)
		{
			break;
		}

		update_->text[0] = 0;
		update_label();

		update_->cnt2 = 0;
		update_->max2 = (handle->model != CALC_TI86) ? 3 : 4;
		update_->pbar();

		ret = SEND_XDP(handle, content->data_length1, content->data_part1);
		if (!ret)
		{
			ret = RECV_ACK(handle, &status);
		}
		if (ret)
		{
			break;
		}
		update_->cnt2++;
		update_->pbar();

		ret = SEND_XDP(handle, content->data_length2, content->data_part2);
		if (!ret)
		{
			ret = RECV_ACK(handle, &status);
		}
		if (ret)
		{
			break;
		}
		update_->cnt2++;
		update_->pbar();

		if (content->data_length3)
		{
			ret = SEND_XDP(handle, content->data_length3, content->data_part3);
			if (!ret)
			{
				ret = RECV_ACK(handle, &status);
			}
			if (ret)
			{
				break;
			}
		}
		update_->cnt2++;
		update_->pbar();

		if (handle->model == CALC_TI86)
		{
			ret = SEND_XDP(handle, content->data_length4, content->data_part4);
			if (!ret)
			{
				ret = RECV_ACK(handle, &status);
			}
			if (ret)
			{
				break;
			}
			update_->cnt2++;
			update_->pbar();
		}

		if (handle->model == CALC_TI83)
		{
			ret = SEND_ACK(handle);
		}
		else if (handle->model == CALC_TI85)
		{
			ret = SEND_EOT(handle);
		}
	} while(0);

	return ret;
}
Ejemplo n.º 8
0
static int		recv_var_ns	(CalcHandle* handle, CalcMode mode, FileContent* content, VarEntry** vr)
{
	int nvar = 0;
	int ret = 0;
	uint16_t ve_size;

	ticalcs_strlcpy(update_->text, _("Waiting for var(s)..."), sizeof(update_->text));
	update_label();

	content->model = handle->model;
	content->num_entries = 0;

	for (nvar = 0;; nvar++)
	{
		VarEntry *ve = tifiles_ve_create();
		int ret2;

		do
		{
			update_refresh();
			if (update_->cancel)
			{
				ret = ERR_ABORT;
				goto error;
			}

			ret = RECV_VAR(handle, &ve_size, &(ve->type), ve->name);
			ve->size = ve_size;
		}
		while (ret == ERROR_READ_TIMEOUT);

		ret2 = SEND_ACK(handle);

		if (ret)
		{
			if (ret == ERR_EOT)	// end of transmission
			{
				ret = 0;
			}
			goto error;
		}
		if (ret2)
		{
			ret = ret2;
			goto error;
		}

		ret = SEND_CTS(handle);
		if (!ret)
		{
			ret = RECV_ACK(handle, NULL);
			if (!ret)
			{
				ticonv_varname_to_utf8_sn(handle->model, ve->name, update_->text, sizeof(update_->text), ve->type);
				update_label();

				ve->data = tifiles_ve_alloc_data(ve->size);
				ret = RECV_XDP(handle, &ve_size, ve->data);
				if (!ret)
				{
					ve->size = ve_size;
					ret = SEND_ACK(handle);
				}
			}
		}

		if (!ret)
		{
			tifiles_content_add_entry(content, ve);
		}
		else
		{
error:
			tifiles_ve_delete(ve);
			break;
		}
	}

	if (nvar == 1)
	{
		ticalcs_strlcpy(content->comment, tifiles_comment_set_single(), sizeof(content->comment));
		*vr = tifiles_ve_dup(content->entries[0]);
	}
	else
	{
		ticalcs_strlcpy(content->comment, tifiles_comment_set_group(), sizeof(content->comment));
		*vr = NULL;
	}

	return ret;
}
Ejemplo n.º 9
0
static int		set_clock	(CalcHandle* handle, CalcClock* _clock)
{
	int ret;
	uint8_t buffer[9];
	uint32_t calc_time;

	struct tm ref, cur;
	time_t r, c, now;

	time(&now);	// retrieve current DST setting
	memcpy(&ref, localtime(&now), sizeof(struct tm));

	ref.tm_year = 1997 - 1900;
	ref.tm_mon = 0;
	ref.tm_yday = 0;
	ref.tm_mday = 1;
	ref.tm_wday = 3;
	ref.tm_hour = 0;
	ref.tm_min = 0;
	ref.tm_sec = 0;
	//ref.tm_isdst = 1;
	r = mktime(&ref);
	//printf("%s\n", asctime(&ref));

	cur.tm_year = _clock->year - 1900;
	cur.tm_mon = _clock->month - 1;
	cur.tm_mday = _clock->day;
	cur.tm_hour = _clock->hours;
	cur.tm_min = _clock->minutes;
	cur.tm_sec = _clock->seconds;
	cur.tm_isdst = 1;
	c = mktime(&cur);
	//printf("%s\n", asctime(&cur));

	calc_time = (uint32_t)difftime(c, r);

	buffer[0] = 0;
	buffer[1] = 0;
	buffer[2] = MSB(MSW(calc_time));
	buffer[3] = LSB(MSW(calc_time));
	buffer[4] = MSB(LSW(calc_time));
	buffer[5] = LSB(LSW(calc_time));
	buffer[6] = _clock->date_format;
	buffer[7] = _clock->time_format;
	buffer[8] = 0xff;

	ticalcs_strlcpy(handle->updat->text, _("Setting clock..."), sizeof(handle->updat->text));
	ticalcs_update_label(handle);

	ret = SEND_RTS(handle, 13, TI73_CLK, "\0x08\0\0\0\0\0\0\0", 0x00, 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, NULL);
		if (!ret)
		{
			ret = RECV_CTS(handle, 13);
			if (!ret)
			{
				ret = SEND_ACK(handle);
				if (!ret)
				{
					ret = SEND_XDP(handle, 9, buffer);
					if (!ret)
					{
						ret = RECV_ACK(handle, NULL);
						if (!ret)
						{
							ret = SEND_EOT(handle);
						}
					}
				}
			}
		}
	}

	return ret;
}
Ejemplo n.º 10
0
int tixx_recv_all_vars_backup(CalcHandle* handle, FileContent* content)
{
	int i, j, k;
	int i_max;
	GNode *vars, *apps;
	int nvars, ivars = 0;
	int b = 0;
	FileContent **group;
	FileContent *single;
	int ret;

	VALIDATE_HANDLE(handle);
	if (content == NULL)
	{
		ticalcs_critical("tixx_recv_backup: content is NULL");
		return -1;
	}
	VALIDATE_CALCFNCTS(handle->calc);

	// Do a directory list and check for something to backup
	ret = handle->calc->get_dirlist(handle, &vars, &apps);
	if (ret)
	{
		return ret;
	}
	nvars = ticalcs_dirlist_ve_count(vars);
	if (!nvars)
	{
		return ERR_NO_VARS;
	}

	handle->updat->cnt2 = handle->updat->cnt3 = 0;
	handle->updat->max2 = handle->updat->max3 = nvars;
	ticalcs_update_pbar(handle);

	// Check whether the last folder is empty
	b = g_node_n_children(g_node_nth_child(vars, g_node_n_children(vars) - 1));
	PAUSE(100); // needed by TI84+/USB

	// Create a group file
	k = 0;
	group = tifiles_content_create_group(nvars);

	// Receive all vars except for FLASH apps
	i_max = g_node_n_children(vars);
	for (i = 0; i < i_max; i++)
	{
		GNode *parent = g_node_nth_child(vars, i);

		int j_max = g_node_n_children(parent);
		for (j = 0; j < j_max; j++)
		{
			GNode *node = g_node_nth_child(parent, j);
			VarEntry *ve = (VarEntry *) (node->data);

			handle->updat->cnt2 = handle->updat->cnt3 = ++ivars;
			ticalcs_update_pbar(handle);

			// we need to group files !
			ret = handle->calc->is_ready(handle);
			if (ret)
			{
				goto end;
			}
			group[k] = tifiles_content_create_regular(handle->model);
			ret = handle->calc->recv_var(handle, 0, group[k++], ve);
			if (ret)
			{
				goto end;
			}
		}
	}

end:
	ticalcs_dirlist_destroy(&vars);
	ticalcs_dirlist_destroy(&apps);

	if (!ret)
	{
		FileContent * cnt;
		ret = tifiles_group_contents(group, &cnt);
		if (!ret)
		{
			cnt->model = content->model;

			// Steal contents of cnt, then clean up.
			memcpy(content, cnt, sizeof(*content));
			cnt->num_entries = 0;
			cnt->entries = NULL;
			tifiles_content_delete_regular(cnt);

			ticalcs_strlcpy(content->comment, tifiles_comment_set_group(), sizeof(content->comment));
		}
	}

	tifiles_content_delete_group(group);

	return ret;
}
Ejemplo n.º 11
0
/**
 * ticalcs_calc_send_tigroup:
 * @handle: a previously allocated handle
 * @filename: name of file
 * @mode: which vars/apps to send
 *
 * Send a TiGroup file.
 *
 * Return value: 0 if ready else ERR_NOT_READY.
 **/
TIEXPORT3 int TICALL ticalcs_calc_send_tigroup(CalcHandle* handle, TigContent* content, TigMode mode)
{
	TigEntry **ptr;
	GNode *vars, *apps;
	int nvars = 0;
	int napps = 0;
	int ret;

	VALIDATE_HANDLE(handle);
	if (content == NULL)
	{
		ticalcs_critical("ticalcs_calc_send_tigroup: content is NULL");
		return -1;
	}
	VALIDATE_CALCFNCTS(handle->calc);

	ret = handle->calc->get_dirlist(handle, &vars, &apps);
	if (ret)
	{
		return ret;
	}

	if ((mode & TIG_RAM) || (mode & TIG_ARCHIVE))
	{
		nvars = content->n_vars;
	}
	if (mode & TIG_FLASH)
	{
		napps = content->n_apps;
	}

	handle->updat->cnt3 = 0;
	handle->updat->max3 = nvars + napps;
	ticalcs_update_pbar(handle);

	if ((handle->model == CALC_TI89 || handle->model == CALC_TI92P ||
		handle->model == CALC_TI89T || handle->model == CALC_V200) && (mode & TIG_BACKUP))
	{
		// erase memory
		ret = ti89_send_VAR(handle, 0, TI89_BKUP, "main");
		if (!ret)
		{
			ret = ti89_recv_ACK(handle, NULL);
			if (!ret)
			{
				ret = ti89_recv_CTS(handle);
				if (!ret)
				{
					ret = ti89_send_ACK(handle);
					if (!ret)
					{
						ret = ti89_send_EOT(handle);
						if (!ret)
						{
							ret = ti89_recv_ACK(handle, NULL);
						}
					}
				}
			}
		}
	}

	if (!ret)
	{
		// Send vars
		if ((mode & TIG_RAM) || (mode & TIG_ARCHIVE))
		{
			for (ptr = content->var_entries; *ptr; ptr++)
			{
				TigEntry *te = *ptr;

				handle->updat->cnt3++;
				ticalcs_update_pbar(handle);

				if ((te->content.regular->entries[0]->attr == ATTRB_ARCHIVED) && !(mode & TIG_ARCHIVE))
				{
					continue;
				}
				if ((te->content.regular->entries[0]->attr != ATTRB_ARCHIVED) && !(mode & TIG_RAM))
				{
					continue;
				}

				ret = handle->calc->send_var(handle, MODE_BACKUP, te->content.regular);
				if (ret)
				{
					break;
				}
			}
		}

		if (!ret)
		{
			ret = handle->calc->is_ready(handle);
			if (!ret)
			{
				// Send apps
				if (mode & TIG_FLASH)
				{
					for (ptr = content->app_entries; *ptr; ptr++)
					{
						TigEntry *te = *ptr;
						VarEntry ve;

						handle->updat->cnt3++;
						ticalcs_update_pbar(handle);

						// can't overwrite apps so check before sending app
						memset(&ve, 0, sizeof(VarEntry));
						ticalcs_strlcpy(ve.name, te->content.flash->name, sizeof(ve.name));
						if (!ticalcs_dirlist_ve_exist(apps, &ve))
						{
							ret = handle->calc->send_app(handle, te->content.flash);
							if (ret)
							{
								break;
							}
						}
					}
				}
			}
		}
	}

	ticalcs_dirlist_destroy(&vars);
	ticalcs_dirlist_destroy(&apps);

	return ret;
}
Ejemplo n.º 12
0
static int		recv_flash	(CalcHandle* handle, FlashContent* content, VarRequest* vr)
{
	int ret;
	FlashPage *fp;
	uint16_t data_addr;
	uint16_t old_page = 0;
	uint16_t data_page;
	uint16_t data_length;
	uint8_t data_type;
	uint32_t size;
	int first_block;
	int page;
	int offset;
	uint8_t buffer[FLASH_PAGE_SIZE + 4];

	ticonv_varname_to_utf8_sn(handle->model, vr->name, handle->updat->text, sizeof(handle->updat->text), vr->type);
	ticalcs_update_label(handle);

	content->model = handle->model;
	ticalcs_strlcpy(content->name, vr->name, sizeof(content->name));
	content->data_type = vr->type;
	content->device_type = handle->model == CALC_TI73 ? DEVICE_TYPE_73 : DEVICE_TYPE_83P;
	content->num_pages = 2048;	// TI83+ has 512 KB of FLASH max
	content->pages = tifiles_fp_create_array(content->num_pages);

	page = 0;
	fp = content->pages[page] = tifiles_fp_create();

	ret = SEND_REQ2(handle, 0x00, TI73_APPL, vr->name, 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, NULL);
	}
	if (ret)
	{
		return ret;
	}

	handle->updat->cnt2 = 0;
	handle->updat->max2 = vr->size;

	for (size = 0, first_block = 1, offset = 0; !ret;)
	{
		char name[9];
		int ret2;

		ret = RECV_VAR2(handle, &data_length, &data_type, name, &data_addr, &data_page);
		ret2 = SEND_ACK(handle);
		if (ret)
		{
			if (ret == ERR_EOT)
			{
				ret = 0;
			}
			break;
		}
		if (ret2)
		{
			ret = ret2;
			break;
		}

		if (first_block)
		{
			old_page = data_page;

			fp->addr = data_addr & 0x4000;
			fp->page = data_page;
		}
		if (old_page != data_page)
		{
			fp->addr = data_addr & 0x4000;
			fp->page = old_page;
			fp->flag = 0x80;
			fp->size = offset;
			fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
			memcpy(fp->data, buffer, fp->size);

			page++;
			offset = 0;
			old_page = data_page;

			fp = content->pages[page] = tifiles_fp_create();
		}

		ret = SEND_CTS(handle);
		if (!ret)
		{
			ret = RECV_ACK(handle, NULL);
			if (!ret)
			{
				ret = RECV_XDP(handle, &data_length, &buffer[offset]);
				if (!ret)
				{
					ret = SEND_ACK(handle);
				}
			}
		}
		if (ret)
		{
			break;
		}

		if (first_block)
		{
			first_block = 0;

			/* compute actual application size */
			if (buffer[0] == 0x80 && buffer[1] == 0x0f)
			{
				uint32_t len = ((uint32_t)(buffer[2])) << 24 | ((uint32_t)(buffer[3])) << 16 | ((uint32_t)(buffer[4])) << 8 | (uint32_t)(buffer[5]);
				handle->updat->max2 = len + 75;
			}
		}

		size += data_length;
		offset += data_length;

		handle->updat->cnt2 = size;
		ticalcs_update_pbar(handle);
	}

	fp->addr = data_addr & 0x4000;
	fp->page = old_page;
	fp->flag = 0x80;
	fp->size = offset;
	fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
	memcpy(fp->data, buffer, fp->size);
	page++;

	content->num_pages = page;

	return ret;
}
Ejemplo n.º 13
0
static int		recv_backup	(CalcHandle* handle, BackupContent* content)
{
	int ret;
	char varname[9];
	uint8_t attr, ver;

	content->model = handle->model;
	ticalcs_strlcpy(content->comment, tifiles_comment_set_backup(), sizeof(content->comment));

	varname[0] = 0;
	ret = SEND_REQ(handle, 0x0000, TI73_BKUP, "\0\0\0\0\0\0\0", 0x00, 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, NULL);
	}
	if (ret)
	{
		return ret;
	}

	do
	{
		ret = RECV_VAR(handle, &content->data_length1, &content->type, varname, &attr, &ver);
		if (ret)
		{
			break;
		}

		content->data_length2 = (uint8_t)varname[0] | (((uint16_t)(uint8_t)varname[1]) << 8);
		content->data_length3 = (uint8_t)varname[2] | (((uint16_t)(uint8_t)varname[3]) << 8);
		content->mem_address  = (uint8_t)varname[4] | (((uint16_t)(uint8_t)varname[5]) << 8);
		content->version = ver;
		ret = SEND_ACK(handle);
		if (!ret)
		{
			ret = SEND_CTS(handle);
			if (!ret)
			{
				ret = RECV_ACK(handle, NULL);
			}
		}
		if (ret)
		{
			break;
		}

		handle->updat->cnt2 = 0;
		handle->updat->max2 = 3;
		ticalcs_update_pbar(handle);

		content->data_part1 = tifiles_ve_alloc_data(65536);
		ret = RECV_XDP(handle, &content->data_length1, content->data_part1);
		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}
		handle->updat->cnt2++;
		ticalcs_update_pbar(handle);

		content->data_part2 = tifiles_ve_alloc_data(65536);
		ret = RECV_XDP(handle, &content->data_length2, content->data_part2);
		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}
		handle->updat->cnt2++;
		ticalcs_update_pbar(handle);

		content->data_part3 = tifiles_ve_alloc_data(65536);
		ret = RECV_XDP(handle, &content->data_length3, content->data_part3);
		if (!ret)
		{
			ret = SEND_ACK(handle);
		}
		if (ret)
		{
			break;
		}
		handle->updat->cnt2++;
		ticalcs_update_pbar(handle);

		content->data_part4 = NULL;
	} while(0);

	return ret;
}
Ejemplo n.º 14
0
static int		get_clock	(CalcHandle* handle, CalcClock* _clock)
{
	int ret;
	uint16_t varsize;
	uint8_t vartype;
	uint8_t varattr;
	uint8_t version;
	char varname[9];
	uint8_t * buffer = handle->buffer2;
	uint32_t calc_time;

	struct tm ref, *cur;
	time_t r, c, now;

	ticalcs_strlcpy(handle->updat->text, _("Getting clock..."), sizeof(handle->updat->text));
	ticalcs_update_label(handle);

	ret = SEND_REQ(handle, 0x0000, TI73_CLK, "\0x08\0\0\0\0\0\0\0", 0x00, 0x00);
	if (!ret)
	{
		ret = RECV_ACK(handle, NULL);
		if (!ret)
		{
			ret = RECV_VAR(handle, &varsize, &vartype, varname, &varattr, &version);
			if (!ret)
			{
				ret = SEND_ACK(handle);
				if (!ret)
				{
					ret = SEND_CTS(handle);
					if (!ret)
					{
						ret = RECV_ACK(handle, NULL);
						if (!ret)
						{
							ret = RECV_XDP(handle, &varsize, buffer);
							if (!ret)
							{
								ret = SEND_ACK(handle);
							}
						}
					}
				}
			}
		}
	}

	if (!ret)
	{
		calc_time = (((uint32_t)(buffer[2])) << 24) | (((uint32_t)(buffer[3])) << 16) | (((uint32_t)(buffer[4])) << 8) | (uint32_t)(buffer[5]);
		//printf("<%08x>\n", time);

		time(&now);	// retrieve current DST setting
		memcpy(&ref, localtime(&now), sizeof(struct tm));;
		ref.tm_year = 1997 - 1900;
		ref.tm_mon = 0;
		ref.tm_yday = 0;
		ref.tm_mday = 1;
		ref.tm_wday = 3;
		ref.tm_hour = 0;
		ref.tm_min = 0;
		ref.tm_sec = 0;
		//ref.tm_isdst = 1;
		r = mktime(&ref);
		//printf("%s\n", asctime(&ref));

		c = r + calc_time;
		cur = localtime(&c);
		//printf("%s\n", asctime(cur));

		_clock->year = cur->tm_year + 1900;
		_clock->month = cur->tm_mon + 1;
		_clock->day = cur->tm_mday;
		_clock->hours = cur->tm_hour;
		_clock->minutes = cur->tm_min;
		_clock->seconds = cur->tm_sec;

		_clock->date_format = buffer[6];
		_clock->time_format = buffer[7];
	}

	return ret;
}
Ejemplo n.º 15
0
static int		recv_var	(CalcHandle* handle, CalcMode mode, FileContent* content, VarRequest* vr)
{
	char *path;
	int ret;

	ret = nsp_session_open(handle, NSP_SID_FILE_MGMT);
	if (ret)
	{
		return ret;
	}

	path = build_path(handle->model, vr);
	ticonv_varname_to_utf8_sn(handle->model, path, update_->text, sizeof(update_->text), vr->type);
	update_label();

	ret = nsp_cmd_s_get_file(handle, path);
	g_free(path);
	if (!ret)
	{
		ret = nsp_cmd_r_get_file(handle, &(vr->size));
		if (!ret)
		{
			ret = nsp_cmd_s_file_ok(handle);
			if (!ret)
			{
				uint8_t *data = NULL;

				if (vr->size)
				{
					ret = nsp_cmd_r_file_contents(handle, &(vr->size), &data);
				}
				if (!ret)
				{
					ret = nsp_cmd_s_status(handle, NSP_ERR_OK);
					if (!ret)
					{
						VarEntry *ve;

						content->model = handle->model;
						ticalcs_strlcpy(content->comment, tifiles_comment_set_single(), sizeof(content->comment));
						content->num_entries = 1;

						content->entries = tifiles_ve_create_array(1);
						ve = content->entries[0] = tifiles_ve_create();
						memcpy(ve, vr, sizeof(VarEntry));

						ve->data = tifiles_ve_alloc_data(ve->size);
						if (data && ve->data)
						{
							memcpy(ve->data, data, ve->size);
						}
					}
					g_free(data);
				}
			}
		}
	}

	// Close session at the end.
	// XXX don't check the result of this call, to enable reception of variables from Nspires running OS >= 1.7.
	// Those versions send a martian packet:
	// * a src port never seen before in the conversation;
	// * an improper dest port;
	// * a 1-byte payload containing 02 (i.e. an invalid address for the next packet).
	// * .ack = 0x00 (instead of 0x0A).
	nsp_session_close(handle);

	return ret;
}
Ejemplo n.º 16
0
static int		get_version	(CalcHandle* handle, CalcInfos* infos)
{
	int ret;

	ret = nsp_session_open(handle, NSP_SID_DEV_INFOS);
	if (ret)
	{
		return ret;
	}

	do
	{
		uint32_t size;
		uint8_t cmd, *data;

		ret = nsp_cmd_s_dev_infos(handle, NSP_CMD_DI_MODEL);
		if (ret)
		{
			break;
		}
		ret = nsp_cmd_r_dev_infos(handle, &cmd, &size, &data);
		if (ret)
		{
			break;
		}

		ticalcs_strlcpy(infos->product_name, (char *)data, sizeof(infos->product_name));
		infos->mask = INFOS_PRODUCT_NAME;

		g_free(data);

		ret = nsp_cmd_s_dev_infos(handle, NSP_CMD_DI_VERSION);
		if (ret)
		{
			break;
		}
		ret = nsp_cmd_r_dev_infos(handle, &cmd, &size, &data);
		if (ret)
		{
			break;
		}

		infos->model = CALC_NSPIRE;

		infos->flash_free = (  (((uint64_t)data[ 0]) << 56)
		                     | (((uint64_t)data[ 1]) << 48)
		                     | (((uint64_t)data[ 2]) << 40)
		                     | (((uint64_t)data[ 3]) << 32)
		                     | (((uint64_t)data[ 4]) << 24)
		                     | (((uint64_t)data[ 5]) << 16)
		                     | (((uint64_t)data[ 6]) <<  8)
		                     | (((uint64_t)data[ 7])      ));
		infos->mask |= INFOS_FLASH_FREE;

		infos->flash_phys = (  (((uint64_t)data[ 8]) << 56)
		                     | (((uint64_t)data[ 9]) << 48)
		                     | (((uint64_t)data[10]) << 40)
		                     | (((uint64_t)data[11]) << 32)
		                     | (((uint64_t)data[12]) << 24)
		                     | (((uint64_t)data[13]) << 16)
		                     | (((uint64_t)data[14]) <<  8)
		                     | (((uint64_t)data[15])      ));
		infos->mask |= INFOS_FLASH_PHYS;

		infos->ram_free = (  (((uint64_t)data[16]) << 56)
		                   | (((uint64_t)data[17]) << 48)
		                   | (((uint64_t)data[18]) << 40)
		                   | (((uint64_t)data[19]) << 32)
		                   | (((uint64_t)data[20]) << 24)
		                   | (((uint64_t)data[21]) << 16)
		                   | (((uint64_t)data[22]) <<  8)
		                   | (((uint64_t)data[23])      ));
		infos->mask |= INFOS_RAM_FREE;

		infos->ram_phys = (  (((uint64_t)data[24]) << 56)
		                   | (((uint64_t)data[25]) << 48)
		                   | (((uint64_t)data[26]) << 40)
		                   | (((uint64_t)data[27]) << 32)
		                   | (((uint64_t)data[28]) << 24)
		                   | (((uint64_t)data[29]) << 16)
		                   | (((uint64_t)data[30]) <<  8)
		                   | (((uint64_t)data[31])      ));
		infos->mask |= INFOS_RAM_PHYS;

		infos->battery = (data[32] == 0x01) ? 0 : 1;
		infos->mask |= INFOS_BATTERY;

		infos->clock_speed = data[35];
		infos->mask |= INFOS_CLOCK_SPEED;

		ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1i.%1i.%04i", data[36], data[37], (((int)data[38]) << 8) | data[39]);
		infos->mask |= INFOS_OS_VERSION;

		ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1i.%1i.%04i", data[40], data[41], (((int)data[42]) << 8) | data[43]);
		infos->mask |= INFOS_BOOT_VERSION;

		ticalcs_slprintf(infos->boot2_version, sizeof(infos->boot2_version), "%1i.%1i.%04i", data[44], data[45], (((int)data[46]) << 8) | data[47]);
		infos->mask |= INFOS_BOOT2_VERSION;

		infos->hw_version = (  (((uint32_t)data[48]) << 24)
		                     | (((uint32_t)data[49]) << 16)
		                     | (((uint32_t)data[50]) <<  8)
		                     | (((uint32_t)data[51])      ));
		infos->mask |= INFOS_HW_VERSION;

		infos->run_level = data[53];
		infos->mask |= INFOS_RUN_LEVEL;

		infos->lcd_width = (  (((uint16_t)data[58]) << 8)
		                    | (((uint16_t)data[59])     ));
		infos->mask |= INFOS_LCD_WIDTH;

		infos->lcd_height = (  (((uint16_t)data[60]) << 8)
		                     | (((uint16_t)data[61])     ));
		infos->mask |= INFOS_LCD_HEIGHT;

		infos->bits_per_pixel = data[62];
		infos->mask |= INFOS_BPP;

		infos->device_type = data[64];
		infos->mask |= INFOS_DEVICE_TYPE;

		memset(infos->main_calc_id, 0, sizeof(infos->main_calc_id));
		strncpy(infos->main_calc_id, (char*)(data + 82), 28);
		infos->mask |= INFOS_MAIN_CALC_ID;
		memset(infos->product_id, 0, sizeof(infos->product_id));
		strncpy(infos->product_id, (char*)(data + 82), 28);
		infos->mask |= INFOS_PRODUCT_ID;

		g_free(data);
	} while (0);

	DO_CLOSE_SESSION(handle);

	return ret;
}
Ejemplo n.º 17
0
static int		recv_var	(CalcHandle* handle, CalcMode mode, FileContent* content, VarRequest* vr)
{
	int ret;
	uint16_t unused;
	VarEntry *ve;
	uint16_t ve_size;

	content->model = handle->model;
	ticalcs_strlcpy(content->comment, tifiles_comment_set_single(), sizeof(content->comment));
	content->num_entries = 1;
	content->entries = tifiles_ve_create_array(1);
	ve = content->entries[0] = tifiles_ve_create();
	memcpy(ve, vr, sizeof(VarEntry));

	ticonv_varname_to_utf8_sn(handle->model, vr->name, update_->text, sizeof(update_->text), vr->type);
	update_label();

	do
	{
		// silent request
		ret = SEND_REQ(handle, (uint16_t)vr->size, vr->type, vr->name);
		if (!ret)
		{
			ret = RECV_ACK(handle, &unused);
			if (!ret)
			{
				ret = RECV_VAR(handle, &ve_size, &ve->type, ve->name);
			}
		}
		if (ret)
		{
			break;
		}

		ve->size = ve_size;

		ret = SEND_ACK(handle);
		if (!ret)
		{
			ret = SEND_CTS(handle);
			if (!ret)
			{
				ret = RECV_ACK(handle, NULL);
			}
		}
		if (ret)
		{
			break;
		}

		ve->data = tifiles_ve_alloc_data(ve->size);
		ret = RECV_XDP(handle, &ve_size, ve->data);
		if (!ret)
		{
			ve->size = ve_size;
			ret = SEND_ACK(handle);
		}
	} while(0);

	return ret;
}