# HDC-RS
[](https://crates.io/crates/hdc-rs)
[](https://docs.rs/hdc-rs)
[](LICENSE-MIT)
[](https://www.rust-lang.org)
A pure Rust implementation of the **HarmonyOS Device Connector (HDC)** client library, providing both async and blocking APIs for interacting with HarmonyOS/OpenHarmony devices.
> **Note:** HDC is to HarmonyOS what ADB is to Android - a bridge for device communication, debugging, and development.
---
## β¨ Features
- π **Async/await** - Built on Tokio for efficient async I/O
- π **Blocking API** - Synchronous wrapper for FFI bindings (PyO3, JNI, etc.)
- π± **Device Management** - List, connect, and monitor devices
- π» **Shell Commands** - Execute commands on devices with full output
- π **Port Forwarding** - TCP, Unix sockets, JDWP, and Ark debugger support
- π¦ **App Management** - Install/uninstall HAP and HSP packages
- π **File Transfer** - Efficient bidirectional file transfer with compression
- π **Device Monitoring** - Real-time device connection/disconnection events
- π **Log Streaming** - Continuous or buffered hilog reading
- π‘οΈ **Type-safe API** - Rust's type system ensures correctness
- β‘ **Zero-copy** - Efficient data handling with `bytes` crate
- π― **Error Handling** - Comprehensive error types with context
## π Table of Contents
- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Examples](#-examples)
- [API Documentation](#-api-documentation)
- [Architecture](#οΈ-architecture)
- [Protocol Details](#-protocol-details)
- [Python Bindings](#-python-bindings)
- [API Reference](#-api-reference)
- [Development](#-development)
- [Troubleshooting](#-troubleshooting)
- [Performance](#-performance)
- [Roadmap](#οΈ-roadmap)
- [Contributing](#-contributing)
- [License](#-license)
- [Resources](#-resources)
## π§ Installation
### Prerequisites
- Rust 1.70 or later
- HDC server must be installed and running
- A HarmonyOS/OpenHarmony device connected via USB or network
### Add to Your Project
Add this to your `Cargo.toml`:
```toml
[dependencies]
hdc-rs = "0.1"
tokio = { version = "1", features = ["full"] }
```
### Feature Flags
- `blocking` - Enable synchronous/blocking API for FFI bindings
```toml
[dependencies]
hdc-rs = { version = "0.1", features = ["blocking"] }
```
## π Quick Start
### Async API (Recommended)
```rust
use hdc_rs::HdcClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to HDC server
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
// List connected devices
let devices = client.list_targets().await?;
println!("Devices: {:?}", devices);
if devices.is_empty() {
println!("No devices connected!");
return Ok(());
}
// Select and connect to first device
client.connect_device(&devices[0]).await?;
println!("Connected to device: {}", devices[0]);
// Execute shell command on the selected device
let output = client.shell("ls -l /data").await?;
println!("Output:\n{}", output);
Ok(())
}
```
### Blocking API (for FFI/PyO3)
Enable the `blocking` feature for synchronous API:
```toml
[dependencies]
hdc-rs = { version = "0.1", features = ["blocking"] }
```
```rust
use hdc_rs::blocking::HdcClient;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to HDC server (synchronous!)
let mut client = HdcClient::connect("127.0.0.1:8710")?;
// List connected devices
let devices = client.list_targets()?;
println!("Devices: {:?}", devices);
if !devices.is_empty() {
// Connect and execute command
client.connect_device(&devices[0])?;
let output = client.shell("uname -a")?;
println!("Output: {}", output);
}
Ok(())
}
```
## π Examples
The repository includes several examples demonstrating different features:
| `list_devices` | List all connected devices | `cargo run --example list_devices` |
| `simple_shell` | Interactive shell session | `cargo run --example simple_shell` |
| `blocking_demo` | Synchronous API demo | `cargo run --example blocking_demo --features blocking` |
| `device_monitor` | Monitor device connections | `cargo run --example device_monitor` |
| `file_demo` | File transfer operations | `cargo run --example file_demo` |
| `forward_demo` | Port forwarding setup | `cargo run --example forward_demo` |
| `app_demo` | App install/uninstall | `cargo run --example app_demo` |
| `hilog_demo` | Device log streaming | `cargo run --example hilog_demo` |
| `comprehensive` | All features combined | `cargo run --example comprehensive` |
### Running Examples
```bash
# List all connected devices
cargo run --example list_devices
# Blocking API demo (synchronous)
cargo run --example blocking_demo --features blocking
# Monitor device connections/disconnections
cargo run --example device_monitor
# Interactive shell
cargo run --example simple_shell
# File transfer demo
cargo run --example file_demo
# Port forwarding demo
cargo run --example forward_demo
# App installation demo
cargo run --example app_demo
# Hilog (device logs) demo
cargo run --example hilog_demo
# Comprehensive example (all features)
cargo run --example comprehensive
# Enable debug logging for troubleshooting
RUST_LOG=hdc_rs=debug cargo run --example list_devices
```
## π API Documentation
For detailed API documentation, visit [docs.rs/hdc-rs](https://docs.rs/hdc-rs).
### Core Types
- **`HdcClient`** - Main async client for HDC communication
- **`blocking::HdcClient`** - Synchronous wrapper for FFI bindings
- **`HdcError`** - Comprehensive error type with context
- **`ForwardNode`** - Port forwarding endpoint specification
- **`InstallOptions`** / **`UninstallOptions`** - App management options
- **`FileTransferOptions`** - File transfer configuration
## ποΈ Architecture
### System Overview
```
βββββββββββββββββββ
β Your App β βββ Your Rust application
ββββββββββ¬βββββββββ
β (uses hdc-rs API)
βΌ
βββββββββββββββββββ
β hdc-rs β βββ This library (Rust)
β βββββββββββββ β
β β Client β β - Connection management
β β Protocol β β - Packet codec
β β Commands β β - Error handling
β βββββββββββββ β
ββββββββββ¬βββββββββ
β (TCP socket: 127.0.0.1:8710)
βΌ
βββββββββββββββββββ
β HDC Server β βββ Native HDC daemon
β (daemon) β
ββββββββββ¬βββββββββ
β (USB/TCP connection)
βΌ
βββββββββββββββββββ
β HarmonyOS β βββ Target device
β Device β
βββββββββββββββββββ
```
### Project Structure
```
hdc-rs/
βββ hdc-rs/ # Core Rust library
β βββ src/
β β βββ lib.rs # Public API
β β βββ client.rs # HdcClient implementation
β β βββ blocking.rs # Synchronous wrapper
β β βββ error.rs # Error types
β β βββ app.rs # App management
β β βββ file.rs # File transfer
β β βββ forward.rs # Port forwarding
β β βββ protocol/ # Protocol implementation
β β βββ packet.rs # Packet codec
β β βββ command.rs # Command builders
β β βββ channel.rs # Channel management
β βββ Cargo.toml
βββ hdc-py/ # Python bindings (PyO3)
β βββ src/lib.rs
β βββ Cargo.toml
βββ examples/ # Usage examples
βββ tests/ # Integration tests
```
## π Protocol Details
### Packet Format
HDC uses a simple length-prefixed binary protocol over TCP:
```
ββββββββββββββββββββββββββββββββ
β 4 bytes: Payload Length β (Big-endian u32)
ββββββββββββββββββββββββββββββββ€
β N bytes: Payload Data β (Command + Arguments)
ββββββββββββββββββββββββββββββββ
```
### Connection Lifecycle
```
Client Server
β β
βββββ TCP Connect ββββββββββββββ>β
β β
β<ββββ Handshake (Channel ID) ββββ€
β β
βββββ Connect Key ββββββββββββββ>β
β β
β<ββββ OK βββββββββββββββββββββββββ€
β β
βββββ Command ββββββββββββββββββ>β
β β
β<ββββ Response βββββββββββββββββββ€
β β
βββββ Close ββββββββββββββββββββ>β
β β
```
### Supported Commands
| `list targets` | List connected devices | β
Implemented |
| `checkserver` | Get server version | β
Implemented |
| `tmode port <port>` | Connect device over TCP | β
Implemented |
| `shell <cmd>` | Execute shell command | β
Implemented |
| `file send <local> <remote>` | Upload file | β
Implemented |
| `file recv <remote> <local>` | Download file | β
Implemented |
| `fport <local> <remote>` | Forward port | β
Implemented |
| `rport <remote> <local>` | Reverse forward | β
Implemented |
| `install <path>` | Install app | β
Implemented |
| `uninstall <pkg>` | Uninstall app | β
Implemented |
| `hilog` | Stream device logs | β
Implemented |
| `wait-for-device` | Wait for device | β
Implemented |
## π Python Bindings
This project includes Python bindings built with PyO3. See [`hdc-py/README.md`](hdc-py/README.md) for complete documentation.
### Quick Example
```python
from hdc_rs import HdcClient
# Connect and list devices
client = HdcClient("127.0.0.1:8710")
devices = client.list_targets()
print(f"Devices: {devices}")
if devices:
# Execute command
client.connect_device(devices[0])
output = client.shell("uname -a")
print(output)
```
### Installation
```bash
cd hdc-py
pip install maturin
maturin develop # Development mode
# or
maturin build --release # Build wheel
pip install target/wheels/hdc_rs-*.whl
```
## π API Reference
### HdcClient
Main client for HDC communication.
#### Connection Methods
- `connect(address)` - Connect to HDC server
- `close()` - Close connection
- `is_connected()` - Check if connected
#### Device Management
- `list_targets()` - List all connected devices
- `connect_device(device_id)` - Select a device for subsequent commands
- `check_server()` - Get server version
- `wait_for_device()` - Block until a device is connected
- `monitor_devices(interval, callback)` - Monitor device list changes with polling
- `interval`: Polling interval (e.g., `Duration::from_secs(2)`)
- `callback`: Function called when device list changes, return `false` to stop
#### Command Execution
- `shell(cmd)` - Execute shell command on the currently selected device
- **Important**: Must call `connect_device()` first, or server will return error
- `shell_on_device(device_id, cmd)` - Execute shell command on specific device
- `target_command(device_id, cmd)` - Execute any command on specific device
#### Port Forwarding
- `fport(local, remote)` - Forward local traffic to remote device
- Example: `fport(ForwardNode::Tcp(8080), ForwardNode::Tcp(8081))`
- `rport(remote, local)` - Reverse forward remote traffic to local host
- Example: `rport(ForwardNode::Tcp(9090), ForwardNode::Tcp(9091))`
- `fport_list()` - List all active forward/reverse tasks
- `fport_remove(task_str)` - Remove a forward task by task string
- Example: `fport_remove("tcp:8080 tcp:8081")`
**Forward Node Types:**
- `ForwardNode::Tcp(port)` - TCP port
- `ForwardNode::LocalFilesystem(path)` - Unix domain socket (filesystem)
- `ForwardNode::LocalReserved(name)` - Unix domain socket (reserved)
- `ForwardNode::LocalAbstract(name)` - Unix domain socket (abstract)
- `ForwardNode::Dev(name)` - Device
- `ForwardNode::Jdwp(pid)` - JDWP (Java Debug Wire Protocol, remote only)
- `ForwardNode::Ark { pid, tid, debugger }` - Ark debugger (remote only)
#### App Management
- `install(paths, options)` - Install application package(s)
- `paths`: Single or multiple `.hap`/`.hsp` files or directories
- `options`: `InstallOptions::new().replace(true).shared(false)`
- `replace`: Replace existing application
- `shared`: Install shared bundle for multi-apps
- `uninstall(package, options)` - Uninstall application package
- `package`: Package name (e.g., `"com.example.app"`)
- `options`: `UninstallOptions::new().keep_data(true).shared(false)`
- `keep_data`: Keep the data and cache directories
- `shared`: Remove shared bundle
#### Log Management
- `hilog(args)` - Read device logs (buffered mode)
- `args`: Optional hilog arguments (e.g., `"-h"` for help, `"-t app"` for app logs)
- Returns all logs as a string after timeout
- `hilog_stream(args, callback)` - Streaming hilog to given callback
#### File Transfer
- `file_send(local, remote, options)` - Send file to device
- `local`: Local file path
- `remote`: Remote device path
- `options`: `FileTransferOptions` - configure transfer behavior
- `file_recv(remote, local, options)` - Receive file from device
- `remote`: Remote device path
- `local`: Local file path
- `options`: `FileTransferOptions` - configure transfer behavior
**File Transfer Options:**
- `hold_timestamp(bool)` - Preserve file timestamps (`-a`)
- `sync_mode(bool)` - Only update if source is newer (`-sync`)
- `compress(bool)` - Compress during transfer (`-z`)
- `mode_sync(bool)` - Sync file permissions (`-m`)
- `debug_dir(bool)` - Transfer to/from debug app directory (`-b`)am device logs continuously
- `args`: Optional hilog arguments
- `callback`: Function called for each log chunk, return `false` to stop streaming
- Useful for real-time log monitoring
### Usage Pattern
**Option 1: Select device first (Recommended)**
```rust
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
// Connect to device - this re-establishes connection with device ID in handshake
client.connect_device(&devices[0]).await?;
// Now shell commands will be routed to the selected device
let output = client.shell("ls /data").await?;
```
**Option 2: Specify device per command**
```rust
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
// Execute on specific device without selecting
let output = client.shell_on_device(&devices[0], "ls /data").await?;
```
**Option 3: Port forwarding**
```rust
use hdc_rs::{HdcClient, ForwardNode};
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
client.connect_device(&devices[0]).await?;
// Forward local TCP 8080 to device TCP 8081
client.fport(ForwardNode::Tcp(8080), ForwardNode::Tcp(8081)).await?;
// List all forwards
let tasks = client.fport_list().await?;
for task in tasks {
println!("Forward: {}", task);
}
// Remove forward
client.fport_remove("tcp:8080 tcp:8081").await?;
```
**Option 4: App management**
```rust
use hdc_rs::{HdcClient, InstallOptions, UninstallOptions};
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
client.connect_device(&devices[0]).await?;
// Install app (replace if exists)
let opts = InstallOptions::new().replace(true);
client.install(&["app.hap"], opts).await?;
// Uninstall app (keep data)
let opts = UninstallOptions::new().keep_data(true);
client.uninstall("com.example.app", opts).await?;
```
**Option 5: Device logs (hilog)**
```rust
use hdc_rs::HdcClient;
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
client.connect_device(&devices[0]).await?;
// Get logs as buffered string
let logs = client.hilog(Some("-t app")).await?;
println!("App logs:\n{}", logs);
// Stream logs continuously
**Option 6: Monitor device connections**
```rust
use hdc_rs::HdcClient;
use std::time::Duration;
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
// Wait for any device to connect (blocks until a device is available)
let device = client.wait_for_device().await?;
println!("Device connected: {}", device);
// Monitor device list changes in real-time
for device in devices {
println!(" - {}", device);
}
true // Continue monitoring, return false to stop
}).await?;
```
**Option 7: File transfer**
```rust
use hdc_rs::{HdcClient, FileTransferOptions};
let mut client = HdcClient::connect("127.0.0.1:8710").await?;
let devices = client.list_targets().await?;
client.connect_device(&devices[0]).await?;
// Send file to device with options
let opts = FileTransferOptions::new()
.hold_timestamp(true) // Preserve timestamp
.compress(true); // Compress transfer
client.file_send("local.txt", "/data/local/tmp/remote.txt", opts).await?;
// Receive file from device
let opts = FileTransferOptions::new().sync_mode(true);
client.file_recv("/data/local/tmp/remote.txt", "local.txt", opts).await?;
``` print!("{}", log_chunk);
true // Continue streaming, return false to stop
}).await?;
```
### Error Handling
All methods return `Result<T, HdcError>`. The library provides comprehensive error types:
```rust
use hdc_rs::{HdcClient, HdcError};
match client.shell("ls").await {
Ok(output) => println!("{}", output),
Err(HdcError::NotConnected) => eprintln!("Not connected to HDC server!"),
Err(HdcError::Timeout) => eprintln!("Command timeout!"),
Err(HdcError::DeviceNotFound) => eprintln!("Device not found!"),
Err(HdcError::ProtocolError(msg)) => eprintln!("Protocol error: {}", msg),
Err(e) => eprintln!("Error: {}", e),
}
```
**Available Error Types:**
- `NotConnected` - Not connected to HDC server
- `Timeout` - Operation timeout
- `DeviceNotFound` - Target device not found
- `ProtocolError` - Protocol-level error
- `IoError` - I/O error (network, file, etc.)
- `InvalidResponse` - Invalid server response
- `CommandFailed` - Command execution failed
## π» Development
```
βββββββββββββββββββββββ
β 4 bytes: length β (big-endian u32)
βββββββββββββββββββββββ€
β N bytes: data β
βββββββββββββββββββββββ
```
### Channel Handshake
1. Client connects to server
2. Server sends handshake with channel ID
3. Client responds with connect key
4. Connection established
## Current Status
### Implemented β
- TCP connection management
- Packet codec (length-prefixed protocol)
- Channel handshake
- Basic commands: `list targets`, `shell`, `checkserver`
- Error handling
- Async/await support
### Planned π§
- File transfer (`file send`, `file recv`)
- Port forwarding (`fport`, `rport`)
- App install/uninstall
- USB connection support
- Encryption (TLS-PSK)
## Development
### Prerequisites
- Rust 1.70 or later
- HDC server installed (from HarmonyOS SDK or OpenHarmony)
- A HarmonyOS/OpenHarmony device or emulator
### Building from Source
```bash
# Clone the repository
git clone https://github.com/oslo254804746/hdc-rs.git
cd hdc-rs
# Build the project
cargo build
# Build with release optimizations
cargo build --release
# Build with all features
cargo build --all-features
```
### Running Tests
```bash
# Run all tests
cargo test
# Run integration tests (requires HDC server running)
cargo test --test integration_test
# Run specific test
cargo test test_name
```
### Enable Debug Logging
Set the `RUST_LOG` environment variable for detailed logging:
```bash
# Linux/macOS
RUST_LOG=hdc_rs=debug cargo run --example list_devices
# Windows PowerShell
$env:RUST_LOG="hdc_rs=debug"; cargo run --example list_devices
# Windows CMD
set RUST_LOG=hdc_rs=debug && cargo run --example list_devices
```
### Code Quality
```bash
# Format code
cargo fmt
# Lint with Clippy
cargo clippy -- -D warnings
# Check without building
cargo check
```
### Documentation
```bash
# Generate and open documentation
cargo doc --open
# Generate documentation for all features
cargo doc --all-features --no-deps --open
```
## π Troubleshooting
### Common Issues
#### "No devices found"
**Solution:**
- Ensure HDC server is running: `hdc start`
- Check device connection: `hdc list targets`
- Verify device is authorized (check device screen for authorization prompt)
- For network devices: `hdc tconn <device_ip>:5555`
#### Connection timeout
**Symptoms:** `HdcError::Timeout` or connection hangs
**Solution:**
- Check if HDC server is listening on port 8710:
- Windows: `netstat -ano | findstr 8710`
- Linux/macOS: `netstat -an | grep 8710` or `lsof -i :8710`
- Restart HDC server: `hdc kill` then `hdc start`
- Check firewall settings
#### Protocol errors
**Symptoms:** `HdcError::ProtocolError` or unexpected responses
**Solution:**
- Ensure HDC server version compatibility (tested with 3.2.0+)
- Check server version: `hdc version` or `client.check_server().await?`
- Update HDC server to the latest version
- Enable debug logging to inspect protocol messages
#### File transfer fails
**Symptoms:** `HdcError::IoError` during file operations
**Solution:**
- Verify file paths are correct
- Check device storage permissions
- Ensure target directory exists on device
- For large files, increase timeout or use compression
#### "Device not authorized"
**Solution:**
- Check device for authorization dialog
- Revoke and re-authorize: `hdc kill-server` then reconnect device
- Check device developer options are enabled
### Debug Tips
1. **Enable verbose logging:**
```bash
RUST_LOG=hdc_rs=trace cargo run --example your_example
```
2. **Use the comprehensive example:**
```bash
cargo run --example comprehensive
```
3. **Check HDC server logs:**
- Server logs are typically in the HDC installation directory
- Use `hdc -l 5` for verbose HDC logging
4. **Test with official HDC client:**
```bash
hdc list targets
hdc shell ls /data
```
If the official client works but hdc-rs doesn't, please file an issue.
## π Performance
- **Zero-copy parsing** with `bytes` crate
- **Async I/O** with Tokio for efficient concurrency
- **Connection pooling** support (reuse connections)
- **Streaming support** for large file transfers and log streaming
### Benchmarks
Typical performance on a modern system:
- Device listing: ~10-50ms
- Shell command: ~20-100ms (depends on command)
- File transfer: ~10-50 MB/s (depends on USB/network speed and device)
## πΊοΈ Roadmap
### Current Status (v0.1.0)
- β
TCP connection management
- β
Async/await API
- β
Blocking API for FFI
- β
Device management (list, connect, monitor)
- β
Shell command execution
- β
File transfer (send/recv)
- β
Port forwarding (TCP, Unix sockets, JDWP, Ark)
- β
App management (install/uninstall)
- β
Log streaming (hilog)
- β
Python bindings (PyO3)
## π€ Contributing
Contributions are welcome! Here's how you can help:
### Ways to Contribute
- π **Report bugs** - Open an issue with reproduction steps
- π‘ **Suggest features** - Share your ideas for improvements
- π **Improve documentation** - Fix typos, add examples, clarify usage
- π§ **Submit pull requests** - Fix bugs or implement new features
- β **Star the project** - Show your support!
### Development Workflow
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Run tests (`cargo test`)
5. Run formatting (`cargo fmt`)
6. Run linting (`cargo clippy`)
7. Commit your changes (`git commit -m 'Add amazing feature'`)
8. Push to the branch (`git push origin feature/amazing-feature`)
9. Open a Pull Request
### Code Guidelines
- Follow Rust naming conventions and idioms
- Add tests for new functionality
- Update documentation for API changes
- Keep commits atomic and well-described
- Ensure all CI checks pass
### Testing
```bash
# Run all tests
cargo test
# Run specific test suite
cargo test --lib
cargo test --test integration_test
# Run with verbose output
cargo test -- --nocapture
```
## π License
This project is dual-licensed under:
- **MIT License** ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
- **Apache License 2.0** ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
You may choose either license for your use.
## π Acknowledgments
- HarmonyOS/OpenHarmony development tools team for HDC
- Tokio project for excellent async runtime
- PyO3 project for Rust-Python bindings
- Rust community for amazing tools and libraries
## π Resources
### Official Documentation
- [HDC Official Docs](https://gitee.com/openharmony/developtools_hdc)
- [HarmonyOS Developer Portal](https://developer.harmonyos.com/)
- [OpenHarmony Documentation](https://docs.openharmony.cn/)
### Related Projects
- [hdc-rs on crates.io](https://crates.io/crates/hdc-rs)
- [hdc-rs documentation](https://docs.rs/hdc-rs)
- [GitHub Repository](https://github.com/oslo254804746/hdc-rs)
### Community
- Report issues: [GitHub Issues](https://github.com/oslo254804746/hdc-rs/issues)
- Discussions: [GitHub Discussions](https://github.com/oslo254804746/hdc-rs/discussions)
## π Project Status



**Version:** 0.1.0
**Status:** Active Development
**Stability:** Beta
---
Made with β€οΈ by the HDC-RS contributors