usbd_adb.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbd_core.h"
  7. #include "usbd_adb.h"
  8. #define ADB_OUT_EP_IDX 0
  9. #define ADB_IN_EP_IDX 1
  10. #define ADB_STATE_READ_MSG 0
  11. #define ADB_STATE_READ_DATA 1
  12. #define ADB_STATE_WRITE_MSG 2
  13. #define ADB_STATE_WRITE_DATA 3
  14. #define ADB_STATE_AWRITE_MSG 4
  15. #define ADB_STATE_AWRITE_DATA 5
  16. #define MAX_PAYLOAD_V1 (4 * 1024)
  17. #define MAX_PAYLOAD_V2 (256 * 1024)
  18. #define MAX_PAYLOAD MAX_PAYLOAD_V1
  19. #define A_VERSION 0x01000000
  20. #define A_SYNC 0x434e5953
  21. #define A_CNXN 0x4e584e43
  22. #define A_OPEN 0x4e45504f
  23. #define A_OKAY 0x59414b4f
  24. #define A_CLSE 0x45534c43
  25. #define A_WRTE 0x45545257
  26. #define A_AUTH 0x48545541
  27. struct adb_msg {
  28. uint32_t command; /* command identifier constant (A_CNXN, ...) */
  29. uint32_t arg0; /* first argument */
  30. uint32_t arg1; /* second argument */
  31. uint32_t data_length; /* length of payload (0 is allowed) */
  32. uint32_t data_crc32; /* crc32 of data payload */
  33. uint32_t magic; /* command ^ 0xffffffff */
  34. };
  35. struct adb_packet {
  36. struct adb_msg msg;
  37. uint8_t payload[MAX_PAYLOAD];
  38. };
  39. struct usbd_adb {
  40. uint8_t state;
  41. uint8_t common_state;
  42. uint8_t write_state;
  43. bool writable;
  44. uint32_t localid;
  45. uint32_t shell_remoteid;
  46. uint32_t file_remoteid;
  47. } adb_client;
  48. static struct usbd_endpoint adb_ep_data[2];
  49. USB_NOCACHE_RAM_SECTION struct adb_packet tx_packet;
  50. USB_NOCACHE_RAM_SECTION struct adb_packet rx_packet;
  51. static inline uint32_t adb_packet_checksum(struct adb_packet *packet)
  52. {
  53. uint32_t sum = 0;
  54. uint32_t i;
  55. for (i = 0; i < packet->msg.data_length; ++i) {
  56. sum += (uint32_t)(packet->payload[i]);
  57. }
  58. return sum;
  59. }
  60. static uint32_t usbd_adb_get_remoteid(uint32_t localid)
  61. {
  62. if (localid == ADB_SHELL_LOALID) {
  63. return adb_client.shell_remoteid;
  64. } else {
  65. return adb_client.file_remoteid;
  66. }
  67. }
  68. static void adb_send_msg(struct adb_packet *packet)
  69. {
  70. adb_client.common_state = ADB_STATE_WRITE_MSG;
  71. packet->msg.data_crc32 = adb_packet_checksum(packet);
  72. packet->msg.magic = packet->msg.command ^ 0xffffffff;
  73. usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
  74. }
  75. static void adb_send_okay(struct adb_packet *packet, uint32_t localid)
  76. {
  77. packet->msg.command = A_OKAY;
  78. packet->msg.arg0 = localid;
  79. packet->msg.arg1 = usbd_adb_get_remoteid(localid);
  80. packet->msg.data_length = 0;
  81. adb_send_msg(&tx_packet);
  82. }
  83. static void adb_send_close(struct adb_packet *packet, uint32_t localid, uint32_t remoteid)
  84. {
  85. packet->msg.command = A_CLSE;
  86. packet->msg.arg0 = localid;
  87. packet->msg.arg1 = remoteid;
  88. packet->msg.data_length = 0;
  89. adb_send_msg(&tx_packet);
  90. }
  91. void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
  92. {
  93. (void)ep;
  94. if (adb_client.common_state == ADB_STATE_READ_MSG) {
  95. if (nbytes != sizeof(struct adb_msg)) {
  96. USB_LOG_ERR("invalid adb msg size:%d\r\n", nbytes);
  97. return;
  98. }
  99. USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n",
  100. rx_packet.msg.command,
  101. rx_packet.msg.arg0,
  102. rx_packet.msg.arg1,
  103. rx_packet.msg.data_length);
  104. if (rx_packet.msg.data_length) {
  105. /* setup next out ep read transfer */
  106. adb_client.common_state = ADB_STATE_READ_DATA;
  107. usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, rx_packet.payload, rx_packet.msg.data_length);
  108. } else {
  109. if (rx_packet.msg.command == A_CLSE) {
  110. adb_client.writable = false;
  111. usbd_adb_notify_write_done();
  112. USB_LOG_INFO("Close remoteid:%x\r\n", rx_packet.msg.arg0);
  113. }
  114. adb_client.common_state = ADB_STATE_READ_MSG;
  115. /* setup first out ep read transfer */
  116. usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
  117. }
  118. } else if (adb_client.common_state == ADB_STATE_READ_DATA) {
  119. switch (rx_packet.msg.command) {
  120. case A_SYNC:
  121. break;
  122. case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
  123. char *support_feature = "device::"
  124. "ro.product.name=cherryadb;"
  125. "ro.product.model=cherrysh;"
  126. "ro.product.device=cherryadb;"
  127. "features=cmd,shell_v1";
  128. tx_packet.msg.command = A_CNXN;
  129. tx_packet.msg.arg0 = A_VERSION;
  130. tx_packet.msg.arg1 = MAX_PAYLOAD;
  131. tx_packet.msg.data_length = strlen(support_feature);
  132. memcpy(tx_packet.payload, support_feature, strlen(support_feature));
  133. adb_send_msg(&tx_packet);
  134. adb_client.writable = false;
  135. break;
  136. case A_OPEN: /* OPEN(local-id, 0, "destination") */
  137. rx_packet.payload[rx_packet.msg.data_length] = '\0';
  138. if (strncmp((const char *)rx_packet.payload, "shell:", 6) == 0) {
  139. adb_client.localid = ADB_SHELL_LOALID;
  140. adb_client.shell_remoteid = rx_packet.msg.arg0;
  141. adb_send_okay(&tx_packet, ADB_SHELL_LOALID);
  142. USB_LOG_INFO("Open shell service, remoteid:%x\r\n", rx_packet.msg.arg0);
  143. } else if (strncmp((const char *)rx_packet.payload, "sync:", 5) == 0) {
  144. adb_client.localid = ADB_FILE_LOALID;
  145. adb_client.file_remoteid = rx_packet.msg.arg0;
  146. adb_send_okay(&tx_packet, ADB_FILE_LOALID);
  147. USB_LOG_INFO("Open file service, remoteid:%x\r\n", rx_packet.msg.arg0);
  148. }
  149. break;
  150. case A_OKAY:
  151. break;
  152. case A_CLSE:
  153. break;
  154. case A_WRTE: /* WRITE(local-id, remote-id, "data") */
  155. if ((rx_packet.msg.arg0 == adb_client.shell_remoteid) && (rx_packet.msg.arg1 == ADB_SHELL_LOALID)) {
  156. adb_send_okay(&tx_packet, rx_packet.msg.arg1);
  157. } else if ((rx_packet.msg.arg0 == adb_client.file_remoteid) && (rx_packet.msg.arg1 == ADB_FILE_LOALID)) {
  158. adb_send_okay(&tx_packet, rx_packet.msg.arg1);
  159. } else {
  160. adb_send_close(&tx_packet, 0, rx_packet.msg.arg0);
  161. }
  162. break;
  163. case A_AUTH:
  164. break;
  165. default:
  166. break;
  167. }
  168. }
  169. }
  170. void usbd_adb_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
  171. {
  172. (void)ep;
  173. (void)nbytes;
  174. if (adb_client.common_state == ADB_STATE_WRITE_MSG) {
  175. if (tx_packet.msg.data_length) {
  176. adb_client.common_state = ADB_STATE_WRITE_DATA;
  177. usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
  178. } else {
  179. if (rx_packet.msg.command == A_WRTE) {
  180. adb_client.writable = true;
  181. if (adb_client.localid == ADB_SHELL_LOALID) {
  182. usbd_adb_notify_shell_read(rx_packet.payload, rx_packet.msg.data_length);
  183. } else {
  184. }
  185. }
  186. adb_client.common_state = ADB_STATE_READ_MSG;
  187. /* setup first out ep read transfer */
  188. usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
  189. }
  190. } else if (adb_client.common_state == ADB_STATE_WRITE_DATA) {
  191. adb_client.common_state = ADB_STATE_READ_MSG;
  192. /* setup first out ep read transfer */
  193. usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
  194. } else if (adb_client.write_state == ADB_STATE_AWRITE_MSG) {
  195. if (tx_packet.msg.data_length) {
  196. adb_client.write_state = ADB_STATE_AWRITE_DATA;
  197. usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length);
  198. } else {
  199. }
  200. } else if (adb_client.write_state == ADB_STATE_AWRITE_DATA) {
  201. usbd_adb_notify_write_done();
  202. }
  203. }
  204. void adb_notify_handler(uint8_t busid, uint8_t event, void *arg)
  205. {
  206. (void)arg;
  207. switch (event) {
  208. case USBD_EVENT_INIT:
  209. break;
  210. case USBD_EVENT_DEINIT:
  211. break;
  212. case USBD_EVENT_RESET:
  213. break;
  214. case USBD_EVENT_CONFIGURED:
  215. adb_client.common_state = ADB_STATE_READ_MSG;
  216. /* setup first out ep read transfer */
  217. usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg));
  218. break;
  219. default:
  220. break;
  221. }
  222. }
  223. struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep)
  224. {
  225. (void)busid;
  226. intf->class_interface_handler = NULL;
  227. intf->class_endpoint_handler = NULL;
  228. intf->vendor_handler = NULL;
  229. intf->notify_handler = adb_notify_handler;
  230. adb_ep_data[ADB_OUT_EP_IDX].ep_addr = out_ep;
  231. adb_ep_data[ADB_OUT_EP_IDX].ep_cb = usbd_adb_bulk_out;
  232. adb_ep_data[ADB_IN_EP_IDX].ep_addr = in_ep;
  233. adb_ep_data[ADB_IN_EP_IDX].ep_cb = usbd_adb_bulk_in;
  234. usbd_add_endpoint(busid, &adb_ep_data[ADB_OUT_EP_IDX]);
  235. usbd_add_endpoint(busid, &adb_ep_data[ADB_IN_EP_IDX]);
  236. return intf;
  237. }
  238. bool usbd_adb_can_write(void)
  239. {
  240. return adb_client.writable;
  241. }
  242. int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len)
  243. {
  244. struct adb_packet *packet;
  245. packet = &tx_packet;
  246. packet->msg.command = A_WRTE;
  247. packet->msg.arg0 = localid;
  248. packet->msg.arg1 = usbd_adb_get_remoteid(localid);
  249. packet->msg.data_length = len;
  250. memcpy(packet->payload, data, len);
  251. packet->msg.data_crc32 = adb_packet_checksum(packet);
  252. packet->msg.magic = packet->msg.command ^ 0xffffffff;
  253. adb_client.write_state = ADB_STATE_AWRITE_MSG;
  254. usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg));
  255. return 0;
  256. }
  257. void usbd_adb_close(uint32_t localid)
  258. {
  259. adb_send_close(&tx_packet, 0, usbd_adb_get_remoteid(localid));
  260. }