예제 #1
0
KDCENTRY* krb_locate_kdc(rdpSettings* settings)
{
#ifdef WITH_RESOLV
	char *qname;
	int reslen, i;
	unsigned char response[4096];
	char kdc_host[4096];
	unsigned char* temp;
	KDCENTRY* head;
	KDCENTRY* kdcentry;
	KDCENTRY* srvans;
	ns_msg handle;
	ns_rr rr;
	head = kdcentry =  NULL;
	if (get_krb_realm(settings))
		return NULL;
	if (settings->kerberos_kdc)
	{
		srvans = xnew(KDCENTRY);
		srvans->kdchost = xstrdup(settings->kerberos_kdc);
		srvans->port = 88;
		return srvans;
	}
	qname = get_dns_queryname(settings->kerberos_realm, "_tcp.");

	if ((reslen = res_query(qname, ns_c_in, ns_t_srv, response, sizeof(response))) < 0)
		return NULL;

	ns_initparse(response, reslen, &handle);

	for (i = 0;i < ns_msg_count(handle, ns_s_an);i++)
	{
		ns_parserr(&handle, ns_s_an, i, &rr);
		srvans = xnew(KDCENTRY);
		temp = (unsigned char*)ns_rr_rdata(rr);
		GETUINT16(temp, &(srvans->priority));
		GETUINT16(temp, &(srvans->weight));
		GETUINT16(temp, &(srvans->port));
		if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle), temp, (char*)kdc_host, sizeof(kdc_host)) < 0)
			srvans->kdchost = xstrdup((const char*)temp);
		else
			srvans->kdchost = xstrdup(kdc_host);
		if (head == NULL || head->priority > srvans->priority)
		{
			srvans->next = head;
			head = srvans;
		}
		else
		{
			for (kdcentry = head;kdcentry->next != NULL && kdcentry->next->priority < srvans->priority;kdcentry = kdcentry->next);
			srvans->next = kdcentry->next;
			kdcentry->next = srvans;
		}
	}

	return head;
#else
	return NULL;
#endif
}
예제 #2
0
static INLINE A_BOOL ParseCAPCtrl(L2CAP_CONTROL *pL2Ctrl,
                                  A_UINT8       *pBuffer,
                                  int           Length)
{
    A_UCHAR     *pTemp = pBuffer + sizeof(ACL_HEADER);
      
    if (Length < (sizeof(ACL_HEADER)+sizeof(L2CAP_HEADER)+sizeof(L2CAP_CONTROL)-6)) {
        return FALSE;
    }
    
    pTemp +=sizeof(L2CAP_HEADER);

    pL2Ctrl->CODE = *pTemp++;
    pL2Ctrl->ID = *pTemp++;
    pL2Ctrl->Length = GETUINT16(pTemp) ;
    pTemp += sizeof(A_UINT16);
    pL2Ctrl->PSM = pL2Ctrl->DESTINATION_CID=GETUINT16(pTemp);
    pTemp += sizeof(A_UINT16);
    pL2Ctrl->SOURCE_CID = GETUINT16(pTemp);
    pTemp += sizeof(A_UINT16);
    
    if (Length >= (sizeof(ACL_HEADER)+sizeof(L2CAP_HEADER)+sizeof(L2CAP_CONTROL)-sizeof(A_UINT16))) { 
        pL2Ctrl->RESULT = GETUINT16(pTemp);
        pTemp += sizeof(A_UINT16);
        pL2Ctrl->STATUS = GETUINT16(pTemp);
        pTemp += sizeof(A_UINT16);
    }
    
    return TRUE;
} 
예제 #3
0
static INLINE A_BOOL ParseCAPheader(L2CAP_HEADER *pL2hdr,
                                    A_UINT8      *pBuffer,
                                    int          Length)
{
    A_UCHAR    *pTemp = pBuffer + sizeof(ACL_HEADER);
    
    if (Length < (sizeof(ACL_HEADER)+sizeof(L2CAP_HEADER))) {
        return FALSE;
    }

    pL2hdr->Length = GETUINT16(pTemp);
    pTemp += sizeof(A_UINT16);
    pL2hdr->CID = GETUINT16(pTemp);
    pTemp += sizeof(A_UINT16);
    return TRUE;
}
예제 #4
0
파일: composite.c 프로젝트: a1ien/nuttx
static int composite_classsetup(FAR struct composite_dev_s *priv,
                                FAR struct usbdev_s *dev,
                                FAR const struct usb_ctrlreq_s *ctrl,
                                FAR uint8_t *dataout, size_t outlen)
{
  uint16_t index;
  uint8_t  interface;
  int ret = -EOPNOTSUPP;

  index     = GETUINT16(ctrl->index);
  interface = (uint8_t)(index & 0xff);

  if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES))
    {
      ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
    }
  else if (interface >= DEV2_FIRSTINTERFACE && interface < (DEV2_FIRSTINTERFACE + DEV2_NINTERFACES))
    {
      ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
    }

  return ret;
}
예제 #5
0
파일: composite.c 프로젝트: a1ien/nuttx
static int composite_setup(FAR struct usbdevclass_driver_s *driver,
                           FAR struct usbdev_s *dev,
                           FAR const struct usb_ctrlreq_s *ctrl,
                           FAR uint8_t *dataout, size_t outlen)
{
  FAR struct composite_dev_s *priv;
  FAR struct usbdev_req_s *ctrlreq;
  uint16_t value;
  uint16_t index;
  uint16_t len;
  bool dispatched = false;
  int ret = -EOPNOTSUPP;

#ifdef CONFIG_DEBUG_FEATURES
  if (!driver || !dev || !dev->ep0 || !ctrl)
    {
      usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_SETUPINVALIDARGS), 0);
      return -EIO;
     }
