Android Question NTRIP Mount Points

Terradrones

Active Member
Licensed User
Hi All

I need help again please. I want to access the Service Provider (www.trignet.co.za) that has GPS Base Stations all over South Africa that transmits GPS corrections. I have registered with Trignet and have a Username and Password. I also know the IP address and Port number of Trignet.

I am trying to access the mountpoints with the following code:

B4X:
Sub FindMountPoints
    Dim su As StringUtils
    Dim HttpClient As HttpJob
    HttpClient.Initialize("NTRIP", Me)
    
    ' Set the NTRIP caster URL and credentials
    Dim IPAddress As String = CGlobals.DF(64)
    Dim Port As String = CGlobals.DF(65)
    Dim NTRIP_URL As String = "http://" & IPAddress & ":" & Port '& "/caster"
    Dim Username As String = CGlobals.DF(66)
    Dim Password As String = CGlobals.DF(67)
    
    ProgressDialogShow2("Searching Mount Points...", True)
    
    Dim AuthString As String = Username & ":" & Password
    Dim AuthHeader As String = "Basic " & su.EncodeBase64(AuthString.GetBytes("UTF8"))
    HttpClient.Download(NTRIP_URL)
    
    ' Set headers before sending the request
    HttpClient.GetRequest.SetHeader("Authorization", AuthHeader)
    HttpClient.GetRequest.SetHeader("User-Agent", "Ceaser")
    HttpClient.GetRequest.SetHeader("Accept", "*/*")
    HttpClient.GetRequest.SetHeader("Connection", "close")
    
    ' Send the request
'    HttpClient.Download(NTRIP_URL)
End Sub

Sub JobDone (Job As HttpJob)
    If Job.Success Then
        CmbMountPoints.cmbBox.Clear
        Dim response As String = Job.GetString
'        Log("NTRIP Response: " & response)
        
        ' Process the NTRIP data here to extract mount points
        Dim MountPoints As List
        MountPoints.Initialize
        Dim Lines() As String = Regex.Split(CRLF, response)
        For Each Line As String In Lines
            Log(Line)
            If Line.StartsWith("STR") Then
                CmbMountPoints.cmbBox.Add(Line)
'                Log(Line)
                MountPoints.Add(Line)
            End If
        Next
        Log("Available Mount Points: " & MountPoints)
    Else
        Log("Job failed: " & Job.ErrorMessage)
        Log("HTTP Status Code: " & Job.Response.StatusCode) ' Log the status code for more details
'        Log("Full Response: " & Job.GetString) ' Log the full response to understand why it fails
        MsgboxAsync("Mount Points Are Not Available" & CRLF & "The Server Might Be Down", "No Mount Points")
    End If
    Job.Release
    ProgressDialogHide
End Sub

It is giving me the following error:

ResponseError. Reason: java.net.ProtocolException: Unexpected status line: SOURCETABLE 200 OK, Response:
Job failed: java.net.ProtocolException: Unexpected status line: SOURCETABLE 200 OK
HTTP Status Code: -1

What does "sourcetable 200 ok" mean?
 

Terradrones

Active Member
Licensed User
Thanks.

I have now used a Socket and I can connect, but I do not receive anything back from Trignet for the GPS corrections.

A question: if I have the IP Address and the Port number, surely that is all that I require to access the correct "room" on the Website?

Modified code:

B4X:
Sub GetMountPoints_Click
    'Get the Mount Points

    Select Case CGlobals.DF(50)
        Case 1
            'Leica
        Case 2
            'Emlid
            FindMountPoints
        Case 3,4,5,10
            'Foif, Rinonav,E-Survey, StoneX
            FindMountPoints
        Case 6
            'Tersus
            FindMountPoints
        Case 7
            'Geomax
        Case 8
            'ComNav
        Case 9
            'CHC
    End Select
End Sub

Sub FindMountPoints
    sckt.Initialize("sckt")
    sckt.Connect(CGlobals.DF(64), CGlobals.DF(65), 5000)     'DF(64)=IP Address & DF(65)=Port
End Sub

