package main import ( "encoding/hex" "flag" "fmt" "dim13.org/asn1/ber" "dim13.org/asn1/spdu" ) /* Limits * * Parameter Maximum Value * * PDU length including header 240 * InvokeID 32767 * (ROSE) * DeviceID 32 * (MakeCall, DialDigits, ConsulationCall) * DeviceID from TDA/TDE 16 * (In events) * charactersToSend 64 * (GenerateDigits) */ var service = flag.String("service", "192.168.240.20:33333", "PBX CTI Service") var conn spdu.Conn func init() { flag.Parse() } /* A-ASSOCIATE Request * * 60 23 AARQ-apdu * 80 02 07 80 protocol-version { version1 } * A1 07 application-context-name * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 } * BE 14 user-information * 28 12 * 06 07 2B 0C 00 82 1D 81 48 direct-reference { 1 3 12 0 285 200 } * A0 07 single-ASN1-type * (ACSEUserInfomrationForCSTA) * A0 05 newDefinition * 03 03 00 08 00 cSTAVersion { versionFive } */ var associate = []byte{ 0x60, 0x23, 0x80, 0x02, 0x07, 0x80, 0xA1, 0x07, 0x06, 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A, 0xBE, 0x14, 0x28, 0x12, 0x06, 0x07, 0x2B, 0x0C, 0x00, 0x82, 0x1D, 0x81, 0x48, 0xA0, 0x07, 0xA0, 0x05, 0x03, 0x03, 0x00, 0x08, 0x00, } /* A-ACCOCIATE Result * 61 2F AARE-apdu * 80 02 07 80 protocol-version { version1 } * A1 07 application-context-name * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 } * A2 03 result * 02 01 00 accepted * A3 05 result-source-diagnostic * A1 03 acse-service-user * 02 01 00 no-reason-given * BE 14 user-information * 28 12 * 06 07 2B 0C 00 82 1D 81 48 direct-reference { 1 3 120 285 200 } * A0 07 single-ASN1-type * (ACSEUserInformationForCSTA) * A0 05 newDefinition * 03 03 00 08 00 cSTAVersion { versionFive } */ /* A-REJECT * 61 19 AARE-apdu * 80 02 07 80 protocol-version { version1 } * A1 07 application-context-name * 06 05 2B 0C 00 81 5A { 1 3 12 0 218 } * A2 03 result * 02 01 01 rejected-permanent * A3 05 result-source-diagnostic * A1 03 acse-service-user * 02 01 01 no-reason-given */ /* A-RELEASE Request * * 62 00 RLRQ-apdu */ var release = []byte{0x62, 0x00} /* A-RELEASE Result * * 63 00 RLRE-apdu */ /* SystemStatus Request * A1 0C ROSE-Invoke * 02 01 01 invokeId present: 1 * 02 02 00 D3 opcode local: 211 * 30 03 SystemStatusArg * 0A 01 02 systemStatus normal */ /* SystemStatus Result * A2 0B ROSE-ReturnResult * 02 01 01 invokeId present: 1 * 30 06 SystemStatusRes * 02 02 00 D3 opcode local: 211 * 05 00 noData */ var status = []byte{ 0xA2, 0x0B, 0x02, 0x01, 0x01, 0x30, 0x06, 0x02, 0x02, 0x00, 0xD3, 0x05, 0x00, } /* A-ABORT * 64 03 ABRT-apdu * 80 01 00 ABRT-source: acse-service-user */ /* Request CO lines * A1 16 ROSE-Invoke * 02 02 00 E0 invokeId: 224 * 02 01 33 opcode local: 51 * 30 0D EscapeArgument * A4 0B kmeSystemData * A0 09 getSystemData * A4 07 deviceList * A1 05 category * A0 03 standardDevice * 0A 01 02 networkInterface */ /* Request CO lines response * A2 17 ROSE-ResultReturn * 02 02 00 E0 invokeId: 224 * 30 11 result * 02 01 33 opcode local: 51 * 7E 0C * A1 0A * A4 08 * A4 06 * 04 04 30 41 31 36 OCTET STRING: '0A16' */ var coLines = []byte{ 0xA1, 0x16, 0x02, 0x02, 0x00, 0xE0, 0x02, 0x01, 0x33, 0x30, 0x0D, 0xA4, 0x0B, 0xA0, 0x09, 0xA4, 0x07, 0xA1, 0x05, 0xA0, 0x03, 0x0A, 0x01, 0x02, } /* Request EXT * A1 16 ROSE-Invoke * 02 02 06 02 invokeId: 1538 * 02 01 33 opcode local: 51 * 30 0D EscapeArgument * A4 0B kmeSystemData * A0 09 getSystemData * A4 07 deviceList * A1 05 category * A0 03 standardDevice * 0A 01 05 station */ var ext = []byte{ 0xA1, 0x16, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x33, 0x30, 0x0D, 0xA4, 0x0B, 0xA0, 0x09, 0xA4, 0x07, 0xA1, 0x05, 0xA0, 0x03, 0x0A, 0x01, 0x05, } /* Monitor 111 * A1 11 ROSE-Invoke * 02 01 78 invokeId: 120 * 02 01 47 opcode local: 71 * 30 09 MonitorStartArgument * 30 05 MonitorObject (CSTAObject) * 80 03 31 31 31 dialingNumber '111' * A0 00 MonitorFilter? */ func dump(b []byte) { fmt.Println(hex.Dump(b)) fmt.Println(ber.Dump(b)) } func Ask(c spdu.Conn, out []byte) []byte { fmt.Println("Ask") dump(out) c.Write(out) in, _ := spdu.ReadAll(c) fmt.Printf("Packet length: 0x%.2X\n", len(in)) dump(in) return in } func Status(c spdu.Conn) { fmt.Println("Status") in, _ := spdu.ReadAll(c) fmt.Printf("Packet length: 0x%.2X\n", len(in)) dump(in) out := status out[4] = in[4] dump(out) c.Write(out) } func main() { conn, _ = spdu.Dial(*service) defer conn.Close() Ask(conn, associate) Status(conn) defer Ask(conn, release) Ask(conn, coLines) Status(conn) //Ask(conn, ext) Status(conn) Status(conn) Status(conn) Status(conn) Status(conn) }