Translate

Thursday, 13 August 2015

Navionics SonarChart™ Live on Android

Skip to the good bit

For a quick hack to get SonarChart™ Live on android working with a home-brew or "unsupported" serial-to-wifi solution without the background, jump here.

How Deep Is Your Love?

A few months back a kplex user made me aware of a new feature in Navionics Boating: SonarChart™ Live.  This is a new feature in Navionics which enables users to generate bathymetric maps using current (hence, presumably, "Live") depth information from their own instruments.  More specifically,  data provided via selected partners' products. 

Anthony was trying to work out how to feed depth information via kplex to Navionics.  He'd done some investigation of the iOS version of Navionics and determined that the app was trying to contact fixed IP addresses and ports associated with the default set-up of the various "supported" partner products.  In subsequent analysis of the app I also noticed references to the bonjour services associated with GoFree (_nmea-0183._tcp) and Vesper (_vesper-nmea0183._tcp).

By setting up his pi to emulate the Digital Yacht Sonar Server, Anthony managed to feed depth information into Navionics from kplex but I thought that there must be a better way to achieve this so I emailed Navionics to ask how Navionics Boating users with existing serial-to-wifi solutions could realise the benefits of this exciting new feature. Not possible came the reply, and no they wouldn't reveal how their "automatic" connection worked:
We have developed at code level this features together with our partners. We do not open it externally at the moment and there's not any future plan to do it.
I asked for this to be escalated to product management as surely they'd want as many people as possible to enjoy this feature. I was promised a reply but despite several prompts over the following weeks one never came.

Echoes

A few days ago my android phone prompted me to upgrade Navionics Boating. The android version previously didn't support SonarChart™ Live but now it does, so despite my disinclination to allow the draconian new permission requirements (access to all my accounts? Make phone calls? Access to my contacts?  Why?) I upgraded.  With my Raymarine plotter bridging my seatalk-1 depth sounder's data to NMEA, converted to wifi by kplex running on my raspberry pi access point, I started experimenting.

Say Hello

First up...would advertising _nmea-0183._tcp as Navico's GoFree does tell Navionics to look for depth data in the right place?  I installed avahi (the linux bonjour implementation) and configured a service, creating a file /etc/avahi/services/kplex.service as follows:

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">

<service-group>
  <name replace-wildcards="yes">%h NMEA</name>

  <service>
    <type>_nmea-0183._tcp</type>
    <port>11010</port>
  </service>

</service-group>

No joy.  For good measure I also tried configuring the _vesper-nmea0183._tcp service. Still nothing.

Listen Like Thieves


