// Copyright 2016 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 <stdlib.h>
#include <string.h>
#include <zircon/compiler.h>

#include <usb/usb.h>

// initializes a usb_desc_iter_t for iterating on descriptors past the
// interface's existing descriptors.
static zx_status_t usb_desc_iter_additional_init(usb_composite_protocol_t* comp,
                                                 usb_desc_iter_t* iter) {
  memset(iter, 0, sizeof(*iter));

  size_t length = usb_composite_get_additional_descriptor_length(comp);
  uint8_t* descriptors = malloc(length);
  if (!descriptors) {
    return ZX_ERR_NO_MEMORY;
  }
  size_t actual;
  zx_status_t status =
      usb_composite_get_additional_descriptor_list(comp, descriptors, length, &actual);
  if (status != ZX_OK) {
    return status;
  }

  iter->desc = descriptors;
  iter->desc_end = descriptors + length;
  iter->current = descriptors;
  return ZX_OK;
}

// helper function for claiming additional interfaces that satisfy the want_interface predicate,
// want_interface will be passed the supplied arg
__EXPORT zx_status_t usb_claim_additional_interfaces(
    usb_composite_protocol_t* comp, bool (*want_interface)(usb_interface_descriptor_t*, void*),
    void* arg) {
  usb_desc_iter_t iter;
  zx_status_t status = usb_desc_iter_additional_init(comp, &iter);
  if (status != ZX_OK) {
    return status;
  }

  usb_interface_descriptor_t* intf = usb_desc_iter_next_interface(&iter, true);
  while (intf != NULL && want_interface(intf, arg)) {
    // We need to find the start of the next interface to calculate the
    // total length of the current one.
    usb_interface_descriptor_t* next = usb_desc_iter_next_interface(&iter, true);
    // If we're currently on the last interface, next will be NULL.
    void* intf_end = next ? next : (void*)iter.desc_end;
    size_t length = intf_end - (void*)intf;

    ZX_ASSERT(length < UINT32_MAX);
    status = usb_composite_claim_interface(comp, intf, (uint32_t)length);
    if (status != ZX_OK) {
      break;
    }
    intf = next;
  }
  usb_desc_iter_release(&iter);
  return status;
}

// initializes a usb_desc_iter_t
__EXPORT zx_status_t usb_desc_iter_init(usb_protocol_t* usb, usb_desc_iter_t* iter) {
  size_t length = usb_get_descriptors_length(usb);
  void* descriptors = malloc(length);
  if (!descriptors) {
    return ZX_ERR_NO_MEMORY;
  }
  size_t actual;
  usb_get_descriptors(usb, descriptors, length, &actual);

  return usb_desc_iter_init_unowned(descriptors, length, iter);
}

// initializes a usb_desc_iter_t
__EXPORT zx_status_t usb_desc_iter_init_unowned(void* descriptors, size_t length,
                                                usb_desc_iter_t* iter) {
  memset(iter, 0, sizeof(*iter));

  iter->desc = descriptors;
  iter->desc_end = descriptors + length;
  iter->current = descriptors;
  return ZX_OK;
}

// clones a usb_desc_iter_t
zx_status_t usb_desc_iter_clone(const usb_desc_iter_t* src, usb_desc_iter_t* dest) {
  size_t length = (size_t)(src->desc_end) - (size_t)(src->desc);
  size_t offset = (size_t)(src->current) - (size_t)(src->desc);
  void* descriptors = malloc(length);
  if (!descriptors) {
    return ZX_ERR_NO_MEMORY;
  }
  memcpy(descriptors, src->desc, length);
  dest->desc = descriptors;
  dest->current = ((unsigned char*)descriptors) + offset;
  dest->desc_end = ((unsigned char*)descriptors) + length;
  return ZX_OK;
}

bool safe_add(uint8_t* a, size_t b, uint8_t** sum) {
  uint8_t* test_sum = a + b;
  if (test_sum < a) {
    return false;
  }
  *sum = test_sum;
  return true;
}

// releases resources in a usb_desc_iter_t
__EXPORT void usb_desc_iter_release(usb_desc_iter_t* iter) {
  free(iter->desc);
  iter->desc = NULL;
}

// resets iterator to the beginning
__EXPORT void usb_desc_iter_reset(usb_desc_iter_t* iter) { iter->current = iter->desc; }

// increase the iterator to the next descriptor. If the current descriptor is not a valid descriptor
// header structure, returns false, otherwise, returns true. The iterator would not be increased
// if false is returned and user is expected to handle the error case and end the descriptor
// parsing.
__EXPORT bool usb_desc_iter_advance(usb_desc_iter_t* iter) {
  usb_descriptor_header_t* header = usb_desc_iter_peek(iter);
  if (!header)
    return false;
  iter->current += header->b_length;
  return true;
}

