package icssessionmanager import ( "strconv" "strings" "time" "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/icssvc" "gitlab.com/ics_cinnamon/voicegateway/recorddata/writecallsignal" ) func (s *IcsSession) analyzeSIP(sip *icspacketparser.SIP) *icserror.IcsError { // fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>") // fmt.Println("sip.Method", sip.Method) // fmt.Println("sip.Version", sip.Version) // fmt.Println("sip.Headers", sip.Headers) // fmt.Println("sip.Source", sip.Source) // fmt.Printf("%+v\n", sip) //fmt.Println(">>>>>>>>>>>>>>>>>>>>>>> sip.Method", sip.Method) l := icslog.GetIcsLog() // fmt.Println(">>>>>>>>>>>>>>>>>>>>>>> sip.Method", sip.Method) if sip.Method == icspacketparser.ICS_SIP_METHOD_INVITE { s.setSrcPort(sip) payload, err := s.setSDPMediaPayload(sip) if err != nil { return icserror.ICSERRSDPAudiotagPortValue } else { s.invitePayloads = payload } } else if strings.Contains(sip.Cseq, " INVITE") { s.setDstPort(sip) } if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 && !s.isFoundPayload { // fmt.Println(">>>>>>>>>>>>>>> ICS_SIP_METHOD_SIP20", sip.ResType, sip.ContentType, sip.ContentLength) if strings.Contains(sip.ContentType, "sdp") && sip.ContentLength > 0 { payload, err := s.compareSDPMediaPayload(sip) if err != nil { return icserror.ICSERRSDPAudiotagPortValue } else { s.isFoundPayload = true s.payloadType = icspacketparser.PayloadType(payload) //fmt.Println("s.payload >>>>>>>>>>>>>>>", s.payloadType) //create media decoder var cerr *icserror.IcsError s.TxConverter, cerr = icsmediaconv.NewConverter(s.ID, s.payloadType, true) if cerr != nil { //s.isFoundPayload = false //cerr.Print() 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) return cerr } else { l.Print(icslog.LOG_LEVEL_INFO, s.ID, "New Rx Converter(Decoder)") } //init VoiceAgent net and send call start signal conf := icssvc.GetServiceStatus().GetIcsConfig() if conf != nil { /* 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(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].VoicePort) */ //set call signal addr 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) //csraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentAddr.VoiceAgentIP, conf.VoiceAgentConfig.AgentAddr.CallSignalPort) //csladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.ServerPort) //set Voice addr vraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentInfo[s.ID].IP, conf.VoiceAgentConfig.AgentInfo[s.ID].VoicePort) //vraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentAddr.VoiceAgentIP, s.VoiceAgentPort) //vraddr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.AgentAddr.VoiceAgentIP, conf.VoiceAgentConfig.AgentAddr.VoicePort) //vladdr := icsnet.NewNetAddrWithIPPort(conf.VoiceAgentConfig.MyAddr.ServerIP, conf.VoiceAgentConfig.MyAddr.BasePort) 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()) 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.Print(icslog.LOG_LEVEL_WARN, s.ID, icserror.ICSERRNETNotConnectError.GetMessage()) } }() var inout string = "O" if s.GetDirection() { inout = "I" } callsignal := writecallsignal.NewCallSignalData() s.StartTimeStamp = time.Now().UnixNano() callsignal.SetData(s.ChannelID, s.ServerID, s.Station, s.CustID, s.StartTimeStamp, 0, "S", inout) t, wlen, werr := icsnet.SendCallSignal(&csladdr, &csraddr, callsignal.GetData()) if werr == nil { l.Printf(icslog.LOG_LEVEL_INFO, s.ID, "Transmitted Call-Start signal to VoiceAgent(%d)", wlen) if t != nil { t.Close() } } t.Close() } } } } return nil } func (s *IcsSession) setSrcPort(sip *icspacketparser.SIP) *icserror.IcsError { if sip.Content == nil { //error 처리 invite인데, sdp 데이터가 없음 return icserror.ICSERRINVITERequired } else { // fmt.Println("sdpMedias", *sip.Content.Media) port, err := s.findSDPMediaAudioPort(sip) if err != nil { return icserror.ICSERRSDPAudiotagPortValue } else { s.srcPort = port } } return nil } func (s *IcsSession) setDstPort(sip *icspacketparser.SIP) *icserror.IcsError { // fmt.Println(">>>>>>>>>>>>>>>>>>>>>>> sip.Cseq", sip.Cseq, sip.Method) if sip.Method == icspacketparser.ICS_SIP_METHOD_SIP20 && sip.ResType == "200" { if sip.Content == nil { //error 처리 INVITE처리의 200 OK인데, sdp 데이터가 없음 return icserror.ICSERR200OKRequired } else { // fmt.Println("sdpMedias", *sip.Content.Media) port, err := s.findSDPMediaAudioPort(sip) if err != nil { return icserror.ICSERRSDPAudiotagPortValue } else { s.dstPort = port } } } else if sip.Method == icspacketparser.ICS_SIP_METHOD_BYE { //fmt.Println(">>>>>>>>>>> haup up event") // s.RemoveSession() } return nil } func (s *IcsSession) findSDPMediaAudioPort(sip *icspacketparser.SIP) (int, *icserror.IcsError) { for _, value := range *sip.Content.Media { if strings.Contains(value.MediaDescription, "audio ") { arrSdpMedia := strings.Split(value.MediaDescription, " ") port, err := strconv.Atoi(arrSdpMedia[1]) if err != nil { return -1, icserror.ICSERRSDPAudiotagPortValue } else { //fmt.Println(">>>>>>>>>>>>>>>>>>>>>>> port", port) return port, nil } } else { return -1, icserror.ICSERRNotFoundSdpMedia } } return -1, icserror.ICSERRNotFoundSdpMedia } func (s *IcsSession) setSDPMediaPayload(sip *icspacketparser.SIP) ([]string, *icserror.IcsError) { for _, value := range *sip.Content.Media { if strings.Contains(value.MediaDescription, "audio ") { //fmt.Println("value.Payload >>>>>>>>>>>", value.Payload) return value.Payload, nil } else { return nil, icserror.ICSERRNotFoundSdpMedia } } return nil, icserror.ICSERRNotFoundSdpMedia } func (s *IcsSession) compareSDPMediaPayload(sip *icspacketparser.SIP) (int, *icserror.IcsError) { for _, value := range *sip.Content.Media { for _, thisPayload := range value.Payload { for _, invitePayload := range s.invitePayloads { ptNum, cerr := strconv.Atoi(thisPayload) if cerr != nil { return -1, icserror.ICSERRSDPAudiotagPortValue } name := icspacketparser.RTPPayloadInfo[icspacketparser.PayloadType(ptNum)].Name if name == invitePayload { //if thisPayload == invitePayload { payload, err := strconv.Atoi(thisPayload) if err != nil { return -1, icserror.ICSERRSDPAudiotagPortValue } else { return payload, nil } } } } } return -1, icserror.ICSERRNotFoundSdpMedia }