HAMMER Utilities: MFC work to date.
[dragonfly.git] / sys / netproto / atm / uni / unisig_mbuf.c
blob2c98843abc696e7d3e59b7cbcaed262143ac832f
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/uni/unisig_mbuf.c,v 1.5 1999/08/28 00:49:05 peter Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/uni/unisig_mbuf.c,v 1.5 2006/01/14 13:36:39 swildner Exp $
31 * ATM Forum UNI 3.0/3.1 Signalling Manager
32 * ----------------------------------------
34 * Message buffer handling routines
38 #include <netproto/atm/kern_include.h>
40 #include "unisig_var.h"
41 #include "unisig_mbuf.h"
42 #include "unisig_msg.h"
45 * Initialize a unisig formatting structure
47 * Arguments:
48 * usf pointer to a unisig formatting structure
49 * usp pointer to a unisig protocol instance
50 * buf pointer to a buffer chain (decode only)
51 * op operation code (encode or decode)
52 * headroom headroom to leave in first buffer
54 * Returns:
55 * 0 success
56 * errno error encountered
59 int
60 usf_init(struct usfmt *usf, struct unisig *usp, KBuffer *buf, int op, int headroom)
62 KBuffer *m;
64 ATM_DEBUG3("usf_init: usf=%p, buf=%p, op=%d\n",
65 usf, buf, op);
68 * Check parameters
70 if (!usf)
71 return(EINVAL);
73 switch(op) {
75 case USF_ENCODE:
77 * Get a buffer
79 KB_ALLOCPKT(m, USF_MIN_ALLOC, KB_F_NOWAIT, KB_T_DATA);
80 if (m == NULL)
81 return(ENOMEM);
82 KB_LEN(m) = 0;
83 if (headroom < KB_BFRLEN(m)) {
84 KB_HEADSET(m, headroom);
86 break;
88 case USF_DECODE:
90 * Verify buffer address
92 if (!buf)
93 return(EINVAL);
94 m = buf;
95 break;
97 default:
98 return(EINVAL);
102 * Save parameters in formatting structure
104 usf->usf_m_addr = m;
105 usf->usf_m_base = m;
106 usf->usf_loc = 0;
107 usf->usf_op = op;
108 usf->usf_sig = usp;
110 return(0);
115 * Get or put the next byte of a signalling message
117 * Arguments:
118 * usf pointer to a unisig formatting structure
119 * c pointer to the byte to send from or receive into
121 * Returns:
122 * 0 success
123 * errno error encountered
127 usf_byte(struct usfmt *usf, u_char *c)
129 u_char *mp;
130 KBuffer *m = usf->usf_m_addr, *m1;
131 int space;
133 switch (usf->usf_op) {
135 case USF_DECODE:
137 * Make sure we're not past the end of the buffer
138 * (allowing for zero-length buffers)
140 while (usf->usf_loc >= KB_LEN(m)) {
141 if (KB_NEXT(usf->usf_m_addr)) {
142 usf->usf_m_addr = m = KB_NEXT(usf->usf_m_addr);
143 usf->usf_loc = 0;
144 } else {
145 return(EMSGSIZE);
150 * Get the data from the buffer
152 KB_DATASTART(m, mp, u_char *);
153 *c = mp[usf->usf_loc];
154 usf->usf_loc++;
155 break;
157 case USF_ENCODE:
159 * If the current buffer is full, get another
161 KB_TAILROOM(m, space);
162 if (space == 0) {
163 KB_ALLOC(m1, USF_MIN_ALLOC, KB_F_NOWAIT, KB_T_DATA);
164 if (m1 == NULL)
165 return(ENOMEM);
166 KB_LEN(m1) = 0;
167 KB_LINK(m1, m);
168 usf->usf_m_addr = m = m1;
169 usf->usf_loc = 0;
173 * Put the data into the buffer
175 KB_DATASTART(m, mp, u_char *);
176 mp[usf->usf_loc] = *c;
177 KB_TAILADJ(m, 1);
178 usf->usf_loc++;
179 break;
181 default:
183 * Invalid operation code
185 return(EINVAL);
188 return(0);
193 * Get or put a short integer
195 * Arguments:
196 * usf pointer to a unisig formatting structure
197 * s pointer to a short to send from or receive into
199 * Returns:
200 * 0 success
201 * errno error encountered
205 usf_short(struct usfmt *usf, u_short *s)
207 int rc;
208 union {
209 u_short value;
210 u_char b[sizeof(u_short)];
211 } tval;
213 tval.value = 0;
214 if (usf->usf_op == USF_ENCODE)
215 tval.value = htons(*s);
217 if ((rc = usf_byte(usf, &tval.b[0])) != 0)
218 return(rc);
219 if ((rc = usf_byte(usf, &tval.b[1])) != 0)
220 return(rc);
222 if (usf->usf_op == USF_DECODE)
223 *s = ntohs(tval.value);
225 return(0);
230 * Get or put a 3-byte integer
232 * Arguments:
233 * usf pointer to a unisig formatting structure
234 * i pointer to an integer to send from or receive into
236 * Returns:
237 * 0 success
238 * errno error encountered
242 usf_int3(struct usfmt *usf, u_int *i)
244 int j, rc;
245 union {
246 u_int value;
247 u_char b[sizeof(u_int)];
248 } tval;
250 tval.value = 0;
252 if (usf->usf_op == USF_ENCODE)
253 tval.value = htonl(*i);
255 for (j=0; j<3; j++) {
256 rc = usf_byte(usf, &tval.b[j+sizeof(u_int)-3]);
257 if (rc)
258 return(rc);
261 if (usf->usf_op == USF_DECODE)
262 *i = ntohl(tval.value);
264 return(rc);
269 * Get or put an integer
271 * Arguments:
272 * usf pointer to a unisig formatting structure
273 * i pointer to an integer to send from or receive into
275 * Returns:
276 * 0 success
277 * errno error encountered
281 usf_int(struct usfmt *usf, u_int *i)
283 int j, rc;
284 union {
285 u_int value;
286 u_char b[sizeof(u_int)];
287 } tval;
289 if (usf->usf_op == USF_ENCODE)
290 tval.value = htonl(*i);
292 for (j=0; j<4; j++) {
293 rc = usf_byte(usf, &tval.b[j+sizeof(u_int)-4]);
294 if (rc)
295 return(rc);
298 if (usf->usf_op == USF_DECODE)
299 *i = ntohl(tval.value);
301 return(rc);
306 * Get or put an extented field
308 * An extented field consists of a string of bytes. All but the last
309 * byte of the field has the high-order bit set to zero. When decoding,
310 * this routine will read bytes until either the input is exhausted or
311 * a byte with a high-order one is found. Whe encoding, it will take an
312 * unsigned integer and write until the highest-order one bit has been
313 * written.
315 * Arguments:
316 * usf pointer to a unisig formatting structure
317 * i pointer to an integer to send from or receive into
319 * Returns:
320 * 0 success
321 * errno error encountered
325 usf_ext(struct usfmt *usf, u_int *i)
327 int j, rc;
328 u_char c, buff[sizeof(u_int)+1];
329 u_int val;
330 union {
331 u_int value;
332 u_char b[sizeof(u_int)];
333 } tval;
335 switch(usf->usf_op) {
337 case USF_ENCODE:
338 val = *i;
339 j = 0;
340 while (val) {
341 tval.value = htonl(val);
342 buff[j] = tval.b[sizeof(u_int)-1] & UNI_IE_EXT_MASK;
343 val >>= 7;
344 j++;
346 j--;
347 buff[0] |= UNI_IE_EXT_BIT;
348 for (; j>=0; j--) {
349 rc = usf_byte(usf, &buff[j]);
350 if (rc)
351 return(rc);
353 break;
355 case USF_DECODE:
356 c = 0;
357 val = 0;
358 while (!(c & UNI_IE_EXT_BIT)) {
359 rc = usf_byte(usf, &c);
360 if (rc)
361 return(rc);
362 val = (val << 7) + (c & UNI_IE_EXT_MASK);
364 *i = val;
365 break;
367 default:
368 return(EINVAL);
371 return(0);
376 * Count the bytes remaining to be decoded
378 * Arguments:
379 * usf pointer to a unisig formatting structure
381 * Returns:
382 * int the number of bytes in the buffer chain remaining to
383 * be decoded
387 usf_count(struct usfmt *usf)
389 int count;
390 KBuffer *m = usf->usf_m_addr;
393 * Return zero if we're not decoding
395 if (usf->usf_op != USF_DECODE)
396 return (0);
399 * Calculate the length of data remaining in the current buffer
401 count = KB_LEN(m) - usf->usf_loc;
404 * Loop through any remaining buffers, adding in their lengths
406 while (KB_NEXT(m)) {
407 m = KB_NEXT(m);
408 count += KB_LEN(m);
411 return(count);
417 * Get or put the next byte of a signalling message and return
418 * the byte's buffer address
420 * Arguments:
421 * usf pointer to a unisig formatting structure
422 * c pointer to the byte to send from or receive into
423 * bp address to store the byte's buffer address
425 * Returns:
426 * 0 success
427 * errno error encountered
431 usf_byte_mark(struct usfmt *usf, u_char *c, u_char **bp)
433 u_char *mp;
434 int rc;
437 * First, get/put the data byte
439 rc = usf_byte(usf, c);
440 if (rc) {
443 * Error encountered
445 *bp = NULL;
446 return (rc);
450 * Now return the buffer address of that byte
452 KB_DATASTART(usf->usf_m_addr, mp, u_char *);
453 *bp = &mp[usf->usf_loc - 1];
455 return (0);