1
/* Hey EMACS -*- linux-c -*- */
2
/* $Id: packets.c 1404 2005-07-20 20:39:39Z roms $ */
4
/* libticalcs - Ti Calculator library, a part of the TiLP project
5
* Copyright (C) 2007 Romain Li�vin
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
This unit manages raw packets from/to NSpire thru DirectLink cable.
24
Documentation & credits can be found at <http://hackspire.unsads.com/USB_Protocol>.
36
#define VPKT_DBG 2 // 1 = verbose, 2 = more verbose
38
// CRC implementation from O. Armand (ExtendeD)
39
static uint16_t compute_crc(uint8_t *data, uint32_t size)
47
for(i = 0; i < (int)size; i++)
49
uint16_t first, second, third;
51
first = (data[i] << 8) | (acc >> 8);
53
second = (((acc & 0x0f) << 4) ^ acc) << 8;
56
acc = (acc ^ first ^ second ^ third);
62
static int hexdump(uint8_t *data, uint32_t size)
65
char *str = (char *)g_malloc(3*size + 8 + 10);
69
for(k = 0; k < 4; k++)
72
for (i = j = 0; i < (int)size; i++, j++)
80
sprintf(&str[3*j+4], "%02X ", 0xff & data[i]);
93
int nsp_send(CalcHandle* handle, RawPacket* pkt)
95
uint8_t buf[sizeof(RawPacket)] = { 0 };
96
uint32_t size = pkt->data_size + HEADER_SIZE;
98
pkt->data_sum = compute_crc(pkt->data, pkt->data_size);
100
if(pkt->src_port == 0x00fe || pkt->src_port == 0x00ff || pkt->src_port == 0x00d3)
107
if(!nsp_seq_pc) nsp_seq_pc++;
108
pkt->seq = nsp_seq_pc;
111
ticalcs_info(" %04x:%04x->%04x:%04x AK=%02x SQ=%02x HC=%02x DC=%04x (%i bytes)",
112
pkt->src_addr, pkt->src_port, pkt->dst_addr, pkt->dst_port,
113
pkt->ack, pkt->seq, pkt->hdr_sum, pkt->data_sum, pkt->data_size);
115
hexdump(pkt->data, pkt->data_size);
119
buf[2] = MSB(pkt->src_addr);
120
buf[3] = LSB(pkt->src_addr);
121
buf[4] = MSB(pkt->src_port);
122
buf[5] = LSB(pkt->src_port);
123
buf[6] = MSB(pkt->dst_addr);
124
buf[7] = LSB(pkt->dst_addr);
125
buf[8] = MSB(pkt->dst_port);
126
buf[9] = LSB(pkt->dst_port);
127
buf[10] = MSB(pkt->data_sum);
128
buf[11] = LSB(pkt->data_sum);
129
buf[12] = pkt->data_size;
132
buf[15] = pkt->hdr_sum = tifiles_checksum(buf, HEADER_SIZE-1) & 0xff;
134
memcpy(buf + HEADER_SIZE, pkt->data, pkt->data_size);
136
ticables_progress_reset(handle->cable);
137
TRYF(ticables_cable_send(handle->cable, buf, size));
139
ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
141
if (handle->updat->cancel)
147
int nsp_recv(CalcHandle* handle, RawPacket* pkt)
149
uint8_t buf[HEADER_SIZE];
151
ticables_progress_reset(handle->cable);
152
TRYF(ticables_cable_recv(handle->cable, buf, HEADER_SIZE));
154
pkt->unused = (buf[0] << 8) | buf[1];
155
pkt->src_addr = (buf[2] << 8) | buf[3];
156
pkt->src_port = (buf[4] << 8) | buf[5];
157
pkt->dst_addr = (buf[6] << 8) | buf[7];
158
pkt->dst_port = (buf[8] << 8) | buf[9];
159
pkt->data_sum = (buf[10] << 8) | buf[11];
160
pkt->data_size = buf[12];
163
pkt->hdr_sum = buf[15];
165
if(pkt->src_port == 0x00fe || pkt->src_port == 0x00ff || pkt->src_port == 0x00d3)
170
// Next, follows data
173
TRYF(ticables_cable_recv(handle->cable, pkt->data, pkt->data_size));
174
if(pkt->data_size >= 128)
175
ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
178
if (handle->updat->cancel)
181
ticalcs_info(" %04x:%04x->%04x:%04x AK=%02x SQ=%02x HC=%02x DC=%04x (%i bytes)",
182
pkt->src_addr, pkt->src_port, pkt->dst_addr, pkt->dst_port,
183
pkt->ack, pkt->seq, pkt->hdr_sum, pkt->data_sum, pkt->data_size);
185
hexdump(pkt->data, pkt->data_size);
1
/* Hey EMACS -*- linux-c -*- */
2
/* $Id: packets.c 1404 2005-07-20 20:39:39Z roms $ */
4
/* libticalcs - Ti Calculator library, a part of the TiLP project
5
* Copyright (C) 2007 Romain Li�vin
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
This unit manages raw packets from/to NSpire thru DirectLink cable.
24
Documentation & credits can be found at <http://hackspire.unsads.com/USB_Protocol>.
35
#define VPKT_DBG 1 // 1 = verbose, 2 = more verbose
37
// CRC implementation from O. Armand (ExtendeD)
38
static uint16_t compute_crc(uint8_t *data, uint32_t size)
46
for(i = 0; i < size; i++)
48
uint16_t first, second, third;
50
first = (data[i] << 8) | (acc >> 8);
52
second = (((acc & 0x0f) << 4) ^ acc) << 8;
55
acc = (acc ^ first ^ second ^ third);
61
static int hexdump(uint8_t *data, uint32_t size)
70
str[0] = ' '; str[1] = ' '; str[2] = ' '; str[3] = ' ';
72
for (i = 0; i < size; i++)
74
sprintf(&str[3*i+4], "%02X ", data[i]);
79
sprintf(str, " %02X %02X %02X %02X %02X ..... %02X %02X %02X %02X %02X",
80
data[0], data[1], data[2], data[3], data[4],
81
data[size-5], data[size-4], data[size-3], data[size-2], data[size-1]);
86
char *str = (char *)g_malloc(3*size + 8 + 10);
90
for(k = 0; k < 4; k++)
95
for (i = j = 0; i < size; i++, j++)
103
sprintf(&str[3*j+4], "%02X ", data[i]);
116
TIEXPORT3 int TICALL nsp_send(CalcHandle* handle, NSPRawPacket* pkt)
118
uint8_t buf[sizeof(NSPRawPacket)] = { 0 };
123
ticalcs_critical("%s: handle is NULL", __FUNCTION__);
124
return ERR_INVALID_HANDLE;
128
ticalcs_critical("%s: pkt is NULL", __FUNCTION__);
129
return ERR_INVALID_PACKET;
132
size = pkt->data_size + NSP_HEADER_SIZE;
133
pkt->data_sum = compute_crc(pkt->data, pkt->data_size);
135
if(pkt->src_port == 0x00fe || pkt->src_port == 0x00ff || pkt->src_port == 0x00d3)
142
if(!nsp_seq_pc) nsp_seq_pc++;
143
pkt->seq = nsp_seq_pc;
146
ticalcs_info(" %04x:%04x->%04x:%04x AK=%02x SQ=%02x HC=%02x DC=%04x (%i bytes)",
147
pkt->src_addr, pkt->src_port, pkt->dst_addr, pkt->dst_port,
148
pkt->ack, pkt->seq, pkt->hdr_sum, pkt->data_sum, pkt->data_size);
150
hexdump(pkt->data, pkt->data_size);
154
buf[2] = MSB(pkt->src_addr);
155
buf[3] = LSB(pkt->src_addr);
156
buf[4] = MSB(pkt->src_port);
157
buf[5] = LSB(pkt->src_port);
158
buf[6] = MSB(pkt->dst_addr);
159
buf[7] = LSB(pkt->dst_addr);
160
buf[8] = MSB(pkt->dst_port);
161
buf[9] = LSB(pkt->dst_port);
162
buf[10] = MSB(pkt->data_sum);
163
buf[11] = LSB(pkt->data_sum);
164
buf[12] = pkt->data_size;
167
buf[15] = pkt->hdr_sum = tifiles_checksum(buf, NSP_HEADER_SIZE-1) & 0xff;
169
memcpy(buf + NSP_HEADER_SIZE, pkt->data, pkt->data_size);
171
ticables_progress_reset(handle->cable);
172
TRYF(ticables_cable_send(handle->cable, buf, size));
174
ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
176
if (handle->updat->cancel)
182
TIEXPORT3 int TICALL nsp_recv(CalcHandle* handle, NSPRawPacket* pkt)
184
uint8_t buf[NSP_HEADER_SIZE];
188
ticalcs_critical("%s: handle is NULL", __FUNCTION__);
189
return ERR_INVALID_HANDLE;
193
ticalcs_critical("%s: pkt is NULL", __FUNCTION__);
194
return ERR_INVALID_PACKET;
197
ticables_progress_reset(handle->cable);
198
TRYF(ticables_cable_recv(handle->cable, buf, NSP_HEADER_SIZE));
200
pkt->unused = (buf[0] << 8) | buf[1];
201
pkt->src_addr = (buf[2] << 8) | buf[3];
202
pkt->src_port = (buf[4] << 8) | buf[5];
203
pkt->dst_addr = (buf[6] << 8) | buf[7];
204
pkt->dst_port = (buf[8] << 8) | buf[9];
205
pkt->data_sum = (buf[10] << 8) | buf[11];
206
pkt->data_size = buf[12];
209
pkt->hdr_sum = buf[15];
211
if(pkt->src_port == 0x00fe || pkt->src_port == 0x00ff || pkt->src_port == 0x00d3)
216
// Next, follows data
219
TRYF(ticables_cable_recv(handle->cable, pkt->data, pkt->data_size));
220
if(pkt->data_size >= 128)
221
ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
224
if (handle->updat->cancel)
227
ticalcs_info(" %04x:%04x->%04x:%04x AK=%02x SQ=%02x HC=%02x DC=%04x (%i bytes)",
228
pkt->src_addr, pkt->src_port, pkt->dst_addr, pkt->dst_port,
229
pkt->ack, pkt->seq, pkt->hdr_sum, pkt->data_sum, pkt->data_size);
231
hexdump(pkt->data, pkt->data_size);