package icsnet import ( "net" "strings" "time" "gitlab.com/ics_cinnamon/voicegateway/icserror" "gitlab.com/ics_cinnamon/voicegateway/icslog" ) 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 { 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 { icserror.ICSERRNETListenError.SetError(aerr) return icserror.ICSERRNETListenError } } return nil } func (t *IcsTCPNet) Accept() *icserror.IcsError { var err error if t.listener != nil { 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(localAddr, remoteAddr *IcsNetAddr) *icserror.IcsError { if remoteAddr != nil { t.raddr = remoteAddr } raddr, rerr := t.raddr.ResolveIcsNetAddr("tcp") if rerr != nil { return rerr } var aerr error switch v := raddr.(type) { case net.TCPAddr: t.conn.ICSTCPConn, aerr = net.DialTCP("tcp", nil, &v) if aerr != nil { icserror.ICSERRNETConnectError.SetError(aerr) 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 } wsize, err := t.conn.ICSTCPConn.Write(b) if err != nil { icserror.ICSERRNETWriteError.SetError(err) return -1, icserror.ICSERRNETWriteError } return wsize, nil } func (u *IcsTCPNet) WriteSIP(b []byte) (int, *icserror.IcsError) { return 0, nil } func (u *IcsTCPNet) WriteRTP(b []byte) (int, *icserror.IcsError) { return 0, nil } 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) 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 (u *IcsTCPNet) ReadSIP() ([]byte, *net.UDPAddr, int, *icserror.IcsError) { return nil, nil, 0, nil } func (u *IcsTCPNet) ReadRTP() ([]byte, *net.UDPAddr, int, *icserror.IcsError) { return nil, nil, 0, nil } 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) SetRemoteAddr(raddr *IcsNetAddr) { t.raddr = raddr } 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) (t *IcsTCPNet, sendlen int, err *icserror.IcsError) { t = NewTCP(laddr, raddr) //connect to VoiceAgent err = t.Connect(laddr, raddr) if err != nil { return nil, -1, err } //defer t.Close() t.SetLinger(1) t.SetDeadline(180) //send call signal sendlen, err = t.Write(buf) if err != nil { return nil, -1, err } return t, 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()) l.Printf(icslog.LOG_LEVEL_INFO, -1, "Started TCP Listen - %s", 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 }