#endif

  /* Extract a reference to private data */

  usbtrace(TRACE_CLASSSETUP, ctrl->req);
  priv = ((FAR struct composite_driver_s *)driver)->dev;

#ifdef CONFIG_DEBUG_FEATURES
  if (!priv)
    {
      usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND2), 0);
      return -ENODEV;
    }
#endif
  ctrlreq   = priv->ctrlreq;

  /* Extract the little-endian 16-bit values to host order */

  value     = GETUINT16(ctrl->value);
  index     = GETUINT16(ctrl->index);
  len       = GETUINT16(ctrl->len);

  uinfo("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
        ctrl->type, ctrl->req, value, index, len);
  UNUSED(index);

  if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
    {
      /**********************************************************************
       * Standard Requests
       **********************************************************************/

      switch (ctrl->req)
        {
        case USB_REQ_GETDESCRIPTOR:
          {
            /* The value field specifies the descriptor type in the MS byte and the
             * descriptor index in the LS byte (order is little endian)
             */

            switch (ctrl->value[1])
              {
              case USB_DESC_TYPE_DEVICE:
                {
                  ret = USB_SIZEOF_DEVDESC;
                  memcpy(ctrlreq->buf, composite_getdevdesc(), ret);
                }
                break;

#ifdef CONFIG_USBDEV_DUALSPEED
              case USB_DESC_TYPE_DEVICEQUALIFIER:
                {
                  ret = USB_SIZEOF_QUALDESC;
                  memcpy(ctrlreq->buf, composite_getqualdesc(), ret);
                }
                break;

              case USB_DESC_TYPE_OTHERSPEEDCONFIG:
#endif

              case USB_DESC_TYPE_CONFIG:
                {
#ifdef CONFIG_USBDEV_DUALSPEED
                  ret = composite_mkcfgdesc(ctrlreq->buf, dev->speed,
                                            ctrl->value[1]);
#else
                  ret = composite_mkcfgdesc(ctrlreq->buf);
#endif
                }
                break;

              case USB_DESC_TYPE_STRING:
                {
                  /* value == string index. Zero is the language ID. */

                  uint8_t strid = ctrl->value[0];
                  FAR struct usb_strdesc_s *buf = (FAR struct usb_strdesc_s *)ctrlreq->buf;

                  if (strid <= COMPOSITE_NSTRIDS)
                    {
                      ret = composite_mkstrdesc(strid, buf);
                    }
#if DEV1_NSTRIDS > 0
                  else if (strid <= DEV1_STRIDBASE + DEV1_NSTRIDS)
                    {
                      ret = DEV1_MKSTRDESC(strid, buf);
                    }
#endif
#if DEV2_NSTRIDS > 0
                  else if (strid <= DEV2_STRIDBASE + DEV2_NSTRIDS)
                    {
                      ret = DEV2_MKSTRDESC(strid, buf);
                    }
#endif
                }
                break;

              default:
                {
                  usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_GETUNKNOWNDESC), value);
                }
                break;
              }
          }
          break;

        case USB_REQ_SETCONFIGURATION:
          {
            if (ctrl->type == 0)
              {
                /* Save the configuration and inform the constituent classes */

                ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
                dispatched = true;

                if (ret >= 0)
                  {
                    ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
                    if (ret >= 0)
                      {
                        priv->config = value;
                      }
                  }
              }
          }
          break;

        case USB_REQ_GETCONFIGURATION:
          {
            if (ctrl->type == USB_DIR_IN)
              {
                ctrlreq->buf[0] = priv->config;
                ret = 1;
              }
          }
          break;

        case USB_REQ_SETINTERFACE:
          {
            if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
                priv->config == COMPOSITE_CONFIGID)
              {
                ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
                dispatched = true;
              }
          }
          break;

        case USB_REQ_GETINTERFACE:
          {
            if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) &&
                priv->config == COMPOSITE_CONFIGIDNONE)
              {
                ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
                dispatched = true;
              }
           }
           break;

        default:
          usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
          break;
        }
    }
  else
    {
      uint8_t recipient;

      /**********************************************************************
       * Non-Standard Class Requests
       **********************************************************************/

       /* Class implementations should handle there own interface and endpoint
        * requests.
        */

       recipient = ctrl->type & USB_REQ_RECIPIENT_MASK;
       if (recipient == USB_REQ_RECIPIENT_INTERFACE || recipient == USB_REQ_RECIPIENT_ENDPOINT)
         {
           ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
           dispatched = true;
         }
    }


  /* Respond to the setup command if (1) data was returned, and (2) the request was
   * NOT successfully dispatched to the component class driver.  On an error return
   * value (ret < 0), the USB driver will stall EP0.
   */

  if (ret >= 0 && !dispatched)
    {
      /* Setup the request */

      ctrlreq->len   = MIN(len, ret);
      ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;

      /* And submit the request to the USB controller driver */

      ret = EP_SUBMIT(dev->ep0, ctrlreq);
      if (ret < 0)
        {
          usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EPRESPQ), (uint16_t)-ret);
          ctrlreq->result = OK;
          composite_ep0incomplete(dev->ep0, ctrlreq);
        }
    }

  return ret;
}
예제 #6
0
파일: usbmsc.c 프로젝트: drashti304/TizenRT
static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout, size_t outlen)
{
	FAR struct usbmsc_dev_s *priv;
	FAR struct usbdev_req_s *ctrlreq;
	uint16_t value;
	uint16_t index;
	uint16_t len;
	int ret = -EOPNOTSUPP;

#ifdef CONFIG_DEBUG
	if (!driver || !dev || !dev->ep0 || !ctrl) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETUPINVALIDARGS), 0);
		return -EIO;
	}
