at_commands/lowlevel/response.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! This module contains an AST for AT command responses.
//!
//! The format of these is not specifed in any one place in the spec, but they are
//! described thoughout HFP 1.8.
use crate::lowlevel::arguments;
use crate::lowlevel::write_to::WriteTo;
use std::io;
/// Responses and indications.
#[derive(Debug, Clone, PartialEq)]
pub enum Response {
/// The success indication. Its format is described in HFP v1.8 Section 4.34.1, and it is
/// used throughout the spec.
Ok,
/// The error indication. Its format is described in HFP v1.8 Section 4.34.1, and it is
/// used throughout the spec.
Error,
/// A set of hardcoded specific error indications. They are described in HFP v1.8 Section 4.34.2.
HardcodedError(HardcodedError),
/// Error codes used with the +CME ERROR indication. Described in HFP v1.8 4.34.2
CmeError(i64),
/// All other non-error responses. These are described throughout the HFP v1.8 spec.
Success { name: String, is_extension: bool, arguments: arguments::DelimitedArguments },
/// Raw bytes to use as a response. Should only be used for testing and development
RawBytes(Vec<u8>),
}
impl WriteTo for Response {
fn write_to<W: io::Write>(&self, sink: &mut W) -> io::Result<()> {
// Responses are delimited on both sides by CRLF.
sink.write_all(b"\r\n")?;
match self {
Response::Ok => sink.write_all(b"OK")?,
Response::Error => sink.write_all(b"ERROR")?,
Response::HardcodedError(error) => error.write_to(sink)?,
Response::CmeError(error_code) => {
sink.write_all(b"+CME ERROR: ")?;
sink.write_all(error_code.to_string().as_bytes())?;
}
Response::Success { name, is_extension, arguments } => {
if *is_extension {
sink.write_all(b"+")?
}
sink.write_all(name.as_bytes())?;
arguments.write_to(sink)?;
}
Response::RawBytes(bytes) => sink.write_all(bytes)?,
};
// Responses are delimited on both sides by CRLF.
sink.write_all(b"\r\n")
}
}
// Hardecoded error indications described in HFP v1.8 Section 4.34.2
#[derive(Debug, Clone, PartialEq)]
pub enum HardcodedError {
NoCarrier,
Busy,
NoAnswer,
Delayed,
Blacklist,
}
impl WriteTo for HardcodedError {
fn write_to<W: io::Write>(&self, sink: &mut W) -> io::Result<()> {
match self {
HardcodedError::NoCarrier => sink.write_all(b"NO CARRIER"),
HardcodedError::Busy => sink.write_all(b"BUSY"),
HardcodedError::NoAnswer => sink.write_all(b"NO ANSWER"),
HardcodedError::Delayed => sink.write_all(b"DELAYED"),
HardcodedError::Blacklist => sink.write_all(b"BLACKLIST"),
}
}
}