Some network snooping showed the phone attempting to connect to 192.168.0.10 on port 10110.  This was the only address I could see it trying apart from an immense volume of traffic to MarkMonitor (apparently a "brand protection" company), Flurry and Amazon Web Services (presumably Navionics's servers).  Good to know how they're using your bandwidth and exploiting all those security privileges then.

My pi is set up as a router (so will move traffic from one interface to another) so I ran up a secondary interface, assigned it the address 192.168.0.10, restarted kplex (which was implementing a tcp server on all interfaces), restarted Navionics boating and Bingo!  SonarChart™ Live functionality.

My Name Is

By curious co-incidence 192.168.0.10 is the first DHCP address handed out by the Navico GoFree Wifi-1 in default configuration and would often be the address handed out to a plotter (distributing GoFree data) on a Navico network.  Further experimentation whilst attempting to emulate a Navico network revealed something bizarre.  Without the 192.168.0.10 address configured, if the SSID of the network the phone connects to contains the string "GoFree" (e.g. "GoFree-1234") and a data service on 192.168.0.10 is not available, the Navionics app throws up a screen asking the user to input the address for the source of depth information.  Port is not configurable and seems to be fixed at 10110 but inputting the pi NMEA server's address once again gave me SonarChart™ Live functionality.

This seems to be a very crude method of attempting to limit the data servers which can be used with SonarChart™ Live given that SSID is configurable and some GoFree wifi-1 users will have doubtless changed theirs from default.  Knowing less about the set-up of other supported data servers (e.g. Vexilar T-Box, Raymarine Dragonfly) I have not investigated whether default SSID plays a part in presuming them to be sources of data.

Disco 2000

So what of UDP?  For some reason Digital Yacht's products have used 2000 as a port for their wireless NMEA servers in the past.  I've had a hard time finding a manual for their SonarServer (one of the Navionics "SonarChart" supported products).  I tried UDP broadcasts from kplex on port 10110 to no avail but changing the port to 2000 once again yielded success.

Where's Your Head At?

Interestingly Navionics Boating seems to be parsing GPS data it is being sent over wifi.  Turn off location services on android and the app doesn't know your position when it fires up.  Turn on wireless data which includes GPS as well as depth sentences and your position is plotted.   This should be of particular interest to people who bought duff mobile devices which don't include an integrated GPS chipset.

Different Trains

It seems to be the case that the iOS version of Navionics may well function differently from the android one in how it determines where its data comes from.  Bonjour is well established on Apple platforms but Network Service Discovery was only added in android 4.1.  On the other hand "wifi multicast reception" is one of the (many, many) privileges Boating requests on android.  Sadly I don't have an iOS device with Navionics to play with in order to learn more.

As Navico's use of bonjour as one of the two ways they advertise their GoFree data service isn't a bad plan, I've decided to retain my avahi configuration on the pi for the time being.

The First Cut is the Deepest

So how best to get SonarChart™ Live on android to use our home-brew data server?  You could run up an interface on 192.168.0.10 but the easiest solution would appear to be one of the following.

If you prefer to access your data over TCP, change your SSID to something with the string "GoFree" in it, e.g. "GoFree-1234" and run an nmea server on port 10110.  When you open Navionics Boating it will ask you for the address of your server, tell it, and you can start using SonarCharts™ Live.

Otherwise broadcast your data over UDP port 2000.

If anyone has a better suggestion on how to achieve this with either the android or iOS versions of Navionics Boating, please do post a comment below.

19 comments:

  1. I'm mostly appreciating the song title headings, dont really have anything technical to add. I probably wouldnt have noticed but the FWIW lyrics bring back memories of an Island sampler I had (may even still have in a box somewhere) with a cover of the track by Spooky Tooth - happy days!

    Actually this is all useful stuff as it encourages me to get a Seatalk - NMEA bridge and perhaps start feeding my depth data to Navionics.

    ReplyDelete
  2. cheers for publishing this I managed to get sonarcharts live working with an android tablet and an off the shelf serial to wifi bridge. Saved serious coin on purchasing a navionics supported product. Tried it on my iPad as well though haven't had success yet.

    ReplyDelete
  3. Hi,
    This is just great.
    What address did you use for broadcasting on port 2000?
    Or even better, could you provide a wireshark log of the traffic broadcasted?

    ReplyDelete
  4. Peter, I was using the subnet broadcast address for my LAN. If your LAN is 192.168.1.0/24, then use 192.168.1.255. I didn't try the unicast address or the broadcast address of the zero network (i.e. 255.255.255.255) but my guess would be that Navionics don't do anything complicated and just open a socket listening for any address on port 2000 (although the device itself would only receive traffic for its configured address or broadcast traffic).

    It's easy to output data like this with kplex (from a unix/OS X/linux device): post a question on the kplex google group if uncertain:
    https://groups.google.com/forum/#!forum/kplex
    Navmonpc will, I believe, do it for windows (no personal experience):
    http://www.navmonpc.com
    And you can always set up OpenCPN to be a data repeater on Linux/Mac/Windows.

    ReplyDelete
    Replies
    1. Thanks,
      I will try to use kplex but I don't have any nmea generating hardware available at the moment and was hoping to do some simulation.

      Delete
  5. I am surprised to learn that Navionics uses port number 10110 for NMEA, while they refused to add our product (the MiniPlex-2Wi) to the app. I probably should have told them that it was I who registered port 10110 with IANA.... funny Italians :-)

    ReplyDelete
    Replies
    1. Hello Meindert, I am owning a Shipmodul MiniPlex-3Wi and would like to use the Navionics live sonar charts.
      Reading the above the only thing I have to change is the SSID name "GoFree-xxxx". how can I do that?
      Regards. Martin.

      Delete
  6. Fantastic piece of research. I was thinking about doing exactly the same and you have saved me a ton of work to get started. I have Navionics running on an iPad.

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Hi Unknown, I also have Navionics running on an iPad with built in GPS and was hoping to use Rasp Pi3 to connect via wifi and using kplex get NMEA 0813 data out to feed into my autopilot. Please keep us updated on your progress

    ReplyDelete
  9. Hi. I'm trying to go the other way and get depth data from the Sonarphone T-box to a PC chart plotter. Anyone know if this can be done?

    ReplyDelete
    Replies
    1. Given that Navionics can consume depth info from the t-box there's a fair chance it's outputting data in a format that something other than the sonarphone app can consume. Try mailing Vexilar and asking what format, transport and port it's using. If it is name-0183 over duo or tcp then how that gets into the plotter software depends on the software. Something like OpenCPN which accepts network data you just set up a data connection for it on the appropriate port. If the plotter program doesn't accept network data then (if windows) you probably need something like NavMonPC to bridge the network->virtual serial gap. If Vexilar aren't forthcoming with the info, a bit of network snooping with wireshark should solve the problem. If you're not confident with that try posting somewhere like the OpenCPN or Marine Electronics sub-forum of cruisers' forum: Someone else must have played with these

      Delete
    2. That's "udp" not "duo". Darned autocorrect....

      Delete
    3. Thanks for your reply. Wireshark (Linux) didn't give me what I needed as I suspect it only reads the traffic on the local pc/AP. I'll try using an app om the phone connected to the T-box. I'll also try mailing Vexilar, but I suspect that they will not give me an answer.

      Delete
  10. Hi,
    Can you tell me what you have in your kplex.conf file
    i ve an aerror: "pi@raspberrypi:~ $ sudo kplex file:direction=out
    bind failed for udp interface _udp-id3: Cannot assign requested address"

    thank

    ReplyDelete
    Replies
    1. It's been a while and maybe navionics have changed things but in theory something like:

      [udp]
      port=2000
      direction=out
      device=<device>
      type is broadcast

      where <device> is the name of the device you're broadcasting over, e.g. "wlan0" or "wifi0" (look at your ifconfig -a output if nothing else). There's a lot of twisty logic in kplex to work out what you want to do specifying the minimum. Not specifying address should use the broadcast address of the interface by default. You shouldn't actually need to say "type=broadcast" because kplex works out that if you didn't specify an address and it's an output interface on a nic which isn't point to point you must mean broadcast. But twisty logic might have a bug in it. If you have problems do post them on:
      https://groups.google.com/forum/#!forum/kplex

      Delete
  11. Hi, Trying to prototype this at home before taking to the boat.

    tried the "GoFree" method, and the UDP example. Not having much success with either.

    Any help appreciated.

    Thanks

    James
    Echo server program
    import socket
    import time

    HOST = '' # Symbolic name meaning all available interfaces
    PORT = 10110 # Arbitrary non-privileged port
    UDP_IP = "255.255.255.255"
    UDP_PORT = 2000

    TEST_DATA1 = b"""$GPRMC,181031.576,V,3926.276,N,07739.361,W,99.7,18.30,250915,,E*79
    $GPGGA,181032.576,3926.276,N,07739.361,W,0,00,,,M,,M,,*5F
    $GPGLL,3926.276,N,07739.361,W,181033.576,V*3E
    $GPRMC,181034.576,V,3949.797,N,07809.854,W,18.8,34.66,250915,,E*75
    $GPGGA,181035.576,3949.797,N,07809.854,W,0,00,,,M,,M,,*5A
    $GPGLL,3949.797,N,07809.854,W,181036.576,V*39
    $GPRMC,181037.576,V,4040.018,N,07808.022,W,32.9,16.43,250915,,E*77
    $GPGGA,181038.576,4040.018,N,07808.022,W,0,00,,,M,,M,,*58
    $GPGLL,4040.018,N,07808.022,W,181039.576,V*39
    $GPRMC,181040.576,V,4133.618,N,07725.034,W,96.8,44.47,250915,,E*7F"""


    TEST_DATA2 = b"""$GPDBT,9.3,f,2.84,M,1.55,F
    $GPGGA,181032.576,3926.276,N,07739.361,W,0,00,,,M,,M,,*5F
    $GPGLL,3926.276,N,07739.361,W,181033.576,V*3E
    $IIDBT,9.3,f,2.84,M,1.55,F
    $SDDBK,1330.5,f,0405.5,M,0221.6,F*2E
    $SDDBS,1330.5,f,0405.5,M,0221.6,F*2E
    $SDDBT,1330.5,f,0405.5,M,0221.6,F*2E
    $SDDPT,3.6,0.0*52
    $GPGLL,4040.018,N,07808.022,W,181039.576,V*39
    $GPRMC,181040.576,V,4133.618,N,07725.034,W,96.8,44.47,250915,,E*7F"""


    sock = socket.socket(socket.AF_INET, # Internet
    socket.SOCK_DGRAM) # UDP


    print ('Connected by')



    while 1:

    sock.sendto(TEST_DATA1, (UDP_IP, UDP_PORT))
    time.sleep(1)
    sock.sendto(TEST_DATA2, (UDP_IP, UDP_PORT))
    time.sleep(1)
    conn.close()

    ReplyDelete
    Replies
    1. Are those data definitely terminated by \r\n rather than just \n? Don't know if navionics is fussy...

      Delete
  12. It would be nice to make the connection by cable from NMEA-0183 to a serial port of a Linux computer. If only there was another Linux program to make the up/download of the data to Navionics servers.

    ReplyDelete