at

package
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2023 License: MIT Imports: 7 Imported by: 0

README

at

A low level Go driver for AT modems.

Build Status go.dev reference Coverage Status Go Report Card

The at package provides a low level driver which sits between an io.ReadWriter, representing the physical modem, and a higher level driver or application.

The AT driver provides the ability to issue AT commands to the modem, and to receive the info and status returned by the modem, as synchronous function calls.

Handlers for asynchronous indications from the modem, such as received SMSs, can be registered with the driver.

Features

Supports the following functionality:

  • Simple synchronous interface for AT commands
  • Serialises access to the modem from multiple goroutines
  • Asynchronous indication handling
  • Pluggable serial driver - any io.ReadWriter will suffice

Usage

Construction

The modem is constructed with New:

modem := at.New(ioWR)

Some modem behaviour can be controlled using optional parameters. This example sets the default timeout for AT commands to one second:

modem := at.New(ioWR, at.WithTimeout(time.Second))
Modem Init

The modem can be initialised to a known state using Init:

err := modem.Init()

By default the Init issues the ATZ and ATE0 commands. The set of commands performed can be replaced using the optional WithCmds parameter. This example replaces the ATE0 with AT^CURC=0:

err := modem.Init(at.WithCmds("Z","^CURC=0"))
AT Commands

Issue AT commands to the modem and receive the response using Command:

info, err := modem.Command("I")

This produces the following interaction with the modem (exact results will differ for your modem):

2018/05/17 20:39:56 w: ATI
2018/05/17 20:39:56 r:
Manufacturer: huawei
Model: E173
Revision: 21.017.09.00.314
IMEI: 1234567
+GCAP: +CGSM,+DS,+ES

OK

and returns this info:

info = []string{
    "Manufacturer: huawei",
    "Model: E173",
    "Revision: 21.017.09.00.314",
    "IMEI: 1234567",
    "+GCAP: +CGSM,+DS,+ES",
    }
SMS Commands

SMS commands are a special case as they are a two stage process, with the modem prompting between stages. The SMSCommand performs the two stage handshake with the modem and returns any resulting info. This example sends an SMS with the modem in text mode:

info, err := modem.SMSCommand("+CMGS=\"12345\"", "hello world")
Asynchronous Indications

Handlers can be provided for asynchronous indications using AddIndication. This example provides a handler for +CMT events:

handler := func(info []string) {
    // handle CMT info here
}
err := modem.AddIndication("+CMT:", handler)

The handler can be removed using CancelIndication:

modem.CancelIndication("+CMT:")
Options

A number of the modem methods accept optional parameters. The following table comprises a list of the available options:

Option Method Description
WithTimeout(time.duration) New, Init, Command, SMSCommand Specify the timeout for commands. A value provided to New becomes the default for the other methods.
WithCmds([]string) New, Init Override the set of commands issued by Init.
WithEscTime(time.Duration) New Specifies the minimum period between issuing an escape and a subsequent command.
WithIndication(prefix, handler) New Adds an indication handler at construction time.
WithTrailingLines(int) AddIndication, WithIndication Specifies the number of lines to collect following the indicationline itself.
WithTrailingLine AddIndication, WithIndication Simple case of one trailing line.

Documentation

Overview

Package at provides a low level driver for AT modems.

Index

Constants

View Source
const EscTimeout = 20 * time.Millisecond

Variables

View Source
var (
	// ErrClosed indicates an operation cannot be performed as the modem has
	// been closed.
	ErrClosed = errors.New("closed")

	// ErrDeadlineExceeded indicates the modem failed to complete an operation
	// within the required time.
	ErrDeadlineExceeded = errors.New("deadline exceeded")

	// ErrError indicates the modem returned a generic AT ERROR in response to
	// an operation.
	ErrError = errors.New("ERROR")

	// ErrIndicationExists indicates there is already a indication registered
	// for a prefix.
	ErrIndicationExists = errors.New("indication exists")
)
View Source
var WithTrailingLine = TrailingLinesOption(1)

WithTrailingLine indicates the indication includes one line after the line containing the indication.

Functions

This section is empty.

Types

type AT

type AT struct {
	// contains filtered or unexported fields
}

AT represents a modem that can be managed using AT commands.

Commands can be issued to the modem using the Command and SMSCommand methods.

The AT closes the closed channel when the connection to the underlying modem is broken (Read returns EOF).

When closed, all outstanding commands return ErrClosed and the state of the underlying modem becomes unknown.

Once closed the AT cannot be re-opened - it must be recreated.

func New

func New(modem io.ReadWriter, options ...Option) *AT

New creates a new AT modem.

func (*AT) AddIndication

func (a *AT) AddIndication(prefix string, handler InfoHandler, options ...IndicationOption) (err error)

AddIndication adds a handler for a set of lines beginning with the prefixed line and the following trailing lines.

func (*AT) CancelIndication

func (a *AT) CancelIndication(prefix string)

CancelIndication removes any indication corresponding to the prefix.

If any such indication exists its return channel is closed and no further indications will be sent to it.

func (*AT) Closed

func (a *AT) Closed() <-chan struct{}

Closed returns a channel which will block while the modem is not closed.

func (*AT) Command

func (a *AT) Command(ctx context.Context, cmd string, options ...CommandOption) ([]string, error)

Command issues the command to the modem and returns the result.

The command should NOT include the AT prefix, nor <CR><LF> suffix which is automatically added.

