Mic-E Parser
Home ] License ] Installation ] Parameters ] Key Commands ] Public Functions ] Compression ] [ Mic-E Parser ] jFindu ] javAPRS SIG ] APRSTextbox ]

 

    private Report parseMic(Report theReport, int infoIndex, String theString)
    {
        int i = infoIndex, j, k;

        // theReport is a structure with fields
        // for parts of a packet
        theReport.reportType = "Mic";
        // theReport.theData is the packet received

        String toField = theReport.toField;
        int lastdash = toField.lastIndexOf('-');
        if (lastdash == 6)
            toField = toField.substring(0, lastdash);
        else if (lastdash >= 0)
            return null;
        if (toField.length() != 6) return null;
        
        // Get message and validate to field
        int micmsg = 0;
        for (j = 0; j < 3; j++)
        {
            micmsg <<= 1;
            micmsg |= getMessageBit(toField, j);
            if (micmsg == -1)
                return null;
        }
        if (micmsg > 7)
        {
            // Custom message
            micmsg &= 0x07;
            micmsg |= 0x08;
        }
        for (; j < 6; j++)
        {
            if (!isValidDest(toField.charAt(j))) return null;
        }
        // Parse the "TO" field
        int c = cnvtDest(toField.charAt(0));
        int d = (c & 0xf) * 10;  // Degrees
        c = cnvtDest(toField.charAt(1));
        d += (c & 0xf);
        c = cnvtDest(toField.charAt(2));
        int m = (c & 0xf) * 10;  // Minutes
        c = cnvtDest(toField.charAt(3));
        boolean north = (c >= 0x20);
        m += (c & 0xf);
        c = cnvtDest(toField.charAt(4));
        boolean hund = (c >= 0x20);
        int s = (c & 0xf) * 10;  // Hundredths of minutes
        c = cnvtDest(toField.charAt(5));
        boolean west = (c >= 0x20);
        s += (c & 0xf);

        theReport.position.lat = d + m / 60.0 + s / 6000.0;
        // javAPRS stores southern latitudes as negative
        if (!north)
            theReport.position.lat *= -1.0;

        // Parse the Icon
        theReport.icon = theString.charAt(i + 7) - ' ';
        char ch = theString.charAt(i + 8);
        theReport.altIcons = (ch != '/');
        if (isLetterOrDigit(ch))
            theReport.overlay = ch - ' ';

        // Parse the longitude
        d = theString.charAt(i + 1) - 28;
        m = theString.charAt(i + 2) - 28;
        s = theString.charAt(i + 3) - 28;

        if (d < 0 || d > 99 || m < 0 || m > 99 || s < 0 || s > 99)
            return null;

        // Adjust the degrees value
        if (hund)
            d += 100;
        if (d >= 190)
            d -= 190;
        else if (d >= 180)
            d -= 80;

        // Adjust minutes 0-9 to proper spot
        if (m >= 60)
            m -= 60;

        theReport.position.lon = d + m / 60.0 + s / 6000.0;
        if (west)
            theReport.position.lon *= -1.0;
        // Parse the Speed/Course (s/d)
        m = theString.charAt(i + 5) - 28;  // DC+28
        if (m < 0 || m > 97) return null;
        s = theString.charAt(i + 4) - 28;
        if (s < 0 || s > 99) return null;
        s = (s * 10) + (m / 10);  //Speed (Knots)
        d = theString.charAt(i + 6) - 28;
        if (d < 0 || d > 99) return null;
        d = ((m % 10) * 100) + d;  // Course
        // Specification decoding method
        if (s >= 800)
            s -= 800;
        if (d >= 400)
            d -= 400;

        if (d > 0)
        {
            theReport.course = d;
            theReport.speed = s;
        }
        theReport.MicEInfo = MicEMsgs[micmsg];
        if (theString.length() > i + 9)
        {
            theReport.comments = i + 9;
            // Look for altitude
            j = theString.indexOf('}', theReport.comments);
            if (j >= theReport.comments + 3)
                theReport.altitude = (int) Math.round(((((((theString.charAt(j - 3) - 33) * 91) + (theString.charAt(j - 2) - 33)) * 91) + (theString.charAt(j - 1) - 33)) - 10000) * 3.28084);
            switch (theReport.theData[i])
            {
                case (byte) '\'':
                    if (theString.charAt(i + 9) == ']')
                    {
                        theReport.MicEInfo += " D700";
                        break;
                    }
                case (byte) '`':
                    if (theString.charAt(i + 9) == '>')
                        theReport.MicEInfo += " D7";
            }
        }

        return theReport;
    }
    
    protected final static String MicEMsgs[] = {"EMERGENCY",
                                                   "Priority",
                                                   "Special",
                                                   "Committed",
                                                   "Returning",
                                                   "In Service",
                                                   "En Route",
                                                   "Off Duty",
                                                   "",
                                                   "Custom 6",
                                                   "Custom 5",
                                                   "Custom 4",
                                                   "Custom 3",
                                                   "Custom 2",
                                                   "Custom 1",
                                                   "Custom 0"
    };

    protected final int getMessageBit(String toField, int index)
    {
        char testchar = toField.charAt(index);
        if ((testchar >= '0' && testchar <= '9') || testchar == 'L')
            return 0;
        if (testchar >= 'A' && testchar <= 'K')
            return 9;
        if (testchar >= 'P' && testchar <= 'Z')
            return 1;
        return -1;
    }

    protected final boolean isValidDest(char testchar)
    {
        return ((testchar >= '0' && testchar <= '9') || testchar == 'L' || (testchar >= 'P' && testchar <= 'Z'));
    }

 

APRS is a registered trademark of APRS Software and Bob Bruninga, WB4APR.

Copyright © 2005 - Peter Loveall AE5PL pete@ae5pl.net
Hosted by AME Corp.