/** @file
  Helper functions to parse HID report descriptor and items.

Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UsbMouseAbsolutePointer.h"


/**
  Get next HID item from report descriptor.

  This function retrieves next HID item from report descriptor, according to
  the start position.
  According to USB HID Specification, An item is piece of information
  about the device. All items have a one-byte prefix that contains
  the item tag, item type, and item size.
  There are two basic types of items: short items and long items.
  If the item is a short item, its optional data size may be 0, 1, 2, or 4 bytes.
  Only short item is supported here.

  @param  StartPos          Start position of the HID item to get.
  @param  EndPos            End position of the range to get the the next HID item.
  @param  HidItem           Buffer for the HID Item to return.

  @return Pointer to end of the HID item returned.
          NULL if no HID item retrieved.

**/
UINT8 *
GetNextHidItem (
  IN  UINT8    *StartPos,
  IN  UINT8    *EndPos,
  OUT HID_ITEM *HidItem
  )
{
  UINT8 Temp;

  if (EndPos <= StartPos) {
    return NULL;
  }

  Temp = *StartPos;
  StartPos++;

  //
  // Bit format of prefix byte:
  // Bits 0-1: Size
  // Bits 2-3: Type
  // Bits 4-7: Tag
  //
  HidItem->Type = BitFieldRead8 (Temp, 2, 3);
  HidItem->Tag  = BitFieldRead8 (Temp, 4, 7);

  if (HidItem->Tag == HID_ITEM_TAG_LONG) {
    //
    // Long Items are not supported, although we try to parse it.
    //
    HidItem->Format = HID_ITEM_FORMAT_LONG;

    if ((EndPos - StartPos) >= 2) {
      HidItem->Size = *StartPos++;
      HidItem->Tag  = *StartPos++;

      if ((EndPos - StartPos) >= HidItem->Size) {
        HidItem->Data.LongData = StartPos;
        StartPos += HidItem->Size;
        return StartPos;
      }
    }
  } else {
    HidItem->Format = HID_ITEM_FORMAT_SHORT;
    HidItem->Size   = BitFieldRead8 (Temp, 0, 1);

    switch (HidItem->Size) {
    case 0:
      //
      // No data
      //
      return StartPos;

    case 1:
      //
      // 1-byte data
      //
      if ((EndPos - StartPos) >= 1) {
        HidItem->Data.Uint8 = *StartPos++;
        return StartPos;
      }

    case 2:
      //
      // 2-byte data
      //
      if ((EndPos - StartPos) >= 2) {
        CopyMem (&HidItem->Data.Uint16, StartPos, sizeof (UINT16));
        StartPos += 2;
        return StartPos;
      }

    case 3:
      //
      // 4-byte data, adjust size
      //
      HidItem->Size = 4;
      if ((EndPos - StartPos) >= 4) {
        CopyMem (&HidItem->Data.Uint32, StartPos, sizeof (UINT32));
        StartPos += 4;
        return StartPos;
      }
    }
  }

  return NULL;
}


/**
  Get data from HID item.

  This function retrieves data from HID item.
  It only supports short items, which has 4 types of data:
  0, 1, 2, or 4 bytes.

  @param  HidItem       Pointer to the HID item.

  @return The data of HID item.

**/
UINT32
GetItemData (
  IN  HID_ITEM *HidItem
  )
{
  //
  // Get data from HID item.
  //
  switch (HidItem->Size) {
  case 1:
    return HidItem->Data.Uint8;
  case 2:
    return HidItem->Data.Uint16;
  case 4:
    return HidItem->Data.Uint32;
  }
  return 0;
}

/**
  Parse HID item from report descriptor.

  There are three item types: Main, Global, and Local.
  This function parses these types of HID items according
  to tag info.

  @param  UsbMouse          The instance of USB_MOUSE_ABSOLUTE_POINTER_DEV
  @param  HidItem           The HID item to parse

**/
VOID
ParseHidItem (
  IN  USB_MOUSE_ABSOLUTE_POINTER_DEV   *UsbMouse,
  IN  HID_ITEM                         *HidItem
  )
{
  UINT8  Data;

  switch (HidItem->Type) {

  case HID_ITEM_TYPE_MAIN:
    //
    // we don't care any main items, just skip
    //
    return ;

  case HID_ITEM_TYPE_GLOBAL:
    //
    // For global items, we only care Usage Page tag for Button Page here
    //
    if (HidItem->Tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE) {
      Data = (UINT8) GetItemData (HidItem);
      if (Data == 0x09) {
        //
        // Button Page
        //
        UsbMouse->PrivateData.ButtonDetected = TRUE;
      }
  }
    return;

  case HID_ITEM_TYPE_LOCAL:
    if (HidItem->Size == 0) {
    //
      // No expected data for local item
    //
    return ;
    }

    Data = (UINT8) GetItemData (HidItem);

    switch (HidItem->Tag) {
    case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
      if (UsbMouse->PrivateData.ButtonDetected) {
        UsbMouse->PrivateData.ButtonMinIndex = Data;
    }
    return ;

    case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
    {
      if (UsbMouse->PrivateData.ButtonDetected) {
        UsbMouse->PrivateData.ButtonMaxIndex = Data;
      }
      return ;
    }

    default:
        return ;
      }
  }
}


/**
  Parse Mouse Report Descriptor.

  According to USB HID Specification, report descriptors are
  composed of pieces of information. Each piece of information
  is called an Item. This function retrieves each item from
  the report descriptor and updates USB_MOUSE_ABSOLUTE_POINTER_DEV.

  @param  UsbMouseAbsolutePointer  The instance of USB_MOUSE_ABSOLUTE_POINTER_DEV
  @param  ReportDescriptor         Report descriptor to parse
  @param  ReportSize               Report descriptor size

  @retval EFI_SUCCESS              Report descriptor successfully parsed.
  @retval EFI_UNSUPPORTED          Report descriptor contains long item.

**/
EFI_STATUS
ParseMouseReportDescriptor (
  OUT USB_MOUSE_ABSOLUTE_POINTER_DEV   *UsbMouseAbsolutePointer,
  IN  UINT8                            *ReportDescriptor,
  IN  UINTN                            ReportSize
  )
{
  UINT8     *DescriptorEnd;
  UINT8     *Ptr;
  HID_ITEM  HidItem;

  DescriptorEnd = ReportDescriptor + ReportSize;

  Ptr = GetNextHidItem (ReportDescriptor, DescriptorEnd, &HidItem);
  while (Ptr != NULL) {
    if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {
      //
      // Long Item is not supported at current HID revision
      //
      return EFI_UNSUPPORTED;
    }

    ParseHidItem (UsbMouseAbsolutePointer, &HidItem);

    Ptr = GetNextHidItem (Ptr, DescriptorEnd, &HidItem);
  }

  UsbMouseAbsolutePointer->NumberOfButtons = (UINT8) (UsbMouseAbsolutePointer->PrivateData.ButtonMaxIndex - UsbMouseAbsolutePointer->PrivateData.ButtonMinIndex + 1);
  UsbMouseAbsolutePointer->XLogicMax = 1023;
  UsbMouseAbsolutePointer->YLogicMax = 1023;
  UsbMouseAbsolutePointer->XLogicMin = -1023;
  UsbMouseAbsolutePointer->YLogicMin = -1023;

  return EFI_SUCCESS;
}
