1
/* Hey EMACS -*- linux-c -*- */
2
/* $Id: cmd84p.c 2077 2006-03-31 21:16:19Z roms $ */
4
/* libticalcs - Ti Calculator library, a part of the TiLP project
5
* Copyright (C) 1999-2005 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 virtual packets from/to NSPire (DirectLink).
24
Virtual packets are fragmented into one or more raw packets.
26
Please note this unit does not fully implement the NSpire protocol. It assumes
27
there is one Nspire which is not exposing services. This assumption allows to
28
work in a linear fashion although we need sometimes some nasty hacks (LOGIN for
31
A better unit should implement a kind of daemon listening on all ports and launching
32
a thread for each connection attempt. This way is fully parallelized but need a state
33
machine and so more (complex) code. Maybe later...
49
static const ServiceName sid_types[] =
51
{ 0x00FE, "Reception Acknowledgment" },
52
{ 0x00FF, "Reception Ack" },
55
{ 0x4003, "Device Address Request/Assignment" },
56
{ 0x4020, "Device Information" },
57
{ 0x4021, "Screen Capture" },
58
{ 0x4024, "Screen Capture w/ RLE" },
60
{ 0x4060, "File Management" },
61
{ 0x4080, "OS Installation" },
62
{ 0x40DE, "Service Disconnect" },
66
const char* nsp_sid2name(uint16_t id)
70
for(p = sid_types; p->name != NULL; p++)
74
return "unknown: not listed";
77
// Creation/Destruction/Garbage Collecting of packets
79
static GList *vtl_pkt_list = NULL;
81
VirtualPacket* nsp_vtl_pkt_new_ex(uint32_t size, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port)
83
VirtualPacket* vtl = g_malloc0(sizeof(VirtualPacket));
85
vtl->src_addr = src_addr;
86
vtl->src_port = src_port;
87
vtl->dst_addr = dst_addr;
88
vtl->dst_port = dst_port;
90
vtl->data = g_malloc0(size+1);
92
vtl_pkt_list = g_list_append(vtl_pkt_list, vtl);
97
VirtualPacket* nsp_vtl_pkt_new(void)
99
return nsp_vtl_pkt_new_ex(0, 0, 0, 0, 0);
102
void nsp_vtl_pkt_del(VirtualPacket* vtl)
104
vtl_pkt_list = g_list_remove(vtl_pkt_list, vtl);
110
void nsp_vtl_pkt_purge(void)
112
g_list_foreach(vtl_pkt_list, (GFunc)nsp_vtl_pkt_del, NULL);
113
g_list_free(vtl_pkt_list);
117
// Session Management
119
uint16_t nsp_src_port = 0x8001;
120
uint16_t nsp_dst_port = PORT_ADDR_REQUEST;
122
int nsp_session_open(CalcHandle *h, uint16_t port)
127
ticalcs_info(" opening session from port #%04x to port #%04x:", nsp_src_port, nsp_dst_port);
132
int nsp_session_close(CalcHandle *h)
134
ticalcs_info(" closed session from port #%04x to port #%04x:", nsp_src_port, nsp_dst_port);
136
TRYF(nsp_send_disconnect(h));
137
TRYF(nsp_recv_ack(h));
139
nsp_dst_port = PORT_ADDR_REQUEST;
144
// Address Request/Assignment
146
int nsp_addr_request(CalcHandle *h)
148
extern uint8_t nsp_seq_pc;
151
// Reset connection so that device send an address request packet
152
// Warning: you need a modified libusb-win32 library (see ticables2/src/win32/usb/libusb-win32.html)
153
TRYC(h->cable->cable->reset(h->cable));
156
ticalcs_info(" device address request:");
158
TRYF(nsp_recv(h, &pkt));
160
if(pkt.src_port != PORT_ADDR_ASSIGN)
161
return ERR_INVALID_PACKET;
162
if(pkt.dst_port != PORT_ADDR_REQUEST)
163
return ERR_INVALID_PACKET;
168
int nsp_addr_assign(CalcHandle *h, uint16_t addr)
172
ticalcs_info(" assigning address %04x:", addr);
175
pkt.src_addr = NSP_SRC_ADDR;
176
pkt.src_port = PORT_ADDR_ASSIGN;
177
pkt.dst_addr = NSP_DEV_ADDR;
178
pkt.dst_port = PORT_ADDR_ASSIGN;
179
pkt.data[0] = MSB(addr);
180
pkt.data[1] = LSB(addr);
183
TRYF(nsp_send(h, &pkt));
190
int nsp_send_ack(CalcHandle* h)
194
ticalcs_info(" sending ack:");
197
pkt.src_addr = NSP_SRC_ADDR;
198
pkt.src_port = PORT_PKT_ACK2;
199
pkt.dst_addr = NSP_DEV_ADDR;
200
pkt.dst_port = nsp_dst_port;
201
pkt.data[0] = MSB(nsp_src_port);
202
pkt.data[1] = LSB(nsp_src_port);
203
TRYF(nsp_send(h, &pkt));
208
int nsp_send_nack(CalcHandle* h)
212
ticalcs_info(" sending nAck:");
215
pkt.src_addr = NSP_SRC_ADDR;
216
pkt.src_port = PORT_PKT_NACK;
217
pkt.dst_addr = NSP_DEV_ADDR;
218
pkt.dst_port = nsp_dst_port;
219
pkt.data[0] = MSB(PORT_LOGIN);
220
pkt.data[1] = LSB(PORT_LOGIN);
221
TRYF(nsp_send(h, &pkt));
226
int nsp_send_nack_ex(CalcHandle* h, uint16_t port)
230
ticalcs_info(" sending nAck:");
233
pkt.src_addr = NSP_SRC_ADDR;
234
pkt.src_port = PORT_PKT_NACK;
235
pkt.dst_addr = NSP_DEV_ADDR;
237
pkt.data[0] = MSB(PORT_LOGIN);
238
pkt.data[1] = LSB(PORT_LOGIN);
239
TRYF(nsp_send(h, &pkt));
244
int nsp_recv_ack(CalcHandle *h)
249
ticalcs_info(" receiving ack:");
251
TRYF(nsp_recv(h, &pkt));
253
if(pkt.src_port != PORT_PKT_ACK2)
254
return ERR_INVALID_PACKET;
255
if(pkt.dst_port != nsp_src_port)
256
return ERR_INVALID_PACKET;
258
addr = (pkt.data[0] << 8) | pkt.data[1];
259
if(addr != nsp_dst_port)
260
return ERR_INVALID_PACKET;
263
return ERR_INVALID_PACKET;
268
// Service Disconnection
270
int nsp_send_disconnect(CalcHandle *h)
274
ticalcs_info(" disconnecting from service #%04x:", nsp_dst_port);
277
pkt.src_addr = NSP_SRC_ADDR;
278
pkt.src_port = PORT_DISCONNECT;
279
pkt.dst_addr = NSP_DEV_ADDR;
280
pkt.dst_port = nsp_dst_port;
281
pkt.data[0] = MSB(nsp_src_port);
282
pkt.data[1] = LSB(nsp_src_port);
283
TRYF(nsp_send(h, &pkt));
288
int nsp_recv_disconnect(CalcHandle *h)
293
ticalcs_info(" receiving disconnect:");
295
TRYF(nsp_recv(h, &pkt));
297
if(pkt.src_port != PORT_DISCONNECT)
298
return ERR_INVALID_PACKET;
301
nsp_dst_port = (pkt.data[0] << 8) | pkt.data[1];
308
ticalcs_info(" sending ack:");
311
pkt.src_addr = NSP_SRC_ADDR;
312
pkt.src_port = PORT_PKT_ACK2;
313
pkt.dst_addr = NSP_DEV_ADDR;
314
pkt.dst_port = nsp_dst_port;
315
pkt.data[0] = MSB(addr);
316
pkt.data[1] = LSB(addr);
317
TRYF(nsp_send(h, &pkt));
323
// Fragmenting of packets
325
int nsp_send_data(CalcHandle *h, VirtualPacket *vtl)
331
raw.src_addr = vtl->src_addr;
332
raw.src_port = vtl->src_port;
333
raw.dst_addr = vtl->dst_addr;
334
raw.dst_port = vtl->dst_port;
336
q = (vtl->size - offset) / (DATA_SIZE-1);
337
r = (vtl->size - offset) % (DATA_SIZE-1);
339
for(i = 1; i <= q; i++)
341
raw.data_size = DATA_SIZE;
342
raw.data[0] = vtl->cmd;
343
memcpy(raw.data + 1, vtl->data + offset, DATA_SIZE-1);
344
offset += DATA_SIZE-1;
346
TRYF(nsp_send(h, &raw));
348
if(raw.src_port != PORT_ADDR_ASSIGN && raw.dst_port != PORT_ADDR_REQUEST)
349
TRYF(nsp_recv_ack(h));
351
h->updat->max1 = vtl->size;
352
h->updat->cnt1 += DATA_SIZE;
358
raw.data_size = r + 1;
359
raw.data[0] = vtl->cmd;
360
memcpy(raw.data + 1, vtl->data + offset, r);
363
TRYF(nsp_send(h, &raw));
365
if(raw.src_port != PORT_ADDR_ASSIGN && raw.dst_port != PORT_ADDR_REQUEST)
366
TRYF(nsp_recv_ack(h));
372
// Note: data field may be re-allocated.
373
int nsp_recv_data(CalcHandle* h, VirtualPacket* vtl)
377
uint32_t size = vtl->size;
380
vtl->data = malloc(DATA_SIZE);
384
TRYF(nsp_recv(h, &raw));
385
vtl->cmd = raw.data[0];
386
vtl->size += raw.data_size-1;
388
vtl->data = realloc(vtl->data, vtl->size);
389
memcpy(vtl->data + offset, &(raw.data[1]), raw.data_size-1);
390
offset += raw.data_size-1;
392
h->updat->max1 = size ? size : vtl->size;
393
h->updat->cnt1 += DATA_SIZE;
396
if(raw.dst_port == PORT_LOGIN)
397
{ TRYF(nsp_send_nack_ex(h, raw.src_port)); }
398
else if(raw.src_port != PORT_ADDR_ASSIGN && raw.dst_port != PORT_ADDR_REQUEST)
399
{ TRYF(nsp_send_ack(h)); }
401
} while(raw.data_size >= DATA_SIZE);
403
vtl->src_addr = raw.src_addr;
404
vtl->src_port = raw.src_port;
405
vtl->dst_addr = raw.dst_addr;
406
vtl->dst_port = raw.dst_port;
1
/* Hey EMACS -*- linux-c -*- */
2
/* $Id: cmd84p.c 2077 2006-03-31 21:16:19Z roms $ */
4
/* libticalcs - Ti Calculator library, a part of the TiLP project
5
* Copyright (C) 1999-2005 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 virtual packets from/to NSPire (DirectLink).
24
Virtual packets are fragmented into one or more raw packets.
26
Please note this unit does not fully implement the NSpire protocol. It assumes
27
there is one Nspire which is not exposing services. This assumption allows to
28
work in a linear fashion although we need sometimes some nasty hacks (LOGIN for
31
A better unit should implement a kind of daemon listening on all ports and launching
32
a thread for each connection attempt. This way is fully parallelized but need a state
33
machine and so more (complex) code. Maybe later...
48
static const NSPServiceName sid_types[] =
50
{ 0x00FE, "Reception Acknowledgment" },
51
{ 0x00FF, "Reception Ack" },
54
{ 0x4003, "Device Address Request/Assignment" },
55
{ 0x4020, "Device Information" },
56
{ 0x4021, "Screen Capture" },
57
{ 0x4024, "Screen Capture w/ RLE" },
58
{ 0x4042, "Keypresses" },
60
{ 0x4060, "File Management" },
61
{ 0x4080, "OS Installation" },
62
{ 0x40DE, "Service Disconnect" },
66
TIEXPORT3 const char* TICALL nsp_sid2name(uint16_t id)
68
const NSPServiceName *p;
70
for(p = sid_types; p->name != NULL; p++)
74
return "unknown: not listed";
77
// Creation/Destruction/Garbage Collecting of packets
79
static GList *vtl_pkt_list = NULL;
81
TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new_ex(uint32_t size, uint16_t src_addr, uint16_t src_port, uint16_t dst_addr, uint16_t dst_port)
83
NSPVirtualPacket* vtl = g_malloc0(sizeof(NSPVirtualPacket)); // aborts the program if it fails.
85
vtl->src_addr = src_addr;
86
vtl->src_port = src_port;
87
vtl->dst_addr = dst_addr;
88
vtl->dst_port = dst_port;
90
vtl->data = g_malloc0(size+1); // aborts the program if it fails.
92
vtl_pkt_list = g_list_append(vtl_pkt_list, vtl);
97
TIEXPORT3 NSPVirtualPacket* TICALL nsp_vtl_pkt_new(void)
99
return nsp_vtl_pkt_new_ex(0, 0, 0, 0, 0);
102
TIEXPORT3 void TICALL nsp_vtl_pkt_del(NSPVirtualPacket* vtl)
106
vtl_pkt_list = g_list_remove(vtl_pkt_list, vtl);
113
ticalcs_critical("%s: vtl is NULL", __FUNCTION__);
117
void nsp_vtl_pkt_purge(void)
119
g_list_foreach(vtl_pkt_list, (GFunc)nsp_vtl_pkt_del, NULL);
120
g_list_free(vtl_pkt_list);
124
// Session Management
126
uint16_t nsp_src_port = 0x8001;
127
uint16_t nsp_dst_port = NSP_PORT_ADDR_REQUEST;
129
TIEXPORT3 int TICALL nsp_session_open(CalcHandle *h, uint16_t port)
133
ticalcs_critical("%s: h is NULL", __FUNCTION__);
134
return ERR_INVALID_HANDLE;
140
ticalcs_info(" opening session from port #%04x to port #%04x:", nsp_src_port, nsp_dst_port);
145
TIEXPORT3 int TICALL nsp_session_close(CalcHandle *h)
149
ticalcs_critical("%s: h is NULL", __FUNCTION__);
150
return ERR_INVALID_HANDLE;
153
ticalcs_info(" closed session from port #%04x to port #%04x:", nsp_src_port, nsp_dst_port);
155
TRYF(nsp_send_disconnect(h));
156
TRYF(nsp_recv_ack(h));
158
nsp_dst_port = NSP_PORT_ADDR_REQUEST;
163
// Address Request/Assignment
165
TIEXPORT3 int TICALL nsp_addr_request(CalcHandle *h)
167
extern uint8_t nsp_seq_pc;
172
ticalcs_critical("%s: h is NULL", __FUNCTION__);
173
return ERR_INVALID_HANDLE;
176
memset(&pkt, 0, sizeof(pkt));
178
// Reset connection so that device send an address request packet
179
TRYC(h->cable->cable->reset(h->cable));
182
ticalcs_info(" device address request:");
184
TRYF(nsp_recv(h, &pkt));
186
if(pkt.src_port != NSP_PORT_ADDR_ASSIGN)
187
return ERR_INVALID_PACKET;
188
if(pkt.dst_port != NSP_PORT_ADDR_REQUEST)
189
return ERR_INVALID_PACKET;
194
TIEXPORT3 int TICALL nsp_addr_assign(CalcHandle *h, uint16_t addr)
200
ticalcs_critical("%s: h is NULL", __FUNCTION__);
201
return ERR_INVALID_HANDLE;
204
ticalcs_info(" assigning address %04x:", addr);
206
memset(&pkt, 0, sizeof(pkt));
208
pkt.src_addr = NSP_SRC_ADDR;
209
pkt.src_port = NSP_PORT_ADDR_ASSIGN;
210
pkt.dst_addr = NSP_DEV_ADDR;
211
pkt.dst_port = NSP_PORT_ADDR_ASSIGN;
212
pkt.data[0] = MSB(addr);
213
pkt.data[1] = LSB(addr);
216
TRYF(nsp_send(h, &pkt));
223
TIEXPORT3 int TICALL nsp_send_ack(CalcHandle* h)
229
ticalcs_critical("%s: h is NULL", __FUNCTION__);
230
return ERR_INVALID_HANDLE;
233
ticalcs_info(" sending ack:");
235
memset(&pkt, 0, sizeof(pkt));
237
pkt.src_addr = NSP_SRC_ADDR;
238
pkt.src_port = NSP_PORT_PKT_ACK2;
239
pkt.dst_addr = NSP_DEV_ADDR;
240
pkt.dst_port = nsp_dst_port;
241
pkt.data[0] = MSB(nsp_src_port);
242
pkt.data[1] = LSB(nsp_src_port);
243
TRYF(nsp_send(h, &pkt));
248
TIEXPORT3 int TICALL nsp_send_nack(CalcHandle* h)
254
ticalcs_critical("%s: h is NULL", __FUNCTION__);
255
return ERR_INVALID_HANDLE;
258
ticalcs_info(" sending nAck:");
260
memset(&pkt, 0, sizeof(pkt));
262
pkt.src_addr = NSP_SRC_ADDR;
263
pkt.src_port = NSP_PORT_PKT_NACK;
264
pkt.dst_addr = NSP_DEV_ADDR;
265
pkt.dst_port = nsp_dst_port;
266
pkt.data[0] = MSB(NSP_PORT_LOGIN);
267
pkt.data[1] = LSB(NSP_PORT_LOGIN);
268
TRYF(nsp_send(h, &pkt));
273
TIEXPORT3 int TICALL nsp_send_nack_ex(CalcHandle* h, uint16_t port)
279
ticalcs_critical("%s: h is NULL", __FUNCTION__);
280
return ERR_INVALID_HANDLE;
283
ticalcs_info(" sending nAck:");
285
memset(&pkt, 0, sizeof(pkt));
287
pkt.src_addr = NSP_SRC_ADDR;
288
pkt.src_port = NSP_PORT_PKT_NACK;
289
pkt.dst_addr = NSP_DEV_ADDR;
291
pkt.data[0] = MSB(NSP_PORT_LOGIN);
292
pkt.data[1] = LSB(NSP_PORT_LOGIN);
293
TRYF(nsp_send(h, &pkt));
298
TIEXPORT3 int TICALL nsp_recv_ack(CalcHandle *h)
306
ticalcs_critical("%s: h is NULL", __FUNCTION__);
307
return ERR_INVALID_HANDLE;
310
ticalcs_info(" receiving ack:");
312
memset(&pkt, 0, sizeof(pkt));
314
TRYF(nsp_recv(h, &pkt));
316
if(pkt.src_port != NSP_PORT_PKT_ACK2)
318
ticalcs_info("XXX weird src_port\n");
319
ret = ERR_INVALID_PACKET;
321
if(pkt.dst_port != nsp_src_port)
323
ticalcs_info("XXX weird .dst_port\n");
324
ret = ERR_INVALID_PACKET;
327
if (pkt.data_size >= 2)
329
addr = (pkt.data[0] << 8) | pkt.data[1];
330
if(addr != nsp_dst_port)
332
ticalcs_info("XXX weird addr\n");
333
ret = ERR_INVALID_PACKET;
338
ticalcs_info("XXX weird addr\n");
339
ret = ERR_INVALID_PACKET;
344
ticalcs_info("XXX weird .ack\n");
345
ret = ERR_INVALID_PACKET;
351
// Service Disconnection
353
TIEXPORT3 int TICALL nsp_send_disconnect(CalcHandle *h)
359
ticalcs_critical("%s: h is NULL", __FUNCTION__);
360
return ERR_INVALID_HANDLE;
363
ticalcs_info(" disconnecting from service #%04x:", nsp_dst_port);
365
memset(&pkt, 0, sizeof(pkt));
367
pkt.src_addr = NSP_SRC_ADDR;
368
pkt.src_port = NSP_PORT_DISCONNECT;
369
pkt.dst_addr = NSP_DEV_ADDR;
370
pkt.dst_port = nsp_dst_port;
371
pkt.data[0] = MSB(nsp_src_port);
372
pkt.data[1] = LSB(nsp_src_port);
373
TRYF(nsp_send(h, &pkt));
378
TIEXPORT3 int TICALL nsp_recv_disconnect(CalcHandle *h)
385
ticalcs_critical("%s: h is NULL", __FUNCTION__);
386
return ERR_INVALID_HANDLE;
389
ticalcs_info(" receiving disconnect:");
391
memset(&pkt, 0, sizeof(pkt));
393
TRYF(nsp_recv(h, &pkt));
395
if(pkt.src_port != NSP_PORT_DISCONNECT)
396
return ERR_INVALID_PACKET;
399
nsp_dst_port = (pkt.data[0] << 8) | pkt.data[1];
404
ticalcs_info(" sending ack:");
408
pkt.src_addr = NSP_SRC_ADDR;
409
pkt.src_port = NSP_PORT_PKT_ACK2;
410
pkt.dst_addr = NSP_DEV_ADDR;
411
pkt.dst_port = nsp_dst_port;
416
pkt.data[0] = MSB(addr);
417
pkt.data[1] = LSB(addr);
418
TRYF(nsp_send(h, &pkt));
424
// Fragmenting of packets
426
TIEXPORT3 int TICALL nsp_send_data(CalcHandle *h, NSPVirtualPacket *vtl)
434
ticalcs_critical("%s: h is NULL", __FUNCTION__);
435
return ERR_INVALID_HANDLE;
439
ticalcs_critical("%s: vtl is NULL", __FUNCTION__);
440
return ERR_INVALID_PACKET;
443
memset(&raw, 0, sizeof(raw));
444
raw.src_addr = vtl->src_addr;
445
raw.src_port = vtl->src_port;
446
raw.dst_addr = vtl->dst_addr;
447
raw.dst_port = vtl->dst_port;
449
q = (vtl->size - offset) / (NSP_DATA_SIZE-1);
450
r = (vtl->size - offset) % (NSP_DATA_SIZE-1);
452
for(i = 1; i <= q; i++)
454
raw.data_size = NSP_DATA_SIZE;
455
raw.data[0] = vtl->cmd;
456
memcpy(raw.data + 1, vtl->data + offset, NSP_DATA_SIZE-1);
457
offset += NSP_DATA_SIZE-1;
459
TRYF(nsp_send(h, &raw));
461
if(raw.src_port != NSP_PORT_ADDR_ASSIGN && raw.dst_port != NSP_PORT_ADDR_REQUEST)
462
TRYF(nsp_recv_ack(h));
464
h->updat->max1 = vtl->size;
465
h->updat->cnt1 += NSP_DATA_SIZE;
471
raw.data_size = r + 1;
472
raw.data[0] = vtl->cmd;
473
memcpy(raw.data + 1, vtl->data + offset, r);
476
TRYF(nsp_send(h, &raw));
478
if(raw.src_port != NSP_PORT_ADDR_ASSIGN && raw.dst_port != NSP_PORT_ADDR_REQUEST)
479
TRYF(nsp_recv_ack(h));
485
// Note: data field may be re-allocated.
486
TIEXPORT3 int TICALL nsp_recv_data(CalcHandle* h, NSPVirtualPacket* vtl)
495
ticalcs_critical("%s: h is NULL", __FUNCTION__);
496
return ERR_INVALID_HANDLE;
500
ticalcs_critical("%s: vtl is NULL", __FUNCTION__);
501
return ERR_INVALID_PACKET;
504
memset(&raw, 0, sizeof(raw));
508
vtl->data = g_malloc(NSP_DATA_SIZE);
514
err = nsp_recv(h, &raw);
519
if (raw.data_size > 0)
521
vtl->cmd = raw.data[0];
522
vtl->size += raw.data_size-1;
524
vtl->data = g_realloc(vtl->data, vtl->size);
525
memcpy(vtl->data + offset, &(raw.data[1]), raw.data_size-1);
526
offset += raw.data_size-1;
528
h->updat->max1 = size ? size : vtl->size;
529
h->updat->cnt1 += NSP_DATA_SIZE;
533
if(raw.dst_port == NSP_PORT_LOGIN)
535
err = nsp_send_nack_ex(h, raw.src_port);
541
else if(raw.src_port != NSP_PORT_ADDR_ASSIGN && raw.dst_port != NSP_PORT_ADDR_REQUEST)
543
err = nsp_send_ack(h);
550
if (raw.data_size < NSP_DATA_SIZE)
552
if (size && vtl->size == size)
557
vtl->src_addr = raw.src_addr;
558
vtl->src_port = raw.src_port;
559
vtl->dst_addr = raw.dst_addr;
560
vtl->dst_port = raw.dst_port;