Use better names for internal functions
[bcusdk.git] / eibd / client / eibclient.c
blobb36c421e2784665a94a1f0da455a448a0a6b6b04
1 /*
2 EIBD client library
3 Copyright (C) 2005-2007 Martin Kögler <mkoegler@auto.tuwien.ac.at>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 In addition to the permissions in the GNU General Public License,
11 you may link the compiled version of this file into combinations
12 with other programs, and distribute those combinations without any
13 restriction coming from the use of this file. (The General Public
14 License restrictions do apply in other respects; for example, they
15 cover modification of the file, and distribution when not linked into
16 a combine executable.)
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32 #include <netinet/in.h>
33 #include <netdb.h>
34 #include <errno.h>
36 #include "config.h"
38 #include "eibclient.h"
39 #include "eibtypes.h"
41 /** unsigned char */
42 typedef uint8_t uchar;
44 /** EIB Connection internal */
45 struct _EIBConnection
47 int (*complete) (EIBConnection *);
48 /** file descriptor */
49 int fd;
50 unsigned readlen;
51 /** buffer */
52 uchar *buf;
53 /** buffer size */
54 unsigned buflen;
55 /** used buffer */
56 unsigned size;
57 struct
59 int len;
60 uint8_t *buf;
61 int16_t *ptr1;
62 uint8_t *ptr2;
63 uint8_t *ptr3;
64 uint16_t *ptr4;
65 } req;
68 /** extracts TYPE code of an eibd packet */
69 #define EIBTYPE(con) (((con)->buf[0]<<8)|((con)->buf[1]))
70 /** sets TYPE code for an eibd packet*/
71 #define EIBSETTYPE(buf,type) do{(buf)[0]=(type>>8)&0xff;(buf)[1]=(type)&0xff;}while(0)
73 /** set EIB address */
74 #define EIBSETADDR(buf,type) do{(buf)[0]=(type>>8)&0xff;(buf)[1]=(type)&0xff;}while(0)
76 /** resolve host name */
77 static int
78 GetHostIP (struct sockaddr_in *sock, const char *Name)
80 #ifdef HAVE_GETHOSTBYNAME_R
81 int len = 2000;
82 struct hostent host;
83 char *buf = (char *) malloc (len);
84 int res;
85 int err;
86 #endif
87 struct hostent *h;
88 if (!Name)
89 return 0;
90 memset (sock, 0, sizeof (*sock));
91 #ifdef HAVE_GETHOSTBYNAME_R
94 res = gethostbyname_r (Name, &host, buf, len, &h, &err);
95 if (res == ERANGE)
97 len += 2000;
98 buf = (char *) realloc (buf, len);
100 if (!buf)
101 return 0;
103 while (res == ERANGE);
105 if (res || !h)
107 free (buf);
108 return 0;
110 #else
111 h = gethostbyname (Name);
112 if (!h)
113 return 0;
114 #endif
115 sock->sin_family = h->h_addrtype;
116 sock->sin_addr.s_addr = (*((unsigned long *) h->h_addr_list[0]));
117 #ifdef HAVE_GETHOSTBYNAME_R
118 if (buf)
119 free (buf);
120 #endif
121 return 1;
125 EIBClose (EIBConnection * con)
127 if (!con)
129 errno = EINVAL;
130 return -1;
132 close (con->fd);
133 if (con->buf)
134 free (con->buf);
135 free (con);
136 return 0;
139 EIBConnection *
140 EIBSocketLocal (const char *path)
142 EIBConnection *con = (EIBConnection *) malloc (sizeof (EIBConnection));
143 struct sockaddr_un addr;
144 if (!con)
146 errno = ENOMEM;
147 return 0;
149 addr.sun_family = AF_LOCAL;
150 strncpy (addr.sun_path, path, sizeof (addr.sun_path));
151 addr.sun_path[sizeof (addr.sun_path) - 1] = 0;
153 con->fd = socket (AF_LOCAL, SOCK_STREAM, 0);
154 if (con->fd == -1)
156 free (con);
157 return 0;
160 if (connect (con->fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
162 int saveerr = errno;
163 close (con->fd);
164 free (con);
165 errno = saveerr;
166 return 0;
168 con->buflen = 0;
169 con->buf = 0;
170 con->readlen = 0;
172 return con;
175 EIBConnection *
176 EIBSocketRemote (const char *host, int port)
178 EIBConnection *con = (EIBConnection *) malloc (sizeof (EIBConnection));
179 struct sockaddr_in addr;
180 if (!con)
182 errno = ENOMEM;
183 return 0;
186 if (!GetHostIP (&addr, host))
188 free (con);
189 errno = ECONNREFUSED;
190 return 0;
192 addr.sin_port = htons (port);
194 con->fd = socket (addr.sin_family, SOCK_STREAM, 0);
195 if (con->fd == -1)
197 free (con);
198 return 0;
201 if (connect (con->fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
203 int saveerr = errno;
204 close (con->fd);
205 free (con);
206 errno = saveerr;
207 return 0;
209 con->buflen = 0;
210 con->buf = 0;
211 con->readlen = 0;
213 return con;
216 EIBConnection *
217 EIBSocketURL (const char *url)
219 if (!url)
221 errno = EINVAL;
222 return 0;
224 if (!strncmp (url, "local:", 6))
226 return EIBSocketLocal (url + 6);
228 if (!strncmp (url, "ip:", 3))
230 char *a = strdup (url + 3);
231 char *b;
232 int port;
233 EIBConnection *c;
234 if (!a)
236 errno = ENOMEM;
237 return 0;
239 for (b = a; *b; b++)
240 if (*b == ':')
241 break;
242 if (*b == ':')
244 *b = 0;
245 port = atoi (b + 1);
247 else
248 port = 6720;
249 c = EIBSocketRemote (a, port);
250 free (a);
251 return c;
253 errno = EINVAL;
254 return 0;
257 /** send a request to eibd */
258 static int
259 _EIB_SendRequest (EIBConnection * con, unsigned int size, uchar * data)
261 uchar head[2];
262 int i, start;
264 if (size > 0xffff || size < 2)
266 errno = EINVAL;
267 return -1;
269 head[0] = (size >> 8) & 0xff;
270 head[1] = (size) & 0xff;
272 lp1:
273 i = write (con->fd, &head, 2);
274 if (i == -1 && errno == EINTR)
275 goto lp1;
276 if (i == -1)
277 return -1;
278 if (i != 2)
280 errno = ECONNRESET;
281 return -1;
283 start = 0;
284 lp2:
285 i = write (con->fd, data + start, size - start);
286 if (i == -1 && errno == EINTR)
287 goto lp2;
288 if (i == -1)
289 return -1;
290 if (i == 0)
292 errno = ECONNRESET;
293 return -1;
295 start += i;
296 if (start < size)
297 goto lp2;
298 return 0;
301 static int
302 _EIB_CheckRequest (EIBConnection * con, int block)
304 int i;
305 struct timeval tv;
306 fd_set readset;
308 if (!block)
310 tv.tv_sec = 0;
311 tv.tv_usec = 0;
312 FD_ZERO (&readset);
313 FD_SET (con->fd, &readset);
314 if (select (con->fd + 1, &readset, 0, 0, &tv) == -1)
315 return -1;
317 if (!FD_ISSET (con->fd, &readset))
318 return 0;
321 if (con->readlen < 2)
323 uchar head[2];
324 head[0] = (con->size >> 8) & 0xff;
325 i = read (con->fd, &head + con->readlen, 2 - con->readlen);
326 if (i == -1 && errno == EINTR)
327 return 0;
328 if (i == -1)
329 return -1;
330 if (i == 0)
332 errno = ECONNRESET;
333 return -1;
335 con->readlen += i;
336 con->size = (head[0] << 8) | (head[1]);
337 if (con->size < 2)
339 errno = ECONNRESET;
340 return -1;
343 if (con->size > con->buflen)
345 con->buf = (uchar *) realloc (con->buf, con->size);
346 if (con->buf == 0)
348 con->buflen = 0;
349 errno = ENOMEM;
350 return -1;
352 con->buflen = con->size;
354 return 0;
357 if (con->readlen < con->size + 2)
360 read (con->fd, con->buf + (con->readlen - 2),
361 con->size - (con->readlen - 2));
362 if (i == -1 && errno == EINTR)
363 return 0;
364 if (i == -1)
365 return -1;
366 if (i == 0)
368 errno = ECONNRESET;
369 return -1;
371 con->readlen += i;
373 return 0;
376 /** receive packet from eibd */
377 static int
378 _EIB_GetRequest (EIBConnection * con)
382 if (_EIB_CheckRequest (con, 1) == -1)
383 return -1;
385 while (con->readlen < 2
386 || (con->readlen >= 2 && con->readlen < con->size + 2));
388 con->readlen = 0;
390 return 0;
394 EIB_Poll_Complete (EIBConnection * con)
396 if (!con)
398 errno = EINVAL;
399 return -1;
401 if (_EIB_CheckRequest (con, 0) == -1)
402 return -1;
403 return (con->readlen >= 2 && con->readlen >= con->size + 2) ? 1 : 0;
407 EIB_Poll_FD (EIBConnection * con)
409 if (!con)
411 errno = EINVAL;
412 return -1;
414 return con->fd;
418 EIBComplete (EIBConnection * con)
420 if (!con)
422 errno = EINVAL;
423 return -1;
425 return con->complete (con);
428 static int
429 OpenBusmonitor_complete (EIBConnection * con)
431 int i;
432 i = _EIB_GetRequest (con);
433 if (i == -1)
434 return -1;
436 if (EIBTYPE (con) == EIB_CONNECTION_INUSE)
438 errno = EBUSY;
439 return -1;
441 if (EIBTYPE (con) != EIB_OPEN_BUSMONITOR)
443 errno = ECONNRESET;
444 return -1;
446 return 0;
450 EIBOpenBusmonitor_async (EIBConnection * con)
452 uchar head[2];
453 int i;
454 if (!con)
456 errno = EINVAL;
457 return -1;
459 EIBSETTYPE (head, EIB_OPEN_BUSMONITOR);
460 i = _EIB_SendRequest (con, 2, head);
461 if (i == -1)
462 return -1;
464 con->complete = OpenBusmonitor_complete;
465 return 0;
469 EIBOpenBusmonitor (EIBConnection * con)
471 if (EIBOpenBusmonitor_async (con) == -1)
472 return -1;
473 return EIBComplete (con);
476 static int
477 OpenBusmonitorText_complete (EIBConnection * con)
479 int i;
480 i = _EIB_GetRequest (con);
481 if (i == -1)
482 return -1;
484 if (EIBTYPE (con) == EIB_CONNECTION_INUSE)
486 errno = EBUSY;
487 return -1;
489 if (EIBTYPE (con) != EIB_OPEN_BUSMONITOR_TEXT)
491 errno = ECONNRESET;
492 return -1;
494 return 0;
498 EIBOpenBusmonitorText_async (EIBConnection * con)
500 uchar head[2];
501 int i;
502 if (!con)
504 errno = EINVAL;
505 return -1;
507 EIBSETTYPE (head, EIB_OPEN_BUSMONITOR_TEXT);
508 i = _EIB_SendRequest (con, 2, head);
509 if (i == -1)
510 return -1;
511 con->complete = OpenBusmonitorText_complete;
512 return 0;
516 EIBOpenBusmonitorText (EIBConnection * con)
518 if (EIBOpenBusmonitorText_async (con) == -1)
519 return -1;
520 return EIBComplete (con);
523 static int
524 OpenVBusmonitor_complete (EIBConnection * con)
526 int i;
527 i = _EIB_GetRequest (con);
528 if (i == -1)
529 return -1;
531 if (EIBTYPE (con) == EIB_CONNECTION_INUSE)
533 errno = EBUSY;
534 return -1;
536 if (EIBTYPE (con) != EIB_OPEN_VBUSMONITOR)
538 errno = ECONNRESET;
539 return -1;
541 return 0;
545 EIBOpenVBusmonitor_async (EIBConnection * con)
547 uchar head[2];
548 int i;
549 if (!con)
551 errno = EINVAL;
552 return -1;
554 EIBSETTYPE (head, EIB_OPEN_VBUSMONITOR);
555 i = _EIB_SendRequest (con, 2, head);
556 if (i == -1)
557 return -1;
558 con->complete = OpenVBusmonitor_complete;
559 return 0;
563 EIBOpenVBusmonitor (EIBConnection * con)
565 if (EIBOpenVBusmonitor_async (con) == -1)
566 return -1;
567 return EIBComplete (con);
570 static int
571 OpenVBusmonitorText_complete (EIBConnection * con)
573 int i;
574 i = _EIB_GetRequest (con);
575 if (i == -1)
576 return -1;
578 if (EIBTYPE (con) == EIB_CONNECTION_INUSE)
580 errno = EBUSY;
581 return -1;
583 if (EIBTYPE (con) != EIB_OPEN_VBUSMONITOR_TEXT)
585 errno = ECONNRESET;
586 return -1;
588 return 0;
592 EIBOpenVBusmonitorText_async (EIBConnection * con)
594 uchar head[2];
595 int i;
596 if (!con)
598 errno = EINVAL;
599 return -1;
601 EIBSETTYPE (head, EIB_OPEN_VBUSMONITOR_TEXT);
602 i = _EIB_SendRequest (con, 2, head);
603 if (i == -1)
604 return -1;
605 con->complete = OpenVBusmonitorText_complete;
606 return 0;
610 EIBOpenVBusmonitorText (EIBConnection * con)
612 if (EIBOpenVBusmonitorText_async (con) == -1)
613 return -1;
614 return EIBComplete (con);
618 EIBGetBusmonitorPacket (EIBConnection * con, int maxlen, uint8_t * buf)
620 int i;
621 if (!con || !buf)
623 errno = EINVAL;
624 return -1;
627 i = _EIB_GetRequest (con);
628 if (i == -1)
629 return -1;
631 if (EIBTYPE (con) != EIB_BUSMONITOR_PACKET)
633 errno = ECONNRESET;
634 return -1;
636 i = con->size - 2;
637 if (i > maxlen)
638 i = maxlen;
639 memcpy (buf, con->buf + 2, i);
640 return i;
643 static int
644 OpenT_Connection_complete (EIBConnection * con)
646 int i;
647 i = _EIB_GetRequest (con);
648 if (i == -1)
649 return -1;
651 if (EIBTYPE (con) != EIB_OPEN_T_CONNECTION)
653 errno = ECONNRESET;
654 return -1;
656 return 0;
660 EIBOpenT_Connection_async (EIBConnection * con, eibaddr_t dest)
662 uchar head[5];
663 int i;
664 if (!con)
666 errno = EINVAL;
667 return -1;
669 EIBSETTYPE (head, EIB_OPEN_T_CONNECTION);
670 EIBSETADDR (head + 2, dest);
671 i = _EIB_SendRequest (con, 5, head);
672 if (i == -1)
673 return -1;
674 con->complete = OpenT_Connection_complete;
675 return 0;
679 EIBOpenT_Connection (EIBConnection * con, eibaddr_t dest)
681 if (EIBOpenT_Connection_async (con, dest) == -1)
682 return -1;
683 return EIBComplete (con);
686 static int
687 OpenT_TPDU_complete (EIBConnection * con)
689 int i;
690 i = _EIB_GetRequest (con);
691 if (i == -1)
692 return -1;
694 if (EIBTYPE (con) != EIB_OPEN_T_TPDU)
696 errno = ECONNRESET;
697 return -1;
699 return 0;
703 EIBOpenT_TPDU_async (EIBConnection * con, eibaddr_t src)
705 uchar head[5];
706 int i;
707 if (!con)
709 errno = EINVAL;
710 return -1;
712 EIBSETTYPE (head, EIB_OPEN_T_TPDU);
713 EIBSETADDR (head + 2, src);
714 i = _EIB_SendRequest (con, 5, head);
715 if (i == -1)
716 return -1;
717 con->complete = OpenT_TPDU_complete;
718 return 0;
722 EIBOpenT_TPDU (EIBConnection * con, eibaddr_t src)
724 if (EIBOpenT_TPDU_async (con, src) == -1)
725 return -1;
726 return EIBComplete (con);
729 static int
730 OpenT_Individual_complete (EIBConnection * con)
732 int i;
733 i = _EIB_GetRequest (con);
734 if (i == -1)
735 return -1;
737 if (EIBTYPE (con) != EIB_OPEN_T_INDIVIDUAL)
739 errno = ECONNRESET;
740 return -1;
742 return 0;
746 EIBOpenT_Individual_async (EIBConnection * con, eibaddr_t dest,
747 int write_only)
749 uchar head[5];
750 int i;
751 if (!con)
753 errno = EINVAL;
754 return -1;
756 EIBSETTYPE (head, EIB_OPEN_T_INDIVIDUAL);
757 EIBSETADDR (head + 2, dest);
758 head[4] = (write_only ? 0xff : 0);
759 i = _EIB_SendRequest (con, 5, head);
760 if (i == -1)
761 return -1;
762 con->complete = OpenT_Individual_complete;
763 return 0;
767 EIBOpenT_Individual (EIBConnection * con, eibaddr_t dest, int write_only)
769 if (EIBOpenT_Individual_async (con, dest, write_only) == -1)
770 return -1;
771 return EIBComplete (con);
774 static int
775 OpenT_Group_complete (EIBConnection * con)
777 int i;
778 i = _EIB_GetRequest (con);
779 if (i == -1)
780 return -1;
782 if (EIBTYPE (con) != EIB_OPEN_T_GROUP)
784 errno = ECONNRESET;
785 return -1;
787 return 0;
791 EIBOpenT_Group_async (EIBConnection * con, eibaddr_t dest, int write_only)
793 uchar head[5];
794 int i;
795 if (!con)
797 errno = EINVAL;
798 return -1;
800 EIBSETTYPE (head, EIB_OPEN_T_GROUP);
801 EIBSETADDR (head + 2, dest);
802 head[4] = (write_only ? 0xff : 0);
803 i = _EIB_SendRequest (con, 5, head);
804 if (i == -1)
805 return -1;
806 con->complete = OpenT_Group_complete;
807 return 0;
811 EIBOpenT_Group (EIBConnection * con, eibaddr_t dest, int write_only)
813 if (EIBOpenT_Group_async (con, dest, write_only) == -1)
814 return -1;
815 return EIBComplete (con);
818 static int
819 OpenT_Broadcast_complete (EIBConnection * con)
821 int i;
822 i = _EIB_GetRequest (con);
823 if (i == -1)
824 return -1;
826 if (EIBTYPE (con) != EIB_OPEN_T_BROADCAST)
828 errno = ECONNRESET;
829 return -1;
831 return 0;
835 EIBOpenT_Broadcast_async (EIBConnection * con, int write_only)
837 uchar head[5];
838 int i;
839 if (!con)
841 errno = EINVAL;
842 return -1;
844 EIBSETTYPE (head, EIB_OPEN_T_BROADCAST);
845 head[4] = (write_only ? 0xff : 0);
846 i = _EIB_SendRequest (con, 5, head);
847 if (i == -1)
848 return -1;
849 con->complete = OpenT_Broadcast_complete;
850 return 0;
854 EIBOpenT_Broadcast (EIBConnection * con, int write_only)
856 if (EIBOpenT_Broadcast_async (con, write_only) == -1)
857 return -1;
858 return EIBComplete (con);
862 EIBSendTPDU (EIBConnection * con, eibaddr_t dest, int len, uint8_t * data)
864 uchar *ibuf;
865 int i;
866 if (!con)
868 errno = EINVAL;
869 return -1;
871 if (len < 2 || !data)
873 errno = EINVAL;
874 return -1;
876 ibuf = (uchar *) malloc (len + 4);
877 if (!ibuf)
879 errno = ENOMEM;
880 return -1;
882 EIBSETTYPE (ibuf, EIB_APDU_PACKET);
883 EIBSETADDR (ibuf + 2, dest);
884 memcpy (ibuf + 4, data, len);
885 i = _EIB_SendRequest (con, len + 4, ibuf);
886 free (ibuf);
887 return i;
891 EIBSendAPDU (EIBConnection * con, int len, uint8_t * data)
893 uchar *ibuf;
894 int i;
895 if (!con)
897 errno = EINVAL;
898 return -1;
900 if (len < 2 || !data)
902 errno = EINVAL;
903 return -1;
905 ibuf = (uchar *) malloc (len + 2);
906 if (!ibuf)
908 errno = ENOMEM;
909 return -1;
911 EIBSETTYPE (ibuf, EIB_APDU_PACKET);
912 memcpy (ibuf + 2, data, len);
913 i = _EIB_SendRequest (con, len + 2, ibuf);
914 free (ibuf);
915 return i;
919 EIBGetAPDU (EIBConnection * con, int maxlen, uint8_t * buf)
921 int i;
922 if (!con || !buf)
924 errno = EINVAL;
925 return -1;
928 i = _EIB_GetRequest (con);
929 if (i == -1)
930 return -1;
932 if (EIBTYPE (con) != EIB_APDU_PACKET)
934 errno = ECONNRESET;
935 return -1;
937 i = con->size - 2;
938 if (i > maxlen)
939 i = maxlen;
940 memcpy (buf, con->buf + 2, i);
941 return i;
945 EIBGetAPDU_Src (EIBConnection * con, int maxlen, uint8_t * buf,
946 eibaddr_t * src)
948 int i;
949 if (!con || !buf)
951 errno = EINVAL;
952 return -1;
955 i = _EIB_GetRequest (con);
956 if (i == -1)
957 return -1;
959 if (EIBTYPE (con) != EIB_APDU_PACKET || con->size < 4)
961 errno = ECONNRESET;
962 return -1;
964 i = con->size - 4;
965 if (i > maxlen)
966 i = maxlen;
967 memcpy (buf, con->buf + 4, i);
968 if (src)
969 *src = (con->buf[2] << 8) | (con->buf[3]);
970 return i;
973 static int
974 Open_GroupSocket_complete (EIBConnection * con)
976 int i;
977 i = _EIB_GetRequest (con);
978 if (i == -1)
979 return -1;
981 if (EIBTYPE (con) != EIB_OPEN_GROUPCON)
983 errno = ECONNRESET;
984 return -1;
986 return 0;
990 EIBOpen_GroupSocket_async (EIBConnection * con, int write_only)
992 uchar head[5];
993 int i;
994 if (!con)
996 errno = EINVAL;
997 return -1;
999 EIBSETTYPE (head, EIB_OPEN_GROUPCON);
1000 head[4] = (write_only ? 0xff : 0);
1001 i = _EIB_SendRequest (con, 5, head);
1002 if (i == -1)
1003 return -1;
1004 con->complete = Open_GroupSocket_complete;
1005 return 0;
1009 EIBOpen_GroupSocket (EIBConnection * con, int write_only)
1011 if (EIBOpen_GroupSocket_async (con, write_only) == -1)
1012 return -1;
1013 return EIBComplete (con);
1017 EIBGetGroup_Src (EIBConnection * con, int maxlen, uint8_t * buf,
1018 eibaddr_t * src, eibaddr_t * dest)
1020 int i;
1021 if (!con || !buf)
1023 errno = EINVAL;
1024 return -1;
1027 i = _EIB_GetRequest (con);
1028 if (i == -1)
1029 return -1;
1031 if (EIBTYPE (con) != EIB_GROUP_PACKET || con->size < 6)
1033 errno = ECONNRESET;
1034 return -1;
1036 i = con->size - 6;
1037 if (i > maxlen)
1038 i = maxlen;
1039 memcpy (buf, con->buf + 6, i);
1040 if (src)
1041 *src = (con->buf[2] << 8) | (con->buf[3]);
1042 if (dest)
1043 *dest = (con->buf[4] << 8) | (con->buf[5]);
1044 return i;
1048 EIBSendGroup (EIBConnection * con, eibaddr_t dest, int len, uint8_t * data)
1050 uchar *ibuf;
1051 int i;
1052 if (!con)
1054 errno = EINVAL;
1055 return -1;
1057 if (len < 2 || !data)
1059 errno = EINVAL;
1060 return -1;
1062 ibuf = (uchar *) malloc (len + 4);
1063 if (!ibuf)
1065 errno = ENOMEM;
1066 return -1;
1068 EIBSETTYPE (ibuf, EIB_GROUP_PACKET);
1069 EIBSETADDR (ibuf + 2, dest);
1070 memcpy (ibuf + 4, data, len);
1071 i = _EIB_SendRequest (con, len + 4, ibuf);
1072 free (ibuf);
1073 return i;
1076 static int
1077 M_ReadIndividualAddresses_complete (EIBConnection * con)
1079 int i;
1080 i = _EIB_GetRequest (con);
1081 if (i == -1)
1082 return -1;
1083 if (EIBTYPE (con) != EIB_M_INDIVIDUAL_ADDRESS_READ)
1085 errno = ECONNRESET;
1086 return -1;
1088 i = con->size - 2;
1089 if (i > con->req.len)
1090 i = con->req.len;
1091 memcpy (con->req.buf, con->buf + 2, i);
1092 return i;
1096 EIB_M_ReadIndividualAddresses_async (EIBConnection * con, int maxlen,
1097 uint8_t * buf)
1099 uchar head[2];
1100 if (!con)
1102 errno = EINVAL;
1103 return -1;
1105 con->req.len = maxlen;
1106 con->req.buf = buf;
1107 EIBSETTYPE (head, EIB_M_INDIVIDUAL_ADDRESS_READ);
1108 if (_EIB_SendRequest (con, 2, head) == -1)
1109 return -1;
1110 con->complete = M_ReadIndividualAddresses_complete;
1111 return 0;
1115 EIB_M_ReadIndividualAddresses (EIBConnection * con, int maxlen, uint8_t * buf)
1117 if (EIB_M_ReadIndividualAddresses_async (con, maxlen, buf) == -1)
1118 return -1;
1119 return EIBComplete (con);
1122 static int
1123 M_Progmode_On_complete (EIBConnection * con)
1125 int i;
1126 i = _EIB_GetRequest (con);
1127 if (i == -1)
1128 return -1;
1129 if (EIBTYPE (con) != EIB_PROG_MODE)
1131 errno = ECONNRESET;
1132 return -1;
1134 return 0;
1138 EIB_M_Progmode_On_async (EIBConnection * con, eibaddr_t dest)
1140 uchar head[5];
1141 if (!con)
1143 errno = EINVAL;
1144 return -1;
1146 EIBSETTYPE (head, EIB_PROG_MODE);
1147 EIBSETADDR (head + 2, dest);
1148 head[4] = 1;
1149 if (_EIB_SendRequest (con, 5, head) == -1)
1150 return -1;
1151 con->complete = M_Progmode_On_complete;
1152 return 0;
1156 EIB_M_Progmode_On (EIBConnection * con, eibaddr_t dest)
1158 if (EIB_M_Progmode_On_async (con, dest) == -1)
1159 return -1;
1160 return EIBComplete (con);
1163 static int
1164 M_Progmode_Off_complete (EIBConnection * con)
1166 int i;
1167 i = _EIB_GetRequest (con);
1168 if (i == -1)
1169 return -1;
1170 if (EIBTYPE (con) != EIB_PROG_MODE)
1172 errno = ECONNRESET;
1173 return -1;
1175 return 0;
1179 EIB_M_Progmode_Off_async (EIBConnection * con, eibaddr_t dest)
1181 uchar head[5];
1182 if (!con)
1184 errno = EINVAL;
1185 return -1;
1187 EIBSETTYPE (head, EIB_PROG_MODE);
1188 EIBSETADDR (head + 2, dest);
1189 head[4] = 0;
1190 if (_EIB_SendRequest (con, 5, head) == -1)
1191 return -1;
1192 con->complete = M_Progmode_Off_complete;
1193 return 0;
1197 EIB_M_Progmode_Off (EIBConnection * con, eibaddr_t dest)
1199 if (EIB_M_Progmode_Off_async (con, dest) == -1)
1200 return -1;
1201 return EIBComplete (con);
1204 static int
1205 M_Progmode_Toggle_complete (EIBConnection * con)
1207 int i;
1208 i = _EIB_GetRequest (con);
1209 if (i == -1)
1210 return -1;
1211 if (EIBTYPE (con) != EIB_PROG_MODE)
1213 errno = ECONNRESET;
1214 return -1;
1216 return 0;
1220 EIB_M_Progmode_Toggle_async (EIBConnection * con, eibaddr_t dest)
1222 uchar head[5];
1223 if (!con)
1225 errno = EINVAL;
1226 return -1;
1228 EIBSETTYPE (head, EIB_PROG_MODE);
1229 EIBSETADDR (head + 2, dest);
1230 head[4] = 2;
1231 if (_EIB_SendRequest (con, 5, head) == -1)
1232 return -1;
1233 con->complete = M_Progmode_Toggle_complete;
1234 return 0;
1238 EIB_M_Progmode_Toggle (EIBConnection * con, eibaddr_t dest)
1240 if (EIB_M_Progmode_Toggle (con, dest) == -1)
1241 return -1;
1242 return EIBComplete (con);
1245 static int
1246 M_Progmode_Status_complete (EIBConnection * con)
1248 int i;
1249 i = _EIB_GetRequest (con);
1250 if (i == -1)
1251 return -1;
1252 if (EIBTYPE (con) != EIB_PROG_MODE || con->size < 3)
1254 errno = ECONNRESET;
1255 return -1;
1257 return con->buf[2];
1261 EIB_M_Progmode_Status_async (EIBConnection * con, eibaddr_t dest)
1263 uchar head[5];
1264 if (!con)
1266 errno = EINVAL;
1267 return -1;
1269 EIBSETTYPE (head, EIB_PROG_MODE);
1270 EIBSETADDR (head + 2, dest);
1271 head[4] = 3;
1272 if (_EIB_SendRequest (con, 5, head) == -1)
1273 return -1;
1274 con->complete = M_Progmode_Status_complete;
1275 return 0;
1279 EIB_M_Progmode_Status (EIBConnection * con, eibaddr_t dest)
1281 if (EIB_M_Progmode_Status (con, dest) == -1)
1282 return -1;
1283 return EIBComplete (con);
1286 static int
1287 M_GetMaskVersion_complete (EIBConnection * con)
1289 int i;
1290 i = _EIB_GetRequest (con);
1291 if (i == -1)
1292 return -1;
1293 if (EIBTYPE (con) != EIB_MASK_VERSION || con->size < 4)
1295 errno = ECONNRESET;
1296 return -1;
1298 return (con->buf[2] << 8) | (con->buf[3]);
1302 EIB_M_GetMaskVersion_async (EIBConnection * con, eibaddr_t dest)
1304 uchar head[4];
1305 if (!con)
1307 errno = EINVAL;
1308 return -1;
1310 EIBSETTYPE (head, EIB_MASK_VERSION);
1311 EIBSETADDR (head + 2, dest);
1312 if (_EIB_SendRequest (con, 4, head) == -1)
1313 return -1;
1314 con->complete = M_GetMaskVersion_complete;
1315 return 0;
1319 EIB_M_GetMaskVersion (EIBConnection * con, eibaddr_t dest)
1321 if (EIB_M_GetMaskVersion_async (con, dest) == -1)
1322 return -1;
1323 return EIBComplete (con);
1326 static int
1327 M_WriteIndividualAddress_complete (EIBConnection * con)
1329 int i;
1330 i = _EIB_GetRequest (con);
1331 if (i == -1)
1332 return -1;
1333 if (EIBTYPE (con) == EIB_ERROR_ADDR_EXISTS)
1335 errno = EADDRINUSE;
1336 return -1;
1338 if (EIBTYPE (con) == EIB_M_INDIVIDUAL_ADDRESS_WRITE)
1340 return 0;
1342 if (EIBTYPE (con) == EIB_ERROR_TIMEOUT)
1344 errno = ETIMEDOUT;
1345 return -1;
1347 if (EIBTYPE (con) == EIB_ERROR_MORE_DEVICE)
1349 errno = EADDRNOTAVAIL;
1350 return -1;
1352 errno = ECONNRESET;
1353 return -1;
1357 EIB_M_WriteIndividualAddress_async (EIBConnection * con, eibaddr_t dest)
1359 uchar head[4];
1360 if (!con)
1362 errno = EINVAL;
1363 return -1;
1365 EIBSETTYPE (head, EIB_M_INDIVIDUAL_ADDRESS_WRITE);
1366 EIBSETADDR (head + 2, dest);
1367 if (_EIB_SendRequest (con, 4, head) == -1)
1368 return -1;
1369 con->complete = M_WriteIndividualAddress_complete;
1370 return 0;
1374 EIB_M_WriteIndividualAddress (EIBConnection * con, eibaddr_t dest)
1376 if (EIB_M_WriteIndividualAddress_async (con, dest) == -1)
1377 return -1;
1378 return EIBComplete (con);
1381 static int
1382 MC_Connect_complete (EIBConnection * con)
1384 int i;
1385 i = _EIB_GetRequest (con);
1386 if (i == -1)
1387 return -1;
1389 if (EIBTYPE (con) != EIB_MC_CONNECTION)
1391 errno = ECONNRESET;
1392 return -1;
1394 return 0;
1398 EIB_MC_Connect_async (EIBConnection * con, eibaddr_t dest)
1400 uchar head[4];
1401 int i;
1402 if (!con)
1404 errno = EINVAL;
1405 return -1;
1407 EIBSETTYPE (head, EIB_MC_CONNECTION);
1408 EIBSETADDR (head + 2, dest);
1409 i = _EIB_SendRequest (con, 4, head);
1410 if (i == -1)
1411 return -1;
1413 con->complete = MC_Connect_complete;
1414 return 0;
1418 EIB_MC_Connect (EIBConnection * con, eibaddr_t dest)
1420 if (EIB_MC_Connect_async (con, dest) == -1)
1421 return -1;
1422 return EIBComplete (con);
1425 static int
1426 MC_Progmode_On_complete (EIBConnection * con)
1428 int i;
1429 i = _EIB_GetRequest (con);
1430 if (i == -1)
1431 return -1;
1432 if (EIBTYPE (con) != EIB_MC_PROG_MODE)
1434 errno = ECONNRESET;
1435 return -1;
1437 return 0;
1441 EIB_MC_Progmode_On_async (EIBConnection * con)
1443 uchar head[3];
1444 if (!con)
1446 errno = EINVAL;
1447 return -1;
1449 EIBSETTYPE (head, EIB_MC_PROG_MODE);
1450 head[2] = 1;
1451 if (_EIB_SendRequest (con, 3, head) == -1)
1452 return -1;
1453 con->complete = MC_Progmode_On_complete;
1454 return 0;
1458 EIB_MC_Progmode_On (EIBConnection * con)
1460 if (EIB_MC_Progmode_On_async (con) == -1)
1461 return -1;
1462 return EIBComplete (con);
1465 static int
1466 MC_Progmode_Off_complete (EIBConnection * con)
1468 int i;
1469 i = _EIB_GetRequest (con);
1470 if (i == -1)
1471 return -1;
1472 if (EIBTYPE (con) != EIB_MC_PROG_MODE)
1474 errno = ECONNRESET;
1475 return -1;
1477 return 0;
1481 EIB_MC_Progmode_Off_async (EIBConnection * con)
1483 uchar head[3];
1484 if (!con)
1486 errno = EINVAL;
1487 return -1;
1489 EIBSETTYPE (head, EIB_MC_PROG_MODE);
1490 head[2] = 0;
1491 if (_EIB_SendRequest (con, 3, head) == -1)
1492 return -1;
1493 con->complete = MC_Progmode_Off_complete;
1494 return 0;
1498 EIB_MC_Progmode_Off (EIBConnection * con)
1500 if (EIB_MC_Progmode_Off_async (con) == -1)
1501 return -1;
1502 return EIBComplete (con);
1505 static int
1506 MC_Progmode_Toggle_complete (EIBConnection * con)
1508 int i;
1509 i = _EIB_GetRequest (con);
1510 if (i == -1)
1511 return -1;
1512 if (EIBTYPE (con) != EIB_MC_PROG_MODE)
1514 errno = ECONNRESET;
1515 return -1;
1517 return 0;
1521 EIB_MC_Progmode_Toggle_async (EIBConnection * con)
1523 uchar head[3];
1524 if (!con)
1526 errno = EINVAL;
1527 return -1;
1529 EIBSETTYPE (head, EIB_MC_PROG_MODE);
1530 head[2] = 2;
1531 if (_EIB_SendRequest (con, 3, head) == -1)
1532 return -1;
1533 con->complete = MC_Progmode_Toggle_complete;
1534 return 0;
1538 EIB_MC_Progmode_Toggle (EIBConnection * con)
1540 if (EIB_MC_Progmode_Toggle_async (con) == -1)
1541 return -1;
1542 return EIBComplete (con);
1545 static int
1546 MC_Progmode_Status_complete (EIBConnection * con)
1548 int i;
1549 i = _EIB_GetRequest (con);
1550 if (i == -1)
1551 return -1;
1552 if (EIBTYPE (con) != EIB_MC_PROG_MODE || con->size < 3)
1554 errno = ECONNRESET;
1555 return -1;
1557 return con->buf[2];
1561 EIB_MC_Progmode_Status_async (EIBConnection * con)
1563 uchar head[3];
1564 if (!con)
1566 errno = EINVAL;
1567 return -1;
1569 EIBSETTYPE (head, EIB_MC_PROG_MODE);
1570 head[2] = 3;
1571 if (_EIB_SendRequest (con, 3, head) == -1)
1572 return -1;
1573 con->complete = MC_Progmode_Status_complete;
1574 return 0;
1578 EIB_MC_Progmode_Status (EIBConnection * con)
1580 if (EIB_MC_Progmode_Status_async (con) == -1)
1581 return -1;
1582 return EIBComplete (con);
1585 static int
1586 MC_GetMaskVersion_complete (EIBConnection * con)
1588 int i;
1589 i = _EIB_GetRequest (con);
1590 if (i == -1)
1591 return -1;
1592 if (EIBTYPE (con) != EIB_MC_MASK_VERSION || con->size < 4)
1594 errno = ECONNRESET;
1595 return -1;
1597 return (con->buf[2] << 8) | (con->buf[3]);
1601 EIB_MC_GetMaskVersion_async (EIBConnection * con)
1603 uchar head[2];
1604 if (!con)
1606 errno = EINVAL;
1607 return -1;
1609 EIBSETTYPE (head, EIB_MC_MASK_VERSION);
1610 if (_EIB_SendRequest (con, 2, head) == -1)
1611 return -1;
1612 con->complete = MC_GetMaskVersion_complete;
1613 return 0;
1617 EIB_MC_GetMaskVersion (EIBConnection * con)
1619 if (EIB_MC_GetMaskVersion_async (con) == -1)
1620 return -1;
1621 return EIBComplete (con);
1624 static int
1625 MC_GetPEIType_complete (EIBConnection * con)
1627 int i;
1628 i = _EIB_GetRequest (con);
1629 if (i == -1)
1630 return -1;
1631 if (EIBTYPE (con) != EIB_MC_PEI_TYPE || con->size < 4)
1633 errno = ECONNRESET;
1634 return -1;
1636 return (con->buf[2] << 8) | (con->buf[3]);
1640 EIB_MC_GetPEIType_async (EIBConnection * con)
1642 uchar head[2];
1643 if (!con)
1645 errno = EINVAL;
1646 return -1;
1648 EIBSETTYPE (head, EIB_MC_PEI_TYPE);
1649 if (_EIB_SendRequest (con, 2, head) == -1)
1650 return -1;
1651 con->complete = MC_GetPEIType_complete;
1652 return 0;
1656 EIB_MC_GetPEIType (EIBConnection * con)
1658 if (EIB_MC_GetPEIType_async (con) == -1)
1659 return -1;
1660 return EIBComplete (con);
1663 static int
1664 MC_ReadADC_complete (EIBConnection * con)
1666 int i;
1667 i = _EIB_GetRequest (con);
1668 if (i == -1)
1669 return -1;
1670 if (EIBTYPE (con) != EIB_MC_ADC_READ || con->size < 4)
1672 errno = ECONNRESET;
1673 return -1;
1675 if (con->req.ptr1)
1676 *con->req.ptr1 = (con->buf[2] << 8) | (con->buf[3]);
1677 return 0;
1681 EIB_MC_ReadADC_async (EIBConnection * con, uint8_t channel, uint8_t count,
1682 int16_t * val)
1684 uchar head[4];
1685 if (!con)
1687 errno = EINVAL;
1688 return -1;
1690 con->req.ptr1 = val;
1691 EIBSETTYPE (head, EIB_MC_ADC_READ);
1692 head[2] = channel;
1693 head[3] = count;
1694 if (_EIB_SendRequest (con, 4, head) == -1)
1695 return -1;
1696 con->complete = MC_ReadADC_complete;
1697 return 0;
1701 EIB_MC_ReadADC (EIBConnection * con, uint8_t channel, uint8_t count,
1702 int16_t * val)
1704 if (EIB_MC_ReadADC_async (con, channel, count, val) == -1)
1705 return -1;
1706 return EIBComplete (con);
1709 static int
1710 MC_PropertyRead_complete (EIBConnection * con)
1712 int i;
1713 i = _EIB_GetRequest (con);
1714 if (i == -1)
1715 return -1;
1716 if (EIBTYPE (con) != EIB_MC_PROP_READ)
1718 errno = ECONNRESET;
1719 return -1;
1721 i = con->size - 2;
1722 if (i > con->req.len)
1723 i = con->req.len;
1724 memcpy (con->req.buf, con->buf + 2, i);
1725 return i;
1729 EIB_MC_PropertyRead_async (EIBConnection * con, uint8_t obj, uint8_t property,
1730 uint16_t start, uint8_t nr_of_elem, int max_len,
1731 uint8_t * buf)
1733 uchar head[7];
1734 if (!con)
1736 errno = EINVAL;
1737 return -1;
1739 con->req.buf = buf;
1740 con->req.len = max_len;
1741 if (!buf)
1743 errno = EINVAL;
1744 return -1;
1746 EIBSETTYPE (head, EIB_MC_PROP_READ);
1747 head[2] = obj;
1748 head[3] = property;
1749 head[4] = (start >> 8) & 0xff;
1750 head[5] = (start) & 0xff;
1751 head[6] = nr_of_elem;
1752 if (_EIB_SendRequest (con, 7, head) == -1)
1753 return -1;
1754 con->complete = MC_PropertyRead_complete;
1755 return 0;
1759 EIB_MC_PropertyRead (EIBConnection * con, uint8_t obj, uint8_t property,
1760 uint16_t start, uint8_t nr_of_elem, int max_len,
1761 uint8_t * buf)
1763 if (EIB_MC_PropertyRead_async
1764 (con, obj, property, start, nr_of_elem, max_len, buf) == -1)
1765 return -1;
1766 return EIBComplete (con);
1769 static int
1770 MC_Read_complete (EIBConnection * con)
1772 int i;
1773 i = _EIB_GetRequest (con);
1774 if (i == -1)
1775 return -1;
1776 if (EIBTYPE (con) != EIB_MC_READ)
1778 errno = ECONNRESET;
1779 return -1;
1781 i = con->size - 2;
1782 if (i > con->req.len)
1783 i = con->req.len;
1784 memcpy (con->req.buf, con->buf + 2, i);
1785 return i;
1789 EIB_MC_Read_async (EIBConnection * con, uint16_t addr, int len, uint8_t * buf)
1791 uchar head[6];
1792 if (!con)
1794 errno = EINVAL;
1795 return -1;
1797 if (!buf)
1799 errno = EINVAL;
1800 return -1;
1802 con->req.len = len;
1803 con->req.buf = buf;
1804 EIBSETTYPE (head, EIB_MC_READ);
1805 head[2] = (addr >> 8) & 0xff;
1806 head[3] = (addr) & 0xff;
1807 head[4] = (len >> 8) & 0xff;
1808 head[5] = (len) & 0xff;
1809 if (_EIB_SendRequest (con, 6, head) == -1)
1810 return -1;
1811 con->complete = MC_Read_complete;
1812 return 0;
1816 EIB_MC_Read (EIBConnection * con, uint16_t addr, int len, uint8_t * buf)
1818 if (EIB_MC_Read_async (con, addr, len, buf) == -1)
1819 return -1;
1820 return EIBComplete (con);
1823 static int
1824 MC_PropertyWrite_complete (EIBConnection * con)
1826 int i;
1827 i = _EIB_GetRequest (con);
1828 if (i == -1)
1829 return -1;
1830 if (EIBTYPE (con) != EIB_MC_PROP_WRITE)
1832 errno = ECONNRESET;
1833 return -1;
1835 i = con->size - 2;
1836 if (i > con->req.len)
1837 i = con->req.len;
1838 memcpy (con->req.buf, con->buf + 2, i);
1839 return i;
1843 EIB_MC_PropertyWrite_async (EIBConnection * con, uint8_t obj,
1844 uint8_t property, uint16_t start,
1845 uint8_t nr_of_elem, int len, const uint8_t * buf,
1846 int max_len, uint8_t * res)
1848 uchar *ibuf;
1849 int i;
1850 if (!con)
1852 errno = EINVAL;
1853 return -1;
1855 if (!buf || !res)
1857 errno = EINVAL;
1858 return -1;
1860 con->req.len = max_len;
1861 con->req.buf = res;
1862 ibuf = (uchar *) malloc (len + 7);
1863 if (!ibuf)
1865 errno = ENOMEM;
1866 return -1;
1868 EIBSETTYPE (ibuf, EIB_MC_PROP_WRITE);
1869 ibuf[2] = obj;
1870 ibuf[3] = property;
1871 ibuf[4] = (start >> 8) & 0xff;
1872 ibuf[5] = (start) & 0xff;
1873 ibuf[6] = nr_of_elem;
1874 memcpy (ibuf + 7, buf, len);
1875 i = _EIB_SendRequest (con, len + 7, ibuf);
1876 free (ibuf);
1877 if (i == -1)
1878 return -1;
1879 con->complete = MC_PropertyWrite_complete;
1880 return 0;
1884 EIB_MC_PropertyWrite (EIBConnection * con, uint8_t obj, uint8_t property,
1885 uint16_t start, uint8_t nr_of_elem, int len,
1886 const uint8_t * buf, int max_len, uint8_t * res)
1888 if (EIB_MC_PropertyWrite_async
1889 (con, obj, property, start, nr_of_elem, len, buf, max_len, res) == -1)
1890 return -1;
1891 return EIBComplete (con);
1893 static int
1894 MC_Write_complete (EIBConnection * con)
1896 int i;
1897 i = _EIB_GetRequest (con);
1898 if (i == -1)
1899 return -1;
1900 if (EIBTYPE (con) == EIB_ERROR_VERIFY)
1902 errno = EIO;
1903 return -1;
1905 if (EIBTYPE (con) != EIB_MC_WRITE)
1907 errno = ECONNRESET;
1908 return -1;
1910 return con->req.len;
1914 EIB_MC_Write_async (EIBConnection * con, uint16_t addr, int len,
1915 const uint8_t * buf)
1917 uchar *ibuf;
1918 int i;
1919 if (!con)
1921 errno = EINVAL;
1922 return -1;
1924 con->req.len = len;
1925 if (!buf)
1927 errno = EINVAL;
1928 return -1;
1930 ibuf = (uchar *) malloc (len + 6);
1931 if (!ibuf)
1933 errno = ENOMEM;
1934 return -1;
1936 EIBSETTYPE (ibuf, EIB_MC_WRITE);
1937 ibuf[2] = (addr >> 8) & 0xff;
1938 ibuf[3] = (addr) & 0xff;
1939 ibuf[4] = (len >> 8) & 0xff;
1940 ibuf[5] = (len) & 0xff;
1941 memcpy (ibuf + 6, buf, len);
1942 i = _EIB_SendRequest (con, len + 6, ibuf);
1943 free (ibuf);
1944 if (i == -1)
1945 return -1;
1946 con->complete = MC_Write_complete;
1947 return 0;
1951 EIB_MC_Write (EIBConnection * con, uint16_t addr, int len,
1952 const uint8_t * buf)
1954 if (EIB_MC_Write_async (con, addr, len, buf) == -1)
1955 return -1;
1956 return EIBComplete (con);
1959 static int
1960 MC_PropertyDesc_complete (EIBConnection * con)
1962 int i;
1963 i = _EIB_GetRequest (con);
1964 if (i == -1)
1965 return -1;
1966 if (EIBTYPE (con) != EIB_MC_PROP_DESC || con->size < 6)
1968 errno = ECONNRESET;
1969 return -1;
1971 /* Type */
1972 if (con->req.ptr2)
1973 *con->req.ptr2 = con->buf[2];
1974 /* max_nr_of_elem */
1975 if (con->req.ptr4)
1976 *con->req.ptr4 = (con->buf[3] << 8) | (con->buf[4]);
1977 /* access */
1978 if (con->req.ptr3)
1979 *con->req.ptr3 = con->buf[5];
1980 return 0;
1984 EIB_MC_PropertyDesc_async (EIBConnection * con, uint8_t obj, uint8_t property,
1985 uint8_t * type, uint16_t * max_nr_of_elem,
1986 uint8_t * access)
1988 uchar head[5];
1989 if (!con)
1991 errno = EINVAL;
1992 return -1;
1994 con->req.ptr2 = type;
1995 con->req.ptr4 = max_nr_of_elem;
1996 con->req.ptr3 = access;
1997 EIBSETTYPE (head, EIB_MC_PROP_DESC);
1998 head[2] = obj;
1999 head[3] = property;
2000 if (_EIB_SendRequest (con, 4, head) == -1)
2001 return -1;
2002 con->complete = MC_PropertyDesc_complete;
2003 return 0;
2007 EIB_MC_PropertyDesc (EIBConnection * con, uint8_t obj, uint8_t property,
2008 uint8_t * type, uint16_t * max_nr_of_elem,
2009 uint8_t * access)
2011 if (EIB_MC_PropertyDesc_async
2012 (con, obj, property, type, max_nr_of_elem, access) == -1)
2013 return -1;
2014 return EIBComplete (con);
2017 static int
2018 MC_Authorize_complete (EIBConnection * con)
2020 int i;
2021 i = _EIB_GetRequest (con);
2022 if (i == -1)
2023 return -1;
2024 if (EIBTYPE (con) != EIB_MC_AUTHORIZE || con->size < 3)
2026 errno = ECONNRESET;
2027 return -1;
2029 return con->buf[2];
2033 EIB_MC_Authorize_async (EIBConnection * con, uint8_t key[4])
2035 uchar head[6];
2036 if (!con)
2038 errno = EINVAL;
2039 return -1;
2041 EIBSETTYPE (head, EIB_MC_AUTHORIZE);
2042 memcpy (head + 2, key, 4);
2043 if (_EIB_SendRequest (con, 6, head) == -1)
2044 return -1;
2045 con->complete = MC_Authorize_complete;
2046 return 0;
2050 EIB_MC_Authorize (EIBConnection * con, uint8_t key[4])
2052 if (EIB_MC_Authorize_async (con, key) == -1)
2053 return -1;
2054 return EIBComplete (con);
2057 static int
2058 MC_SetKey_complete (EIBConnection * con)
2060 int i;
2061 i = _EIB_GetRequest (con);
2062 if (i == -1)
2063 return -1;
2064 if (EIBTYPE (con) == EIB_PROCESSING_ERROR)
2066 errno = EPERM;
2067 return -1;
2069 if (EIBTYPE (con) != EIB_MC_KEY_WRITE)
2071 errno = ECONNRESET;
2072 return -1;
2074 return 0;
2078 EIB_MC_SetKey_async (EIBConnection * con, uint8_t key[4], uint8_t level)
2080 uchar head[7];
2081 if (!con)
2083 errno = EINVAL;
2084 return -1;
2086 EIBSETTYPE (head, EIB_MC_KEY_WRITE);
2087 memcpy (head + 2, key, 4);
2088 head[6] = level;
2089 if (_EIB_SendRequest (con, 7, head) == -1)
2090 return -1;
2091 con->complete = MC_SetKey_complete;
2092 return 0;
2096 EIB_MC_SetKey (EIBConnection * con, uint8_t key[4], uint8_t level)
2098 if (EIB_MC_SetKey_async (con, key, level) == -1)
2099 return -1;
2100 return EIBComplete (con);
2103 static int
2104 MC_PropertyScan_complete (EIBConnection * con)
2106 int i;
2107 i = _EIB_GetRequest (con);
2108 if (i == -1)
2109 return -1;
2110 if (EIBTYPE (con) != EIB_MC_PROP_SCAN)
2112 errno = ECONNRESET;
2113 return -1;
2115 i = con->size - 2;
2116 if (i > con->req.len)
2117 i = con->req.len;
2118 memcpy (con->req.buf, con->buf + 2, i);
2119 return i;
2123 EIB_MC_PropertyScan_async (EIBConnection * con, int maxlen, uint8_t * buf)
2125 uchar head[2];
2126 if (!con)
2128 errno = EINVAL;
2129 return -1;
2131 con->req.len = maxlen;
2132 con->req.buf = buf;
2133 EIBSETTYPE (head, EIB_MC_PROP_SCAN);
2134 if (_EIB_SendRequest (con, 2, head) == -1)
2135 return -1;
2136 con->complete = MC_PropertyScan_complete;
2137 return 0;
2141 EIB_MC_PropertyScan (EIBConnection * con, int maxlen, uint8_t * buf)
2143 if (EIB_MC_PropertyScan_async (con, maxlen, buf) == -1)
2144 return -1;
2145 return EIBComplete (con);
2148 static int
2149 LoadImage_complete (EIBConnection * con)
2151 int i;
2152 i = _EIB_GetRequest (con);
2153 if (i == -1)
2154 return -1;
2155 if (EIBTYPE (con) != EIB_LOAD_IMAGE || con->size < 4)
2157 errno = ECONNRESET;
2158 return IMG_UNKNOWN_ERROR;
2160 return (con->buf[2] << 8) | con->buf[3];
2164 EIB_LoadImage_async (EIBConnection * con, const uint8_t * image, int len)
2166 uchar *ibuf;
2167 int i;
2168 if (!con)
2170 errno = EINVAL;
2171 return -1;
2173 if (!image)
2175 errno = EINVAL;
2176 return -1;
2178 ibuf = (uchar *) malloc (len + 2);
2179 if (!ibuf)
2181 errno = ENOMEM;
2182 return -1;
2184 EIBSETTYPE (ibuf, EIB_LOAD_IMAGE);
2185 memcpy (ibuf + 2, image, len);
2186 i = _EIB_SendRequest (con, len + 2, ibuf);
2187 free (ibuf);
2188 if (i == -1)
2189 return -1;
2190 con->complete = LoadImage_complete;
2191 return 0;
2194 BCU_LOAD_RESULT
2195 EIB_LoadImage (EIBConnection * con, const uint8_t * image, int len)
2197 if (EIB_LoadImage_async (con, image, len) == -1)
2198 return -1;
2199 return EIBComplete (con);