michael@0: /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "ObexBase.h" michael@0: michael@0: BEGIN_BLUETOOTH_NAMESPACE michael@0: michael@0: int michael@0: AppendHeaderName(uint8_t* aRetBuf, int aBufferSize, const char* aName, michael@0: int aLength) michael@0: { michael@0: int headerLength = aLength + 3; michael@0: michael@0: aRetBuf[0] = ObexHeaderId::Name; michael@0: aRetBuf[1] = (headerLength & 0xFF00) >> 8; michael@0: aRetBuf[2] = headerLength & 0x00FF; michael@0: michael@0: memcpy(&aRetBuf[3], aName, (aLength < aBufferSize - 3)? aLength michael@0: : aBufferSize - 3); michael@0: michael@0: return headerLength; michael@0: } michael@0: michael@0: int michael@0: AppendHeaderBody(uint8_t* aRetBuf, int aBufferSize, const uint8_t* aData, michael@0: int aLength) michael@0: { michael@0: int headerLength = aLength + 3; michael@0: michael@0: aRetBuf[0] = ObexHeaderId::Body; michael@0: aRetBuf[1] = (headerLength & 0xFF00) >> 8; michael@0: aRetBuf[2] = headerLength & 0x00FF; michael@0: michael@0: memcpy(&aRetBuf[3], aData, (aLength < aBufferSize - 3)? aLength michael@0: : aBufferSize - 3); michael@0: michael@0: return headerLength; michael@0: } michael@0: michael@0: int michael@0: AppendHeaderEndOfBody(uint8_t* aRetBuf) michael@0: { michael@0: aRetBuf[0] = ObexHeaderId::EndOfBody; michael@0: aRetBuf[1] = 0x00; michael@0: aRetBuf[2] = 0x03; michael@0: michael@0: return 3; michael@0: } michael@0: michael@0: int michael@0: AppendHeaderLength(uint8_t* aRetBuf, int aObjectLength) michael@0: { michael@0: aRetBuf[0] = ObexHeaderId::Length; michael@0: aRetBuf[1] = (aObjectLength & 0xFF000000) >> 24; michael@0: aRetBuf[2] = (aObjectLength & 0x00FF0000) >> 16; michael@0: aRetBuf[3] = (aObjectLength & 0x0000FF00) >> 8; michael@0: aRetBuf[4] = aObjectLength & 0x000000FF; michael@0: michael@0: return 5; michael@0: } michael@0: michael@0: int michael@0: AppendHeaderConnectionId(uint8_t* aRetBuf, int aConnectionId) michael@0: { michael@0: aRetBuf[0] = ObexHeaderId::ConnectionId; michael@0: aRetBuf[1] = (aConnectionId & 0xFF000000) >> 24; michael@0: aRetBuf[2] = (aConnectionId & 0x00FF0000) >> 16; michael@0: aRetBuf[3] = (aConnectionId & 0x0000FF00) >> 8; michael@0: aRetBuf[4] = aConnectionId & 0x000000FF; michael@0: michael@0: return 5; michael@0: } michael@0: michael@0: void michael@0: SetObexPacketInfo(uint8_t* aRetBuf, uint8_t aOpcode, int aPacketLength) michael@0: { michael@0: aRetBuf[0] = aOpcode; michael@0: aRetBuf[1] = (aPacketLength & 0xFF00) >> 8; michael@0: aRetBuf[2] = aPacketLength & 0x00FF; michael@0: } michael@0: michael@0: bool michael@0: ParseHeaders(const uint8_t* aHeaderStart, michael@0: int aTotalLength, michael@0: ObexHeaderSet* aRetHandlerSet) michael@0: { michael@0: const uint8_t* ptr = aHeaderStart; michael@0: michael@0: while (ptr - aHeaderStart < aTotalLength) { michael@0: ObexHeaderId headerId = (ObexHeaderId)*ptr++; michael@0: michael@0: uint16_t contentLength = 0; michael@0: uint8_t highByte, lowByte; michael@0: michael@0: // Defined in 2.1 OBEX Headers, IrOBEX 1.2 michael@0: switch (headerId >> 6) michael@0: { michael@0: case 0x00: michael@0: // Null-terminated Unicode text, length prefixed with 2-byte michael@0: // unsigned integer. michael@0: case 0x01: michael@0: // byte sequence, length prefixed with 2 byte unsigned integer. michael@0: highByte = *ptr++; michael@0: lowByte = *ptr++; michael@0: contentLength = (((uint16_t)highByte << 8) | lowByte) - 3; michael@0: break; michael@0: michael@0: case 0x02: michael@0: // 1 byte quantity michael@0: contentLength = 1; michael@0: break; michael@0: michael@0: case 0x03: michael@0: // 4 byte quantity michael@0: contentLength = 4; michael@0: break; michael@0: } michael@0: michael@0: // Length check to prevent from memory pollusion. michael@0: if (ptr + contentLength > aHeaderStart + aTotalLength) { michael@0: // Severe error occurred. We can't even believe the received data, so michael@0: // clear all headers. michael@0: MOZ_ASSERT(false); michael@0: aRetHandlerSet->ClearHeaders(); michael@0: return false; michael@0: } michael@0: michael@0: aRetHandlerSet->AddHeader(new ObexHeader(headerId, contentLength, ptr)); michael@0: ptr += contentLength; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: END_BLUETOOTH_NAMESPACE