/* Support for the HID Boot Protocol.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/term.h>
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/usb.h>
#include <grub/dl.h>
#include <grub/time.h>
#include <grub/keyboard_layouts.h>

GRUB_MOD_LICENSE ("GPLv3+");



enum
  {
    KEY_NO_KEY = 0x00,
    KEY_ERR_BUFFER = 0x01,
    KEY_ERR_POST  = 0x02,
    KEY_ERR_UNDEF = 0x03,
    KEY_CAPS_LOCK = 0x39,
    KEY_NUM_LOCK  = 0x53,
  };

enum
  {
    LED_NUM_LOCK = 0x01,
    LED_CAPS_LOCK = 0x02
  };

/* Valid values for bRequest.  See HID definition version 1.11 section 7.2. */
#define USB_HID_GET_REPORT	0x01
#define USB_HID_GET_IDLE	0x02
#define USB_HID_GET_PROTOCOL	0x03
#define USB_HID_SET_REPORT	0x09
#define USB_HID_SET_IDLE	0x0A
#define USB_HID_SET_PROTOCOL	0x0B

#define USB_HID_BOOT_SUBCLASS	0x01
#define USB_HID_KBD_PROTOCOL	0x01

#define GRUB_USB_KEYBOARD_LEFT_CTRL   0x01
#define GRUB_USB_KEYBOARD_LEFT_SHIFT  0x02
#define GRUB_USB_KEYBOARD_LEFT_ALT    0x04
#define GRUB_USB_KEYBOARD_RIGHT_CTRL  0x10
#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20
#define GRUB_USB_KEYBOARD_RIGHT_ALT   0x40

struct grub_usb_keyboard_data
{
  grub_usb_device_t usbdev;
  grub_uint8_t status;
  grub_uint16_t mods;
  int interfno;
  struct grub_usb_desc_endp *endp;
  grub_usb_transfer_t transfer;
  grub_uint8_t report[8];
  int dead;
  int last_key;
  grub_uint64_t repeat_time;
  grub_uint8_t current_report[8];
  grub_uint8_t last_report[8];
  int index;
  int max_index;
};

static int grub_usb_keyboard_getkey (struct grub_term_input *term);
static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term);

static struct grub_term_input grub_usb_keyboard_term =
  {
    .getkey = grub_usb_keyboard_getkey,
    .getkeystatus = grub_usb_keyboard_getkeystatus,
    .next = 0
  };

static struct grub_term_input grub_usb_keyboards[16];

static int
interpret_status (grub_uint8_t data0)
{
  int mods = 0;

  /* Check Shift, Control, and Alt status.  */
  if (data0 & GRUB_USB_KEYBOARD_LEFT_SHIFT)
    mods |= GRUB_TERM_STATUS_LSHIFT;
  if (data0 & GRUB_USB_KEYBOARD_RIGHT_SHIFT)
    mods |= GRUB_TERM_STATUS_RSHIFT;
  if (data0 & GRUB_USB_KEYBOARD_LEFT_CTRL)
    mods |= GRUB_TERM_STATUS_LCTRL;
  if (data0 & GRUB_USB_KEYBOARD_RIGHT_CTRL)
    mods |= GRUB_TERM_STATUS_RCTRL;
  if (data0 & GRUB_USB_KEYBOARD_LEFT_ALT)
    mods |= GRUB_TERM_STATUS_LALT;
  if (data0 & GRUB_USB_KEYBOARD_RIGHT_ALT)
    mods |= GRUB_TERM_STATUS_RALT;

  return mods;
}

static void
grub_usb_keyboard_detach (grub_usb_device_t usbdev,
			  int config __attribute__ ((unused)),
			  int interface __attribute__ ((unused)))
{
  unsigned i;
  for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++)
    {
      struct grub_usb_keyboard_data *data = grub_usb_keyboards[i].data;

      if (!data)
	continue;

      if (data->usbdev != usbdev)
	continue;

      if (data->transfer)
	grub_usb_cancel_transfer (data->transfer);

      grub_term_unregister_input (&grub_usb_keyboards[i]);
      grub_free ((char *) grub_usb_keyboards[i].name);
      grub_usb_keyboards[i].name = NULL;
      grub_free (grub_usb_keyboards[i].data);
      grub_usb_keyboards[i].data = 0;
    }
}

