You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
5.8 KiB
Go
292 lines
5.8 KiB
Go
3 years ago
|
package icsnet
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"gitlab.com/cinnamon/voiceagent/icserror"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
NET_BUFFER_LENGTH = 4096
|
||
|
)
|
||
|
|
||
|
type IcsTCPNet struct {
|
||
|
laddr *IcsNetAddr
|
||
|
raddr *IcsNetAddr
|
||
|
conn *IcsConn
|
||
|
listener *net.TCPListener
|
||
|
}
|
||
|
|
||
|
func NewTCP(laddr, raddr *IcsNetAddr) (tcpnet *IcsTCPNet) {
|
||
|
tcpnet = &IcsTCPNet{
|
||
|
laddr: laddr,
|
||
|
raddr: raddr,
|
||
|
conn: &IcsConn{},
|
||
|
}
|
||
|
|
||
|
return tcpnet
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Listen() *icserror.IcsError {
|
||
|
if t.laddr == nil {
|
||
|
return icserror.ICSERRNETResolveAddrError
|
||
|
}
|
||
|
|
||
|
addr, err := t.laddr.ResolveIcsNetAddr("tcp")
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var aerr error
|
||
|
switch v := addr.(type) {
|
||
|
case net.TCPAddr:
|
||
|
t.listener, aerr = net.ListenTCP("tcp", &v)
|
||
|
if aerr != nil {
|
||
|
//fmt.Println(addr, v, aerr)
|
||
|
icserror.ICSERRNETListenError.SetError(aerr)
|
||
|
return icserror.ICSERRNETListenError
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Accept() *icserror.IcsError {
|
||
|
if t.listener != nil {
|
||
|
var err error
|
||
|
t.conn.ICSTCPConn, err = t.listener.AcceptTCP()
|
||
|
if err != nil {
|
||
|
icserror.ICSERRNETAcceptError.SetError(err)
|
||
|
return icserror.ICSERRNETAcceptError
|
||
|
}
|
||
|
} else {
|
||
|
return icserror.ICSERRNETAcceptError
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Connect() *icserror.IcsError {
|
||
|
laddr, rerr := t.laddr.ResolveIcsNetAddr("tcp")
|
||
|
if rerr != nil {
|
||
|
return rerr
|
||
|
}
|
||
|
|
||
|
switch v := laddr.(type) {
|
||
|
case net.TCPAddr:
|
||
|
var err error
|
||
|
t.conn.ICSTCPConn, err = net.DialTCP("tcp", nil, &v)
|
||
|
if err != nil {
|
||
|
icserror.ICSERRNETConnectError.SetError(err)
|
||
|
return icserror.ICSERRNETConnectError
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Close() *icserror.IcsError {
|
||
|
if t.conn.ICSTCPConn == nil {
|
||
|
return icserror.ICSERRNETNotConnectError
|
||
|
}
|
||
|
|
||
|
aerr := t.conn.ICSTCPConn.Close()
|
||
|
if aerr != nil {
|
||
|
icserror.ICSERRNETNotConnectError.SetError(aerr)
|
||
|
return icserror.ICSERRNETNotConnectError
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Write(b []byte) (int, *icserror.IcsError) {
|
||
|
if t.conn.ICSTCPConn == nil {
|
||
|
return 0, icserror.ICSERRNETNotConnectError
|
||
|
}
|
||
|
|
||
|
bsize := len(b)
|
||
|
var wlen int
|
||
|
for wlen = 0; ; {
|
||
|
wsize, err := t.conn.ICSTCPConn.Write(b[wlen:])
|
||
|
if err == nil {
|
||
|
wlen += wsize
|
||
|
if wlen >= bsize {
|
||
|
return wlen, nil
|
||
|
}
|
||
|
} else {
|
||
|
icserror.ICSERRNETWriteError.SetError(err)
|
||
|
return -1, icserror.ICSERRNETWriteError
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) Read(size int) ([]byte, int, *icserror.IcsError) {
|
||
|
var rlen int = 0
|
||
|
buf := make([]byte, size)
|
||
|
|
||
|
for rlen = 0; ; {
|
||
|
len, err := t.conn.ICSTCPConn.Read(buf[rlen:])
|
||
|
//len, err := t.conn.ICSTCPConn.Read(buf)
|
||
|
if err == nil {
|
||
|
rlen += len
|
||
|
if rlen >= size {
|
||
|
return buf, rlen, nil
|
||
|
}
|
||
|
} else {
|
||
|
icserror.ICSERRNETReadError.SetError(err)
|
||
|
return nil, -1, icserror.ICSERRNETReadError
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) ReadS(length int, lineEnd string) ([]byte, int, *icserror.IcsError) {
|
||
|
var rlen int = 0
|
||
|
size := NET_BUFFER_LENGTH
|
||
|
if length > 0 {
|
||
|
size = length
|
||
|
}
|
||
|
buf := make([]byte, size)
|
||
|
//fmt.Println("Reads make size:", size, "buf size:", len(buf))
|
||
|
|
||
|
for rlen = 0; ; {
|
||
|
rbuf := make([]byte, size)
|
||
|
len, err := t.conn.ICSTCPConn.Read(rbuf)
|
||
|
if err == nil {
|
||
|
rlen += len
|
||
|
copy(buf[:rlen], rbuf)
|
||
|
//buf = append(buf, rbuf...)
|
||
|
if rlen >= size {
|
||
|
return buf, rlen, nil
|
||
|
} else if strings.Contains(string(buf), lineEnd) {
|
||
|
return buf, rlen, nil
|
||
|
}
|
||
|
} else {
|
||
|
icserror.ICSERRNETReadError.SetError(err)
|
||
|
return nil, -1, icserror.ICSERRNETReadError
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) LocalAddr() net.Addr {
|
||
|
return t.conn.ICSTCPConn.LocalAddr()
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) RemoteAddr() net.Addr {
|
||
|
return t.conn.ICSTCPConn.RemoteAddr()
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) SetLinger(sec int) {
|
||
|
t.conn.ICSTCPConn.SetLinger(sec)
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) SetDeadline(sec int64) {
|
||
|
t.conn.ICSTCPConn.SetDeadline(time.Now().Add(time.Second * time.Duration(sec)))
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) SetWriteDeadline(sec int64) {
|
||
|
t.conn.ICSTCPConn.SetWriteDeadline(time.Now().Add(time.Second * time.Duration(sec)))
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) SetReadDeadline(sec int64) {
|
||
|
t.conn.ICSTCPConn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(sec)))
|
||
|
}
|
||
|
|
||
|
func SendCallSignal(laddr, raddr *IcsNetAddr, buf []byte) (sendlen int, err *icserror.IcsError) {
|
||
|
t := NewTCP(laddr, raddr)
|
||
|
//connect to VoiceAgent
|
||
|
err = t.Connect()
|
||
|
if err != nil {
|
||
|
return -1, err
|
||
|
}
|
||
|
defer t.Close()
|
||
|
|
||
|
t.SetLinger(1)
|
||
|
t.SetDeadline(180)
|
||
|
|
||
|
//send call signal
|
||
|
sendlen, err = t.Write(buf)
|
||
|
if err != nil {
|
||
|
return -1, err
|
||
|
}
|
||
|
|
||
|
return sendlen, err
|
||
|
}
|
||
|
|
||
|
func SendCallSignal2(laddr, raddr *IcsNetAddr, buf []byte) (conn *IcsTCPNet, sendlen int, err *icserror.IcsError) {
|
||
|
t := NewTCP(laddr, raddr)
|
||
|
//connect to VoiceAgent
|
||
|
err = t.Connect()
|
||
|
if err != nil {
|
||
|
return nil, -1, err
|
||
|
}
|
||
|
|
||
|
t.SetLinger(1)
|
||
|
t.SetDeadline(180)
|
||
|
|
||
|
//send call signal
|
||
|
sendlen, err = t.Write(buf)
|
||
|
if err != nil {
|
||
|
t.Close()
|
||
|
return nil, -1, err
|
||
|
}
|
||
|
|
||
|
return t, sendlen, err
|
||
|
}
|
||
|
func SendByeSignal(laddr, raddr *IcsNetAddr, buf []byte) (sendlen int, err *icserror.IcsError) {
|
||
|
t := NewTCP(laddr, raddr)
|
||
|
//connect to VoiceAgent
|
||
|
err = t.Connect()
|
||
|
if err != nil {
|
||
|
return -1, err
|
||
|
}
|
||
|
|
||
|
t.SetLinger(1)
|
||
|
t.SetDeadline(180)
|
||
|
|
||
|
//send call signal
|
||
|
sendlen, err = t.Write(buf)
|
||
|
if err != nil {
|
||
|
t.Close()
|
||
|
return -1, err
|
||
|
}
|
||
|
|
||
|
return sendlen, err
|
||
|
}
|
||
|
func ListenAndServeTCP(laddr, raddr *IcsNetAddr, bufend string, f func(*IcsTCPNet, string)) (t *IcsTCPNet, err *icserror.IcsError) {
|
||
|
t = NewTCP(laddr, raddr)
|
||
|
err = t.Listen()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
//defer t.listener.Close()
|
||
|
|
||
|
//l := icslog.GetIcsLog()
|
||
|
go func() {
|
||
|
//fmt.Printf("Started TCP Listen - %s\n", laddr.String())
|
||
|
for {
|
||
|
if accepterr := t.Accept(); accepterr != nil {
|
||
|
continue
|
||
|
}
|
||
|
go f(t, bufend)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (t *IcsTCPNet) CloseListener() *icserror.IcsError {
|
||
|
if t.listener == nil {
|
||
|
return icserror.ICSERRNETNotConnectError
|
||
|
}
|
||
|
|
||
|
aerr := t.listener.Close()
|
||
|
if aerr != nil {
|
||
|
icserror.ICSERRNETNotConnectError.SetError(aerr)
|
||
|
return icserror.ICSERRNETNotConnectError
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|