1 /*
2 * This software is Copyright (c) 2016 Denis Burykin
3 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru]
4 * and it is hereby released to the general public under the following terms:
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted.
7 *
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <sys/time.h>
14 #include <signal.h>
15 #include <errno.h>
16 #include <unistd.h>
17 #include <stdint.h>
18
19 #include "pkt_comm.h"
20
21
pkt_error(const char * s,...)22 void pkt_error(const char *s, ...) {
23 va_list ap;
24 va_start(ap, s);
25 vfprintf(stderr, s, ap);
26 va_end(ap);
27 }
28
29 int total_pkt_count=0;
get_pkt_count(void)30 int get_pkt_count(void)
31 {
32 return total_pkt_count;
33 }
34
pkt_new(int type,char * data,int data_len)35 struct pkt *pkt_new(int type, char *data, int data_len)
36 {
37 if (data_len > PKT_MAX_DATA_LEN) {
38 pkt_error("pkt_new(type %d): data_len(%d) exceeds %d bytes\n",
39 type, data_len, PKT_MAX_DATA_LEN);
40 exit(-1);
41 return NULL;
42 }
43
44 struct pkt *pkt = malloc(sizeof(struct pkt));
45 if (!pkt) {
46 pkt_error("pkt_new(type %d): unable to allocate %d bytes\n",
47 type, sizeof(struct pkt));
48 return NULL;
49 }
50
51 pkt->version = PKT_COMM_VERSION;
52 pkt->type = type;
53 pkt->data_len = data_len;
54 pkt->id = 0;
55
56 pkt->data = data;
57 pkt->header_ok = 0;
58 pkt->partial_header_len = 0;
59 pkt->partial_data_len = 0;
60 pkt->header = NULL;
61
62 total_pkt_count++;
63 return pkt;
64 }
65
pkt_get_id(struct pkt * pkt)66 unsigned int pkt_get_id(struct pkt *pkt)
67 {
68 return pkt->id;
69 }
70
pkt_delete(struct pkt * pkt)71 void pkt_delete(struct pkt *pkt)
72 {
73 if (pkt->data)
74 free(pkt->data);
75 if (pkt->partial_header_len && pkt->header)
76 free(pkt->header);
77 free(pkt);
78 total_pkt_count--;
79 }
80
81 //
82 // Create binary packet header in the area pointed to by *header
83 //
pkt_create_header(struct pkt * pkt,unsigned char * header)84 void pkt_create_header(struct pkt *pkt, unsigned char *header)
85 {
86 pkt->header = header;
87
88 pkt->header[0] = pkt->version;
89 pkt->header[1] = pkt->type;
90 //pkt->header[2] = 0;
91 //pkt->header[3] = 0;
92 pkt->header[4] = pkt->data_len;
93 pkt->header[5] = pkt->data_len >> 8;
94 pkt->header[6] = pkt->data_len >> 16;
95 //pkt->header[7] = 0;
96 pkt->header[8] = pkt->id;
97 pkt->header[9] = pkt->id >> 8;
98 }
99
100 // Read checksum pointed to by 'src' and convert to integer type
101 //
pkt_checksum_read(unsigned char * src)102 PKT_CHECKSUM_TYPE pkt_checksum_read(unsigned char *src)
103 {
104 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
105 }
106
107 //
108 // Calculate checksum of 'data' of length 'len'
109 // If 'dst' is not NULL, place checksum there
110 //
pkt_checksum(unsigned char * dst,unsigned char * data,int len)111 PKT_CHECKSUM_TYPE pkt_checksum(unsigned char *dst, unsigned char *data, int len)
112 {
113 PKT_CHECKSUM_TYPE checksum = 0;
114
115 PKT_CHECKSUM_TYPE checksum_tmp = 0;
116 int checksum_byte_count = 0;
117
118 int i;
119 for (i = 0; i < len; i++) {
120 checksum_tmp |= data[i] << 8 * checksum_byte_count;
121 if (++checksum_byte_count == PKT_CHECKSUM_LEN) {
122 checksum += checksum_tmp;
123 checksum_tmp = 0;
124 checksum_byte_count = 0;
125 }
126 }
127 checksum += checksum_tmp;
128
129 checksum = ~checksum;
130
131 for (i = 0; i < PKT_CHECKSUM_LEN; i++) {
132 if (dst)
133 dst[i] = checksum >> 8 * i;
134 }
135 return checksum;
136 }
137
138 //
139 // Convert binary packet header into human-readable string
140 // (for debug purposes)
141 //
pkt_header2str(struct pkt * pkt,unsigned char * header,char * str)142 void pkt_header2str(struct pkt *pkt, unsigned char *header, char *str)
143 {
144 char tmp_str[16];
145 int i;
146 strcpy(str, "[ ");
147 for (i=0; i < PKT_HEADER_LEN; i++) {
148 if (i && !(i % 4))
149 strcat(str, ". ");
150 sprintf(tmp_str, "%d ", header[i]);
151 strcat(str, tmp_str);
152 }
153 strcat(str, "]");
154 }
155
156 //
157 // Process input packet header in the area pointed to by *header
158 // including checksum
159 // Return < 0 on error
160 //
pkt_process_header(struct pkt * pkt,unsigned char * header)161 int pkt_process_header(struct pkt *pkt, unsigned char *header)
162 {
163 char str[256];
164
165 PKT_CHECKSUM_TYPE checksum = pkt_checksum(NULL, header, PKT_HEADER_LEN);
166 PKT_CHECKSUM_TYPE checksum_got = pkt_checksum_read(header + PKT_HEADER_LEN);
167 if (checksum_got != checksum) {
168 pkt_error("pkt_process_header: bad checksum: got 0x%x, must be 0x%x\n",
169 checksum_got, checksum);
170 return -1;
171 }
172
173 pkt->version = header[0];
174 if (pkt->version != PKT_COMM_VERSION) {
175 pkt_header2str(pkt, header, str);
176 pkt_error("pkt_process_header: wrong version %d, must be %d, header: %s\n",
177 pkt->version, PKT_COMM_VERSION, str);
178 return -1;
179 }
180 pkt->type = header[1];
181 if (!pkt->type) {
182 pkt_header2str(pkt, header, str);
183 pkt_error("pkt_process_header: empty packet type, header: %s\n", str);
184 return -1;
185 }
186
187 pkt->data_len = (unsigned)(header[4] | (header[5] << 8) | (header[6] << 16));
188 if (!pkt->data_len || pkt->data_len > PKT_MAX_DATA_LEN) {
189 pkt_header2str(pkt, header, str);
190 pkt_error("pkt_process_header: bad data_len %d, header: %s\n",
191 pkt->data_len, str);
192 return -1;
193 }
194 pkt->id = header[8] | (header[9] << 8);
195
196 pkt->partial_header_len = 0;
197 pkt->header_ok = 1;
198 return 0;
199 }
200
201 // ****************************************************************
202
pkt_queue_new()203 struct pkt_queue *pkt_queue_new()
204 {
205 struct pkt_queue *queue = malloc(sizeof(struct pkt_queue));
206 if (!queue) {
207 pkt_error("pkt_queue_new(): unable to allocate %d bytes\n",
208 sizeof(struct pkt_queue));
209 return NULL;
210 }
211 queue->count = 0;
212 queue->empty_slot_idx = 0;
213 queue->first_pkt_idx = 0;
214
215 int i;
216 for (i = 0; i < PKT_QUEUE_MAX; i++)
217 queue->pkt[i] = NULL;
218
219 return queue;
220 }
221
pkt_queue_delete(struct pkt_queue * queue)222 void pkt_queue_delete(struct pkt_queue *queue)
223 {
224 if (!queue) {
225 pkt_error("pkt_queue_delete(): NULL argument\n");
226 return;
227 }
228
229 int i;
230 for (i = 0; i < PKT_QUEUE_MAX; i++) {
231 if (queue->pkt[i])
232 pkt_delete(queue->pkt[i]);
233 }
234 free(queue);
235 }
236
pkt_queue_push(struct pkt_queue * queue,struct pkt * pkt)237 int pkt_queue_push(struct pkt_queue *queue, struct pkt *pkt)
238 {
239 if (queue->count == PKT_QUEUE_MAX)
240 return -1;
241
242 queue->pkt[queue->empty_slot_idx] = pkt;
243 if (++queue->empty_slot_idx == PKT_QUEUE_MAX)
244 queue->empty_slot_idx = 0;
245
246 queue->count++;
247 return 0;
248 }
249
pkt_queue_full(struct pkt_queue * queue,int num)250 int pkt_queue_full(struct pkt_queue *queue, int num)
251 {
252 return queue->count + num > PKT_QUEUE_MAX ? 1 : 0;
253 }
254
pkt_queue_fetch(struct pkt_queue * queue)255 struct pkt *pkt_queue_fetch(struct pkt_queue *queue)
256 {
257 if (!queue->count)
258 return NULL;
259
260 struct pkt *pkt = queue->pkt[queue->first_pkt_idx];
261 queue->pkt[queue->first_pkt_idx] = NULL;
262 queue->count--;
263
264 if (++queue->first_pkt_idx == PKT_QUEUE_MAX)
265 queue->first_pkt_idx = 0;
266
267 return pkt;
268 }
269
270 // Get total size (including headers and checksums) of all packets in queue
pkt_queue_get_total_size(struct pkt_queue * queue)271 int pkt_queue_get_total_size(struct pkt_queue *queue)
272 {
273 int total_size = 0;
274
275 int i;
276 for (i = 0; i < PKT_QUEUE_MAX; i++)
277 if (queue->pkt[i]) {
278 total_size += queue->pkt[i]->data_len + PKT_HEADER_LEN;
279 total_size += 2 * PKT_CHECKSUM_LEN;
280 }
281
282 return total_size;
283 }
284
285 // ****************************************************************
286
pkt_comm_new(struct pkt_comm_params * params)287 struct pkt_comm *pkt_comm_new(struct pkt_comm_params *params)
288 {
289 if (params->output_max_len <= 0 || params->input_max_len <= 0
290 || params->alignment < 0 || params->alignment > 256) {
291 pkt_error("pkt_comm_new(): wrong pkt_comm_params\n");
292 return NULL;
293 }
294
295 struct pkt_comm *comm = malloc(sizeof(struct pkt_comm));
296 if (!comm) {
297 pkt_error("pkt_comm_new(): unable to allocate %d bytes\n",
298 sizeof(struct pkt_comm));
299 return NULL;
300 }
301 comm->params = params;
302
303 comm->output_queue = pkt_queue_new();
304 if (!comm->output_queue) {
305 free(comm);
306 return NULL;
307 }
308 comm->output_buf = NULL;
309
310 comm->input_queue = pkt_queue_new();
311 if (!comm->input_queue) {
312 free(comm);
313 return NULL;
314 }
315 comm->input_buf = malloc(params->input_max_len);
316 if (!comm->input_buf) {
317 pkt_error("pkt_comm_new(): unable to allocate %d bytes\n",
318 params->input_max_len);
319 free(comm);
320 return NULL;
321 }
322 comm->input_buf_len = 0;
323 comm->input_pkt = NULL;
324
325 comm->error = 0;
326 return comm;
327 }
328
pkt_comm_delete(struct pkt_comm * comm)329 void pkt_comm_delete(struct pkt_comm *comm)
330 {
331 if (!comm) {
332 pkt_error("pkt_comm_delete(): NULL argument\n");
333 return;
334 }
335
336 pkt_queue_delete(comm->input_queue);
337 pkt_queue_delete(comm->output_queue);
338 free(comm->input_buf);
339 if (comm->output_buf)
340 free(comm->output_buf);
341 if (comm->input_pkt)
342 pkt_delete(comm->input_pkt);
343 }
344
345
346 // ******************************************************************
347 //
348 // pkt_comm output over link layer
349 //
350 // ******************************************************************
351
352 // allocates output buffer
353 // fetches all packets from output queue and puts them into output buffer
354 // calculates checksums
355 // deals with alignment issues
356 //
pkt_comm_create_output_buf(struct pkt_comm * comm)357 int pkt_comm_create_output_buf(struct pkt_comm *comm)
358 {
359 // there's already output buffer
360 if (comm->output_buf) {
361 pkt_error("pkt_comm_create_output_buf(): buffer already created\n");
362 return -1;
363 }
364
365 // output queue empty, output buffer not created
366 if (!comm->output_queue->count)
367 return 0;
368
369 int size = pkt_queue_get_total_size(comm->output_queue);
370 if (!size)
371 return 0;
372
373 // alignment issue; pad with 0's
374 int align = comm->params->alignment;
375 int extra_zeroes = align && size % align ? align - size % align : 0;
376 size += extra_zeroes;
377
378 comm->output_buf = malloc(size);
379 if (!comm->output_buf) {
380 pkt_error("pkt_comm_create_output_buf(): unable to allocate %d bytes\n", size);
381 return 0;
382 }
383 comm->output_buf_size = size;
384 comm->output_buf_offset = 0;
385
386 int i;
387 for (i = 0; i < extra_zeroes; i++)
388 comm->output_buf[size - i - 1] = 0;
389
390 // fetch all packets from output queue and put them into output buffer
391 int offset = 0;
392 struct pkt *pkt;
393 while ( (pkt = pkt_queue_fetch(comm->output_queue)) ) {
394
395 pkt_create_header(pkt, comm->output_buf + offset);
396 pkt_checksum(comm->output_buf + offset + PKT_HEADER_LEN,
397 comm->output_buf + offset, PKT_HEADER_LEN);
398 offset += PKT_HEADER_LEN + PKT_CHECKSUM_LEN;
399
400 memcpy(comm->output_buf + offset, pkt->data, pkt->data_len);
401 pkt_checksum(comm->output_buf + offset + pkt->data_len,
402 comm->output_buf + offset, pkt->data_len);
403 offset += pkt->data_len + PKT_CHECKSUM_LEN;
404
405 pkt_delete(pkt);
406 }
407
408 return size;
409 }
410
411 /*
412 // Not tested
413 int pkt_comm_has_output_data(struct pkt_comm *comm)
414 {
415 // There's data in output buffer
416 if (comm->output_buf) {
417 if (comm->output_buf_offset >= comm->output_buf_size
418 || !comm->output_buf_size) {
419 // Looks like internal error
420 pkt_error("pkt_comm_has_output_data: %d, %d\n",
421 comm->output_buf_offset, comm->output_buf_size);
422 return 0;
423 }
424 return 1;
425 }
426
427 // There's data in output queue
428 if (!comm->output_queue->count)
429 return 1;
430
431 return 0;
432 }
433 */
434
pkt_comm_get_output_data(struct pkt_comm * comm,int * len)435 unsigned char *pkt_comm_get_output_data(struct pkt_comm *comm, int *len)
436 {
437 if (!comm->output_buf) {
438 if (!pkt_comm_create_output_buf(comm)) {
439 // No output data
440 *len = 0;
441 return NULL;
442 }
443 }
444
445 int size = comm->output_buf_size;
446 int offset = comm->output_buf_offset;
447 //printf("pkt: size %d off %d\n",size,offset);
448 if (size - offset <= comm->params->output_max_len) {
449 // TODO: check if there's data in output queue, add-up to buffer
450 // if remeining size is less than max.transfer size over link layer
451 *len = size - offset;
452 } else {
453 *len = comm->params->output_max_len;
454 }
455
456 return comm->output_buf + offset;
457 }
458
459
pkt_comm_output_completed(struct pkt_comm * comm,int len,int error)460 void pkt_comm_output_completed(struct pkt_comm *comm, int len, int error)
461 {
462 comm->error = error;
463 if (error)
464 return;
465
466 comm->output_buf_offset += len;
467 if (comm->output_buf_offset >= comm->output_buf_size) {
468 free(comm->output_buf);
469 comm->output_buf = NULL;
470 }
471 }
472
473 // ******************************************************************
474 //
475 // pkt_comm input over link layer
476 //
477 // ******************************************************************
478
pkt_comm_input_process_zeroes(struct pkt_comm * comm)479 int pkt_comm_input_process_zeroes(struct pkt_comm *comm)
480 {
481 int count = 0;
482 while (comm->input_buf[comm->input_buf_offset] == 0) {
483 if (++comm->input_buf_offset >= comm->input_buf_len) {
484 comm->input_buf_len = 0;
485 return 0;
486 }
487 if (++count > 256) {
488 pkt_error("pkt_comm_process_input_buf: too many padding 0's\n");
489 return -1;
490 }
491 }
492 return 0;
493 }
494
495 // process packet header from input buffer
496 // including checksum after the header
497 //
pkt_comm_process_input_header(struct pkt_comm * comm)498 int pkt_comm_process_input_header(struct pkt_comm *comm)
499 {
500 struct pkt *pkt = comm->input_pkt;
501 unsigned char *buf = comm->input_buf;
502 int offset = comm->input_buf_offset;
503 //printf("process input header: off %d, input_pkt(y/n): %d\n", offset, !!pkt);
504
505 // nothing in input buffer
506 if (!comm->input_buf_len)
507 return 0;
508
509 // There's already input packet with partial header
510 if (pkt && pkt->partial_header_len) {
511 //printf("process input header: partial header len %d\n",pkt->partial_header_len);
512
513 // packet header is split over 3+ link layer transfers - should not happen
514 if (offset + PKT_HEADER_LEN + PKT_CHECKSUM_LEN - pkt->partial_header_len
515 > comm->input_buf_len) {
516 pkt_error("pkt_comm_process_input_buf: splitted partial header, buf_len %d, off %d\n",
517 comm->input_buf_len, offset);
518 return -1;
519 }
520
521 memcpy(pkt->header + pkt->partial_header_len, buf + offset,
522 PKT_HEADER_LEN + PKT_CHECKSUM_LEN - pkt->partial_header_len);
523 comm->input_buf_offset += PKT_HEADER_LEN + PKT_CHECKSUM_LEN - pkt->partial_header_len;
524
525 if (pkt_process_header(pkt, pkt->header) < 0)
526 return -1;
527 free(pkt->header);
528 pkt->header = NULL;
529 return 0;
530 }
531
532 // Partial header of a new input packet
533 if (offset + PKT_HEADER_LEN + PKT_CHECKSUM_LEN > comm->input_buf_len) {
534 pkt->header = malloc(PKT_HEADER_LEN + PKT_CHECKSUM_LEN);
535 if (!pkt->header) {
536 pkt_error("pkt_comm_process_input_header: unable to allocate %d bytes\n",
537 PKT_HEADER_LEN + PKT_CHECKSUM_LEN);
538 return -1;
539 }
540 pkt->partial_header_len = comm->input_buf_len - offset;
541 memcpy(pkt->header, buf + offset, pkt->partial_header_len);
542 comm->input_buf_len = 0;
543 //printf("partial header: off %d len %d\n", offset, pkt->partial_header_len);
544 return 0;
545 }
546 // Full header of a new input packet
547 else {
548 if (pkt_process_header(pkt, buf + offset) < 0)
549 return -1;
550 comm->input_buf_offset += PKT_HEADER_LEN + PKT_CHECKSUM_LEN;
551 if (comm->input_buf_offset == comm->input_buf_len)
552 comm->input_buf_len = 0;
553 }
554
555 return 0;
556 }
557
558 // process packet data from input buffer
559 // including checksum
560 //
pkt_comm_process_input_packet_data(struct pkt_comm * comm)561 int pkt_comm_process_input_packet_data(struct pkt_comm *comm)
562 {
563 struct pkt *pkt = comm->input_pkt;
564 if (!pkt || !pkt->data_len) {
565 pkt_error("pkt_comm_process_input_packet_data: bad input packet\n");
566 return -1;
567 }
568
569 // nothing in input buffer
570 if (!comm->input_buf_len)
571 return 0;
572
573 // no data in packet
574 if (!pkt->data) {
575 // allocate memory for packet data
576 pkt->data = malloc(pkt->data_len + PKT_CHECKSUM_LEN);
577 if (!pkt->data) {
578 pkt_error("pkt_comm_process_input_packet_data: unable to allocate %d bytes\n",
579 pkt->data_len + PKT_CHECKSUM_LEN);
580 return -1;
581 }
582 }
583 // ok, packet already has partial data
584 else if (pkt->data && pkt->partial_data_len
585 && pkt->partial_data_len < pkt->data_len + PKT_CHECKSUM_LEN) {
586 //printf("PARTIAL DATA: %d\n", pkt->partial_data_len);
587 }
588 else {
589 pkt_error("pkt_comm_process_input_packet_data: bad partial packet\n");
590 return -1;
591 }
592
593 int offset = comm->input_buf_offset;
594 int remains = pkt->data_len + PKT_CHECKSUM_LEN - pkt->partial_data_len ;
595
596 // packet completed
597 if (remains <= comm->input_buf_len - offset) {
598 memcpy(pkt->data + pkt->partial_data_len, comm->input_buf + offset, remains);
599 pkt->partial_data_len = 0;
600
601 PKT_CHECKSUM_TYPE checksum = pkt_checksum(NULL, (unsigned char *)pkt->data, pkt->data_len);
602 PKT_CHECKSUM_TYPE checksum_got = pkt_checksum_read((unsigned char *)pkt->data + pkt->data_len);
603 if (checksum_got != checksum) {
604 pkt_error("pkt_comm_process_input_packet_data: bad checksum: got 0x%x, must be 0x%x\n",
605 checksum_got, checksum);
606 return -1;
607 }
608
609 // input buffer is empty
610 if (remains == comm->input_buf_len - offset) {
611 comm->input_buf_len = 0;
612 }
613 // input buffer is not empty
614 else {
615 comm->input_buf_offset += remains;
616 }
617 }
618 // partial packet data, input buffer is empty
619 else {
620 memcpy(pkt->data + pkt->partial_data_len, comm->input_buf + offset,
621 comm->input_buf_len - offset);
622 pkt->partial_data_len += comm->input_buf_len - offset;
623 comm->input_buf_len = 0;
624 }
625
626 return 0;
627 }
628
629 // Process input buffer, store full packets in input queue
630 // store partially received packet in comm->input_pkt
631 // return < 0 on error
632 //
pkt_comm_process_input_buf(struct pkt_comm * comm)633 int pkt_comm_process_input_buf(struct pkt_comm *comm)
634 {
635 //printf("pkt_comm_process_input_buf: off %d\n", comm->input_buf_offset);
636 struct pkt *pkt = comm->input_pkt;
637
638 //if (pkt) printf("process_input_buf: h_ok %d part_head %d data %d part_data %d\n",
639 // pkt->header_ok, pkt->partial_header_len, !!pkt->data, pkt->partial_data_len);
640 //else printf("process_input_buf: no input_pkt\n");
641 while(1) {
642 // there's input packet with no header or partial header
643 if (pkt && !pkt->header_ok) {
644 if (pkt_comm_process_input_header(comm) < 0)
645 return -1;
646 }
647
648 // there's full header and no data or partial data
649 if (pkt && pkt->header_ok && (!pkt->data || pkt->partial_data_len)) {
650 if (pkt_comm_process_input_packet_data(comm) < 0)
651 return -1;
652 }
653
654 // there's already a complete input packet
655 if (pkt && pkt->header_ok && pkt->data && !pkt->partial_data_len) {
656 //printf("pkt_comm_process_input_buf: header_ok:%d data:%d partial_data_len:%d\n",
657 // !!pkt->header_ok, !!pkt->data, pkt->partial_data_len);
658 if (pkt_queue_full(comm->input_queue, 1))
659 return 0;
660 // push packet into input queue
661 pkt_queue_push(comm->input_queue, pkt);
662 comm->input_pkt = NULL;
663 }
664
665 // input buffer is empty - finish processing
666 if (!comm->input_buf_len)
667 return 0;
668
669 // skip padding zeroes
670 /*
671 * OK - the device creates aligned packets only
672 *
673 if (pkt_comm_input_process_zeroes(comm) < 0)
674 return -1;
675 if (!comm->input_buf_len)
676 return 0;
677 */
678
679 // expecting new input packet
680 pkt = pkt_new(0, NULL, 0);
681 comm->input_pkt = pkt;
682
683 } // while(1) - process incoming packets
684 }
685
pkt_comm_input_get_buf(struct pkt_comm * comm)686 unsigned char *pkt_comm_input_get_buf(struct pkt_comm *comm)
687 {
688 // input queue full
689 if (pkt_queue_full(comm->input_queue, 1))
690 return NULL;
691
692 // input buffer not empty
693 // that's probably because input queue was full
694 // at time of processing
695 if (comm->input_buf_len) {
696 // try to process and empty it
697 if (pkt_comm_process_input_buf(comm) < 0) {
698 comm->error = 1;
699 return NULL;
700 }
701
702 // still not empty
703 if (comm->input_buf_len)
704 return NULL;
705 }
706
707 comm->input_buf_offset = 0;
708 return comm->input_buf;
709 }
710
pkt_comm_input_completed(struct pkt_comm * comm,int len,int error)711 int pkt_comm_input_completed(struct pkt_comm *comm, int len, int error)
712 {
713 //printf("input_completed %d %d\n", len, error);
714 comm->error = error;
715 if (error)
716 return -1;
717
718 if (!len)
719 return -1;
720 if (len > comm->params->input_max_len) {
721 pkt_error("pkt_comm_input_completed: len %d exceeds input_max_len(%d)\n",
722 len, comm->params->input_max_len);
723 return -1;
724 }
725 comm->input_buf_len = len;
726
727 if (pkt_comm_process_input_buf(comm) < 0) {
728 comm->error = 1;
729 return -1;
730 }
731 return 0;
732 }
733
734