fixed RTP/CMoIP streaming

master
cheetah 8 months ago
parent b42323d518
commit a1a6c6d7ef

@ -10,5 +10,6 @@ type RegistrationInfo struct {
CallCount byte
StreamCount byte
RoamingRef uint32
Description string
RTPPorts []uint16
}

@ -0,0 +1,21 @@
package common
type TetraFlexCMoIPPayload byte
const (
TetraFlexCMoIPPayload_None TetraFlexCMoIPPayload = 0
TetraFlexCMoIPPayload_Tetra_STCH_U TetraFlexCMoIPPayload = 1
TetraFlexCMoIPPayload_Tetra_TCH_S TetraFlexCMoIPPayload = 2
TetraFlexCMoIPPayload_Tetra_TCH_7_2 TetraFlexCMoIPPayload = 3
TetraFlexCMoIPPayload_Tetra_TCH_4_8 TetraFlexCMoIPPayload = 4
TetraFlexCMoIPPayload_Tetra_TCH_2_4 TetraFlexCMoIPPayload = 5
TetraFlexCMoIPPayload_aLaw TetraFlexCMoIPPayload = 7
TetraFlexCMoIPPayload_uLaw TetraFlexCMoIPPayload = 8
)
type TetraFlexRTPPayload byte
const (
TetraFlexRTPPayload_uLaw TetraFlexRTPPayload = 0
TetraFlexRTPPayload_aLaw TetraFlexRTPPayload = 8
)

