Skip to content

Commit

Permalink
发布第一个测试版
Browse files Browse the repository at this point in the history
  • Loading branch information
heyuanjie87 committed Nov 29, 2018
0 parents commit 2261f89
Show file tree
Hide file tree
Showing 19 changed files with 3,161 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
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)
18 changes: 18 additions & 0 deletions SConscript
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')
218 changes: 218 additions & 0 deletions core/adb.c
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);
}
68 changes: 68 additions & 0 deletions core/adb.h
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
Loading

0 comments on commit 2261f89

Please sign in to comment.