Sub sckt_Connected(Successful As Boolean)
    If Successful Then
        Log("Connection successful")
        
        ' Build NTRIP request message
        Dim msg As String
        'msg = "GET /caster HTTP/1.1" & CRLF ' Switching to HTTP/1.1
        msg = "GET /HTTP/1.1" & CRLF
        msg = msg & "Host: " & CGlobals.DF(64) & CRLF
        msg = msg & "User-Agent: NTRIP Client" & CRLF
        msg = msg & "Accept: */*" & CRLF
        msg = msg & "Connection: close" & CRLF
        
        ' Add authorization header if username and password are provided
        If CGlobals.DF(66).Length > 0 And CGlobals.DF(67).Length > 0 Then        'DF(66)=User Name & DF(67)=Password
            Dim credentials As String = CGlobals.DF(66) & ":" & CGlobals.DF(67)
            Dim data() As Byte = credentials.GetBytes("UTF8")
            Dim auth As String = su.EncodeBase64(data)
            msg = msg & "Authorization: Basic " & auth & CRLF
        End If
        msg = msg & CRLF
        
        Log("Request message: " & msg)

        ' Initialize AsyncStreams
        AStream.Initialize(sckt.InputStream, sckt.OutputStream, "AStream")
        
        ' Send request
        AStream.Write(msg.GetBytes("UTF8"))
    Else
        Log("Connection failed")
    End If
End Sub

Sub AStream_NewData(Buffer() As Byte)
    Dim receivedData As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Log("Received Data Chunk: " & receivedData)
    response = response & receivedData
End Sub

Sub AStream_Terminated
    Log("Connection terminated. Full response: " & response)
    
    ' Process the response here
    Dim mountPoints As List = ParseMountPoints(response)
    For Each mountPoint As String In mountPoints
        Log(mountPoint)
    Next
End Sub

Sub ParseMountPoints(response1 As String) As List
    Dim mountPoints As List
    mountPoints.Initialize
    Dim lines() As String = Regex.Split(CRLF, response1)
    For Each line As String In lines
        If line.StartsWith("STR;") Then ' NTRIP response contains lines starting with "STR;" for mount points
            mountPoints.Add(line)
        End If
    Next
    Return mountPoints
End Sub

Any ideas?

Thank you
Michael
 
Upvote 0

Terradrones

Active Member
Licensed User
I have now changed the functions to find NTRIP mountpoints into a class. The connection is successful, but there is still no response from Trignet.

Code:

B4X:
Sub Class_Globals
    Private sock As Socket
    Private Astream As AsyncStreams
    Private response As String
    Private su As StringUtils
    Private mHost As String
    Private mCallback As Object
    Private mEventName As String
End Sub

Public Sub Initialize(Callback As Object, EventName As String)
    mCallback = Callback
    mEventName = EventName
End Sub

Public Sub Connect(IPAddress As String, Port As Int, Username As String, Password As String)
    If Astream.IsInitialized Then Astream.Close
    sock.Initialize("sock")
    sock.Connect(IPAddress, Port, 30000)
    mHost = IPAddress
    Dim credentials As String = Username & ":" & Password
    Dim Data() As Byte = credentials.GetBytes("UTF8")
    Dim auth As String = su.EncodeBase64(Data)
    response = $"GET / HTTP/1.1
