/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2015 Samsung LSI
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package javax.obex;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import android.util.Log;

/**
 * This class defines a set of helper methods for the implementation of Obex.
 * @hide
 */
public final class ObexHelper {

    private static final String TAG = "ObexHelper";
    public static final boolean VDBG = false;
    /**
     * Defines the basic packet length used by OBEX. Every OBEX packet has the
     * same basic format:<BR>
     * Byte 0: Request or Response Code Byte 1&2: Length of the packet.
     */
    public static final int BASE_PACKET_LENGTH = 3;

    /** Prevent object construction of helper class */
    private ObexHelper() {
    }

    /**
     * The maximum packet size for OBEX packets that this client can handle. At
     * present, this must be changed for each port. TODO: The max packet size
     * should be the Max incoming MTU minus TODO: L2CAP package headers and
     * RFCOMM package headers. TODO: Retrieve the max incoming MTU from TODO:
     * LocalDevice.getProperty().
     * NOTE: This value must be larger than or equal to the L2CAP SDU
     */
    /*
     * android note set as 0xFFFE to match remote MPS
     */
    public static final int MAX_PACKET_SIZE_INT = 0xFFFE;

    // The minimum allowed max packet size is 255 according to the OBEX specification
    public static final int LOWER_LIMIT_MAX_PACKET_SIZE = 255;

    /**
     * Temporary workaround to be able to push files to Windows 7.
     * TODO: Should be removed as soon as Microsoft updates their driver.
     */
    public static final int MAX_CLIENT_PACKET_SIZE = 0xFC00;

    public static final int OBEX_OPCODE_FINAL_BIT_MASK = 0x80;

    public static final int OBEX_OPCODE_CONNECT = 0x80;

    public static final int OBEX_OPCODE_DISCONNECT = 0x81;

    public static final int OBEX_OPCODE_PUT = 0x02;

    public static final int OBEX_OPCODE_PUT_FINAL = 0x82;

    public static final int OBEX_OPCODE_GET = 0x03;

    public static final int OBEX_OPCODE_GET_FINAL = 0x83;

    public static final int OBEX_OPCODE_RESERVED = 0x04;

    public static final int OBEX_OPCODE_RESERVED_FINAL = 0x84;

    public static final int OBEX_OPCODE_SETPATH = 0x85;

    public static final int OBEX_OPCODE_ABORT = 0xFF;

    public static final int OBEX_AUTH_REALM_CHARSET_ASCII = 0x00;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_1 = 0x01;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_2 = 0x02;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_3 = 0x03;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_4 = 0x04;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_5 = 0x05;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_6 = 0x06;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_7 = 0x07;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_8 = 0x08;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_9 = 0x09;

    public static final int OBEX_AUTH_REALM_CHARSET_UNICODE = 0xFF;

    public static final byte OBEX_SRM_ENABLE         = 0x01; // For BT we only need enable/disable
    public static final byte OBEX_SRM_DISABLE        = 0x00;
    public static final byte OBEX_SRM_SUPPORT        = 0x02; // Unused for now

    public static final byte OBEX_SRMP_WAIT          = 0x01; // Only SRMP value used by BT

