Commit | Line | Data |
---|---|---|
ba212048 GM |
1 | #include <stdio.h> |
2 | ||
3 | #include "api_exch.h" | |
4 | ||
62946391 GM |
5 | static int sock; /* Socket number */ |
6 | ||
ba212048 GM |
7 | static char ibuffer[40], *ibuf_next, *ibuf_last; |
8 | #define IBUFADDED(i) ibuf_last += (i) | |
9 | #define IBUFAVAILABLE() (ibuf_last -ibuf_next) | |
10 | #define IBUFFER() ibuffer | |
11 | #define IBUFGETCHAR() (*ibuf_next++) | |
12 | #define IBUFGETSHORT() ((*ibuf_next++<<8)|(*ibuf_next++&0xff)) | |
13 | #define IBUFRESET() (ibuf_next = ibuf_last = ibuffer) | |
14 | ||
15 | char obuffer[40], *obuf_next; | |
16 | #define OBUFADDBYTES(w,l) { memcpy(obuf_next, w, l); obuf_next += l; } | |
17 | #define OBUFADDCHAR(c) (*obuf_next++ = c) | |
18 | #define OBUFADDSHORT(s) {*obuf_next++ = (s)>>8; *obuf_next++ = s; } | |
19 | #define OBUFAVAILABLE() (obuf_next - obuffer) | |
20 | #define OBUFFER() obuffer | |
21 | #define OBUFRESET() obuf_next = obuffer | |
22 | #define OBUFROOM() (obuffer+sizeof obuffer-obuf_next) | |
23 | ||
24 | ||
25 | static int | |
26 | outflush() | |
27 | { | |
28 | int length = OBUFAVAILABLE(); | |
29 | ||
30 | if (length != 0) { | |
31 | if (write(sock, OBUFFER(), length) != length) { | |
32 | perror("writing to API client"); | |
33 | return -1; | |
34 | } | |
35 | OBUFRESET(); | |
36 | } | |
37 | return 0; /* All OK */ | |
38 | } | |
39 | ||
40 | ||
41 | static int | |
42 | infill(count) | |
43 | int count; | |
44 | { | |
45 | int i; | |
46 | ||
47 | if (OBUFAVAILABLE()) { | |
48 | if (outflush() == -1) { | |
49 | return -1; | |
50 | } | |
51 | } | |
52 | if (ibuf_next == ibuf_last) { | |
53 | IBUFRESET(); | |
54 | } | |
55 | while (count) { | |
56 | if ((i = read(sock, IBUFFER(), count)) < 0) { | |
57 | perror("reading from API client"); | |
58 | return -1; | |
59 | } | |
60 | count -= i; | |
61 | IBUFADDED(i); | |
62 | } | |
63 | return 0; | |
64 | } | |
65 | ||
62946391 GM |
66 | int |
67 | api_exch_inbyte() | |
68 | { | |
69 | if (IBUFAVAILABLE() < 1) { | |
70 | if (infill(1) == -1) { | |
71 | return -1; | |
72 | } | |
73 | } | |
74 | return IBUFGETCHAR(); | |
75 | } | |
76 | ||
77 | ||
78 | int | |
ba212048 GM |
79 | api_exch_incommand(command) |
80 | int command; | |
81 | { | |
82 | int i; | |
83 | ||
84 | if (IBUFAVAILABLE() < 1) { | |
85 | if (infill(1) == -1) { | |
86 | return -1; | |
87 | } | |
88 | } | |
89 | i = IBUFGETCHAR(); | |
90 | if (i != command) { | |
91 | fprintf(stderr, "Expected API command 0x%x, got API command 0x%x.\n", | |
92 | command, i); | |
93 | return -1; | |
94 | } | |
95 | return 0; | |
96 | } | |
97 | ||
98 | ||
62946391 | 99 | int |
ba212048 GM |
100 | api_exch_outcommand(command) |
101 | int command; | |
102 | { | |
103 | if (OBUFROOM() < 1) { | |
104 | if (outflush() == -1) { | |
105 | return -1; | |
106 | } | |
107 | } | |
108 | OBUFADDCHAR(command); | |
109 | return 0; | |
110 | } | |
111 | ||
112 | ||
62946391 | 113 | int |
ba212048 GM |
114 | api_exch_outtype(type, length, location) |
115 | int | |
116 | type, | |
117 | length; | |
118 | char | |
119 | *location; | |
120 | { | |
121 | int netleng = htons(length); | |
122 | ||
123 | if (OBUFROOM() < 3) { | |
124 | if (outflush() == -1) { | |
125 | return -1; | |
126 | } | |
127 | } | |
128 | OBUFADDCHAR(type); | |
129 | OBUFADDSHORT(netleng); | |
130 | if (OBUFROOM() > length) { | |
131 | OBUFADDBYTES(location, length); | |
132 | } else { | |
133 | if (outflush() == -1) { | |
134 | return -1; | |
135 | } | |
136 | if (write(sock, location, length) != length) { | |
137 | perror("writing to API client"); | |
138 | return -1; | |
139 | } | |
140 | } | |
141 | } | |
142 | ||
143 | ||
62946391 | 144 | int |
ba212048 GM |
145 | api_exch_intype(type, length, location) |
146 | int | |
147 | type, | |
148 | length; | |
149 | char | |
150 | *location; | |
151 | { | |
152 | int i, netleng = htons(length); | |
153 | ||
154 | if (IBUFAVAILABLE() < 3) { | |
155 | if (infill(3) == -1) { | |
156 | return -1; | |
157 | } | |
158 | } | |
159 | if ((i = IBUFGETCHAR()) != type) { | |
160 | fprintf(stderr, "Expected type 0x%x, got type 0x%x.\n", type, i); | |
161 | return -1; | |
162 | } | |
163 | if ((i = IBUFGETSHORT()) != netleng) { | |
164 | fprintf(stderr, "Type 0x%x - expected length %d, received length %d.\n", | |
165 | type, length, ntohs(i)); | |
166 | return -1; | |
167 | } | |
168 | while (length) { | |
169 | if ((i = read(sock, location, length)) < 0) { | |
170 | perror("reading from API client"); | |
171 | return -1; | |
172 | } | |
173 | length -= i; | |
174 | location += i; | |
175 | } | |
176 | return 0; | |
177 | } | |
62946391 GM |
178 | |
179 | int | |
180 | api_exch_init(sock_number) | |
181 | int sock_number; | |
182 | { | |
183 | sock = sock_number; | |
184 | ||
185 | IBUFRESET(); | |
186 | OBUFRESET(); | |
187 | ||
188 | return 0; | |
189 | } |