(Tämän jutun kirjoitin muutama vuosi sitten Radioamatööri lehteen)

Tämä juttu on tarkoitettu Windows Phone/APRS-IS kehitystä harrastaville tahi aiheesta muuten kiinnostuneille.
wpAPRS on pieni, minun kehittämä APRS-IS paikkatietosovellus Windows Phone 7.5  ja  8.0 käyttöjärjestelmää käyttäviin matkapuhelimiin. wpAPRS lähettää käyttäjän sijainnin datayhteyden (2G, 3G, WLAN) välityksellä APRS-IS palvelimelle (1).  Sovellusta ei ole julkaistu Windows Phone sovelluskaupassa, vaan sen lähdekoodi on ladattavissa internetistä (2). Lähdekoodi on vapaasti ladattavissa ja sitä voi käyttää omissa sovelluksissa sekä laittaa sovelluskauppaan sovelluksia jotka pohjautuvat ko. koodiin ilman rahallista tai mitään muutakaan korvausta lähdekoodin tekijälle.  Sovellusta on testattu Windows Phone emulaattorissa. wpAPRS on ohjelmoitu C# kielellä.

Kehitystyökalut
Jotta koodia voisi muokata/kehittää tarvitaan Windows Phone kehitystyökalut, jotka saa ilmaiseksi Microsoftin sivuilta (3). Windows Phone SDK:n mukana tulee ilmainen Visual Studio 2010 Express for Windows Phone sovelluskehitin. Kehitystyökaluissa on Windows Phone emulaattori, jolla voi kattavasti testata sovellusta ennenkuin se siirretään matkapuhelimeen. Visual Studiosta voi siirtää sovelluksen matkapuhelimeen sekä debugata sovellusta puhelimessa (4). Sovellus kannattaa testata emulaattorissa mahdollisimman laajasti, ennenkuin sen siirtää puhelimeen jatkotestausta varten. WP sovelluskehityksestä löytyy netistä runsaasti tietoa, WP kehitys amatöörin kannattaa aloittaa esim. näistä julkaisuista (5).

Sovelluksen rakenne
wpAPRS:n käyttöliittymä perustuu Pivot käyttöliittymämalliin. Pivot koostuu yhdestä tai useammasta sivusta. Näytön yläreunassa on valikko, jossa on sivujen otsikot. Valikkoa voi liikuttaa sormella ja valita haluamansa sovelluksen sivun. Sivuja voi myös vaihtaa sormella reunasta reunaan liikuttamalla.
wpAPRS sovellus koostuu neljästä sivusta (MainPage.xaml). Sovelluksen pääsivulla (Location) näytetään GPS tiedot (sijainti, nopeus, suunta, korkeus, paikannuksen horisontaalinen ja vertikaalinen tarkkuus), painike jolla käynnistetään/pysäytetään GPS paikkatietojen näyttäminen ja lähettäminen APRS-IS palvelimelle. Sivun yläreunassa näytetään lähetetyn APRS-IS sijaintitietopaketin tiedot ja alareunassa teksti: Connected to APRS-IS server, kun yhteys palvelimeen on muodostettu.
Configuration sivulla syötetään tarvittavat asetustiedot: kutsu, APRS-IS server passcode (6), APRS-IS palvelimen IP-osoite ja porttinumero, nimi/vapaa teksti ja pollausväli (1-60 minuuttia), jolla asetetaan se, kuinka tiheään sijaintitietopaketti lähetetään APRS-IS palvelimelle. Asetustiedot talletetaan puhelimen muistiin (isolated storage), jossa ne säilyvät vaikka laite sammutettaisiin.
About sivulla näytetään tietoja sovelluksesta ja WP alustasta (mm. laitteen nimi, .net framework versio ja käyttöjärjestelmän versiotiedot). APRS symbols sivulla on kuva, jossa näkyvät graafiset APRS ikonit (APRS symbolit) ja niiden merkkivastineet (7).  APRS symboli määrittelee sen, millaisella graafisella ikonilla asema näkyy APRS ohjelmassa kartalla (8). wpAPRS sovelluksen sijaintitietopaketissa on APRS symbolina >, latitude ja longitude kentät erotetaan / merkillä, joten kartalla näkyy auton kuva aseman tiedoissa.