#endif

	/* Extract reference to private data */

	usbtrace(TRACE_CLASSSETUP, ctrl->req);
	priv = ((FAR struct usbmsc_driver_s *)driver)->dev;

#ifdef CONFIG_DEBUG
	if (!priv || !priv->ctrlreq) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EP0NOTBOUND2), 0);
		return -ENODEV;
	}
#endif
	ctrlreq = priv->ctrlreq;

	/* Extract the little-endian 16-bit values to host order */

	value = GETUINT16(ctrl->value);
	index = GETUINT16(ctrl->index);
	len = GETUINT16(ctrl->len);

	uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n", ctrl->type, ctrl->req, value, index, len);

	if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) {
		/**********************************************************************
		 * Standard Requests
		 **********************************************************************/

		switch (ctrl->req) {
		case USB_REQ_GETDESCRIPTOR: {
			/* The value field specifies the descriptor type in the MS byte and the
			 * descriptor index in the LS byte (order is little endian)
			 */

			switch (ctrl->value[1]) {
				/* If the mass storage device is used in as part of a composite
				 * device, then the device descriptor is is provided by logic
				 * in the composite device implementation.
				 */

#ifndef CONFIG_USBMSC_COMPOSITE
			case USB_DESC_TYPE_DEVICE: {
				ret = USB_SIZEOF_DEVDESC;
				memcpy(ctrlreq->buf, usbmsc_getdevdesc(), ret);
			}
			break;
#endif

				/* If the mass storage device is used in as part of a composite device,
				 * then the device qualifier descriptor is provided by logic in the
				 * composite device implementation.
				 */

#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
			case USB_DESC_TYPE_DEVICEQUALIFIER: {
				ret = USB_SIZEOF_QUALDESC;
				memcpy(ctrlreq->buf, usbmsc_getqualdesc(), ret);
			}
			break;

			case USB_DESC_TYPE_OTHERSPEEDCONFIG:
#endif

				/* If the mass storage device is used in as part of a composite device,
				 * then the configuration descriptor is provided by logic in the
				 * composite device implementation.
				 */

#ifndef CONFIG_USBMSC_COMPOSITE
			case USB_DESC_TYPE_CONFIG: {
#ifdef CONFIG_USBDEV_DUALSPEED
				ret = usbmsc_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->value[1]);
#else
				ret = usbmsc_mkcfgdesc(ctrlreq->buf);
#endif
			}
			break;
#endif

				/* If the mass storage device is used in as part of a composite device,
				 * then the language string descriptor is provided by logic in the
				 * composite device implementation.
				 */

#ifndef CONFIG_USBMSC_COMPOSITE
			case USB_DESC_TYPE_STRING: {
				/* index == language code. */

				ret = usbmsc_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
			}
			break;
#endif

			default: {
				usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC), value);
			}
			break;
			}
		}
		break;

		case USB_REQ_SETCONFIGURATION: {
			if (ctrl->type == 0) {
				/* Signal the worker thread to instantiate the new configuration */

				priv->theventset |= USBMSC_EVENT_CFGCHANGE;
				priv->thvalue = value;
				usbmsc_scsi_signal(priv);

				/* Return here... the response will be provided later by the
				 * worker thread.
				 */

				return OK;
			}
		}
		break;

			/* If the mass storage device is used in as part of a composite device,
			 * then the overall composite class configuration is managed by logic
			 * in the composite device implementation.
			 */

