/* Hey EMACS -*- linux-c -*- */ /* libcalcprotocols - link protocol library, a part of the CalcForge project * Copyright (C) 1999-2005 Romain Lievin * Copyright (C) 2006-2010 Kevin Kofler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "calcprotocols.h" #include "error.h" #include "logging.h" #include "gettext.h" /** * calcprotocols_calc_features: * @handle: a previously allocated handle * * Returns the features and operations supported by the hand-held. * * Return value: a mask of features (CalcFeatures). **/ CALCPROTOCOLS_EXPORT CalcFeatures CALCFORGE_CALL calcprotocols_calc_features(CalcHandle* handle) { const CalcFncts *calc; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; return calc->features; } /** * calcprotocols_calc_isready: * @handle: a previously allocated handle * * Check whether calc is ready. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_isready(CalcHandle* handle) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Checking hand-held status:")); handle->busy = 1; if(calc->is_ready) ret = calc->is_ready(handle); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_key: * @handle: a previously allocated handle * @key: a TI scancode * * Check whether calc is ready. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_key(CalcHandle* handle, uint16_t key) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending key %04x:"), key); handle->busy = 1; if(calc->send_key) ret = calc->send_key(handle, key); handle->busy = 0; return ret; } /** * calcprotocols_calc_execute: * @handle: a previously allocated handle * @ve: folder and variable name with type * @args: argument to pass to program (in TI-charset, aka native) * * Remotely execute a program or a FLASH application. * Restrictions: execution of FLASH applications is supported thru D-USB only. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_execute(CalcHandle* handle, VarEntry* ve, const char* args) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Executing %s/%s with %s:"), ve->folder, ve->name, args); handle->busy = 1; if(calc->execute) ret = calc->execute(handle, ve, args); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_screen: * @handle: a previously allocated handle * @sc: a structure which contains required screen format and returns screen sizes * @bitmap: adress of pointer for allocated bitmap. Must be freed when no longer needed. * * Request a screenshot and receive a raw B&W bitmap (1 bit per pixel). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_screen(CalcHandle* handle, CalcScreenCoord* sc, uint8_t** bitmap) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting screenshot:")); handle->busy = 1; if(calc->recv_screen) ret = calc->recv_screen(handle, sc, bitmap); handle->busy = 0; return ret; } /** * calcprotocols_calc_get_dirlist: * @handle: a previously allocated handle * @vars: a tree of folder & variables * @apps: a tree of FLASH apps * * Request a directory listing. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_get_dirlist(CalcHandle* handle, GNode** vars, GNode **apps) { const CalcFncts *calc; int ret = 0; TreeInfo *ti; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting folder & vars & apps listing:")); handle->busy = 1; if(calc->get_dirlist) ret = calc->get_dirlist(handle, vars, apps); ti = (*vars)->data; ti->mem_mask |= MEMORY_USED; ti->mem_used = calcprotocols_dirlist_ram_used(*vars); ti = (*apps)->data; ti->mem_mask |= MEMORY_USED; ti->mem_used = calcprotocols_dirlist_flash_used(*vars, *apps); handle->busy = 0; return ret; } /** * calcprotocols_calc_get_memfree: * @handle: a previously allocated handle * @ram: RAM memory available * @flash: FlashROM memory available * * Request free memory. Do a dirlist to update value. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_get_memfree(CalcHandle* handle, uint32_t* ram, uint32_t *flash) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting RAM & FLASH free")); handle->busy = 1; if(calc->get_memfree) ret = calc->get_memfree(handle, ram, flash); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_backup: * @handle: a previously allocated handle * @content: backup content * * Request a backup and receive it. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_backup(CalcHandle* handle, BackupContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting backup:")); handle->busy = 1; if(calc->recv_backup) ret = calc->recv_backup(handle, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_backup: * @handle: a previously allocated handle * @content: backup content * * Send a backup. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_backup(CalcHandle* handle, BackupContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending backup:")); handle->busy = 1; if(calc->send_backup) ret = calc->send_backup(handle, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_var: * @handle: a previously allocated handle * @mode: to document * @content: file content to send * * Send one or more variables (silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_var(CalcHandle* handle, CalcMode mode, FileContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending one or more variables:")); handle->busy = 1; if(calc->send_var) ret = calc->send_var(handle, mode, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_var: * @handle: a previously allocated handle * @mode: * @content: where to store variable content * @var: a #VarEntry structure got with dirlist * * Request receiving of _one_ variable (silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_var(CalcHandle* handle, CalcMode mode, FileContent* content, VarRequest* vr) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting variable '%s':"), vr->name); handle->busy = 1; if(calc->recv_var) ret = calc->recv_var(handle, mode, content, vr); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_var_ns: * @handle: a previously allocated handle * @mode: * @content: file content to send * * Send one or more variable (non-silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_var_ns(CalcHandle* handle, CalcMode mode, FileContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending variable (non-silent mode):")); handle->busy = 1; if(calc->send_var_ns) ret = calc->send_var_ns(handle, mode, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_var_ns: * @handle: a previously allocated handle * @mode: * @content: where to store variables * @var: informations on the received variable (if single) or NULL (if group) * * Receive one or more variable (non-silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_var_ns(CalcHandle* handle, CalcMode mode, FileContent* content, VarEntry** var) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Receiving variable (non-silent mode):")); handle->busy = 1; if(calc->recv_var_ns) ret = calc->recv_var_ns(handle, mode, content, var); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_app: * @handle: a previously allocated handle * @content: content to send * * Send a FLASH app. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_app(CalcHandle* handle, FlashContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending FLASH application:")); handle->busy = 1; if(calc->send_app) ret = calc->send_app(handle, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_app: * @handle: a previously allocated handle * @content: where to store content * @var: FLASH app to request * * Request receiving of a FLASH app. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_app(CalcHandle* handle, FlashContent* content, VarRequest* var) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting receiving of FLASH application:")); handle->busy = 1; if(calc->recv_app) ret = calc->recv_app(handle, content, var); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_os: * @handle: a previously allocated handle * @content: content to send * * Send a FLASH os. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_os(CalcHandle* handle, FlashContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending FLASH os:")); handle->busy = 1; if(calc->send_app) ret = calc->send_os(handle, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_idlist: * @handle: a previously allocated handle * @idlist: static buffer (32 chars) where to store ID-LIST * * Request ID-LIST of hand-held. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_idlist(CalcHandle* handle, uint8_t* idlist) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting ID-LIST:")); handle->busy = 1; if(calc->recv_idlist) ret = calc->recv_idlist(handle, idlist); handle->busy = 0; return ret; } /** * calcprotocols_calc_dump_rom_1: * @handle: a previously allocated handle * * Send a ROM dumping program to hand-held. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_dump_rom_1(CalcHandle* handle) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending ROM dumper:")); handle->busy = 1; if(calc->dump_rom_1) ret = calc->dump_rom_1(handle); handle->busy = 0; return ret; } /** * calcprotocols_calc_dump_rom_2: * @handle: a previously allocated handle * @size: optional size of dump * @filename: where to store the dump * * Start dumping (if possible). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_dump_rom_2(CalcHandle* handle, CalcDumpSize size, const char *filename) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Dumping ROM:")); handle->busy = 1; if(calc->dump_rom_2) ret = calc->dump_rom_2(handle, size, filename); handle->busy = 0; return ret; } /** * calcprotocols_calc_set_clock: * @handle: a previously allocated handle * @clock: a #CalcClock structure * * Set date & time of hand-held (if AMS >= 2.09). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_set_clock(CalcHandle* handle, CalcClock* clock) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Setting clock:")); handle->busy = 1; if(calc->set_clock) ret = calc->set_clock(handle, clock); handle->busy = 0; return ret; } /** * calcprotocols_calc_get_clock: * @handle: a previously allocated handle * @clock: a #CalcClock structure * * Get date & time of hand-held (if AMS >= 2.09). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_get_clock(CalcHandle* handle, CalcClock* clock) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Getting clock:")); handle->busy = 1; if(calc->get_clock) ret = calc->get_clock(handle, clock); handle->busy = 0; return ret; } /** * calcprotocols_calc_send_cert: * @handle: a previously allocated handle * @content: content to send * * Send a certificate. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_cert(CalcHandle* handle, FlashContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Sending certificate:")); handle->busy = 1; if(calc->send_cert) ret = calc->send_cert(handle, content); handle->busy = 0; return ret; } /** * calcprotocols_calc_recv_cert: * @handle: a previously allocated handle * @content: where to store content * * Request receiving of a FLASH app. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_cert(CalcHandle* handle, FlashContent* content) { const CalcFncts *calc; int ret = 0; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting receiving of certificate:")); handle->busy = 1; if(calc->recv_cert) ret = calc->recv_cert(handle, content); handle->busy = 0; return ret; } // --- /** * calcprotocols_calc_recv_backup2: * @handle: a previously allocated handle * @filename: name of file where to store backup * * Request a backup and receive it to file. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_backup2(CalcHandle* handle, const char *filename) { BackupContent *content1; FileContent *content2; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; if(calcprotocols_calc_features(handle) & FTS_BACKUP) { // true backup capability content1 = calcfiles_content_create_backup(handle->model); TRYF(calcprotocols_calc_recv_backup(handle, content1)); TRYF(calcfiles_file_write_backup(filename, content1)); TRYF(calcfiles_content_delete_backup(content1)); } else { // pseudo-backup content2 = calcfiles_content_create_regular(handle->model); TRYF(calcprotocols_calc_recv_backup(handle, (BackupContent *)content2)); TRYF(calcfiles_file_write_regular(filename, content2, NULL)); TRYF(calcfiles_content_delete_regular(content2)); } return 0; } /** * calcprotocols_calc_send_backup2: * @handle: a previously allocated handle * @filename: name of file which contains backup to send * * Send a backup from file. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_backup2(CalcHandle* handle, const char* filename) { BackupContent *content1; FileContent *content2; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; if(calcprotocols_calc_features(handle) & FTS_BACKUP) { // true backup capability content1 = calcfiles_content_create_backup(handle->model); TRYF(calcfiles_file_read_backup(filename, content1)); TRYF(calcprotocols_calc_send_backup(handle, content1)); TRYF(calcfiles_content_delete_backup(content1)); } else { // pseudo-backup content2 = calcfiles_content_create_regular(handle->model); TRYF(calcfiles_file_read_regular(filename, content2)); TRYF(calcprotocols_calc_send_backup(handle, (BackupContent *)content2)); TRYF(calcfiles_content_delete_regular(content2)); } return 0; } /** * calcprotocols_calc_send_var2: * @handle: a previously allocated handle * @mode: to document * @filename: name of file * * Send one or more variables (silent mode) from file. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_var2(CalcHandle* handle, CalcMode mode, const char* filename) { FileContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_regular(handle->model); TRYF(calcfiles_file_read_regular(filename, content)); TRYF(calcprotocols_calc_send_var(handle, mode, content)); TRYF(calcfiles_content_delete_regular(content)); return 0; } /** * calcprotocols_calc_recv_var2: * @handle: a previously allocated handle * @mode: * @content: where to store variable content * @var: a #VarEntry structure got with dirlist * * Request receiving of _one_ variable (silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_var2(CalcHandle* handle, CalcMode mode, const char* filename, VarRequest* vr) { FileContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_regular(handle->model); TRYF(calcprotocols_calc_recv_var(handle, mode, content, vr)); TRYF(calcfiles_file_write_regular(filename, content, NULL)); TRYF(calcfiles_content_delete_regular(content)); return 0; } /** * calcprotocols_calc_send_var_ns2: * @handle: a previously allocated handle * @mode: * @filename: name of file * * Send one or more variable (non-silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_var_ns2(CalcHandle* handle, CalcMode mode, const char* filename) { FileContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_regular(handle->model); TRYF(calcfiles_file_read_regular(filename, content)); TRYF(calcprotocols_calc_send_var_ns(handle, mode, content)); TRYF(calcfiles_content_delete_regular(content)); return 0; } /** * calcprotocols_calc_recv_var_ns2: * @handle: a previously allocated handle * @mode: * @filename: where to store variables * @var: informations on the received variable (if single) or NULL (if group) * * Receive one or more variable (non-silent mode). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_var_ns2(CalcHandle* handle, CalcMode mode, const char* filename, VarEntry** vr) { FileContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_regular(handle->model); TRYF(calcprotocols_calc_recv_var_ns(handle, mode, content, vr)); TRYF(calcfiles_file_write_regular(filename, content, NULL)); TRYF(calcfiles_content_delete_regular(content)); return 0; } /** * calcprotocols_calc_send_app2: * @handle: a previously allocated handle * @filename: name of file * * Send a FLASH app or os. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_app2(CalcHandle* handle, const char* filename) { FlashContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_flash(handle->model); TRYF(calcfiles_file_read_flash(filename, content)); TRYF(calcprotocols_calc_send_app(handle, content)); TRYF(calcfiles_content_delete_flash(content)); return 0; } /** * calcprotocols_calc_recv_app2: * @handle: a previously allocated handle * @content: where to store content * @var: FLASH app to request * * Request receiving of a FLASH app. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_app2(CalcHandle* handle, const char* filename, VarRequest* vr) { FlashContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_flash(handle->model); TRYF(calcprotocols_calc_recv_app(handle, content, vr)); TRYF(calcfiles_file_write_flash(filename, content)); TRYF(calcfiles_content_delete_flash(content)); return 0; } /** * calcprotocols_calc_new_fld: * @handle: a previously allocated handle * @vr: name of folder to create (vr->folder) * * Request creation of a folder. Beware: %vr.name may be modified ! * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_new_fld(CalcHandle* handle, VarRequest* vr) { const CalcFncts *calc; int ret; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Creating folder '%s':"), vr->folder); handle->busy = 1; ret = calc->new_fld(handle, vr); handle->busy = 0; return ret; } /** * calcprotocols_calc_del_var: * @handle: a previously allocated handle * @var: var to delete * * Request deleting of a variable (if possible ??). * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_del_var(CalcHandle* handle, VarRequest* vr) { const CalcFncts *calc; int ret; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Deleting variable '%s':"), vr->name); handle->busy = 1; ret = calc->del_var(handle, vr); handle->busy = 0; return ret; } /** * calcprotocols_calc_get_version: * @handle: a previously allocated handle * @infos: where to store version information * * Request version info. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_get_version(CalcHandle* handle, CalcInfos* infos) { const CalcFncts *calc; int ret; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; //if(!handle->attached) // return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Requesting version infos:")); handle->busy = 1; ret = calc->get_version(handle, infos); handle->busy = 0; return ret; } int nspire_copy_var(CalcHandle* handle, VarRequest* vr, VarRequest* newvr); /** * calcprotocols_calc_copy_var: * @handle: a previously allocated handle * @vr: var to copy * @newvr: new name for the copied var * * Request copying a variable. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_copy_var(CalcHandle* handle, VarRequest* vr, VarRequest* newvr) { const CalcFncts *calc; int ret; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if (calc->model == CALC_NSPIRE) { // Nspire / NSpire CAS, use the copy command if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Copying variable '%s' to '%s':"), vr->name, newvr->name); handle->busy = 1; ret = nspire_copy_var(handle, vr, newvr); handle->busy = 0; } else { // Client-side copy FileContent *content = calcfiles_content_create_regular(handle->model); ret = calcprotocols_calc_recv_var(handle, MODE_NORMAL, content, vr); if (!ret && content->num_entries) { VarEntry *ve = content->entries[0]; strcpy(ve->folder, newvr->folder); strcpy(ve->name, newvr->name); ret = calcprotocols_calc_send_var(handle, MODE_NORMAL, content); } calcfiles_content_delete_regular(content); } return ret; } int nspire_get_attributes(CalcHandle* handle, VarRequest* vr, uint32_t *size, uint32_t *date, uint8_t *type); /** * calcprotocols_calc_nspire_get_attributes: * @handle: a previously allocated handle for an Nspire family calculator * @vr: var or folder to get the attributes for * @size: pointer to store the file size in (0 for a directory) or NULL * @date: pointer to store the file date in the calc's internal format in or NULL * @type: pointer to store NSP_TNS for a file or NSP_DIR for a folder in or NULL * * Get the attributes of a file or directory on the TI-Nspire or TI-Nspire CAS. * If the file or directory does not exist, an error occurs. Note that the type * stored into the pointer will never be NSP_OTHER, it will be NSP_TNS * regardless of the file's extension. In most cases, you already know the type * and thus can just pass NULL. * * Note that this function may become deprecated in the future in favor of * higher-level APIs. * * Return value: 0 if successful, an error code otherwise. In particular, * ERR_VOID_FUNCTION when used on a non-Nspire handle. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_nspire_get_attributes(CalcHandle* handle, VarRequest* vr, uint32_t *size, uint32_t *date, uint8_t *type) { const CalcFncts *calc; int ret; if(handle == NULL) return ERR_INVALID_HANDLE; calc = handle->calc; if (calc->model == CALC_NSPIRE) { if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; calcprotocols_info(_("Getting attributes of '%s/%s':"), vr->folder, vr->name); handle->busy = 1; ret = nspire_get_attributes(handle, vr, size, date, type); handle->busy = 0; } else return ERR_VOID_FUNCTION; return ret; } /** * calcprotocols_calc_send_cert2: * @handle: a previously allocated handle * @filename: name of file * * Send a certificate. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_cert2(CalcHandle* handle, const char* filename) { FlashContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_flash(handle->model); TRYF(calcfiles_file_read_flash(filename, content)); TRYF(calcprotocols_calc_send_cert(handle, content)); TRYF(calcfiles_content_delete_flash(content)); return 0; } /** * calcprotocols_calc_recv_cert2: * @handle: a previously allocated handle * @content: where to store content * @var: FLASH app to request * * Request certificate. Depending on extension, saves it as *.9Xq or *.cer. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_cert2(CalcHandle* handle, const char* filename) { FlashContent *content; char *ext = calcfiles_fext_get(filename); if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; if(!strcmp(ext, "cer")) { // .cer format as generated by SDK gchar *basename = g_strdup(filename); FILE *f; gchar *e = calcfiles_fext_get(basename); int err; memcpy(e, "crt", 3); content = calcfiles_content_create_flash(handle->model); if ((err = calcprotocols_calc_recv_cert(handle, content))) { g_free(basename); return err; } f = fopen(basename, "wb"); g_free(basename); if (!f) return ERR_SAVE_FILE; if (fwrite(content->data_part, content->data_length, 1, f) < 1) { fclose(f); return ERR_SAVE_FILE; } if (fclose(f)) return ERR_SAVE_FILE; TRYF(calcfiles_content_delete_flash(content)); } else { // .??q format as generated by TI content = calcfiles_content_create_flash(handle->model); TRYF(calcprotocols_calc_recv_cert(handle, content)); TRYF(calcfiles_file_write_flash(filename, content)); TRYF(calcfiles_content_delete_flash(content)); } return 0; } /** * calcprotocols_calc_send_os2: * @handle: a previously allocated handle * @filename: name of file * * Send a FLASH app. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_os2(CalcHandle* handle, const char* filename) { FlashContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_flash(handle->model); TRYF(calcfiles_file_read_flash(filename, content)); TRYF(calcprotocols_calc_send_os(handle, content)); TRYF(calcfiles_content_delete_flash(content)); return 0; } /** * calcprotocols_calc_send_tigroup2: * @handle: a previously allocated handle * @filename: name of file * @mode: which vars/apps to send * * Send a TiGroup file. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_send_tigroup2(CalcHandle* handle, const char* filename, TigMode mode) { TigContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_tigroup(handle->model, 0); TRYF(calcfiles_file_read_tigroup(filename, content)); TRYF(calcprotocols_calc_send_tigroup(handle, content, mode)); TRYF(calcfiles_content_delete_tigroup(content)); return 0; } /** * calcprotocols_calc_recv_tigroup2: * @handle: a previously allocated handle * @filename: name of file * @mode: which vars/apps to receive * * Receive a TiGroup file. * * Return value: 0 if successful, an error code otherwise. **/ CALCPROTOCOLS_EXPORT int CALCFORGE_CALL calcprotocols_calc_recv_tigroup2(CalcHandle* handle, const char* filename, TigMode mode) { TigContent *content; if(!handle->attached) return ERR_NO_CABLE; if(!handle->open) return ERR_NO_CABLE; if(handle->busy) return ERR_BUSY; content = calcfiles_content_create_tigroup(handle->model, 0); TRYF(calcprotocols_calc_recv_tigroup(handle, content, mode)); TRYF(calcfiles_file_write_tigroup(filename, content)); TRYF(calcfiles_content_delete_tigroup(content)); return 0; }