Isolated storage
Windows Phone käyttöjärjestelmän tiedostojärjestelmänä on isolated storage. Jokaisella sovelluksella on oma eristetty alue tiedostojärjestelmässä. Sovelluksilla ei ole suoraa pääsyä alueensa ulkopuolelle, tämän tarkoituksena on parantaa järjestelmän turvallisuutta. Isolated storageen voidaan tehdä/muokata/poistaa tiedostoja ja hakemistoja. Emulaattorissa sovellusta ajettaessa tiedot eivät tallennu pysyvästi isolated storage alueelle, vaan ne ovat käytettävissä vain sen ajan kuin emulaattori on käynnissä. wpAPRS sovellus käyttää staattisessa luokassa gensets määriteltyä muuttujaa, TEST_MODE, määrittelemään toiminnallisuuksia eri tavoin, silloin kun sovellusta ajetaan emulaattorissa (pitää muistaa asettaa TEST_MODE:n arvoksi false, ennenkuin sovellus käännetään/siirretään puhelimeen). Jos TEST_MODE on true, niin sovelluksen käynnistyessä testidataa sisältävät asetustiedot kirjoitetaan isolated storageen (private void MainPage_Loaded). Isolated storage käsittely on wpARPS sovelluksessa IsoStoHandler luokassa.
         // for testing in emulator
         // stores test values in isolated storage
         // when building for real device change gensets.TEST_MODE value to false
         if (gensets.TEST_MODE)
         {
             sAprs_data[0] = "OH1xxx-7"; // callsign
             sAprs_data[1] = "0000"; // passcode
             sAprs_data[2] = "finland.aprs2.net:14580";
             sAprs_data[3] = "windows phone test";
             sAprs_data[4] = "1"; // polling interval in minutes
             sAprs_data[5] = "finland.aprs2.net";
             sAprs_data[6] = "14580";
             sAprs_data[7] = aprsSym;  // aprs symbolhttp://wa8lmf.net/aprs/APRS_symbols.htm
             isoSto.CreateDataFile(sAprs_data);
         }

Watcher
GPS tiedot saadaan käyttämällä GeoCoordinateWatcher luokkaa.
private GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
GeoPositionAccuracy asetus määrittää tarkkuuden, sillä voi olla kaksi arvoa: default tai high. Default asetus kuluttaa vähiten puhelimen akkua paikannustarkkuuden kustannuksella.
if (watcher.TryStart(false, TimeSpan.FromMilliseconds(gensets.GEO_TIMEOUT)) == true)
TryStart metodi käynnistää paikannustietojen hakemisen, ensimmäinen parametri määrittää kysytäänkö käyttäjältä lupaa GPS:än käyttämiseen sovelluksessa (false = ei kysytä), toinen parametri määrittää aikakatkaisun arvon, eli kuinka kauan sovellus odottaa käyttöjärjestelmän location providerin käynnistymistä (public const double GEO_TIMEOUT).
Kun käyttöjärjestelmä saa GPS-vastaanottimelta tietoja laukeaa sovelluksessa watcher_PositionChanged tapahtuma, jossa paikannustiedot otetaan muuttujiin talteen ja tulostetaan näytölle.

dLat = e.Position.Location.Latitude;
dLon = e.Position.Location.Longitude;
dSpeed = e.Position.Location.Speed;
dCourse = e.Position.Location.Course;

DispatcherTimer ajastimen tapahtuman käsittelijä (void timer_Tick) sijoittaa muuttujien arvot APRS-IS:iin lähetettävään sijaintitietopakettiin.

Sijaintitietopaketti
Sijaintitietopaketti lähetetään IP-yhteyden yli määriteltyyn osoitteeseen+porttiin TCP-paketteina. Paketin rakenne on:
1>APRS,TCPIP*:!latitude/longitude23/45
1 = radioamatöörikutsu (asetustiedoista, sAprs_data[0])
2 = APRS symboli (asetustiedoista, sAprs_data[7])
3 = kompassisuunta
4 = nopeus, maileina/tunti, (dSpeed * 3.6) / 1.852)
5 = nimi/vapaateksti (asetustiedoista, sAprs_data[3])

