static int del_var (CalcHandle* handle, VarRequest* vr) { char *utf8; char *path; int ret; ret = nsp_session_open(handle, NSP_SID_FILE_MGMT); if (ret) { return ret; } path = build_path(handle->model, vr); utf8 = ticonv_varname_to_utf8(handle->model, path, vr->type); ticalcs_slprintf(update_->text, sizeof(update_->text), _("Deleting %s..."), utf8); ticonv_utf8_free(utf8); update_label(); ret = nsp_cmd_s_del_file(handle, path); g_free(path); if (!ret) { ret = nsp_cmd_r_del_file(handle); } DO_CLOSE_SESSION(handle); return ret; }
static int new_folder (CalcHandle* handle, VarRequest* vr) { char *utf8; char *path; int ret; ret = nsp_session_open(handle, NSP_SID_FILE_MGMT); if (ret) { return ret; } path = g_strconcat("/", vr->folder, NULL); utf8 = ticonv_varname_to_utf8(handle->model, path, -1); ticalcs_slprintf(update_->text, sizeof(update_->text), _("Creating %s..."), utf8); ticonv_utf8_free(utf8); update_label(); ret = nsp_cmd_s_new_folder(handle, path); g_free(path); if (!ret) { ret = nsp_cmd_r_new_folder(handle); } DO_CLOSE_SESSION(handle); return ret; }
static int rename_var (CalcHandle* handle, VarRequest* oldname, VarRequest* newname) { char *utf81, *utf82; char *path1, *path2; int ret; ret = nsp_session_open(handle, NSP_SID_FILE_MGMT); if (ret) { return ret; } path1 = build_path(handle->model, oldname); path2 = build_path(handle->model, newname); utf81 = ticonv_varname_to_utf8(handle->model, path1, oldname->type); utf82 = ticonv_varname_to_utf8(handle->model, path2, newname->type); ticalcs_slprintf(update_->text, sizeof(update_->text), _("Renaming %s to %s..."), utf81, utf82); ticonv_utf8_free(utf82); ticonv_utf8_free(utf81); update_label(); ret = nsp_cmd_s_rename_file(handle, path1, path2); g_free(path2); g_free(path1); if (!ret) { ret = nsp_cmd_r_rename_file(handle); } DO_CLOSE_SESSION(handle); return ret; }
static int del_var (CalcHandle* handle, VarRequest* vr) { int ret = 0; static const uint16_t keys[] = { 0x40, 0x09, 0x09, /* Quit, Clear, Clear, */ 0x3e, 0x9d, 0x04, /* Catalog, D, Down */ 0x04, 0x04, 0x05 /* Down, Down, Enter */ }; unsigned int i; char *utf8; utf8 = ticonv_varname_to_utf8(handle->model, vr->name, vr->type); ticalcs_slprintf(update_->text, sizeof(update_->text), _("Deleting %s..."), utf8); ticonv_utf8_free(utf8); update_label(); // Input keys by remote control for (i = 0; !ret && i < sizeof(keys) / sizeof(keys[0]); i++) { ret = send_key(handle, (uint32_t)(keys[i])); } for (i = 0; !ret && i < strlen(vr->name); i++) { char c = toupper(vr->name[i]); if (isdigit(c)) { ret = send_key(handle, (uint32_t)(0x008e + c - '0')); } else { ret = send_key(handle, (uint32_t)(0x009a + c - 'A')); } } if (!ret) { ret = send_key(handle, 0x0005); // Enter } return ret; }
static int del_var (CalcHandle* handle, VarRequest* vr) { int ret; char *utf8; utf8 = ticonv_varname_to_utf8(handle->model, vr->name, vr->type); ticalcs_slprintf(handle->updat->text, sizeof(handle->updat->text), _("Deleting %s..."), utf8); ticonv_utf8_free(utf8); ticalcs_update_label(handle); ret = SEND_DEL(handle, (uint16_t)vr->size, vr->type, vr->name, vr->attr); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { ret = RECV_ACK(handle, NULL); } } return ret; }
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; }
// 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; }
static int get_dirlist (CalcHandle* handle, GNode** vars, GNode** apps) { int ret; uint16_t unused; TreeInfo *ti; GNode *folder, *node; char *utf8; ret = dirlist_init_trees(handle, vars, apps); if (ret) { return ret; } ti = (*vars)->data; ret = SEND_REQ(handle, 0x0000, (handle->model == CALC_TI83) ? TI83_DIR : TI86_DIR, "\0\0\0\0\0\0\0"); if (!ret) { ret = RECV_ACK(handle, &unused); if (!ret) { ret = RECV_XDP(handle, &unused, handle->buffer2); if (!ret) { ret = SEND_ACK(handle); } } } if (!ret) { VarEntry *ve; uint8_t * mem = (uint8_t *)handle->buffer2; folder = dirlist_create_append_node(NULL, vars); if (handle->model == CALC_TI83) { ti->mem_free = (((uint32_t)(mem[1])) << 8) | mem[0]; // Clamp mem_free to a 16-bit value. // Add permanent variables (Window, RclWindow, TblSet aka WINDW, ZSTO, TABLE) ve = tifiles_ve_create(); ve->type = TI83_WINDW; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI83_ZSTO; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI83_TABLE; node = dirlist_create_append_node(ve, &folder); } } } else { ti->mem_free = (((uint32_t)(mem[0])) << 16) | (((uint32_t)(mem[1])) << 8) | mem[2]; // Add permanent variables (Func, Pol, Param, DifEq, ZRCL as WIND, WIND, WIND, WIND, WIND) ve = tifiles_ve_create(); ve->type = TI86_FUNC; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI86_POL; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI86_PARAM; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI86_DIFEQ; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI86_ZRCL; node = dirlist_create_append_node(ve, &folder); } } } } } if (!node) { ret = ERR_MALLOC; } else { for (;;) { uint16_t ve_size; int ret2; ve = tifiles_ve_create(); ret = RECV_VAR(handle, &ve_size, &ve->type, ve->name); ve->size = ve_size; ret2 = SEND_ACK(handle); if (ret) { if (ret == ERR_EOT) // end of transmission { ret = 0; } error: tifiles_ve_delete(ve); break; } if (ret2) { ret = ret2; goto error; } node = dirlist_create_append_node(ve, &folder); if (!node) { return ERR_MALLOC; } utf8 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type); ticalcs_slprintf(update_->text, sizeof(update_->text), _("Parsing %s"), utf8); ticonv_utf8_free(utf8); update_label(); } } } return ret; }
static int get_dirlist (CalcHandle* handle, GNode** vars, GNode** apps) { int ret; TreeInfo *ti; GNode *folder, *root, *node; uint16_t unused; uint32_t memory; char *utf8; ret = dirlist_init_trees(handle, vars, apps); if (ret) { return ret; } ti = (*vars)->data; ret = SEND_REQ(handle, 0x0000, TI73_DIR, "\0\0\0\0\0\0\0", 0x00, 0x00); if (!ret) { ret = RECV_ACK(handle, &unused); if (!ret) { ret = RECV_XDP(handle, &unused, handle->buffer2); if (!ret) { ret = SEND_ACK(handle); if (!ret) { uint8_t * mem = (uint8_t *)handle->buffer2; memory = (((uint32_t)(mem[1])) << 8) | mem[0]; // Clamp mem_free to a 16-bit value. } } } } if (ret) { return ret; } ti->mem_free = memory; folder = dirlist_create_append_node(NULL, vars); if (!folder) { return ERR_MALLOC; } root = dirlist_create_append_node(NULL, apps); if (!root) { return ERR_MALLOC; } // Add permanent variables (Window, RclWindow, TblSet aka WINDW, ZSTO, TABLE) { VarEntry *ve; ve = tifiles_ve_create(); ve->type = TI84p_WINDW; node = dirlist_create_append_node(ve, &folder); if (node != NULL) { if (handle->model != CALC_TI73) { ve = tifiles_ve_create(); ve->type = TI84p_ZSTO; node = dirlist_create_append_node(ve, &folder); } if (node != NULL) { ve = tifiles_ve_create(); ve->type = TI84p_TABLE; node = dirlist_create_append_node(ve, &folder); } } } if (!node) { return ERR_MALLOC; } for (;;) { VarEntry *ve = tifiles_ve_create(); uint16_t ve_size; int ret2; ret = RECV_VAR(handle, &ve_size, &ve->type, ve->name, &ve->attr, &ve->version); ve->size = ve_size; ret2 = SEND_ACK(handle); if (ret) { if (ret == ERR_EOT) { ret = 0; } error: tifiles_ve_delete(ve); break; } if (ret2) { ret = ret2; goto error; } if (ve->type == TI73_APPL) { /* Size is reported as a number of pages -- compute amount of space consumed (the actual application may be somewhat smaller.) Note: the MSB of the "size" word is the application's starting page number. */ ve->size = (ve->size & 0xff) * 0x4000; } node = dirlist_create_append_node(ve, (ve->type != TI73_APPL) ? &folder : &root); if (!node) { return ERR_MALLOC; } utf8 = ticonv_varname_to_utf8(handle->model, ve->name, ve->type); ticalcs_slprintf(handle->updat->text, sizeof(handle->updat->text), _("Parsing %s"), utf8); ticonv_utf8_free(utf8); ticalcs_update_label(handle); } return ret; }
static int get_version (CalcHandle* handle, CalcInfos* infos) { int ret; uint16_t length; uint8_t buf[32]; ret = SEND_VER(handle); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { ret = SEND_CTS(handle); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { ret = RECV_XDP(handle, &length, buf); if (!ret) { ret = SEND_ACK(handle); } } } } } if (!ret) { memset(infos, 0, sizeof(CalcInfos)); if (handle->model == CALC_TI73) { ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1x.%02x", buf[0], buf[1]); ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1x.%02x", buf[2], buf[3]); } else { ticalcs_slprintf(infos->os_version, sizeof(infos->os_version), "%1i.%02i", buf[0], buf[1]); ticalcs_slprintf(infos->boot_version, sizeof(infos->boot_version), "%1i.%02i", buf[2], buf[3]); } infos->battery = (buf[4] & 1) ? 0 : 1; infos->hw_version = buf[5]; switch(buf[5]) { 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; case 5: infos->model = CALC_TI84PC; break; default: infos->model = CALC_TI84PC; break; // If new models ever arise, they'll probably be 84+CSE or newer anyway. } infos->language_id = buf[6]; infos->sub_lang_id = buf[7]; infos->mask = INFOS_BOOT_VERSION | INFOS_OS_VERSION | INFOS_BATTERY | INFOS_HW_VERSION | INFOS_CALC_MODEL | INFOS_LANG_ID | INFOS_SUB_LANG_ID; tifiles_hexdump(buf, length); ticalcs_info(_(" OS: %s"), infos->os_version); ticalcs_info(_(" BIOS: %s"), infos->boot_version); ticalcs_info(_(" HW: %i"), infos->hw_version); ticalcs_info(_(" Battery: %s"), infos->battery ? _("good") : _("low")); } return ret; }