Example #1
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;

	if(handle == NULL) return ERR_INVALID_HANDLE;
	if (content == NULL)
	{
		ticalcs_critical("ticalcs_calc_send_tigroup: content is NULL");
		return -1;
	}

	TRYF(handle->calc->get_dirlist(handle, &vars, &apps));

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

	update_->cnt3 = 0;
	update_->max3 = nvars + napps;
	update_->pbar();

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

		TRYF(ti89_recv_CTS());
		TRYF(ti89_send_ACK());

		TRYF(ti89_send_EOT());
		TRYF(ti89_recv_ACK(NULL));
	}

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

			update_->cnt3++;
			update_->pbar();

			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;

			TRYF(handle->calc->send_var(handle, MODE_BACKUP, te->content.regular));
		}
	}

	TRYF(handle->calc->is_ready(handle));

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

			update_->cnt3++;
			update_->pbar();

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

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

	return 0;
}
Example #2
0
/**
 * ticalcs_calc_recv_tigroup:
 * @handle: a previously allocated handle
 * @filename: name of file
 * @mode: which vars/apps to receive
 *
 * Receive a TiGroup file.
 *
 * Return value: 0 if ready else ERR_NOT_READY.
 **/
TIEXPORT3 int TICALL ticalcs_calc_recv_tigroup(CalcHandle* handle, TigContent* content, TigMode mode)
{
	int i, j;
	int i_max, j_max;
	GNode *vars, *apps;
	int nvars = 0;
	int napps = 0;
	int b = 0;

	if(handle == NULL) return ERR_INVALID_HANDLE;
	if (content == NULL)
	{
		ticalcs_critical("ticalcs_calc_send_tigroup: content is NULL");
		return -1;
	}

	update_->cnt3 = 0;
	update_->pbar();

	// Do a directory list and check for something to backup
	TRYF(handle->calc->get_dirlist(handle, &vars, &apps));
	if((mode & TIG_RAM) || (mode & TIG_ARCHIVE))
		nvars = ticalcs_dirlist_ve_count(vars);
	if(mode & TIG_FLASH)
		napps = ticalcs_dirlist_ve_count(apps);

	update_->cnt3 = 0;
	update_->max3 = nvars + napps;
	update_->pbar();

	if(!nvars && !napps)
		return ERR_NO_VARS;

	// 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

	// Receive all vars
	i_max = g_node_n_children(vars);
	if((mode & TIG_RAM) || (mode & TIG_ARCHIVE))
	for(i = 0; i < i_max; i++) 
	{
		GNode *parent = g_node_nth_child(vars, i);

		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);
			TigEntry *te;
			char *filename;
			char *varname;
			char *fldname;

			PAUSE(100);
			TRYF(handle->calc->is_ready(handle));
			PAUSE(100);

			update_->cnt3++;
			update_->pbar();

			if(((mode & TIG_ARCHIVE) && (ve->attr == ATTRB_ARCHIVED)) ||
			   ((mode & TIG_RAM) && ve->attr != ATTRB_ARCHIVED))
			{
				fldname = ticonv_varname_to_filename(handle->model, ve->folder, -1);
				varname = ticonv_varname_to_filename(handle->model, ve->name, ve->type);
				if(handle->calc->features & FTS_FOLDER)
					filename = g_strconcat(fldname, ".", varname, ".", 
						tifiles_vartype2fext(handle->model, ve->type), NULL);
				else
					filename = g_strconcat(varname, ".", 
						tifiles_vartype2fext(handle->model, ve->type), NULL);
				g_free(fldname);
				g_free(varname);

				te = tifiles_te_create(filename, TIFILE_SINGLE, handle->model);
				g_free(filename);

				TRYF(handle->calc->recv_var(handle, 0, te->content.regular, ve));
				tifiles_content_add_te(content, te);
			}
		}
	}
	ticalcs_dirlist_destroy(&vars);

	// Receive all apps
	i_max = g_node_n_children(apps);
	if(mode & TIG_FLASH)
	for(i = 0; i < i_max; i++) 
	{
		GNode *parent = g_node_nth_child(apps, i);

		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);
			TigEntry *te;
			char *filename;
			char *basename;

			TRYF(handle->calc->is_ready(handle));

			update_->cnt3++;
			update_->pbar();

			basename = ticonv_varname_to_filename(handle->model, ve->name, ve->type);
			filename = g_strconcat(basename, ".", tifiles_vartype2fext(handle->model, ve->type), NULL);
			g_free(basename);

			te = tifiles_te_create(filename, TIFILE_FLASH, handle->model);
			g_free(filename);

			TRYF(handle->calc->recv_app(handle, te->content.flash, ve));
			tifiles_content_add_te(content, te);
		}
	}	
	ticalcs_dirlist_destroy(&apps);

	return 0;
}
Example #3
0
static int		set_clock	(CalcHandle* handle, CalcClock* _clock)
{
	CalcParam *param;

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

	time(&now);
	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);

	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);

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

	g_snprintf(update_->text, sizeof(update_->text), _("Setting clock..."));
	update_label();

	param = cp_new(PID_CLK_SEC, 4);
	param->data[0] = MSB(MSW(calc_time));
	param->data[1] = LSB(MSW(calc_time));
	param->data[2] = MSB(LSW(calc_time));
	param->data[3] = LSB(LSW(calc_time));
	TRYF(cmd_s_param_set(handle, param));
	TRYF(cmd_r_data_ack(handle));
	cp_del(param);

	param = cp_new(PID_CLK_DATE_FMT, 1);
	param->data[0] = _clock->date_format == 3 ? 0 : _clock->date_format;
	TRYF(cmd_s_param_set(handle, param));
	TRYF(cmd_r_data_ack(handle));
	cp_del(param);

	param = cp_new(PID_CLK_TIME_FMT, 1);
	param->data[0] = _clock->time_format == 24 ? 1 : 0;
	TRYF(cmd_s_param_set(handle, param));
	TRYF(cmd_r_data_ack(handle));
	cp_del(param);

	param = cp_new(PID_CLK_ON, 1);
	param->data[0] = _clock->state;
	TRYF(cmd_s_param_set(handle, param));
	TRYF(cmd_r_data_ack(handle));
	cp_del(param);

	return 0;
}
Example #4
0
static int		get_version	(CalcHandle* handle, CalcInfos* infos)
{
	uint16_t pids[] = { 
		PID_PRODUCT_NAME, PID_MAIN_PART_ID,
		PID_HW_VERSION, PID_LANGUAGE_ID, PID_SUBLANG_ID, PID_DEVICE_TYPE,
		PID_BOOT_VERSION, PID_OS_VERSION, 
		PID_PHYS_RAM, PID_USER_RAM, PID_FREE_RAM,
		PID_PHYS_FLASH, PID_USER_FLASH, PID_FREE_FLASH,
		PID_LCD_WIDTH, PID_LCD_HEIGHT, PID_BATTERY, PID_OS_MODE,
	};
	const int size = sizeof(pids) / sizeof(uint16_t);
	CalcParam **params;
	int i = 0;

	g_snprintf(update_->text, sizeof(update_->text), _("Getting version..."));
	update_label();

	memset(infos, 0, sizeof(CalcInfos));
	params = cp_new_array(size);

	TRYF(cmd_s_param_request(handle, size, pids));
	TRYF(cmd_r_param_data(handle, size, params));

	strncpy(infos->product_name, (char*)params[i]->data, params[i]->size);
	infos->mask |= INFOS_PRODUCT_NAME;
	i++;

	g_snprintf(infos->main_calc_id, 10, "%02X%02X%02X%02X%02X", 
		params[i]->data[0], params[i]->data[1], params[i]->data[2], params[i]->data[3], params[i]->data[4]);
	infos->mask |= INFOS_MAIN_CALC_ID;
	strcpy(infos->product_id, infos->main_calc_id);
	infos->mask |= INFOS_PRODUCT_ID;
	i++;

	infos->hw_version = (params[i]->data[0] << 8) | params[i]->data[1];
	infos->mask |= INFOS_HW_VERSION; // hw version or model ?
	i++;

	infos->language_id = params[i]->data[0];
	infos->mask |= INFOS_LANG_ID;
	i++;

	infos->sub_lang_id = params[i]->data[0];
	infos->mask |= INFOS_SUB_LANG_ID;
	i++;

	infos->device_type = params[i]->data[1];
	infos->mask |= INFOS_DEVICE_TYPE;
	i++;

	g_snprintf(infos->boot_version, 5, "%1i.%02i", params[i]->data[1], params[i]->data[2]);
	infos->mask |= INFOS_BOOT_VERSION;
	i++;

	g_snprintf(infos->os_version, 5, "%1i.%02i", params[i]->data[1], params[i]->data[2]);
	infos->mask |= INFOS_OS_VERSION;
	i++;

	infos->ram_phys = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_RAM_PHYS;
	i++;
	infos->ram_user = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_RAM_USER;
	i++;
	infos->ram_free = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_RAM_FREE;
	i++;

	infos->flash_phys = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_FLASH_PHYS;
	i++;
	infos->flash_user = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_FLASH_USER;
	i++;
	infos->flash_free = GINT64_FROM_BE(*((uint64_t *)(params[i]->data)));
	infos->mask |= INFOS_FLASH_FREE;
	i++;

	infos->lcd_width = GINT16_FROM_BE(*((uint16_t *)(params[i]->data)));
	infos->mask |= INFOS_LCD_WIDTH;
	i++;
	infos->lcd_height = GINT16_FROM_BE(*((uint16_t *)(params[i]->data)));
	infos->mask |= INFOS_LCD_HEIGHT;
	i++;

	infos->bits_per_pixel = 1;
	infos->mask |= INFOS_BPP;

	infos->battery = params[i]->data[0];
	infos->mask |= INFOS_BATTERY;
	i++;

	infos->run_level = params[i]->data[0];
	infos->mask |= INFOS_RUN_LEVEL;
	i++;

	switch(infos->hw_version)
	{
		case 0: infos->model = CALC_TI83P; break;
		case 1: infos->model = CALC_TI83P; break;
		case 2: infos->model = CALC_TI84P; break;
		case 3: infos->model = CALC_TI84P; break;
	}
	infos->mask |= INFOS_CALC_MODEL;

	cp_del_array(size, params);
	return 0;
}
Example #5
0
static int		send_os    (CalcHandle* handle, FlashContent* content)
{
	ModeSet mode = { 2, 1, 0, 0, 0x0fa0 }; //MODE_BASIC;
	uint32_t pkt_size = 266;
	uint32_t os_size = 0;
	FlashContent *ptr;
	int i, j;
	int boot = 0;

	// search for data header
	for (ptr = content; ptr != NULL; ptr = ptr->next)
		if(ptr->data_type == TI83p_AMS || ptr->data_type == TI83p_APPL)
			break;
	if(ptr == NULL)
		return -1;
	if(ptr->data_type != TI83p_AMS)
		return -1;

#if 0
	printf("#pages: %i\n", ptr->num_pages);
	printf("type: %02x\n", ptr->data_type);
	for (i = 0; i < ptr->num_pages; i++) 
	{
		FlashPage *fp = ptr->pages[i];

		printf("page #%i: %04x %02x %02x %04x\n", i,
			fp->addr, fp->page, fp->flag, fp->size);
		//tifiles_hexdump(fp->data, 16);
	}
	printf("data length = %08x %i\n", ptr->data_length, ptr->data_length);
#endif

	for(i = 0; i < ptr->num_pages; i++)
	{
		FlashPage *fp = ptr->pages[i];

		if(fp->size < 256)
			os_size += 4;
		else
			os_size += 4*(fp->size / 260);
	}
	printf("os_size overhead = %i\n", os_size);
	os_size += ptr->data_length;
	printf("os_size new = %i\n", os_size);

	// switch to BASIC mode
	TRYF(cmd_s_mode_set(handle, mode));
	TRYF(cmd_r_mode_ack(handle));

	// test for boot mode
	{
		uint16_t pids[] = { PID_OS_MODE };
		const int size = sizeof(pids) / sizeof(uint16_t);
		CalcParam **params;

		params = cp_new_array(size);
		TRYF(cmd_s_param_request(handle, size, pids));
		TRYF(cmd_r_param_data(handle, size, params));
		boot = !params[0]->data[0];
	}

	// start OS transfer
	TRYF(cmd_s_os_begin(handle, os_size));
	if(!boot)
	{
		TRYF(dusb_recv_buf_size_request(handle, &pkt_size));
		TRYF(dusb_send_buf_size_alloc(handle, pkt_size));
	}
	TRYF(cmd_r_os_ack(handle, &pkt_size));	// this pkt_size is important

	// send OS header/signature
	TRYF(cmd_s_os_header(handle, 0x4000, 0x7A, 0x80, pkt_size-4, ptr->pages[0]->data));
	TRYF(cmd_r_os_ack(handle, &pkt_size));

	// send OS data
	update_->cnt2 = 0;
	update_->max2 = ptr->num_pages;

	for(i = 0; i < ptr->num_pages; i++)
	{
		FlashPage *fp = ptr->pages[i];

		fp->addr = 0x4000;

		if(i == 0)	// need relocation
		{
			TRYF(cmd_s_os_data(handle, 0x4000, 0x7A, 0x80, pkt_size-4, fp->data));
			TRYF(cmd_r_data_ack(handle));
		}
		else if(i == ptr->num_pages-1)	// idem
		{
			TRYF(cmd_s_os_data(handle, 0x4100, 0x7A, 0x80, pkt_size-4, fp->data));
			TRYF(cmd_r_data_ack(handle));
		}
		else
		{
			for(j = 0; j < fp->size; j += 256/*(pkt_size-4)*/)
			{
				TRYF(cmd_s_os_data(handle, 
					(uint16_t)(fp->addr + j), (uint8_t)fp->page, fp->flag, 
					pkt_size-4, fp->data + j));
				TRYF(cmd_r_data_ack(handle));
			}
		}

		update_->cnt2 = i;
		update_->pbar();
	}
	
	TRYF(cmd_s_eot(handle));
	PAUSE(500);
	TRYF(cmd_r_eot_ack(handle));

	return 0;
}
Example #6
0
static int		dump_rom_1	(CalcHandle* handle)
{
	TRYF(rd_send(handle, "romdump.8Xp", romDumpSize84p, romDump84p));

	return 0;
}
Example #7
0
static int		send_flash	(CalcHandle* handle, FlashContent* content)
{
	FlashContent *ptr;
	int i;
	char *utf8;
	CalcAttr **attrs;
	const int nattrs = 2;

	uint8_t *data;
	uint32_t size;

	// search for data header
	for (ptr = content; ptr != NULL; ptr = ptr->next)
		if(ptr->data_type == TI83p_AMS || ptr->data_type == TI83p_APPL)
			break;
	if(ptr == NULL)
		return -1;
	if(ptr->data_type != TI83p_APPL)
		return -1;

#if 0
	printf("#pages: %i\n", ptr->num_pages);
	printf("type: %02x\n", ptr->data_type);
	for (i = 0; i < ptr->num_pages; i++) 
	{
		FlashPage *fp = ptr->pages[i];

		printf("page #%i: %04x %02x %02x %04x\n", i,
			fp->addr, fp->page, fp->flag, fp->size);
	}
	printf("data length: %08x\n", ptr->data_length);

	return 0;
#endif

	size = ptr->num_pages * FLASH_PAGE_SIZE;
	data = tifiles_fp_alloc_data(size);	// must be rounded-up

	update_->cnt2 = 0;
	update_->max2 = ptr->num_pages;

	for (i = 0; i < ptr->num_pages; i++) 
	{
		FlashPage *fp = ptr->pages[i];
		memcpy(data + i*FLASH_PAGE_SIZE, fp->data, FLASH_PAGE_SIZE);

		update_->cnt2 = i;
		update_->pbar();
	}
	{
		FlashPage *fp = ptr->pages[--i];
		memset(data + i*FLASH_PAGE_SIZE + fp->size, 0x00, FLASH_PAGE_SIZE - fp->size); 

		update_->cnt2 = i;
		update_->pbar();
	}

	// send
	utf8 = ticonv_varname_to_utf8(handle->model, ptr->name, ptr->data_type);
	g_snprintf(update_->text, sizeof(update_->text), "%s", utf8);
	g_free(utf8);
	update_label();

	attrs = ca_new_array(nattrs);
	attrs[0] = ca_new(AID_VAR_TYPE, 4);
	attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x07;
	attrs[0]->data[2] = 0x00; attrs[0]->data[3] = ptr->data_type;
	attrs[1] = ca_new(AID_ARCHIVED, 1);
	attrs[1]->data[0] = 0;
	
	TRYF(cmd_s_rts(handle, "", ptr->name, size, nattrs, CA(attrs)));
	TRYF(cmd_r_data_ack(handle));
	TRYF(cmd_s_var_content(handle, size, data));
	TRYF(cmd_r_data_ack(handle));
	TRYF(cmd_s_eot(handle));

	return 0;
}
Example #8
0
static int		recv_var_ns	(CalcHandle* handle, CalcMode mode, FileContent* content, VarEntry** vr)
{
  int nvar = 0;
  int err = 0;
  char *utf8;
  uint16_t ve_size;

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

  content->model = CALC_TI85;

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

    content->entries = tifiles_ve_resize_array(content->entries, nvar+1);
    ve = content->entries[nvar] = tifiles_ve_create();;

    do 
	{
      update_refresh();
      if (update_->cancel)
		return ERR_ABORT;

      err = ti85_recv_VAR(&ve_size, &(ve->type), ve->name);
      ve->size = ve_size;
    }
    while (err == ERROR_READ_TIMEOUT);

    TRYF(ti85_send_ACK());
    if (err == ERR_EOT) 
      goto exit;
    TRYF(err);

    TRYF(ti85_send_CTS());
    TRYF(ti85_recv_ACK(NULL));

	utf8 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type);
    g_snprintf(update_->text, sizeof(update_->text), "%s", utf8);
	g_free(utf8);
    update_label();

    ve->data = tifiles_ve_alloc_data(ve->size);
    TRYF(ti85_recv_XDP(&ve_size, ve->data));
    ve->size = ve_size;
    TRYF(ti85_send_ACK());
  }

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

  return 0;
}
Example #9
0
static int		get_dirlist	(CalcHandle* handle, GNode** vars, GNode** apps)
{
	uint16_t aids[] = { AID_VAR_SIZE, AID_VAR_TYPE, AID_ARCHIVED, };
	const int size = sizeof(aids) / sizeof(uint16_t);
	TreeInfo *ti;
	int err;
	CalcAttr **attr;
	GNode *folder, *root;
	char fldname[40], varname[40];
	char *utf8;

	(*apps) = g_node_new(NULL);
	ti = (TreeInfo *)g_malloc(sizeof(TreeInfo));
	ti->model = handle->model;
	ti->type = APP_NODE_NAME;
	(*apps)->data = ti;

	(*vars) = g_node_new(NULL);
	ti = (TreeInfo *)g_malloc(sizeof(TreeInfo));
	ti->model = handle->model;
	ti->type = VAR_NODE_NAME;
	(*vars)->data = ti;

	folder = g_node_new(NULL);
	g_node_append(*vars, folder);

	root = g_node_new(NULL);
	g_node_append(*apps, root);

	// Add permanent variables (Window, RclWindow, TblSet aka WINDW, ZSTO, TABLE)
	{
		GNode *node;
		VarEntry *ve;

		ve = tifiles_ve_create();
		strcpy(ve->name, "Window");
		ve->type = TI84p_WINDW;
		node = g_node_new(ve);
		g_node_append(folder, node);

		ve = tifiles_ve_create();
		strcpy(ve->name, "RclWin");
		ve->type = TI84p_ZSTO;
		node = g_node_new(ve);
		g_node_append(folder, node);

		ve = tifiles_ve_create();
		strcpy(ve->name, "TblSet");
		ve->type = TI84p_TABLE;
		node = g_node_new(ve);
		g_node_append(folder, node);
	}

	TRYF(cmd_s_dirlist_request(handle, size, aids));
	do
	{
		VarEntry *ve = tifiles_ve_create();
		GNode *node;

		attr = ca_new_array(size);
		err = cmd_r_var_header(handle, fldname, varname, attr);
		if (err == ERR_EOT)
			break;
		else if (err != 0)
			return err;

		strcpy(ve->name, varname);
		ve->size = GINT32_FROM_BE(*((uint32_t *)(attr[0]->data)));
		ve->type = GINT32_FROM_BE(*((uint32_t *)(attr[1]->data))) & 0xff;
		ve->attr = attr[2]->data[0] ? ATTRB_ARCHIVED : ATTRB_NONE;
		ca_del_array(size, attr);

		node = g_node_new(ve);
		if (ve->type != TI73_APPL)
			g_node_append(folder, node);
		else
			g_node_append(root, node);

		utf8 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type);
		g_snprintf(update_->text, sizeof(update_->text), _("Parsing %s"), utf8);
		g_free(utf8);
		update_label();
	} while(1);

	return 0;
}
Example #10
0
static int		send_backup	(CalcHandle* handle, BackupContent* content)
{
	TRYF(send_var(handle, MODE_BACKUP, (FileContent *)content));
	return 0;
}
Example #11
0
static int		get_version	(CalcHandle* handle, CalcInfos* infos)
{
	uint32_t size;
	uint8_t cmd, *data;
	//int i;

	TRYF(nsp_session_open(handle, SID_DEV_INFOS));

	TRYF(nsp_cmd_s_dev_infos(handle, CMD_DI_MODEL));
	TRYF(nsp_cmd_r_dev_infos(handle, &cmd, &size, &data));

	strcpy(infos->product_name, (char*)data);
	infos->mask |= INFOS_PRODUCT_NAME;

	TRYF(nsp_cmd_s_dev_infos(handle, CMD_DI_VERSION));
	TRYF(nsp_cmd_r_dev_infos(handle, &cmd, &size, &data));

	infos->model = CALC_NSPIRE;

	//i = 0;
	//infos->flash_free = GUINT64_FROM_BE(*((uint64_t *)(data + i)));
	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;

	//i = 8;
	//infos->flash_phys = GUINT64_FROM_BE(*((uint64_t *)(data + i)));
	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;

	//i = 16;
	//infos->ram_free = GUINT64_FROM_BE(*((uint64_t *)(data + i)));
	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;

	//i = 24;
	//infos->ram_phys = GUINT64_FROM_BE(*((uint64_t *)(data + i)));
	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;

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

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

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

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

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

	//i = 48;
	//infos->hw_version = GUINT32_FROM_BE(*((uint32_t *)(data + i)));
	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;

	//i = 52;
	//infos->run_level = (uint8_t)GUINT16_FROM_BE(*((uint16_t *)(data + i)));
	infos->run_level = data[53];
	infos->mask |= INFOS_RUN_LEVEL;

	//i = 58;
	//infos->lcd_width = GUINT16_FROM_BE(*((uint16_t *)(data + i)));
	infos->lcd_width = (  (((uint16_t)data[58]) << 8)
	                    | (((uint16_t)data[59])     ));
	infos->mask |= INFOS_LCD_WIDTH;

	//i = 60;
	//infos->lcd_height = GUINT16_FROM_BE(*((uint16_t *)(data + i)));
	infos->lcd_height = (  (((uint16_t)data[60]) << 8)
	                     | (((uint16_t)data[61])     ));
	infos->mask |= INFOS_LCD_HEIGHT;

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

	//i = 64;
	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);
	TRYF(nsp_session_close(handle));

	return 0;
}
Example #12
0
static int		is_ready	(CalcHandle* handle)
{
	static int rom_11 = 0;
	static int rom_14 = 0;

	// XXX debrouxl forcing a full sequence makes all operations a LOT slower (especially on
	// older OS), but fixes the 100% reproducible loss of connection after a few "Status"
	// operations or a single "List" operation, on my S-0907A non-CAS Nspire.
	// Tested with OS 1.1.9253, 1.2.2398, 1.3.2407, 1.4.11653, 1.6.4379, 1.7.2471, 1.7.1.50.
	//
	// A better fix is needed in the mid- and long-term.

	// checking for OS version and LOGIN packet
	//if(!nsp_reset)
	{
		// XXX debrouxl moving those two lines above the 'if(!nsp_reset)' test fixes connection
		// loss, but linking with at least 1.7.1.50 does not work properly after that: at least
		// directory listing and screenshot don't do anything beyond the "Status" probe.
		TRYF(nsp_addr_request(handle));
		TRYF(nsp_addr_assign(handle, NSP_DEV_ADDR));

		// XXX after commenting the following block of code, sending many Status or Dirlist
		// requests in short succession often triggers memory corruption (hangs, reboots,
		// a variable amount of black pixels on the screen) on (at least) Nspire (CAS) OS 1.7...
		{
			int old;
			int ret;

			ticalcs_info("  waiting for LOGIN request (OS >= 1.2 check)...");
			old = ticables_options_set_timeout(handle->cable, 40);	// 3s mini

			ret = nsp_cmd_r_login(handle);	// no call to TRYF(nsp_send_nack(handle)) because nack is managed in nsp_recv_data()

			ticables_options_set_timeout(handle->cable, old);
			if(ret)
			{
				ticalcs_info("OS = 1.1");
				rom_11 = !0;

				TRYF(nsp_addr_request(handle));
				TRYF(nsp_addr_assign(handle, NSP_DEV_ADDR));
			}
			else
			{
				ret = nsp_recv_disconnect(handle);
				if(ret)
				{
					ticalcs_info("OS = 1.2 or 1.3");
					rom_14 = 0;
				}
				else
				{
					ticalcs_info("OS = 1.4 or later");
					rom_14 = !0;
				}

			}
		}

		//nsp_reset = !0;
	}

	// Use ECHO packet as ready check
	{
		char str[] = "ready";
		uint32_t size;
		uint8_t *data;

		TRYF(nsp_session_open(handle, SID_ECHO));

		TRYF(nsp_cmd_s_echo(handle, strlen(str)+1, (uint8_t *)str));
		TRYF(nsp_cmd_r_echo(handle, &size, &data));
		g_free(data);

		TRYF(nsp_session_close(handle));
	}

	return 0;
}
Example #13
0
static int		get_dirlist	(CalcHandle* handle, GNode** vars, GNode** apps)
{
	TreeInfo *ti;
	int err;
	GNode *root, *folder = NULL;
	char varname[VARNAME_MAX];
	uint32_t varsize;
	uint8_t vartype;
	int i;

	(*apps) = g_node_new(NULL);
	ti = (TreeInfo *)g_malloc(sizeof(TreeInfo));
	ti->model = handle->model;
	ti->type = APP_NODE_NAME;
	(*apps)->data = ti;

	(*vars) = g_node_new(NULL);
	ti = (TreeInfo *)g_malloc(sizeof(TreeInfo));
	ti->model = handle->model;
	ti->type = VAR_NODE_NAME;
	(*vars)->data = ti;

	root = g_node_new(NULL);
	g_node_append(*apps, root);

	TRYF(nsp_session_open(handle, SID_FILE_MGMT));
	TRYF(nsp_cmd_s_dir_attributes(handle, "/"));
	TRYF(nsp_cmd_r_dir_attributes(handle, NULL, NULL, NULL));
	TRYF(nsp_session_close(handle));

	TRYF(nsp_session_open(handle, SID_FILE_MGMT));

	TRYF(nsp_cmd_s_dir_enum_init(handle, "/"));
	TRYF(nsp_cmd_r_dir_enum_init(handle));

	for(;;)
	{
		VarEntry *fe;
		GNode *node;

		TRYF(nsp_cmd_s_dir_enum_next(handle));
		err = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype);

		if (err == ERR_EOT)
			break;
		else if (err != 0)
			return err;

		fe = tifiles_ve_create();
		strcpy(fe->folder, varname);
		strcpy(fe->name, varname);
		fe->size = varsize;
		fe->type = vartype;
		fe->attr = ATTRB_NONE;

		node = g_node_new(fe);
		folder = g_node_append(*vars, node);

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

	TRYF(nsp_cmd_s_dir_enum_done(handle));
	TRYF(nsp_cmd_r_dir_enum_done(handle));

	for(i = 0; i < (int)g_node_n_children(*vars); i++) 
	{
		char *folder_name;
		char *u1, *u2;

		folder = g_node_nth_child(*vars, i);
		folder_name = ((VarEntry *) (folder->data))->name;
		vartype = ((VarEntry *) (folder->data))->type;

		// Skip entries whose type is 0 (TNS), for example themes.csv on OS 3.0+.
		if (vartype == 0)
		{
			ticalcs_info(_("Not enumerating documents in %s because it's not a folder"), folder_name);
			continue;
		}

		ticalcs_info(_("Directory listing in <%s>..."), folder_name);

		TRYF(nsp_cmd_s_dir_enum_init(handle, folder_name));
		TRYF(nsp_cmd_r_dir_enum_init(handle));

		for(;;)
		{
			VarEntry *ve = tifiles_ve_create();
			GNode *node;
			char *ext;

			TRYF(nsp_cmd_s_dir_enum_next(handle));
			err = nsp_cmd_r_dir_enum_next(handle, varname, &varsize, &vartype);

			if (err == ERR_EOT)
				break;
			else if (err != 0)
				return err;

			ext = tifiles_fext_get(varname);
			strcpy(ve->folder, folder_name);
			ve->size = varsize;
			ve->type = tifiles_fext2vartype(handle->model, ext);
			ve->attr = ATTRB_NONE;
			// 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 (ve->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.
			}
			strcpy(ve->name, varname);

			node = g_node_new(ve);
			g_node_append(folder, node);

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

			u1 = ticonv_varname_to_utf8(handle->model, ((VarEntry *) (folder->data))->name, -1);
			u2 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type);
			g_snprintf(update_->text, sizeof(update_->text), _("Parsing %s/%s"), u1, u2);
			g_free(u1); g_free(u2);
			update_label();
		}

		TRYF(nsp_cmd_s_dir_enum_done(handle));
		TRYF(nsp_cmd_r_dir_enum_done(handle));
	}

	TRYF(nsp_session_close(handle));

	return 0;
}
Example #14
0
int tixx_recv_backup(CalcHandle* handle, BackupContent* content)
{
	int i, j, k;
	int i_max, j_max;
	GNode *vars, *apps;
	int nvars, ivars = 0;
	int b = 0;
	FileContent **group;
	FileContent *single;

	if(handle == NULL) return ERR_INVALID_HANDLE;
	if (content == NULL)
	{
		ticalcs_critical("tixx_recv_backup: content is NULL");
		return -1;
	}

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

	update_->cnt2 = update_->cnt3 = 0;
	update_->max2 = update_->max3 = nvars;
	update_->pbar();

	// 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);

		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);

			update_->cnt2 = update_->cnt3 = ++ivars;
			update_->pbar();

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

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

	tifiles_group_contents(group, &single);
	tifiles_content_delete_group(group);

	// Swap content and single because we have a pointer on an allocated content
	{
		FileContent* cnt = (FileContent *)content;

		memcpy(content, single, sizeof(FileContent));
		cnt->entries = single->entries;
		strcpy(cnt->comment, tifiles_comment_set_group());
	}

	return 0;
}
Example #15
0
static int		recv_flash	(CalcHandle* handle, FlashContent* content, VarRequest* vr)
{
	uint16_t aids[] = { AID_ARCHIVED, AID_VAR_VERSION };
	const int naids = sizeof(aids) / sizeof(uint16_t);
	CalcAttr **attrs;
	const int nattrs = 1;
	char fldname[40], varname[40];
	uint8_t *data;
	char *utf8;
	
	int page;
	uint16_t data_addr = 0x4000;
	uint16_t data_page = 0;
	int r, q;

	utf8 = ticonv_varname_to_utf8(handle->model, vr->name, vr->type);
	g_snprintf(update_->text, sizeof(update_->text), "%s", utf8);
	g_free(utf8);
	update_label();

	attrs = ca_new_array(nattrs);
	attrs[0] = ca_new(AID_VAR_TYPE2, 4);
	attrs[0]->data[0] = 0xF0; attrs[0]->data[1] = 0x07;
	attrs[0]->data[2] = 0x00; attrs[0]->data[3] = vr->type;

	TRYF(cmd_s_var_request(handle, "", vr->name, naids, aids, 
			       nattrs, CA(attrs)));
	ca_del_array(nattrs, attrs);
	attrs = ca_new_array(naids);
	TRYF(cmd_r_var_header(handle, fldname, varname, attrs));
	TRYF(cmd_r_var_content(handle, NULL, &data));

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

	q = vr->size / FLASH_PAGE_SIZE;
	r = vr->size % FLASH_PAGE_SIZE;

	update_->cnt2 = 0;
	update_->max2 = q;

	for(page = 0; page < q; page++)
	{
		FlashPage *fp = content->pages[page] = tifiles_fp_create();

		fp->addr = data_addr;
		fp->page = data_page++;
		fp->flag = 0x80;
		fp->size = FLASH_PAGE_SIZE;
		fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
		memcpy(fp->data, data + FLASH_PAGE_SIZE*page, FLASH_PAGE_SIZE);

		update_->cnt2 = page;
		update_->pbar();
	}
	{
		FlashPage *fp = content->pages[page] = tifiles_fp_create();

		fp->addr = data_addr;
		fp->page = data_page++;
		fp->flag = 0x80;
		fp->size = r;
		fp->data = tifiles_fp_alloc_data(FLASH_PAGE_SIZE);
		memcpy(fp->data, data + FLASH_PAGE_SIZE*page, r);

		update_->cnt2 = page;
		update_->pbar();
	}
	content->num_pages = page+1;

	g_free(data);	
	ca_del_array(naids, attrs);
	return 0;
}
Example #16
0
static int		send_backup	(CalcHandle* handle, BackupContent* content)
{
  int err = 0;
  uint16_t length;
  char varname[9];
  uint8_t rej_code;
  uint16_t status;

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

  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(content->mem_address);
  varname[5] = MSB(content->mem_address);

  TRYF(ti85_send_VAR(content->data_length1, TI85_BKUP, varname));
  TRYF(ti85_recv_ACK(&status));

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

    if (update_->cancel)
      return ERR_ABORT;

    err = ti85_recv_SKP(&rej_code);
  }
  while (err == ERROR_READ_TIMEOUT);

  TRYF(ti85_send_ACK());
  switch (rej_code) 
  {
  case REJ_EXIT:
  case REJ_SKIP:
    return ERR_ABORT;
  case REJ_MEMORY:
    return ERR_OUT_OF_MEMORY;
  default:			// RTS
    break;
  }

  strcpy(update_->text, ""); 
  update_label();

  update_->cnt2 = 0;
  update_->max2 = 3;
  update_->pbar();

  TRYF(ti85_send_XDP(content->data_length1, content->data_part1));
  TRYF(ti85_recv_ACK(&status));
  update_->cnt2++;
  update_->pbar();

  TRYF(ti85_send_XDP(content->data_length2, content->data_part2));
  TRYF(ti85_recv_ACK(&status));
  update_->cnt2++;
  update_->pbar();

  TRYF(ti85_send_XDP(content->data_length3, content->data_part3));
  TRYF(ti85_recv_ACK(&status));
  update_->cnt2++;
  update_->pbar();

  TRYF(ti85_send_EOT());

  return 0;
}
Example #17
0
static int		send_var_ns	(CalcHandle* handle, CalcMode mode, FileContent* content)
{
  int i;
  int err;
  uint8_t rej_code;
  uint16_t status;
  char *utf8;

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

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

    TRYF(ti85_send_VAR((uint16_t)entry->size, entry->type, entry->name));
    TRYF(ti85_recv_ACK(&status));

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

    do {			// wait user's action
      update_refresh();
      if (update_->cancel)
		return ERR_ABORT;

      err = ti85_recv_SKP(&rej_code);
    }
    while (err == ERROR_READ_TIMEOUT);

    TRYF(ti85_send_ACK());
    switch (rej_code) 
	{
    case REJ_EXIT:
      return ERR_ABORT;
    case REJ_SKIP:
      continue;
    case REJ_MEMORY:
      return ERR_OUT_OF_MEMORY;
    default:			// RTS
      break;
    }

	utf8 = ticonv_varname_to_utf8(handle->model, entry->name, entry->type);
    g_snprintf(update_->text, sizeof(update_->text), "%s", utf8);
	g_free(utf8);
    update_label();

    TRYF(ti85_send_XDP(entry->size, entry->data));
    TRYF(ti85_recv_ACK(&status));

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

  if ((mode & MODE_SEND_ONE_VAR) || (mode & MODE_SEND_LAST_VAR)) 
  {
    TRYF(ti85_send_EOT());
    TRYF(ti85_recv_ACK(NULL));
  }

  return 0;
}