def testStringToByteArrayAlphaOnlyAscii(self):
     testVal = 'abcdefghijklmn'
     result = DecodeFunctions.stringToIntList(testVal, 'ascii')
     self.assertEqual([
         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B,
         0x6C, 0x6D, 0x6E
     ], result)
Esempio n. 2
0
    def create_requestFunctions(diagServiceElement, xmlElements):

        serviceId = 0
        diagnosticId = 0

        shortName = "request_{0}".format(diagServiceElement.find('SHORT-NAME').text)
        requestSIDFuncName = "requestSID_{0}".format(shortName)
        requestDIDFuncName = "requestDID_{0}".format(shortName)
        requestElement = xmlElements[diagServiceElement.find('REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')
        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass

            if(semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif(semantic == 'ID'):
                diagnosticId = DecodeFunctions.intArrayToIntArray([int(param.find('CODED-VALUE').text)], 'int16', 'int8')

        funcString = requestSIDFuncTemplate.format(requestSIDFuncName, # 0
                                                serviceId) #1
        exec(funcString)

        funcString = requestDIDFuncTemplate.format(requestDIDFuncName, #0
                                                diagnosticId) # 1
        exec(funcString)

        return (locals()[requestSIDFuncName],locals()[requestDIDFuncName])
 def testStringToByteArrayNumericOnlyAscii(self):
     testVal = 'abcdefg01234'
     result = DecodeFunctions.stringToIntList(testVal, 'ascii')
     self.assertEqual([
         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x30, 0x31, 0x32, 0x33,
         0x34
     ], result)
 def testByteArrayToStringAlphaOnlyAscii(self):
     testVal = [
         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B,
         0x6C, 0x6D, 0x6E
     ]
     result = DecodeFunctions.intListToString(testVal, 'ascii')
     self.assertEqual('abcdefghijklmn', result)
    def create_requestFunction(diagServiceElement, xmlElements):
        # Note: due to the compleixty of the call, this one is partially hardcoded - we do at least check the ODX file far enough to ensure that the request and subfunction are accurate.
        serviceId = 0
        diagnosticId = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')
        encodeString = ""

        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass
            except KeyError:
                pass

            if (semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif (semantic == 'SUBFUNCTION'):
                shortName += param.find('SHORT-NAME').text
                subfunction = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int8', 'int8')
                if subfunction[0] in [
                        0x01, 0x02, 0x0F, 0x11, 0x12, 0x13
                ]:  # ... DTCStatusMask required for these subfunctions
                    encodeString = "encoded += DTCStatusMask"
                elif subfunction[0] in [
                        0x03, 0x04, 0x06, 0x09, 0x10
                ]:  # ... DTCMaskRecord required for these subfunctions
                    encodeString = "encoded += DTCMaskRecord # ... format is [0xNN,0xNN,0xNN]"
                elif subfunction[0] in [
                        0x03, 0x04, 0x05
                ]:  # ... DTCSnapshotRecordNumber required for these subfunctions
                    encodeString = "encoded += DTCSnapshotRecordNumber"
                elif subfunction[0] in [
                        0x06, 0x10
                ]:  # ... DTCExtendedRecordNumber required for these subfunctions
                    encodeString = "encoded += DTCExtendedRecordNumber"
                elif subfunction[0] in [
                        0x07, 0x08
                ]:  # ... DTCSeverityMaskRecord required for these subfunctions
                    encodeString = "encoded += DTCSeverityMask+DTCStatusMask"

        funcString = requestFuncTemplate.format(shortName, serviceId,
                                                subfunction, encodeString)
        exec(funcString)
        return (locals()[shortName], str(subfunction))
 def testMultipleBitExtractFromByte(self):
     testVal = 0x5A
     result = DecodeFunctions.extractBitFromPosition(testVal, 0)
     self.assertEqual(False, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 1)
     self.assertEqual(True, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 2)
     self.assertEqual(False, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 3)
     self.assertEqual(True, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 4)
     self.assertEqual(True, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 5)
     self.assertEqual(False, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 6)
     self.assertEqual(True, result)
     result = DecodeFunctions.extractBitFromPosition(testVal, 7)
     self.assertEqual(False, result)
Esempio n. 7
0
    def create_requestFunction(diagServiceElement, xmlElements):
        serviceId = 0
        diagnosticId = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')

        encodeFunction = "None"

        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass

            if (semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif (semantic == 'ID'):
                diagnosticId = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int16', 'int8')
            elif semantic == 'DATA':
                dataObjectElement = xmlElements[(
                    param.find('DOP-REF')).attrib['ID-REF']]
                longName = param.find('LONG-NAME').text
                bytePosition = int(param.find('BYTE-POSITION').text)
                # We're not worrying about the formatting here, as we simply need the 3 byte hex to identify the DTC or DTC group ... (but can be changed if required)
                functionStringSingle = "DecodeFunctions.intArrayToIntArray(groupOfDTC, 'uint8', 'int8')"

                encodeFunction = "encoded = {1}".format(
                    longName, functionStringSingle)

        funcString = requestFuncTemplate.format(shortName, serviceId,
                                                encodeFunction)
        exec(funcString)
        return locals()[shortName]
 def testUint16ArrayToUint8Array(self):
     testVal = [0x5AA5, 0xA55A]
     result = DecodeFunctions.intArrayToUInt8Array(testVal, 'int16')
     self.assertEqual([0x5a, 0xA5, 0xA5, 0x5A], result)
 def testBuildIntFromArray3ByteArray(self):
     testVal = [0x5A, 0xA5, 0x5A]
     result = DecodeFunctions.buildIntFromList(testVal)
     self.assertEqual(0x5AA55A, result)
 def test6BitIntExtractFromPos2Of8BitInt(self):
     testVal = 0xA5
     result = DecodeFunctions.extractIntFromPosition(testVal, 6, 2)
     self.assertEqual(0x29, result)
 def test4BitIntExtractFromPos1Of8BitInt(self):
     testVal = 0xA5
     result = DecodeFunctions.extractIntFromPosition(testVal, 4, 1)
     self.assertEqual(0x2, result)
 def testBitExtractFromWordPos8False(self):
     testVal = 0x000
     result = DecodeFunctions.extractBitFromPosition(testVal, 8)
     self.assertEqual(False, result)
 def testBitExtractFromBytePos1False(self):
     testVal = 0x00
     result = DecodeFunctions.extractBitFromPosition(testVal, 1)
     self.assertEqual(False, result)
 def testBitExtractFromBytePos0True(self):
     testVal = 0x01
     result = DecodeFunctions.extractBitFromPosition(testVal, 0)
     self.assertEqual(True, result)
 def testUint8ArraytoUint16Array(self):
     testVal = [0x5aa55aa5, 0xa55aa55a]
     result = DecodeFunctions.intArrayToUInt8Array(testVal, 'int32')
     self.assertEqual([0x5a, 0xa5, 0x5a, 0xa5, 0xA5, 0x5A, 0xa5, 0x5a],
                      result)
Esempio n. 16
0
 def transmitAddress(self):
     return DecodeFunctions.intArrayToIntArray([self.__startAddress],
                                               'int32', 'int8')
Esempio n. 17
0
    def create_requestFunction(diagServiceElement, xmlElements):
        # Some services are present in the ODX in both response and send only versions (with the same short name, so one will overwrite the other).
        # Avoiding the overwrite by ignoring the send-only versions, i.e. these are identical other than positive response details being missing.
        try:
            if diagServiceElement.attrib['TRANSMISSION-MODE'] == 'SEND-ONLY':
                return (None, "")
        except:
            pass

        serviceId = 0
        controlType = 0
        routineId = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')

        encodeFunctions = []
        encodeFunction = ""

        for param in paramsElement:
            try:
                semantic = None
                try:
                    semantic = param.attrib['SEMANTIC']
                except AttributeError:
                    pass

                if (semantic == 'SERVICE-ID'):
                    serviceId = [int(param.find('CODED-VALUE').text)]
                elif (semantic == 'SUBFUNCTION'):
                    controlType = [int(param.find('CODED-VALUE').text)]
                    if controlType[0] >= SUPPRESS_RESPONSE_BIT:
                        pass
                        #raise ValueError("ECU Reset:reset type exceeds maximum value (received {0})".format(resetType[0]))
                elif (semantic == 'ID'):
                    routineId = DecodeFunctions.intArrayToIntArray(
                        [int(param.find('CODED-VALUE').text)], 'int16', 'int8')
                elif semantic == 'DATA':
                    dataObjectElement = xmlElements[(
                        param.find('DOP-REF')).attrib['ID-REF']]
                    longName = param.find('LONG-NAME').text
                    bytePosition = int(param.find('BYTE-POSITION').text)
                    # Catching any exceptions where we don't know the type - these will fail elsewhere, but at least we can test what does work.
                    try:
                        encodingType = dataObjectElement.find(
                            'DIAG-CODED-TYPE').attrib['BASE-DATA-TYPE']
                    except:
                        encodingType = "unknown"  # ... for now just drop into the "else" catch-all ??????????????????????????????????????????????
                    if (encodingType) == "A_ASCIISTRING":
                        functionStringList = "DecodeFunctions.stringToIntList(drDict['{0}'], None)".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.stringToIntList(optionRecord, None)"
                    elif (encodingType) == "A_INT8":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int8', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'int8', 'int8')"
                    elif (encodingType) == "A_INT16":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int16', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'int16', 'int8')"
                    elif (encodingType) == "A_INT32":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int32', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'int32', 'int8')"
                    elif (encodingType) == "A_UINT8":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint8', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'uint8', 'int8')"
                    elif (encodingType) == "A_UINT16":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint16', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'uint16', 'int8')"
                    elif (encodingType) == "A_UINT32":
                        functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint32', 'int8')".format(
                            longName)
                        functionStringSingle = "DecodeFunctions.intArrayToIntArray(optionRecord, 'uint32', 'int8')"
                    else:
                        functionStringList = "drDict['{0}']".format(longName)
                        functionStringSingle = "optionRecord"
                    """
The following encoding types may be required at some stage, but are not currently supported by any functions in the DecodeFunctions.py module ...

    A_VOID: pseudo type for non-existing elements
    A_BIT: one bit
    A_INT64: signed integer 64-bit, two's complement
    A_FLOAT32: IEEE 754 single precision
    A_FLOAT64: IEEE 754 double precision
    A_ASCIISTRING: string, ISO-8859-1 encoded
    A_UTF8STRING: string, UTF-8 encoded
    A_UNICODE2STRING: string, UCS-2 encoded
    A_BYTEFIELD: Field of bytes
	
Also, we will most need to handle scaling at some stage within DecodeFunctions.py (for RDBI at the very least)
                    """

                    #
                    encodeFunctions.append("encoded += {1}".format(
                        longName, functionStringList))
                    encodeFunction = "        else:\n            encoded = {1}".format(
                        longName, functionStringSingle)

            except:
                pass

        funcString = requestFuncTemplate.format(
            shortName,  # 0
            serviceId,  # 1
            controlType,  # 2
            routineId,  # 3
            "\n            ".join(
                encodeFunctions),  # ... handles input via list # 4
            encodeFunction,  # ... handles input via single value # 5
            SUPPRESS_RESPONSE_BIT)  # 6
        exec(funcString)
        return (locals()[shortName], str(controlType))
 def testStringToByteArrayAlphaOnlyUtf8(self):
     testVal = 'abcdefg'
     result = DecodeFunctions.stringToIntList(testVal, 'utf-8')
     self.assertEqual([0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67], result)
Esempio n. 19
0
 def transmitLength(self):  # ... this is dataLength encoded
     return DecodeFunctions.intArrayToIntArray([self.dataLength], 'int32',
                                               'int8')
Esempio n. 20
0
 def transmitLength(self):  # ... this is dataLength encoded
     return DecodeFunctions.intArrayToIntArray(
         [self.dataLength], 'int32', 'int8'
     )  # ... length calc'd as [0x00, 0x01, 0x4F, 0xe4] as expected
Esempio n. 21
0
    def create_requestFunction(diagServiceElement, xmlElements):
        serviceId = 0
        diagnosticId = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')

        encodeFunctions = []
        encodeFunction = "None"

        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass

            if (semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif (semantic == 'ID'):
                diagnosticId = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int16', 'int8')
            elif semantic == 'DATA':
                dataObjectElement = xmlElements[(
                    param.find('DOP-REF')).attrib['ID-REF']]
                longName = param.find('LONG-NAME').text
                bytePosition = int(param.find('BYTE-POSITION').text)
                # Catching any exceptions where we don't know the type - these will fail elsewhere, but at least we can test what does work.
                try:
                    encodingType = dataObjectElement.find(
                        'DIAG-CODED-TYPE').attrib['BASE-DATA-TYPE']
                except:
                    encodingType = "unknown"  # ... for now just drop into the "else" catch-all ??????????????????????????????????????????????
                if (encodingType) == "A_ASCIISTRING":
                    functionStringList = "DecodeFunctions.stringToIntList(drDict['{0}'], None)".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.stringToIntList(dataRecord, None)"
                elif (encodingType) == "A_INT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int8', 'int8')"
                elif (encodingType) == "A_INT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int16', 'int8')"
                elif (encodingType) == "A_INT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int32', 'int8')"
                elif (encodingType) == "A_UINT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint8', 'int8')"
                elif (encodingType) == "A_UINT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint16', 'int8')"
                elif (encodingType) == "A_UINT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint32', 'int8')"
                else:
                    functionStringList = "drDict['{0}']".format(longName)
                    functionStringSingle = "dataRecord"
                """
The following encoding types may be required at some stage, but are not currently supported by any functions in the DecodeFunctions.py module ...

    A_VOID: pseudo type for non-existing elements
    A_BIT: one bit
    A_INT64: signed integer 64-bit, two's complement
    A_FLOAT32: IEEE 754 single precision
    A_FLOAT64: IEEE 754 double precision
    A_ASCIISTRING: string, ISO-8859-1 encoded
    A_UTF8STRING: string, UTF-8 encoded
    A_UNICODE2STRING: string, UCS-2 encoded
    A_BYTEFIELD: Field of bytes
	
Also, we will most need to handle scaling at some stage within DecodeFunctions.py (for RDBI at the very least)
                """

                #
                encodeFunctions.append("encoded += {1}".format(
                    longName, functionStringList))
                encodeFunction = "    else:\n        encoded = {1}".format(
                    longName, functionStringSingle)

        # If we have only a single value for the dataRecord to send, then we can simply suppress the single value sending option.
        # Note: in the reverse case, we do not suppress the dictionary method of sending, as this allows extra flexibility, allowing
        # a user to use a consistent list format in all situations if desired.
        if len(encodeFunctions) > 1:
            encodeFunction = ""

        funcString = requestFuncTemplate.format(
            shortName,
            serviceId,
            diagnosticId,
            "\n        ".join(encodeFunctions),  # ... handles input via list
            encodeFunction)  # ... handles input via single value
        exec(funcString)
        return locals()[shortName]
Esempio n. 22
0
    def create_requestFunction(diagServiceElement, xmlElements):
        serviceId = 0
        diagnosticId = 0
        optionRecord = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')

        encodeFunctions = []
        encodeFunction = ""

        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass

            if (semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif (semantic == 'ID'):
                diagnosticId = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int16', 'int8')
            elif (semantic == 'SUBFUNCTION'):
                optionRecord = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int8', 'int8')
            elif semantic == 'DATA':
                dataObjectElement = xmlElements[(
                    param.find('DOP-REF')).attrib['ID-REF']]
                longName = param.find('LONG-NAME').text
                bytePosition = int(param.find('BYTE-POSITION').text)

                # If data object is a structure
                if dataObjectElement.find('DIAG-CODED-TYPE') is None:
                    dataObjectElement = xmlElements[dataObjectElement.find(
                        'PARAMS').find('PARAM').find(
                            'DOP-REF').attrib['ID-REF']]

                try:
                    encodingType = dataObjectElement.find(
                        'DIAG-CODED-TYPE').attrib['BASE-DATA-TYPE']
                except:
                    encodingType = "unknown"  # ... for now just drop into the "else" catch-all

                # We need to always respect given bit lengths!
                try:
                    bitLength = int(
                        dataObjectElement.find('DIAG-CODED-TYPE').find(
                            'BIT-LENGTH').text)
                except:
                    bitLength = 32  # just assume maximum length when in doubt

                if (encodingType) == "A_ASCIISTRING":
                    functionStringList = "DecodeFunctions.stringToIntList(drDict['{0}'], None)".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.stringToIntList(dataRecord, None)"
                elif (encodingType) == "A_INT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int8', 'int8')"
                elif (encodingType) == "A_INT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int16', 'int8')"
                    if bitLength < 16:
                        functionStringList = functionStringList + "[1:]"
                        functionStringSingle = functionStringSingle + "[1:]"
                elif (encodingType) == "A_INT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int32', 'int8')"
                    if bitLength == 8:
                        functionStringList = functionStringList + "[3:]"
                        functionStringSingle = functionStringSingle + "[3:]"
                    elif bitLength == 16:
                        functionStringList = functionStringList + "[2:]"
                        functionStringSingle = functionStringSingle + "[2:]"
                    elif bitLength == 24:
                        functionStringList = functionStringList + "[1:]"
                        functionStringSingle = functionStringSingle + "[1:]"
                elif (encodingType) == "A_UINT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint8', 'int8')"
                elif (encodingType) == "A_UINT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint16', 'int8')"
                    if bitLength < 16:
                        functionStringList = functionStringList + "[1:]"
                        functionStringSingle = functionStringSingle + "[1:]"
                elif (encodingType) == "A_UINT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint32', 'int8')"
                    if bitLength == 8:
                        functionStringList = functionStringList + "[3:]"
                        functionStringSingle = functionStringSingle + "[3:]"
                    elif bitLength == 16:
                        functionStringList = functionStringList + "[2:]"
                        functionStringSingle = functionStringSingle + "[2:]"
                    elif bitLength == 24:
                        functionStringList = functionStringList + "[1:]"
                        functionStringSingle = functionStringSingle + "[1:]"
                else:
                    functionStringList = "drDict['{0}']".format(longName)
                    functionStringSingle = "dataRecord"

                #
                encodeFunctions.append(
                    "encoded += {}".format(functionStringList))
                encodeFunction = "    else:\n" \
                                 "      if type(dataRecord) == list:\n" \
                                 "          for elem in dataRecord:\n" \
                                 "              encoded += {0}\n" \
                                 "      else:\n" \
                                 "          encoded = {1}".format(functionStringSingle.replace("dataRecord", "elem"),
                                                                  functionStringSingle)

        funcString = requestFuncTemplate.format(
            shortName,
            serviceId,
            diagnosticId,
            optionRecord,
            "\n        ".join(encodeFunctions),  # ... handles input via list
            encodeFunction)  # ... handles input via single value

        exec(funcString)
        return (locals()[shortName], str(optionRecord))
    def create_requestFunction(diagServiceElement, xmlElements):
        serviceId = 0
        diagnosticId = 0
        optionRecord = 0

        shortName = "request_{0}".format(
            diagServiceElement.find('SHORT-NAME').text)
        requestElement = xmlElements[diagServiceElement.find(
            'REQUEST-REF').attrib['ID-REF']]
        paramsElement = requestElement.find('PARAMS')

        encodeFunctions = []
        encodeFunction = ""

        for param in paramsElement:
            semantic = None
            try:
                semantic = param.attrib['SEMANTIC']
            except AttributeError:
                pass

            if (semantic == 'SERVICE-ID'):
                serviceId = [int(param.find('CODED-VALUE').text)]
            elif (semantic == 'ID'):
                diagnosticId = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int16', 'int8')
            elif (semantic == 'SUBFUNCTION'):
                optionRecord = DecodeFunctions.intArrayToIntArray(
                    [int(param.find('CODED-VALUE').text)], 'int8', 'int8')
            elif semantic == 'DATA':
                dataObjectElement = xmlElements[(
                    param.find('DOP-REF')).attrib['ID-REF']]
                longName = param.find('LONG-NAME').text
                bytePosition = int(param.find('BYTE-POSITION').text)
                # Catching any exceptions where we don't know the type - these will fail elsewhere, but at least we can test what does work.
                try:
                    encodingType = dataObjectElement.find(
                        'DIAG-CODED-TYPE').attrib['BASE-DATA-TYPE']
                except:
                    encodingType = "unknown"  # ... for now just drop into the "else" catch-all
                if (encodingType) == "A_ASCIISTRING":
                    functionStringList = "DecodeFunctions.stringToIntList(drDict['{0}'], None)".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.stringToIntList(dataRecord, None)"
                elif (encodingType) == "A_INT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int8', 'int8')"
                elif (encodingType) == "A_INT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int16', 'int8')"
                elif (encodingType) == "A_INT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'int32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'int32', 'int8')"
                elif (encodingType) == "A_UINT8":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint8', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint8', 'int8')"
                elif (encodingType) == "A_UINT16":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint16', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint16', 'int8')"
                elif (encodingType) == "A_UINT32":
                    functionStringList = "DecodeFunctions.intArrayToIntArray(drDict['{0}'], 'uint32', 'int8')".format(
                        longName)
                    functionStringSingle = "DecodeFunctions.intArrayToIntArray(dataRecord, 'uint32', 'int8')"
                else:
                    functionStringList = "drDict['{0}']".format(longName)
                    functionStringSingle = "dataRecord"

                #
                encodeFunctions.append("encoded += {1}".format(
                    longName, functionStringList))
                encodeFunction = "    else:\n        encoded = {1}".format(
                    longName, functionStringSingle)

        funcString = requestFuncTemplate.format(
            shortName,
            serviceId,
            diagnosticId,
            optionRecord,
            "\n        ".join(encodeFunctions),  # ... handles input via list
            encodeFunction)  # ... handles input via single value

        exec(funcString)
        return (locals()[shortName], str(optionRecord))