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

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())
}