blob: 0b317429875189606a5bf1fc846dff8f024a129d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
AnjaneeDevi Kapparapu24b52ff2014-02-18 18:44:02 -08002 * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala9c070ad2013-01-08 21:16:34 -080020 */
AnjaneeDevi Kapparapu24b52ff2014-02-18 18:44:02 -080021
Gopichand Nakkala9c070ad2013-01-08 21:16:34 -080022/*
AnjaneeDevi Kapparapu24b52ff2014-02-18 18:44:02 -080023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
Jeff Johnson295189b2012-06-20 16:38:30 -070029 * File: $File: //depot/software/projects/feature_branches/nova_phase1/ap/apps/asf/aniAsfPacket.c $
30 * Contains definitions for packet manipulation routines that make it
31 * easy to create and parse multi-layered network frames. This module
32 * minimizes buffer copies while adding or removing headers, and
33 * adding or removing payload.
34 *
35 * Author: Mayank D. Upadhyay
36 * Date: 19-June-2002
37 * History:-
38 * Date Modified by Modification Information
39 * ------------------------------------------------------
40 *
41 */
42#include "vos_types.h"
43#include "vos_trace.h"
44#include <bapRsnAsfPacket.h>
45#include <bapRsnErrors.h>
46#include "vos_memory.h"
47#include "vos_packet.h"
48
49/*
50 * Allocate one more than required because the last bytes is waste. We
51 * waste the last byte because in the adopted model, the tail always
52 * points to the next location where data should be stored. In a full
53 * buffer we don't want to position the tail to memory we haven't
54 * allocated ourself.
55 */
56#define ANI_INTERNAL_DEFAULT_PACKET_SIZE (ANI_DEFAULT_PACKET_SIZE + 4)
57
58#define TAIL_SPACE(packet) \
59 ((packet)->buf + (packet)->size - (packet)->tail)
60
61#define HEAD_SPACE(packet) \
62 ((packet)->head - (packet)->buf)
63
64#define ANI_CHECK_RANGE(x , upper) \
65 ( (x) <= (upper) )
66
67/**
68 * Opaque packet structure with internal storage for raw bytes.
69 * Conceptually, a tAniPacket is a pre-allocated buffer that contains
70 * data in the middle and free space on either side. The start of the
71 * data is called the head. Routines are provided to add data at the
72 * front or at the rear. The length of the packet is the total number
73 * of valid data bytes contained in it. The size of the packet is the
74 * total number of preallocated bytes.
75 */
76struct tAniPacket {
77 v_U8_t *buf;
78 v_U32_t size;
79 v_U8_t *head;
80 v_U8_t *tail;
81 v_U8_t *recordHeader;
82 v_U32_t len;
83};
84
85/**
86 * aniAsfPacketAllocate
87 *
88 * FUNCTION:
89 * Create a packet of size 2*ANI_DEFAULT_PACKET_SIZE and positions the
90 * head of the packet in the center. The allocated storage can be free
91 * with a call to aniAsfPacketFree.
92 *
93 * LOGIC:
94 * Allocates storage for tAniPacket and its internal raw data
95 * buffer. Positions the head and tail pointers in the middle of the
96 * raw data buffer.
97 *
98 * @param packetPtr pointer that will be set to newly allocated
99 * tAniPacket if the operation succeeds.
100 *
101 * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if
102 * memory could not be allocated.
103 * @see aniAsfPacketFree
104 */
105int
106aniAsfPacketAllocate(tAniPacket **packetPtr)
107{
108 return aniAsfPacketAllocateExplicit(packetPtr,
109 ANI_INTERNAL_DEFAULT_PACKET_SIZE,
110 ANI_INTERNAL_DEFAULT_PACKET_SIZE/2);
111}
112
113/**
114 * aniAsfPacketAllocateExplicit
115 *
116 * FUNCTION:
117 * Create a packet of the desired size and position the head of the
118 * packet at the desired offset in the internal raw data buffer. An
119 * application would normally set this offset to the expected length
120 * of the protocol header, then append the payload, and finally,
121 * prepend the header. The allocated storage can be free with a call
122 * to aniAsfPacketFree.
123 *
124 * LOGIC:
125 * Allocates storage for tAniPacket and its internal raw data
126 * buffer. Positions the head and tail pointers at the given offset in
127 * the internal raw data buffer.
128 *
129 * @param packetPtr pointer that will be set to newly allocated
130 * tAniPacket if the operation succeeds.
131 * @param size the size of the internal raw data buffer
132 * @param offset the offset in the internal raw data buffer where the
133 * head of the packet will be positioned initially
134 *
135 * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if
136 * memory could not be allocated.
137 * @see aniAsfPacketFree
138 */
139int
140aniAsfPacketAllocateExplicit(tAniPacket **packetPtr,
141 v_U32_t size,
142 v_U32_t offset)
143{
144 tAniPacket *packet = NULL;
145 v_U32_t maxHead = size;
146
147 *packetPtr = NULL;
148 if (size == 0)
149 return ANI_E_ILLEGAL_ARG;
150
151 VOS_ASSERT(ANI_CHECK_RANGE(offset, maxHead));
152 if (!ANI_CHECK_RANGE(offset, maxHead))
153 return ANI_E_ILLEGAL_ARG;
154
155 packet = (tAniPacket *) vos_mem_malloc( sizeof(tAniPacket) );
156
157 if (packet == NULL)
158 {
159 VOS_ASSERT( 0 );
160 return ANI_E_MALLOC_FAILED;
161 }
162
163 // transparently add one to the size since last byte is wasted
164 size = (size + 4) & 0xfffffffc;
165
166 packet->buf = (v_U8_t *)vos_mem_malloc( sizeof(v_U8_t) * size );
167 if (packet->buf == NULL)
168 {
169 vos_mem_free( packet );
170 VOS_ASSERT( 0 );
171 return ANI_E_MALLOC_FAILED;
172 }
173
174 packet->size = size; // Should not be visible to the user
175 packet->head = packet->buf + offset;
176 packet->tail = packet->head;
177 packet->len = 0;
178
179 *packetPtr = packet;
180 return ANI_OK;
181}
182
183/**
184 * aniAsfPacketDuplicate
185 *
186 * Duplicates a given packet exactly. That is, the contents, the size
187 * of the packet, and the positions of the pointers are maintained in
188 * the new copy.
189 *
190 * @param newPacketPtr is set to a newly allocated packet that is a
191 * duplicate of oldPacket
192 * @param oldPacket the original packet that should be duplicated
193 *
194 * @return ANI_OK if the operation succeeds; ANI_E_NULL if oldPacket
195 * is NULL;
196 */
197int
198aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket)
199{
200 int retVal;
201 int recordPos;
202 tAniPacket *packet = NULL;
203
204 if (oldPacket == NULL)
205 return ANI_E_NULL_VALUE;
206
207 retVal = aniAsfPacketAllocateExplicit(&packet,
208 oldPacket->size,
209 oldPacket->head - oldPacket->buf);
210 if (retVal != ANI_OK)
211 return retVal;
212
213 retVal = aniAsfPacketAppendBuffer(packet,
214 oldPacket->head,
215 oldPacket->len);
216 if (retVal != ANI_OK)
217 {
218 VOS_ASSERT( 0 );
219 aniAsfPacketFree(packet);
220 return ANI_E_FAILED;
221 }
222
223 if (oldPacket->recordHeader != NULL)
224 {
225 recordPos = oldPacket->recordHeader - oldPacket->buf;
226 packet->recordHeader = packet->buf + recordPos;
227 }
228 *newPacketPtr = packet;
229
230 return ANI_OK;
231}
232
233/**
234 * aniAsfPacketFree
235 *
236 * FUNCTION:
237 * Free a previously allocated tAniPacket and its internal raw data
238 * buffer.
239 *
240 * @param packet the packet to free
241 *
242 * @return ANI_OK if the operation succeeds; ANI_E_NULL_VALUE if an
243 * unexpected NULL pointer is encountered
244 */
245int
246aniAsfPacketFree(tAniPacket *packet)
247{
248 if (packet == NULL)
249 return ANI_E_NULL_VALUE;
250
251 if (packet->buf != NULL)
252 vos_mem_free( packet->buf );
253
254 vos_mem_free( packet );
255
256 return ANI_OK;
257}
258
259
260/**
261 * aniAsfPacketAppendBuffer
262 *
263 * FUNCTION:
264 * Appends the data contained in buf to the end of the data in
265 * destAniPacket. The head of destAniPacket remains unchanged, while its
266 * length increases by len.
267 *
268 * If there isn't enough free space in destAniPacket for all len bytes
269 * then the routine fails and the length of destAniPacket remains
270 * unchanged.
271 *
272 * LOGIC:
273 * Check that there is enough free space in the packet to append the
274 * buffer. If not, bail. Otherwise, copy bytes from the buffer into
275 * the packet's internal raw data buffer and increase the value of its
276 * length to reflect this.
277 *
278 * @param packet the packet to append to
279 * @param buf the buffer containing data to be appended to the packet
280 * @param len the number of bytes to append
281 *
282 * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the
283 * packet does not have enough free space for the complete buffer
284 * @see aniAsfPacketPrependBuffer
285 */
286int
287aniAsfPacketAppendBuffer(tAniPacket *destPacket,
288 const v_U8_t *buf,
289 v_U32_t len)
290{
291 if (aniAsfPacketCanAppendBuffer(destPacket, len) != ANI_OK)
292 return ANI_E_FAILED;
293
294 if (buf == NULL)
295 return ANI_E_NULL_VALUE;
296
297 vos_mem_copy(destPacket->tail, buf, len);
298 destPacket->tail += len;
299 destPacket->len += len;
300 return ANI_OK;
301}
302
303/**
304 * aniAsfPacketPrependBuffer
305 *
306 * FUNCTION:
307 * Prepends the data contained in buf to the start of the data in
308 * destPacket. The head of destPacket is repositioned and the length
309 * of destPacket increases by len.
310 *
311 * If there isn't enough free space in destPacket for all len bytes
312 * then the routine fails and the length of destPacket remains
313 * unchanged.
314 *
315 * LOGIC:
316 * Check that there is enough free space in the packet to prepend the
317 * buffer. If not, bail. Otherwise, copy bytes from the buffer into
318 * the packet's internal raw data buffer and increase the value of its
319 * length to reflect this.
320 *
321 * @param packet the packet to prepend to
322 * @param buf the buffer containing data to be prepended to the packet
323 * @param len the number of bytes to prepend
324 *
325 * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the
326 * packet does not have enough free space for the complete buffer
327 * @see aniAsfPacketAppendBuffer
328 */
329int
330aniAsfPacketPrependBuffer(tAniPacket *destPacket,
331 const v_U8_t *buf,
332 v_U32_t len)
333{
334 if (aniAsfPacketCanPrependBuffer(destPacket, len) != ANI_OK)
335 return ANI_E_FAILED;
336
337 if (buf == NULL)
338 return ANI_E_NULL_VALUE;
339
340 destPacket->head -= len;
341 destPacket->len += len;
342 vos_mem_copy(destPacket->head, buf, len);
343 return ANI_OK;
344
345}
346
347/**
348 * aniAsfPacketCanAppendBuffer
349 *
350 * FUNCTION:
351 * Determines if len bytes can be safely appended to destPacket
352 * without overflowing.
353 *
354 * LOGIC:
355 * Current packet tail plus len of buffer should not exceed packet
356 * start plus packet size
357 *
358 * Note: This does not return a boolean value, but instead an integer
359 * code.
360 *
361 * @param packet the packet to append to
362 * @param len the number of bytes to append
363 *
364 * @return ANI_OK if the append operation would succeed; ANI_E_FAILED
365 * otherwise
366 */
367int
368aniAsfPacketCanAppendBuffer(tAniPacket *destPacket,
369 v_U32_t len)
370{
371 if (destPacket == NULL)
372 return ANI_E_FAILED;
373
374 if ((int)len <= TAIL_SPACE(destPacket))
375 return ANI_OK;
376 else
377 return ANI_E_FAILED;
378}
379
380/**
381 * aniAsfPacketCanPrependBuffer
382 *
383 * FUNCTION:
384 * Determines if len bytes can be safely prepended to destPacket
385 * without overflowing.
386 *
387 * LOGIC:
388 * Current packet head minus len of buffer should not be less than
389 * start of packet.
390 *
391 * Note: This does not return a boolean value, but instead an integer
392 * code.
393 *
394 * @param packet the packet to prepend to
395 * @param len the number of bytes to prepend
396 *
397 * @return ANI_OK if the append operation would succeed; ANI_E_FAILED
398 * otherwise
399 */
400int
401aniAsfPacketCanPrependBuffer(tAniPacket *destPacket,
402 v_U32_t len)
403{
404 if (destPacket == NULL)
405 return ANI_E_FAILED;
406
407 if (!(len > 0))
408 return ANI_E_FAILED;
409
410 if ((int)len <= HEAD_SPACE(destPacket))
411 return ANI_OK;
412 else
413 return ANI_E_FAILED;
414}
415
416/**
417 * aniAsfPacketTruncateFromFront
418 *
419 * FUNCTION:
420 * Removes len bytes from the front of the packet by moving its
421 * head. The length of the packet is decremented by len.
422 *
423 * @param packet the packet to truncate from the front
424 * @param len the number of bytes to truncate
425 *
426 * @return ANI_OK if the append operation would succeed; ANI_E_FAILED
427 * otherwise
428 */
429int
430aniAsfPacketTruncateFromFront(tAniPacket *packet,
431 v_U32_t len)
432{
433 if (packet == NULL)
434 return ANI_E_NULL_VALUE;
435
436 if (!ANI_CHECK_RANGE(len, packet->len))
437 return ANI_E_FAILED;
438
439 packet->head += len;
440 packet->len -= len;
441
442 return ANI_OK;
443}
444
445/**
446 * aniAsfPacketTruncateFromRear
447 *
448 * FUNCTION:
449 * Removes len bytes from the rear of the packet by moving its
450 * tail. The length of the packet is decremented by len.
451 *
452 * @param packet the packet to truncate from the rear
453 * @param len the number of bytes to truncate
454 *
455 * @return ANI_OK if the append operation would succeed; ANI_E_FAILED
456 * otherwise
457 */
458int
459aniAsfPacketTruncateFromRear(tAniPacket *packet,
460 v_U32_t len)
461{
462 if (packet == NULL)
463 return ANI_E_NULL_VALUE;
464
465 if (!ANI_CHECK_RANGE(len, packet->len))
466 return ANI_E_FAILED;
467
468 packet->tail -= len;
469 packet->len -= len;
470
471 return ANI_OK;
472}
473
474/**
475 * aniAsfPacketGetLen
476 *
477 * FUNCTION:
478 * Returns the number of valid data bytes stored in the packet.
479 *
480 * @param packet the packet whose len we need
481 *
482 * @return the non-negative number of bytes stored in the packet
483 */
484int
485aniAsfPacketGetLen(tAniPacket *packet)
486{
487 if (packet == NULL)
488 return ANI_E_NULL_VALUE;
489
490 return packet->len;
491}
492
493/**
494 * aniAsfPacketGetBytes
495 *
496 * FUNCTION:
497 * Returns a pointer to the head of the valid data stored in the
498 * packet.
499 *
500 * @param packet the packet whose bytes we need
501 * @param rawBytesPtr the pointer that will be set the start of the
502 * raw bytes.
503 *
504 * @return The non-negative number of bytes stored in the packet if
505 * the operation succeeded. That is the same value as what would be
506 * returned by aniAsfPacketGetLen.
507 */
508int
509aniAsfPacketGetBytes(tAniPacket *packet, v_U8_t **rawBytesPtr)
510{
511 if (packet == NULL)
512 return ANI_E_NULL_VALUE;
513
514 *rawBytesPtr = packet->head;
515 return packet->len;
516}
517
518/**
519 * aniAsfPacketGetN
520 *
521 * Returns N bytes from the packet and moves the head of the packet
522 * beyond those bytes.
523 *
524 * @param packet the packet to read from
525 * @param n the number of bytes to read
526 * @param bytesPtr is set to the start of the octets
527 *
528 * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the
529 * packet does not have n bytes.
530 */
531int
532aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr)
533{
534 int retVal;
535 v_U8_t *bytes = NULL;
536
537 if (packet == NULL)
538 return ANI_E_NULL_VALUE;
539
540 retVal = aniAsfPacketGetBytes(packet, &bytes);
541 if (retVal < n)
542 return ANI_E_SHORT_PACKET;
543
544 aniAsfPacketTruncateFromFront(packet, n);
545
546 *bytesPtr = bytes;
547
548 return ANI_OK;
549}
550
551/**
552 * aniAsfPacketEmpty
553 *
554 * FUNCTION:
555 * Re-initializes the packet by positioning the head to the middle and
556 * setting the length to zero.
557 *
558 * @param packet the packet to empty
559 *
560 * @return ANI_OK if the operation succeeded
561 */
562int
563aniAsfPacketEmpty(tAniPacket *packet)
564{
565 return aniAsfPacketEmptyExplicit(packet, packet->size/2);
566}
567
568/**
569 * aniAsfPacketEmptyExplicit
570 *
571 * FUNCTION:
572 * Re-initializes the packet by positioning the head to the desired
573 * offset and setting the length to zero.
574 *
575 * @param packet the packet to empty
576 * @param offset the offset that the head of the packet should be set
577 * to. An application will be able to prepend and append data relative
578 * to this offset.
579 *
580 * @return ANI_OK if the operation succeeded
581 */
582int
583aniAsfPacketEmptyExplicit(tAniPacket *packet,
584 v_U32_t offset)
585{
586 if (packet == NULL)
587 return ANI_E_NULL_VALUE;
588
589 VOS_ASSERT(ANI_CHECK_RANGE(offset, packet->size));
590 if (!ANI_CHECK_RANGE(offset, packet->size))
591 return ANI_E_ILLEGAL_ARG;
592
593 packet->head = packet->buf + offset;
594 packet->tail = packet->head;
595 packet->len = 0;
596
597 return ANI_OK;
598}
599
600
601
602/**
603 * aniAsfPacketPrependHdr
604 *
605 * FUNCTION:
606 * Prepends a tAniHdr at the start of the packet. All host to network
607 * byte order translation is also taken care of.
608 *
609 * @param packet the packet to write to
610 * @param msgType the message type to write as part of the header
611 *
612 * @return ANI_OK if the operation succeeds
613 */
614int
615aniAsfPacketPrependHdr(tAniPacket *packet, v_U16_t msgType)
616{
617 int retVal;
618 int length;
619
620 if (packet == NULL)
621 return ANI_E_NULL_VALUE;
622
623 length = 4;
624
625 length = 2 + 2 + packet->len;
626
627 retVal = aniAsfPacketPrepend16(packet, length);
628 if (retVal < 0)
629 return retVal;
630
631 retVal = aniAsfPacketPrepend16(packet, msgType);
632 if (retVal < 0)
633 return retVal;
634
635 return ANI_OK;
636}
637
638/**
639 * aniAsfPacketGet32
640 *
641 * FUNCTION:
642 * Reads a ANI_U32 out of the packet and returns it. The packet's head
643 * is advanced and its length decremented by the appropriate length.
644 * All network to host byte order translation is also taken care of.
645 *
646 * @param packet the packet to read from
647 * @param val the value to fill in
648 *
649 * @return ANI_OK if the operation succeeds
650 */
651int
652aniAsfPacketGet32(tAniPacket *packet, v_U32_t *val)
653{
654 v_U8_t u32Arr[4];
655
656 if (packet == NULL)
657 return ANI_E_NULL_VALUE;
658
659 if (val == NULL)
660 return ANI_E_NULL_VALUE;
661
662 if (packet->len < 4)
663 return ANI_E_SHORT_PACKET;
664
665 //packet is in network order, make sure it is align
666 u32Arr[0] = packet->head[0];
667 u32Arr[1] = packet->head[1];
668 u32Arr[2] = packet->head[2];
669 u32Arr[3] = packet->head[3];
670 *val = vos_be32_to_cpu( *(v_U32_t *)u32Arr );
671 aniAsfPacketTruncateFromFront(packet, 4);
672
673 return ANI_OK;
674}
675
676/**
677 * aniAsfPacketAppend32
678 *
679 * FUNCTION:
680 * Appends a ANI_U32 to the end of the packet.
681 * All host to network byte order translation is also taken care of.
682 *
683 * @param packet the packet to write to
684 * @param val the value to append
685 *
686 * @return ANI_OK if the operation succeeds
687 */
688int
689aniAsfPacketAppend32(tAniPacket *packet, v_U32_t val)
690{
691 v_U8_t *p8;
692
693 if (packet == NULL)
694 return ANI_E_NULL_VALUE;
695
696 if (TAIL_SPACE(packet) < 4)
697 return ANI_E_FAILED;
698
699 val = vos_cpu_to_be32( val );
700 p8 = (v_U8_t *)&val;
701 packet->tail[0] = p8[0];
702 packet->tail[1] = p8[1];
703 packet->tail[2] = p8[2];
704 packet->tail[3] = p8[3];
705 aniAsfPacketMoveRight(packet, 4);
706
707 return ANI_OK;
708}
709
710/**
711 * aniAsfPacketGet16
712 *
713 * FUNCTION:
714 * Reads a ANI_U16 out of the packet and returns it. The packet's head
715 * is advanced and its length decremented by the appropriate length.
716 * All network to host byte order translation is also taken care of.
717 *
718 * @param packet the packet to read from
719 * @param val the value to fill in
720 *
721 * @return ANI_OK if the operation succeeds
722 */
723int
724aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val)
725{
726 v_U8_t u16Arr[2];
727
728 if (packet == NULL)
729 return ANI_E_NULL_VALUE;
730
731 if (val == NULL)
732 return ANI_E_NULL_VALUE;
733
734 if (packet->len < 2)
735 return ANI_E_SHORT_PACKET;
736
737 u16Arr[0] = packet->head[0];
738 u16Arr[1] = packet->head[1];
739 *val = vos_be16_to_cpu( *(v_U16_t *)u16Arr );
740 aniAsfPacketTruncateFromFront(packet, 2);
741
742 return ANI_OK;
743}
744
745/**
746 * aniAsfPacketPrepend16
747 *
748 * FUNCTION:
749 * Prepends a ANI_U16 to the start of the packet.
750 * All host to network byte order translation is also taken care of.
751 *
752 * @param packet the packet to write to
753 * @param val the value to prepend
754 *
755 * @return ANI_OK if the operation succeeds
756 */
757int
758aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val)
759{
760 v_U8_t *p8;
761
762 if (packet == NULL)
763 return ANI_E_NULL_VALUE;
764
765 if (HEAD_SPACE(packet) < 2)
766 return ANI_E_FAILED;
767
768 aniAsfPacketMoveLeft(packet, 2);
769 val = vos_cpu_to_be16( val );
770 p8 = (v_U8_t *)&val;
771 packet->head[0] = p8[0];
772 packet->head[1] = p8[1];
773
774 return ANI_OK;
775}
776
777/**
778 * aniAsfPacketAppend16
779 *
780 * FUNCTION:
781 * Appends a ANI_U16 to the end of the packet.
782 * All host to network byte order translation is also taken care of.
783 *
784 * @param packet the packet to write to
785 * @param val the value to append
786 *
787 * @return ANI_OK if the operation succeeds
788 */
789int
790aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val)
791{
792 v_U8_t *p8;
793
794 if (packet == NULL)
795 return ANI_E_NULL_VALUE;
796
797 if (TAIL_SPACE(packet) < 2)
798 return ANI_E_FAILED;
799
800 val = vos_cpu_to_be16( val );
801 p8 = (v_U8_t *)&val;
802 packet->tail[0] = p8[0];
803 packet->tail[1] = p8[1];
804 aniAsfPacketMoveRight(packet, 2);
805
806 return ANI_OK;
807}
808
809/**
810 * aniAsfPacketGet8
811 *
812 * FUNCTION:
813 * Reads a ANI_U8 out of the packet and returns it. The packet's head
814 * is advanced and its length decremented by the appropriate length.
815 * All network to host byte order translation is also taken care of.
816 *
817 * @param packet the packet to read from
818 * @param val the value to fill in
819 *
820 * @return ANI_OK if the operation succeeds
821 */
822int
823aniAsfPacketGet8(tAniPacket *packet, v_U8_t *val)
824{
825 if (packet == NULL)
826 return ANI_E_NULL_VALUE;
827
828 if (val == NULL)
829 return ANI_E_NULL_VALUE;
830
831 if (packet->len < 1)
832 return ANI_E_SHORT_PACKET;
833
834 *val = *(packet->head);
835 aniAsfPacketTruncateFromFront(packet, 1);
836
837 return ANI_OK;
838}
839
840/**
841 * aniAsfPacketPrepend8
842 *
843 * FUNCTION:
844 * Prepends a ANI_U8 to the start of the packet.
845 * All host to network byte order translation is also taken care of.
846 *
847 * @param packet the packet to read from
848 * @param val the value to prepend
849 *
850 * @return ANI_OK if the operation succeeds
851 */
852int
853aniAsfPacketPrepend8(tAniPacket *packet, v_U8_t val)
854{
855 if (packet == NULL)
856 return ANI_E_NULL_VALUE;
857
858 VOS_ASSERT(HEAD_SPACE(packet) >= 1);
859 if (HEAD_SPACE(packet) < 1)
860 return ANI_E_FAILED;
861
862 aniAsfPacketMoveLeft(packet, 1);
863 *(packet->head) = val;
864
865 return ANI_OK;
866}
867
868/**
869 * aniAsfPacketAppend8
870 *
871 * FUNCTION:
872 * Appends a ANI_U8 to the end of the packet.
873 * All host to network byte order translation is also taken care of.
874 *
875 * @param packet the packet to write to
876 * @param val the value to append
877 *
878 * @return ANI_OK if the operation succeeds
879 */
880int
881aniAsfPacketAppend8(tAniPacket *packet, v_U8_t val)
882{
883 if (packet == NULL)
884 return ANI_E_NULL_VALUE;
885
886 if (TAIL_SPACE(packet) < 1)
887 return ANI_E_FAILED;
888
889 *(packet->tail) = val;
890 aniAsfPacketMoveRight(packet, 1);
891
892 return ANI_OK;
893}
894
895/**
896 * aniAsfPacketGetMac
897 *
898 * FUNCTION:
899 * Returns a tAniMacAddr from the start of the packet.
900 *
901 * @param packet the packet to read from
902 * @param macAddr the destination to copy the MAC address to
903 *
904 * @return ANI_OK if the operation succeeds. Also, the packet head
905 * pointer is advanced past the MAC address.
906 */
907int
908aniAsfPacketGetMac(tAniPacket *packet, tAniMacAddr macAddr)
909{
910 if (packet->len < sizeof(tAniMacAddr))
911 return ANI_E_SHORT_PACKET;
912
913 vos_mem_copy(macAddr, packet->head, sizeof(tAniMacAddr));
914
915 packet->head += sizeof(tAniMacAddr);
916 packet->len -= sizeof(tAniMacAddr);
917
918 return ANI_OK;
919}
920
921/**
922 * aniAsfPacketMoveLeft
923 *
924 * FUNCTION:
925 * Pretends that a certain number of bytes have been prepended to the
926 * packet, without actually copying any bytes in. The packet head and
927 * length are appropriately changed. This function is useful while
928 * interfacing with other libraries that only support byte array
929 * manipulation.
930 *
931 * WARNING:
932 * Applications are discouraged from using this function
933 * because correct usage is a two-step process - one: copy some bytes
934 * to the packet's internal buffer, two: move head and length. This
935 * violates the encapsulation the packet library aims to provide.
936 *
937 * @param packet the packet whose head and length needs to be modified
938 * @param count the number of bytes to modify by
939 *
940 * @return ANI_OK if the operation succeeds
941 */
942int
943aniAsfPacketMoveLeft(tAniPacket *packet, v_U32_t count)
944{
945 if (aniAsfPacketCanPrependBuffer(packet, count) != ANI_OK)
946 return ANI_E_FAILED;
947
948 packet->head -= count;
949 packet->len += count;
950
951 return ANI_OK;
952}
953
954/**
955 * aniAsfPacketMoveRight
956 *
957 * FUNCTION:
958 * Pretends that a certain number of bytes have been appended to the
959 * packet, without actually copying any bytes in. The packet tail and
960 * length are appropriately changed. This function is useful while
961 * interfacing with other libraries that only support byte array
962 * manipulation.
963 *
964 * WARNING:
965 * Applications are discouraged from using this function
966 * because correct usage is a two-step process - one: copy some bytes
967 * to the packet's internal buffer, two: move tail and length. This
968 * violates the encapsulation the packet library aims to provide.
969 *
970 * @param packet the packet whose head and length needs to be modified
971 * @param count the number of bytes to modify by
972 *
973 * @return ANI_OK if the operation succeeds
974 */
975int
976aniAsfPacketMoveRight(tAniPacket *packet, v_U32_t count)
977{
978 if (aniAsfPacketCanAppendBuffer(packet, count) != ANI_OK)
979 return ANI_E_FAILED;
980
981 packet->tail += count;
982 packet->len += count;
983
984 return ANI_OK;
985}
986
987/**
988 * aniAsfPacketGetBytesFromTail
989 *
990 * FUNCTION:
991 * Returns a pointer to the tail of the valid data stored
992 * in the packet.
993 *
994 * WARNING:
995 * Applications are discouraged from using this function
996 * because correct usage is a three-step process - one: call this
997 * routine to obtain a pointer to the current tail of the packet.
998 * two: treat this returned pointer like a simple array and copy
999 * some bytes to the packet's internal buffer, and finally
1000 * three: move tail and length. This violates the encapsulation
1001 * the packet library aims to provide.
1002 *
1003 * @param packet the packet whose bytes we need
1004 * @param rawBytesPtr the pointer that will be set the start of the
1005 * raw bytes.
1006 *
1007 * @return The non-negative number of bytes stored in the packet if
1008 * the operation succeeded. That is the same value as what would be
1009 * returned by aniAsfPacketGetLen.
1010 */
1011int
1012aniAsfPacketGetBytesFromTail(tAniPacket *packet, v_U8_t **rawBytesPtr)
1013{
1014 if (packet == NULL)
1015 return ANI_E_NULL_VALUE;
1016
1017 *rawBytesPtr = packet->tail;
1018 return 0; // The length of used bytes returned is zero
1019}
1020