static int
grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno)
{
  unsigned curnum;
  struct grub_usb_keyboard_data *data;
  struct grub_usb_desc_endp *endp = NULL;
  int j;

  grub_dprintf ("usb_keyboard", "%x %x %x %d %d\n",
		usbdev->descdev.class, usbdev->descdev.subclass,
		usbdev->descdev.protocol, configno, interfno);

  for (curnum = 0; curnum < ARRAY_SIZE (grub_usb_keyboards); curnum++)
    if (!grub_usb_keyboards[curnum].data)
      break;

  if (curnum == ARRAY_SIZE (grub_usb_keyboards))
    return 0;

  if (usbdev->descdev.class != 0 
      || usbdev->descdev.subclass != 0 || usbdev->descdev.protocol != 0)
    return 0;

  if (usbdev->config[configno].interf[interfno].descif->subclass
      != USB_HID_BOOT_SUBCLASS
      || usbdev->config[configno].interf[interfno].descif->protocol
      != USB_HID_KBD_PROTOCOL)
    return 0;

  for (j = 0; j < usbdev->config[configno].interf[interfno].descif->endpointcnt;
       j++)
    {
      endp = &usbdev->config[configno].interf[interfno].descendp[j];

      if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
	  == GRUB_USB_EP_INTERRUPT)
	break;
    }
  if (j == usbdev->config[configno].interf[interfno].descif->endpointcnt)
    return 0;

  grub_dprintf ("usb_keyboard", "HID found!\n");

  data = grub_malloc (sizeof (*data));
  if (!data)
    {
      grub_print_error ();
      return 0;
    }

  data->usbdev = usbdev;
  data->interfno = interfno;
  data->endp = endp;

  /* Configure device */
  grub_usb_set_configuration (usbdev, configno + 1);
  
  /* Place the device in boot mode.  */
  grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT,
  			USB_HID_SET_PROTOCOL, 0, interfno, 0, 0);

  /* Reports every time an event occurs and not more often than that.  */
  grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT,
  			USB_HID_SET_IDLE, 0<<8, interfno, 0, 0);

  grub_memcpy (&grub_usb_keyboards[curnum], &grub_usb_keyboard_term,
	       sizeof (grub_usb_keyboards[curnum]));
  grub_usb_keyboards[curnum].data = data;
  usbdev->config[configno].interf[interfno].detach_hook
    = grub_usb_keyboard_detach;
  grub_usb_keyboards[curnum].name = grub_xasprintf ("usb_keyboard%d", curnum);
  if (!grub_usb_keyboards[curnum].name)
    {
      grub_print_error ();
      return 0;
    }

  /* Test showed that getting report may make the keyboard go nuts.
     Moreover since we're reattaching keyboard it usually sends
     an initial message on interrupt pipe and so we retrieve
     the same keystatus.
   */
#if 0
  {
    grub_uint8_t report[8];
    grub_usb_err_t err;
    grub_memset (report, 0, sizeof (report));
    err = grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_IN,
    				USB_HID_GET_REPORT, 0x0100, interfno,
				sizeof (report), (char *) report);
    if (err)
      data->status = 0;
    else
      data->status = report[0];
  }
#else
  data->status = 0;
#endif

  data->transfer = grub_usb_bulk_read_background (usbdev,
						  data->endp,
						  sizeof (data->report),
						  (char *) data->report);
  if (!data->transfer)
    {
      grub_print_error ();
      return 0;
    }

  data->last_key = -1;
  data->mods = 0;
  data->dead = 0;

  grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]);

  return 1;
}



static void
send_leds (struct grub_usb_keyboard_data *termdata)
{
  char report[1];
  report[0] = 0;
  if (termdata->mods & GRUB_TERM_STATUS_CAPS)
    report[0] |= LED_CAPS_LOCK;
  if (termdata->mods & GRUB_TERM_STATUS_NUM)
    report[0] |= LED_NUM_LOCK;
  grub_usb_control_msg (termdata->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT,
			USB_HID_SET_REPORT, 0x0200, termdata->interfno,
			sizeof (report), (char *) report);
  grub_errno = GRUB_ERR_NONE;
}

