aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-10-09 19:41:46 +0200
committerDimitri Sokolyuk <demon@dim13.org>2015-10-09 19:41:46 +0200
commit3479b3dbacceeb2fdc7591bdb150c10e31299ba4 (patch)
tree8ed0cb7990755c0eda55f4fd07ad189f7ae30dcc
parent5da3820c360e34ef8e7c6b4757783e9514f72f71 (diff)
First real communication
-rw-r--r--acse/acse.go21
-rw-r--r--csta/system-status.go2
-rw-r--r--kxtde/main.go79
-rw-r--r--parse/packets.go18
-rw-r--r--parse/parse.go37
-rw-r--r--rose/rose.go34
6 files changed, 174 insertions, 17 deletions
diff --git a/acse/acse.go b/acse/acse.go
index 2552710..5fb1786 100644
--- a/acse/acse.go
+++ b/acse/acse.go
@@ -46,6 +46,12 @@ type RLRE struct {
asn1.Tag `asn1:"application,tag:3"`
}
+// ABRT Source
+const (
+ ABRTServiceUser = iota
+ ABRTServiceProvider
+)
+
// A-ABORT
// Application Constructed implicit 4
type ABRT struct {
@@ -89,3 +95,18 @@ func Associate() ([]byte, error) {
}
return asn1.Marshal(aarq)
}
+
+const (
+ AssociateResultAccepted = iota
+ AssociateResultRejectedPermanent
+ AssociateResultRejectedTransient
+)
+
+func AssociateResult(b []byte) (int, error) {
+ aare := AARE{}
+ _, err := asn1.Unmarshal(b, &aare)
+ if err != nil {
+ return 0, err
+ }
+ return aare.Result, nil
+}
diff --git a/csta/system-status.go b/csta/system-status.go
index 1953d7b..9e0ea22 100644
--- a/csta/system-status.go
+++ b/csta/system-status.go
@@ -2,6 +2,8 @@ package csta
import "github.com/dim13/asn1"
+const SystemStatusOpcode = 211
+
const (
SystemStatusInitializing asn1.Enumerated = iota
SystemStatusEnabled
diff --git a/kxtde/main.go b/kxtde/main.go
new file mode 100644
index 0000000..98e5038
--- /dev/null
+++ b/kxtde/main.go
@@ -0,0 +1,79 @@
+package main
+
+import (
+ "flag"
+ "log"
+
+ "dim13.org/asn1/acse"
+ "dim13.org/asn1/csta"
+ "dim13.org/asn1/rose"
+ "dim13.org/asn1/spdu"
+
+ "github.com/dim13/asn1"
+)
+
+var pbx = flag.String("pbx", "192.168.240.20:33333", "PBX CTI Service")
+
+const (
+ AARQ = 0x60
+ AARE = 0x61
+ RLRQ = 0x62
+ RLRE = 0x63
+ ABRT = 0x64
+ Invoke = 0xa1
+ Result = 0xa2
+)
+
+func main() {
+ conn, err := spdu.Dial(*pbx)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer conn.Close()
+
+ aare, _ := acse.Associate()
+ conn.Write(aare)
+
+ var connected bool
+ for {
+ buf, err := spdu.ReadAll(conn)
+ if err != nil {
+ log.Fatal(err)
+ }
+ switch buf[0] {
+ case AARQ:
+ case AARE:
+ result, _ := acse.AssociateResult(buf)
+ connected = result == acse.AssociateResultAccepted
+ case RLRQ:
+ case RLRE:
+ case ABRT:
+ case Invoke:
+ id, opcode, payload, err := rose.Unmarshal(buf)
+ if err != nil {
+ log.Fatal(err)
+ }
+ switch opcode {
+ case csta.SystemStatusOpcode:
+ ss := &csta.SystemStatusArg{}
+ _, err := asn1.Unmarshal(payload, ss)
+ if err != nil {
+ log.Fatal(err)
+ }
+ log.Println(id, "System Status", ss.SystemStatus)
+ null, _ := asn1.Marshal(asn1.Null{})
+ res, err := rose.Marshal(id, opcode, null)
+ if err != nil {
+ log.Fatal(err)
+ }
+ conn.Write(res)
+ default:
+ log.Println("Opcode", opcode, payload)
+ }
+ case Result:
+ }
+ if !connected {
+ log.Fatal("EOT")
+ }
+ }
+}
diff --git a/parse/packets.go b/parse/packets.go
index 917ae19..80e6f67 100644
--- a/parse/packets.go
+++ b/parse/packets.go
@@ -182,6 +182,24 @@ var session = [][]byte{
0x08, 0x30, 0x06, 0x81, 0x04, 0x01, 0x31, 0x00,
0x01,
},
+ { // AARQ
+ 0x61, 0x2F, 0x80, 0x02, 0x07, 0x80, 0xA1, 0x07,
+ 0x06, 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A, 0xA2,
+ 0x03, 0x02, 0x01, 0x00, 0xA3, 0x05, 0xA1, 0x03,
+ 0x02, 0x01, 0x01, 0xBE, 0x14, 0x28, 0x12, 0x06,
+ 0x07, 0x2B, 0x0C, 0x00, 0x82, 0x1D, 0x81, 0x48,
+ 0xA0, 0x07, 0xA0, 0x05, 0x03, 0x03, 0x00, 0x08,
+ 0x00,
+ },
+ { // AARE
+ 0x61, 0x19, 0x80, 0x02, 0x07, 0x80, 0xA1, 0x07,
+ 0x06, 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A, 0xA2,
+ 0x03, 0x02, 0x01, 0x01, 0xA3, 0x05, 0xA1, 0x03,
+ 0x02, 0x01, 0x01,
+ },
+ { // ABRT
+ 0x64, 0x03, 0x80, 0x01, 0x00,
+ },
}
var (
diff --git a/parse/parse.go b/parse/parse.go
index f128440..3d74e58 100644
--- a/parse/parse.go
+++ b/parse/parse.go
@@ -37,30 +37,43 @@ func main() {
//fmt.Println(ber.Dump(s))
switch s[0] {
case 0xa1:
- v := &rose.Invoke{}
- unmarshal(s, v)
- if v.Opcode == 211 {
+ id, opcode, buf, err := rose.Unmarshal(s)
+ if err != nil {
+ fmt.Println(err)
+ }
+ if opcode == csta.SystemStatusOpcode {
ss := &csta.SystemStatusArg{}
- unmarshal(v.RawValue.FullBytes, ss)
- fmt.Println(ss.SystemStatus)
+ asn1.Unmarshal(buf, ss)
+ fmt.Println("Status", ss.SystemStatus)
+ null, _ := asn1.Marshal(asn1.Null{})
+ res, err := rose.Marshal(id, opcode, null)
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Printf("%x\n", s)
+ fmt.Printf("%x\n", res)
+ } else {
+ unmarshal(s, &rose.Invoke{})
}
case 0xa2:
- v := &rose.ReturnResult{}
- unmarshal(s, v)
- if v.Result.Opcode == 211 {
- ss := &csta.SystemStatusRes{}
- unmarshal(v.Result.RawValue.FullBytes, ss)
- }
+ unmarshal(s, &rose.ReturnResult{})
case 0x60:
unmarshal(s, &acse.AARQ{})
+ a, _ := acse.Associate()
+ fmt.Printf("%x\n", s)
+ fmt.Printf("%x\n", a)
case 0x61:
unmarshal(s, &acse.AARE{})
+ reason, _ := acse.AssociateResult(s)
+ fmt.Println("Reason", reason)
case 0x62:
unmarshal(s, &acse.RLRQ{})
case 0x63:
unmarshal(s, &acse.RLRE{})
case 0x64:
- unmarshal(s, &acse.ABRT{})
+ a := &acse.ABRT{}
+ unmarshal(s, a)
+ fmt.Println(a)
}
}
diff --git a/rose/rose.go b/rose/rose.go
index 27365cd..1e670cc 100644
--- a/rose/rose.go
+++ b/rose/rose.go
@@ -7,7 +7,12 @@ import "github.com/dim13/asn1"
// Invoke is Context-specific Constructed 1
type Invoke struct {
asn1.Tag `asn1:"tag:1"`
- InvokeId int
+ InvokeID int
+ Opcode int `asn1:"optional"`
+ asn1.RawValue `asn1:"optional"`
+}
+
+type Result struct {
Opcode int `asn1:"optional"`
asn1.RawValue `asn1:"optional"`
}
@@ -15,9 +20,28 @@ type Invoke struct {
// ReturnResult it Context-specific Constructed 2
type ReturnResult struct {
asn1.Tag `asn1:"tag:2"`
- InvokeId int
- Result struct {
- Opcode int `asn1:"optional"`
- asn1.RawValue `asn1:"optional"`
+ InvokeID int
+ Result `asn1:"optional,expicit"`
+}
+
+func Unmarshal(b []byte) (int, int, []byte, error) {
+ v := &Invoke{}
+ _, err := asn1.Unmarshal(b, v)
+ if err != nil {
+ return 0, 0, nil, err
+ }
+ return v.InvokeID, v.Opcode, v.RawValue.FullBytes, nil
+}
+
+func Marshal(id, opcode int, b []byte) ([]byte, error) {
+ v := ReturnResult{
+ InvokeID: id,
+ Result: Result{
+ Opcode: opcode,
+ RawValue: asn1.RawValue{
+ FullBytes: b,
+ },
+ },
}
+ return asn1.Marshal(v)
}