#ifndef CONFIG_USBMSC_COMPOSITE
		case USB_REQ_GETCONFIGURATION: {
			if (ctrl->type == USB_DIR_IN) {
				ctrlreq->buf[0] = priv->config;
				ret = 1;
			}
		}
		break;
#endif

		case USB_REQ_SETINTERFACE: {
			if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE) {
				if (priv->config == USBMSC_CONFIGID && index == USBMSC_INTERFACEID && value == USBMSC_ALTINTERFACEID) {
					/* Signal to instantiate the interface change */

					priv->theventset |= USBMSC_EVENT_IFCHANGE;
					usbmsc_scsi_signal(priv);

					/* Return here... the response will be provided later by the
					 * worker thread.
					 */

					return OK;
				}
			}
		}
		break;

		case USB_REQ_GETINTERFACE: {
			if (ctrl->type == (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE) && priv->config == USBMSC_CONFIGIDNONE) {
				if (index != USBMSC_INTERFACEID) {
					ret = -EDOM;
				} else {
					ctrlreq->buf[0] = USBMSC_ALTINTERFACEID;
					ret = 1;
				}
			}
		}
		break;

		default:
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
			break;
		}
	} else if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS) {
		/**********************************************************************
		 * Bulk-Only Mass Storage Class Requests
		 **********************************************************************/

		/* Verify that we are configured */

		if (!priv->config) {
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOTCONFIGURED), 0);
			return ret;
		}

		switch (ctrl->req) {
		case USBMSC_REQ_MSRESET: {	/* Reset mass storage device and interface */
			if (ctrl->type == USBMSC_TYPE_SETUPOUT && value == 0 && len == 0) {
				/* Only one interface is supported */

				if (index != USBMSC_INTERFACEID) {
					usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX), index);
					ret = -EDOM;
				} else {
					/* Signal to stop the current operation and reinitialize state */

					priv->theventset |= USBMSC_EVENT_RESET;
					usbmsc_scsi_signal(priv);

					/* Return here... the response will be provided later by the
					 * worker thread.
					 */

					return OK;
				}
			}
		}
		break;

		case USBMSC_REQ_GETMAXLUN: {	/* Return number LUNs supported */
			if (ctrl->type == USBMSC_TYPE_SETUPIN && value == 0 && len == 1) {
				/* Only one interface is supported */

				if (index != USBMSC_INTERFACEID) {
					usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX), index);
					ret = -EDOM;
				} else {
					ctrlreq->buf[0] = priv->nluns - 1;
					ret = 1;
				}
			}
		}
		break;

		default:
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BADREQUEST), ctrl->req);
			break;
		}
	} else {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
	}

	/* Respond to the setup command if data was returned.  On an error return
	 * value (ret < 0), the USB driver will stall EP0.
	 */

	if (ret >= 0) {
		/* Configure the response */

		ctrlreq->len = MIN(len, ret);
		ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;

		/* Send the response -- either directly to the USB controller or
		 * indirectly in the case where this class is a member of a composite
		 * device.
		 */

#ifndef CONFIG_USBMSC_COMPOSITE
		ret = EP_SUBMIT(dev->ep0, ctrlreq);
#else
		ret = composite_ep0submit(driver, dev, ctrlreq);
#endif
		if (ret < 0) {
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPRESPQ), (uint16_t)-ret);
#if 0							/* Not necessary */
			ctrlreq->result = OK;
			usbmsc_ep0incomplete(dev->ep0, ctrlreq);
