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.
1823 lines
62 KiB
Go
1823 lines
62 KiB
Go
package icssessionmanager
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"fmt"
|
|
// "net"
|
|
"math/rand"
|
|
"runtime/debug"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitlab.com/ics_cinnamon/voicegateway/icscbtimer"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsconf"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsdtmf"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icserror"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icslog"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsmediaconv"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsnet"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icspacketparser"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icsrtp"
|
|
"gitlab.com/ics_cinnamon/voicegateway/icssvc"
|
|
"gitlab.com/ics_cinnamon/voicegateway/recorddata"
|
|
"gitlab.com/ics_cinnamon/voicegateway/recorddata/writecallsignal"
|
|
"gitlab.com/ics_cinnamon/voicegateway/sipasm"
|
|
)
|
|
|
|
func (s *IcsSession) SetRegisterStatus(status int) int {
|
|
s.registerStatus = status
|
|
|
|
return s.registerStatus
|
|
}
|
|
|
|
func (s IcsSession) GetRegisterStatus() int {
|
|
return s.registerStatus
|
|
}
|
|
|
|
func (s *IcsSession) SetAgentStatus(status int) int {
|
|
s.agentStatus = status
|
|
|
|
return s.agentStatus
|
|
}
|
|
|
|
func (s IcsSession) GetAgentStatus() int {
|
|
return s.agentStatus
|
|
}
|
|
|
|
//response register
|
|
func (s *IcsSession) ProcRegister(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
|
|
//check expires header value
|
|
expires := sip.Headers["EXPIRES"][0]
|
|
if len(expires) == 0 {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Invalid SIP - No Expires header")
|
|
return nil
|
|
}
|
|
expN, cerr := strconv.Atoi(expires)
|
|
if cerr != nil {
|
|
return icserror.ICSERRStrConv
|
|
}
|
|
|
|
//remove register
|
|
if expN == 0 {
|
|
//stop callback timer
|
|
s.RegisterCallBackTimer.Stop()
|
|
|
|
//make response
|
|
resSIP := sipasm.NewSIPResponse(sip, 200)
|
|
resSIP.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR, "")
|
|
|
|
//send response
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(resSIP.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, -1, werr.GetMessage())
|
|
return icserror.ICSERRNETWriteError
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, -1, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
resSIP.String())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//register callback timer function
|
|
func (s *IcsSession) RequestRegisterCB(t *icscbtimer.IcsCBTimer) {
|
|
l := icslog.GetIcsLog()
|
|
|
|
for s.GetRegisterStatus() == STATUS_REGISTER_NOT_READY {
|
|
time.Sleep(time.Millisecond)
|
|
}
|
|
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
port := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
|
|
regifunc := func(t *time.Time) {
|
|
regiMethod := fmt.Sprintf("sip:%s;transport=%s", ip, transport)
|
|
reqRegi := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_REGISTER, regiMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP %s;rport;branch=%s", ip, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := fmt.Sprintf("<sip:%s@%s>;tag=%s", s.AgentName, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
postfix := fmt.Sprintf("@%s", ip)
|
|
var callid string
|
|
if len(s.callID) != 0 {
|
|
callid = s.callID
|
|
//if len(s.regiCallID) != 0 {
|
|
//callid = s.regiCallID
|
|
} else {
|
|
callid = sipasm.GenerateCallID(postfix)
|
|
}
|
|
cseq := fmt.Sprintf("%d REGISTER", s.Cseq)
|
|
s.Cseq++
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
expires := fmt.Sprintf("%d", conf.AgentConfig[s.ID].RegisterConfig.RegisterExpire)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
contentLength := "0"
|
|
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, from)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, to)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_EXPIRES, expires)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, contentLength)
|
|
reqRegi.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
s.callID = callid
|
|
//s.regiCallID = callid
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID,
|
|
"Session Allocated[%d] Call ID: %s==========================",
|
|
s.goroutineID, s.callID)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqRegi.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
s.SetRegisterStatus(STATUS_REGISTER_REQUEST)
|
|
s.SetSessionMethodWithType(ICS_SIP_AUTOMATA_REGISTER)
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqRegi.String())
|
|
|
|
//fmt.Println(reqRegi)
|
|
//fmt.Println(wlen)
|
|
}
|
|
regifunc(nil)
|
|
|
|
for t1 := range t.GetTick() {
|
|
//fmt.Println(s.ID, t1)
|
|
regifunc(&t1)
|
|
}
|
|
|
|
}
|
|
|
|
func (s *IcsSession) RequestInviteCB(inviteto string, t *icscbtimer.IcsCBTimer) {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
inviteFunc := func() {
|
|
status := s.GetAgentStatus()
|
|
if status == STATUS_AGENT_READY {
|
|
ip := conf.InfoConfig.ServerIP
|
|
port := conf.SIPConfig.Port
|
|
mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
proxy := conf.SIPConfig.SIPProxy
|
|
transport := conf.SIPConfig.Transport
|
|
format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
inviteMethod := fmt.Sprintf("sip:%s@%s;transport=%s", inviteto, proxy, transport)
|
|
reqInvite := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_INVITE, inviteMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP %s;rport;branch=%s", ip, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := fmt.Sprintf("<sip:%s@%s:5090>;tag=%s", s.AgentName, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := fmt.Sprintf("<sip:%s@%s;user=phone>", "01025670081", ip)
|
|
//to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
postfix := fmt.Sprintf("@%s", ip)
|
|
var callid string
|
|
if len(s.callID) != 0 {
|
|
callid = s.callID
|
|
//if len(s.regiCallID) != 0 {
|
|
//callid = s.regiCallID
|
|
} else {
|
|
callid = sipasm.GenerateCallID(postfix)
|
|
}
|
|
cseq := fmt.Sprintf("%d INVITE", s.Cseq)
|
|
s.Cseq++
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
//expires := fmt.Sprintf("%d", conf.AgentConfig[s.ID].RegisterConfig.RegisterExpire)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
|
|
formats := strings.Split(format, " ")
|
|
reqInvite.SDP = sipasm.NewSDPMessage(ip, mediaPort, formats[:], 0)
|
|
sdpLength := fmt.Sprintf("%d", len(reqInvite.SDP.String()))
|
|
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, from)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, to)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
//reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_EXPIRES, expires)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_TYPE, "application/sdp")
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, sdpLength)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqInvite.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
|
|
s.callID = callid
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_CALLING)
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqInvite.String())
|
|
}
|
|
}
|
|
inviteFunc()
|
|
|
|
for t1 := range t.GetTick() {
|
|
fmt.Println(s.ID, t1)
|
|
t.Stop()
|
|
}
|
|
}
|
|
|
|
func (s *IcsSession) RequestInvite(inviteto string) {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
inviteFunc := func() {
|
|
ip := conf.InfoConfig.ServerIP
|
|
// port := conf.SIPConfig.Port
|
|
mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
// proxy := conf.SIPConfig.SIPProxy
|
|
transport := conf.SIPConfig.Transport
|
|
format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
inviteMethod := fmt.Sprintf("sip:%s@192.168.0.83;transport=%s", s.AgentName, transport)
|
|
reqInvite := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_INVITE, inviteMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP 192.168.0.83:5090;branch=%s", sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := fmt.Sprintf("<sip:%s@%s>;tag=%s", inviteto, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := fmt.Sprintf("<sip:%s@192.168.0.83;user=phone>", s.AgentName)
|
|
postfix := "192.168.0.83"
|
|
var callid string
|
|
if len(s.callID) != 0 {
|
|
callid = s.callID
|
|
//if len(s.regiCallID) != 0 {
|
|
//callid = s.regiCallID
|
|
} else {
|
|
callid = sipasm.GenerateCallID(postfix)
|
|
}
|
|
cseq := fmt.Sprintf("%d INVITE", s.Cseq)
|
|
s.Cseq++
|
|
// contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
contact := fmt.Sprintf("<sip:%s@192.168.0.83:5090>", inviteto)
|
|
//expires := fmt.Sprintf("%d", conf.AgentConfig[s.ID].RegisterConfig.RegisterExpire)
|
|
// userAgent := conf.InfoConfig.Product
|
|
userAgent := "M800B/v.7.20A.204.759"
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "em,100rel,timer,replaces,path,resource-priority,sdp-anat"
|
|
|
|
formats := strings.Split(format, " ")
|
|
// reqInvite.SDP = sipasm.NewSDPMessage(ip, mediaPort, formats[:], 0)
|
|
reqInvite.SDP = sipasm.NewSDPMessage("192.168.0.83", mediaPort, formats[:], 0)
|
|
sdpLength := fmt.Sprintf("%d", len(reqInvite.SDP.String()))
|
|
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, from)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, to)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
//reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_EXPIRES, expires)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_TYPE, "application/sdp")
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, sdpLength)
|
|
reqInvite.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqInvite.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
|
|
s.callID = callid
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_CALLING)
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqInvite.String())
|
|
}
|
|
inviteFunc()
|
|
}
|
|
|
|
//response invite
|
|
func (s *IcsSession) ProcInvite(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
// TODO - send bye
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "%s \n%s",
|
|
icserror.ICSERRNETNotConnectError.GetMessage(), debug.Stack())
|
|
|
|
}
|
|
}()
|
|
s.referto = sip.XAICall
|
|
|
|
name1 := strings.SplitN(sip.To, "@", 2)
|
|
name2 := strings.SplitN(name1[0], ":", 2)
|
|
ac := FindAgentConfig(name2[1])
|
|
if ac == nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
icserror.ICSERRUnkown.GetMessage())
|
|
s.ResError(sip, 400)
|
|
return icserror.ICSERRUnkown
|
|
}
|
|
s.SetAgentConfig(ac)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent config - %+v", ac)
|
|
|
|
ai := FindAgentInfo(name2[1])
|
|
if ai == nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
icserror.ICSERRUnkown.GetMessage())
|
|
s.ResError(sip, 400)
|
|
return icserror.ICSERRUnkown
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent Info - %+v", ai)
|
|
s.SetAgentInfo(ai)
|
|
|
|
ip := conf.InfoConfig.ServerIP
|
|
sipPort := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
format := s.AgentConf.MediaConfig.Format
|
|
mediaPort := s.AgentConf.MediaConfig.Port
|
|
|
|
ierr := s.Init()
|
|
if ierr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Session Init Error - %d",
|
|
ierr.GetMessage())
|
|
s.ResError(sip, 500)
|
|
return ierr
|
|
}
|
|
|
|
status := s.GetAgentStatus()
|
|
if status == STATUS_AGENT_READY || status == STATUS_AGENT_CALLING {
|
|
//reset rx cnt
|
|
s.rxCnt = 0
|
|
|
|
//get remote rtp addr in SDP
|
|
//fmt.Println("invite > method type", sip.Method, sip.Content)
|
|
rport, perr := s.findSDPMediaAudioPort(sip)
|
|
if perr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Audio Port [%d] - %s",
|
|
rport, perr.GetMessage())
|
|
s.ResError(sip, 500)
|
|
return perr
|
|
}
|
|
sdpConnectInfo := strings.Split(sip.Content.Connection, " ")
|
|
remoteIP := sdpConnectInfo[len(sdpConnectInfo)-1]
|
|
remoteAddrs := fmt.Sprintf("%s:%d", remoteIP, rport)
|
|
remoteAddr := icsnet.NewNetAddrWithIPAddr(remoteAddrs)
|
|
//connect to remote RTP
|
|
s.rtpMediaNeter.SetRemoteAddr(&remoteAddr)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set media remote address - %s(%s)", remoteAddr, s.rtpMediaNeter.RemoteAddr())
|
|
/*
|
|
cerr := s.rtpMediaNeter.Connect(nil, &remoteAddr)
|
|
if cerr != nil {
|
|
fmt.Println("CONNECTION FAIL!!!", cerr)
|
|
}
|
|
*/
|
|
|
|
/*
|
|
//send 100 trying
|
|
s.SetAgentStatus(STATUS_AGENT_CALLING)
|
|
res100 := sipasm.NewSIPResponse(sip, 100)
|
|
res100.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res100.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, "0")
|
|
res100.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
//fmt.Println(res100)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res100.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res100.String())
|
|
*/
|
|
//send 200 ok
|
|
res200 := sipasm.NewSIPResponse(sip, 200)
|
|
formats := strings.Split(format, " ")
|
|
s.invitePayloads = formats
|
|
m := *sip.Content.Media
|
|
mLen := len(m)
|
|
var sendrecv int
|
|
for iter1 := 0; iter1 < mLen; iter1++ {
|
|
for iter2 := 0; iter2 < mLen; iter2++ {
|
|
if strings.Contains(m[iter1].Attributes[iter2], "sendrecv") {
|
|
sendrecv = 0
|
|
break
|
|
} else if strings.Contains(m[iter1].Attributes[iter2], "sendonly") {
|
|
sendrecv = 2
|
|
break
|
|
} else if strings.Contains(m[iter1].Attributes[iter2], "recvonly") {
|
|
sendrecv = 1
|
|
break
|
|
}
|
|
}
|
|
}
|
|
res200.SDP = sipasm.NewSDPMessage(ip, mediaPort, formats[:1], sendrecv)
|
|
|
|
//set payload
|
|
payload, err := s.compareSDPMediaPayload(sip)
|
|
if err != nil {
|
|
l.Print(icslog.LOG_LEVEL_ERROR, s.ID, "Not found payload type")
|
|
//TODO: should response error sip message
|
|
s.ResError(sip, 500)
|
|
return err
|
|
}
|
|
s.payloadType = icspacketparser.PayloadType(payload)
|
|
//create media decoder
|
|
var cerr *icserror.IcsError
|
|
/*
|
|
s.TxConverter, cerr = icsmediaconv.NewConverter(s.ID, s.payloadType, false)
|
|
if cerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_FATAL, s.ID, "Failed to New Tx Converter-%v", cerr)
|
|
return cerr
|
|
} else {
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "New Tx Converter(Decoder)")
|
|
}
|
|
*/
|
|
s.RxConverter, cerr = icsmediaconv.NewConverter(s.ID, s.payloadType, true)
|
|
if cerr != nil {
|
|
//s.isFoundPayload = false
|
|
l.Printf(icslog.LOG_LEVEL_FATAL, s.ID, "Failed to New Rx Converter-%v", cerr)
|
|
s.ResError(sip, 415)
|
|
return cerr
|
|
} else {
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "New Rx Converter(Decoder)")
|
|
}
|
|
|
|
//fmt.Printf("%v\n", res200.SDP.String())
|
|
//fmt.Println(res200)
|
|
|
|
//s.callID = sip.CallID
|
|
/////////////////////////////////////////////
|
|
//set call signal addr
|
|
csraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.Port)
|
|
//csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
/*
|
|
csraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].Port)
|
|
csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
*/
|
|
|
|
//set Voice addr
|
|
vraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.VoicePort)
|
|
//vraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].VoicePort)
|
|
|
|
s.VoiceNeter = icsnet.NewUDP(nil, &vraddr)
|
|
//s.VoiceNeter = icsnet.NewUDP(&vladdr, &vraddr)
|
|
conerr := s.VoiceNeter.Connect(nil, nil)
|
|
if conerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Error init Voice Neter[%s->%s]-%v", s.VoiceNeter.LocalAddr().String(), vraddr.String(), conerr.GetError())
|
|
s.ResError(sip, 500)
|
|
return conerr
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Voice(UDP) Connected to VoiceAgent[%s->%s]", s.VoiceNeter.LocalAddr().String(), vraddr.String())
|
|
|
|
////////////////////////////////////////
|
|
//send call signal data to VoiceAgent
|
|
// defer func() {
|
|
// if err := recover(); err != nil {
|
|
// l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "%s [%s]\n%s",
|
|
// icserror.ICSERRNETNotConnectError.GetMessage(), csraddr, debug.Stack())
|
|
// }
|
|
// }()
|
|
var inout string = "O"
|
|
s.SetDirection(true)
|
|
if s.GetDirection() {
|
|
inout = "I"
|
|
}
|
|
callsignal := writecallsignal.NewCallSignalData()
|
|
s.StartTimeStamp = time.Now().UnixNano()
|
|
s.ChannelID = conf.GetChannelID()
|
|
s.ServerID = conf.GetServerID()
|
|
//TODO : agent conf
|
|
//station := conf.AgentConfig[s.ID].Name
|
|
s.Station = s.AgentInfo.Name
|
|
fmt.Println("s.Station = s.AgentInfo.Name>>>>>", s.Station)
|
|
///////////
|
|
cust1 := strings.SplitN(sip.From, "@", 2)
|
|
cust2 := strings.SplitN(cust1[0], ":", 2)
|
|
s.CustID = cust2[1]
|
|
//////////
|
|
callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, 0, "S", inout)
|
|
t, _, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
if werr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-Start signal to VoiceAgent(%s)", werr.GetError())
|
|
if t != nil {
|
|
s.ResError(sip, 502)
|
|
t.Close()
|
|
}
|
|
s.ResError(sip, 502)
|
|
// Before not return => not stop call process
|
|
return werr
|
|
} else {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call-Start signal to VoiceAgent - channelid: %s, serverid: %d, station: %s, Custom: %s, starttimestamp: %d, START, inout: %s\n",
|
|
s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, inout)
|
|
}
|
|
//t, wlen, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
//t, wlen, werr := icsnet.SendCallSignal(&csladdr, &csraddr, callsignal.GetData())
|
|
/*
|
|
if werr == nil {
|
|
defer t.Close()
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call-Start signal to VoiceAgent(%d)", wlen)
|
|
///////////////////////////////////
|
|
// recv TTS data
|
|
//recv tts header
|
|
ttsHeader, rlen, rerr := t.Read(36)
|
|
if rerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to recv TTS header(%d,%s)", rlen, rerr.GetError())
|
|
//return rerr
|
|
}
|
|
ttscmd := binary.LittleEndian.Uint32(ttsHeader[0:])
|
|
ttsrc := binary.LittleEndian.Uint32(ttsHeader[4:])
|
|
ttspl := binary.LittleEndian.Uint64(ttsHeader[8:])
|
|
agentname := string(ttsHeader[16:])
|
|
//remove null terminator
|
|
n := bytes.Index([]byte(agentname), []byte{0})
|
|
agentName := string([]byte(agentname)[:n])
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Recved TTS header(%d) AgentName: %s, Command: %d result code: %d, payload length: %d",
|
|
rlen, agentName, ttscmd, ttsrc, ttspl)
|
|
//recv tts data
|
|
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())
|
|
//return rerr
|
|
}
|
|
s.m.Lock()
|
|
s.tts = make([]byte, int(ttspl))
|
|
copy(s.tts, tts)
|
|
s.m.Unlock()
|
|
//s.tts = tts
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Recved TTS data. Length: %d", len(s.tts))
|
|
} else {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-Start signal to VoiceAgent(%s)", werr.GetError())
|
|
if t != nil {
|
|
t.Close()
|
|
}
|
|
//return rerr
|
|
}
|
|
*/
|
|
|
|
/*
|
|
//////////////////////
|
|
//RTP start
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "Started RTP sender Callback")
|
|
s.txCnt = 0
|
|
s.callStartTime = time.Now()
|
|
s.RTPSenderCallBackTimer.Start()
|
|
*/
|
|
|
|
//set sip resp header
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
sdpLength := fmt.Sprintf("%d", len(res200.SDP.String()))
|
|
supported := "timer, path, replaces, sdp-anat"
|
|
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_TYPE, "application/sdp")
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, sdpLength)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res200.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res200.String())
|
|
s.txCnt = 0
|
|
s.callStartTime = time.Now()
|
|
s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
/*////
|
|
time.Sleep(3000 * time.Millisecond)
|
|
s.RequestRefer(sip)
|
|
*/
|
|
} else if status == STATUS_AGENT_BUSY {
|
|
if strings.Contains(strings.ToUpper(sip.Supported), "SDP-ANAT") {
|
|
//send 486 busy
|
|
res486 := sipasm.NewSIPResponse(sip, 486)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res486.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
//s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res486.String())
|
|
} else {
|
|
//send 486 busy
|
|
res486 := sipasm.NewSIPResponse(sip, 486)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res486.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res486.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
//s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res486.String())
|
|
//remove session
|
|
//s.RemoveSession()
|
|
}
|
|
//TODO:re-Invite
|
|
} else {
|
|
//TODO: send error response
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//response invite
|
|
func (s *IcsSession) ProcACKInvite(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
///////////////////////////////////////////
|
|
///////////////////////////////////////////
|
|
// set agentinfo
|
|
name1 := strings.SplitN(sip.To, "@", 2)
|
|
name2 := strings.SplitN(name1[0], ":", 2)
|
|
ac := FindAgentConfig(name2[1])
|
|
if ac == nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
icserror.ICSERRUnkown.GetMessage())
|
|
s.ResError(sip, 400)
|
|
return icserror.ICSERRUnkown
|
|
}
|
|
s.SetAgentConfig(ac)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent config - %+v", ac)
|
|
|
|
ai := FindAgentInfo(name2[1])
|
|
if ai == nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
icserror.ICSERRUnkown.GetMessage())
|
|
s.ResError(sip, 400)
|
|
return icserror.ICSERRUnkown
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent Info - %+v", ai)
|
|
s.SetAgentInfo(ai)
|
|
|
|
ierr := s.Init()
|
|
if ierr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Session Init Error - %d",
|
|
ierr.GetMessage())
|
|
s.ResError(sip, 500)
|
|
return ierr
|
|
}
|
|
|
|
ip := conf.InfoConfig.ServerIP
|
|
//mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
sipPort := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
status := s.GetAgentStatus()
|
|
if status == STATUS_AGENT_CALLING {
|
|
ackMethod := fmt.Sprintf("sip:01025670081@%s;transport=%s", "192.168.0.222:5090", transport)
|
|
|
|
reqAck := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_ACK, ackMethod)
|
|
|
|
//via := fmt.Sprintf("SIP/2.0/UDP %s;rport;branch=%s", ip, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
//from := fmt.Sprintf("<sip:%s@%s:5090>;tag=%s", s.AgentName, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
//to := fmt.Sprintf("<sip:%s@%s;user=phone>", "01025670081", "192.168.0.221")
|
|
//to := fmt.Sprintf("<sip:%s@%s;user=phone>", "01025670081", ip)
|
|
//to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
//cseq := fmt.Sprintf("%d INVITE", s.Cseq)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
|
|
if sip.Source == "200" {
|
|
//get remote rtp addr in SDP
|
|
//fmt.Println("invite > method type", sip.Method, sip.Content)
|
|
rport, perr := s.findSDPMediaAudioPort(sip)
|
|
if perr != nil {
|
|
return perr
|
|
}
|
|
sdpConnectInfo := strings.Split(sip.Content.Connection, " ")
|
|
remoteIP := sdpConnectInfo[len(sdpConnectInfo)-1]
|
|
remoteAddrs := fmt.Sprintf("%s:%d", remoteIP, rport)
|
|
//fmt.Println("remote RTP addr:", remoteAddrs)
|
|
remoteAddr := icsnet.NewNetAddrWithIPAddr(remoteAddrs)
|
|
//connect to remote RTP
|
|
s.rtpMediaNeter.SetRemoteAddr(&remoteAddr)
|
|
|
|
//set payload
|
|
formats := strings.Split(format, " ")
|
|
s.invitePayloads = formats
|
|
payload, err := s.compareSDPMediaPayload(sip)
|
|
if err != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Not found payload type - %s", err.GetError().Error())
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Not found payload type - %s", sip.Content)
|
|
//TODO: should response error sip message
|
|
return err
|
|
}
|
|
s.payloadType = icspacketparser.PayloadType(payload)
|
|
var cerr *icserror.IcsError
|
|
s.RxConverter, cerr = icsmediaconv.NewConverter(s.ID, s.payloadType, true)
|
|
if cerr != nil {
|
|
//s.isFoundPayload = false
|
|
l.Printf(icslog.LOG_LEVEL_FATAL, s.ID, "Failed to New Rx Converter-%v", cerr)
|
|
s.ResError(sip, 415)
|
|
return cerr
|
|
} else {
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "New Rx Converter(Decoder)")
|
|
}
|
|
}
|
|
|
|
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).WriteSIP([]byte(reqAck.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
if sip.Source == "200" {
|
|
//RTP start
|
|
s.txCnt = 0
|
|
s.callStartTime = time.Now()
|
|
// s.RTPSenderCallBackTimer.Start()
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
s.RTPSenderCallBackTimer.Start()
|
|
}
|
|
|
|
///////////////////////////////////////////
|
|
///////////////////////////////////////////
|
|
// set agentinfo
|
|
// name1 := strings.SplitN(sip.To, "@", 2)
|
|
// name2 := strings.SplitN(name1[0], ":", 2)
|
|
// ac := FindAgentConfig(name2[1])
|
|
// if ac == nil {
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
// icserror.ICSERRUnkown.GetMessage())
|
|
// s.ResError(sip, 400)
|
|
// return icserror.ICSERRUnkown
|
|
// }
|
|
// s.SetAgentConfig(ac)
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent config - %+v", ac)
|
|
|
|
// ai := FindAgentInfo(name2[1])
|
|
// if ai == nil {
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Agent Name - %s",
|
|
// icserror.ICSERRUnkown.GetMessage())
|
|
// s.ResError(sip, 400)
|
|
// return icserror.ICSERRUnkown
|
|
// }
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Found Agent Info - %+v", ai)
|
|
// s.SetAgentInfo(ai)
|
|
|
|
// ierr := s.Init()
|
|
// if ierr != nil {
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Session Init Error - %d",
|
|
// ierr.GetMessage())
|
|
// s.ResError(sip, 500)
|
|
// return ierr
|
|
// }
|
|
|
|
//set payload
|
|
// payload, err := s.compareSDPMediaPayload(sip)
|
|
// if err != nil {
|
|
// l.Print(icslog.LOG_LEVEL_ERROR, s.ID, "Not found payload type")
|
|
// //TODO: should response error sip message
|
|
// s.ResError(sip, 500)
|
|
// return err
|
|
// }
|
|
// s.payloadType = icspacketparser.PayloadType(payload)
|
|
|
|
// set audio port
|
|
// rport, perr := s.findSDPMediaAudioPort(sip)
|
|
// if perr != nil {
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Could not found Audio Port [%d] - %s",
|
|
// rport, perr.GetMessage())
|
|
// }
|
|
// sdpConnectInfo := strings.Split(sip.Content.Connection, " ")
|
|
// remoteIP := sdpConnectInfo[len(sdpConnectInfo)-1]
|
|
// remoteAddrs := fmt.Sprintf("%s:%d", remoteIP, rport)
|
|
// remoteAddr := icsnet.NewNetAddrWithIPAddr(remoteAddrs)
|
|
// //connect to remote RTP
|
|
// s.rtpMediaNeter.SetRemoteAddr(&remoteAddr)
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set media remote address - %s(%s)", remoteAddr, s.rtpMediaNeter.RemoteAddr())
|
|
|
|
|
|
///////////////////////////////////////////
|
|
///////////////////////////////////////////
|
|
// send call signal
|
|
// var inout string = "O"
|
|
// s.SetDirection(true)
|
|
// if s.GetDirection() {
|
|
// inout = "I"
|
|
// }
|
|
// csraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.Port)
|
|
// callsignal := writecallsignal.NewCallSignalData()
|
|
// s.StartTimeStamp = time.Now().UnixNano()
|
|
// s.ChannelID = conf.GetChannelID()
|
|
// s.ServerID = conf.GetServerID()
|
|
// //TODO : agent conf
|
|
// //station := conf.AgentConfig[s.ID].Name
|
|
// s.Station = s.AgentInfo.Name
|
|
// fmt.Println("s.Station = s.AgentInfo.Name>>>>>", s.Station)
|
|
// ///////////
|
|
// cust1 := strings.SplitN(sip.From, "@", 2)
|
|
// cust2 := strings.SplitN(cust1[0], ":", 2)
|
|
// s.CustID = cust2[1]
|
|
// //////////
|
|
// callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, 0, "S", inout)
|
|
// t, _, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
// if werr != nil {
|
|
// fmt.Println("Failed to send Call-Start ", werr.GetError())
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-Start signal to VoiceAgent(%s)", werr.GetError())
|
|
// if t != nil {
|
|
// s.ResError(sip, 502)
|
|
// t.Close()
|
|
// }
|
|
// s.ResError(sip, 502)
|
|
// // Before not return => not stop call process
|
|
// return werr
|
|
// } else {
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call-Start signal to VoiceAgent - channelid: %s, serverid: %d, station: %s, Custom: %s, starttimestamp: %d, START, inout: %s\n",
|
|
// s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, inout)
|
|
// }
|
|
// fmt.Println("Send Call Signal to 83 VAB")
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Send Call Signal to 83 VAB")
|
|
///////////////////////////////////////////
|
|
///////////////////////////////////////////
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqAck.String())
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//for cancel method
|
|
func (s *IcsSession) ProcInvite487(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
//mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
sipPort := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
//format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
//status := s.GetAgentStatus()
|
|
//send 487 Request Terminiated
|
|
res487 := sipasm.NewSIPResponse(sip, 487)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
res487.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res487.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res487.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res487.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
//s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
s.callEndTime = time.Now()
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res487.String())
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *IcsSession) ProcCancel(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
//mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
sipPort := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
//format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
//status := s.GetAgentStatus()
|
|
//send 200 ok
|
|
res200 := sipasm.NewSIPResponse(sip, 200)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res200.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
//s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
s.callEndTime = time.Now()
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res200.String())
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_CANCELING)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *IcsSession) ProcBye(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
//mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
sipPort := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
//format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
////////////////////////////////////////
|
|
//send call signal-end to VoiceAgent
|
|
/////////////////////////////////////////////
|
|
//set call signal addr
|
|
csraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.Port)
|
|
//csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
/*
|
|
csraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].Port)
|
|
csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
*/
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "%s %s\n%s",
|
|
icserror.ICSERRNETNotConnectError.GetMessage(), csraddr, debug.Stack())
|
|
}
|
|
}()
|
|
var inout string = "O"
|
|
s.SetDirection(true)
|
|
if s.GetDirection() {
|
|
inout = "I"
|
|
}
|
|
callsignal := writecallsignal.NewCallSignalData()
|
|
s.StartTimeStamp = time.Now().UnixNano()
|
|
s.EndTimeStamp = time.Now().UnixNano()
|
|
s.ChannelID = conf.GetChannelID()
|
|
s.ServerID = conf.GetServerID()
|
|
station := conf.AgentConfig[s.ID].Name
|
|
s.Station = station
|
|
///////////
|
|
cust1 := strings.SplitN(sip.From, "@", 2)
|
|
cust2 := strings.SplitN(cust1[0], ":", 2)
|
|
s.CustID = cust2[1]
|
|
//////////
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG2, s.ID, ">>>>>channelid: %s, serverid: %d, station: %s, Custom: %s, starttimestamp: %d, START, inout: %s\n",
|
|
s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, inout)
|
|
callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, s.EndTimeStamp, "E", inout)
|
|
// t, wlen, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
//t, wlen, werr := icsnet.SendCallSignal(&csladdr, &csraddr, callsignal.GetData())
|
|
// if werr != nil {
|
|
// l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-End signal to VoiceAgent(%s)", werr.GetError())
|
|
// } else {
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call-End signal to VoiceAgent(%d)", wlen)
|
|
// defer t.Close()
|
|
// }
|
|
//close voiceneter(voice connection to voice agent)
|
|
if s.VoiceNeter != nil {
|
|
s.VoiceNeter.Close()
|
|
}
|
|
////////////////////////////////////////
|
|
|
|
//status := s.GetAgentStatus()
|
|
//send 200 ok
|
|
res200 := sipasm.NewSIPResponse(sip, 200)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, sipPort, transport)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, conf.InfoConfig.Product)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res200.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return werr
|
|
}
|
|
|
|
//s.SetAgentStatus(STATUS_AGENT_BUSY)
|
|
|
|
s.callEndTime = time.Now()
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res200.String())
|
|
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
|
|
s.AgentConf = nil
|
|
s.AgentInfo = nil
|
|
|
|
return nil
|
|
}
|
|
|
|
// SIM
|
|
func (s *IcsSession) SendRequestInvite() {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
fmt.Println("######### sim loop count!! ", conf.SimLoopCount)
|
|
fmt.Printf("Send Call Start Sip(%s) count %d!!!!!!!", s.AgentName, s.simLoopCount)
|
|
if s.simLoopCount < conf.SimLoopCount {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Send Call Start Sip(%s) count %d!!!!!!!", s.AgentName, s.simLoopCount)
|
|
s.RequestInvite("01024342788")
|
|
// fmt.Printf("Sent Call Start sip(%s) count (%d)\n\n", s.AgentName, s.simLoopCount)
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call Start sip(%s) count (%d)", s.AgentName, s.simLoopCount)
|
|
// tmp := "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.83;received=192.168.0.21;rport=5090;branch=N2IwOGJjNmYtMTY5Zi00Y2NkLThjYzAtYWVhOTg3OGMyYTdj\r\nFrom: <sip:%s@192.168.83>;tag=MTY1MDk1NTEwNTY4NzgzNjI3NQ--\r\nTo: <sip:%s@192.168.0.83>;tag=1c1466330427\r\nCall-ID: 6a0b9cc3-e0c6-48da-a4f8-e7c40003bab2@192.168.0.21\r\nCSeq: 2 OPTIONS\r\nContact: <sip:192.168.0.222:5090>\r\nServer: M800B/v.7.20A.204.759\r\nContent-Length: 0\r\n"
|
|
// sendVal := []string{fmt.Sprintf(tmp, s.AgentName, s.AgentName)}
|
|
// address, err := net.ResolveUDPAddr("udp", "192.168.0.83:5090")
|
|
// if err != nil {
|
|
// fmt.Printf("ERROR!: %s\n", err)
|
|
// }
|
|
// conn, err := net.DialUDP("udp", nil, address)
|
|
// if err != nil {
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "connect err", err)
|
|
// fmt.Println("## connect err", err)
|
|
// }
|
|
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "send val - %s", []string(sendVal))
|
|
// for _, elem := range sendVal[:] {
|
|
// sent, err := conn.Write([]byte(elem))
|
|
// if err != nil {
|
|
// fmt.Printf("sent %d-%s\n", sent, elem)
|
|
// }
|
|
|
|
// time.Sleep(time.Millisecond * 100)
|
|
// }
|
|
s.simLoopCount += 1
|
|
} else {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Send Call Start Sip(%s) END!!!!!!!", s.AgentName, s.simLoopCount)
|
|
}
|
|
}
|
|
|
|
func (s *IcsSession) ProcSIP20Bye(sip *icspacketparser.SIP) *icserror.IcsError {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
//ip := conf.InfoConfig.ServerIP
|
|
//mediaPort := conf.AgentConfig[s.ID].MediaConfig.Port
|
|
//sipPort := conf.SIPConfig.Port
|
|
//transport := conf.SIPConfig.Transport
|
|
//format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "SIP2.0 BYE")
|
|
////////////////////////////////////////
|
|
//send call signal-end to VoiceAgent
|
|
/////////////////////////////////////////////
|
|
//set call signal addr
|
|
csraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.Port)
|
|
//csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
/*
|
|
csraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].Port)
|
|
csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort)
|
|
*/
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "%s %s\n%s",
|
|
icserror.ICSERRNETNotConnectError.GetMessage(), csraddr, debug.Stack())
|
|
}
|
|
}()
|
|
var inout string = "O"
|
|
s.SetDirection(true)
|
|
if s.GetDirection() {
|
|
inout = "I"
|
|
}
|
|
callsignal := writecallsignal.NewCallSignalData()
|
|
s.StartTimeStamp = time.Now().UnixNano()
|
|
s.EndTimeStamp = time.Now().UnixNano()
|
|
s.ChannelID = conf.GetChannelID()
|
|
s.ServerID = conf.GetServerID()
|
|
station := conf.AgentConfig[s.ID].Name
|
|
s.Station = station
|
|
///////////
|
|
cust1 := strings.SplitN(sip.From, "@", 2)
|
|
cust2 := strings.SplitN(cust1[0], ":", 2)
|
|
s.CustID = cust2[1]
|
|
//////////
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG2, s.ID, ">>>>>channelid: %s, serverid: %d, station: %s, Custom: %s, starttimestamp: %d, START, inout: %s\n",
|
|
s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, inout)
|
|
callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, s.EndTimeStamp, "E", inout)
|
|
t, wlen, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
//t, wlen, werr := icsnet.SendCallSignal(&csladdr, &csraddr, callsignal.GetData())
|
|
defer t.Close()
|
|
if werr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-End signal to VoiceAgent(%s)", werr.GetError())
|
|
} else {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Call-End signal to VoiceAgent(%d)", wlen)
|
|
}
|
|
//close voiceneter(voice connection to voice agent)
|
|
if s.VoiceNeter != nil {
|
|
s.VoiceNeter.Close()
|
|
}
|
|
|
|
s.RemoveSession()
|
|
|
|
return nil
|
|
}
|
|
|
|
//rtp sender callback timer function
|
|
func (s *IcsSession) SendRTPCB(t *icscbtimer.IcsCBTimer) {
|
|
l := icslog.GetIcsLog()
|
|
//conf := icsconf.GetIcsConfig()
|
|
//format := conf.AgentConfig[s.ID].MediaConfig.Format
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "%s\n%s",
|
|
icserror.ICSERRNETNotConnectError.GetMessage(), debug.Stack())
|
|
}
|
|
}()
|
|
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "Started Callback SendRTPCB")
|
|
//fmt.Printf(">>>>>neter: %d %+v\n", s.ID, s.rtpMediaNeter)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "RTP Payload : %d [%p], Destination: %+v",
|
|
s.payloadType,
|
|
&s.rtpMediaNeter,
|
|
s.rtpMediaNeter)
|
|
|
|
//init rtp info of session
|
|
//ssrc
|
|
seed := rand.NewSource(time.Now().UnixNano())
|
|
r1 := rand.New(seed)
|
|
s.rtpSSRC = uint32(r1.Intn(999999999))
|
|
//seq
|
|
seed = rand.NewSource(time.Now().UnixNano())
|
|
r1 = rand.New(seed)
|
|
s.rtpSeq = uint16(r1.Intn(9999))
|
|
//timestamp
|
|
s.rtpTS = uint32(time.Now().Unix())
|
|
|
|
//s.TX
|
|
// iter := 0
|
|
// totalSentLen := 0
|
|
// offset := 0
|
|
// psize := icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
// ts := s.rtpTS
|
|
// seq := s.rtpSeq
|
|
|
|
|
|
// voiceFilePath := "/home/leejj9612/sim/voice/9001-RX-1648533187911907029.pcm"
|
|
voiceFilePath := "/home/leejj9612/sim/voice/Sample.pcm"
|
|
readPcmData, ferr := ioutil.ReadFile(voiceFilePath)
|
|
if ferr != nil {
|
|
fmt.Println("Read Voice File error ", ferr)
|
|
return
|
|
}
|
|
|
|
|
|
s.m.Lock()
|
|
// pcmDataLen := len(s.tts)
|
|
pcmDataLen := len(readPcmData)
|
|
pcmData := make([]byte, pcmDataLen)
|
|
copy(pcmData, readPcmData[44:]) //cut off wave header
|
|
//pcmData := s.tts[44:] //cut off wave header
|
|
//fmt.Println("pcmData len>>>", pcmDataLen, len(s.tts))
|
|
s.m.Unlock()
|
|
|
|
var cerr *icserror.IcsError
|
|
s.TxConverter, cerr = icsmediaconv.NewConverter(s.ID, s.payloadType, false)
|
|
if cerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_FATAL, s.ID, "Failed to New Tx Converter-%v", cerr)
|
|
return
|
|
} else {
|
|
l.Print(icslog.LOG_LEVEL_INFO, s.ID, "New Tx Converter(Encoder)")
|
|
}
|
|
//defer s.TxConverter.Close()
|
|
|
|
//fmt.Println(">>>", s.payloadType, icspacketparser.RTPPayloadInfo[s.payloadType].PSize)
|
|
var rtp *icsrtp.RTP
|
|
for {
|
|
iter := 0
|
|
totalSentLen := 0
|
|
offset := 0
|
|
psize := icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
ts := s.rtpTS
|
|
seq := s.rtpSeq
|
|
for t1 := range t.GetTick() {
|
|
if pcmDataLen < offset+psize*2 {
|
|
//fmt.Println("BREAK!", pcmDataLen, offset+psize*2)
|
|
break
|
|
}
|
|
payload, convErr := s.TxConverter.Encode(pcmData[offset : offset+psize*2])
|
|
//payload, convErr := s.TxConverter.Encode(s.tts[offset : offset+icspacketparser.RTPPayloadInfo[s.payloadType].PSize])
|
|
if convErr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Encoding Error - %s", convErr.GetError())
|
|
return
|
|
}
|
|
|
|
//fmt.Printf("1048@@@@ %+v\n", s.rtpMediaNeter)
|
|
/*
|
|
wflen, wferr := ttsfile1.Write(payload)
|
|
if wferr != nil {
|
|
fmt.Println("file.write error", wferr, wflen)
|
|
os.Exit(1)
|
|
}
|
|
ttsfile1.Sync()
|
|
*/
|
|
|
|
if iter == 0 {
|
|
if offset+psize >= pcmDataLen {
|
|
//if offset+psize >= alawDataLen {
|
|
offset = 0
|
|
}
|
|
rtp = icsrtp.NewRTP(1, //set mark bit
|
|
int(s.payloadType),
|
|
int(seq),
|
|
int(ts),
|
|
int(s.rtpSSRC),
|
|
payload)
|
|
//alawData[offset:offset+icspacketparser.RTPPayloadInfo[s.payloadType].PSize])
|
|
totalSentLen += icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
offset += psize * 2
|
|
//offset += icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
} else {
|
|
if offset+psize >= pcmDataLen {
|
|
//if offset+psize >= alawDataLen {
|
|
offset = 0
|
|
}
|
|
rtp = icsrtp.NewRTP(0,
|
|
int(s.payloadType),
|
|
int(seq),
|
|
int(ts),
|
|
int(s.rtpSSRC),
|
|
payload)
|
|
//alawData[offset:offset+icspacketparser.RTPPayloadInfo[s.payloadType].PSize])
|
|
totalSentLen += icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
offset += psize * 2
|
|
//offset += icspacketparser.RTPPayloadInfo[s.payloadType].PSize
|
|
}
|
|
iter++
|
|
ts += uint32(psize)
|
|
seq++
|
|
s.txCnt++
|
|
|
|
//fmt.Printf("1095@@@@ %+v\n", s.rtpMediaNeter)
|
|
wlen, werr := s.rtpMediaNeter.WriteRTP(rtp.Byte())
|
|
if werr != nil {
|
|
fmt.Println(t1, wlen, werr)
|
|
}
|
|
//fmt.Printf("wlen: %d\r", totalSentLen)
|
|
//l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent RTP(%d) to %s", wlen, s.rtpMediaNeter.RemoteAddr().String())
|
|
|
|
}
|
|
// fmt.Printf("Sent RTP(%d) to [%s] [%s]\r\n", totalSentLen, s.rtpMediaNeter.RemoteAddr().String(), s.AgentName )
|
|
// l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent RTP(%d) to %s", totalSentLen, s.rtpMediaNeter.RemoteAddr().String())
|
|
time.Sleep(time.Second)
|
|
}
|
|
}
|
|
|
|
func (s *IcsSession) ReadRTP() {
|
|
l := icslog.GetIcsLog()
|
|
svc := icssvc.GetServiceStatus()
|
|
conf := icsconf.GetIcsConfig()
|
|
|
|
/*
|
|
n := time.Now()
|
|
filename := fmt.Sprintf("./%daaabbb%d-2.pcm", s.ID, n.Nanosecond())
|
|
ttsfile, ferr := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND|os.O_TRUNC|os.O_SYNC, os.FileMode(0644))
|
|
if ferr != nil {
|
|
fmt.Println(ferr)
|
|
os.Exit(1)
|
|
}
|
|
//ttsfile.Write(tts)
|
|
defer ttsfile.Close()
|
|
*/
|
|
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Started ReadRTP - %s", s.rtpMediaNeter.LocalAddr())
|
|
|
|
s.readTimer = *time.NewTicker(time.Second)
|
|
// s.ExpTimer = icscbtimer.NewCBTimer(time.Second, s.ExpiredRTP)
|
|
// s.ExpTimer.Start()
|
|
// go s.ExpiredRTP(s.readTimer)
|
|
for !svc.GetExit() || !svc.GetStop() {
|
|
//fmt.Println(">>>", s.ID, s.rtpMediaNeter.LocalAddr().String())
|
|
|
|
if s.rtpMediaNeter == nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "######### media neter nil!!!")
|
|
break
|
|
}
|
|
|
|
data, _, rlen, rerr := s.rtpMediaNeter.ReadRTP()
|
|
//data, raddr, rlen, rerr := s.rtpMediaNeter.ReadRTP()
|
|
if rerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "%s-%s", rerr.GetMessage(), rerr.GetError())
|
|
break
|
|
}
|
|
//l.Printf(icslog.LOG_LEVEL_DEBUG2, s.ID, "Recved RTP from %s - %d", raddr.String(), rlen)
|
|
|
|
//parsing rtp
|
|
rtp := icspacketparser.NewRTP()
|
|
if err := rtp.RTPParser(data[:rlen]); err != nil {
|
|
l.Print(icslog.LOG_LEVEL_ERROR, s.ID, err.GetMessage())
|
|
continue
|
|
}
|
|
RPT := rtp.GetPayloadType()
|
|
|
|
if RPT == icspacketparser.PayloadType(101) { //rfc2833
|
|
///////////////
|
|
//dtmf
|
|
dtmf, derr := icsdtmf.DTMF(s.dtmf, rtp, nil)
|
|
if derr == icserror.ICSERRDTMFOK {
|
|
if s.BotStatus == recorddata.DTMF_COMMAND {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "DTMF : %s", dtmf)
|
|
s.RTPSenderCallBackTimer.Stop()
|
|
}
|
|
//fmt.Printf("DTMF : %s\n", dtmf)
|
|
|
|
csraddr := icsnet.NewNetAddrWithIPPort(s.AgentInfo.IP, s.AgentInfo.Port)
|
|
/*
|
|
var inout string = "O"
|
|
s.SetDirection(true)
|
|
if s.GetDirection() {
|
|
inout = "I"
|
|
}
|
|
*/
|
|
callsignal := writecallsignal.NewCallSignalData()
|
|
s.StartTimeStamp = time.Now().UnixNano()
|
|
s.ChannelID = conf.GetChannelID()
|
|
s.ServerID = conf.GetServerID()
|
|
//TODO : agent conf
|
|
//station := conf.AgentConfig[s.ID].Name
|
|
s.Station = s.AgentInfo.Name
|
|
callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, 0, "D", dtmf)
|
|
t, _, werr := icsnet.SendCallSignal(nil, &csraddr, callsignal.GetData())
|
|
if werr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Failed to send Call-Start signal to VoiceAgent(%s)", werr.GetError())
|
|
if t != nil {
|
|
t.Close()
|
|
}
|
|
} else {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent DTMF signal to VoiceAgent - channelid: %s, serverid: %d, station: %s, Custom: %s, starttimestamp: %d, DTMF: %s\n",
|
|
s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, dtmf)
|
|
}
|
|
|
|
} else if derr == icserror.ICSERRDTMFFail {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "DTMF error - %s", derr.GetError())
|
|
}
|
|
} else if RPT == icspacketparser.PayloadType(8) { //rfc2833{
|
|
// fmt.Println("Recev 21 TTS!!!")
|
|
s.expRead = time.Now()
|
|
s.expCheck = false
|
|
} else {
|
|
//rtp decoding
|
|
pcm, cerr := s.RxConverter.Decode(rtp.Payload)
|
|
if cerr != nil {
|
|
l.Print(icslog.LOG_LEVEL_ERROR, s.ID, cerr.GetMessage())
|
|
continue
|
|
}
|
|
//fmt.Println("payload len", len(rtp.Payload), rtp.PayloadLen, len(pcm))
|
|
//ttsfile.Write(pcm)
|
|
|
|
///////////////
|
|
//dtmf
|
|
dtmf, derr := icsdtmf.DTMF(s.dtmf, rtp, pcm)
|
|
if derr == nil {
|
|
if s.BotStatus == recorddata.DTMF_COMMAND {
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "DTMF : %s", dtmf)
|
|
s.RTPSenderCallBackTimer.Stop()
|
|
}
|
|
continue
|
|
} /*else if derr == icserror.ICSERRDTMFFail {
|
|
l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "DTMF error - %s", derr.GetError())
|
|
}*/
|
|
|
|
//send voice data to voice agent
|
|
if s.rxSeq == -1 {
|
|
s.rxSeq = int(rtp.Seq)
|
|
}
|
|
|
|
voicedata := recorddata.NewVoiceData()
|
|
voicedata.SetData(s.ServerID, s.Station, int32(rtp.Seq-uint16(s.rxSeq)), s.StartTimeStamp, "0", RPT, pcm)
|
|
_, werr := s.VoiceNeter.Write(voicedata.GetData())
|
|
//_, werr := s.VoiceNeter.WriteRTP(pcm)
|
|
if werr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "Voice writing error(%d) - %s", werr.GetCode(), werr.GetError())
|
|
break
|
|
// continue
|
|
}
|
|
s.rxCnt++
|
|
}
|
|
}
|
|
}
|
|
|
|
// func (s *IcsSession)ExpiredRTP(t *icscbtimer.IcsCBTimer) {
|
|
func (s *IcsSession)ExpiredRTP(t time.Ticker) {
|
|
s.mychannel = make(chan bool)
|
|
fmt.Println("### timer start")
|
|
// valCheckTimer := time.NewTicker(time.Second)
|
|
s.expRead = time.Now()
|
|
for {
|
|
select {
|
|
case <-s.mychannel:
|
|
return
|
|
case tm := <- t.C:
|
|
if s.expCheck {
|
|
fmt.Println("agent : ", s.AgentName , " ", tm)
|
|
} else if !s.expCheck {
|
|
if time.Now().Sub(s.expRead) > time.Second {
|
|
fmt.Printf("### session expired %s\n", s.AgentName)
|
|
s.RTPSenderCallBackTimer.Start()
|
|
s.expCheck = true
|
|
}
|
|
}
|
|
}
|
|
// if s.expCheck {
|
|
// fmt.Println(t)
|
|
// } else if !s.expCheck {
|
|
// if time.Now().Sub(s.expRead) > time.Second {
|
|
// fmt.Println("### session expired")
|
|
// s.RTPSenderCallBackTimer.Start()
|
|
// s.expCheck = true
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
func (s *IcsSession) ReadRTCP() {
|
|
l := icslog.GetIcsLog()
|
|
svc := icssvc.GetServiceStatus()
|
|
|
|
for !svc.GetExit() || !svc.GetStop() {
|
|
//fmt.Println("###", s.ID, s.rtcpMediaNeter.LocalAddr().String())
|
|
|
|
if s.rtcpMediaNeter == nil {
|
|
break
|
|
}
|
|
|
|
data, raddr, rlen, rerr := s.rtcpMediaNeter.ReadRTP()
|
|
if rerr != nil {
|
|
l.Printf(icslog.LOG_LEVEL_ERROR, s.ID, "%s-%s", rerr.GetMessage(), rerr.GetError())
|
|
break
|
|
}
|
|
|
|
rtp := icspacketparser.NewRTP()
|
|
if err := rtp.RTPParser(data[:rlen]); err != nil {
|
|
l.Print(icslog.LOG_LEVEL_ERROR, s.ID, err.GetMessage())
|
|
}
|
|
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG2, s.ID, "Recved RTCP from %s - %d", raddr.String(), rlen)
|
|
}
|
|
}
|
|
|
|
/*
|
|
//rtp recver callback timer function
|
|
func (s *IcsSession) RecverRTPCB() icsnet.RT
|
|
*/
|
|
|
|
//options callback timer function
|
|
func (s *IcsSession) RequestOptionsCB(t *icscbtimer.IcsCBTimer) {
|
|
l := icslog.GetIcsLog()
|
|
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
port := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
|
|
optfunc := func(t *time.Time) {
|
|
optMethod := fmt.Sprintf("sip:%s;transport=%s", ip, transport)
|
|
reqOpt := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_OPTIONS, optMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP %s;rport;branch=%s", ip, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := fmt.Sprintf("<sip:%s@%s>;tag=%s", s.AgentName, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
postfix := fmt.Sprintf("@%s", ip)
|
|
callid := sipasm.GenerateCallID(postfix)
|
|
cseq := fmt.Sprintf("%d OPTIONS", s.Cseq)
|
|
s.Cseq++
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
contentLength := "0"
|
|
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, from)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, to)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, contentLength)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqOpt.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG, s.ID, "Sent Data(%d) [%s]->[%s]> OPTIONS [%s]",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
callid)
|
|
}
|
|
optfunc(nil)
|
|
|
|
for t1 := range t.GetTick() {
|
|
//fmt.Println(s.ID, t1)
|
|
optfunc(&t1)
|
|
}
|
|
|
|
}
|
|
|
|
//refer callback timer function
|
|
func (s *IcsSession) RequestRefer(referto string, sip *icspacketparser.SIP) {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
port := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
|
|
optfunc := func() {
|
|
optMethod := fmt.Sprintf("sip:%s;transport=%s", ip, transport)
|
|
reqOpt := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_REFER, optMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP %s;rport;branch=%s", ip, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := strings.SplitN(sip.From, ": ", 2)[0]
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
callid := sip.GetCallID()
|
|
cseq := fmt.Sprintf("%d REFER", s.Cseq)
|
|
s.Cseq++
|
|
referto := fmt.Sprintf("<sip:%s>", s.referto)
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
contentLength := "0"
|
|
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, from)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, to)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_REFER_TO, referto)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, contentLength)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqOpt.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqOpt.String())
|
|
}
|
|
optfunc()
|
|
}
|
|
|
|
// refer notify 200ok
|
|
func (s *IcsSession) ProcReferNotify200ok(sip *icspacketparser.SIP) {
|
|
|
|
l := icslog.GetIcsLog()
|
|
|
|
optfunc := func() {
|
|
res200 := sipasm.NewSIPResponse(sip, 200)
|
|
res200.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(res200.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
return
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
res200.String())
|
|
s.txCnt = 0
|
|
s.callStartTime = time.Now()
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
}
|
|
optfunc()
|
|
}
|
|
|
|
//request bye
|
|
func (s *IcsSession) RequestBYE(inviteSIP *icspacketparser.SIP) {
|
|
l := icslog.GetIcsLog()
|
|
conf := icsconf.GetIcsConfig()
|
|
ip := conf.InfoConfig.ServerIP
|
|
port := conf.SIPConfig.Port
|
|
transport := conf.SIPConfig.Transport
|
|
fmt.Println(">>>contact", inviteSIP.Contact)
|
|
contactName1 := strings.SplitN(inviteSIP.Contact, "sip:", 2)
|
|
contactName := strings.SplitN(contactName1[1], "@", 2)
|
|
|
|
optfunc := func() {
|
|
optMethod := fmt.Sprintf("sip:%s@%s;transport=%s", contactName[0], conf.SIPConfig.SIPProxy, transport)
|
|
reqOpt := sipasm.NewSIPMessage(sipasm.ICSSIP_METHOD_BYE, optMethod)
|
|
|
|
via := fmt.Sprintf("SIP/2.0/UDP %s:%d;branch=%s", ip, port, sipasm.GenerateBranch())
|
|
maxforwards := "70"
|
|
from := strings.SplitN(inviteSIP.From, ": ", 2)
|
|
//from := fmt.Sprintf("<sip:%s@%s>;tag=%s", s.AgentName, ip, sipasm.GenerateTag())
|
|
|
|
s.uri = fmt.Sprintf("sip:%s@%s", s.AgentName, ip)
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Set URI [%s]", s.uri)
|
|
|
|
to := strings.SplitN(inviteSIP.To, ": ", 2)
|
|
//to := fmt.Sprintf("<sip:%s@%s>", s.AgentName, ip)
|
|
callid := inviteSIP.GetCallID()
|
|
cseq := fmt.Sprintf("%d BYE", s.Cseq)
|
|
s.Cseq++
|
|
//referto := fmt.Sprintf("<sip:01025670081@192.168.0.221>")
|
|
contact := fmt.Sprintf("<sip:%s@%s:%d;transport=%s>", s.AgentName, ip, port, transport)
|
|
userAgent := conf.InfoConfig.Product
|
|
allow := "REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE"
|
|
supported := "timer,path,replaces"
|
|
contentLength := "0"
|
|
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_VIA, via)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_MAX_FORWARDS, maxforwards)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_FROM, to[0])
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TO, from[0])
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CALL_ID, callid)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CSEQ, cseq)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTACT, contact)
|
|
//reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_REFER_TO, referto)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_USER_AGENT, userAgent)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_ALLOW, allow)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_SUPPORTED, supported)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_CONTENT_LENGTH, contentLength)
|
|
reqOpt.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(reqOpt.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_FATAL, s.ID, werr.GetMessage())
|
|
return
|
|
}
|
|
|
|
//l.Printf(icslog.LOG_LEVEL_WARN, s.ID, "BYE CALL STACK\n%s", debug.Stack())
|
|
|
|
l.Printf(icslog.LOG_LEVEL_DEBUG, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
reqOpt.String())
|
|
}
|
|
optfunc()
|
|
}
|
|
|
|
func (s *IcsSession) ResError(sip *icspacketparser.SIP, errNum int) {
|
|
var resError *sipasm.SIPMessage
|
|
l := icslog.GetIcsLog()
|
|
switch errNum { // 4xx : client error, 5xx~ : server error
|
|
case 400:
|
|
resError = sipasm.NewSIPResponse(sip, 400) // Bad requeset : request could not be understood by the server
|
|
case 415:
|
|
resError = sipasm.NewSIPResponse(sip, 415) // Unsupported Media Type
|
|
case 488:
|
|
resError = sipasm.NewSIPResponse(sip, 488) // Not Acceptable Here : Codec error
|
|
case 500:
|
|
resError = sipasm.NewSIPResponse(sip, 500) // Internal Server error : server encountered an unexpected condition
|
|
case 502:
|
|
resError = sipasm.NewSIPResponse(sip, 502) // Bad Gateway : The server, while acting as a gateway or proxy, received an invalid response from the upstream server
|
|
}
|
|
resError.AddSIPHeader(sipasm.ICSSIP_HEADER_TERMINATOR)
|
|
wlen, werr := (*s.sipNeter).WriteSIP([]byte(resError.String()))
|
|
if werr != nil {
|
|
l.Print(icslog.LOG_LEVEL_ERROR, s.ID, werr.GetMessage())
|
|
s.SetAgentStatus(STATUS_AGENT_READY)
|
|
}
|
|
l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Sent Data(%d) [%s]->[%s]>\n%s",
|
|
wlen,
|
|
(*s.sipNeter).LocalAddr().String(),
|
|
(*s.sipNeter).RemoteAddr().String(),
|
|
resError.String())
|
|
}
|