aoa.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * @file aoa.c
  3. * @brief https://source.android.com/devices/accessories/aoa
  4. * http://www.hackermi.com/2015-04/aoa-analyse/
  5. * Android 开放配件协议 1.0
  6. * @author chenrixin@zh-jieli.com
  7. * @version 1
  8. * @date 2020-03-25
  9. */
  10. #include "includes.h"
  11. #include "app_config.h"
  12. #include "usb_config.h"
  13. #include "usb/host/usb_host.h"
  14. #include "usb/usb_phy.h"
  15. #include "device_drive.h"
  16. #include "usb_ctrl_transfer.h"
  17. #include "usb_bulk_transfer.h"
  18. #include "usb_storage.h"
  19. #include "adb.h"
  20. #include "aoa.h"
  21. #include "usb_hid_keys.h"
  22. #if TCFG_AOA_ENABLE
  23. #include "gamebox.h"
  24. #define LOG_TAG_CONST USB
  25. #define LOG_TAG "[AOA]"
  26. #define LOG_ERROR_ENABLE
  27. #define LOG_DEBUG_ENABLE
  28. #define LOG_INFO_ENABLE
  29. /* #define LOG_DUMP_ENABLE */
  30. #define LOG_CLI_ENABLE
  31. #include "debug.h"
  32. //0x2D00 有一个接口,该接口有两个批量端点,用于输入和输出通信。
  33. //0x2D01 有两个接口,每个接口有两个批量端点,用于输入和输出通信。
  34. //第一个接口处理标准通信,
  35. //第二个接口则处理 ADB 通信。
  36. //要使用接口,请找到第一个批量输入和输出端点,
  37. //使用 SET_CONFIGURATION (0x09) 设备请求将设备配置的值设为 1,然后使用端点进行通信
  38. //
  39. static void aoa_timer_handler(void *priv);
  40. static u32 aoa_timer_id;
  41. static struct aoa_device_t aoa;
  42. static struct device aoa_device;
  43. static int set_power(struct usb_host_device *host_dev, u32 value)
  44. {
  45. if (aoa_timer_id) {
  46. usr_timer_del(aoa_timer_id);
  47. aoa_timer_id = 0;
  48. }
  49. return DEV_ERR_NONE;
  50. }
  51. static int get_power(struct usb_host_device *host_dev, u32 value)
  52. {
  53. return DEV_ERR_NONE;
  54. }
  55. static const struct interface_ctrl aoa_ctrl = {
  56. .interface_class = USB_CLASS_AOA,
  57. .set_power = set_power,
  58. .get_power = get_power,
  59. .ioctl = NULL,
  60. };
  61. static const struct usb_interface_info aoa_inf = {
  62. .ctrl = (struct interface_ctrl *) &aoa_ctrl,
  63. .dev.aoa = &aoa,
  64. };
  65. static const char *credetials[] = {"JieLiTec",
  66. "GameBox",
  67. "Android accessories devcie !",
  68. "1.0.0",
  69. "http://www.zh-jieli.com",
  70. "1234567890ABCDEF",
  71. };
  72. void aoa_switch(struct usb_host_device *host_dev)
  73. {
  74. u16 version;
  75. log_info("aoa_switch");
  76. usb_get_aoa_version(host_dev, &version);
  77. log_info("AOA version: %x", version);
  78. for (int i = 0; i < 5; i++) {
  79. log_info("send string [%d] %s", i, credetials[i]);
  80. int r = usb_set_credentials(host_dev, credetials[i], i);
  81. if (r < 0) {
  82. break;
  83. }
  84. }
  85. usb_switch2aoa(host_dev);
  86. }
  87. int usb_aoa_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
  88. {
  89. struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
  90. pBuf += sizeof(struct usb_interface_descriptor);
  91. int len = 0;
  92. const usb_dev usb_id = host_device2id(host_dev);
  93. aoa_device.private_data = host_dev;
  94. host_dev->interface_info[interface_num] = &aoa_inf;
  95. for (int endnum = 0; endnum < interface->bNumEndpoints; endnum++) {
  96. struct usb_endpoint_descriptor *end_desc = (struct usb_endpoint_descriptor *)pBuf;
  97. if (end_desc->bDescriptorType != USB_DT_ENDPOINT ||
  98. end_desc->bLength != USB_DT_ENDPOINT_SIZE) {
  99. log_error("ep bDescriptorType = %d bLength = %d", end_desc->bDescriptorType, end_desc->bLength);
  100. return -USB_DT_ENDPOINT;
  101. }
  102. len += USB_DT_ENDPOINT_SIZE;
  103. pBuf += USB_DT_ENDPOINT_SIZE;
  104. if ((end_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
  105. if (end_desc->bEndpointAddress & USB_DIR_IN) {
  106. aoa.target_epin = end_desc->bEndpointAddress & 0x0f;
  107. #if HUSB_MODE
  108. aoa.rxmaxp = end_desc->wMaxPacketSize;
  109. #endif
  110. } else {
  111. aoa.target_epout = end_desc->bEndpointAddress & 0x0f;
  112. #if HUSB_MODE
  113. aoa.txmaxp = end_desc->wMaxPacketSize;
  114. #endif
  115. }
  116. }
  117. }
  118. return len;
  119. }
  120. static int aoa_tx_data(const u8 *pbuf, u32 len)
  121. {
  122. struct usb_host_device *host_dev = aoa_device.private_data;
  123. usb_dev usb_id = host_device2id(host_dev);
  124. g_printf("TX:");
  125. printf_buf(pbuf, len);
  126. return usb_h_ep_write_async(usb_id, aoa.host_epout, 64, aoa.target_epout, pbuf, len, USB_ENDPOINT_XFER_BULK, 1);
  127. }
  128. static void aoa_epin_isr(struct usb_host_device *host_dev, u32 ep)
  129. {
  130. u8 buffer[64] = {0};
  131. usb_dev usb_id = host_device2id(host_dev);
  132. u32 rx_len = usb_h_ep_read_async(usb_id, ep, aoa.target_epin, buffer, sizeof(buffer), USB_ENDPOINT_XFER_BULK, 0);
  133. g_printf("RX:");
  134. printf_buf(buffer, rx_len);
  135. usb_h_ep_read_async(usb_id, ep, aoa.target_epin, NULL, 0, USB_ENDPOINT_XFER_BULK, 1);
  136. }
  137. #define Accessory_assigned_ID 0x0001
  138. u32 aoa_process(u32 mode, u32 id)
  139. {
  140. struct usb_host_device *host_dev = aoa_device.private_data;
  141. struct usb_device_descriptor device_desc;
  142. usb_get_device_descriptor(host_dev, &device_desc);
  143. if ((device_desc.idVendor == 0x18d1) &&
  144. ((device_desc.idProduct & 0x2d00) == 0x2d00)) {
  145. log_info("aoa mode ready idVendor:%x idProduct: %x",
  146. device_desc.idVendor, device_desc.idProduct);
  147. } else {
  148. log_info("aoa switch idVendor:%x idProduct: %x",
  149. device_desc.idVendor, device_desc.idProduct);
  150. aoa_switch(host_dev);
  151. usb_host_remount(id, 3, 30, 50, 1);
  152. return 0;
  153. }
  154. usb_aoa_register_hid(host_dev, Accessory_assigned_ID, sizeof(hid_report_desc));
  155. u32 offset = 0;
  156. while (offset < sizeof(hid_report_desc)) {
  157. u32 cnt = min(sizeof(hid_report_desc) - offset, 63);
  158. usb_aoa_set_hid_report_desc(host_dev, Accessory_assigned_ID, offset, &hid_report_desc[offset], cnt);
  159. offset += cnt;
  160. }
  161. aoa.host_epout = usb_get_ep_num(id, USB_DIR_OUT, USB_ENDPOINT_XFER_BULK);
  162. aoa.host_epin = usb_get_ep_num(id, USB_DIR_IN, USB_ENDPOINT_XFER_BULK);
  163. log_debug("D(%d)->H(%d)", aoa.target_epin, aoa.host_epin);
  164. log_debug("H(%d)->D(%d)", aoa.host_epout, aoa.target_epout);
  165. usb_h_set_ep_isr(host_dev, aoa.host_epin | USB_DIR_IN, aoa_epin_isr, host_dev);
  166. u8 *ep_buffer = usb_h_get_ep_buffer(id, aoa.host_epin | USB_DIR_IN);
  167. usb_h_ep_config(id, aoa.host_epin | USB_DIR_IN, USB_ENDPOINT_XFER_BULK, 1, 0, ep_buffer, 64);
  168. int r = usb_h_ep_read_async(id, aoa.host_epin, aoa.target_epin, NULL, 0, USB_ENDPOINT_XFER_BULK, 1);
  169. ep_buffer = usb_h_get_ep_buffer(id, aoa.host_epout | USB_DIR_OUT);
  170. usb_h_ep_config(id, aoa.host_epout | USB_DIR_OUT, USB_ENDPOINT_XFER_BULK, 0, 0, ep_buffer, 64);
  171. aoa_timer_id = usr_timer_add((void *)0, aoa_timer_handler, 4, 0);
  172. g_printf("aoa succ");
  173. return 1;
  174. }
  175. static void aoa_timer_handler(void *priv)
  176. {
  177. struct usb_host_device *host_dev = aoa_device.private_data;
  178. u8 tx_buffer[32];
  179. if (mouse_data_send == 1) {
  180. tx_buffer[0] = MOUSE_POINT_ID;
  181. memcpy(&tx_buffer[1], &mouse_data, sizeof(mouse_data));
  182. usb_aoa_send_hid_event(host_dev, Accessory_assigned_ID, tx_buffer, sizeof(mouse_data) + 1);
  183. memset(&mouse_data, 0, sizeof(mouse_data)) ;
  184. mouse_data_send = 0;
  185. }
  186. tx_buffer[0] = TOUCH_SCREEN_ID;
  187. struct touch_screen_t t;
  188. memset(&t, 0, sizeof(t));
  189. if (point_list_pop(&t)) {
  190. memcpy(&tx_buffer[1], &t, sizeof(t));
  191. usb_aoa_send_hid_event(host_dev, Accessory_assigned_ID, tx_buffer, sizeof(t) + 1);
  192. }
  193. }
  194. #endif