Host: ${IPAddress}
Ntrip-Version: Ntrip/2.0
User-Agent: NTRIP Client
Accept: */*
Authorization: Basic ${auth}
Connection: close

"$
End Sub

Private Sub Sock_Connected(Successful As Boolean)
    If Successful Then
        Astream.Initialize(sock.InputStream, sock.OutputStream, "astream")
        Log("Request message: " & response)
        Astream.Write(response.GetBytes("UTF8"))
        Log(response.GetBytes("UTF8"))
    Else
        Log("Connection failed")
        CallSubDelayed2(mCallback, mEventName & "_ConnectionFailed", True)
    End If
End Sub

Private Sub AStream_NewData(Buffer() As Byte)
    Dim receivedData As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Log("Received Data Chunk: " & receivedData)
    response = response & receivedData
End Sub

Private Sub Astream_Terminated
    Log("Connection terminated. Full response: " & response)
    ' Process the response here
    Dim mountPoints As List = ParseMountPoints(response)
    CallSubDelayed2(mCallback, mEventName & "_MountPointsReceived", mountPoints)
End Sub

Private Sub ParseMountPoints(Response1 As String) As List
    Dim mountPoints As List
    mountPoints.Initialize
    Dim lines() As String = Regex.Split(CRLF, Response1)
    For Each line As String In lines
        If line.StartsWith("STR;") Then ' NTRIP response contains lines starting with "STR;" for mount points
            mountPoints.Add(line)
        End If
    Next
    Return mountPoints
End Sub

I am at wits ends here.
 
Upvote 0

Terradrones

Active Member
Licensed User
I am not getting any response. I have tried another way but still there is no response. I can connect but that is all.

Different way:

B4X:
Sub Class_Globals
    Private Client As Socket
    Private outputStream As OutputStream
    Public AStream As AsyncStreams
    Public Serial As Serial
    Private message As String
    Private IsConnected As Boolean
End Sub

' Initialize the class, and attempt to connect to the Trignet GPS server.
Public Sub Initialize(ServerAddress As String, Port As Int)
    ' Initialize socket connection
    Client.Initialize("client")
    Client.Connect(ServerAddress, Port,30000)
    IsConnected = False
    If AStream.IsInitialized Then AStream.Close
End Sub

Sub client_Connected(Success As Boolean)
    If Success Then
        Dim outputStream As OutputStream = Client.OutputStream
        Log("Connected to Trignet")
        IsConnected = True
        
        message = "REQUEST_MOUNTPOINTS"
        outputStream = Client.OutputStream
        outputStream.WriteBytes(message.GetBytes("UTF8"), 0, message.Length)
    Else
        Log("Connection failed")
        IsConnected = False
    End If
End Sub

' Handle incoming data from the Trignet GPS server.
Sub client_Received(bytes() As Byte)
    Dim receivedData As String
    receivedData = BytesToString(bytes, 0, bytes.Length, "UTF8")
    Log("Received data: " & receivedData)
    
    If receivedData.Contains("GPRMC") Then
        ParseGPRMC(receivedData)
    End If
End Sub

Sub ParseGPRMC(sentence As String)
    Dim parts As List
    parts = Regex.Split(",", sentence)
    
    If parts.Size > 9 Then
        Dim latitude As String = parts.Get(3)
        Dim longitude As String = parts.Get(5)
        Dim speed As String = parts.Get(7)
        Dim timestamp As String = parts.Get(1)
        
        Log("Latitude: " & latitude)
        Log("Longitude: " & longitude)
        Log("Speed: " & speed)
        Log("Timestamp: " & timestamp)
        
    Else
        Log("Invalid GPRMC sentence: " & sentence)
    End If
End Sub

' Handle disconnection from the server.
Sub client_Disconnected
    Log("Disconnected from server")
    IsConnected = False
End Sub

' Handle any errors during socket communication.
Sub client_Error(Reason As String)
    Log("Error: " & Reason)
    IsConnected = False
End Sub

' Close the socket connection when done.
Public Sub CloseConnection
    If Client.IsInitialized Then
        Client.Close
        Log("Connection closed")
        IsConnected = False
    End If
End Sub

' Send a custom message to the Trignet GPS server
Public Sub SendMessage(message1 As String)
    If IsConnected Then
        outputStream = Client.OutputStream
        outputStream.WriteBytes(message1.GetBytes("UTF8"), 0, message1.Length)
        Log("Sent message: " & message1)
    Else
        Log("Not connected to the server.")
    End If
End Sub
 
Upvote 0

Terradrones

Active Member
Licensed User
Here is another go at getting NTRIP mountpoints with no success.

This is in one of my Activities:

B4X:
Sub FindMountPoints
    Ntripp.Initialize(Me, "NTRIP")
    Ntripp.Connect(CGlobals.DF(64), CGlobals.DF(65), CGlobals.DF(66), CGlobals.DF(67))
End Sub

Sub NTRIP_ConnectionFailed(Success As Boolean)
    Log("Connection to NTRIP server failed.")
End Sub

Sub NTRIP_MountPointsReceived(mountPoints As List)
    Log("Mount Points: " & mountPoints)
    For Each mountPoint As String In mountPoints
        Log(mountPoint)
    Next
End Sub

And the following is in my Class:

B4X:
Sub Class_Globals
    Private sock As Socket
    Private Astream As AsyncStreams
    Private su As StringUtils
    Private response As String
    Private bc As ByteConverter
    Private mHost As String
    Private mCallback As Object
    Private mEventName As String
End Sub

Public Sub Initialize(Callback As Object, EventName As String)
    mCallback = Callback
    mEventName = EventName
End Sub

Public Sub Connect(IPAddress As String, Port As Int, Username As String, Password As String)
    If Astream.IsInitialized Then Astream.Close
    sock.Initialize("sock")
    sock.Connect(IPAddress, Port, 30000)
    mHost = IPAddress
    Dim credentials As String = Username & ":" & Password
    Dim data() As Byte = credentials.GetBytes("UTF8")
    Dim auth As String = su.EncodeBase64(data)
    response = "GET / HTTP/1.0" & CRLF & _
           "Host: " & IPAddress & CRLF & _
           "User-Agent: NTRIP Client" & CRLF & _
           "Accept: */*" & CRLF & _
           "Authorization: Basic " & auth & CRLF & _
           "Connection: close" & CRLF & CRLF
