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
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
56 * errno error encountered
60 usf_init(struct usfmt
*usf
, struct unisig
*usp
, KBuffer
*buf
, int op
, int headroom
)
64 ATM_DEBUG3("usf_init: usf=%p, buf=%p, op=%d\n",
79 KB_ALLOCPKT(m
, USF_MIN_ALLOC
, KB_F_NOWAIT
, KB_T_DATA
);
83 if (headroom
< KB_BFRLEN(m
)) {
84 KB_HEADSET(m
, headroom
);
90 * Verify buffer address
102 * Save parameters in formatting structure
115 * Get or put the next byte of a signalling message
118 * usf pointer to a unisig formatting structure
119 * c pointer to the byte to send from or receive into
123 * errno error encountered
127 usf_byte(struct usfmt
*usf
, u_char
*c
)
130 KBuffer
*m
= usf
->usf_m_addr
, *m1
;
133 switch (usf
->usf_op
) {
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
);
150 * Get the data from the buffer
152 KB_DATASTART(m
, mp
, u_char
*);
153 *c
= mp
[usf
->usf_loc
];
159 * If the current buffer is full, get another
161 KB_TAILROOM(m
, space
);
163 KB_ALLOC(m1
, USF_MIN_ALLOC
, KB_F_NOWAIT
, KB_T_DATA
);
168 usf
->usf_m_addr
= m
= m1
;
173 * Put the data into the buffer
175 KB_DATASTART(m
, mp
, u_char
*);
176 mp
[usf
->usf_loc
] = *c
;
183 * Invalid operation code
193 * Get or put a short integer
196 * usf pointer to a unisig formatting structure
197 * s pointer to a short to send from or receive into
201 * errno error encountered
205 usf_short(struct usfmt
*usf
, u_short
*s
)
210 u_char b
[sizeof(u_short
)];
214 if (usf
->usf_op
== USF_ENCODE
)
215 tval
.value
= htons(*s
);
217 if ((rc
= usf_byte(usf
, &tval
.b
[0])) != 0)
219 if ((rc
= usf_byte(usf
, &tval
.b
[1])) != 0)
222 if (usf
->usf_op
== USF_DECODE
)
223 *s
= ntohs(tval
.value
);
230 * Get or put a 3-byte integer
233 * usf pointer to a unisig formatting structure
234 * i pointer to an integer to send from or receive into
238 * errno error encountered
242 usf_int3(struct usfmt
*usf
, u_int
*i
)
247 u_char b
[sizeof(u_int
)];
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]);
261 if (usf
->usf_op
== USF_DECODE
)
262 *i
= ntohl(tval
.value
);
269 * Get or put an integer
272 * usf pointer to a unisig formatting structure
273 * i pointer to an integer to send from or receive into
277 * errno error encountered
281 usf_int(struct usfmt
*usf
, u_int
*i
)
286 u_char b
[sizeof(u_int
)];
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]);
298 if (usf
->usf_op
== USF_DECODE
)
299 *i
= ntohl(tval
.value
);
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
316 * usf pointer to a unisig formatting structure
317 * i pointer to an integer to send from or receive into
321 * errno error encountered
325 usf_ext(struct usfmt
*usf
, u_int
*i
)
328 u_char c
, buff
[sizeof(u_int
)+1];
332 u_char b
[sizeof(u_int
)];
335 switch(usf
->usf_op
) {
341 tval
.value
= htonl(val
);
342 buff
[j
] = tval
.b
[sizeof(u_int
)-1] & UNI_IE_EXT_MASK
;
347 buff
[0] |= UNI_IE_EXT_BIT
;
349 rc
= usf_byte(usf
, &buff
[j
]);
358 while (!(c
& UNI_IE_EXT_BIT
)) {
359 rc
= usf_byte(usf
, &c
);
362 val
= (val
<< 7) + (c
& UNI_IE_EXT_MASK
);
376 * Count the bytes remaining to be decoded
379 * usf pointer to a unisig formatting structure
382 * int the number of bytes in the buffer chain remaining to
387 usf_count(struct usfmt
*usf
)
390 KBuffer
*m
= usf
->usf_m_addr
;
393 * Return zero if we're not decoding
395 if (usf
->usf_op
!= USF_DECODE
)
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
417 * Get or put the next byte of a signalling message and return
418 * the byte's buffer address
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
427 * errno error encountered
431 usf_byte_mark(struct usfmt
*usf
, u_char
*c
, u_char
**bp
)
437 * First, get/put the data byte
439 rc
= usf_byte(usf
, c
);
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];