From a069989ec7a22b1aba12106174f05e4adbf90e2f Mon Sep 17 00:00:00 2001 From: Lionel Debroux Date: Wed, 5 Jun 2019 23:18:17 +0200 Subject: [PATCH] WIP libticalcs: start building the Nspire CX II / NWB protocol support code, from RE work by myself and Fabian "Vogtinator" Vogt. TODO commit message. Signed-off-by: Lionel Debroux --- libticalcs/trunk/CMakeLists.txt | 6 + libticalcs/trunk/src/Makefile.am | 5 +- libticalcs/trunk/src/dbus_pkt.cc | 6 +- libticalcs/trunk/src/dbus_pkt.h | 6 +- libticalcs/trunk/src/dusb_cmd.cc | 6 +- libticalcs/trunk/src/dusb_cmd.h | 6 +- libticalcs/trunk/src/dusb_rpkt.cc | 6 +- libticalcs/trunk/src/dusb_rpkt.h | 6 +- libticalcs/trunk/src/dusb_vpkt.cc | 8 +- libticalcs/trunk/src/dusb_vpkt.h | 6 +- libticalcs/trunk/src/internal.h | 31 +- libticalcs/trunk/src/nnse_cmd.cc | 1074 +++++++++++++++++ libticalcs/trunk/src/nnse_cmd.h | 123 ++ libticalcs/trunk/src/nnse_rpkt.cc | 415 +++++++ libticalcs/trunk/src/nnse_rpkt.h | 41 + libticalcs/trunk/src/nnse_vpkt.cc | 211 ++++ libticalcs/trunk/src/nnse_vpkt.h | 60 + libticalcs/trunk/src/nsp_cmd.h | 8 +- libticalcs/trunk/src/nsp_rpkt.cc | 45 +- libticalcs/trunk/src/nsp_rpkt.h | 8 +- libticalcs/trunk/src/nsp_vpkt.cc | 11 +- libticalcs/trunk/src/nsp_vpkt.h | 9 +- libticalcs/trunk/src/ticalcs.cc | 21 +- libticalcs/trunk/src/ticalcs.h | 135 ++- ...itial_nspire_communication_through_raw.txt | 18 + libticalcs/trunk/tests/test_ticalcs_2.cc | 63 +- libticalcs/trunk/tests/torture_ticalcs.c | 137 ++- 27 files changed, 2377 insertions(+), 94 deletions(-) create mode 100644 libticalcs/trunk/src/nnse_cmd.cc create mode 100644 libticalcs/trunk/src/nnse_cmd.h create mode 100644 libticalcs/trunk/src/nnse_rpkt.cc create mode 100644 libticalcs/trunk/src/nnse_rpkt.h create mode 100644 libticalcs/trunk/src/nnse_vpkt.cc create mode 100644 libticalcs/trunk/src/nnse_vpkt.h create mode 100644 libticalcs/trunk/tests/input_nnse_initial_nspire_communication_through_raw.txt diff --git a/libticalcs/trunk/CMakeLists.txt b/libticalcs/trunk/CMakeLists.txt index d6acb4fd8..3c271aab9 100644 --- a/libticalcs/trunk/CMakeLists.txt +++ b/libticalcs/trunk/CMakeLists.txt @@ -32,6 +32,9 @@ set(SRC_FILES src/keys86.cc src/keys89.cc src/keys92p.cc + src/nnse_cmd.cc + src/nnse_rpkt.cc + src/nnse_vpkt.cc src/nsp_cmd.cc src/nsp_rpkt.cc src/nsp_vpkt.cc @@ -56,6 +59,9 @@ set(PUBLIC_HEADERS src/dusb_rpkt.h src/dusb_vpkt.h src/dusb_cmd.h + src/nnse_rpkt.h + src/nnse_vpkt.h + src/nnse_cmd.h src/nsp_rpkt.h src/nsp_vpkt.h src/nsp_cmd.h diff --git a/libticalcs/trunk/src/Makefile.am b/libticalcs/trunk/src/Makefile.am index f952e68db..768d7af47 100644 --- a/libticalcs/trunk/src/Makefile.am +++ b/libticalcs/trunk/src/Makefile.am @@ -11,7 +11,7 @@ libticalcsinclude_HEADERS = \ ticalcs.h export3.h \ keys73.h keys83.h keys83p.h keys86.h keys89.h keys92p.h \ dbus_pkt.h dusb_rpkt.h dusb_vpkt.h dusb_cmd.h nsp_rpkt.h nsp_vpkt.h nsp_cmd.h \ - cmdz80.h cmd68k.h calclabequipmentdata.h + nnse_rpkt.h nnse_vpkt.h nnse_cmd.h cmdz80.h cmd68k.h calclabequipmentdata.h # build instructions libticalcs2_la_CPPFLAGS = -I$(top_srcdir)/intl \ @@ -28,13 +28,14 @@ libticalcs2_la_SOURCES = *.h \ calc_nsp.cc \ calclabequipmentdata.cc \ clock.cc \ - cmdz80.cc cmd68k.cc dusb_cmd.cc nsp_cmd.cc \ + cmdz80.cc cmd68k.cc dusb_cmd.cc nsp_cmd.cc nnse_cmd.cc \ dirlist.cc \ error.cc \ keys73.cc keys83.cc keys83p.cc keys86.cc keys89.cc keys92p.cc \ dbus_pkt.cc \ dusb_rpkt.cc dusb_vpkt.cc \ nsp_rpkt.cc nsp_vpkt.cc \ + nnse_rpkt.cc nnse_vpkt.cc \ probe.cc \ romdump.cc \ screen.cc \ diff --git a/libticalcs/trunk/src/dbus_pkt.cc b/libticalcs/trunk/src/dbus_pkt.cc index 84b93edaa..ab7bb331a 100644 --- a/libticalcs/trunk/src/dbus_pkt.cc +++ b/libticalcs/trunk/src/dbus_pkt.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id$ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 1999-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dbus_pkt.h b/libticalcs/trunk/src/dbus_pkt.h index b8503c335..263757e9a 100644 --- a/libticalcs/trunk/src/dbus_pkt.h +++ b/libticalcs/trunk/src/dbus_pkt.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: packets.h 1179 2005-06-06 14:42:32Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 1999-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dusb_cmd.cc b/libticalcs/trunk/src/dusb_cmd.cc index fa5fc3ead..cb9ef0fbc 100644 --- a/libticalcs/trunk/src/dusb_cmd.cc +++ b/libticalcs/trunk/src/dusb_cmd.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.c 2077 2006-03-31 21:16:19Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dusb_cmd.h b/libticalcs/trunk/src/dusb_cmd.h index 090c71958..502aca243 100644 --- a/libticalcs/trunk/src/dusb_cmd.h +++ b/libticalcs/trunk/src/dusb_cmd.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.h 2074 2006-03-31 08:36:06Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dusb_rpkt.cc b/libticalcs/trunk/src/dusb_rpkt.cc index 1e9164d9e..160aa9d78 100644 --- a/libticalcs/trunk/src/dusb_rpkt.cc +++ b/libticalcs/trunk/src/dusb_rpkt.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: packets.c 1404 2005-07-20 20:39:39Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dusb_rpkt.h b/libticalcs/trunk/src/dusb_rpkt.h index 0c106ee07..a44efb52a 100644 --- a/libticalcs/trunk/src/dusb_rpkt.h +++ b/libticalcs/trunk/src/dusb_rpkt.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: packets.h 1179 2005-06-06 14:42:32Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/dusb_vpkt.cc b/libticalcs/trunk/src/dusb_vpkt.cc index 3bd9cd028..0530bf659 100644 --- a/libticalcs/trunk/src/dusb_vpkt.cc +++ b/libticalcs/trunk/src/dusb_vpkt.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.c 2077 2006-03-31 21:16:19Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -100,7 +100,7 @@ TIEXPORT3 DUSBVirtualPacket* TICALL dusb_vtl_pkt_new_ex(CalcHandle * handle, uin if (ticalcs_validate_handle(handle)) { - vtl = (DUSBVirtualPacket *)g_malloc0(sizeof(DUSBVirtualPacket)); + vtl = (DUSBVirtualPacket *)g_malloc0(sizeof(*vtl)); if (NULL != vtl) { diff --git a/libticalcs/trunk/src/dusb_vpkt.h b/libticalcs/trunk/src/dusb_vpkt.h index ec297ec73..5465736a7 100644 --- a/libticalcs/trunk/src/dusb_vpkt.h +++ b/libticalcs/trunk/src/dusb_vpkt.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.h 2074 2006-03-31 08:36:06Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2004-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 diff --git a/libticalcs/trunk/src/internal.h b/libticalcs/trunk/src/internal.h index a6ad67d35..17dbdaeee 100644 --- a/libticalcs/trunk/src/internal.h +++ b/libticalcs/trunk/src/internal.h @@ -1,6 +1,6 @@ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2012 Romain Liévin - * Copyright (C) 2012 Lionel Debroux +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 1999-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -325,7 +325,7 @@ static inline void ticalcs_event_fill_dusb_vpkt(CalcEventData * event, uint32_t event->data.dusb_vpkt.data = data; } -static inline void ticalcs_event_fill_nsp_rpkt(CalcEventData * event, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint16_t data_sum, uint8_t data_size, uint8_t ack, uint8_t seq, uint8_t hdr_sum, uint8_t * data) +static inline void ticalcs_event_fill_nsp_rpkt(CalcEventData * event, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint16_t data_sum, uint32_t data_size, uint8_t ack, uint8_t seq, uint8_t hdr_sum, uint8_t * data) { event->data.nsp_rpkt.src_addr = src_addr; event->data.nsp_rpkt.src_port = src_port; @@ -339,6 +339,20 @@ static inline void ticalcs_event_fill_nsp_rpkt(CalcEventData * event, uint16_t s event->data.nsp_rpkt.data = data; } +static inline void ticalcs_event_fill_nnse_rpkt(CalcEventData * event, uint8_t unused1, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint8_t unknown2, uint8_t req_ack, uint16_t size, uint16_t seq, uint16_t csum, uint8_t * data) +{ + event->data.nnse_rpkt.unused1 = unused1; + event->data.nnse_rpkt.service = service; + event->data.nnse_rpkt.src_addr = src_addr; + event->data.nnse_rpkt.dst_addr = dst_addr; + event->data.nnse_rpkt.unknown2 = unknown2; + event->data.nnse_rpkt.req_ack = req_ack; + event->data.nnse_rpkt.size = size; + event->data.nnse_rpkt.seq = seq; + event->data.nnse_rpkt.csum = csum; + event->data.nnse_rpkt.data = data; +} + static inline void ticalcs_event_fill_nsp_vpkt(CalcEventData * event, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint32_t size, uint8_t * data) { event->data.nsp_vpkt.src_addr = src_addr; @@ -350,6 +364,15 @@ static inline void ticalcs_event_fill_nsp_vpkt(CalcEventData * event, uint16_t s event->data.nsp_vpkt.data = data; } +static inline void ticalcs_event_fill_nnse_vpkt(CalcEventData * event, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint32_t size, uint8_t * data) +{ + event->data.nnse_vpkt.service = service; + event->data.nnse_vpkt.src_addr = src_addr; + event->data.nnse_vpkt.dst_addr = dst_addr; + event->data.nnse_vpkt.size = size; + event->data.nnse_vpkt.data = data; +} + static inline void ticalcs_event_fill_romdump_pkt(CalcEventData * event, uint16_t length, uint16_t cmd, uint8_t * data) { event->data.romdump_pkt.length = length; diff --git a/libticalcs/trunk/src/nnse_cmd.cc b/libticalcs/trunk/src/nnse_cmd.cc new file mode 100644 index 000000000..cf636070e --- /dev/null +++ b/libticalcs/trunk/src/nnse_cmd.cc @@ -0,0 +1,1074 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + This unit handles commands and session management thru DirectLink. +*/ + +#include +#include +#include + +#include "ticalcs.h" +#include "internal.h" +#include "logging.h" +#include "error.h" + +#include "nnse_vpkt.h" +#include "nnse_cmd.h" + +/////////////---------------- + +/*static const uint8_t usb_errors[] = { + +}; + +static int err_code(uint8_t code) +{ + int i; + + for (i = 0; i < (int)(sizeof(usb_errors) / sizeof(usb_errors[0])); i++) + { + if (usb_errors[i] == code) + { + return i+1; + } + } + + ticalcs_warning("NNSE error code 0x%02x not found in list. Please report it at .", (int)code); + + return 0; +}*/ + +/////////////---------------- + + + +/////////////---------------- +#if 0 +TIEXPORT3 int TICALL nsp_cmd_r_login(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving login:"); + + retval = nsp_recv_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_status(CalcHandle *handle, uint8_t status) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 1, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, handle->priv.nsp_dst_port, NSP_CMD_STATUS, (uint8_t *)nsp_vtl_pkt_alloc_data(1)); + + ticalcs_info(" sending status (%04x):", status); + + pkt->data[0] = status; + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_status(CalcHandle *handle, uint8_t *status) +{ + NSPVirtualPacket* pkt; + uint8_t value; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving status:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + value = pkt->data[0]; + + if (pkt->cmd != NSP_CMD_STATUS) + { + retval = ERR_INVALID_PACKET; + goto end; + } + + if (status) + { + *status = value; + } + + if (value != 0x00) + { + retval = ERR_CALC_ERROR3 + err_code(value); + } + } + +end: + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_dev_infos(CalcHandle *handle, uint8_t cmd) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + ticalcs_info(" requesting device information (cmd = %02x):", cmd); + + pkt = nsp_vtl_pkt_new_ex(handle, 0, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_DEV_INFOS, cmd, (uint8_t *)nsp_vtl_pkt_alloc_data(0)); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_dev_infos(CalcHandle *handle, uint8_t *cmd, uint32_t *size, uint8_t **data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(cmd); + VALIDATE_NONNULL(size); + VALIDATE_NONNULL(data); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving device information:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + *cmd = pkt->cmd; + *data = (uint8_t *)g_malloc0(pkt->size); + if (NULL != *data) + { + memcpy(*data, pkt->data, pkt->size); + } + else + { + retval = ERR_MALLOC; + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_screen_rle(CalcHandle *handle, uint8_t cmd) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 0, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_SCREEN_RLE, cmd, (uint8_t *)nsp_vtl_pkt_alloc_data(0)); + + ticalcs_info(" requesting RLE screenshot (cmd = %02x):", cmd); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_screen_rle(CalcHandle *handle, uint8_t *cmd, uint32_t *size, uint8_t **data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(cmd); + VALIDATE_NONNULL(size); + VALIDATE_NONNULL(data); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving RLE screenshot:"); + + pkt->size = *size; + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + *cmd = pkt->cmd; + *size = pkt->size; + *data = (uint8_t *)g_malloc0(pkt->size); + if (NULL != *data) + { + memcpy(*data, pkt->data, pkt->size); + } + else + { + retval = ERR_MALLOC; + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_dir_attributes(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + pkt = nsp_vtl_pkt_new_ex(handle, 1 + len + 1, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_ATTRIBUTES, (uint8_t *)nsp_vtl_pkt_alloc_data(1 + len + 1)); + + ticalcs_info(" unknown directory list command in <%s>:", name); + + pkt->data[0] = 0x01; + put_str(pkt->data + 1, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_dir_attributes(CalcHandle *handle, uint32_t *size, uint8_t *type, uint32_t *date) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" unknown directory list command reply received:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + if (pkt->cmd != NSP_CMD_FM_ATTRIBUTES) + { + retval = ERR_CALC_ERROR3 + err_code(pkt->data[0]); + goto end; + } + + if (size) + { + *size = ( (((uint32_t)pkt->data[0]) << 24) + | (((uint32_t)pkt->data[1]) << 16) + | (((uint32_t)pkt->data[2]) << 8) + | (((uint32_t)pkt->data[3]) )); + } + if (date) + { + *date = ( (((uint32_t)pkt->data[4]) << 24) + | (((uint32_t)pkt->data[5]) << 16) + | (((uint32_t)pkt->data[6]) << 8) + | (((uint32_t)pkt->data[7]) )); + } + if (type) + { + *type = *(pkt->data + 8); + } + } + +end: + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_dir_enum_init(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + + pkt = nsp_vtl_pkt_new_ex(handle, len + 1, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_DIRLIST_INIT, (uint8_t *)nsp_vtl_pkt_alloc_data(len + 1)); + + ticalcs_info(" initiating directory listing in <%s>:", name); + + put_str(pkt->data, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_dir_enum_init(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_dir_enum_next(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 0, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_DIRLIST_NEXT, (uint8_t *)nsp_vtl_pkt_alloc_data(0)); + if (pkt != NULL) + { + ticalcs_info(" requesting next directory entry:"); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + } + else + { + retval = ERR_MALLOC; + } + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_dir_enum_next(CalcHandle *handle, char* name, uint32_t *size, uint8_t *type) +{ + NSPVirtualPacket* pkt; + uint8_t data_size; + //uint32_t date; + int o; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" next directory entry:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + if (pkt->cmd != NSP_CMD_FM_DIRLIST_ENT) + { + if (pkt->data[0] == NSP_ERR_NO_MORE_TO_LIST) + { + retval = ERR_EOT; + goto end; + } + else + { + retval = ERR_CALC_ERROR3 + err_code(pkt->data[0]); + goto end; + } + } + + data_size = pkt->data[1] + 2; + ticalcs_strlcpy(name, (char *)pkt->data + 2, data_size + 1); + o = data_size - 10; + + if (size) + { + *size = ( (((uint32_t)pkt->data[o ]) << 24) + | (((uint32_t)pkt->data[o + 1]) << 16) + | (((uint32_t)pkt->data[o + 2]) << 8) + | (((uint32_t)pkt->data[o + 3]) )); + } + if (type) + { + *type = pkt->data[o + 8]; + } + } + +end: + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_dir_enum_done(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 0, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_DIRLIST_DONE, (uint8_t *)nsp_vtl_pkt_alloc_data(0)); + + ticalcs_info(" closing directory listing:"); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_dir_enum_done(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_put_file(CalcHandle *handle, const char *name, uint32_t size) +{ + NSPVirtualPacket* pkt; + int o; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + pkt = nsp_vtl_pkt_new_ex(handle, 6 + len, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_PUT_FILE, (uint8_t *)nsp_vtl_pkt_alloc_data(6 + len)); + + ticalcs_info(" sending variable:"); + + pkt->data[0] = 0x01; + o = put_str(pkt->data + 1, name); + o++; + + pkt->data[o+0] = MSB(MSW(size)); + pkt->data[o+1] = LSB(MSW(size)); + pkt->data[o+2] = MSB(LSW(size)); + pkt->data[o+3] = LSB(LSW(size)); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_put_file(CalcHandle *handle) +{ + return nsp_cmd_r_file_ok(handle); +} + +TIEXPORT3 int TICALL nsp_cmd_s_put_file_eot(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 2, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_PUT_FILE_EOT, (uint8_t *)nsp_vtl_pkt_alloc_data(2)); + + ticalcs_info(" sending EOT:"); + + pkt->data[0] = 0x01; + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +// No nsp_cmd_r_put_file_eot because the calculator doesn't seem to reply to CMD_FM_PUT_FILE_EOT. + +TIEXPORT3 int TICALL nsp_cmd_s_get_file(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + + ticalcs_info(" requesting variable:"); + + pkt = nsp_vtl_pkt_new_ex(handle, 2 + len, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_GET_FILE, (uint8_t *)nsp_vtl_pkt_alloc_data(2 + len)); + pkt->data[0] = 0x01; + put_str(pkt->data + 1, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_get_file(CalcHandle *handle, uint32_t *size) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" file size:"); + + retval = nsp_recv_data(handle, pkt); + + if (!retval) + { + + if (pkt->cmd != NSP_CMD_FM_PUT_FILE) + { + retval = ERR_INVALID_PACKET; + goto end; + } + + if (size) + { + *size = ( (((uint32_t)pkt->data[10]) << 24) + | (((uint32_t)pkt->data[11]) << 16) + | (((uint32_t)pkt->data[12]) << 8) + | (((uint32_t)pkt->data[13]) )); + } + } + +end: + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_del_file(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + pkt = nsp_vtl_pkt_new_ex(handle, 2 + len, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_DEL_FILE, (uint8_t *)nsp_vtl_pkt_alloc_data(2 + len)); + + ticalcs_info(" deleting variable:"); + + pkt->data[0] = 0x01; + put_str(pkt->data + 1, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_del_file(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_new_folder(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + + pkt = nsp_vtl_pkt_new_ex(handle, 2 + len, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_NEW_FOLDER, (uint8_t *)nsp_vtl_pkt_alloc_data(2 + len)); + + ticalcs_info(" creating folder:"); + + pkt->data[0] = 0x03; + put_str(pkt->data + 1, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_new_folder(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_del_folder(CalcHandle *handle, const char *name) +{ + NSPVirtualPacket* pkt; + size_t len; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + + len = strlen(name) < 8 ? 8 : strlen(name); + + pkt = nsp_vtl_pkt_new_ex(handle, 2 + len, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_DEL_FOLDER, (uint8_t *)nsp_vtl_pkt_alloc_data(2 + len)); + + ticalcs_info(" deleting folder:"); + + pkt->data[0] = 0x03; + put_str(pkt->data + 1, name); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_del_folder(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_copy_file(CalcHandle *handle, const char *name, const char *name2) +{ + NSPVirtualPacket* pkt; + size_t len; + size_t len2; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + VALIDATE_NONNULL(name2); + + len = strlen(name) < 8 ? 8 : strlen(name); + len2 = strlen(name2) < 8 ? 8 : strlen(name2); + + pkt = nsp_vtl_pkt_new_ex(handle, 3 + len + len2, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_COPY_FILE, (uint8_t *)nsp_vtl_pkt_alloc_data(3 + len + len2)); + + ticalcs_info(" copying file:"); + + pkt->data[0] = 0x01; + put_str(pkt->data + 1, name); + put_str(pkt->data + 2 + len, name2); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_copy_file(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_rename_file(CalcHandle *handle, const char *name, const char *name2) +{ + NSPVirtualPacket* pkt; + size_t len; + size_t len2; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(name); + VALIDATE_NONNULL(name2); + + len = strlen(name) < 8 ? 8 : strlen(name); + len2 = strlen(name2) < 8 ? 8 : strlen(name2); + + ticalcs_info(" renaming file:"); + + pkt = nsp_vtl_pkt_new_ex(handle, 3 + len + len2, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_RENAME_FILE, (uint8_t *)nsp_vtl_pkt_alloc_data(3 + len + len2)); + pkt->data[0] = 0x01; + put_str(pkt->data + 1, name); + put_str(pkt->data + 2 + len, name2); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_rename_file(CalcHandle *handle) +{ + return nsp_cmd_r_status(handle, NULL); +} + +TIEXPORT3 int TICALL nsp_cmd_s_file_ok(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 0, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_OK, (uint8_t *)nsp_vtl_pkt_alloc_data(0)); + + ticalcs_info(" sending file contents:"); + + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_file_ok(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" file status:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + if (pkt->cmd != NSP_CMD_FM_OK) + { + if (pkt->cmd == NSP_CMD_STATUS) + { + retval = ERR_CALC_ERROR3 + err_code(pkt->data[0]); + } + else + { + retval = ERR_INVALID_PACKET; + } + } + else + { + ticalcs_info(" ok"); + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_file_contents(CalcHandle *handle, uint32_t size, uint8_t *data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(data); + + pkt = nsp_vtl_pkt_new_ex(handle, size, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_FILE_MGMT, NSP_CMD_FM_CONTENTS, (uint8_t *)nsp_vtl_pkt_alloc_data(size)); + + ticalcs_info(" sending file contents:"); + + memcpy(pkt->data, data, size); + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_file_contents(CalcHandle *handle, uint32_t *size, uint8_t **data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(size); + VALIDATE_NONNULL(data); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving file contents:"); + + pkt->size = *size; + retval = nsp_recv_data(handle, pkt); + + if (!retval) + { + *size = pkt->size; + *data = (uint8_t *)g_malloc0(pkt->size); + memcpy(*data, pkt->data, pkt->size); + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_os_install(CalcHandle *handle, uint32_t size) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new_ex(handle, 4, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_OS_INSTALL, NSP_CMD_OS_INSTALL, (uint8_t *)nsp_vtl_pkt_alloc_data(4)); + + ticalcs_info(" installing OS:"); + + pkt->data[0] = MSB(MSW(size)); + pkt->data[1] = LSB(MSW(size)); + pkt->data[2] = MSB(LSW(size)); + pkt->data[3] = LSB(LSW(size)); + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_os_install(CalcHandle *handle) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving OS installation:"); + + retval = nsp_recv_data(handle, pkt); + + if (!retval) + { + if (pkt->cmd != NSP_CMD_OS_OK) + { + retval = ERR_INVALID_PACKET; + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_os_contents(CalcHandle *handle, uint32_t size, uint8_t *data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(data); + + pkt = nsp_vtl_pkt_new_ex(handle, size, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_OS_INSTALL, NSP_CMD_OS_CONTENTS, (uint8_t *)nsp_vtl_pkt_alloc_data(size)); + + ticalcs_info(" sending OS contents:"); + + memcpy(pkt->data, data, size); + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_progress(CalcHandle *handle, uint8_t *value) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(value); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" OS installation status:"); + + retval = nsp_recv_data(handle, pkt); + if (!retval) + { + *value = pkt->data[0]; + + switch(pkt->cmd) + { + case NSP_CMD_OS_PROGRESS: + ticalcs_info(" %i/100", *value); + break; + case NSP_CMD_STATUS: + retval = ERR_CALC_ERROR3 + err_code(*value); + break; + default: + retval = ERR_INVALID_PACKET; + break; + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_generic_data(CalcHandle *handle, uint32_t size, uint8_t *data, uint16_t sid, uint8_t cmd) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + ticalcs_info(" sending generic data of size %lu (%lX) with command %02X:", (unsigned long)size, (unsigned long)size, cmd); + + pkt = nsp_vtl_pkt_new_ex(handle, size, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, sid, cmd, (uint8_t *)nsp_vtl_pkt_alloc_data(size)); + + if (data) + { + memcpy(pkt->data, data, size); + } + retval = nsp_send_data(handle, pkt); + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_r_generic_data(CalcHandle *handle, uint32_t *size, uint8_t **data) +{ + NSPVirtualPacket* pkt; + int retval = 0; + + VALIDATE_HANDLE(handle); + + pkt = nsp_vtl_pkt_new(handle); + + ticalcs_info(" receiving generic data:"); + + retval = nsp_recv_data(handle, pkt); + if (size) + { + *size = pkt->size; + } + + if (data) + { + *data = (uint8_t *)g_malloc0(pkt->size); + if (*data) + { + memcpy(*data, pkt->data, pkt->size); + } + else + { + retval = ERR_MALLOC; + } + } + + nsp_vtl_pkt_del(handle, pkt); + + return retval; +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_echo(CalcHandle *handle, uint32_t size, uint8_t *data) +{ + ticalcs_info(" sending echo:"); + return nsp_cmd_s_generic_data(handle, size, data, NSP_PORT_ECHO, 0); +} + +TIEXPORT3 int TICALL nsp_cmd_r_echo(CalcHandle *handle, uint32_t *size, uint8_t **data) +{ + ticalcs_info(" receiving echo:"); + return nsp_cmd_r_generic_data(handle, size, data); +} + +/////////////---------------- + +TIEXPORT3 int TICALL nsp_cmd_s_key(CalcHandle *handle, uint32_t code) +{ + NSPVirtualPacket * pkt1, * pkt2; + int retval = 0; + + VALIDATE_HANDLE(handle); + + ticalcs_info(" sending key:"); + + retval = nsp_session_open(handle, NSP_SID_KEYPRESSES); + if (!retval) + { + pkt1 = nsp_vtl_pkt_new_ex(handle, 3, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_KEYPRESSES, 0x01, (uint8_t *)nsp_vtl_pkt_alloc_data(3)); + + pkt1->data[2] = 0x80; + retval = nsp_send_data(handle, pkt1); + + if (!retval) + { + pkt2 = nsp_vtl_pkt_new_ex(handle, 25, NSP_SRC_ADDR, handle->priv.nsp_src_port, NSP_DEV_ADDR, NSP_PORT_KEYPRESSES, 0, (uint8_t *)nsp_vtl_pkt_alloc_data(25)); + + pkt2->data[3] = 0x08; + pkt2->data[4] = 0x02; + pkt2->data[5] = (uint8_t)(code >> 16); + pkt2->data[7] = (uint8_t)(code >> 8); + pkt2->data[23] = (uint8_t)(code & 0xFF); + + retval = nsp_send_data(handle, pkt2); + + nsp_vtl_pkt_del(handle, pkt2); + } + + nsp_vtl_pkt_del(handle, pkt1); + + if (!retval) + { + retval = nsp_session_close(handle); + } + } + + return retval; +} + +TIEXPORT3 int TICALL nsp_cmd_s_keypress_event(CalcHandle *handle, const uint8_t keycode[3]) +{ + uint32_t key; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(keycode); + + key = ((uint32_t)(keycode[0]) << 16) | ((uint32_t)(keycode[1]) << 8) | (uint32_t)(keycode[2]); + return nsp_cmd_s_key(handle, key); +} + +// There doesn't seem to be a need for cmd_r_key / cmd_r_keypress_event. +#endif diff --git a/libticalcs/trunk/src/nnse_cmd.h b/libticalcs/trunk/src/nnse_cmd.h new file mode 100644 index 000000000..828a35e13 --- /dev/null +++ b/libticalcs/trunk/src/nnse_cmd.h @@ -0,0 +1,123 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// /!\ NOTE: for this file, backwards compatibility will not necessarily be maintained as strongly as it is for ticalcs.h ! + +#ifndef __NNSE_CMDS__ +#define __NNSE_CMDS__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Service IDs +#define NNSE_SID_ADDR_REQUEST 0x01 +#define NNSE_SID_TIME 0x02 +#define NNSE_SID_ECHO 0x03 +#define NNSE_SID_STREAM 0x04 +#define NNSE_SID_TRANSMIT 0x05 +#define NNSE_SID_LOOPBACK 0x06 +#define NNSE_SID_STATS 0x07 +#define NNSE_SID_UNKNOWN 0x08 +#define NNSE_SID_ACK_FLAG 0x80 + +// Structures +// ... + +// Command wrappers + +// FIXME these will need an overhaul, but most functions should exist - NNSE is mostly wrapping NN. +#if 0 +TIEXPORT3 int TICALL nnse_cmd_r_login(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_status(CalcHandle *handle, uint8_t status); +TIEXPORT3 int TICALL nnse_cmd_r_status(CalcHandle *handle, uint8_t *status); + +TIEXPORT3 int TICALL nnse_cmd_s_generic_data(CalcHandle *handle, uint32_t size, uint8_t *data, uint16_t sid, uint8_t cmd); +TIEXPORT3 int TICALL nnse_cmd_r_generic_data(CalcHandle *handle, uint32_t *size, uint8_t **data); + +TIEXPORT3 int TICALL nnse_cmd_s_echo(CalcHandle *handle, uint32_t size, uint8_t *data); +TIEXPORT3 int TICALL nnse_cmd_r_echo(CalcHandle *handle, uint32_t *size, uint8_t **data); + +TIEXPORT3 int TICALL nnse_cmd_s_dev_infos(CalcHandle *handle, uint8_t cmd); +TIEXPORT3 int TICALL nnse_cmd_r_dev_infos(CalcHandle *handle, uint8_t *cmd, uint32_t *size, uint8_t **data); + +TIEXPORT3 int TICALL nnse_cmd_s_screen_rle(CalcHandle *handle, uint8_t cmd); +TIEXPORT3 int TICALL nnse_cmd_r_screen_rle(CalcHandle *handle, uint8_t *cmd, uint32_t *size, uint8_t **data); + +TIEXPORT3 int TICALL nnse_cmd_s_dir_attributes(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_dir_attributes(CalcHandle *handle, uint32_t *size, uint8_t *type, uint32_t *date); + +TIEXPORT3 int TICALL nnse_cmd_s_dir_enum_init(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_dir_enum_init(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_dir_enum_next(CalcHandle *handle); +TIEXPORT3 int TICALL nnse_cmd_r_dir_enum_next(CalcHandle *handle, char* name, uint32_t *size, uint8_t *type); + +TIEXPORT3 int TICALL nnse_cmd_s_dir_enum_done(CalcHandle *handle); +TIEXPORT3 int TICALL nnse_cmd_r_dir_enum_done(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_put_file(CalcHandle *handle, const char *name, uint32_t size); +TIEXPORT3 int TICALL nnse_cmd_r_put_file(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_put_file_eot(CalcHandle *handle); +// No nnse_cmd_r_put_file_eot because the calculator doesn't seem to reply to CMD_FM_PUT_FILE_EOT. + +TIEXPORT3 int TICALL nnse_cmd_s_get_file(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_get_file(CalcHandle *handle, uint32_t *size); + +TIEXPORT3 int TICALL nnse_cmd_s_del_file(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_del_file(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_new_folder(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_new_folder(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_del_folder(CalcHandle *handle, const char *name); +TIEXPORT3 int TICALL nnse_cmd_r_del_folder(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_copy_file(CalcHandle *handle, const char *name, const char *name2); +TIEXPORT3 int TICALL nnse_cmd_r_copy_file(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_rename_file(CalcHandle *handle, const char *name, const char *name2); +TIEXPORT3 int TICALL nnse_cmd_r_rename_file(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_file_ok(CalcHandle *handle); +TIEXPORT3 int TICALL nnse_cmd_r_file_ok(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_file_contents(CalcHandle *handle, uint32_t size, uint8_t *data); +TIEXPORT3 int TICALL nnse_cmd_r_file_contents(CalcHandle *handle, uint32_t *size, uint8_t **data); + +TIEXPORT3 int TICALL nnse_cmd_s_os_install(CalcHandle *handle, uint32_t size); +TIEXPORT3 int TICALL nnse_cmd_r_os_install(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_cmd_s_os_contents(CalcHandle *handle, uint32_t size, uint8_t *data); +TIEXPORT3 int TICALL nnse_cmd_r_progress(CalcHandle *handle, uint8_t *value); + +TIEXPORT3 int TICALL nnse_cmd_s_key(CalcHandle *handle, uint32_t code); +TIEXPORT3 int TICALL nnse_cmd_s_keypress_event(CalcHandle *handle, const uint8_t keycode[3]); +// There doesn't seem to be a need for nnse_cmd_r_key / nnse_cmd_r_keypress_event. +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libticalcs/trunk/src/nnse_rpkt.cc b/libticalcs/trunk/src/nnse_rpkt.cc new file mode 100644 index 000000000..170287094 --- /dev/null +++ b/libticalcs/trunk/src/nnse_rpkt.cc @@ -0,0 +1,415 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + This unit manages raw packets from/to Nspire CX II thru DirectLink cable. + Documentation & credits can be found at . +*/ + +#include +#include + +#include "ticalcs.h" +#include "internal.h" +#include "nnse_rpkt.h" +#include "logging.h" +#include "error.h" + +#define VPKT_DBG 1 // 1 = verbose, 2 = more verbose + +typedef struct +{ + uint8_t id; + const char* name; +} NNSEServiceId; + +typedef struct +{ + uint8_t id; + const char* name; +} NNSEAddress; + +static const NNSEAddress nnseaddrs[] = +{ + { 0x01, "CALC" }, + { 0xFE, "ME" }, + { 0xFF, "ALL" }, +}; + +static const NNSEServiceId nnsesids[] = +{ + { 0x01, "Address Request" }, + { 0x02, "Time" }, + { 0x03, "Echo" }, + { 0x04, "Stream" }, + { 0x05, "Transmit" }, + { 0x06, "Loopback" }, + { 0x07, "Stats" }, + { 0x08, "Unknown" }, + { 0x80, "ACK Flag" }, +}; + +TIEXPORT3 const char* TICALL nnse_addr2name(uint8_t id) +{ + unsigned int i; + + for (i = 0; i < sizeof(nnseaddrs) / sizeof(nnseaddrs[0]); i++) + { + if (id == nnseaddrs[i].id || id == nnseaddrs[i].id + 0x80) + { + return nnseaddrs[i].name; + } + } + + return ""; +} + +TIEXPORT3 const char* TICALL nnse_sid2name(uint8_t id) +{ + unsigned int i; + + for (i = 0; i < sizeof(nnsesids) / sizeof(nnsesids[0]); i++) + { + if (id == nnsesids[i].id || id == nnseaddrs[i].id + 0x80) + { + return nnsesids[i].name; + } + } + + return ""; +} + +// UDP checksum implementation +static uint16_t compute_checksum(const uint8_t *data, uint32_t size) +{ + uint32_t acc = 0; + + if (size > 0) + { + for (uint32_t i = 0; i < size - 1; i += 2) + { + uint16_t cur = (((uint16_t)data[i]) << 8) | data[i + 1]; + acc += cur; + } + if (size & 1) + { + acc += (((uint16_t)data[size - 1]) << 8); + } + + acc = (acc & 0xFFFF) + (acc >> 16); + acc = ~acc; + } + + return (uint16_t)acc; +} + +static int hexdump(uint8_t *data, uint32_t size) +{ +#if (VPKT_DBG == 1) + char str[64]; + uint32_t i; + + str[0] = 0; + if (size <= 12) + { + str[0] = ' '; str[1] = ' '; str[2] = ' '; str[3] = ' '; + + for (i = 0; i < size; i++) + { + sprintf(&str[3*i+4], "%02X ", data[i]); + } + } + else + { + sprintf(str, " %02X %02X %02X %02X %02X ..... %02X %02X %02X %02X %02X", + data[0], data[1], data[2], data[3], data[4], + data[size-5], data[size-4], data[size-3], data[size-2], data[size-1]); + } + ticalcs_info("%s", str); +#endif +#if (VPKT_DBG == 2) + char *str = (char *)g_malloc(3*size + 8 + 10); + uint32_t i, j, k; + int step = 12; + + for (k = 0; k < 4; k++) + { + str[k] = ' '; + } + + for (i = j = 0; i < size; i++, j++) + { + if (i && !(i % step)) + { + ticalcs_info(str); + j = 0; + } + + sprintf(&str[3*j+4], "%02X ", data[i]); + } + ticalcs_info("%s", str); + + g_free(str); +#endif + return 0; +} + +TIEXPORT3 int TICALL nnse_send(CalcHandle* handle, NNSERawPacket* pkt) +{ + int ret; + CalcEventData event; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(pkt); + + ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_BEFORE_SEND_NNSE_RPKT, /* retval */ 0, /* operation */ CALC_FNCT_LAST); + ticalcs_event_fill_nnse_rpkt(&event, /* unused1 */ pkt->unused1, /* service */ pkt->service, /* src_addr */ pkt->src_addr, /* dst_addr */ pkt->dst_addr, + /* unknown2 */ pkt->unknown2, /* req_ack */ pkt->req_ack, /* size */ pkt->size, /* seq */ pkt->seq, /* csum */ pkt->csum, /* data */ pkt->data); + ret = ticalcs_event_send(handle, &event); + + if (!ret) + { + uint8_t buf[sizeof(NNSERawPacket)] = { 0 }; + uint32_t size = pkt->size + NNSE_HEADER_SIZE; + uint32_t csum; + + csum = compute_checksum((uint8_t*)pkt, NNSE_HEADER_SIZE - 2); + csum += compute_checksum(pkt->data, pkt->size); + if (csum > 0xFFFF) + { + csum = (csum & 0xFFFF) + (csum >> 16); + } + pkt->csum = (uint16_t)csum; + + pkt->seq = handle->priv.nnse_seq_pc; + handle->priv.nnse_seq_pc++; + + ticalcs_info(" %02X: %02X->%02X RA=%02X SQ=%04X CK=%04X U12=%02X,%02X (%u bytes)\n", + pkt->service, pkt->src_addr, pkt->dst_addr, pkt->req_ack, + pkt->seq, pkt->csum, pkt->unused1, pkt->unknown2, pkt->size); + if (pkt->size) + { + hexdump(pkt->data, pkt->size); + } + + buf[0] = pkt->unused1; + buf[1] = pkt->service; + buf[2] = pkt->src_addr; + buf[3] = pkt->dst_addr; + buf[4] = pkt->unknown2; + buf[5] = pkt->req_ack; + buf[6] = MSB(pkt->size); + buf[7] = LSB(pkt->size); + buf[8] = MSB(pkt->seq); + buf[9] = LSB(pkt->seq); + buf[10] = MSB(pkt->csum); + buf[11] = LSB(pkt->csum); + + memcpy(buf + NNSE_HEADER_SIZE, pkt->data, pkt->size); + + ticables_progress_reset(handle->cable); + ret = ticables_cable_send(handle->cable, buf, size); + if (!ret) + { + if (size >= 128) + { + ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate); + } + + if (handle->updat->cancel) + { + ret = ERR_ABORT; + } + } + } + + ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_AFTER_SEND_NNSE_RPKT, /* retval */ ret, /* operation */ CALC_FNCT_LAST); + ticalcs_event_fill_nnse_rpkt(&event, /* unused1 */ pkt->unused1, /* service */ pkt->service, /* src_addr */ pkt->src_addr, /* dst_addr */ pkt->dst_addr, + /* unknown2 */ pkt->unknown2, /* req_ack */ pkt->req_ack, /* size */ pkt->size, /* seq */ pkt->seq, /* csum */ pkt->csum, /* data */ pkt->data); + ret = ticalcs_event_send(handle, &event); + + return ret; +} + +TIEXPORT3 int TICALL nnse_recv(CalcHandle* handle, NNSERawPacket* pkt) +{ + int ret; + CalcEventData event; + + VALIDATE_HANDLE(handle); + VALIDATE_NONNULL(pkt); + + ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_BEFORE_RECV_NNSE_RPKT, /* retval */ 0, /* operation */ CALC_FNCT_LAST); + ticalcs_event_fill_nnse_rpkt(&event, /* unused1 */ 0, /* service */ 0, /* src_addr */ 0, /* dst_addr */ 0, /* unknown2 */ 0, /* req_ack */ 0, + /* size */ 0, /* seq */ 0, /* csum */ 0, /* data */ pkt->data); + ret = ticalcs_event_send(handle, &event); + + if (!ret) + { + uint8_t buf[NNSE_HEADER_SIZE]; + ticables_progress_reset(handle->cable); + ret = ticables_cable_recv(handle->cable, buf, NNSE_HEADER_SIZE); + while (!ret) + { + pkt->unused1 = buf[0]; + pkt->service = buf[1]; + pkt->src_addr = buf[2]; + pkt->dst_addr = buf[3]; + pkt->unknown2 = buf[4]; + pkt->req_ack = buf[5]; + pkt->size = (((uint16_t)buf[6]) << 8) | buf[7]; + pkt->seq = (((uint16_t)buf[8]) << 8) | buf[9]; + pkt->csum = (((uint16_t)buf[10]) << 8) | buf[11]; + + // TODO take seq / ACK into account correctly. + handle->priv.nnse_seq = pkt->seq; + + // Next, follows data + if (pkt->size) + { + ret = ticables_cable_recv(handle->cable, pkt->data, pkt->size); + if (ret) + { + break; + } + + if (pkt->size >= 256) + { + ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate); + } + } + + if (handle->updat->cancel) + { + ret = ERR_ABORT; + break; + } + + ticalcs_info(" %02X: %02X->%02X RA=%02X SQ=%04X CK=%04X U12=%02X,%02X (%u bytes)\n", + pkt->service, pkt->src_addr, pkt->dst_addr, pkt->req_ack, + pkt->seq, pkt->csum, pkt->unused1, pkt->unknown2, pkt->size); + if (pkt->size) + { + hexdump(pkt->data, pkt->size); + } + + break; + } + } + + ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_AFTER_RECV_NNSE_RPKT, /* retval */ ret, /* operation */ CALC_FNCT_LAST); + ticalcs_event_fill_nnse_rpkt(&event, /* unused1 */ pkt->unused1, /* service */ pkt->service, /* src_addr */ pkt->src_addr, /* dst_addr */ pkt->dst_addr, + /* unknown2 */ pkt->unknown2, /* req_ack */ pkt->req_ack, /* size */ pkt->size, /* seq */ pkt->seq, /* csum */ pkt->csum, /* data */ pkt->data); + ret = ticalcs_event_send(handle, &event); + + return ret; +} + +static const char* ep_way(uint8_t ep) +{ + if (ep == 0x01) + { + return "TI>PC"; + } + else if (ep == 0x02) + { + return "PC>TI"; + } + else + { + return "XX>XX"; + } +} + +TIEXPORT3 int TICALL nnse_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep) +{ + int ret = 0; + uint8_t unused1; + uint8_t service; + uint8_t src_addr; + uint8_t dst_addr; + uint8_t unknown2; + uint8_t req_ack; + uint16_t size; + uint16_t seq; + uint16_t csum; + uint32_t i; + uint32_t computed_csum; + + VALIDATE_NONNULL(f); + VALIDATE_NONNULL(data); + + if (len < NNSE_HEADER_SIZE || len > NNSE_DATA_SIZE) + { + ticalcs_critical("Length %lu (%lX) is too small or too large for a valid NNSE raw packet", (unsigned long)len, (unsigned long)len); + return ERR_INVALID_PACKET; + } + + unused1 = data[0]; + service = data[1]; + src_addr = data[2]; + dst_addr = data[3]; + unknown2 = data[4]; + req_ack = data[5]; + size = (((uint16_t)data[6]) << 8) | data[7]; + seq = (((uint16_t)data[8]) << 8) | data[9]; + csum = (((uint16_t)data[10]) << 8) | data[11]; + + fprintf(f, "%08lX\t| %s: srv (%02X - %s): %02X - %s -> %02X - %s\n", (unsigned long)len, ep_way(ep), + service, nnse_sid2name(service), src_addr, nnse_addr2name(src_addr), + dst_addr, nnse_addr2name(dst_addr)); + fprintf(f, "\t unused1=%02X unknown2=%02X req_ack=%02X seq=%04X checksum=%04X (%u bytes)\n", + unused1, unknown2, req_ack, seq, csum, size); + + if (len != (uint32_t)size) + { + ticalcs_critical("Data size %u (%X) is incoherent with given NNSE raw packet length %lu (%lX)", size, size, (unsigned long)len, (unsigned long)len); + return ERR_INVALID_PACKET; + } + + computed_csum = compute_checksum(data, NNSE_HEADER_SIZE - 2); + computed_csum += compute_checksum(data + NNSE_HEADER_SIZE, len - NNSE_HEADER_SIZE); + if (computed_csum > 0xFFFF) + { + computed_csum = (computed_csum & 0xFFFF) + (computed_csum >> 16); + } + + fprintf(f, "\t computed_csum=%04X\n", computed_csum); + if (computed_csum != csum) + { + fprintf(f, "\t (NOTE: data checksum does not match header)\n"); + } + + data += NNSE_HEADER_SIZE; + len -= NNSE_HEADER_SIZE; + fprintf(f, "\t\t"); + for (i = 0; i < len;) + { + fprintf(f, "%02X ", *data++); + if (!(++i & 15)) + { + fprintf(f, "\n\t\t"); + } + } + fputc('\n', f); + + return ret; +} diff --git a/libticalcs/trunk/src/nnse_rpkt.h b/libticalcs/trunk/src/nnse_rpkt.h new file mode 100644 index 000000000..f79cf77d1 --- /dev/null +++ b/libticalcs/trunk/src/nnse_rpkt.h @@ -0,0 +1,41 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// /!\ NOTE: for this file, backwards compatibility will not necessarily be maintained as strongly as it is for ticalcs.h ! + +#ifndef __NNSE_RPKT__ +#define __NNSE_RPKT__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +TIEXPORT3 const char* TICALL nnse_addr2name(uint8_t id); +TIEXPORT3 const char* TICALL nnse_sid2name(uint8_t id); +TIEXPORT3 int TICALL nnse_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libticalcs/trunk/src/nnse_vpkt.cc b/libticalcs/trunk/src/nnse_vpkt.cc new file mode 100644 index 000000000..a26612119 --- /dev/null +++ b/libticalcs/trunk/src/nnse_vpkt.cc @@ -0,0 +1,211 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + This unit manages virtual packets from/to NSPire (DirectLink). + Virtual packets are fragmented into one or more raw packets. + + Please note this unit does not fully implement the NSpire protocol. It assumes + there is one Nspire which is not exposing services. This assumption allows to + work in a linear fashion although we need sometimes some nasty hacks (LOGIN for + instance). + + A better unit should implement a kind of daemon listening on all ports and launching + a thread for each connection attempt. This way is fully parallelized but need a state + machine and so more (complex) code. Maybe later... +*/ + +#include +#include +#include + +#include "ticalcs.h" +#include "internal.h" +#include "logging.h" +#include "error.h" + +#include "nnse_vpkt.h" + +// Creation/Destruction/Garbage Collecting of packets + +TIEXPORT3 NNSEVirtualPacket* TICALL nnse_vtl_pkt_new(CalcHandle * handle) +{ + return nnse_vtl_pkt_new_ex(handle, 0, 0, 0, 0, NULL); +} + +TIEXPORT3 NNSEVirtualPacket* TICALL nnse_vtl_pkt_new_ex(CalcHandle * handle, uint32_t size, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint8_t * data) +{ + NNSEVirtualPacket* vtl = NULL; + + if (ticalcs_validate_handle(handle)) + { + vtl = (NNSEVirtualPacket *)g_malloc0(sizeof(*vtl)); + + if (NULL != vtl) + { + //GList * vtl_pkt_list; + + nnse_vtl_pkt_fill(vtl, size, service, src_addr, dst_addr, data); + + //vtl_pkt_list = g_list_append((GList *)(handle->priv.nnse_vtl_pkt_list), vtl); + //handle->priv.nnse_vtl_pkt_list = (void *)vtl_pkt_list; + } + } + else + { + ticalcs_critical("%s: handle is invalid", __FUNCTION__); + } + + return vtl; +} + +TIEXPORT3 void TICALL nnse_vtl_pkt_fill(NNSEVirtualPacket* vtl, uint32_t size, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint8_t * data) +{ + if (vtl != NULL) + { + vtl->service = service; + vtl->src_addr = src_addr; + vtl->dst_addr = dst_addr; + vtl->size = size; + vtl->data = data; + } + else + { + ticalcs_critical("%s: vtl is NULL", __FUNCTION__); + } +} + +TIEXPORT3 void TICALL nnse_vtl_pkt_del(CalcHandle *handle, NNSEVirtualPacket* vtl) +{ + //GList *vtl_pkt_list; + + if (!ticalcs_validate_handle(handle)) + { + ticalcs_critical("%s: handle is invalid", __FUNCTION__); + return; + } + + if (vtl == NULL) + { + ticalcs_critical("%s: vtl is NULL", __FUNCTION__); + return; + } + + //vtl_pkt_list = g_list_remove((GList *)(handle->priv.nnse_vtl_pkt_list), vtl); + //handle->priv.nnse_vtl_pkt_list = (void *)vtl_pkt_list; + + g_free(vtl->data); + g_free(vtl); +} + +TIEXPORT3 void * TICALL nnse_vtl_pkt_alloc_data(size_t size) +{ + return g_malloc0(size + 1); +} + +TIEXPORT3 NNSEVirtualPacket * TICALL nnse_vtl_pkt_realloc_data(NNSEVirtualPacket* vtl, size_t size) +{ + if (vtl != NULL) + { + if (size + 1 > size) + { + uint8_t * data = (uint8_t *)g_realloc(vtl->data, size + 1); + if (NULL != data) + { + if (size > vtl->size) + { + // The previous time, vtl->size + 1 bytes were allocated and initialized. + // This time, we've allocated size + 1 bytes, so we need to initialize size - vtl->size extra bytes. + memset(data + vtl->size + 1, 0x00, size - vtl->size); + } + vtl->data = data; + } + else + { + return NULL; + } + } + else + { + return NULL; + } + } + + return vtl; +} + +TIEXPORT3 void TICALL nnse_vtl_pkt_free_data(void * data) +{ + return g_free(data); +} + +// Session Management + + + +// Address Request/Assignment + +TIEXPORT3 int TICALL nnse_addr_request(CalcHandle *handle) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} + +TIEXPORT3 int TICALL nnse_addr_assign(CalcHandle *handle, uint8_t addr) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} + +// Acknowledgement + +TIEXPORT3 int TICALL nnse_send_ack(CalcHandle* handle) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} + +TIEXPORT3 int TICALL nnse_recv_ack(CalcHandle *handle) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} + +// Fragmenting of packets + +TIEXPORT3 int TICALL nnse_send_data(CalcHandle *handle, NNSEVirtualPacket *vtl) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} + +// Note: data field may be re-allocated. +TIEXPORT3 int TICALL nnse_recv_data(CalcHandle* handle, NNSEVirtualPacket* vtl) +{ + int ret; + ret = ERR_UNSUPPORTED; + return ret; +} diff --git a/libticalcs/trunk/src/nnse_vpkt.h b/libticalcs/trunk/src/nnse_vpkt.h new file mode 100644 index 000000000..0174b8240 --- /dev/null +++ b/libticalcs/trunk/src/nnse_vpkt.h @@ -0,0 +1,60 @@ +/* Hey EMACS -*- linux-c -*- */ + +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2019 Lionel Debroux + * Copyright (C) 2019 Fabian Vogt + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// /!\ NOTE: for this file, backwards compatibility will not necessarily be maintained as strongly as it is for ticalcs.h ! + +#ifndef __NNSE_VPKT__ +#define __NNSE_VPKT__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Constants + +#define NNSE_ADDR_CALC 0x01 +#define NNSE_ADDR_ME 0xFE +#define NNSE_ADDR_ALL 0xFF + +// Functions + +TIEXPORT3 NNSEVirtualPacket* TICALL nnse_vtl_pkt_new(CalcHandle *handle); +TIEXPORT3 NNSEVirtualPacket* TICALL nnse_vtl_pkt_new_ex(CalcHandle *handle, uint32_t size, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint8_t * data); +TIEXPORT3 void TICALL nnse_vtl_pkt_fill(NNSEVirtualPacket* vtl, uint32_t size, uint8_t service, uint8_t src_addr, uint8_t dst_addr, uint8_t * data); +TIEXPORT3 void TICALL nnse_vtl_pkt_del(CalcHandle *handle, NNSEVirtualPacket* vtl); +TIEXPORT3 void * TICALL nnse_vtl_pkt_alloc_data(size_t size); +TIEXPORT3 NNSEVirtualPacket * TICALL nnse_vtl_pkt_realloc_data(NNSEVirtualPacket* vtl, size_t size); +TIEXPORT3 void TICALL nnse_vtl_pkt_free_data(void * data); + +TIEXPORT3 int TICALL nnse_addr_request(CalcHandle *handle); +TIEXPORT3 int TICALL nnse_addr_assign(CalcHandle *handle, uint8_t dev_addr); + +TIEXPORT3 int TICALL nnse_send_ack(CalcHandle *handle); +TIEXPORT3 int TICALL nnse_recv_ack(CalcHandle *handle); + +TIEXPORT3 int TICALL nnse_send_data(CalcHandle *handle, NNSEVirtualPacket* vtl); +TIEXPORT3 int TICALL nnse_recv_data(CalcHandle *handle, NNSEVirtualPacket* vtl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libticalcs/trunk/src/nsp_cmd.h b/libticalcs/trunk/src/nsp_cmd.h index ec4688a8c..be1bb64e2 100644 --- a/libticalcs/trunk/src/nsp_cmd.h +++ b/libticalcs/trunk/src/nsp_cmd.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.h 2074 2006-03-31 08:36:06Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2007-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -28,7 +28,7 @@ extern "C" { #endif -// Services IDs +// Service IDs #define NSP_SID_NULL 0x4001 #define NSP_SID_ECHO 0x4002 #define NSP_SID_ADDR_REQUEST 0x4003 diff --git a/libticalcs/trunk/src/nsp_rpkt.cc b/libticalcs/trunk/src/nsp_rpkt.cc index b515a6e06..51b47fd5b 100644 --- a/libticalcs/trunk/src/nsp_rpkt.cc +++ b/libticalcs/trunk/src/nsp_rpkt.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: packets.c 1404 2005-07-20 20:39:39Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 2007 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2007-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -190,8 +190,6 @@ static int hexdump(uint8_t *data, uint32_t size) TIEXPORT3 int TICALL nsp_send(CalcHandle* handle, NSPRawPacket* pkt) { - uint8_t buf[sizeof(NSPRawPacket)] = { 0 }; - uint32_t size; int ret; CalcEventData event; @@ -200,12 +198,13 @@ TIEXPORT3 int TICALL nsp_send(CalcHandle* handle, NSPRawPacket* pkt) ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_BEFORE_SEND_NSP_RPKT, /* retval */ 0, /* operation */ CALC_FNCT_LAST); ticalcs_event_fill_nsp_rpkt(&event, /* src_addr */ pkt->src_addr, /* src_port */ pkt->src_port, /* dst_addr */ pkt->dst_addr, /* dst_port */ pkt->dst_port, - /* data_sum */ pkt->data_sum, /* data_size */ pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); + /* data_sum */ pkt->data_sum, /* data_size */ (uint32_t)pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); ret = ticalcs_event_send(handle, &event); if (!ret) { - size = pkt->data_size + NSP_HEADER_SIZE; + uint8_t buf[sizeof(NSPRawPacket)] = { 0 }; + uint32_t size = pkt->data_size + NSP_HEADER_SIZE; pkt->data_sum = compute_crc(pkt->data, pkt->data_size); if (pkt->src_port == 0x00fe || pkt->src_port == 0x00ff || pkt->src_port == 0x00d3) @@ -267,7 +266,7 @@ TIEXPORT3 int TICALL nsp_send(CalcHandle* handle, NSPRawPacket* pkt) ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_AFTER_SEND_NSP_RPKT, /* retval */ ret, /* operation */ CALC_FNCT_LAST); ticalcs_event_fill_nsp_rpkt(&event, /* src_addr */ pkt->src_addr, /* src_port */ pkt->src_port, /* dst_addr */ pkt->dst_addr, /* dst_port */ pkt->dst_port, - /* data_sum */ pkt->data_sum, /* data_size */ pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); + /* data_sum */ pkt->data_sum, /* data_size */ (uint32_t)pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); ret = ticalcs_event_send(handle, &event); return ret; @@ -275,7 +274,6 @@ TIEXPORT3 int TICALL nsp_send(CalcHandle* handle, NSPRawPacket* pkt) TIEXPORT3 int TICALL nsp_recv(CalcHandle* handle, NSPRawPacket* pkt) { - uint8_t buf[NSP_HEADER_SIZE]; int ret; CalcEventData event; @@ -289,6 +287,7 @@ TIEXPORT3 int TICALL nsp_recv(CalcHandle* handle, NSPRawPacket* pkt) if (!ret) { + uint8_t buf[NSP_HEADER_SIZE]; ticables_progress_reset(handle->cable); ret = ticables_cable_recv(handle->cable, buf, NSP_HEADER_SIZE); while (!ret) @@ -348,7 +347,7 @@ TIEXPORT3 int TICALL nsp_recv(CalcHandle* handle, NSPRawPacket* pkt) ticalcs_event_fill_header(handle, &event, /* type */ CALC_EVENT_TYPE_AFTER_RECV_NSP_RPKT, /* retval */ ret, /* operation */ CALC_FNCT_LAST); ticalcs_event_fill_nsp_rpkt(&event, /* src_addr */ pkt->src_addr, /* src_port */ pkt->src_port, /* dst_addr */ pkt->dst_addr, /* dst_port */ pkt->dst_port, - /* data_sum */ pkt->data_sum, /* data_size */ pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); + /* data_sum */ pkt->data_sum, /* data_size */ (uint32_t)pkt->data_size, /* ack */ pkt->ack, /* seq */ pkt->seq, /* hdr_sum */ pkt->hdr_sum, /* data */ pkt->data); ret = ticalcs_event_send(handle, &event); return ret; @@ -370,7 +369,7 @@ static const char* ep_way(uint8_t ep) } } -TIEXPORT3 int TICALL nsp_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep) +TIEXPORT3 int TICALL nn_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep) { int ret = 0; uint16_t unused; @@ -379,7 +378,7 @@ TIEXPORT3 int TICALL nsp_dissect(CalcModel model, FILE * f, const uint8_t * data uint16_t dst_addr; uint16_t dst_port; uint16_t data_sum; - uint8_t data_size; + uint32_t data_size; uint8_t ack; uint8_t seq; uint8_t hdr_sum; @@ -391,9 +390,9 @@ TIEXPORT3 int TICALL nsp_dissect(CalcModel model, FILE * f, const uint8_t * data VALIDATE_NONNULL(f); VALIDATE_NONNULL(data); - if (len < NSP_HEADER_SIZE + 1 || len > NSP_HEADER_SIZE + 1 + NSP_DATA_SIZE) // 1 is the cmd byte. + if (len < NSP_HEADER_SIZE + 1 || len > NNSE_DATA_SIZE - NNSE_HEADER_SIZE) // 1 is the cmd byte. { - ticalcs_critical("Length %lu (%lX) is too small or too large for a valid NSP raw packet", (unsigned long)len, (unsigned long)len); + ticalcs_critical("Length %lu (%lX) is too small or too large for a valid NavNet raw packet", (unsigned long)len, (unsigned long)len); return ERR_INVALID_PACKET; } @@ -416,14 +415,24 @@ TIEXPORT3 int TICALL nsp_dissect(CalcModel model, FILE * f, const uint8_t * data unused, ack, seq, hdr_sum, data_sum, data_size); fprintf(f, "\t cmd=%02X\n", cmd); - if (data_size > NSP_DATA_SIZE) + if (data_size == 0xFF) { - ticalcs_critical("Data size %u (%X) is too large for a valid NSP raw packet", data_size, data_size); - return ERR_INVALID_PACKET; + if (len < NSP_HEADER_SIZE + 1 + 4) + { + ticalcs_critical("Length %lu (%lX) is too small for a valid NavNet raw packet with larger size info", (unsigned long)len, (unsigned long)len); + return ERR_INVALID_PACKET; + } + data_size = (((uint32_t)data[16]) << 24) | (((uint32_t)data[17]) << 16) | (((uint32_t)data[18]) << 8) | data[19]; + cmd = data[20]; + if (data_size > NNSE_DATA_SIZE - NNSE_HEADER_SIZE - NSP_HEADER_SIZE) + { + ticalcs_critical("Data size %u (%X) is too large for a valid NavNet raw packet with larger size info", data_size, data_size); + return ERR_INVALID_PACKET; + } } if (len != (uint32_t)data_size + NSP_HEADER_SIZE) { - ticalcs_critical("Data size %u (%X) is incoherent with given NSP raw packet length %lu (%lX)", data_size, data_size, (unsigned long)len, (unsigned long)len); + ticalcs_critical("Data size %u (%X) is incoherent with given NavNet raw packet length %lu (%lX)", data_size, data_size, (unsigned long)len, (unsigned long)len); return ERR_INVALID_PACKET; } diff --git a/libticalcs/trunk/src/nsp_rpkt.h b/libticalcs/trunk/src/nsp_rpkt.h index c5ca8ed94..8fdb2e5e8 100644 --- a/libticalcs/trunk/src/nsp_rpkt.h +++ b/libticalcs/trunk/src/nsp_rpkt.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id$ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2007-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -32,7 +32,7 @@ extern "C" { TIEXPORT3 const char* TICALL nsp_addr2name(uint16_t id); TIEXPORT3 const char* TICALL nsp_sid2name(uint16_t id); -TIEXPORT3 int TICALL nsp_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep); +TIEXPORT3 int TICALL nn_dissect(CalcModel model, FILE * f, const uint8_t * data, uint32_t len, uint8_t ep); #ifdef __cplusplus } diff --git a/libticalcs/trunk/src/nsp_vpkt.cc b/libticalcs/trunk/src/nsp_vpkt.cc index 39a5a3fd8..6f565f38a 100644 --- a/libticalcs/trunk/src/nsp_vpkt.cc +++ b/libticalcs/trunk/src/nsp_vpkt.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id: cmd84p.c 2077 2006-03-31 21:16:19Z roms $ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2007-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -57,7 +57,7 @@ TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new_ex(CalcHandle * handle, uint3 if (ticalcs_validate_handle(handle)) { - vtl = (NSPVirtualPacket *)g_malloc0(sizeof(NSPVirtualPacket)); + vtl = (NSPVirtualPacket *)g_malloc0(sizeof(*vtl)); if (NULL != vtl) { @@ -77,7 +77,7 @@ TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new_ex(CalcHandle * handle, uint3 return vtl; } -TIEXPORT3 void TICALL nsp_vtl_pkt_fill(NSPVirtualPacket* vtl, uint32_t size, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint8_t * data) +TIEXPORT3 void TICALL nsp_vtl_pkt_fill(NSPVirtualPacket* vtl, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint32_t size, uint8_t * data) { if (vtl != NULL) { @@ -166,6 +166,7 @@ TIEXPORT3 void TICALL nsp_vtl_pkt_free_data(CalcHandle * handle, void * data) { if (ticalcs_validate_handle(handle)) { + // Keep synchronized with ~NSPVirtualPacket() ! g_free(data); } } diff --git a/libticalcs/trunk/src/nsp_vpkt.h b/libticalcs/trunk/src/nsp_vpkt.h index 26ca7300a..822e1aa7c 100644 --- a/libticalcs/trunk/src/nsp_vpkt.h +++ b/libticalcs/trunk/src/nsp_vpkt.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id$ */ -/* libticalcs - Ti Calculator library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 2007-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -19,7 +19,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - // /!\ NOTE: for this file, backwards compatibility will not necessarily be maintained as strongly as it is for ticalcs.h ! #ifndef __NSP_VPKT__ @@ -64,7 +63,7 @@ extern "C" { TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new(CalcHandle *handle); TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new_ex(CalcHandle *handle, uint32_t size, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint8_t * data); -TIEXPORT3 void TICALL nsp_vtl_pkt_fill(NSPVirtualPacket* vtl, uint32_t size, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint8_t * data); +TIEXPORT3 void TICALL nsp_vtl_pkt_fill(NSPVirtualPacket* vtl, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port, uint8_t cmd, uint32_t size, uint8_t * data); TIEXPORT3 void TICALL nsp_vtl_pkt_del(CalcHandle *handle, NSPVirtualPacket* vtl); TIEXPORT3 void * TICALL nsp_vtl_pkt_alloc_data(CalcHandle * handle, size_t size); TIEXPORT3 NSPVirtualPacket * TICALL nsp_vtl_pkt_realloc_data(CalcHandle * handle, NSPVirtualPacket* vtl, size_t size); diff --git a/libticalcs/trunk/src/ticalcs.cc b/libticalcs/trunk/src/ticalcs.cc index 7fbf044f0..8cc7afb18 100644 --- a/libticalcs/trunk/src/ticalcs.cc +++ b/libticalcs/trunk/src/ticalcs.cc @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id$ */ -/* libticalcs2 - hand-helds support library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin +/* libticalcs - TI Calculator library, a part of the TILP project + * Copyright (C) 1999-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -787,6 +787,21 @@ TIEXPORT3 int TICALL ticalcs_model_supports_nsp(CalcModel model) || model == CALC_NSPIRE_CRADLE)); } +/** + * ticalcs_model_supports_nnse: + * @model: a calculator model taken in #CalcModel. + * + * Returns whether the given calculator model supports the NavNet SE protocol. + * That is, the standard protocol used by TI-Nspire CX II calculators and the NWB over the USB port. + * + * Return value: nonzero if the calculator supports the NNSE protocol, zero if it doesn't. + */ +TIEXPORT3 int TICALL ticalcs_model_supports_nnse(CalcModel model) +{ + return ( /*model < CALC_MAX + &&*/ ( model == CALC_NSPIRE_CXII)); +} + /** * ticalcs_model_supports_installing_flashapps: * @model: a calculator model taken in #CalcModel. diff --git a/libticalcs/trunk/src/ticalcs.h b/libticalcs/trunk/src/ticalcs.h index fe3ac48f3..adc18b5c6 100644 --- a/libticalcs/trunk/src/ticalcs.h +++ b/libticalcs/trunk/src/ticalcs.h @@ -1,8 +1,8 @@ /* Hey EMACS -*- linux-c -*- */ -/* $Id$ */ /* libticalcs2 - hand-helds support library, a part of the TiLP project - * Copyright (C) 1999-2005 Romain Liévin + * Copyright (C) 1999-2009 Romain Liévin + * Copyright (C) 2009-2019 Lionel Debroux * * 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 @@ -398,14 +398,20 @@ typedef struct } DUSBVirtualPacket; //! Size of the header of a \a NSPRawPacket -#define NSP_HEADER_SIZE (16) +#define NSP_HEADER_SIZE (16) //! Size of the data contained in \a NSPRawPacket -#define NSP_DATA_SIZE (254) +#define NSP_DATA_SIZE (254) + +//! Size of the header of a \a NNSERawPacket +#define NNSE_HEADER_SIZE (12) +//! Size of the data contained in \a NNSERawPacket +#define NNSE_DATA_SIZE (0x5C0) /** * NSPRawPacket: * - * Raw packet for the Nspire NavNet protocol, version with pre-allocated packet data. + * Raw packet for the Nspire NavNet protocol, now supporting > 254 bytes of data. + * This structure contains pre-allocated storage for packet data. **/ typedef struct { @@ -420,13 +426,24 @@ typedef struct uint8_t seq; uint8_t hdr_sum; - uint8_t data[NSP_DATA_SIZE]; + union + { + //! Used when data_size <= NSP_DATA_SIZE. + uint8_t data[NSP_DATA_SIZE]; + //! Used otherwise, with data_size == 0xFF. + struct + { + uint32_t real_size; + uint8_t large_data[NNSE_DATA_SIZE - NNSE_HEADER_SIZE - NSP_HEADER_SIZE - sizeof(uint32_t)]; + }; + }; } NSPRawPacket; /** * NSPRawPacketA: * - * Raw packet for the Nspire NavNet protocol, version with externally allocated packet data. + * Raw packet for the Nspire NavNet protocol, supporting > 254 bytes of data. + * This structure references externally allocated packet data. **/ typedef struct { @@ -436,7 +453,7 @@ typedef struct uint16_t dst_addr; uint16_t dst_port; uint16_t data_sum; - uint8_t data_size; + uint32_t data_size; uint8_t ack; uint8_t seq; uint8_t hdr_sum; @@ -451,6 +468,13 @@ typedef struct **/ typedef struct { +#ifdef __cplusplus + /*NSPVirtualPacket() : src_addr(0), src_port(0), dst_addr(0), dst_port(0), cmd(0), size(0), data(nullptr) {} + NSPVirtualPacket(uint16_t src_addr_, uint16_t src_port_, uint16_t dst_addr_, uint16_t dst_port_, uint8_t cmd_, uint32_t size_, uint8_t * data_) : + src_addr(src_addr_), src_port(src_port_), dst_addr(dst_addr_), dst_port(dst_port_), cmd(cmd_), size(size_), data(data_) {} + // Keep synchronized with nsp_vtl_pkt_free_data() ! + ~NSPVirtualPacket() { g_free(data); data = nullptr; }*/ +#endif uint16_t src_addr; uint16_t src_port; uint16_t dst_addr; @@ -462,6 +486,81 @@ typedef struct uint8_t *data; } NSPVirtualPacket; +/** + * NNSERawPacket: + * + * Raw packet for the NavNet SE (NWB / CX II) protocol. + * This structure contains pre-allocated storage for packet data. + **/ +typedef struct +{ + uint8_t unused1; ///< Unused? + uint8_t service; ///< Service number. If bit 7 set, an ACK + uint8_t src_addr; ///< Address of the source + uint8_t dst_addr; ///< Address of the destination + uint8_t unknown2; ///< No idea + uint8_t req_ack; ///< Whether an ack is expected + uint16_t size; ///< Length of the packet, including this header + uint16_t seq; ///< Sequence number. Increases by one for every non-ACK packet. + uint16_t csum; ///< Checksum. Inverse of the 16-bit modular sum with carry added. + + union + { + //! Used when there's no NavNet payload. + uint8_t data[NNSE_DATA_SIZE - NNSE_HEADER_SIZE]; + NSPRawPacket pkt; + }; +} NNSERawPacket; + +//static_assert(sizeof(NNSERawPacket::data) == sizeof(NNSERawPacket::rpkt), "Sizes don't match"); + +/** + * NNSERawPacketA: + * + * Raw packet for the NavNet SE (NWB / CX II) protocol. + * This structure references externally allocated packet data. + **/ +typedef struct +{ + uint8_t unused1; ///< Unused? + uint8_t service; ///< Service number. If bit 7 set, an ACK + uint8_t src_addr; ///< Address of the source + uint8_t dst_addr; ///< Address of the destination + uint8_t unknown2; ///< No idea + uint8_t req_ack; ///< Whether an ack is expected + uint16_t size; ///< Length of the packet, including this header + uint16_t seq; ///< Sequence number. Increases by one for every non-ACK packet. + uint16_t csum; ///< Checksum. Inverse of the 16bit modular sum with carry added. + + union + { + uint8_t * data; + NSPRawPacket * pkt; + }; +} NNSERawPacketA; + +/** + * NNSEVirtualPacket: + * + * Virtual packet for the NavNet SE (NWB / CX II) protocol. + **/ +typedef struct +{ + uint8_t service; ///< Service number. If bit 7 set, an ACK + uint8_t src_addr; ///< Address of the source + uint8_t dst_addr; ///< Address of the destination + uint8_t wraps_nsp_vpkt; ///< Whether the union wraps a NN VPKT. + union + { + struct + { + uint32_t size; + uint8_t *data; + }; + NSPVirtualPacket pkt; + }; +} NNSEVirtualPacket; + /** * ROMDumpRawPacket: * @@ -844,6 +943,16 @@ typedef enum CALC_EVENT_TYPE_BEFORE_RECV_NSP_VPKT, CALC_EVENT_TYPE_AFTER_RECV_NSP_VPKT, + CALC_EVENT_TYPE_BEFORE_SEND_NNSE_RPKT, + CALC_EVENT_TYPE_AFTER_SEND_NNSE_RPKT, + CALC_EVENT_TYPE_BEFORE_RECV_NNSE_RPKT, + CALC_EVENT_TYPE_AFTER_RECV_NNSE_RPKT, + + CALC_EVENT_TYPE_BEFORE_SEND_NNSE_VPKT, + CALC_EVENT_TYPE_AFTER_SEND_NNSE_VPKT, + CALC_EVENT_TYPE_BEFORE_RECV_NNSE_VPKT, + CALC_EVENT_TYPE_AFTER_RECV_NNSE_VPKT, + CALC_EVENT_TYPE_BEFORE_SEND_ROMDUMP_PKT, CALC_EVENT_TYPE_AFTER_SEND_ROMDUMP_PKT, CALC_EVENT_TYPE_BEFORE_RECV_ROMDUMP_PKT, @@ -884,7 +993,9 @@ typedef struct DUSBRawPacketA dusb_rpkt; DUSBVirtualPacket dusb_vpkt; NSPRawPacketA nsp_rpkt; + NNSERawPacketA nnse_rpkt; NSPVirtualPacket nsp_vpkt; + NNSEVirtualPacket nnse_vpkt; ROMDumpPacket romdump_pkt; CalcLabEquipmentData labeq_data; struct @@ -946,10 +1057,13 @@ struct _CalcHandle //void * dusb_vtl_pkt_list; //void * dusb_cpca_list; //void * nsp_vtl_pkt_list; + //void * nnse_vtl_pkt_list; uint8_t nsp_seq_pc; uint8_t nsp_seq; uint16_t nsp_src_port; uint16_t nsp_dst_port; + uint16_t nnse_seq_pc; + uint16_t nnse_seq; } priv; }; @@ -1005,6 +1119,7 @@ typedef struct TIEXPORT3 int TICALL ticalcs_model_supports_dbus(CalcModel model); TIEXPORT3 int TICALL ticalcs_model_supports_dusb(CalcModel model); TIEXPORT3 int TICALL ticalcs_model_supports_nsp(CalcModel model); + TIEXPORT3 int TICALL ticalcs_model_supports_nnse(CalcModel model); TIEXPORT3 int TICALL ticalcs_model_supports_installing_flashapps(CalcModel model); TIEXPORT3 ticalcs_event_hook_type TICALL ticalcs_calc_get_event_hook(CalcHandle *handle); @@ -1172,6 +1287,10 @@ typedef struct TIEXPORT3 int TICALL nsp_send(CalcHandle *handle, NSPRawPacket* pkt); TIEXPORT3 int TICALL nsp_recv(CalcHandle *handle, NSPRawPacket* pkt); + // nnse_rpkt.c + TIEXPORT3 int TICALL nnse_send(CalcHandle *handle, NNSERawPacket* pkt); + TIEXPORT3 int TICALL nnse_recv(CalcHandle *handle, NNSERawPacket* pkt); + /************************/ /* Deprecated functions */ /************************/ diff --git a/libticalcs/trunk/tests/input_nnse_initial_nspire_communication_through_raw.txt b/libticalcs/trunk/tests/input_nnse_initial_nspire_communication_through_raw.txt new file mode 100644 index 000000000..0addaf975 --- /dev/null +++ b/libticalcs/trunk/tests/input_nnse_initial_nspire_communication_through_raw.txt @@ -0,0 +1,18 @@ +version 0 +raw_recv_data 12 +buffer_peek_data be16 6 r1 +reg_sub 12 r1 +raw_recv_data r1 +raw_send_data +00 01 01 fe 00 00 000d 0000 00f0 +01 + +raw_send_data +00 01 01 fe 00 00 000d 0001 81ee +80 + +raw_recv_data 12 +buffer_peek_data be16 6 r1 +reg_sub 12 r1 +raw_recv_data r1 +exit diff --git a/libticalcs/trunk/tests/test_ticalcs_2.cc b/libticalcs/trunk/tests/test_ticalcs_2.cc index 25ce38342..09286b4a2 100644 --- a/libticalcs/trunk/tests/test_ticalcs_2.cc +++ b/libticalcs/trunk/tests/test_ticalcs_2.cc @@ -1,4 +1,4 @@ -/* $Id$ */ +/* Hey EMACS -*- linux-c -*- */ /* libticalcs - Ti Calculator library, a part of the TiLP project * Copyright (C) 1999-2009 Romain Lievin @@ -60,6 +60,7 @@ #include "../src/dusb_cmd.h" #include "../src/keysnsp.h" #include "../src/nsp_rpkt.h" +#include "../src/nnse_rpkt.h" #include "../src/error.h" #undef VERSION @@ -1790,6 +1791,24 @@ static int nsp_recv_rpkt(CalcHandle * h, int, char *) return ret; } +static int nnse_send_rpkt(CalcHandle * h, int, char *) +{ + int ret = -1; + + fputs("Not implemented\n", stderr); + + return ret; +} + +static int nnse_recv_rpkt(CalcHandle * h, int, char *) +{ + int ret = -1; + + fputs("Not implemented\n", stderr); + + return ret; +} + static int dbus_dissect_pkt(CalcHandle * h, int, char * input) { int ret; @@ -1856,7 +1875,31 @@ static int nsp_dissect_rpkt(CalcHandle * h, int, char * input) ret = get_hex_input(inbuf, sizeof(inbuf), pktdata2, sizeof(((NSPRawPacket *)0)->data), &length, "raw NSP packet", xstr(INBUF_DATA_SIZE)); if (!ret) { - ret = nsp_dissect((CalcModel)model, stderr, pktdata2, length, ep); + ret = nn_dissect((CalcModel)model, stderr, pktdata2, length, ep); + } + + return ret; +} + +static int nnse_dissect_rpkt(CalcHandle * h, int, char * input) +{ + int ret; + uint8_t ep = 2; // Assume PC -> TI. + uint32_t length = 0; + int model; + + printf("Enter calc model (usually 24): "); + ret = scan_print_output_1(input, "%d", "%d", &model, model); + if (ret < 1) + { + fputs("Missing parameters\n", stderr); + return 1; + } + + ret = get_hex_input(inbuf, sizeof(inbuf), pktdata2, sizeof(((NNSERawPacket *)0)->data), &length, "raw NNSE packet", xstr(INBUF_DATA_SIZE)); + if (!ret) + { + ret = nnse_dissect((CalcModel)model, stderr, pktdata2, length, ep); } return ret; @@ -2355,28 +2398,32 @@ static menu_entry fnct_menu[] = DEFINE_MENU_ENTRY("NSP Send raw packet", nsp_send_rpkt), // 60 DEFINE_MENU_ENTRY("NSP Recv raw packet", nsp_recv_rpkt), NULL_ENTRY, + DEFINE_MENU_ENTRY("NNSE Send raw packet", nnse_send_rpkt), + DEFINE_MENU_ENTRY("NNSE Recv raw packet", nnse_recv_rpkt), + NULL_ENTRY, // Front-ends for dissection functions. DEFINE_MENU_ENTRY("DIS Dissect DBUS raw packet", dbus_dissect_pkt), - DEFINE_MENU_ENTRY("DIS Dissect DUSB raw packet", dusb_dissect_rpkt), + DEFINE_MENU_ENTRY("DIS Dissect DUSB raw packet", dusb_dissect_rpkt), // 65 DEFINE_MENU_ENTRY("DIS Dissect NSP raw packet", nsp_dissect_rpkt), + DEFINE_MENU_ENTRY("DIS Dissect NNSE raw packet", nnse_dissect_rpkt), NULL_ENTRY, // Front-ends for protocol-specific capabilities. - DEFINE_MENU_ENTRY("DBUS 83+ Memory dump", ti83p_dump), // 65 + DEFINE_MENU_ENTRY("DBUS 83+ Memory dump", ti83p_dump), NULL_ENTRY, DEFINE_MENU_ENTRY("DBUS 83+ Enable key echo", ti83p_eke), - DEFINE_MENU_ENTRY("DBUS 83+ Disable key echo", ti83p_dke), + DEFINE_MENU_ENTRY("DBUS 83+ Disable key echo", ti83p_dke), // 70 NULL_ENTRY, DEFINE_MENU_ENTRY("DBUS 83+ Enable lockdown", ti83p_eld), DEFINE_MENU_ENTRY("DBUS 83+ Disable lockdown", ti83p_dld), NULL_ENTRY, - DEFINE_MENU_ENTRY("DBUS 83+ Get standard calculator ID", ti83p_gid), // 70 + DEFINE_MENU_ENTRY("DBUS 83+ Get standard calculator ID", ti83p_gid), DEFINE_MENU_ENTRY("DBUS 83+ Get some 32-byte memory area", ti83p_rid), - DEFINE_MENU_ENTRY("DBUS 83+ Set some 32-byte memory area", ti83p_sid), + DEFINE_MENU_ENTRY("DBUS 83+ Set some 32-byte memory area", ti83p_sid), // 75 NULL_ENTRY, DEFINE_MENU_ENTRY("DUSB Get parameter IDs", dusb_get_param_ids), DEFINE_MENU_ENTRY("DUSB Set parameter ID", dusb_set_param_id), NULL_ENTRY, - DEFINE_MENU_ENTRY("NSP Send key (specific and generic)", nsp_send_key), // 75 + DEFINE_MENU_ENTRY("NSP Send key (specific and generic)", nsp_send_key), NULL_ENTRY, DEFINE_MENU_ENTRY("NSP Test remote management stuff", nsp_remote_mgmt), NULL_ENTRY, diff --git a/libticalcs/trunk/tests/torture_ticalcs.c b/libticalcs/trunk/tests/torture_ticalcs.c index 26f51471e..76847f805 100644 --- a/libticalcs/trunk/tests/torture_ticalcs.c +++ b/libticalcs/trunk/tests/torture_ticalcs.c @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -50,6 +53,7 @@ static void torture_ticalcs(void) PRINTF(ticalcs_model_supports_dbus, INT, CALC_NONE); PRINTF(ticalcs_model_supports_dusb, INT, CALC_NONE); PRINTF(ticalcs_model_supports_nsp, INT, CALC_NONE); + PRINTF(ticalcs_model_supports_nnse, INT, CALC_NONE); PRINTF(ticalcs_model_supports_installing_flashapps, INT, CALC_NONE); PRINTF(ticalcs_calc_get_event_hook, PTR, NULL); PRINTF(ticalcs_calc_set_event_hook, PTR, NULL, (void *)0x12345678); @@ -266,6 +270,12 @@ static void torture_ticalcs(void) PRINTF(nsp_recv, INT, NULL, (void *)0x12345678); PRINTF(nsp_recv, INT, (void *)0x12345678, NULL); +// nnse_rpkt.c + PRINTF(nnse_send, INT, NULL, (void *)0x12345678); + + PRINTF(nnse_send, INT, (void *)0x12345678, NULL); + PRINTF(nnse_recv, INT, NULL, (void *)0x12345678); + PRINTF(nnse_recv, INT, (void *)0x12345678, NULL); } static void torture_nsp(void) @@ -275,8 +285,8 @@ static void torture_nsp(void) // nsp_rpkt.c PRINTF(nsp_addr2name, STR, 0); PRINTF(nsp_sid2name, STR, 0); - PRINTF(nsp_dissect, INT, CALC_NONE, NULL, (void *)0x12345678, 8, 2); - PRINTF(nsp_dissect, INT, CALC_NONE, (void *)0x12345678, NULL, 8, 2); + PRINTF(nn_dissect, INT, CALC_NONE, NULL, (void *)0x12345678, 8, 2); + PRINTF(nn_dissect, INT, CALC_NONE, (void *)0x12345678, NULL, 8, 2); // nsp_vpkt.c PRINTF(nsp_vtl_pkt_new, PTR, NULL); PRINTF(nsp_vtl_pkt_new_ex, PTR, NULL, 0x12345678, 0x1234, 0x1234, 0x1234, 0x1234, 0x12, (void *)0x12345678); @@ -385,6 +395,116 @@ static void torture_nsp(void) PRINTF(nsp_cmd_s_keypress_event, INT, (void *)0x12345678, NULL); } +static void torture_nnse(void) +{ + void * ptr; + +// nnse_rpkt.c + PRINTF(nnse_addr2name, STR, 0); + PRINTF(nnse_sid2name, STR, 0); + PRINTF(nnse_dissect, INT, CALC_NONE, NULL, (void *)0x12345678, 8, 2); + PRINTF(nnse_dissect, INT, CALC_NONE, (void *)0x12345678, NULL, 8, 2); +// nnse_vpkt.c + PRINTF(nnse_vtl_pkt_new, PTR, NULL); + PRINTF(nnse_vtl_pkt_new_ex, PTR, NULL, 0x12345678, 0x12, 0x12, 0x12, (void *)0x12345678); + PRINTFVOID(nnse_vtl_pkt_fill, NULL, 0x12345678, 0x12, 0x12, 0x12, NULL); + PRINTFVOID(nnse_vtl_pkt_del, NULL, (void *)0x12345678); + PRINTFVOID(nnse_vtl_pkt_del, (void *)0x12345678, NULL); + ptr = nnse_vtl_pkt_alloc_data(0); + PRINTF(, PTR, ptr); + nnse_vtl_pkt_free_data(ptr); + + ptr = nnse_vtl_pkt_realloc_data(NULL, 1); + PRINTF(, PTR, ptr); + nnse_vtl_pkt_free_data(ptr); + PRINTFVOID(nnse_vtl_pkt_free_data, NULL); + PRINTF(nnse_addr_request, INT, NULL); + PRINTF(nnse_addr_assign, INT, NULL, 0); + PRINTF(nnse_send_ack, INT, NULL); + PRINTF(nnse_recv_ack, INT, NULL); + + PRINTF(nnse_send_data, INT, NULL, (void *)0x12345678); + PRINTF(nnse_send_data, INT, (void *)0x12345678, NULL); + PRINTF(nnse_recv_data, INT, NULL, (void *)0x12345678); + PRINTF(nnse_recv_data, INT, (void *)0x12345678, NULL); +// nnse_cmd.c +#if 0 + PRINTF(nsp_cmd_r_login, INT, NULL); + PRINTF(nsp_cmd_s_status, INT, NULL, 0); + PRINTF(nsp_cmd_r_status, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_dev_infos, INT, NULL, 0); + + PRINTF(nsp_cmd_r_dev_infos, INT, NULL, (void *)0x12345678, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_r_dev_infos, INT, (void *)0x12345678, (void *)0x12345678, NULL, NULL); + PRINTF(nsp_cmd_r_dev_infos, INT, (void *)0x12345678, NULL, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_dev_infos, INT, (void *)0x12345678, NULL, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_screen_rle, INT, NULL, 0); + PRINTF(nsp_cmd_r_screen_rle, INT, NULL, (void *)0x12345678, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_r_screen_rle, INT, (void *)0x12345678, NULL, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_r_screen_rle, INT, (void *)0x12345678, (void *)0x12345678, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_r_screen_rle, INT, (void *)0x12345678, (void *)0x12345678, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_s_dir_attributes, INT, NULL, (void *)0x12345678); + + PRINTF(nsp_cmd_s_dir_attributes, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_dir_attributes, INT, NULL, (void *)0x12345678, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_s_dir_enum_init, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_dir_enum_init, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_dir_enum_init, INT, NULL); + PRINTF(nsp_cmd_s_dir_enum_next, INT, NULL); + PRINTF(nsp_cmd_r_dir_enum_next, INT, NULL, (void *)0x12345678, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_r_dir_enum_next, INT, (void *)0x12345678, NULL, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_s_dir_enum_done, INT, NULL); + PRINTF(nsp_cmd_r_dir_enum_done, INT, NULL); + + PRINTF(nsp_cmd_s_put_file, INT, NULL, (void *)0x12345678, 0); + PRINTF(nsp_cmd_s_put_file, INT, (void *)0x12345678, NULL, 0); + PRINTF(nsp_cmd_r_put_file, INT, NULL); + PRINTF(nsp_cmd_s_get_file, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_get_file, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_get_file, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_del_file, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_del_file, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_del_file, INT, NULL); + PRINTF(nsp_cmd_s_new_folder, INT, NULL, (void *)0x12345678); + + PRINTF(nsp_cmd_s_new_folder, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_new_folder, INT, NULL); + PRINTF(nsp_cmd_s_del_folder, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_del_folder, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_del_folder, INT, NULL); + PRINTF(nsp_cmd_s_copy_file, INT, NULL, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_s_copy_file, INT, (void *)0x12345678, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_copy_file, INT, (void *)0x12345678, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_copy_file, INT, NULL); + PRINTF(nsp_cmd_s_rename_file, INT, NULL, (void *)0x12345678, (void *)0x12345678); + + PRINTF(nsp_cmd_s_rename_file, INT, (void *)0x12345678, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_rename_file, INT, (void *)0x12345678, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_r_rename_file, INT, NULL); + PRINTF(nsp_cmd_s_file_ok, INT, NULL); + PRINTF(nsp_cmd_r_file_ok, INT, NULL); + PRINTF(nsp_cmd_s_file_contents, INT, NULL, 0, (void *)0x12345678); + PRINTF(nsp_cmd_s_file_contents, INT, (void *)0x12345678, 0, NULL); + PRINTF(nsp_cmd_r_file_contents, INT, NULL, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_r_file_contents, INT, (void *)0x12345678, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_r_file_contents, INT, (void *)0x12345678, (void *)0x12345678, NULL); + + PRINTF(nsp_cmd_s_os_install, INT, NULL, 0); + PRINTF(nsp_cmd_r_os_install, INT, NULL); + PRINTF(nsp_cmd_s_os_contents, INT, NULL, 0, (void *)0x12345678); + PRINTF(nsp_cmd_s_os_contents, INT, (void *)0x12345678, 0, NULL); + PRINTF(nsp_cmd_r_progress, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_r_progress, INT, (void *)0x12345678, NULL); + PRINTF(nsp_cmd_s_generic_data, INT, NULL, 0, (void *)0x12345678, 0, 0); + PRINTF(nsp_cmd_r_generic_data, INT, NULL, (void *)0x12345678, (void *)0x12345678); + PRINTF(nsp_cmd_s_echo, INT, NULL, 0, (void *)0x12345678); + PRINTF(nsp_cmd_r_echo, INT, NULL, (void *)0x12345678, (void *)0x12345678); + + PRINTF(nsp_cmd_s_keypress_event, INT, NULL, (void *)0x12345678); + PRINTF(nsp_cmd_s_keypress_event, INT, (void *)0x12345678, NULL); +#endif +} + static void torture_dusb(void) { void * ptr; @@ -947,12 +1067,12 @@ static const uint8_t nsp_good_keypress_home[] = { static void dissect_functions_unit_test_3(void) { - assert(ERR_INVALID_PACKET == nsp_dissect(CALC_NONE, stderr, (void *)0x12345678, 16, 0)); - assert(ERR_INVALID_PACKET == nsp_dissect(CALC_NONE, stderr, (void *)0x12345678, 272, 0)); - assert(ERR_INVALID_PACKET == nsp_dissect(CALC_NONE, stderr, nsp_bad_device_address_request, sizeof(nsp_bad_device_address_request), 0)); - assert(ERR_INVALID_PACKET == nsp_dissect(CALC_NONE, stderr, nsp_bad_device_address_request_2, sizeof(nsp_bad_device_address_request_2), 0)); - assert(0 == nsp_dissect(CALC_NONE, stderr, nsp_good_device_address_request, sizeof(nsp_good_device_address_request), 0)); - assert(0 == nsp_dissect(CALC_NONE, stderr, nsp_good_keypress_home, sizeof(nsp_good_keypress_home), 0)); + assert(ERR_INVALID_PACKET == nn_dissect(CALC_NONE, stderr, (void *)0x12345678, 16, 0)); + assert(ERR_INVALID_PACKET == nn_dissect(CALC_NONE, stderr, (void *)0x12345678, NNSE_DATA_SIZE + 1, 0)); + assert(ERR_INVALID_PACKET == nn_dissect(CALC_NONE, stderr, nsp_bad_device_address_request, sizeof(nsp_bad_device_address_request), 0)); + assert(ERR_INVALID_PACKET == nn_dissect(CALC_NONE, stderr, nsp_bad_device_address_request_2, sizeof(nsp_bad_device_address_request_2), 0)); + assert(0 == nn_dissect(CALC_NONE, stderr, nsp_good_device_address_request, sizeof(nsp_good_device_address_request), 0)); + assert(0 == nn_dissect(CALC_NONE, stderr, nsp_good_keypress_home, sizeof(nsp_good_keypress_home), 0)); } int main(int argc, char **argv) @@ -961,6 +1081,7 @@ int main(int argc, char **argv) torture_ticalcs(); torture_nsp(); + torture_nnse(); torture_dusb(); torture_dbus(); torture_cmdz80();