Skip to content

Commit

Permalink
ver1.7 with better interface and refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
staskobzar committed Jan 29, 2024
1 parent 0ee0a86 commit f0297d5
Show file tree
Hide file tree
Showing 20 changed files with 1,041 additions and 3,565 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,16 @@ tags
# Persistent undo
[._]*.un~

# emacs
\#*\#
.\#*
# flymake-mode
*_flymake.*
# projectiles files
.projectile

# directory configuration
.dir-locals.el


# End of https://www.gitignore.io/api/go,vim,gcov
14 changes: 0 additions & 14 deletions .travis.yml

This file was deleted.

23 changes: 12 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
# GO AMI v2 protocol implementation
#
.PHONY: test cov bench clean
.PHONY: test cov bench clean parser
all: test
golint

test:
go test -race -cover
dev: test parser

cov:
test: parser
go test -race -cover -timeout=3s

parser:
re2go parse.re -o parse.go -i --no-generation-date

cov: parser
@go test -coverprofile=coverage.out
@go tool cover -html=coverage.out

codecov:
go test -race -coverprofile=coverage.txt -covermode=atomic
bash <(curl -s https://codecov.io/bash) -t f0414e7c-240f-492f-a78c-354bf33321d9

vet:
@go vet -c=2
lint:
golangci-lint run

bench:
@go test -bench=.

readme:
mdr README.md
@go test -benchmem -bench=.

clean:
rm -f coverage.out
Expand Down
244 changes: 34 additions & 210 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,234 +6,58 @@
[![GitHub go.mod Go version of a Go module](https://img.shields.io/github/go-mod/go-version/gomods/athens.svg)](https://github.com/staskobzar/goami2)
[![GitHub release](https://img.shields.io/github/release/staskobzar/goami2.svg)](https://github.com/staskobzar/goami2/releases)

Go library that provides interface to Asteris AMI. The library uses given ```net.Conn``` (tcp or tls), login
and starts reading AMI messages from connection and parse them into ```*Message``` object.
Provides simple interface to send messages to AMI.
It uses ```re2c``` to create very fast protocol parser. Run "make bench" for benchmark tests.

Usage example:

```go
import "github.com/staskobzar/goami2"
//.....more code

import (
"errors"
"fmt"
"log"
"net"

"github.com/staskobzar/goami2"
)

func main() {
conn, err := net.Dial("tcp", "127.0.0.1:5038")
conn, err := net.Dial("tcp", "asterisk.host:5038")
if err != nil {
log.Fatalln(err)
}
client, err := goami2.NewClient(conn, "admin", "secret")

// login and create client
client, err := goami2.NewClient(conn, "admin", "pa55w0rd")
if err != nil {
log.Fatalln(err)
}

chAll := client.AllMessages()
chEvt := client.OnEvent("Newchannel")
log.Println("client connected and logged in")

defer client.Close()
// create AMI Action message and send to the asterisk.host
msg := goami2.NewAction("CoreStatus")
msg.AddActionID()
client.Send(msg.Byte())

defer client.Close() // close connections and all channels
for {
select {
case msg := <-chAll:
case msg := <-client.AllMessages():
log.Printf("Got message: %s\n", msg.JSON())
case msg := <-chEvt:
log.Printf("Got new channel: %s\n", msg.Field("Channel"))
case err := <- client.Error():
client.Close()
log.Fatalf("Connection error: %s", err)
case err := <-client.Err():
// terminate on network closed
if errors.Is(err, goami2.ErrEOF) {
log.Fatalf("Connection error: %s", err)
}
log.Printf("WARNING: AMI client error: %s", err)
}
}
}
```

## Usage

```go
var ErrorConnTOUT = errorNew("Connection timeout")
```
ErrorConnTOUT error on connection timeout

```go
var ErrorInvalidPrompt = errorNew("Invalid prompt on AMI server")
```
ErrorInvalidPrompt invalid prompt received from AMI server

```go
var ErrorLogin = errorNew("Login failed")
```
ErrorLogin AMI server login failed

```go
var ErrorNet = errorNew("Network error")
```
ErrorNet networking errors

```go
var NetTOUT = time.Second * 3
```
NetTOUT timeout for net connections and requests

#### type Client

```go
type Client struct {
}
```

Client structure

#### func NewClient

```go
func NewClient(conn net.Conn, username, password string) (*Client, error)
```
NewClient connects to Asterisk using conn and tries to login using username and
password. Creates new AMI client and returns client or error

#### func (*Client) Action

```go
func (c *Client) Action(msg *Message) bool
```
Action sends AMI message to Asterisk server and returns send-only response
channel on nil

#### func (*Client) AllMessages

```go
func (c *Client) AllMessages() <-chan *Message
```
AllMessages subscribes to any AMI message received from Asterisk server returns
send-only channel or nil

#### func (*Client) Close

```go
func (c *Client) Close()
```
Close client and destroy all subscriptions to events and action responses

#### func (*Client) Err

```go
func (c *Client) Err() <-chan error
```
Err returns channel for error and signals that client should be probably
restarted

#### func (*Client) OnEvent

```go
func (c *Client) OnEvent(name string) <-chan *Message
```
OnEvent subscribes by event by name (case insensitive) and returns send-only
channel or nil

#### type Message

```go
type Message struct {
}
```


#### func FromJSON

```go
func FromJSON(jstr string) (*Message, error)
```
FromJSON creates message from JSON string

#### func NewAction

```go
func NewAction(name string) *Message
```
NewAction creats action message

#### func (*Message) ActionID

```go
func (m *Message) ActionID() string
```
ActionID get AMI message action id as string

#### func (*Message) AddActionID

```go
func (m *Message) AddActionID()
```
AddActionID generate random action id and insert into message

#### func (*Message) AddField

```go
func (m *Message) AddField(key, value string)
```
AddField set new field from pair key: value

#### func (*Message) Bytes

```go
func (m *Message) Bytes() []byte
```
String return AMI message as byte array

#### func (*Message) DelField

```go
func (m *Message) DelField(key string)
```
DelField deletes fields associated with key

#### func (*Message) Field

```go
func (m *Message) Field(key string) string
```
Field returns first value associated with the given key

#### func (*Message) FieldValues

```go
func (m *Message) FieldValues(key string) []string
```
FieldValues returns all values associated with the given key

#### func (*Message) IsEvent

```go
func (m *Message) IsEvent() bool
```
IsEvent returns true if AMI message is Event

#### func (*Message) IsResponse

```go
func (m *Message) IsResponse() bool
```
IsResponse returns true if AMI message is Response

#### func (*Message) IsSuccess

```go
func (m *Message) IsSuccess() bool
```
IsSuccess returns true if AMI message is Response with value success

#### func (*Message) JSON

```go
func (m *Message) JSON() string
```
JSON returns AMI message as JSON string

#### func (*Message) String

```go
func (m *Message) String() string
```
String return AMI message as string

#### func (*Message) Var

```go
func (m *Message) Var(key string) (string, bool)
```
Var search in AMI message fields Variable and ChanVariable for a value of the
type key=value or just key. If found, returns value as string and true. Variable
name is case sensative.
## Docs
See documentation at [https://pkg.go.dev/github.com/staskobzar/goami2](https://pkg.go.dev/github.com/staskobzar/goami2)
Loading

0 comments on commit f0297d5

Please sign in to comment.