End Sub

Private Sub Sock_Connected(Successful As Boolean)
    If Successful Then
        Astream.Initialize(sock.InputStream, sock.OutputStream, "astream")
        Log("Request message: " & response)
        Astream.Write(response.GetBytes("UTF8"))
    Else
        Log("Connection failed")
        CallSubDelayed2(mCallback, mEventName & "_ConnectionFailed", True)
    End If
End Sub

Private Sub AStream_NewData(Buffer() As Byte)
    Dim receivedData As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Log("Received Data Chunk: " & receivedData)
    response = response & receivedData
End Sub

Private Sub Astream_Terminated
    Log("Connection terminated. Full response: " & response)
    ' Process the response here
    Dim mountPoints As List = ParseMountPoints(response)
    CallSubDelayed2(mCallback, mEventName & "_MountPointsReceived", mountPoints)
End Sub

Private Sub ParseMountPoints(response1 As String) As List
    Dim mountPoints As List
    mountPoints.Initialize
    Dim lines() As String = Regex.Split(CRLF, response1)
    For Each line As String In lines
        If line.StartsWith("STR;") Then ' NTRIP response contains lines starting with "STR;" for mount points
            mountPoints.Add(line)
        End If
    Next
    Return mountPoints
End Sub

I can connect, but I am getting no response.

A push please?
 
Upvote 0

amorosik

Expert
Licensed User
Is there some standard form of communication that we can refer to?
I mean, the servers you want to connect to, what communication protocol do they use?
 
Upvote 0

Terradrones

Active Member
Licensed User
I asked AI about it, as there is nothing on their website (www.trignet.co.za) and this is AI's reply:

TrigNet uses the Networked Transport of RTCM via Internet Protocol (NTRIP) for its real-time services. This protocol allows users to access real-time corrections from GNSS base stations over the internet
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
i'm reading that you have to set the user-agent manually for ntrip calls. haven't found what it should be set to yet, but you might want to look into that. a "wrong" user-agent could just make the server sit there

Protocol requirement: The NTRIP protocol specifically requires clients to identify themselves using the User-Agent header
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
Hi, are you saying if the following command "User-Agent: NTRIP Client" is wrong then nothing will happen?
that is what i would expect to happen.
also, i would get rid of this "Connection: close" in your request header. if you're going to use http 1, then try Connection: keep-alive. for http 1.1, i think keep-alive is the default, but it probably couldn't hurt to set it specifically. in any case, you don't want the connection closed (that is the default for http 1)
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
if you manage to get an initial response, i think the data keep coming line by line. that may suit your purposes. my impression is that it's almost like an old time blocking read-until-there's-nothing-more-to-read call. but, obviously, i have no way of testing. what i'm saying is that if you're expecting some kind of complete data set in response to your get, i don't think it's going to come at once. i think you're going to have to piece it together to build a "complete" whatever. i think it works like nmea data from a gnss satellite: a line every second
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
SOURCETABLE 200 OK is good news. that's the start of server's ouput.

here's the http response headers from a server:
B4X:
SOURCETABLE 200 OK
Server: SubCarrier Systems Corp SNIP simpleNTRIP_Caster_[wPRO]R3.16.18/of:Nov 04 2024
Date: Wed, 06 November 2024 02:35:06 UTC
Content-Type: text/plain
Content-Length: 111934

are you really sure okhttputils doesn't work?
 
Upvote 0
Top