static int
parse_keycode (struct grub_usb_keyboard_data *termdata)
{
  int index = termdata->index;
  int i, keycode;

  /* Sanity check */
  if (index < 2)
    index = 2;

  for ( ; index < termdata->max_index; index++)
    {
      keycode = termdata->current_report[index];
      
      if (keycode == KEY_NO_KEY
          || keycode == KEY_ERR_BUFFER
          || keycode == KEY_ERR_POST
          || keycode == KEY_ERR_UNDEF)
        {
          /* Don't parse (rest of) this report */
          termdata->index = 0;
          if (keycode != KEY_NO_KEY)
          /* Don't replace last report with current faulty report
           * in future ! */
            grub_memcpy (termdata->current_report,
                         termdata->last_report,
                         sizeof (termdata->report));
          return GRUB_TERM_NO_KEY;
        }

      /* Try to find current keycode in last report. */
      for (i = 2; i < 8; i++)
        if (keycode == termdata->last_report[i])
          break;
      if (i < 8)
        /* Keycode is in last report, it means it was not released,
         * ignore it. */
        continue;
        
      if (keycode == KEY_CAPS_LOCK)
        {
          termdata->mods ^= GRUB_TERM_STATUS_CAPS;
          send_leds (termdata);
          continue;
        }

      if (keycode == KEY_NUM_LOCK)
        {
          termdata->mods ^= GRUB_TERM_STATUS_NUM;
          send_leds (termdata);
          continue;
        }

      termdata->last_key = grub_term_map_key (keycode,
                                              interpret_status (termdata->current_report[0])
					        | termdata->mods);
      termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL;

      grub_errno = GRUB_ERR_NONE;

      index++;
      if (index >= termdata->max_index)
        termdata->index = 0;
      else
        termdata->index = index;

      return termdata->last_key;
    }

  /* All keycodes parsed */
  termdata->index = 0;
  return GRUB_TERM_NO_KEY;
}

static int
grub_usb_keyboard_getkey (struct grub_term_input *term)
{
  grub_usb_err_t err;
  struct grub_usb_keyboard_data *termdata = term->data;
  grub_size_t actual;
  int keycode = GRUB_TERM_NO_KEY;

  if (termdata->dead)
    return GRUB_TERM_NO_KEY;

  if (termdata->index)
    keycode = parse_keycode (termdata);
  if (keycode != GRUB_TERM_NO_KEY)
    return keycode;
    
  /* Poll interrupt pipe.  */
  err = grub_usb_check_transfer (termdata->transfer, &actual);

  if (err == GRUB_USB_ERR_WAIT)
    {
      if (termdata->last_key != -1
	  && grub_get_time_ms () > termdata->repeat_time)
	{
	  termdata->repeat_time = grub_get_time_ms ()
	    + GRUB_TERM_REPEAT_INTERVAL;
	  return termdata->last_key;
	}
      return GRUB_TERM_NO_KEY;
    }

  if (!err && (actual >= 3))
    grub_memcpy (termdata->last_report,
                 termdata->current_report,
                 sizeof (termdata->report));
                 
  grub_memcpy (termdata->current_report,
               termdata->report,
               sizeof (termdata->report));

  termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev,
						      termdata->endp,
						      sizeof (termdata->report),
						      (char *) termdata->report);
  if (!termdata->transfer)
    {
      grub_printf ("%s failed. Stopped\n", term->name);
      termdata->dead = 1;
    }

  termdata->last_key = -1;

  grub_dprintf ("usb_keyboard",
		"err = %d, actual = %" PRIuGRUB_SIZE
		" report: 0x%02x 0x%02x 0x%02x 0x%02x"
		" 0x%02x 0x%02x 0x%02x 0x%02x\n",
		err, actual,
		termdata->current_report[0], termdata->current_report[1],
		termdata->current_report[2], termdata->current_report[3],
		termdata->current_report[4], termdata->current_report[5],
		termdata->current_report[6], termdata->current_report[7]);

  if (err || actual < 1)
    return GRUB_TERM_NO_KEY;

  termdata->status = termdata->current_report[0];

  if (actual < 3)
    return GRUB_TERM_NO_KEY;

  termdata->index = 2; /* New data received. */
  termdata->max_index = actual;
  
  return parse_keycode (termdata);
}

static int
grub_usb_keyboard_getkeystatus (struct grub_term_input *term)
{
  struct grub_usb_keyboard_data *termdata = term->data;

  return interpret_status (termdata->status) | termdata->mods;
}

static struct grub_usb_attach_desc attach_hook =
{
  .class = GRUB_USB_CLASS_HID,
  .hook = grub_usb_keyboard_attach
};

GRUB_MOD_INIT(usb_keyboard)
{
  grub_usb_register_attach_hook_class (&attach_hook);
}

GRUB_MOD_FINI(usb_keyboard)
{
  unsigned i;
  for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++)
    if (grub_usb_keyboards[i].data)
      {
	struct grub_usb_keyboard_data *data = grub_usb_keyboards[i].data;

	if (!data)
	  continue;
	
	if (data->transfer)
	  grub_usb_cancel_transfer (data->transfer);

	grub_term_unregister_input (&grub_usb_keyboards[i]);
	grub_free ((char *) grub_usb_keyboards[i].name);
	grub_usb_keyboards[i].name = NULL;
	grub_free (grub_usb_keyboards[i].data);
	grub_usb_keyboards[i].data = 0;
      }
  grub_usb_unregister_attach_hook_class (&attach_hook);
}
