at_commands/lowlevel/
response.rs

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