    /**
     * Updates the HeaderSet with the headers received in the byte array
     * provided. Invalid headers are ignored.
     * <P>
     * The first two bits of an OBEX Header specifies the type of object that is
     * being sent. The table below specifies the meaning of the high bits.
     * <TABLE>
     * <TR>
     * <TH>Bits 8 and 7</TH>
     * <TH>Value</TH>
     * <TH>Description</TH>
     * </TR>
     * <TR>
     * <TD>00</TD>
     * <TD>0x00</TD>
     * <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
     * </TR>
     * <TR>
     * <TD>01</TD>
     * <TD>0x40</TD>
     * <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
     * </TR>
     * <TR>
     * <TD>10</TD>
     * <TD>0x80</TD>
     * <TD>1 byte quantity</TD>
     * </TR>
     * <TR>
     * <TD>11</TD>
     * <TD>0xC0</TD>
     * <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
     * </TR>
     * </TABLE>
     * This method uses the information in this table to determine the type of
     * Java object to create and passes that object with the full header to
     * setHeader() to update the HeaderSet object. Invalid headers will cause an
     * exception to be thrown. When it is thrown, it is ignored.
     * @param header the HeaderSet to update
     * @param headerArray the byte array containing headers
     * @return the result of the last start body or end body header provided;
     *         the first byte in the result will specify if a body or end of
     *         body is received
     * @throws IOException if an invalid header was found
     */
    public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
        int index = 0;
        int length = 0;
        int headerID;
        byte[] value = null;
        byte[] body = null;
        HeaderSet headerImpl = header;
        try {
            while (index < headerArray.length) {
                headerID = 0xFF & headerArray[index];
                switch (headerID & (0xC0)) {

                    /*
                     * 0x00 is a unicode null terminate string with the first
                     * two bytes after the header identifier being the length
                     */
                    case 0x00:
                        // Fall through
                        /*
                         * 0x40 is a byte sequence with the first
                         * two bytes after the header identifier being the length
                         */
                    case 0x40:
                        boolean trimTail = true;
                        index++;
                        length = 0xFF & headerArray[index];
                        length = length << 8;
                        index++;
                        length += 0xFF & headerArray[index];
                        length -= 3;
                        index++;
                        value = new byte[length];
                        System.arraycopy(headerArray, index, value, 0, length);
                        if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
                            trimTail = false;
                        }
                        switch (headerID) {
                            case HeaderSet.TYPE:
                                try {
                                    // Remove trailing null
                                    if (trimTail == false) {
                                        headerImpl.setHeader(headerID, new String(value, 0,
                                                value.length, "ISO8859_1"));
                                    } else {
                                        headerImpl.setHeader(headerID, new String(value, 0,
                                                value.length - 1, "ISO8859_1"));
                                    }
                                } catch (UnsupportedEncodingException e) {
                                    throw e;
                                }
                                break;

                            case HeaderSet.AUTH_CHALLENGE:
                                headerImpl.mAuthChall = new byte[length];
                                System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0,
                                        length);
                                break;

                            case HeaderSet.AUTH_RESPONSE:
                                headerImpl.mAuthResp = new byte[length];
                                System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0,
                                        length);
                                break;

                            case HeaderSet.BODY:
                                /* Fall Through */
                            case HeaderSet.END_OF_BODY:
                                body = new byte[length + 1];
                                body[0] = (byte)headerID;
                                System.arraycopy(headerArray, index, body, 1, length);
                                break;

                            case HeaderSet.TIME_ISO_8601:
                                try {
                                    String dateString = new String(value, "ISO8859_1");
                                    Calendar temp = Calendar.getInstance();
                                    if ((dateString.length() == 16)
                                            && (dateString.charAt(15) == 'Z')) {
                                        temp.setTimeZone(TimeZone.getTimeZone("UTC"));
                                    }
                                    temp.set(Calendar.YEAR, Integer.parseInt(dateString.substring(
                                            0, 4)));
                                    temp.set(Calendar.MONTH, Integer.parseInt(dateString.substring(
                                            4, 6)));
                                    temp.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString
                                            .substring(6, 8)));
                                    temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString
                                            .substring(9, 11)));
                                    temp.set(Calendar.MINUTE, Integer.parseInt(dateString
                                            .substring(11, 13)));
                                    temp.set(Calendar.SECOND, Integer.parseInt(dateString
                                            .substring(13, 15)));
                                    headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp);
                                } catch (UnsupportedEncodingException e) {
                                    throw e;
                                }
                                break;

                            default:
                                if ((headerID & 0xC0) == 0x00) {
                                    headerImpl.setHeader(headerID, ObexHelper.convertToUnicode(
                                            value, true));
                                } else {
                                    headerImpl.setHeader(headerID, value);
                                }
                        }

                        index += length;
                        break;

                    /*
                     * 0x80 is a byte header.  The only valid byte headers are
                     * the 16 user defined byte headers.
                     */
                    case 0x80:
                        index++;
                        try {
                            headerImpl.setHeader(headerID, Byte.valueOf(headerArray[index]));
                        } catch (Exception e) {
                            // Not a valid header so ignore
                        }
                        index++;
                        break;

                    /*
                     * 0xC0 is a 4 byte unsigned integer header and with the
                     * exception of TIME_4_BYTE will be converted to a Long
                     * and added.
                     */
                    case 0xC0:
                        index++;
                        value = new byte[4];
                        System.arraycopy(headerArray, index, value, 0, 4);
                        try {
                            if (headerID != HeaderSet.TIME_4_BYTE) {
                                // Determine if it is a connection ID.  These
                                // need to be handled differently
                                if (headerID == HeaderSet.CONNECTION_ID) {
                                    headerImpl.mConnectionID = new byte[4];
                                    System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4);
                                } else {
                                    headerImpl.setHeader(headerID, Long
                                            .valueOf(convertToLong(value)));
                                }
                            } else {
                                Calendar temp = Calendar.getInstance();
                                temp.setTime(new Date(convertToLong(value) * 1000L));
                                headerImpl.setHeader(HeaderSet.TIME_4_BYTE, temp);
                            }
                        } catch (Exception e) {
                            // Not a valid header so ignore
                            throw new IOException("Header was not formatted properly", e);
                        }
                        index += 4;
                        break;
                }

            }
        } catch (IOException e) {
            throw new IOException("Header was not formatted properly", e);
        }

        return body;
    }

    /**
     * Creates the header part of OBEX packet based on the header provided.
     * TODO: Could use getHeaderList() to get the array of headers to include
     * and then use the high two bits to determine the the type of the object
     * and construct the byte array from that. This will make the size smaller.
     * @param head the header used to construct the byte array
     * @param nullOut <code>true</code> if the header should be set to
     *        <code>null</code> once it is added to the array or
     *        <code>false</code> if it should not be nulled out
     * @return the header of an OBEX packet
     */
    public static byte[] createHeader(HeaderSet head, boolean nullOut) {
        Long intHeader = null;
        String stringHeader = null;
        Calendar dateHeader = null;
        Byte byteHeader = null;
        StringBuffer buffer = null;
        byte[] value = null;
        byte[] result = null;
        byte[] lengthArray = new byte[2];
        int length;
        HeaderSet headImpl = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        headImpl = head;

        try {
            /*
             * Determine if there is a connection ID to send.  If there is,
             * then it should be the first header in the packet.
             */
            if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) {

                out.write((byte)HeaderSet.CONNECTION_ID);
                out.write(headImpl.mConnectionID);
            }

            // Count Header
            intHeader = (Long)headImpl.getHeader(HeaderSet.COUNT);
            if (intHeader != null) {
                out.write((byte)HeaderSet.COUNT);
                value = ObexHelper.convertToByteArray(intHeader.longValue());
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.COUNT, null);
                }
            }

            // Name Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.NAME);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.NAME);
                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                length = value.length + 3;
                lengthArray[0] = (byte)(0xFF & (length >> 8));
                lengthArray[1] = (byte)(0xFF & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.NAME, null);
                }
            } else if (headImpl.getEmptyNameHeader()) {
                out.write((byte) HeaderSet.NAME);
                lengthArray[0] = (byte) 0x00;
                lengthArray[1] = (byte) 0x03;
                out.write(lengthArray);
            }

            // Type Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.TYPE);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.TYPE);
                try {
                    value = stringHeader.getBytes("ISO8859_1");
                } catch (UnsupportedEncodingException e) {
                    throw e;
                }

                length = value.length + 4;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                out.write(0x00);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TYPE, null);
                }
            }

            // Length Header
            intHeader = (Long)headImpl.getHeader(HeaderSet.LENGTH);
            if (intHeader != null) {
                out.write((byte)HeaderSet.LENGTH);
                value = ObexHelper.convertToByteArray(intHeader.longValue());
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.LENGTH, null);
                }
            }

            // Time ISO Header
            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_ISO_8601);
            if (dateHeader != null) {

                /*
                 * The ISO Header should take the form YYYYMMDDTHHMMSSZ.  The
                 * 'Z' will only be included if it is a UTC time.
                 */
                buffer = new StringBuffer();
                int temp = dateHeader.get(Calendar.YEAR);
                for (int i = temp; i < 1000; i = i * 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.MONTH);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.DAY_OF_MONTH);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                buffer.append("T");
                temp = dateHeader.get(Calendar.HOUR_OF_DAY);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.MINUTE);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.SECOND);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);

                if (dateHeader.getTimeZone().getID().equals("UTC")) {
                    buffer.append("Z");
                }

                try {
                    value = buffer.toString().getBytes("ISO8859_1");
                } catch (UnsupportedEncodingException e) {
                    throw e;
                }

                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(HeaderSet.TIME_ISO_8601);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TIME_ISO_8601, null);
                }
            }

            // Time 4 Byte Header
            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_4_BYTE);
            if (dateHeader != null) {
                out.write(HeaderSet.TIME_4_BYTE);

                /*
                 * Need to call getTime() twice.  The first call will return
                 * a java.util.Date object.  The second call returns the number
                 * of milliseconds since January 1, 1970.  We need to convert
                 * it to seconds since the TIME_4_BYTE expects the number of
                 * seconds since January 1, 1970.
                 */
                value = ObexHelper.convertToByteArray(dateHeader.getTime().getTime() / 1000L);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TIME_4_BYTE, null);
                }
            }

            // Description Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.DESCRIPTION);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.DESCRIPTION);
                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.DESCRIPTION, null);
                }
            }

            // Target Header
            value = (byte[])headImpl.getHeader(HeaderSet.TARGET);
            if (value != null) {
                out.write((byte)HeaderSet.TARGET);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TARGET, null);
                }
            }

            // HTTP Header
            value = (byte[])headImpl.getHeader(HeaderSet.HTTP);
            if (value != null) {
                out.write((byte)HeaderSet.HTTP);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.HTTP, null);
                }
            }

            // Who Header
            value = (byte[])headImpl.getHeader(HeaderSet.WHO);
            if (value != null) {
                out.write((byte)HeaderSet.WHO);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.WHO, null);
                }
            }

            // Connection ID Header
            value = (byte[])headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
            if (value != null) {
                out.write((byte)HeaderSet.APPLICATION_PARAMETER);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.APPLICATION_PARAMETER, null);
                }
            }

            // Object Class Header
            value = (byte[])headImpl.getHeader(HeaderSet.OBJECT_CLASS);
            if (value != null) {
                out.write((byte)HeaderSet.OBJECT_CLASS);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.OBJECT_CLASS, null);
                }
            }

            // Check User Defined Headers
            for (int i = 0; i < 16; i++) {

                //Unicode String Header
                stringHeader = (String)headImpl.getHeader(i + 0x30);
                if (stringHeader != null) {
                    out.write((byte)i + 0x30);
                    value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                    length = value.length + 3;
                    lengthArray[0] = (byte)(255 & (length >> 8));
                    lengthArray[1] = (byte)(255 & length);
                    out.write(lengthArray);
                    out.write(value);
                    if (nullOut) {
                        headImpl.setHeader(i + 0x30, null);
                    }
                }

                // Byte Sequence Header
                value = (byte[])headImpl.getHeader(i + 0x70);
                if (value != null) {
                    out.write((byte)i + 0x70);
                    length = value.length + 3;
                    lengthArray[0] = (byte)(255 & (length >> 8));
                    lengthArray[1] = (byte)(255 & length);
                    out.write(lengthArray);
                    out.write(value);
                    if (nullOut) {
                        headImpl.setHeader(i + 0x70, null);
                    }
                }

                // Byte Header
                byteHeader = (Byte)headImpl.getHeader(i + 0xB0);
                if (byteHeader != null) {
                    out.write((byte)i + 0xB0);
                    out.write(byteHeader.byteValue());
                    if (nullOut) {
                        headImpl.setHeader(i + 0xB0, null);
                    }
                }

                // Integer header
                intHeader = (Long)headImpl.getHeader(i + 0xF0);
                if (intHeader != null) {
                    out.write((byte)i + 0xF0);
                    out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
                    if (nullOut) {
                        headImpl.setHeader(i + 0xF0, null);
                    }
                }
            }

            // Add the authentication challenge header
            if (headImpl.mAuthChall != null) {
                out.write((byte)HeaderSet.AUTH_CHALLENGE);
                length = headImpl.mAuthChall.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(headImpl.mAuthChall);
                if (nullOut) {
                    headImpl.mAuthChall = null;
                }
            }

            // Add the authentication response header
            if (headImpl.mAuthResp != null) {
                out.write((byte)HeaderSet.AUTH_RESPONSE);
                length = headImpl.mAuthResp.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(headImpl.mAuthResp);
                if (nullOut) {
                    headImpl.mAuthResp = null;
                }
            }

            // TODO:
            // If the SRM and SRMP header is in use, they must be send in the same OBEX packet
            // But the current structure of the obex code cannot handle this, and therefore
            // it makes sense to put them in the tail of the headers, since we then reduce the
            // chance of enabling SRM to soon. The down side is that SRM cannot be used while
            // transferring non-body headers

            // Add the SRM header
            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
            if (byteHeader != null) {
                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE);
                out.write(byteHeader.byteValue());
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, null);
                }
            }

            // Add the SRM parameter header
            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
            if (byteHeader != null) {
                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
                out.write(byteHeader.byteValue());
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
                }
            }

        } catch (IOException e) {
        } finally {
            result = out.toByteArray();
            try {
                out.close();
            } catch (Exception ex) {
            }
        }

        return result;

    }

    /**
     * Determines where the maximum divide is between headers. This method is
     * used by put and get operations to separate headers to a size that meets
     * the max packet size allowed.
     * @param headerArray the headers to separate
     * @param start the starting index to search
     * @param maxSize the maximum size of a packet
     * @return the index of the end of the header block to send or -1 if the
     *         header could not be divided because the header is too large
     */
    public static int findHeaderEnd(byte[] headerArray, int start, int maxSize) {

        int fullLength = 0;
        int lastLength = -1;
        int index = start;
        int length = 0;

        // TODO: Ensure SRM and SRMP headers are not split into two OBEX packets

        while ((fullLength < maxSize) && (index < headerArray.length)) {
            int headerID = (headerArray[index] < 0 ? headerArray[index] + 256 : headerArray[index]);
            lastLength = fullLength;

            switch (headerID & (0xC0)) {

                case 0x00:
                    // Fall through
                case 0x40:

                    index++;
                    length = (headerArray[index] < 0 ? headerArray[index] + 256
                            : headerArray[index]);
                    length = length << 8;
                    index++;
                    length += (headerArray[index] < 0 ? headerArray[index] + 256
                            : headerArray[index]);
                    length -= 3;
                    index++;
                    index += length;
                    fullLength += length + 3;
                    break;

                case 0x80:

                    index++;
                    index++;
                    fullLength += 2;
                    break;

                case 0xC0:

                    index += 5;
                    fullLength += 5;
                    break;

            }

        }

        /*
         * Determine if this is the last header or not
         */
        if (lastLength == 0) {
            /*
             * Since this is the last header, check to see if the size of this
             * header is less then maxSize.  If it is, return the length of the
             * header, otherwise return -1.  The length of the header is
             * returned since it would be the start of the next header
             */
            if (fullLength < maxSize) {
                return headerArray.length;
            } else {
                return -1;
            }
        } else {
            return lastLength + start;
        }
    }

    /**
     * Converts the byte array to a long.
     * @param b the byte array to convert to a long
     * @return the byte array as a long
     */
    public static long convertToLong(byte[] b) {
        long result = 0;
        long value = 0;
        long power = 0;

        for (int i = (b.length - 1); i >= 0; i--) {
            value = b[i];
            if (value < 0) {
                value += 256;
            }

            result = result | (value << power);
            power += 8;
        }

        return result;
    }

    /**
     * Converts the long to a 4 byte array. The long must be non negative.
     * @param l the long to convert
     * @return a byte array that is the same as the long
     */
    public static byte[] convertToByteArray(long l) {
        byte[] b = new byte[4];

        b[0] = (byte)(255 & (l >> 24));
        b[1] = (byte)(255 & (l >> 16));
        b[2] = (byte)(255 & (l >> 8));
        b[3] = (byte)(255 & l);

        return b;
    }

    /**
     * Converts the String to a UNICODE byte array. It will also add the ending
     * null characters to the end of the string.
     * @param s the string to convert
     * @return the unicode byte array of the string
     */
    public static byte[] convertToUnicodeByteArray(String s) {
        if (s == null) {
            return null;
        }

        char c[] = s.toCharArray();
        byte[] result = new byte[(c.length * 2) + 2];
        for (int i = 0; i < c.length; i++) {
            result[(i * 2)] = (byte)(c[i] >> 8);
            result[((i * 2) + 1)] = (byte)c[i];
        }

        // Add the UNICODE null character
        result[result.length - 2] = 0;
        result[result.length - 1] = 0;

        return result;
    }

    /**
     * Retrieves the value from the byte array for the tag value specified. The
     * array should be of the form Tag - Length - Value triplet.
     * @param tag the tag to retrieve from the byte array
     * @param triplet the byte sequence containing the tag length value form
     * @return the value of the specified tag
     */
    public static byte[] getTagValue(byte tag, byte[] triplet) {

        int index = findTag(tag, triplet);
        if (index == -1) {
            return null;
        }

        index++;
        int length = triplet[index] & 0xFF;

        byte[] result = new byte[length];
        index++;
        System.arraycopy(triplet, index, result, 0, length);

        return result;
    }

    /**
     * Finds the index that starts the tag value pair in the byte array provide.
     * @param tag the tag to look for
     * @param value the byte array to search
     * @return the starting index of the tag or -1 if the tag could not be found
     */
    public static int findTag(byte tag, byte[] value) {
        int length = 0;

        if (value == null) {
            return -1;
        }

        int index = 0;

        while ((index < value.length) && (value[index] != tag)) {
            length = value[index + 1] & 0xFF;
            index += length + 2;
        }

        if (index >= value.length) {
            return -1;
        }

        return index;
    }

    /**
     * Converts the byte array provided to a unicode string.
     * @param b the byte array to convert to a string
     * @param includesNull determine if the byte string provided contains the
     *        UNICODE null character at the end or not; if it does, it will be
     *        removed
     * @return a Unicode string
     * @throws IllegalArgumentException if the byte array has an odd length
     */
    public static String convertToUnicode(byte[] b, boolean includesNull) {
        if (b == null || b.length == 0) {
            return null;
        }
        int arrayLength = b.length;
        if (!((arrayLength % 2) == 0)) {
            throw new IllegalArgumentException("Byte array not of a valid form");
        }
        arrayLength = (arrayLength >> 1);
        if (includesNull) {
            arrayLength -= 1;
        }

        char[] c = new char[arrayLength];
        for (int i = 0; i < arrayLength; i++) {
            int upper = b[2 * i];
            int lower = b[(2 * i) + 1];
            if (upper < 0) {
                upper += 256;
            }
            if (lower < 0) {
                lower += 256;
            }
            // If upper and lower both equal 0, it should be the end of string.
            // Ignore left bytes from array to avoid potential issues
            if (upper == 0 && lower == 0) {
                return new String(c, 0, i);
            }

            c[i] = (char)((upper << 8) | lower);
        }

        return new String(c);
    }

    /**
     * Compute the MD5 hash of the byte array provided. Does not accumulate
     * input.
     * @param in the byte array to hash
     * @return the MD5 hash of the byte array
     */
    public static byte[] computeMd5Hash(byte[] in) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return md5.digest(in);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Computes an authentication challenge header.
     * @param nonce the challenge that will be provided to the peer; the
     *        challenge must be 16 bytes long
     * @param realm a short description that describes what password to use
     * @param access if <code>true</code> then full access will be granted if
     *        successful; if <code>false</code> then read only access will be
     *        granted if successful
     * @param userID if <code>true</code>, a user ID is required in the reply;
     *        if <code>false</code>, no user ID is required
     * @throws IllegalArgumentException if the challenge is not 16 bytes long;
     *         if the realm can not be encoded in less then 255 bytes
     * @throws IOException if the encoding scheme ISO 8859-1 is not supported
     */
    public static byte[] computeAuthenticationChallenge(byte[] nonce, String realm, boolean access,
            boolean userID) throws IOException {
        byte[] authChall = null;

        if (nonce.length != 16) {
            throw new IllegalArgumentException("Nonce must be 16 bytes long");
        }

        /*
         * The authentication challenge is a byte sequence of the following form
         * byte 0: 0x00 - the tag for the challenge
         * byte 1: 0x10 - the length of the challenge; must be 16
         * byte 2-17: the authentication challenge
         * byte 18: 0x01 - the options tag; this is optional in the spec, but
         *                 we are going to include it in every message
         * byte 19: 0x01 - length of the options; must be 1
         * byte 20: the value of the options; bit 0 is set if user ID is
         *          required; bit 1 is set if access mode is read only
         * byte 21: 0x02 - the tag for authentication realm; only included if
         *                 an authentication realm is specified
         * byte 22: the length of the authentication realm; only included if
         *          the authentication realm is specified
         * byte 23: the encoding scheme of the authentication realm; we will use
         *          the ISO 8859-1 encoding scheme since it is part of the KVM
         * byte 24 & up: the realm if one is specified.
         */
        if (realm == null) {
            authChall = new byte[21];
        } else {
            if (realm.length() >= 255) {
                throw new IllegalArgumentException("Realm must be less then 255 bytes");
            }
            authChall = new byte[24 + realm.length()];
            authChall[21] = 0x02;
            authChall[22] = (byte)(realm.length() + 1);
            authChall[23] = 0x01; // ISO 8859-1 Encoding
            System.arraycopy(realm.getBytes("ISO8859_1"), 0, authChall, 24, realm.length());
        }

        // Include the nonce field in the header
        authChall[0] = 0x00;
        authChall[1] = 0x10;
        System.arraycopy(nonce, 0, authChall, 2, 16);

        // Include the options header
        authChall[18] = 0x01;
        authChall[19] = 0x01;
        authChall[20] = 0x00;

        if (!access) {
            authChall[20] = (byte)(authChall[20] | 0x02);
        }
        if (userID) {
            authChall[20] = (byte)(authChall[20] | 0x01);
        }

        return authChall;
    }

    /**
     * Return the maximum allowed OBEX packet to transmit.
     * OBEX packets transmitted must be smaller than this value.
     * @param transport Reference to the ObexTransport in use.
     * @return the maximum allowed OBEX packet to transmit
     */
    public static int getMaxTxPacketSize(ObexTransport transport) {
        int size = transport.getMaxTransmitPacketSize();
        return validateMaxPacketSize(size);
    }

    /**
     * Return the maximum allowed OBEX packet to receive - used in OBEX connect.
     * @param transport
     * @return he maximum allowed OBEX packet to receive
     */
    public static int getMaxRxPacketSize(ObexTransport transport) {
        int size = transport.getMaxReceivePacketSize();
        return validateMaxPacketSize(size);
    }

    private static int validateMaxPacketSize(int size) {
        if(VDBG && (size > MAX_PACKET_SIZE_INT)) Log.w(TAG,
                "The packet size supported for the connection (" + size + ") is larger"
                + " than the configured OBEX packet size: " + MAX_PACKET_SIZE_INT);
        if(size != -1) {
            if(size < LOWER_LIMIT_MAX_PACKET_SIZE) {
                throw new IllegalArgumentException(size + " is less that the lower limit: "
                        + LOWER_LIMIT_MAX_PACKET_SIZE);
            }
            return size;
        }
        return MAX_PACKET_SIZE_INT;
    }
}