GPS tiedoissa nopeuden yksikkö on m/s, joten se kerrotaan 3.6:lla jotta siitä saadaan km/h ja tämä jaetaan 1.852:llä (maileja/tunti).
Jos kompassisuuntaa tai nopeutta ei ole saatavilla GPS-tiedoista, niin ne jätetään paketista pois.
if (dSpeed.Equals(Double.NaN) == false && dCourse.Equals(Double.NaN) == false)
 {
    sb.Append(gutil.fmtnum(dCourse);
    sb.Append("/");
    sb.Append(gutil.fmtnum((dSpeed * 3.6) / 1.852));
}
Gpsutil luokassa (ohjelmassa viitataan gutil nimellä) on muutamia apufunktioita, joilla muunnetaan (toAprsLat, toAprsLon) Windows Phonen GeoCoordinate luokan desimaalimuodossa olevat GPS koordinaatit APRS formaattiin (NMEA) sekä muokataan desimaaliset nopeus ja suunta arvot APRS:ssä käytettävän etunollilla tarvittaessa täytetyn merkki formaatin mukaisiksi (fmtnum).

Sockets
Ennen kuin sijaintipaketti voidaan lähettää pitää avata TCP/IP yhteys palvelimen osoitteeseen+porttiin (socket) ja lähettää kirjautumispaketti palvelimelle, tämän jälkeen lähetetään sijaintitietopaketti ja yhteys suljetaan. Asetustietojen pollausvälissä määritetään kuinka tiheään em. proseduuri toistetaan (1-60 minuutin välein). Yhteys avataan sovelluksessa CreateConnection metodissa ja tietojen lähetys käsitellään AprsSend metodissa. Yhteys suljetaan CloseConnection metodissa. Pollausvälillä määritetty ajastettu tietojen lähetys APRS-IS palvelimelle on toteutettu DispatcherTimer ajastimella (StartTimer ja StopTimer metodit). Kirjautumispaketin formaatti on:
user  1 pass 2 vers wpAPRS 1.0
1 = radioamatöörikutsu (asetustiedoista, sAprs_data[0])
2 = APRS-IS passcode (asetustiedoista, sAprs_data[1])

Jotta TCP/IP-yhteys toimisi APRS-IS palvelimen kanssa, pitää asettaa TCP NO_DELAY päälle.
socketAPRS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketAPRS.NoDelay = true;
socketEventArg.RemoteEndPoint = new DnsEndPoint(sAprs_data[5], iTcpPort);
DnsEndPoint =  Socketin IP osoite + porttinumero.
Socketteja ohjelmoitaessa pitää ohjelmakoodissa olla käsittelyt virheiden ja aikakatkaisujen varalta. Gensets luokassa määritellään aikakatkaisujen arvot millisekunteina.
if (done.WaitOne(gensets.APRS_CONNECT_TIMEOUT))

public const double GEO_TIMEOUT = 2000; //ms
public const int APRS_CONNECT_TIMEOUT = 30000; //ms
public const int APRS_SEND_TIMEOUT = 30000; //ms

socketEventArg.Completed += new
EventHandler<SocketAsyncEventArgs>(delegate(object o, SocketAsyncEventArgs e)
{
    if (e.SocketError != SocketError.Success)
Socket virhetilanteessa sovellus näyttää SocketError virhekoodin arvon (9).

Jatkokehitystä ...
Sovellukseen voisi lisätä configuration sivulle APRS symboli valinnan ja valinnan talletuksen asetustietoihin jota sitten käytettäisiin sijaintitietopaketissa.  APRS:ssä on myös muita viestityyppejä kuin sijaintitieto, sovellukseen voisi kehittää vaikkapa sää- ja telemetriatietojen sekä lyhytviestien lähetyksen. APRS karttanäkymän avaaminen Internet Explorer selaimeen kävisi näppärästi muutamalla koodirivillä:
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = new Uri("http://www.aprs.fi", UriKind.Absolute);
webBrowserTask.Show();

aprs_i1.jpg

aprs_i2.jpg

Linkit
1. http://wiki.ham.fi/APRS-IS (teknistä tietoa kehittäjille: http://www.aprs-is.net/)
2. http://teknokoodiradio.vuodatus.net/lue/2015/08/windows-phone-aprs-c-lahdekoodit
3. Windows Phone 7.1 SDK
     http://www.microsoft.com/en-us/download/details.aspx?id=27570
    Windows Phone 7.1.1 SDK update
     http://www.microsoft.com/en-us/download/details.aspx?id=29233

4. http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff928362(v=vs.105).aspx
5. https://publications.theseus.fi/bitstream/handle/10024/49508/Lindholm_Joonas.pdf?sequence=1
http://publications.theseus.fi/bitstream/handle/10024/20618/Koski_Kimmo.pdf?sequence=1
6. http://aprs.ham.fi/laskuri/
7. http://wiki.ham.fi/APRS_symbolit
8. http://www.aprs.fi/
9. http://msdn.microsoft.com/en-us/library/system.net.sockets.socketerror.aspx