huawei-dongle-api

Crates.iohuawei-dongle-api
lib.rshuawei-dongle-api
version0.2.1
created_at2025-07-04 15:54:45.587052+00
updated_at2025-08-22 16:57:50.999797+00
descriptionAsync Rust library for interacting with Huawei LTE dongles
homepagehttps://github.com/Narf-AI/huawei-lte-api
repositoryhttps://github.com/Narf-AI/huawei-lte-api
max_upload_size
id1738168
size216,475
Paweł Kobojek (pawelkobojek)

documentation

README

huawei-dongle-api

Documentation

A robust async Rust client library for interacting with Huawei LTE dongles and routers.

This library provides a type-safe, async interface to the XML-based API used by Huawei HiLink devices such as the E3372, E5577, B525 and many others. It handles authentication, session management, and CSRF token rotation automatically.

Features

  • Async/await - Built on tokio for efficient async I/O
  • Automatic retry - Configurable retry logic with exponential backoff
  • Session management - Automatic CSRF token handling and refresh
  • Type safety - Strongly typed requests and responses with enums
  • Error handling - Comprehensive error types with automatic recovery
  • Device compatibility - Handles quirks across different firmware versions
  • Strong types - Enums for all API values (connection status, network types, etc.)

Installation

Add this to your Cargo.toml:

[dependencies]
huawei-dongle-api = "0.2"
tokio = { version = "1", features = ["full"] }

Quick Start

use huawei_dongle_api::{Client, Config};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client with default config
    let client = Client::new(Config::default())?;
    
    // Get device information (no auth required)
    let device_info = client.device().information().await?;
    println!("Device: {}", device_info.device_name);
    
    // Check connection status (auth handled automatically)
    let status = client.monitoring().status().await?;
    println!("Connected: {}", status.is_connected());
    
    Ok(())
}

Configuration

The client can be configured with custom settings:

use huawei_dongle_api::{Client, Config};
use std::time::Duration;

let config = Config::builder()
    .base_url("http://192.168.8.1")
    .timeout(Duration::from_secs(30))
    .max_retries(5)
    .retry_delay(Duration::from_millis(500))
    .build()?;
    
let client = Client::new(config)?;

Authentication

Most endpoints require authentication. The library handles this automatically, retrying with fresh tokens when needed:

// Login (only needed for password-protected operations)
client.auth().login("admin", "password").await?;

// Access protected endpoints
use huawei_dongle_api::models::{SmsListRequest, SmsBoxType, SmsSortType};
let request = SmsListRequest::new(1, 20, SmsBoxType::LocalInbox, SmsSortType::ByTime, false, true);
let sms_list = client.sms().list(&request).await?;

// Logout when done
client.auth().logout().await?;

Examples

Monitoring Connection Status

let status = client.monitoring().status().await?;

println!("Connection: {}", status.connection_status_text());
println!("Network: {}", status.network_type_text());
println!("Signal: {}/5", status.signal_level().unwrap_or(0));

if status.is_connected() {
    println!("Connected to {}", status.operator_name().unwrap_or("Unknown"));
}

SMS Management

use huawei_dongle_api::models::{SmsListRequest, SmsBoxType, SmsSortType};

// Get SMS count
let count = client.sms().count().await?;
println!("Unread messages: {}", count.total_unread().unwrap_or(0));

// List messages
let request = SmsListRequest::new(
    1,                        // page
    20,                       // count per page
    SmsBoxType::LocalInbox,   // inbox
    SmsSortType::ByTime,      // sort by date
    false,                    // descending
    true,                     // unread first
);

let messages = client.sms().list(&request).await?;
for msg in &messages.messages.messages {
    println!("From: {} - {}", msg.phone, msg.content);
}

// Delete a message
client.sms().delete("40001").await?;

Network Configuration

// Get current network mode
let net_mode = client.network().get_mode().await?;
println!("Network mode: {}", net_mode.mode_text());

// Switch network mode (for IP rotation)
use huawei_dongle_api::models::network::NetworkModeRequest;

let request = NetworkModeRequest::lte_only();
client.network().set_mode(&request).await?;

DHCP Configuration

// Get current DHCP settings
let settings = client.dhcp().settings().await?;
println!("Gateway IP: {}", settings.dhcp_ip_address);

// Change gateway IP
use huawei_dongle_api::models::dhcp::DhcpSettingsRequest;
use huawei_dongle_api::models::{DhcpStatus, DnsStatus};

let new_settings = DhcpSettingsRequest::new(
    "192.168.62.1".to_string(),      // new gateway IP
    "255.255.255.0".to_string(),     // netmask
    DhcpStatus::Enabled,              // DHCP enabled
    "192.168.62.100".to_string(),    // start IP
    "192.168.62.200".to_string(),    // end IP
    "86400".to_string(),              // lease time (seconds)
    DnsStatus::Enabled,               // DNS enabled
    "192.168.62.1".to_string(),      // primary DNS
    "192.168.62.1".to_string(),      // secondary DNS
);

client.dhcp().set_settings(&new_settings).await?;

Error Handling

The library provides comprehensive error handling with automatic recovery:

match client.monitoring().status().await {
    Ok(status) => println!("Connected: {}", status.is_connected()),
    Err(huawei_dongle_api::Error::CsrfTokenInvalid) => {
        // This is handled automatically with retry
        println!("Token error (handled automatically)");
    }
    Err(huawei_dongle_api::Error::LoginRequired) => {
        println!("Need to login first");
    }
    Err(e) => println!("Error: {}", e),
}

Supported Devices

This library has been tested with:

  • Huawei E3372h-320
  • Huawei E5577
  • Huawei B525

It should work with any Huawei HiLink device that uses the same XML API.

Thread Safety

The client is thread-safe and can be shared across multiple tasks:

use std::sync::Arc;

let client = Arc::new(Client::new(Config::default())?);

let client2 = client.clone();
tokio::spawn(async move {
    let status = client2.monitoring().status().await;
});

Used In Production

This library powers the mobile proxy infrastructure at Scraping Fish API, a high-performance web scraping API service.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 3

cargo fmt