// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <ddk/debug.h>
#include <usb/usb.h>
#include <string.h>

#include "garnet/drivers/usb_video/video-util.h"

static void print_controls(usb_video_vc_probe_and_commit_controls* proposal) {
  zxlogf(TRACE, "bmHint 0x%x\n", proposal->bmHint);
  zxlogf(TRACE, "bFormatIndex: %u\n", proposal->bFormatIndex);
  zxlogf(TRACE, "bFrameIndex: %u\n", proposal->bFrameIndex);
  zxlogf(TRACE, "dwFrameInterval: %u\n", proposal->dwFrameInterval);
  zxlogf(TRACE, "dwMaxVideoFrameSize: %u\n", proposal->dwMaxVideoFrameSize);
  zxlogf(TRACE, "dwMaxPayloadTransferSize: %u\n",
         proposal->dwMaxPayloadTransferSize);
}

zx_status_t usb_video_negotiate_probe(
    usb_protocol_t* usb, uint8_t vs_interface_num,
    usb_video_vc_probe_and_commit_controls* proposal,
    usb_video_vc_probe_and_commit_controls* out_result) {
  zx_status_t status;
  size_t out_length;

  zxlogf(TRACE, "usb_video_negotiate_probe: PROBE_CONTROL SET_CUR\n");
  print_controls(proposal);
  // The wValue field (the fourth parameter) specifies the Control Selector
  // (in this case USB_VIDEO_VS_PROBE_CONTROL) in the high byte,
  // and the low byte must be set to zero.
  // See UVC 1.5 Spec. 4.2.1 Interface Control Requests.
  status = usb_control_out(usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                           USB_VIDEO_SET_CUR, USB_VIDEO_VS_PROBE_CONTROL << 8,
                           vs_interface_num, ZX_TIME_INFINITE,
                           proposal, sizeof(*proposal));
  if (status != ZX_OK)
    goto out;

  // The length of returned result varies, so zero this out before hand.
  memset(out_result, 0, sizeof(usb_video_vc_probe_and_commit_controls));

  zxlogf(TRACE, "usb_video_negotiate_probe: PROBE_CONTROL GET_CUR\n");
  status = usb_control_in(usb, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                          USB_VIDEO_GET_CUR, USB_VIDEO_VS_PROBE_CONTROL << 8,
                          vs_interface_num, ZX_TIME_INFINITE,
                          out_result, sizeof(*out_result), &out_length);
  if (status != ZX_OK) {
    goto out;
  }
  // Fields after dwMaxPayloadTransferSize are optional, only 26 bytes are
  // guaranteed.
  if (out_length < 26) {
    zxlogf(ERROR, "usb_video_negotiate_probe: got length %lu, want >= 26\n",
           out_length);
    goto out;
  }
  print_controls(out_result);

out:
  if (status == ZX_ERR_IO_REFUSED || status == ZX_ERR_IO_INVALID) {
    // clear the stall/error
    usb_reset_endpoint(usb, 0);
  }
  return status;
}

zx_status_t usb_video_negotiate_commit(
    usb_protocol_t* usb, uint8_t vs_interface_num,
    usb_video_vc_probe_and_commit_controls* ctrls) {
  zxlogf(TRACE, "usb_video_negotiate_commit: COMMIT_CONTROL SET_CUR\n");
  zx_status_t status = usb_control_out(
      usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
      USB_VIDEO_SET_CUR, USB_VIDEO_VS_COMMIT_CONTROL << 8, vs_interface_num,
      ZX_TIME_INFINITE, ctrls, sizeof(*ctrls));
  if (status == ZX_ERR_IO_REFUSED || status == ZX_ERR_IO_INVALID) {
    // clear the stall/error
    usb_reset_endpoint(usb, 0);
  }
  return status;
}
