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