1cb7b3927b
Signed-off-by: jyzhiyu <jyzhiyu@gmail.com>
317 lines
10 KiB
C
317 lines
10 KiB
C
/*
|
|
* Copyright 2012 Jared Boone
|
|
* Copyright 2013/2014 Benjamin Vernoux <bvernoux@gmail.com>
|
|
*
|
|
* This file is part of AirSpy (based on HackRF project).
|
|
*
|
|
* This program 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 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program 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 this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "usb_type.h"
|
|
#include "airspy_commands.h"
|
|
#include "usb_descriptor.h"
|
|
|
|
#define USB_VENDOR_ID (0x1D50)
|
|
#define USB_PRODUCT_ID (0x60A1)
|
|
|
|
#define USB_WORD(x) (x & 0xFF), ((x >> 8) & 0xFF)
|
|
|
|
#define USB_MAX_PACKET0 (64)
|
|
#define USB_MAX_PACKET_BULK_FS (64)
|
|
#define USB_MAX_PACKET_BULK_HS (512)
|
|
|
|
#define USB_BULK_IN_EP_ADDR (0x81)
|
|
#define USB_BULK_OUT_EP_ADDR (0x02)
|
|
|
|
#define USB_STRING_LANGID (0x0409)
|
|
|
|
uint8_t usb_descriptor_device[] =
|
|
{
|
|
18, // bLength
|
|
USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType
|
|
USB_WORD(0x0200), // bcdUSB
|
|
0x00, // bDeviceClass
|
|
0x00, // bDeviceSubClass
|
|
0x00, // bDeviceProtocol
|
|
USB_MAX_PACKET0, // bMaxPacketSize0
|
|
USB_WORD(USB_VENDOR_ID), // idVendor
|
|
USB_WORD(USB_PRODUCT_ID), // idProduct
|
|
USB_WORD(0x0100), // bcdDevice
|
|
0x01, // iManufacturer
|
|
0x02, // iProduct
|
|
0x03, // iSerialNumber
|
|
0x01 // bNumConfigurations
|
|
};
|
|
|
|
uint8_t usb_descriptor_device_qualifier[] =
|
|
{
|
|
10, // bLength
|
|
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, // bDescriptorType
|
|
USB_WORD(0x0200), // bcdUSB
|
|
0x00, // bDeviceClass
|
|
0x00, // bDeviceSubClass
|
|
0x00, // bDeviceProtocol
|
|
64, // bMaxPacketSize0
|
|
0x01, // bNumOtherSpeedConfigurations
|
|
0x00 // bReserved
|
|
};
|
|
|
|
uint8_t usb_descriptor_configuration_full_speed[] =
|
|
{
|
|
9, // bLength
|
|
USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType
|
|
USB_WORD(32), // wTotalLength
|
|
0x01, // bNumInterfaces
|
|
0x01, // bConfigurationValue
|
|
0x00, // iConfiguration
|
|
0x80, // bmAttributes: USB-powered
|
|
250, // bMaxPower: 500mA
|
|
|
|
9, // bLength
|
|
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
|
|
0x00, // bInterfaceNumber
|
|
0x00, // bAlternateSetting
|
|
0x02, // bNumEndpoints
|
|
0xFF, // bInterfaceClass: vendor-specific
|
|
0xFF, // bInterfaceSubClass
|
|
0xFF, // bInterfaceProtocol: vendor-specific
|
|
0x00, // iInterface
|
|
|
|
7, // bLength
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
|
|
USB_BULK_IN_EP_ADDR, // bEndpointAddress
|
|
0x02, // bmAttributes: BULK
|
|
USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize
|
|
0x00, // bInterval: no NAK
|
|
|
|
7, // bLength
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
|
|
USB_BULK_OUT_EP_ADDR, // bEndpointAddress
|
|
0x02, // bmAttributes: BULK
|
|
USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize
|
|
0x00, // bInterval: no NAK
|
|
|
|
0, // TERMINATOR
|
|
};
|
|
|
|
uint8_t usb_descriptor_configuration_high_speed[] =
|
|
{
|
|
9, // bLength
|
|
USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType
|
|
USB_WORD(32), // wTotalLength
|
|
0x01, // bNumInterfaces
|
|
0x01, // bConfigurationValue
|
|
0x00, // iConfiguration
|
|
0x80, // bmAttributes: USB-powered
|
|
250, // bMaxPower: 500mA
|
|
|
|
9, // bLength
|
|
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
|
|
0x00, // bInterfaceNumber
|
|
0x00, // bAlternateSetting
|
|
0x02, // bNumEndpoints
|
|
0xFF, // bInterfaceClass: vendor-specific
|
|
0xFF, // bInterfaceSubClass
|
|
0xFF, // bInterfaceProtocol: vendor-specific
|
|
0x00, // iInterface
|
|
|
|
7, // bLength
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
|
|
USB_BULK_IN_EP_ADDR, // bEndpointAddress
|
|
0x02, // bmAttributes: BULK
|
|
USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize
|
|
0x00, // bInterval: no NAK
|
|
|
|
7, // bLength
|
|
USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType
|
|
USB_BULK_OUT_EP_ADDR, // bEndpointAddress
|
|
0x02, // bmAttributes: BULK
|
|
USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize
|
|
0x00, // bInterval: no NAK
|
|
|
|
0, // TERMINATOR
|
|
};
|
|
|
|
uint8_t usb_descriptor_string_languages[] =
|
|
{
|
|
0x04, // bLength
|
|
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
|
USB_WORD(USB_STRING_LANGID), // wLANGID
|
|
};
|
|
|
|
uint8_t usb_descriptor_string_manufacturer[] =
|
|
{
|
|
30, // bLength
|
|
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
|
'w', 0x00,
|
|
'w', 0x00,
|
|
'w', 0x00,
|
|
'.', 0x00,
|
|
'a', 0x00,
|
|
'i', 0x00,
|
|
'r', 0x00,
|
|
's', 0x00,
|
|
'p', 0x00,
|
|
'y', 0x00,
|
|
'.', 0x00,
|
|
'c', 0x00,
|
|
'o', 0x00,
|
|
'm', 0x00
|
|
};
|
|
|
|
uint8_t usb_descriptor_string_product[] =
|
|
{
|
|
14, // bLength
|
|
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
|
'A', 0x00,
|
|
'I', 0x00,
|
|
'R', 0x00,
|
|
'S', 0x00,
|
|
'P', 0x00,
|
|
'Y', 0x00
|
|
};
|
|
|
|
/* 64bits Serial Number from SPIFI */
|
|
#define USB_DESCRIPTOR_SN_POS (22)
|
|
uint8_t usb_descriptor_string_serial_number[] =
|
|
{
|
|
54, // bLength
|
|
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
|
'A', 0x00,
|
|
'I', 0x00,
|
|
'R', 0x00,
|
|
'S', 0x00,
|
|
'P', 0x00,
|
|
'Y', 0x00,
|
|
' ', 0x00,
|
|
'S', 0x00,
|
|
'N', 0x00,
|
|
':', 0x00,
|
|
/* Data filled by CPU with 64bits Serial Number from SPIFI to ASCII HEX */
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00,
|
|
' ', 0x00
|
|
};
|
|
|
|
static const uint8_t htoa[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
|
|
|
void usb_descriptor_fill_string_serial_number(usb_descriptor_serial_number_t serial_number)
|
|
{
|
|
int i, j;
|
|
uint32_t data_u32;
|
|
uint8_t data_u8;
|
|
|
|
j = 0;
|
|
for(i=0; i<2; i++)
|
|
{
|
|
data_u32 = serial_number.sn_32b[i];
|
|
|
|
data_u8 = (data_u32 & 0xFF000000) >> 24;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0xF0) >> 4];
|
|
j+=2;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0x0F)];
|
|
j+=2;
|
|
|
|
data_u8 = (data_u32 & 0x00FF0000) >> 16;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0xF0) >> 4];
|
|
j+=2;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0x0F)];
|
|
j+=2;
|
|
|
|
data_u8 = (data_u32 & 0x0000FF00) >> 8;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0xF0) >> 4];
|
|
j+=2;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0x0F)];
|
|
j+=2;
|
|
|
|
data_u8 = (data_u32 & 0x000000FF);
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0xF0) >> 4];
|
|
j+=2;
|
|
usb_descriptor_string_serial_number[USB_DESCRIPTOR_SN_POS + j] = htoa[(data_u8 & 0x0F)];
|
|
j+=2;
|
|
}
|
|
}
|
|
|
|
uint8_t* const usb_descriptor_strings[] =
|
|
{
|
|
usb_descriptor_string_languages,
|
|
usb_descriptor_string_manufacturer,
|
|
usb_descriptor_string_product,
|
|
usb_descriptor_string_serial_number,
|
|
0, // TERMINATOR
|
|
};
|
|
|
|
uint8_t usb_descriptor_MSDescriptor[] =
|
|
{
|
|
0x12, /* Length */
|
|
0x03, /* Descriptor Type */
|
|
0x4D,0x00,0x53,0x00,0x46,0x00,0x54,0x00,0x31,0x00,0x30,0x00,0x30,0x00, /* 'MSFT100' */
|
|
AIRSPY_MS_VENDOR_CMD, /* Vendor Specific to retrieve OS feature descriptors (shall be > 0) */
|
|
0x00 /* Pad field */
|
|
};
|
|
|
|
uint8_t usb_descriptor_CompatIDDescriptor[] =
|
|
{
|
|
0x28,0x00,0x00,0x00, //dwLength
|
|
0x00,0x01, //bcdVersion
|
|
0x04,0x00, //wIndex (Fixed:INDEX_CONFIG_DESCRIPTOR)
|
|
0x01, //bCount (Count of device functions - Must be 1)
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00, //Reserved
|
|
0x01, //bFirstInterfaceNumber (First interface for this function)
|
|
0x01, //Reserved
|
|
'W' ,'I' ,'N' ,'U' ,'S' ,'B' ,0x00,0x00, //Compatible ID, padded with zeros
|
|
'W' ,'I' ,'N' ,'U' ,'S' ,'B' ,0x00,0x00, //Sub-compatible ID, padded with zeros
|
|
0x00,0x00,0x00,0x00,0x00,0x00 //Reserved
|
|
};
|
|
|
|
uint8_t usb_descriptor_ExtProps[] =
|
|
{
|
|
0x8e,0x00,0x00,0x00, //dwLength
|
|
0x00,0x01, //bcdVersion 0x02
|
|
0x05,0x00, //wIndex (Fixed:5) 0x02
|
|
0x01,0x00, //wCount 0x02
|
|
//0x00,0x00,0x00,0x00,0x00,0x00,0x00, //Reserved 0x07
|
|
////////////////////////////////////////////////////////
|
|
//Custom Property 1
|
|
////////////////////////////////////////////////////////
|
|
0x84,0x00,0x00,0x00, //dwLength //0x04
|
|
0x01,0x00,0x00,0x00, //dwPropertyDataType //0x04
|
|
0x28,0x00, //wPropertyNameLength //0x02
|
|
'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0,'t',0,'e',0,'r',0,'f',0,'a',0,'c',0,'e',0,'G',0,'U',0,'I',0,'D',0,0,0,//bPropertyName = 0x28
|
|
0x4e,0x00,0x00,0x00, //dwPropertyDataLength //0x04
|
|
'{',0,'4',0,'A',0,'F',0,'4',0,'1',0,'8',0,'6'
|
|
,0,'5',0,'-',0,'B',0,'C',0,'1',0,'E',0,'-'
|
|
,0,'7',0,'4',0,'5',0,'A',0,'-',0,'9',0,'8'
|
|
,0,'2',0,'6',0,'-',0,'9',0,'7',0,'C',0,'A'
|
|
,0,'A',0,'8',0,'E',0,'E',0,'0',0,'4',0,'7'
|
|
,0,'F',0,'}',0,0,0 //0x4e //bPropertyData
|
|
};
|