The return value includes the info (the lines returned by the modem between the command and the status line), or an error if the command did not complete successfully.

func (*AT) Escape added in v0.4.0

func (a *AT) Escape(b ...byte)

Escape issues an escape sequence to the modem.

It does not wait for any response, but it does inhibit subsequent commands until the escTime has elapsed.

The escape sequence is "\x1b\r\n". Additional characters may be added to the sequence using the b parameter.

func (*AT) Init

func (a *AT) Init(ctx context.Context, options ...InitOption) error

Init initialises the modem by escaping any outstanding SMS commands and resetting the modem to factory defaults.

The Init is intended to be called after creation and before any other commands are issued in order to get the modem into a known state. It can also be used subsequently to return the modem to a known state.

The default init commands can be overridden by the options parameter.

func (*AT) SMSCommand

func (a *AT) SMSCommand(ctx context.Context, cmd string, sms string, options ...CommandOption) (info []string, err error)

SMSCommand issues an SMS command to the modem, and returns the result.

An SMS command is issued in two steps; first the command line:

AT<command><CR>

which the modem responds to with a ">" prompt, after which the SMS PDU is sent to the modem:

<sms><Ctrl-Z>

The modem then completes the command as per other commands, such as those issued by Command.

The format of the sms may be a text message or a hex coded SMS PDU, depending on the configuration of the modem (text or PDU mode).

type CMEError

type CMEError string

CMEError indicates a CME Error was returned by the modem.

The value is the error value, in string form, which may be the numeric or textual, depending on the modem configuration.

func (CMEError) Error

func (e CMEError) Error() string

type CMSError

type CMSError string

CMSError indicates a CMS Error was returned by the modem.

The value is the error value, in string form, which may be the numeric or textual, depending on the modem configuration.

func (CMSError) Error

func (e CMSError) Error() string

type CmdsOption added in v0.4.0

type CmdsOption []string

CmdsOption specifies the set of AT commands issued by Init.

func WithCmds added in v0.4.0

func WithCmds(cmds ...string) CmdsOption

WithCmds specifies the set of AT commands issued by Init.

The default commands are ATZ.

type CommandOption added in v0.4.0

type CommandOption interface {
	// contains filtered or unexported methods
}

CommandOption defines a behaviouralk option for Command and SMSCommand.

type ConnectError added in v0.4.0

type ConnectError string

ConnectError indicates an attempt to dial failed.

The value of the error is the failure indication returned by the modem.

func (ConnectError) Error added in v0.4.0

func (e ConnectError) Error() string

type CustomParseRxLineOption added in v0.5.8

type CustomParseRxLineOption ParseRxLineFunc

type EscTimeOption added in v0.4.0

type EscTimeOption time.Duration

EscTimeOption defines the escape guard time for the modem.

func WithEscTime added in v0.4.0

func WithEscTime(d time.Duration) EscTimeOption

WithEscTime sets the guard time for the modem.

The escape time is the minimum time between an escape command being sent to the modem and any subsequent commands.

The default guard time is 20msec.

type Indication added in v0.4.0

type Indication struct {
	// contains filtered or unexported fields
}

Indication represents an unsolicited result code (URC) from the modem, such as a received SMS message.

Indications are lines prefixed with a particular pattern, and may include a number of trailing lines. The matching lines are bundled into a slice and sent to the handler.

func WithIndication added in v0.4.0

func WithIndication(prefix string, handler InfoHandler, options ...IndicationOption) Indication

WithIndication adds an indication during construction.

type IndicationOption added in v0.4.0

type IndicationOption interface {
	// contains filtered or unexported methods
}

IndicationOption alters the behavior of the indication.

type InfoHandler added in v0.4.0

type InfoHandler func([]string)

InfoHandler receives indication info.

type InitOption added in v0.4.0

type InitOption interface {
	// contains filtered or unexported methods
}

InitOption defines a behaviouralk option for Init.

type NoModifyOption added in v0.5.8

type NoModifyOption bool

NoModifyOption specifies that the command should not be appended with "AT" prefix and "\r\n" suffix and must be issued as is.

type Option added in v0.4.0

type Option interface {
	// contains filtered or unexported methods
}

Option is a construction option for an AT.

type ParseRxLineFunc added in v0.5.8

type ParseRxLineFunc func(line string, cmdID string) Rxl

type Rxl added in v0.5.8

type Rxl int

Received line types.

const (
	RxlUnknown Rxl = iota
	RxlEchoCmdLine
	RxlInfo
	RxlStatusOK
	RxlStatusError
	RxlAsync
	RxlSMSPrompt
	RxlConnect
	RxlConnectError
	RxlSkip
)

type TimeoutOption added in v0.4.0

type TimeoutOption time.Duration

TimeoutOption specifies the maximum time allowed for the modem to complete a command.

func WithTimeout added in v0.4.0

func WithTimeout(d time.Duration) TimeoutOption

WithTimeout specifies the maximum time allowed for the modem to complete a command.

type TrailingLinesOption added in v0.4.0

type TrailingLinesOption int

TrailingLinesOption specifies the number of trailing lines expected after an indication line.

func WithTrailingLines added in v0.4.0

func WithTrailingLines(l int) TrailingLinesOption

WithTrailingLines indicates the number of lines after the line containing the indication that arew to be collected as part of the indication.

The default is 0 - only the indication line itself is collected and returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL