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; }
static int send_var_8386 (CalcHandle* handle, CalcMode mode, FileContent* content) { int ret = 0; unsigned int i; uint8_t rej_code; uint16_t status; update_->cnt2 = 0; update_->max2 = content->num_entries; for (i = 0; !ret && 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_RTS(handle, size, entry->type, entry->name); if (!ret) { ret = RECV_ACK(handle, &status); if (!ret) { ret = RECV_SKP(handle, &rej_code); if (!ret) { ret = SEND_ACK(handle); } } } if (ret) { break; } switch (rej_code) { case DBUS_REJ_EXIT: ret = ERR_ABORT; break; case DBUS_REJ_SKIP: 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) { ret = SEND_EOT(handle); if (!ret) { ticalcs_info("Sent variable #%u", i); update_->cnt2 = i+1; update_->max2 = content->num_entries; update_->pbar(); } } } } return ret; }
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; }
static int send_flash (CalcHandle* handle, FlashContent* content) { int ret; FlashContent *ptr; unsigned int i, j; uint16_t size; int cpu15mhz = 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) { size = 0x100; } else if (ptr->data_type == TI83p_APPL) { size = 0x80; } else { return -1; } // check for 83+ Silver Edition (not usable in boot mode, sic!) if (handle->model != CALC_TI73 && ptr->data_type == TI83p_APPL) { CalcInfos infos; ret = get_version(handle, &infos); if (ret) { return ret; } cpu15mhz = infos.hw_version & 1; if (!infos.battery) { ticalcs_info(_("Battery low, stopping flash app transfer")); return -1; } } ticalcs_info(_("FLASH name: \"%s\""), ptr->name); ticalcs_info(_("FLASH size: %i bytes."), ptr->data_length); ticonv_varname_to_utf8_sn(handle->model, ptr->name, handle->updat->text, sizeof(handle->updat->text), ptr->data_type); ticalcs_update_label(handle); handle->updat->cnt2 = 0; handle->updat->max2 = ptr->data_length; for (i = 0; !ret && i < ptr->num_pages; i++) { FlashPage *fp = ptr->pages[i]; if ((ptr->data_type == TI83p_AMS) && (i == 1)) // need relocation ? { fp->addr = 0x4000; } for (j = 0; !ret && j < fp->size; j += size) { uint16_t addr = fp->addr + j; uint8_t* data = fp->data + j; ret = SEND_VAR2(handle, size, ptr->data_type, fp->flag, addr, fp->page); if (!ret) { ret = RECV_ACK(handle, NULL); } if (ret) { break; } if (handle->model == CALC_TI73 && ptr->data_type == TI83p_APPL) { ret = RECV_CTS(handle, 0); } // Depends on OS version? else { ret = RECV_CTS(handle, 10); } if (!ret) { ret = SEND_ACK(handle); if (!ret) { ret = SEND_XDP(handle, size, data); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { handle->updat->cnt2 += size; ticalcs_update_pbar(handle); } } } } } /* Note: TI83+SE, TI84+ and TI84+SE don't need a pause (otherwise transfer fails). TI73 and TI83+ need a pause (otherwise transfer fails). Delay also causes OS transfers to fail on the 15Mhz calcs and unneeded for OS's */ if (!ret && !cpu15mhz && ptr->data_type == TI83p_APPL) { if (i == 1) { PAUSE(1000); // This pause is NEEDED ! } if (i == ptr->num_pages - 2) { PAUSE(2500); // This pause is NEEDED ! } } } if (!ret) { ret = SEND_EOT(handle); if (!ret) { ret = RECV_ACK(handle, NULL); } } return ret; }
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(content->mem_address); varname[5] = MSB(content->mem_address); varname[6] = 0; varname[7] = 0; varname[8] = 0; do { ret = SEND_RTS(handle, content->data_length1, TI73_BKUP, varname, 0x00, content->version); if (!ret) { ret = RECV_ACK(handle, &status); if (!ret) { ret = RECV_SKP(handle, &rej_code); if (!ret) { ret = SEND_ACK(handle); } } } if (!ret) { switch (rej_code) { case DBUS_REJ_EXIT: case DBUS_REJ_SKIP: return ERR_ABORT; case DBUS_REJ_MEMORY: return ERR_OUT_OF_MEMORY; case DBUS_REJ_VERSION: return ERR_VAR_VERSION; case 0: // CTS break; default: return ERR_VAR_REJECTED; } handle->updat->cnt2 = 0; handle->updat->max2 = 3; ticalcs_update_pbar(handle); ret = SEND_XDP(handle, content->data_length1, content->data_part1); if (!ret) { ret = RECV_ACK(handle, &status); } if (ret) { break; } handle->updat->cnt2++; ticalcs_update_pbar(handle); ret = SEND_XDP(handle, content->data_length2, content->data_part2); if (!ret) { ret = RECV_ACK(handle, &status); } if (ret) { break; } handle->updat->cnt2++; ticalcs_update_pbar(handle); ret = SEND_XDP(handle, content->data_length3, content->data_part3); if (!ret) { ret = RECV_ACK(handle, &status); } if (ret) { break; } handle->updat->cnt2++; ticalcs_update_pbar(handle); ret = SEND_ACK(handle); } } while(0); return ret; }
static int send_cert (CalcHandle* handle, FlashContent* content) { int ret = 0; FlashContent *ptr; int i, nblocks; uint16_t size = 0xE8; // search for cert header for (ptr = content; ptr != NULL; ptr = ptr->next) { if (ptr->data_type == TI83p_CERT) { break; } } if (ptr != NULL) { // send content ticalcs_info(_("FLASH name: \"%s\""), ptr->name); ticalcs_info(_("FLASH size: %i bytes."), ptr->data_length); nblocks = ptr->data_length / size; handle->updat->max2 = nblocks; ret = SEND_VAR2(handle, size, ptr->data_type, 0x04, 0x4000, 0x00); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { ret = RECV_CTS(handle, 10); if (!ret) { ret = SEND_ACK(handle); } } } for (i = 0; !ret && i <= nblocks; i++) { uint16_t length = size; ret = SEND_XDP(handle, length, (ptr->data_part) + length * i); if (!ret) { ret = RECV_ACK(handle, NULL); if (!ret) { ret = RECV_CTS(handle, size); if (!ret) { ret = SEND_ACK(handle); if (!ret) { handle->updat->cnt2 = i; ticalcs_update_pbar(handle); } } } } } if (!ret) { ret = SEND_EOT(handle); ticalcs_info(_("Header sent completely.")); } } return ret; }
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; }