|
|
|
@ -9,8 +9,6 @@ import (
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
// "strconv"
|
|
|
|
|
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icscbtimer"
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsconf"
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icserror"
|
|
|
|
@ -20,7 +18,6 @@ import (
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icspacketparser"
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icssvc"
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/recorddata"
|
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/sipasm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type SessionManager struct {
|
|
|
|
@ -42,12 +39,6 @@ var bigSession []*IcsSession
|
|
|
|
|
var onceSession sync.Once
|
|
|
|
|
var channelNum int
|
|
|
|
|
|
|
|
|
|
var m *sync.Mutex
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
m = &sync.Mutex{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getSessionInstance(SIPNeter *icsnet.IcsNeter) []*IcsSession {
|
|
|
|
|
//l := icslog.GetIcsLog()
|
|
|
|
|
|
|
|
|
@ -260,199 +251,34 @@ func (sm *SessionManager) Run() (icserr *icserror.IcsError) {
|
|
|
|
|
|
|
|
|
|
sip := icspacketparser.NewSIP()
|
|
|
|
|
sip.SipParser(data)
|
|
|
|
|
|
|
|
|
|
fmt.Println(sip.Diversion)
|
|
|
|
|
if icspacketparser.ICS_SIP_METHOD_NOT_FOUND == sip.Method { //not found sip. maybe abnormal use
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, -1, "icspacketparser.ICS_SIP_METHOD_NOT_FOUND-%s", string(data))
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
// fmt.Println("메서드", sip.Method.String())
|
|
|
|
|
// if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE {
|
|
|
|
|
// // conf := icsconf.GetIcsConfig()
|
|
|
|
|
|
|
|
|
|
// // TODO - send bye
|
|
|
|
|
// // defer func() {
|
|
|
|
|
// // if err := recover(); err != nil {
|
|
|
|
|
// // l.Printf(icslog.LOG_LEVEL_WARN, =1, "%s \n%s",
|
|
|
|
|
// // icserror.ICSERRNETNotConnectError.GetMessage(), debug.Stack())
|
|
|
|
|
// // }
|
|
|
|
|
// // }()
|
|
|
|
|
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, -1, "sip 내용 전달! %+v", sip)
|
|
|
|
|
// // ip := strings.Split(conf.SIPConfig.SIPProxy, ":")[0]
|
|
|
|
|
// // port, cerr := strconv.Atoi(strings.Split(conf.SIPConfig.SIPProxy, ":")[1])
|
|
|
|
|
// // if cerr != nil {
|
|
|
|
|
// // fmt.Println("cerr err")
|
|
|
|
|
// // }
|
|
|
|
|
// // iport := fmt.Sprintf("%s:%d", ip, port)
|
|
|
|
|
|
|
|
|
|
// // fmt.Println(ip, port)
|
|
|
|
|
|
|
|
|
|
// sipPort := conf.SIPConfig.Port
|
|
|
|
|
// // transport := conf.SIPConfig.Transport
|
|
|
|
|
// sipProxy := conf.SIPConfig.SIPProxy
|
|
|
|
|
|
|
|
|
|
// remoteaddr := icsnet.NewNetAddrWithIPAddr(sipProxy)
|
|
|
|
|
// localAddrStr := fmt.Sprintf("192.168.0.4:%d", sipPort)
|
|
|
|
|
// localAddr := icsnet.NewNetAddrWithIPAddr(localAddrStr)
|
|
|
|
|
|
|
|
|
|
// t := icsnet.NewUDP(&localAddr, &remoteaddr)
|
|
|
|
|
// // fmt.Println("local ", t.LocalAddr().String())
|
|
|
|
|
// fmt.Println("remote ", t.RemoteAddr().String())
|
|
|
|
|
// // sendSIP := []string{data[:]}
|
|
|
|
|
|
|
|
|
|
// // for _, elem := range data {
|
|
|
|
|
// sent, err := t.WriteSIP([]byte(data))
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// fmt.Println(err)
|
|
|
|
|
// }
|
|
|
|
|
// // }
|
|
|
|
|
|
|
|
|
|
// // wlen, werr := t.WriteSIP([]byte(data))
|
|
|
|
|
// // if werr != nil {
|
|
|
|
|
// // l.Print(icslog.LOG_LEVEL_FATAL, -1, werr.GetMessage())
|
|
|
|
|
// // // s.SetAgentStatus(STATUS_AGENT_READY)
|
|
|
|
|
// // // return werr
|
|
|
|
|
// // }
|
|
|
|
|
// fmt.Printf("send data \r\n%s, \r\n %d\r\n", string(data), sent)
|
|
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
if SessionAvailableSipMethod(&sip) {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG, -1, "Session Processing Method-[%s, %s, %s]",
|
|
|
|
|
sip.Method, sip.ResType, sip.Cseq)
|
|
|
|
|
|
|
|
|
|
s, serr := FindSession(sip)
|
|
|
|
|
if serr != nil { //not found session
|
|
|
|
|
// name1 := strings.SplitN(sip.To, "@", 2)
|
|
|
|
|
// name2 := strings.SplitN(name1[0], ":", 2)
|
|
|
|
|
// agentname := name2[1]
|
|
|
|
|
if conf.Representative.Value && sip.Source == "486" {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, -1, "All Agent Calling!!!!!")
|
|
|
|
|
sipPort := conf.SIPConfig.Port
|
|
|
|
|
// sipProxy := conf.SIPConfig.SIPProxy
|
|
|
|
|
transport := conf.SIPConfig.Transport
|
|
|
|
|
// remoteaddr := icsnet.NewNetAddrWithIPAddr(sipProxy)
|
|
|
|
|
// localAddrStr := fmt.Sprintf("0.0.0.0:%d", sipPort)
|
|
|
|
|
// localAddr := icsnet.NewNetAddrWithIPAddr(localAddrStr)
|
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
|
ip := conf.InfoConfig.ServerIP
|
|
|
|
|
ackMethod := fmt.Sprintf("sip:%s@%s;transport=%s", "192.168.0.222:5090", "AISB", transport)
|
|
|
|
|
reqAck := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_ACK, ackMethod)
|
|
|
|
|
maxforwards := "70"
|
|
|
|
|
// s.uri = fmt.Sprintf("sip:%s@%s", conf.Representative.Name, ip)
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, -1, "Set URI [%s]", s.uri)
|
|
|
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", conf.Representative.Name, ip, sipPort, transport)
|
|
|
|
|
userAgent := conf.InfoConfig.Product
|
|
|
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
|
|
|
supported := "timer,path,replaces"
|
|
|
|
|
|
|
|
|
|
for _, viav := range sip.Via {
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, viav)
|
|
|
|
|
}
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, sip.From)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, sip.To)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, sip.CallID)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, sip.Cseq)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, "0")
|
|
|
|
|
reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
|
|
|
|
|
|
// wlen, werr := (*s.sipNeter).WriteSIPTo([]byte(reqAck.String()), s.remoteSIPAddr)
|
|
|
|
|
wlen, werr := (sm.SIPNeter).WriteSIP([]byte(reqAck.String()))
|
|
|
|
|
if werr != nil {
|
|
|
|
|
l.Print(icslog.LOG_LEVEL_FATAL, -1, werr.GetMessage())
|
|
|
|
|
return werr
|
|
|
|
|
}
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, -1, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
|
|
|
wlen,
|
|
|
|
|
(sm.SIPNeter).LocalAddr().String(),
|
|
|
|
|
(sm.SIPNeter).RemoteAddr().String(),
|
|
|
|
|
reqAck.String())
|
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
|
}
|
|
|
|
|
if serr != nil { //not found session, create new
|
|
|
|
|
name1 := strings.SplitN(sip.To, "@", 2)
|
|
|
|
|
name2 := strings.SplitN(name1[0], ":", 2)
|
|
|
|
|
agentname := name2[1]
|
|
|
|
|
s, serr = AllocSession(agentname, sip.GetCallID())
|
|
|
|
|
if serr != nil {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, -1, "Licensed Session number[%d:%s] is EXCEEDED-%s",
|
|
|
|
|
conf.GetChannelNum(), agentname, serr.GetMessage())
|
|
|
|
|
continue
|
|
|
|
|
// s, serr = AllocSession(agentname, sip.GetCallID())
|
|
|
|
|
// if serr != nil {
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, -1, "Licensed Session number[%d:%s] is EXCEEDED-%s",
|
|
|
|
|
// conf.GetChannelNum(), agentname, serr.GetMessage())
|
|
|
|
|
// if conf.Representative.Value && sip.Source == "486" {
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, -1, "All Agent Calling!!!!!")
|
|
|
|
|
// sipPort := conf.SIPConfig.Port
|
|
|
|
|
// // sipProxy := conf.SIPConfig.SIPProxy
|
|
|
|
|
// transport := conf.SIPConfig.Transport
|
|
|
|
|
// // remoteaddr := icsnet.NewNetAddrWithIPAddr(sipProxy)
|
|
|
|
|
// // localAddrStr := fmt.Sprintf("0.0.0.0:%d", sipPort)
|
|
|
|
|
// // localAddr := icsnet.NewNetAddrWithIPAddr(localAddrStr)
|
|
|
|
|
// //////////////////////////////////////////////
|
|
|
|
|
// ip := conf.InfoConfig.ServerIP
|
|
|
|
|
// ackMethod := fmt.Sprintf("sip:01025670081@%s;transport=%s", "192.168.0.222:5090", transport)
|
|
|
|
|
// reqAck := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_ACK, ackMethod)
|
|
|
|
|
// maxforwards := "70"
|
|
|
|
|
// // s.uri = fmt.Sprintf("sip:%s@%s", conf.Representative.Name, ip)
|
|
|
|
|
// // l.Printf(icslog.LOG_LEVEL_INFO, -1, "Set URI [%s]", s.uri)
|
|
|
|
|
// contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", conf.Representative.Name, ip, sipPort, transport)
|
|
|
|
|
// userAgent := conf.InfoConfig.Product
|
|
|
|
|
// allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
|
|
|
// supported := "timer,path,replaces"
|
|
|
|
|
|
|
|
|
|
// for _, viav := range sip.Via {
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, viav)
|
|
|
|
|
// }
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, sip.From)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, sip.To)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, sip.CallID)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, sip.Cseq)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, "0")
|
|
|
|
|
// reqAck.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
|
|
|
|
|
|
// // wlen, werr := (*s.sipNeter).WriteSIPTo([]byte(reqAck.String()), s.remoteSIPAddr)
|
|
|
|
|
// wlen, werr := (sm.SIPNeter).WriteSIP([]byte(reqAck.String()))
|
|
|
|
|
// if werr != nil {
|
|
|
|
|
// l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
|
|
|
// return werr
|
|
|
|
|
// }
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, -1, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
|
|
|
// wlen,
|
|
|
|
|
// (sm.SIPNeter).LocalAddr().String(),
|
|
|
|
|
// (sm.SIPNeter).RemoteAddr().String(),
|
|
|
|
|
// reqAck.String())
|
|
|
|
|
// //////////////////////////////////////////////
|
|
|
|
|
// }
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, -1, "Session Allocated. Session ID[%d] Call ID[%s]", s.ID, sip.GetCallID())
|
|
|
|
|
// s.SetSessionMethod(sip)
|
|
|
|
|
// //session start
|
|
|
|
|
// s.Start()
|
|
|
|
|
}
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, -1, "Session Allocated. Session ID[%d] Call ID[%s]", s.ID, sip.GetCallID())
|
|
|
|
|
s.SetSessionMethod(sip)
|
|
|
|
|
//session start
|
|
|
|
|
s.Start()
|
|
|
|
|
} else { //found session
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Session found [%s][%s]", sip.GetCallID(), s.callID)
|
|
|
|
|
if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE {
|
|
|
|
|
s.SetCallID(sip.GetCallID())
|
|
|
|
|
}
|
|
|
|
|
// 대표번호
|
|
|
|
|
if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 || strings.SplitN(sip.Cseq, " ", 2)[1] == "INVITE" {
|
|
|
|
|
s.SetCallID(sip.GetCallID())
|
|
|
|
|
// representative
|
|
|
|
|
if conf.Representative.Value {
|
|
|
|
|
sip.SetToRep()
|
|
|
|
|
sip.SetTo(s.AgentName)
|
|
|
|
|
// if sip.Source == "486" {
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, -1, "All Agent Calling!!!!!")
|
|
|
|
|
// fmt.Println("##### All Agent Clling!!!!!! ")
|
|
|
|
|
// s.Res486Ack(&sip)
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if s.CheckAutomata(&sip) {
|
|
|
|
|
s.SetSessionMethod(sip)
|
|
|
|
@ -462,13 +288,6 @@ func (sm *SessionManager) Run() (icserr *icserror.IcsError) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if conf.Representative.Value && sip.Source == "486" {
|
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, -1, "All Agent Calling!!!!!")
|
|
|
|
|
// fmt.Println("##### All Agent Clling!!!!!! ")
|
|
|
|
|
// s.Res486Ack(&sip)
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
//if cancel ACK or bye res, remove the session
|
|
|
|
|
if s.MethodAutomata == ICS_SIP_AUTOMATA_CANCEL && sip.Method == icspacketparser.ICS_SIP_METHOD_ACK {
|
|
|
|
|
s.Stop()
|
|
|
|
@ -483,8 +302,6 @@ func (sm *SessionManager) Run() (icserr *icserror.IcsError) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.remoteSIPAddr = addr
|
|
|
|
|
|
|
|
|
|
//post the sip event to session
|
|
|
|
|
h := icsevent.NewEventH()
|
|
|
|
|
evt, evtErr := h.AllocEvent(sip)
|
|
|
|
@ -513,7 +330,7 @@ func (sm *SessionManager) Run() (icserr *icserror.IcsError) {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, -1, "%v", sip)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data = nil
|
|
|
|
@ -654,7 +471,7 @@ func BotCommand(t *icsnet.IcsTCPNet, bufend string) {
|
|
|
|
|
if agentStatus == STATUS_AGENT_BUSY {
|
|
|
|
|
s.RequestBYE(s.InviteSIP)
|
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_BYEING)
|
|
|
|
|
// fmt.Println("AGENT_STATUS : ", s.GetAgentStatus())
|
|
|
|
|
fmt.Println("AGENT_STATUS : ", s.GetAgentStatus())
|
|
|
|
|
}
|
|
|
|
|
s.BotStatus = ttscmd
|
|
|
|
|
} else {
|
|
|
|
@ -674,7 +491,7 @@ func BotCommand(t *icsnet.IcsTCPNet, bufend string) {
|
|
|
|
|
tts, rlen, rerr := t.Read(int(ttspl))
|
|
|
|
|
if rerr != nil {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to recv TTS(%d,%s)", rlen, rerr.GetError())
|
|
|
|
|
// fmt.Println("error : ", rerr.GetError())
|
|
|
|
|
fmt.Println("error : ", rerr.GetError())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Recved TTS data. Length: %d", len(tts))
|
|
|
|
@ -724,7 +541,7 @@ func BotCommand(t *icsnet.IcsTCPNet, bufend string) {
|
|
|
|
|
if agentStatus == STATUS_AGENT_BUSY {
|
|
|
|
|
s.RequestRefer(telNo, s.InviteSIP)
|
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_BYEING)
|
|
|
|
|
// fmt.Println("AGENT_STATUS : ", s.GetAgentStatus())
|
|
|
|
|
fmt.Println("AGENT_STATUS : ", s.GetAgentStatus())
|
|
|
|
|
}
|
|
|
|
|
s.BotStatus = ttscmd
|
|
|
|
|
} else {
|
|
|
|
@ -741,6 +558,6 @@ func BotCommand(t *icsnet.IcsTCPNet, bufend string) {
|
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "485LINE %+v, %+v, %+v, %s", ttscmd, ttsrc, ttspl, agentName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// fmt.Println("418LINE rlen", rlen, rerr)
|
|
|
|
|
fmt.Println("418LINE rlen", rlen, rerr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|