@ -8,6 +8,7 @@ import (
"fmt"
"io"
"net"
"strings"
"git.cheetah.cat/cheetah/opentetraflex-go/common/tmkind"
)
@ -24,6 +25,8 @@ type TerminalClient struct {
GroupConfig []GroupConfig
RegistrationInfo RegistrationInfo
udpRTP_TX *net.UDPConn
}
func NewTerminalClient(address string) (tc *TerminalClient) {
@ -184,6 +187,26 @@ func (tc *TerminalClient) CallConnect(callRef byte) (err error) {
return nil
}
func (tc *TerminalClient) CallStreamRequest(uint1 uint, callRef byte, streamRef byte, audioChannelType TetraFlexAudioChannelTypes) (err error) {
tfStreamReq, err := NewTMIpApiCallStreamRequest(uint1, callRef, streamRef, audioChannelType)
if err != nil {
return nil
}
fmt.Println(hex.EncodeToString(tfStreamReq.Encode()))
tc.HandlerMap[tfStreamReq.handler] = make(chan HandlerResponse)
//fmt.Println(hex.EncodeToString(tfAuthReq.Encode()))
err = tc.Send(tfStreamReq)
if err != nil {
return err
}
response := <-tc.HandlerMap[tfStreamReq.handler]
if !response.Success {
return response.Error
}
return nil
}
func (tc *TerminalClient) PTTRequest(callRef byte, identityInfo TetraFlexIdentityInfo, octaStateByte byte) (err error) {
// IpApiCallPttRequest
tfPTTRequest, err := NewTMIpApiCallPTTRequest(callRef, identityInfo, octaStateByte)
@ -226,6 +249,32 @@ func (tc *TerminalClient) PTTRelease(callRef byte) (err error) {
return nil
}
func (tc *TerminalClient) RTPConnect() (err error) {
portNum := tc.RegistrationInfo.RTPPorts[0]
localAddress, _ := net.ResolveUDPAddr("udp", fmt.Sprintf("0.0.0.0:%d", portNum))
parts := strings.Split(tc.address, ":")
remoteTXAddr := fmt.Sprintf("%s:%d", parts[0], portNum)
remoteAddress, _ := net.ResolveUDPAddr("udp", remoteTXAddr)
tc.udpRTP_TX, err = net.DialUDP("udp", localAddress, remoteAddress)
if err != nil {
return err
}
return nil
}
func (tc *TerminalClient) RTPSend(data []byte) (err error) {
//parts := strings.Split(tc.address, ":")
//remoteTXAddr := fmt.Sprintf("%s:%d", parts[0], tc.RegistrationInfo.RTPPorts[0])
//remoteAddress, _ := net.ResolveUDPAddr("udp", remoteTXAddr)
_, err = tc.udpRTP_TX.Write(data) //WriteToUDP(data, remoteAddress)
if err != nil {
return err
}
return nil
}
/*
groupAddr := common.NewAddressFromSSINumber(103)
identityNum := common.NewAddressFromSSINumber(1007)

@ -37,11 +37,11 @@ func NewTerminalMessage(length uint16, kind tmkind.TetraFlexTerminalMessageKinds
return tm, nil
}
// Write<Type> Functions
func (tm *TerminalMessage) WriteShort(data uint16) (err error) {
_, err = tm.data.Write(uint16ToBytes(data))
return err
}
func (tm *TerminalMessage) WriteUInt(data uint32) (err error) {
_, err = tm.data.Write(uint32ToBytes(data))
return err
@ -150,11 +150,9 @@ func (tm *TerminalMessage) WriteTFAddress(addr TetraFlexAddress) (err error) {
//return tm.data.WriteByte(data)
return nil
}
func (tm *TerminalMessage) WriteIdentityInfoAddress(identityInfo TetraFlexIdentityInfo) (err error) {
return tm.WriteTFAddress(identityInfo.Address)
}
func (tm *TerminalMessage) WriteIdentityInfoKind(identityInfo TetraFlexIdentityInfo) (err error) {
/*
case TetraFlexIdentityKind.Mobile:
@ -175,16 +173,15 @@ func (tm *TerminalMessage) WriteIdentityInfoUnfied(identityInfo TetraFlexIdentit
}
return tm.data.WriteByte(byteVal)
}
func (tm *TerminalMessage) FillZero(zeroCount uint32) (err error) {
_, err = tm.data.Write(make([]byte, zeroCount))
return err
}
func (tm *TerminalMessage) Encode() []byte {
return tm.data.Bytes()
}
// TerminalMessage Builder for PDUs
func NewTMAuthReq(addr TetraFlexAddress, num uint32, randomBytes []byte, terminalTypeID byte, terminalTypeStr string, terminalVersionDate uint32, terminalVersionStr string) (tm *TerminalMessage, err error) {
tfAuthReq, err := NewTerminalMessage(256, tmkind.IpApiRegistrationRequest, NextHandlerID())
if err != nil {

@ -121,6 +121,13 @@ func (tmr *TerminalMessageResponse) readAddress() (result TetraFlexAddress, err
return result, nil
}
func (tmr *TerminalMessageResponse) readString(count int) (result string, err error) {
textBytes := make([]byte, count)
if _, err = tmr.data.Read(textBytes); err != nil {
return result, err
}
return string(textBytes), nil
}
func (tmr *TerminalMessageResponse) AsAuthenticationChallenge() (authChallenge AuthenticationChallenge, err error) {
authChallenge.RandomSeed = make([]byte, 10)
@ -181,6 +188,14 @@ func (tmr *TerminalMessageResponse) AsRegistrationInfo() (regInfo RegistrationIn
if regInfo.RoamingRef, err = tmr.readUInt32(); err != nil {
return regInfo, err
}
if regInfo.Description, err = tmr.readString(64); err != nil {
return regInfo, err
}
if err != nil {
return regInfo, err
}
if regInfo.RemoteVersion > 20120702 {
port1, err := tmr.readUInt16()
if err != nil {

@ -3,23 +3,24 @@ package tmkind
type TetraFlexTerminalMessageKinds uint16
const (
NONE TetraFlexTerminalMessageKinds = 0
IpApiGeneralConfirm TetraFlexTerminalMessageKinds = 1
IpApiRegistrationRequest TetraFlexTerminalMessageKinds = 273
IpApiRegistrationConfirm TetraFlexTerminalMessageKinds = 274
IpApiAuthenticationChallenge TetraFlexTerminalMessageKinds = 529
IpApiAuthenticationResponse TetraFlexTerminalMessageKinds = 530
IpApiNotificationRequest TetraFlexTerminalMessageKinds = 785
IpApiNotificationConfirm TetraFlexTerminalMessageKinds = 786
IpApiGroupAttachRequest TetraFlexTerminalMessageKinds = 1041
IpApiGroupAttachConfirm TetraFlexTerminalMessageKinds = 1042
IpApiDeregistrationRequest TetraFlexTerminalMessageKinds = 1297
IpApiKeepAliveChallenge TetraFlexTerminalMessageKinds = 1553
IpApiKeepAliveResponse TetraFlexTerminalMessageKinds = 1554
IpApiSubscriberInfoRequest TetraFlexTerminalMessageKinds = 1809
IpApiSubscriberInfoConfirm TetraFlexTerminalMessageKinds = 1810
IpApiSoftwareInfoRequest TetraFlexTerminalMessageKinds = 2065
IpApiSoftwareInfoConfirm TetraFlexTerminalMessageKinds = 2066
NONE TetraFlexTerminalMessageKinds = 0
IpApiGeneralConfirm TetraFlexTerminalMessageKinds = 1
IpApiRegistrationRequest TetraFlexTerminalMessageKinds = 273
IpApiRegistrationConfirm TetraFlexTerminalMessageKinds = 274
IpApiAuthenticationChallenge TetraFlexTerminalMessageKinds = 529
IpApiAuthenticationResponse TetraFlexTerminalMessageKinds = 530
IpApiNotificationRequest TetraFlexTerminalMessageKinds = 785
IpApiNotificationConfirm TetraFlexTerminalMessageKinds = 786
IpApiGroupAttachRequest TetraFlexTerminalMessageKinds = 1041
IpApiGroupAttachConfirm TetraFlexTerminalMessageKinds = 1042
IpApiDeregistrationRequest TetraFlexTerminalMessageKinds = 1297
IpApiKeepAliveChallenge TetraFlexTerminalMessageKinds = 1553
IpApiKeepAliveResponse TetraFlexTerminalMessageKinds = 1554
IpApiSubscriberInfoRequest TetraFlexTerminalMessageKinds = 1809
IpApiSubscriberInfoConfirm TetraFlexTerminalMessageKinds = 1810
IpApiSoftwareInfoRequest TetraFlexTerminalMessageKinds = 2065
IpApiSoftwareInfoConfirm TetraFlexTerminalMessageKinds = 2066
IpApiCallSetupRequest TetraFlexTerminalMessageKinds = 4369
IpApiCallSetupConfirm TetraFlexTerminalMessageKinds = 4370
IpApiCallConnectRequest TetraFlexTerminalMessageKinds = 4625
@ -28,14 +29,15 @@ const (
IpApiCallStreamRequest TetraFlexTerminalMessageKinds = 5393
IpApiCallUpdateNotification TetraFlexTerminalMessageKinds = 5649
IpApiCallRoamingFinishedNotification TetraFlexTerminalMessageKinds = 5905
IpApiSdsDataType4Request TetraFlexTerminalMessageKinds = 9233
IpApiSdsStatusRequest TetraFlexTerminalMessageKinds = 9489
IpApiSdsTlTransferRequest TetraFlexTerminalMessageKinds = 9745
IpApiSdsTlReportRequest TetraFlexTerminalMessageKinds = 10001
IpApiSdsTlShortReportRequest TetraFlexTerminalMessageKinds = 10257
IpApiSdsDataType4Notification TetraFlexTerminalMessageKinds = 13329
IpApiSdsStatusNotification TetraFlexTerminalMessageKinds = 13585
IpApiSdsTlTransferNotification TetraFlexTerminalMessageKinds = 13841
IpApiSdsTlReportNotification TetraFlexTerminalMessageKinds = 14097
IpApiSdsTlShortReportNotification TetraFlexTerminalMessageKinds = 14353
IpApiSdsDataType4Request TetraFlexTerminalMessageKinds = 9233
IpApiSdsStatusRequest TetraFlexTerminalMessageKinds = 9489
IpApiSdsTlTransferRequest TetraFlexTerminalMessageKinds = 9745
IpApiSdsTlReportRequest TetraFlexTerminalMessageKinds = 10001
IpApiSdsTlShortReportRequest TetraFlexTerminalMessageKinds = 10257
IpApiSdsDataType4Notification TetraFlexTerminalMessageKinds = 13329
IpApiSdsStatusNotification TetraFlexTerminalMessageKinds = 13585
IpApiSdsTlTransferNotification TetraFlexTerminalMessageKinds = 13841
IpApiSdsTlReportNotification TetraFlexTerminalMessageKinds = 14097
IpApiSdsTlShortReportNotification TetraFlexTerminalMessageKinds = 14353
)

@ -1,10 +1,13 @@
package main
import (
"bufio"
"encoding/hex"
"encoding/json"
"fmt"
"math/rand"
"os"
"strings"
"time"
"git.cheetah.cat/cheetah/opentetraflex-go/common"
@ -26,7 +29,7 @@ func main() {
//
myAddr := common.TetraFlexAddress{
Kind: common.UserNo,
UserNo: "1005",
UserNo: "9400001",
}
err = terminalClient.Authenticate(myAddr)
if err != nil {
@ -69,19 +72,17 @@ func main() {
}
fmt.Println("Groups attached")
go func() {
fmt.Println("Test started, waiting 3s")
time.Sleep(3 * time.Second)
groupAddr := common.NewAddressFromSSINumber(101)
fmt.Println("Test callSetup")
callRef, err := terminalClient.CallSetup(*groupAddr, common.CallTypeGroup, common.CallPriorityDefault, false, common.TetraFlexIdentityInfo{
Description: "Blaa",
Description: "2m/FM Gateway SWM",
/* Kind: common.IdentityKindApplication,
Address: *common.NewAddressFromSSINumber(1002),
UnifiedSSIKinds: common.UnifiedKindExternalNumber,
*/
Kind: common.IdentityKindTerminal,
Address: *common.NewAddressFromSSINumber(1002),
Address: *common.NewAddressFromSSINumber(9400001),
UnifiedSSIKinds: common.UnifiedKindPersonalNumber,
})
if err != nil {
@ -89,6 +90,11 @@ func main() {
}
fmt.Printf("callRef=%d\n", callRef)
err = terminalClient.CallStreamRequest(0, callRef, 0, common.AudioChannel_CMoIP_Tetra) // CMoIP_aLaw
if err != nil {
panic(err)
}
// IpApiCallStreamRequest
err = terminalClient.PTTRequest(callRef, common.TetraFlexIdentityInfo{
Description: "Blaa",
@ -104,18 +110,62 @@ func main() {
if err != nil {
panic(err)
}
time.Sleep(3 * time.Second)
// PTT Release
err = terminalClient.PTTRelease(callRef)
time.Sleep(1 * time.Second)
// Connect RTP
err = terminalClient.RTPConnect()
if err != nil {
panic(err)
}
time.Sleep(3 * time.Second)
err = terminalClient.CallDisconnect(callRef, common.DisconnectReason_CallRejectedByCalled)
file, err := os.Open("./test.tetra.txt")
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
var counter byte = 0
var voiceArray [][]byte
for scanner.Scan() {
hexData := scanner.Text()
hexData = strings.Trim(hexData, " ")
byteData, _ := hex.DecodeString(hexData)
fmt.Println(hexData)
voiceArray = append(voiceArray, byteData)
}
for {
for _, byteData := range voiceArray {
fmt.Println(byteData)
byteData[8] = counter
err = terminalClient.RTPSend(byteData)
if err != nil {
panic(err)
}
if counter == 255 {
counter = 128
} else {
counter++
}
time.Sleep(20 * time.Millisecond)
}
}
/*
time.Sleep(3 * time.Second)
// PTT Release
err = terminalClient.PTTRelease(callRef)
if err != nil {
panic(err)
}
time.Sleep(3 * time.Second)
err = terminalClient.CallDisconnect(callRef, common.DisconnectReason_CallRejectedByCalled)
if err != nil {
panic(err)
}
*/
// IpApiCallPttRequest
}()
// idk send help xD

Loading…
Cancel
Save