Esempio n. 1
0
/**
 * This function decodes a message into either the NegotiationData or GuessData structs depending
 * on what the type of message is. This function receives the message one byte at a time, where the
 * messages are in the format defined by MESSAGE_TEMPLATE, with payloads of the format defined by
 * the PAYLOAD_TEMPLATE_* macros. It returns the type of message that was decoded and also places
 * the decoded data into either the `nData` or `gData` structs depending on what the message held.
 * The onus is on the calling function to make sure the appropriate structs are available (blame the
 * lack of function overloading in C for this ugliness).
 *
 * PROTOCOL_PARSING_FAILURE is returned if there was an error of any kind (though this excludes
 * checking for NULL pointers), while
 *
 * @param parser The struct holding the data for this instance of the parser. Allows for multiple
 *               protocol decoding streams.
 * @param in The next character in the NMEA0183 message to be decoded.
 * @param nData A struct used for storing data if a message is decoded that stores NegotiationData.
 * @param gData A struct used for storing data if a message is decoded that stores GuessData.
 * @return A value from the UnpackageDataEnum enum.
 */
ProtocolParserStatus ProtocolDecode(char in, NegotiationData *nData, GuessData *gData) {
    static int i;
    static uint8_t expSum;
    switch (p.state)
    {
        //WATING case
        case (WAITING) :
        {
            //Recycle WAITING
            if (in != '$') {
                p.state = WAITING;
                return PROTOCOL_WAITING;
            }
            //Enter RECORDING
            else if (in == '$') {
                i = 0;
                p.state = RECORDING;
                return PROTOCOL_PARSING_GOOD;
            }
            break;
        }
        //RECORDING case
        case (RECORDING) :
        {
            //Recycle RECORDING
            if (in != '*') {
                sentence[i] = in;
                i += 1;
                p.state = RECORDING;
                return PROTOCOL_PARSING_GOOD;
            }
            //Enter FIRSTCHECKSUMHALF
            else if (in == '*') {
                p.state = FIRST_CHECKSUM_HALF;
                return PROTOCOL_PARSING_GOOD;
            }
            break;
        }
        //FIRSTCHECKSUMHALF case
        case (FIRST_CHECKSUM_HALF) :
        {
            //If given valid Hex Data continue accordingly
            if (((in >= 'A') && (in <= 'F')) || ((in >= 'a') && (in <= 'f')) ||
                                                  ((in >= '0') && (in <= '9'))) {
                p.checkSum = (ConvertAscii(in) << 4);
                p.state = SECOND_CHECKSUM_HALF;
                return PROTOCOL_PARSING_GOOD;
            }
            //Given invalid hex data enter WAITING
            else {
                p.state = WAITING;
                return PROTOCOL_PARSING_FAILURE;
            }
            break;
        }
        //SECONDCHECKSUM case
        case (SECOND_CHECKSUM_HALF) :
        {
            //Calculate the expected checkSum
            expSum = CreateCheckSum(i, sentence);
            //If given VALID hex data and continue
            if (((in >= 'A') && (in <= 'F')) || ((in >= 'a') && (in <= 'f')) ||
                                                  ((in >= '0') && (in <= '9'))) {
                //Finish assembling the Checksum thats read
                p.checkSum |= ConvertAscii(in);
                printf("Checksum is: %x\nExpChecksum is: %x\n", p.checkSum, expSum);
                //If the two checkSums ARE equal pass GOOD and enter NEWLINE
                if (p.checkSum == expSum) {
                    sentence[i] = '\0';
                    p.state = NEWLINE;
                    return PROTOCOL_PARSING_GOOD;
                }
                //If they ARENT equal then pass failure and enter WAITING
                else {
                    p.state = WAITING;
                    return PROTOCOL_PARSING_FAILURE;
                }
            }
            //Given INVALID hex data return FAILURE and enter WAITING
            else {
               p.state = WAITING;
               return PROTOCOL_PARSING_FAILURE;
            }
            break;
        }
        //NEWINE case
        case (NEWLINE) :
        {
            //If GIVEN a newline terminated string then evalauate the message
            //Check what kind of message it is
            if (in == '\n') {
                //Check which C message it is
                if (sentence[0] == 'C') {
                    //return CHA_MESSAGE and enter WAITING
                    if (sentence[1] == 'H') {
                        sscanf(sentence, PAYLOAD_TEMPLATE_CHA, &(nData->encryptedGuess),
                                                                          &(nData->hash));
                        p.state = WAITING;
                        return PROTOCOL_PARSED_CHA_MESSAGE;
                    }
                    //return COO_MESSAGE and enter WAITING
                    else {
                        sscanf(sentence, PAYLOAD_TEMPLATE_COO, &(gData->row), &(gData->col));
                        p.state = WAITING;
                        return PROTOCOL_PARSED_COO_MESSAGE;
                    }
                }
                //return DET_MESSAGE and enter WAITING
                else if (sentence[0] == 'D') {
                    sscanf(sentence, PAYLOAD_TEMPLATE_DET, &(nData->guess),
                                                  &(nData->encryptionKey));
                    p.state = WAITING;
                    return PROTOCOL_PARSED_DET_MESSAGE;
                }
                //return HIT_MESSAGE and enter WAITING
                else if (sentence[0] == 'H') {
                    sscanf(sentence, PAYLOAD_TEMPLATE_HIT, &(gData->row), &(gData->col),
                                                                          &(gData->hit));
                    p.state = WAITING;
                    return PROTOCOL_PARSED_HIT_MESSAGE;
                }

            }
            //If NOT GIVEN a newline terminated string then evalauate the message
            //return FAILURE and enter WAITING
            else {
                p.state = WAITING;
                return PROTOCOL_PARSING_FAILURE;
            }
            break;
        }
        //Default to waiting just in case of failure
        default :
        {
            p.state = WAITING;
            return PROTOCOL_PARSING_FAILURE;
            break;
        }
    }
    //In case it didnt hit anything then indicate a failure
    return PROTOCOL_PARSING_FAILURE;
}
Esempio n. 2
0
SqlVal GetCsAsciiVal(const SqlVal& val)
{
    return ConvertAscii(GetCsVal(val));
}