1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id$ */
3
4 /* libticables2 - link cable library, a part of the TiLP project
5 * Copyright (C) 1999-2005 Romain Lievin
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 #include <stdlib.h>
26
27 #include "ticables.h"
28 #include "internal.h"
29 #include "error.h"
30 #include "logging.h"
31 #include "data_log.h"
32
33 /**
34 * ticables_cable_open:
35 * @handle: a previously allocated handle
36 *
37 * Attempt to open a connection on the cable with the parameters
38 * given with #ticables_handle_new().
39 *
40 * Return value: 0 if successful, an error code otherwise.
41 **/
ticables_cable_open(CableHandle * handle)42 TIEXPORT1 int TICALL ticables_cable_open(CableHandle* handle)
43 {
44 const CableFncts *cable;
45 int ret = 0;
46
47 VALIDATE_HANDLE(handle);
48
49 cable = handle->cable;
50 VALIDATE_CABLEFNCTS(cable);
51
52 if (cable->prepare)
53 {
54 ret = cable->prepare(handle);
55 }
56
57 if (!ret)
58 {
59 if (cable->open)
60 {
61 ret = cable->open(handle);
62 }
63 if (!ret)
64 {
65 handle->open = 1;
66 START_LOGGING(handle);
67 }
68 }
69 return ret;
70 }
71
72 /**
73 * ticables_cable_close:
74 * @handle: a previously allocated handle
75 *
76 * Attempt to close a connection on the cable with the parameters
77 * given with #ticables_handle_new().
78 *
79 * Return value: 0 if successful, an error code otherwise.
80 **/
ticables_cable_close(CableHandle * handle)81 TIEXPORT1 int TICALL ticables_cable_close(CableHandle* handle)
82 {
83 const CableFncts *cable;
84 int ret = 0;
85
86 VALIDATE_HANDLE(handle);
87
88 cable = handle->cable;
89 VALIDATE_CABLEFNCTS(cable);
90
91 STOP_LOGGING(handle);
92 if (handle->open)
93 {
94 if (cable->close)
95 {
96 ret = cable->close(handle);
97 }
98 handle->open = 0;
99 free(handle->device);
100 handle->device = NULL;
101 }
102
103 return ret;
104 }
105
106 /**
107 * ticables_cable_reset:
108 * @handle: a previously allocated handle
109 *
110 * Reset link cable status (flush buffers, set ready).
111 *
112 * Return value: 0 if successful, an error code otherwise.
113 **/
ticables_cable_reset(CableHandle * handle)114 TIEXPORT1 int TICALL ticables_cable_reset(CableHandle* handle)
115 {
116 const CableFncts *cable;
117 int ret = 0;
118
119 VALIDATE_HANDLE(handle);
120
121 cable = handle->cable;
122 VALIDATE_CABLEFNCTS(cable);
123
124 RETURN_IF_HANDLE_NOT_OPEN(handle);
125 RETURN_IF_HANDLE_BUSY(handle);
126
127 handle->busy = 1;
128 if (cable->reset)
129 {
130 ret = cable->reset(handle);
131 }
132 handle->busy = 0;
133
134 return ret;
135 }
136
137 /**
138 * ticables_cable_probe:
139 * @handle: a previously allocated handle
140 * @result: cable found (!0) or not (0)
141 *
142 * Attempt to probe if a cable is present. Open device if not opened.
143 *
144 * Return value: 0 if successful, an error code otherwise.
145 **/
ticables_cable_probe(CableHandle * handle,int * result)146 TIEXPORT1 int TICALL ticables_cable_probe(CableHandle* handle, int* result)
147 {
148 const CableFncts *cable;
149 int opened;
150 int ret = 0;
151
152 VALIDATE_HANDLE(handle);
153
154 cable = handle->cable;
155 VALIDATE_CABLEFNCTS(cable);
156
157 opened = handle->open;
158
159 // Check if device is already opened
160 if (!opened && cable->need_open)
161 {
162 ret = ticables_cable_open(handle);
163 }
164 else if (!opened && !cable->need_open)
165 {
166 if (cable->prepare)
167 {
168 ret = cable->prepare(handle);
169 }
170 }
171
172 if (!ret)
173 {
174 // Do the check itself
175 if (cable->probe)
176 {
177 ret = cable->probe(handle);
178 if (result != NULL)
179 {
180 *result = !ret;
181 }
182 else
183 {
184 ticables_critical("%s: result is NULL", __FUNCTION__);
185 }
186
187 // If it was opened for this, close it
188 if (!opened && cable->need_open)
189 {
190 ret = ticables_cable_close(handle);
191 }
192 else if (!opened && !cable->need_open)
193 {
194 free(handle->device); handle->device = NULL;
195 free(handle->priv2); handle->priv2 = NULL;
196 }
197 }
198 }
199
200 return ret;
201 }
202
203 /**
204 * ticables_cable_send:
205 * @handle: a previously allocated handle
206 * @data: buffer with data to send
207 * @len: length of buffer
208 *
209 * Send %len bytes of the %data buffer from PC to hand-held.
210 *
211 * Return value: 0 if successful, an error code otherwise.
212 **/
ticables_cable_send(CableHandle * handle,uint8_t * data,uint32_t len)213 TIEXPORT1 int TICALL ticables_cable_send(CableHandle* handle, uint8_t *data, uint32_t len)
214 {
215 const CableFncts *cable;
216 int ret = 0;
217
218 VALIDATE_HANDLE(handle);
219
220 cable = handle->cable;
221 VALIDATE_CABLEFNCTS(cable);
222
223 RETURN_IF_HANDLE_NOT_OPEN(handle);
224 RETURN_IF_HANDLE_BUSY(handle);
225
226 if (!len)
227 {
228 // Complain loudly, but don't return 0 immediately in such a case.
229 // Indeed, the DUSB file transfer code of the 84+(SE) & 89T wants writes
230 // of length 0 after writes of length 64, otherwise transfer hangs...
231 //
232 // The workaround for these models used to be done purely in libticables,
233 // but doing so broke ROM dumping... so the problem is probably not
234 // intrinsic to the USB controller and low-level USB stack.
235 ticables_critical("ticables_cable_send: len = 0\n");
236 }
237
238 handle->busy = 1;
239 if (data != NULL)
240 {
241 handle->rate.count += len;
242 if (handle->pre_send_hook != NULL)
243 {
244 ret = handle->pre_send_hook(handle, data, len);
245 }
246 if (!ret)
247 {
248 if (cable->send)
249 {
250 ret = cable->send(handle, data, len);
251 }
252 if (handle->post_send_hook != NULL)
253 {
254 ret = handle->post_send_hook(handle, data, len, ret);
255 }
256 }
257 }
258 else
259 {
260 ticables_critical("%s: data is NULL", __FUNCTION__);
261 }
262 handle->busy = 0;
263
264 return ret;
265 }
266
267 /**
268 * ticables_cable_recv:
269 * @handle: a previously allocated handle
270 * @data: buffer where data can be placed
271 * @len: number of bytes requested
272 *
273 * Attempt to receive %len bytes from hand-held to PC.
274 *
275 * Return value: 0 if successful, an error code otherwise.
276 **/
ticables_cable_recv(CableHandle * handle,uint8_t * data,uint32_t len)277 TIEXPORT1 int TICALL ticables_cable_recv(CableHandle* handle, uint8_t *data, uint32_t len)
278 {
279 const CableFncts *cable;
280 int ret = 0;
281
282 VALIDATE_HANDLE(handle);
283
284 cable = handle->cable;
285 VALIDATE_CABLEFNCTS(cable);
286
287 RETURN_IF_HANDLE_NOT_OPEN(handle);
288 RETURN_IF_HANDLE_BUSY(handle);
289
290 if (!len)
291 {
292 // See ticables_cable_send above.
293 ticables_critical("ticables_cable_recv: len = 0\n");
294 }
295
296 handle->busy = 1;
297 if (data != NULL)
298 {
299 handle->rate.count += len;
300 if (handle->pre_recv_hook != NULL)
301 {
302 ret = handle->pre_recv_hook(handle, data, len);
303 }
304 if (!ret)
305 {
306 if (cable->recv)
307 {
308 ret = cable->recv(handle, data, len);
309 }
310 if (handle->post_recv_hook != NULL)
311 {
312 ret = handle->post_recv_hook(handle, data, len, ret);
313 }
314 }
315 }
316 else
317 {
318 ticables_critical("%s: data is NULL", __FUNCTION__);
319 }
320 handle->busy = 0;
321
322 return ret;
323 }
324
325 /**
326 * ticables_cable_check:
327 * @handle: a previously allocated handle
328 * @status: status is placed here
329 *
330 * Check for link cable status
331 *
332 * Return value: 0 if successful, an error code otherwise.
333 **/
ticables_cable_check(CableHandle * handle,CableStatus * status)334 TIEXPORT1 int TICALL ticables_cable_check(CableHandle* handle, CableStatus *status)
335 {
336 const CableFncts *cable;
337 int ret = 0;
338
339 VALIDATE_HANDLE(handle);
340
341 cable = handle->cable;
342 VALIDATE_CABLEFNCTS(cable);
343
344 RETURN_IF_HANDLE_NOT_OPEN(handle);
345 RETURN_IF_HANDLE_BUSY(handle);
346
347 handle->busy = 1;
348 if (status != NULL)
349 {
350 if (cable->check)
351 {
352 ret = cable->check(handle, (int *)status);
353 }
354 }
355 else
356 {
357 ticables_critical("%s: status is NULL", __FUNCTION__);
358 }
359 handle->busy = 0;
360
361 return ret;
362 }
363
364 /**
365 * ticables_cable_set_d0:
366 * @handle: a previously allocated handle
367 * @state: logical state (0 or 1) of D0 wire.
368 *
369 * Set the electrical state of the D0 wire (if possible).
370 *
371 * Return value: 0 if successful, an error code otherwise.
372 **/
ticables_cable_set_d0(CableHandle * handle,int state)373 TIEXPORT1 int TICALL ticables_cable_set_d0(CableHandle* handle, int state)
374 {
375 const CableFncts *cable;
376 int ret = 0;
377
378 VALIDATE_HANDLE(handle);
379
380 cable = handle->cable;
381 VALIDATE_CABLEFNCTS(cable);
382
383 RETURN_IF_HANDLE_NOT_OPEN(handle);
384 RETURN_IF_HANDLE_BUSY(handle);
385
386 handle->busy = 1;
387 if (cable->set_d0)
388 {
389 ret = cable->set_d0(handle, state);
390 }
391 handle->busy = 0;
392
393 return ret;
394 }
395
396 /**
397 * ticables_cable_set_d1:
398 * @handle: a previously allocated handle
399 * @state: logical state (0 or 1) of D1 wire.
400 *
401 * Set the electrical state of the D1 wire (if possible).
402 *
403 * Return value: 0 if successful, an error code otherwise.
404 **/
ticables_cable_set_d1(CableHandle * handle,int state)405 TIEXPORT1 int TICALL ticables_cable_set_d1(CableHandle* handle, int state)
406 {
407 const CableFncts *cable;
408 int ret = 0;
409
410 VALIDATE_HANDLE(handle);
411
412 cable = handle->cable;
413 VALIDATE_CABLEFNCTS(cable);
414
415 RETURN_IF_HANDLE_NOT_OPEN(handle);
416 RETURN_IF_HANDLE_BUSY(handle);
417
418 handle->busy = 1;
419 if (cable->set_d1)
420 {
421 ret = cable->set_d1(handle, state);
422 }
423 handle->busy = 0;
424
425 return ret;
426 }
427
428 /**
429 * ticables_cable_get_d0:
430 * @handle: a previously allocated handle
431 *
432 * Get the electrical state of the D0 wire (if possible).
433 *
434 * Return value: 0 or 1.
435 **/
ticables_cable_get_d0(CableHandle * handle)436 TIEXPORT1 int TICALL ticables_cable_get_d0(CableHandle* handle)
437 {
438 const CableFncts *cable;
439 int ret = 0;
440
441 VALIDATE_HANDLE(handle);
442
443 cable = handle->cable;
444 VALIDATE_CABLEFNCTS(cable);
445
446 RETURN_IF_HANDLE_NOT_OPEN(handle);
447 RETURN_IF_HANDLE_BUSY(handle);
448
449 handle->busy = 1;
450 if (cable->get_d0)
451 {
452 ret = cable->get_d0(handle);
453 }
454 handle->busy = 0;
455
456 return ret;
457 }
458
459 /**
460 * ticables_cable_get_d1:
461 * @handle: a previously allocated handle
462 *
463 * Get the electrical state of the D1 wire (if possible).
464 *
465 * Return value: 0 or 1.
466 **/
ticables_cable_get_d1(CableHandle * handle)467 TIEXPORT1 int TICALL ticables_cable_get_d1(CableHandle* handle)
468 {
469 const CableFncts *cable;
470 int ret = 0;
471
472 VALIDATE_HANDLE(handle);
473
474 cable = handle->cable;
475 VALIDATE_CABLEFNCTS(cable);
476
477 RETURN_IF_HANDLE_NOT_OPEN(handle);
478 RETURN_IF_HANDLE_BUSY(handle);
479
480 handle->busy = 1;
481 if (cable->get_d1)
482 {
483 ret = cable->get_d1(handle);
484 }
485 handle->busy = 0;
486
487 return ret;
488 }
489
490 /**
491 * ticables_cable_set_raw:
492 * @handle: a previously allocated handle
493 * @state: bit mask of lines to pull low
494 *
495 * Set the raw cable state (if the hardware supports raw access.) An
496 * input of 3 is the default state; 2 means to pull the D0 ("red")
497 * line low; 1 means to pull the D1 ("white") line low; 0 means both
498 * (never used in the TI link protocol.)
499 *
500 * Return value: 0 if successful, an error code otherwise.
501 **/
ticables_cable_set_raw(CableHandle * handle,int state)502 TIEXPORT1 int TICALL ticables_cable_set_raw(CableHandle* handle, int state)
503 {
504 const CableFncts *cable;
505 int ret = 0;
506
507 VALIDATE_HANDLE(handle);
508
509 cable = handle->cable;
510 VALIDATE_CABLEFNCTS(cable);
511
512 RETURN_IF_HANDLE_NOT_OPEN(handle);
513 RETURN_IF_HANDLE_BUSY(handle);
514 if (!cable->set_raw)
515 {
516 return ERR_RAW_IO_UNSUPPORTED;
517 }
518
519 handle->busy = 1;
520 if (cable->set_raw)
521 {
522 ret = cable->set_raw(handle, state);
523 }
524 handle->busy = 0;
525
526 return ret;
527 }
528
529 /**
530 * ticables_cable_get_raw:
531 * @handle: a previously allocated handle
532 * @state: pointer to variable to store current state
533 *
534 * Get the raw cable state (if the hardware supports raw access.) A
535 * bit set in the output means the line is high (1 for the D0 or "red"
536 * line, 2 for the D1 or "white" line.)
537 *
538 * Return value: 0 if successful, an error code otherwise.
539 **/
ticables_cable_get_raw(CableHandle * handle,int * state)540 TIEXPORT1 int TICALL ticables_cable_get_raw(CableHandle* handle, int *state)
541 {
542 const CableFncts *cable;
543 int ret = 0;
544
545 VALIDATE_HANDLE(handle);
546 VALIDATE_NONNULL(state);
547
548 cable = handle->cable;
549 VALIDATE_CABLEFNCTS(cable);
550
551 RETURN_IF_HANDLE_NOT_OPEN(handle);
552 RETURN_IF_HANDLE_BUSY(handle);
553 if (!cable->get_raw)
554 {
555 return ERR_RAW_IO_UNSUPPORTED;
556 }
557
558 handle->busy = 1;
559 if (cable->get_raw)
560 {
561 ret = cable->get_raw(handle, state);
562 }
563 handle->busy = 0;
564
565 return ret;
566 }
567
568 /**
569 * ticables_cable_set_device:
570 * @handle: a previously allocated handle
571 * @device: new device information
572 *
573 * Sets cable device if that makes sense.
574 *
575 * Return value: 0 if successful, an error code otherwise.
576 **/
ticables_cable_set_device(CableHandle * handle,const char * device)577 TIEXPORT1 int TICALL ticables_cable_set_device(CableHandle* handle, const char * device)
578 {
579 const CableFncts *cable;
580 int ret = 0;
581
582 VALIDATE_HANDLE(handle);
583 VALIDATE_NONNULL(device);
584
585 cable = handle->cable;
586 VALIDATE_CABLEFNCTS(cable);
587
588 RETURN_IF_HANDLE_OPEN(handle);
589 RETURN_IF_HANDLE_BUSY(handle);
590
591 handle->busy = 1;
592 if (cable->set_device)
593 {
594 ret = cable->set_device(handle, device);
595 }
596 handle->busy = 0;
597
598 return ret;
599 }
600
601 /**
602 * ticables_cable_get_device_info:
603 * @handle: a previously allocated handle
604 * @info: pointer to structure to store device info
605 *
606 * Get the type of device on the other end of the cable, if this can
607 * be determined.
608 */
ticables_cable_get_device_info(CableHandle * handle,CableDeviceInfo * info)609 TIEXPORT1 int TICALL ticables_cable_get_device_info(CableHandle *handle, CableDeviceInfo *info)
610 {
611 const CableFncts *cable;
612 int ret = 0;
613
614 VALIDATE_HANDLE(handle);
615 VALIDATE_NONNULL(info);
616
617 cable = handle->cable;
618 VALIDATE_CABLEFNCTS(cable);
619
620 RETURN_IF_HANDLE_NOT_OPEN(handle);
621 RETURN_IF_HANDLE_BUSY(handle);
622
623 handle->busy = 1;
624 if (cable->get_device_info)
625 {
626 ret = (cable->get_device_info)(handle, info);
627 }
628 else
629 {
630 info->family = CABLE_FAMILY_DBUS;
631 info->variant = CABLE_VARIANT_UNKNOWN;
632 }
633 handle->busy = 0;
634
635 return ret;
636 }
637
638 /**
639 * ticables_cable_progress_reset:
640 * @handle: a previously allocated handle
641 *
642 * Reset byte counter and timer used for computing data rate.
643 *
644 * Return value: always 0.
645 **/
ticables_progress_reset(CableHandle * handle)646 TIEXPORT1 int TICALL ticables_progress_reset(CableHandle* handle)
647 {
648 VALIDATE_HANDLE(handle);
649
650 handle->rate.count = 0;
651 TO_START(handle->rate.start);
652
653 return 0;
654 }
655
656 /**
657 * ticables_cable_progress_get:
658 * @handle: a previously allocated handle
659 * @count: number of bytes transfered
660 * @msec: time needed for the operation
661 * @rate: data rate
662 *
663 * Returns information needed to compute the transfer rate of the link cable.
664 *
665 * Return value: always 0.
666 **/
ticables_progress_get(CableHandle * handle,int * count,int * msec,float * rate)667 TIEXPORT1 int TICALL ticables_progress_get(CableHandle* handle, int* count, int* msec, float* rate)
668 {
669 VALIDATE_HANDLE(handle);
670
671 TO_START(handle->rate.current);
672
673 if (count)
674 {
675 *count = handle->rate.count;
676 }
677
678 if (msec)
679 {
680 *msec = handle->rate.current - handle->rate.start;
681 }
682
683 if (rate)
684 {
685 if (handle->rate.current > handle->rate.start)
686 *rate = (float)handle->rate.count / ((float)(handle->rate.current - handle->rate.start));
687 }
688
689 #if 0
690 if (handle->rate.current > handle->rate.start)
691 printf("<%u %u %u %u %f\n",
692 handle->rate.count, handle->rate.start, handle->rate.current,
693 handle->rate.current - handle->rate.start, (float)handle->rate.count / ((float)(handle->rate.current - handle->rate.start)));
694 #endif
695
696 return 0;
697 }
698
699 /**
700 * ticables_cable_put:
701 * @handle: a previously allocated handle
702 * @data: data to send
703 *
704 * Send one byte from PC to hand-held.
705 * Convenient function implemented for compatibility.
706 *
707 * Return value: 0 if successful, an error code otherwise.
708 **/
ticables_cable_put(CableHandle * handle,uint8_t data)709 TIEXPORT1 int TICALL ticables_cable_put(CableHandle* handle, uint8_t data)
710 {
711 return ticables_cable_send(handle, &data, 1);
712 }
713
714 /**
715 * ticables_cable_get:
716 * @handle: a previously allocated handle
717 * @data: data to receive
718 *
719 * Receive one byte from hand-held to PC.
720 * Convenient function implemented for compatibility.
721 *
722 * Return value: 0 if successful, an error code otherwise.
723 **/
ticables_cable_get(CableHandle * handle,uint8_t * data)724 TIEXPORT1 int TICALL ticables_cable_get(CableHandle* handle, uint8_t *data)
725 {
726 return ticables_cable_recv(handle, data, 1);
727 }
728
729 /**
730 * ticables_cable_get_pre_send_hook:
731 *
732 * Get the current pre send hook function pointer.
733 *
734 * Return value: a function pointer.
735 */
ticables_cable_get_pre_send_hook(CableHandle * handle)736 TIEXPORT1 ticables_pre_send_hook_type TICALL ticables_cable_get_pre_send_hook(CableHandle *handle)
737 {
738 if (handle == NULL)
739 {
740 ticables_critical("%s: handle is NULL", __FUNCTION__);
741 return NULL;
742 }
743
744 return handle->pre_send_hook;
745 }
746
747 /**
748 * ticables_cable_set_pre_send_hook:
749 * @hook: new pre send hook
750 *
751 * Set the current pre send hook function pointer.
752 *
753 * Return value: the previous pre send hook, so that the caller can use it to chain hooks.
754 */
ticables_cable_set_pre_send_hook(CableHandle * handle,ticables_pre_send_hook_type hook)755 TIEXPORT1 ticables_pre_send_hook_type TICALL ticables_cable_set_pre_send_hook(CableHandle *handle, ticables_pre_send_hook_type hook)
756 {
757 ticables_pre_send_hook_type old_hook;
758
759 if (handle == NULL)
760 {
761 ticables_critical("%s: handle is NULL", __FUNCTION__);
762 return NULL;
763 }
764
765 old_hook = handle->pre_send_hook;
766 handle->pre_send_hook = hook;
767
768 return old_hook;
769 }
770
771 /**
772 * ticables_cable_get_post_send_hook:
773 *
774 * Get the current post send hook function pointer.
775 *
776 * Return value: a function pointer.
777 */
ticables_cable_get_post_send_hook(CableHandle * handle)778 TIEXPORT1 ticables_post_send_hook_type TICALL ticables_cable_get_post_send_hook(CableHandle *handle)
779 {
780 if (handle == NULL)
781 {
782 ticables_critical("%s: handle is NULL", __FUNCTION__);
783 return NULL;
784 }
785
786 return handle->post_send_hook;
787 }
788
789 /**
790 * ticables_cable_set_post_send_hook:
791 * @hook: new post send hook
792 *
793 * Set the current post send hook function pointer.
794 *
795 * Return value: the previous post send hook, so that the caller can use it to chain hooks.
796 */
ticables_cable_set_post_send_hook(CableHandle * handle,ticables_post_send_hook_type hook)797 TIEXPORT1 ticables_post_send_hook_type TICALL ticables_cable_set_post_send_hook(CableHandle *handle, ticables_post_send_hook_type hook)
798 {
799 ticables_post_send_hook_type old_hook;
800
801 if (handle == NULL)
802 {
803 ticables_critical("%s: handle is NULL", __FUNCTION__);
804 return NULL;
805 }
806
807 old_hook = handle->post_send_hook;
808 handle->post_send_hook = hook;
809
810 return old_hook;
811 }
812
813 /**
814 * ticables_cable_get_pre_recv_hook:
815 *
816 * Get the current pre recv hook function pointer.
817 *
818 * Return value: a function pointer.
819 */
ticables_cable_get_pre_recv_hook(CableHandle * handle)820 TIEXPORT1 ticables_pre_recv_hook_type TICALL ticables_cable_get_pre_recv_hook(CableHandle *handle)
821 {
822 if (handle == NULL)
823 {
824 ticables_critical("%s: handle is NULL", __FUNCTION__);
825 return NULL;
826 }
827
828 return handle->pre_recv_hook;
829 }
830
831 /**
832 * ticables_cable_set_pre_recv_hook:
833 * @hook: new pre recv hook
834 *
835 * Set the current pre recv hook function pointer.
836 *
837 * Return value: the previous pre recv hook, so that the caller can use it to chain hooks.
838 */
ticables_cable_set_pre_recv_hook(CableHandle * handle,ticables_pre_recv_hook_type hook)839 TIEXPORT1 ticables_pre_recv_hook_type TICALL ticables_cable_set_pre_recv_hook(CableHandle *handle, ticables_pre_recv_hook_type hook)
840 {
841 ticables_pre_recv_hook_type old_hook;
842
843 if (handle == NULL)
844 {
845 ticables_critical("%s: handle is NULL", __FUNCTION__);
846 return NULL;
847 }
848
849 old_hook = handle->pre_recv_hook;
850 handle->pre_recv_hook = hook;
851
852 return old_hook;
853 }
854
855 /**
856 * ticables_cable_get_post_recv_hook:
857 *
858 * Get the current post recv hook function pointer.
859 *
860 * Return value: a function pointer.
861 */
ticables_cable_get_post_recv_hook(CableHandle * handle)862 TIEXPORT1 ticables_post_recv_hook_type TICALL ticables_cable_get_post_recv_hook(CableHandle *handle)
863 {
864 if (handle == NULL)
865 {
866 ticables_critical("%s: handle is NULL", __FUNCTION__);
867 return NULL;
868 }
869
870 return handle->post_recv_hook;
871 }
872
873 /**
874 * ticables_cable_set_post_recv_hook:
875 * @hook: new post recv hook
876 *
877 * Set the current post recv hook function pointer.
878 *
879 * Return value: the previous post recv hook, so that the caller can use it to chain hooks.
880 */
ticables_cable_set_post_recv_hook(CableHandle * handle,ticables_post_recv_hook_type hook)881 TIEXPORT1 ticables_post_recv_hook_type TICALL ticables_cable_set_post_recv_hook(CableHandle *handle, ticables_post_recv_hook_type hook)
882 {
883 ticables_post_recv_hook_type old_hook;
884
885 if (handle == NULL)
886 {
887 ticables_critical("%s: handle is NULL", __FUNCTION__);
888 return NULL;
889 }
890
891 old_hook = handle->post_recv_hook;
892 handle->post_recv_hook = hook;
893
894 return old_hook;
895 }
896