1 #include <stdio.h> 2 3 #include "api_exch.h" 4 5 static int sock; /* Socket number */ 6 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 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 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 99 int 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 113 int 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 144 int 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 } 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 } 190