-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2261f89
Showing
19 changed files
with
3,161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Android Debug Bridge daemon implementation in RT-Thread | ||
|
||
## 1. 介绍 | ||
|
||
以TCP为通信接口,在PC与RT-Thread之间建立文件传输与执行shell | ||
的通道。 | ||
|
||
## 2. 依赖 | ||
|
||
- 传输 - LWIP | ||
- 文件系统、POSIX、LIBC | ||
- shell - 依赖finsh/msh | ||
|
||
- 上位机工具 - (win: adb.exe) | ||
|
||
## 2. 配置ADBD | ||
|
||
### 2.1 启用ADBD | ||
在rtconfig.h写入如下定义: | ||
|
||
`#define PKG_USING_ADB` | ||
`#define ADB_SERVICE_SHELL_ENABLE` /* 开启shell服务 */ | ||
`#define ADB_SERVICE_FILESYNC_ENABLE` /* 开启文件服务 */ | ||
|
||
## 3. 参考文档 | ||
|
||
### 3.1 ADB官方文档 | ||
|
||
- [ADB简介](docs/OVERVIEW.TXT) | ||
- [协议简介](docs/PROTOCOL.TXT) | ||
- [文件服务](docs/SYNC.TXT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Import('RTT_ROOT') | ||
Import('rtconfig') | ||
from building import * | ||
|
||
cwd = GetCurrentDir() | ||
src = Glob('core/*.c') | ||
|
||
CPPPATH = [cwd + '/inc'] | ||
|
||
if GetDepend('ADB_SERVICE_SHELL_ENABLE'): | ||
src += ['services/shell_service.c'] | ||
|
||
if GetDepend('ADB_SERVICE_FILESYNC_ENABLE'): | ||
src += ['services/file_sync_service.c'] | ||
|
||
group = DefineGroup('adb', src, depend = ['PKG_USING_ADB'], CPPPATH = CPPPATH) | ||
|
||
Return('group') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
/* | ||
* Copyright (c) 2018, Real-Thread Information Technology Ltd | ||
* All rights reserved | ||
* | ||
* Copyright (c) 2006-2018, RT-Thread Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2018-11-11 heyuanjie87 the first version | ||
*/ | ||
|
||
#include "adb.h" | ||
#include <adb_service.h> | ||
|
||
#if 1 | ||
#define DBG_ENABLE | ||
#else | ||
#undef DBG_ENABLE | ||
#endif | ||
#define DBG_SECTION_NAME "ADB" | ||
#define DBG_LEVEL DBG_LOG | ||
#define DBG_COLOR | ||
#include <rtdbg.h> | ||
|
||
#ifdef DBG_ENABLE | ||
#define LOG_CON(c, fmt, ...) \ | ||
if (c) \ | ||
LOG_E(fmt, ##__VA_ARGS__) | ||
#else | ||
#define LOG_CON(...) | ||
#endif | ||
|
||
static rt_list_t _adb_list = RT_LIST_OBJECT_INIT(_adb_list); | ||
|
||
static void write_packet(struct adb *d, struct adb_packet *p) | ||
{ | ||
bool ret; | ||
|
||
p->msg.data_crc32 = adb_packet_checksum(p); | ||
p->msg.magic = p->msg.command ^ 0xffffffff; | ||
ret = adb_packet_enqueue(&d->send_que, p, 100); | ||
if (!ret) | ||
{ | ||
adb_packet_delete(p); | ||
LOG_E("write packet fail"); | ||
} | ||
} | ||
|
||
static void send_connect(struct adb *d) | ||
{ | ||
struct adb_packet* cp; | ||
int slen; | ||
char *con_str = "device::" \ | ||
"ro.product.name=mido;" \ | ||
"ro.product.model=rtthread;" \ | ||
"ro.product.device=mido;" \ | ||
"features=cmd,shell_v1"; | ||
|
||
slen = rt_strlen(con_str); | ||
cp = adb_packet_new(slen); | ||
|
||
cp->msg.command = A_CNXN; | ||
// Send the max supported version, but because the transport is | ||
// initialized to A_VERSION_MIN, this will be compatible with every | ||
// device. | ||
cp->msg.arg0 = A_VERSION; | ||
cp->msg.arg1 = MAX_PAYLOAD; | ||
|
||
cp->msg.data_length = slen; | ||
rt_memcpy(cp->payload, con_str, slen); | ||
|
||
write_packet(d, cp); | ||
} | ||
|
||
static void send_ready(struct adb *d, unsigned local, unsigned remote) | ||
{ | ||
struct adb_packet* p = adb_packet_new(0); | ||
|
||
p->msg.command = A_OKAY; | ||
p->msg.arg0 = local; | ||
p->msg.arg1 = remote; | ||
write_packet(d, p); | ||
} | ||
|
||
void adb_send_close(struct adb *d, unsigned local, unsigned remote) | ||
{ | ||
struct adb_packet* p = adb_packet_new(0); | ||
|
||
p->msg.command = A_CLSE; | ||
p->msg.arg0 = local; | ||
p->msg.arg1 = remote; | ||
write_packet(d, p); | ||
} | ||
|
||
static void handle_new_connection(struct adb *d, struct adb_packet *p) | ||
{ | ||
send_connect(d); | ||
} | ||
|
||
static bool _service_enqueue(struct adb_service *ser, struct adb_packet *p) | ||
{ | ||
bool ret; | ||
|
||
ret = ser->ops->enqueue(ser, p, 200); | ||
|
||
return ret; | ||
} | ||
|
||
void adb_packet_handle(struct adb *d, struct adb_packet *p, bool pisnew) | ||
{ | ||
bool del = true; | ||
|
||
if (!p) | ||
return; | ||
|
||
switch(p->msg.command) | ||
{ | ||
case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ | ||
{ | ||
handle_new_connection(d, p); | ||
}break; | ||
case A_OPEN: /* OPEN(local-id, 0, "destination") */ | ||
{ | ||
if (p->msg.arg0 != 0 && p->msg.arg1 == 0) | ||
{ | ||
int localid; | ||
|
||
localid = adb_service_create(d, p->payload, p->msg.arg0); | ||
if (localid) | ||
{ | ||
send_ready(d, localid, p->msg.arg0); | ||
} | ||
else | ||
{ | ||
adb_send_close(d, 0, p->msg.arg0); | ||
} | ||
} | ||
}break; | ||
case A_WRTE: | ||
{ | ||
if (p->msg.arg0 != 0 && p->msg.arg1 != 0) | ||
{ | ||
struct adb_service *ser; | ||
int split = p->split; | ||
|
||
ser = adb_service_find(d, p->msg.arg1, p->msg.arg0); | ||
if (ser) | ||
{ | ||
if (_service_enqueue(ser, p)) | ||
{ | ||
if (split == 0) | ||
send_ready(d, ser->localid, ser->remoteid); | ||
del = false; | ||
} | ||
} | ||
} | ||
}break; | ||
case A_OKAY: | ||
{ | ||
|
||
}break; | ||
case A_CLSE: | ||
{ | ||
if (p->msg.arg1 != 0) | ||
{ | ||
adb_service_destroy(d, p->msg.arg1, p->msg.arg0); | ||
} | ||
}break; | ||
} | ||
|
||
if (del && pisnew) | ||
adb_packet_delete(p); | ||
} | ||
|
||
struct adb* adb_new(int trtype) | ||
{ | ||
struct adb *d; | ||
|
||
d = rt_calloc(sizeof(struct adb), 1); | ||
if (!d) | ||
return d; | ||
|
||
d->tr_type = trtype; | ||
rt_list_init(&d->node); | ||
rt_list_insert_after(&_adb_list, &d->node); | ||
|
||
rt_list_init(&d->s_list); | ||
rt_mb_init(&d->send_que, "adbsque", d->sque_buf, | ||
sizeof(d->sque_buf)/sizeof(d->sque_buf[0]), 0); | ||
|
||
return d; | ||
} | ||
|
||
void adb_delete(struct adb *d) | ||
{ | ||
struct rt_list_node *node, *head; | ||
|
||
rt_list_remove(&d->node); | ||
|
||
head = &d->s_list; | ||
for (node = head->next; node != head; ) | ||
{ | ||
struct adb_service *ser; | ||
struct adb_service_handler *h; | ||
|
||
ser = rt_list_entry(node, struct adb_service, list); | ||
node = node->next; | ||
h = ser->h; | ||
|
||
rt_list_remove(&ser->list); | ||
ser->ops->close(ser); | ||
h->destroy(h, ser); | ||
} | ||
rt_mb_detach(&d->send_que); | ||
rt_free(d); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (c) 2006-2018, RT-Thread Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2018-11-11 heyuanjie87 the first version | ||
*/ | ||
|
||
#ifndef __ADB_H__ | ||
#define __ADB_H__ | ||
|
||
#include <stdbool.h> | ||
#include <adbtypes.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define MAX_PAYLOAD 4*1024 | ||
#define A_VERSION 0x01000000 | ||
|
||
#define A_SYNC 0x434e5953 | ||
#define A_CNXN 0x4e584e43 | ||
#define A_OPEN 0x4e45504f | ||
#define A_OKAY 0x59414b4f | ||
#define A_CLSE 0x45534c43 | ||
#define A_WRTE 0x45545257 | ||
#define A_AUTH 0x48545541 | ||
|
||
struct adb; | ||
struct adb_tr_ops; | ||
struct adb_service; | ||
|
||
struct adb | ||
{ | ||
rt_list_t node; | ||
rt_list_t s_list; | ||
|
||
adb_queue_t send_que; | ||
int sque_buf[8]; | ||
|
||
int tr_type; | ||
int tr_fd; | ||
int tr_refcnt; | ||
rt_thread_t tr_rtid; | ||
rt_thread_t tr_wtid; | ||
const struct adb_tr_ops *ops; | ||
|
||
long user_data; | ||
}; | ||
|
||
struct adb* adb_new(int trtype); | ||
void adb_delete(struct adb* d); | ||
|
||
void adb_send_close(struct adb *d, unsigned local, unsigned remote); | ||
|
||
void adb_packet_handle(struct adb *d, struct adb_packet *p, bool pisnew); | ||
|
||
struct adb_service* adb_service_find(struct adb *d, unsigned localid, unsigned remoteid); | ||
unsigned adb_service_create(struct adb *d, char *name, unsigned remoteid); | ||
void adb_service_destroy(struct adb *d, unsigned localid, unsigned remoteid); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif |
Oops, something went wrong.