#endif
		}
	}

	return ret;
}
예제 #7
0
파일: apb-es1.c 프로젝트: KimMui/GDMAC
static int usbclass_setup(struct usbdevclass_driver_s *driver,
                          struct usbdev_s *dev,
                          const struct usb_ctrlreq_s *ctrl,
                          uint8_t * dataout, size_t outlen)
{
    struct apbridge_dev_s *priv;
    struct usbdev_req_s *ctrlreq;
    uint16_t value;
    uint16_t index;
    uint16_t len;
    int ret = -EOPNOTSUPP;

#ifdef CONFIG_DEBUG
    if (!driver || !dev || !dev->ep0 || !ctrl) {
        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
        return -EIO;
    }
#endif

    /* Extract reference to private data */

    usbtrace(TRACE_CLASSSETUP, ctrl->req);
    priv = ((struct apbridge_driver_s *)driver)->dev;

#ifdef CONFIG_DEBUG
    if (!priv || !priv->ctrlreq) {
        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
        return -ENODEV;
    }
#endif
    ctrlreq = priv->ctrlreq;
    ctrlreq->priv = (void *)USB_REQ;

    /* Extract the little-endian 16-bit values to host order */

    value = GETUINT16(ctrl->value);
    index = GETUINT16(ctrl->index);
    len = GETUINT16(ctrl->len);

    uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
          ctrl->type, ctrl->req, value, index, len);

    switch (ctrl->type & USB_REQ_TYPE_MASK) {
     /***********************************************************************
      * Standard Requests
      ***********************************************************************/

    case USB_REQ_TYPE_STANDARD:
        {
            switch (ctrl->req) {
            case USB_REQ_GETDESCRIPTOR:
                {
                    /* The value field specifies the descriptor type in the MS byte and the
                     * descriptor index in the LS byte (order is little endian)
                     */

                    switch (ctrl->value[1]) {
                    case USB_DESC_TYPE_DEVICE:
                        {
                            ret = USB_SIZEOF_DEVDESC;
                            memcpy(ctrlreq->buf, &g_devdesc, ret);
                        }
                        break;

                    case USB_DESC_TYPE_DEVICEQUALIFIER:
                        {
                            ret = USB_SIZEOF_QUALDESC;
                            memcpy(ctrlreq->buf, &g_qualdesc, ret);
                        }
                        break;

                    case USB_DESC_TYPE_OTHERSPEEDCONFIG:
                    case USB_DESC_TYPE_CONFIG:
                        {
                            ret =
                                usbclass_mkcfgdesc(ctrlreq->buf, dev->speed,
                                                   ctrl->req);
                        }
                        break;

                    case USB_DESC_TYPE_STRING:
                        {
                            /* index == language code. */

                            ret =
                                usbclass_mkstrdesc(ctrl->value[0],
                                                   (struct usb_strdesc_s *)
                                                   ctrlreq->buf);
                        }
                        break;

                    default:
                        {
                            usbtrace(TRACE_CLSERROR
                                     (USBSER_TRACEERR_GETUNKNOWNDESC), value);
                        }
                        break;
                    }
                }
                break;

            case USB_REQ_SETCONFIGURATION:
                {
                    if (ctrl->type == 0) {
                        ret = usbclass_setconfig(priv, value);
                    }
                }
                break;

            case USB_REQ_GETCONFIGURATION:
                {
                    if (ctrl->type == USB_DIR_IN) {
                        *(uint8_t *) ctrlreq->buf = priv->config;
                        ret = 1;
                    }
                }
                break;

            case USB_REQ_SETINTERFACE:
                {
                    if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE) {
                        if (priv->config == APBRIDGE_CONFIGID &&
                            index == APBRIDGE_INTERFACEID &&
                            value == APBRIDGE_ALTINTERFACEID) {
                            usbclass_resetconfig(priv);
                            usbclass_setconfig(priv, priv->config);
                            ret = 0;
                        }
                    }
                }
                break;

            case USB_REQ_GETINTERFACE:
                {
                    if (ctrl->type ==
                        (USB_DIR_IN | USB_REQ_RECIPIENT_INTERFACE)
                        && priv->config == APBRIDGE_CONFIGIDNONE) {
                        if (index != APBRIDGE_INTERFACEID) {
                            ret = -EDOM;
                        } else {
                            *(uint8_t *) ctrlreq->buf =
                                APBRIDGE_ALTINTERFACEID;
                            ret = 1;
                        }
                    }
                }
                break;

            default:
                usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDSTDREQ),
                         ctrl->req);
                break;
            }
        }
        break;

        /* Put here vendor request */
    case USB_REQ_TYPE_VENDOR:
        {
            if ((ctrl->type & USB_REQ_RECIPIENT_MASK) ==
                USB_REQ_RECIPIENT_INTERFACE) {
                if (ctrl->req == APBRIDGE_RWREQUEST_SVC) {
                    if ((ctrl->type & USB_DIR_IN) != 0) {
                        *(uint32_t *) ctrlreq->buf = 0xdeadbeef;
                        ret = 4;
                    } else {
                        ctrlreq->priv = (void *)GREYBUS_SVC_REQ;
                        ret = len;
                    }
                } else if (ctrl->req == APBRIDGE_RWREQUEST_LOG) {
                    if ((ctrl->type & USB_DIR_IN) == 0) {
                    } else {
#if defined(CONFIG_APB_USB_LOG)
                        ctrlreq->priv = (void *)GREYBUS_LOG;
                        ret = usb_get_log(ctrlreq->buf, len);
#else
                        ret = 0;
#endif
                    }
                } else {
                    usbtrace(TRACE_CLSERROR
                             (USBSER_TRACEERR_UNSUPPORTEDCLASSREQ),
                             ctrl->type);
                }
            }
        }
        break;

    default:
        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
        break;
    }

    /* Respond to the setup command if data was returned.  On an error return
     * value (ret < 0), the USB driver will stall.
     */

    if (ret >= 0) {
        ctrlreq->len = min(len, ret);
        ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
        ret = EP_SUBMIT(dev->ep0, ctrlreq);
        if (ret < 0) {
            usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ),
                     (uint16_t) - ret);
            ctrlreq->result = OK;
            usbclass_ep0incomplete(dev->ep0, ctrlreq);
        }
    }

    return ret;
}