// returns the descriptor header structure currently pointed by the iterator. If the current
// iterator does not point to a valid descriptor header structure, NULL would be returned and user
// is expected to handle the error case and end the descriptor parsing.
__EXPORT usb_descriptor_header_t* usb_desc_iter_peek(usb_desc_iter_t* iter) {
  uint8_t* end;
  if (!safe_add(iter->current, sizeof(usb_descriptor_header_t), &end)) {
    return NULL;
  }
  if (end > iter->desc_end) {
    return NULL;
  }
  usb_descriptor_header_t* header = (usb_descriptor_header_t*)iter->current;
  if (!safe_add(iter->current, header->b_length, &end)) {
    return NULL;
  }
  if (end > iter->desc_end) {
    return NULL;
  }
  if (header->b_length == 0) {
    // An descriptor must not have 0 length, otherwise, it might cause infinite loop.
    return NULL;
  }
  return header;
}

// returns the expected structure with structure size currently pointed by the iterator. If the
// length of descriptor buffer current pointed by the iterator is not enough to hold the structure,
// NULL would be returned, user is expected to handle the error case.
__EXPORT void* usb_desc_iter_get_structure(usb_desc_iter_t* iter, size_t structure_size) {
  uint8_t* start = (uint8_t*)iter->current;
  uint8_t* end = 0;
  if (!safe_add(start, structure_size, &end)) {
    return NULL;
  }
  if (end > iter->desc_end) {
    return NULL;
  }
  return (void*)start;
}

// returns the next interface descriptor, optionally skipping alternate interfaces. The last
// association descriptor pointer is filled in at assoc. If none are seen, assoc does not change.
__EXPORT usb_interface_descriptor_t* usb_desc_iter_next_interface_with_assoc(
    usb_desc_iter_t* iter, bool skip_alt, usb_interface_assoc_descriptor_t** assoc) {
  usb_descriptor_header_t* header;
  while ((header = usb_desc_iter_peek(iter)) != NULL) {
    if (assoc && header->b_descriptor_type == USB_DT_INTERFACE_ASSOCIATION) {
      usb_interface_assoc_descriptor_t* desc =
          usb_desc_iter_get_structure(iter, sizeof(usb_interface_assoc_descriptor_t));
      if (!desc) {
        return NULL;
      }
      *assoc = desc;
    }

    if (header->b_descriptor_type == USB_DT_INTERFACE) {
      usb_interface_descriptor_t* desc =
          usb_desc_iter_get_structure(iter, sizeof(usb_interface_descriptor_t));
      if (desc == NULL) {
        return NULL;
      }
      if (!skip_alt || desc->b_alternate_setting == 0) {
        usb_desc_iter_advance(iter);
        return desc;
      }
    }
    usb_desc_iter_advance(iter);
  }
  // not found
  return NULL;
}

__EXPORT usb_interface_descriptor_t* usb_desc_iter_next_interface(usb_desc_iter_t* iter,
                                                                  bool skip_alt) {
  return usb_desc_iter_next_interface_with_assoc(iter, skip_alt, NULL);
}

// returns the next endpoint descriptor within the current interface
__EXPORT usb_endpoint_descriptor_t* usb_desc_iter_next_endpoint(usb_desc_iter_t* iter) {
  usb_descriptor_header_t* header;
  while ((header = usb_desc_iter_peek(iter)) != NULL) {
    if (header->b_descriptor_type == USB_DT_INTERFACE) {
      // we are at end of previous interface
      return NULL;
    }
    if (header->b_descriptor_type == USB_DT_ENDPOINT) {
      usb_endpoint_descriptor_t* desc =
          usb_desc_iter_get_structure(iter, sizeof(usb_endpoint_descriptor_t));
      if (desc == NULL) {
        return NULL;
      }
      usb_desc_iter_advance(iter);
      return desc;
    }
    usb_desc_iter_advance(iter);
  }
  // not found
  return NULL;
}

// returns the next ss-companion descriptor within the current interface.
// drivers may use usb_desc_iter_peek() to determine if an endpoint or ss_companion descriptor is
// expected.
__EXPORT usb_ss_ep_comp_descriptor_t* usb_desc_iter_next_ss_ep_comp(usb_desc_iter_t* iter) {
  usb_descriptor_header_t* header;
  while ((header = usb_desc_iter_peek(iter)) != NULL) {
    uint8_t desc_type = header->b_descriptor_type;
    if (desc_type == USB_DT_ENDPOINT || desc_type == USB_DT_INTERFACE) {
      // we are either at next endpoint or end of previous interface
      return NULL;
    }
    if (header->b_descriptor_type == USB_DT_SS_EP_COMPANION) {
      usb_ss_ep_comp_descriptor_t* desc =
          usb_desc_iter_get_structure(iter, sizeof(usb_ss_ep_comp_descriptor_t));
      if (desc == NULL) {
        return NULL;
      }
      usb_desc_iter_advance(iter);
      return desc;
    }
    usb_desc_iter_advance(iter);
  }
  // not found
  return NULL;
}
