Esempio n. 1
0
    def _parseData(self, byteArray):

        returnVal = {}

        # log
        log.debug("_parseData with byteArray {0}".format(
            FormatUtils.formatBuffer(byteArray)))

        # command ID
        try:
            (returnVal['cmdId'], ) = struct.unpack(
                '>H', self._toString(byteArray[:2]))
        except struct.error as err:
            raise ValueError(err)

        if returnVal['cmdId'] == CMDID_CONFIGURATION:

            try:
                (
                    returnVal['reportPeriod'],
                    returnVal['bridgeSettlingTime'],
                    returnVal['ldoOnTime'],
                ) = struct.unpack('>III', self._toString(byteArray[2:]))
            except struct.error as err:
                raise ValueError(err)

        elif returnVal['cmdId'] == CMDID_REPORT:

            try:
                (
                    returnVal['temperature'],
                    returnVal['adcValue'],
                ) = struct.unpack('>IH', self._toString(byteArray[2:]))
            except struct.error as err:
                raise ValueError(err)

        elif returnVal['cmdId'] == ERR_NO_SERVICE:
            pass

        elif returnVal['cmdId'] == ERR_NOT_ENOUGH_BW:
            try:
                (returnVal['bw'], ) = struct.unpack(
                    '>I', self._toString(byteArray[2:]))
            except struct.error as err:
                raise ValueError(err)

        else:
            raise ValueError("unexpected command ID {0}".format(
                returnVal['cmdId']))

        return returnVal
Esempio n. 2
0
    def _parseData(self, byteArray):
        returnVal = {}
        #log
        log.debug("_parseData with byteArray {0}".format(
            FormatUtils.formatBuffer(byteArray)))

        try:
            (
                returnVal['current'],
                returnVal['charge'],
            ) = struct.unpack('>HB', self._toString(byteArray[:]))
        except struct.error as err:
            raise ValueError(err)
        return returnVal
Esempio n. 3
0
 def _parseData(self,byteArray):
     
     returnVal = {}
     
     # log
     log.debug("_parseData with byteArray {0}".format(FormatUtils.formatBuffer(byteArray)))
     
     # command ID
     try:
         (returnVal['cmdId'],) = struct.unpack('>H', self._toString(byteArray[:2]))
     except struct.error as err:
         raise ValueError(err)
     
     if   returnVal['cmdId']==CMDID_CONFIGURATION:
         
         try:
             (
                 returnVal['reportPeriod'],
                 returnVal['bridgeSettlingTime'],
                 returnVal['ldoOnTime'],
             ) = struct.unpack('>III', self._toString(byteArray[2:]))
         except struct.error as err:
             raise ValueError(err)
     
     elif returnVal['cmdId']==CMDID_REPORT:
         
         try:
             (
                 returnVal['temperature'],
                 returnVal['adcValue'],
             ) = struct.unpack('>IH', self._toString(byteArray[2:]))
         except struct.error as err:
             raise ValueError(err)
     
     elif returnVal['cmdId']==ERR_NO_SERVICE:
         pass
     
     elif returnVal['cmdId']==ERR_NOT_ENOUGH_BW:
         try:
             (
                 returnVal['bw'],
             ) = struct.unpack('>I', self._toString(byteArray[2:]))
         except struct.error as err:
             raise ValueError(err)
     
     else:
         raise ValueError("unexpected command ID {0}".format(returnVal['cmdId']))
     
     return returnVal
Esempio n. 4
0
 def calculate(self,data):
     
     if log.isEnabledFor(logging.DEBUG):
         log.debug('calculating for data={0}'.format(FormatUtils.formatBuffer(data)))
     
     ptr = 0
     tempfcs = 0xffff
     while ptr<len(data):
         tempfcs = (tempfcs >> 8) ^ self._fcstab[(tempfcs ^ data[ptr]) & 0xff];
         ptr += 1
     tempfcs ^= 0xffff
     fcs  = []
     fcs.append( (tempfcs>>0) & 0xff )
     fcs.append( (tempfcs>>8) & 0xff )
     
     if log.isEnabledFor(logging.DEBUG):
         log.debug('fcs=0x%2x%2x',fcs[0],fcs[1])
     
     return fcs
 
 #======================== private =========================================
Esempio n. 5
0
 def serialize(self,commandArray,fieldsToFill):
     
     # log
     if log.isEnabledFor(logging.DEBUG):
         output  = []
         output += ["serialize ..."]
         output += ["- commandArray:     {0}".format(commandArray)]
         output += ["- fieldsToFill:     {0}".format(fieldsToFill)]
         output  = '\n'.join(output)
         log.debug(output)
     
     # validate input
     if type(commandArray)!=types.ListType and type(commandArray)!=types.TupleType:
         raise TypeError("First parameter should be a list or tuple, not "+str(type(commandArray)))
     
     # initialize the output
     byteArray  = []
     
     for cmdCounter in range(len(commandArray)):
     
         # packet payload
         definition = self.ApiDef.getDefinition(
             ApiDefinition.ApiDefinition.COMMAND,
             commandArray[:cmdCounter+1]
         )
         
         fields = [ApiDefinition.Field(fieldRaw,self.ApiDef.fieldOptions)
                      for fieldRaw in definition['request']]
         
         for field in fields:
             thisFieldByteArray = []
             if field.name in ApiDefinition.ApiDefinition.RESERVED:
                 thisFieldByteArray.append(
                     self.ApiDef.subcommandNameToId(
                         ApiDefinition.ApiDefinition.COMMAND,
                         commandArray[:cmdCounter+1],
                         commandArray[cmdCounter+1]
                     )
                 )
             else:
                 val                          = fieldsToFill[field.name]
                 
                 if   field.format==ApiDefinition.FieldFormats.STRING:
                     thisFieldByteArray      += [ord(car) for car in val]
                 
                 elif field.format==ApiDefinition.FieldFormats.BOOL:
                     thisFieldByteArray.append(val)
                 
                 elif field.format==ApiDefinition.FieldFormats.INT:
                     thisFieldByteArray      += [operator.mod(int(val>>(8*i)), 0x100) for i in xrange(field.length-1, -1, -1)]
                 
                 elif field.format==ApiDefinition.FieldFormats.INTS:
                     if   field.length==1:
                         temp = struct.pack('>b',int(val))
                     elif field.length==2:
                         temp = struct.pack('>h',int(val))
                     elif field.length==4:
                         temp = struct.pack('>i',int(val))
                     else:
                         raise SystemError('field with format='+field.format+' and length='+str(field.length)+' unsupported.')
                     for i in range(len(temp)):
                         thisFieldByteArray.append(ord(temp[i]))
                 
                 elif field.format==ApiDefinition.FieldFormats.HEXDATA:
                     thisFieldByteArray    += val
                 
                 else:
                     raise SystemError('unknown field format='+field.format)
                 
                 # padding
                 while len(thisFieldByteArray)<field.length:
                     thisFieldByteArray  = [0x00]+thisFieldByteArray
             
             byteArray = byteArray+thisFieldByteArray
     
     cmdId = self.ApiDef.nameToId(ApiDefinition.ApiDefinition.COMMAND,commandArray)
     
     if log.isEnabledFor(logging.DEBUG):
         output  = []
         output += ["... serialize into"]
         output += ["- cmdId:            {0}".format(cmdId)]
         output += ["- byteArray:        {0}".format(FormatUtils.formatBuffer(byteArray))]
         output  = '\n'.join(output)
         log.debug(output)
     
     return cmdId,byteArray
Esempio n. 6
0
 def deserialize(self,type,id,byteArray):
     notRcOk         = False
     returnFields    = {}
     nameArray       = [self.ApiDef.idToName(type,id)]
     index           = 0
     
     # log
     if log.isEnabledFor(logging.DEBUG):
         output  = []
         output += ["deserialize ..."]
         output += ["- type:             {0}".format(type)]
         output += ["- id:               {0}".format(id)]
         output += ["- byteArray:        {0}".format(FormatUtils.formatBuffer(byteArray))]
         output  = '\n'.join(output)
         log.debug(output)
     
     continueParsing  = True
     while continueParsing:
         
         fieldDefs   = self.ApiDef.getResponseFields(type,nameArray)
         
         for fieldDef in fieldDefs:
             
             fieldMissing = False
             
             # isolate the piece of the byteArray corresponding to this field
             if fieldDef.length:
                 # this field has an expected length
                 
                 thisFieldArray = byteArray[index:index+fieldDef.length]
                 index         += fieldDef.length
                 
                 if   len(thisFieldArray)==0:
                     # field missing: allowed
                     fieldMissing   = True
                 elif len(thisFieldArray)<fieldDef.length:
                     # incomplete field: not allowed
                     raise CommandError(
                         CommandError.TOO_FEW_BYTES,
                         "incomplete field {0}".format(fieldDef.name),
                     )
                 
             else:
                 thisFieldArray = byteArray[index:]
                 index          = len(byteArray)
                 
                 if len(thisFieldArray)<1:
                     # too few bytes
                     fieldMissing    = True
             
             # find thisFieldValue
             if fieldMissing:
                 thisFieldValue = None
             else:
                 if   fieldDef.format==ApiDefinition.FieldFormats.STRING:
                     thisFieldValue = ''
                     for byte in thisFieldArray:
                         thisFieldValue += chr(byte)
                 
                 elif fieldDef.format==ApiDefinition.FieldFormats.BOOL:
                     if    len(thisFieldArray)==1 and thisFieldArray[0]==0x00:
                         thisFieldValue = False
                     elif  len(thisFieldArray)==1 and thisFieldArray[0]==0x01:
                         thisFieldValue = True
                     else:
                         raise CommandError(CommandError.VALUE_NOT_IN_OPTIONS,
                                            "field="+fieldDef.name+" value="+str(thisFieldValue))
                 
                 elif fieldDef.format==ApiDefinition.FieldFormats.INT:
                     thisFieldValue = 0
                     for i in range(len(thisFieldArray)):
                         thisFieldValue += thisFieldArray[i]*pow(2,8*(len(thisFieldArray)-i-1))
                 
                 elif fieldDef.format==ApiDefinition.FieldFormats.INTS:
                     tempList = [chr(i) for i in thisFieldArray]
                     tempString = ''.join(tempList)
                     if   len(thisFieldArray)==1:
                         (thisFieldValue,) = struct.unpack_from('>b',tempString)
                     elif len(thisFieldArray)==2:
                         (thisFieldValue,) = struct.unpack_from('>h',tempString)
                     elif len(thisFieldArray)==4:
                         (thisFieldValue,) = struct.unpack_from('>i',tempString)
                     else:
                         raise SystemError('field with format='+fieldDef.format+' and length='+str(fieldDef.length)+' unsupported.')
                 
                 elif fieldDef.format==ApiDefinition.FieldFormats.HEXDATA:
                     thisFieldValue = thisFieldArray
                 
                 else:
                     raise SystemError('unknown field format='+fieldDef.format)
                 
                 # make sure thisFieldValue in fieldDef.options
                 if fieldDef.options.validOptions:
                     if thisFieldValue not in fieldDef.options.validOptions:
                         raise CommandError(CommandError.VALUE_NOT_IN_OPTIONS,
                                            "field="+fieldDef.name+" value="+str(thisFieldValue))
             
             if fieldDef.name in ApiDefinition.ApiDefinition.RESERVED:
                 # the subcommand specifier cannot be missing
                 if thisFieldValue==None:
                     raise CommandError(
                         CommandError.TOO_FEW_BYTES,
                         "reserved field missing {0}".format(fieldDef.name),
                     )
                 idNextCommand = thisFieldValue
             else:
                 returnFields[fieldDef.name] = thisFieldValue
                 
             # stop if not RC_OK
             if  (
                     (ApiDefinition.ApiDefinition.RC in returnFields) and
                     (
                         returnFields[ApiDefinition.ApiDefinition.RC]!= \
                             ApiDefinition.ApiDefinition.RC_OK
                     )
                ):
                notRcOk = True
                break
         
         # continue if subCommand
         if  (
                 (not notRcOk)           and
                 continueParsing         and
                 self.ApiDef.hasSubcommands(type,nameArray)
             ):
             # find name of subCommand
             nameArray.append(self.ApiDef.subcommandIdToName(type,
                                                             nameArray,
                                                             idNextCommand))
             continueParsing = True
         else:
             continueParsing = False
         
         # stop if not RC_OK
         if  (
                 continueParsing         and
                 notRcOk
             ):
             continueParsing = False
         
         # stop if end of packet reached
         if  (
                 continueParsing         and
                 index>=len(byteArray)
             ):
             continueParsing = False
     
     if log.isEnabledFor(logging.DEBUG):
         output  = []
         output += ["... deserialized into"]
         output += ["- nameArray:        {0}".format(nameArray)]
         output += ["- returnFields:     {0}".format(returnFields)]
         output  = '\n'.join(output)
         log.debug(output)
     
     return nameArray,returnFields
Esempio n. 7
0
    def _notifDataCallback(self, notifName, notifParams):

        #get number of motes
        numMotes = dc2369aData().get('numDisplayedMotes')

        # verify board type
        if notifParams.dstPort != WKP_DC2369A:
            return

        #board is now of the correct type, add to list of accepted motes
        motes = dc2369aData().get('motes')
        motesCorrectType = dc2369aData().get('motesCorrectType')

        #check over all the motes, to see if the mote sending this data pack marked as viewable
        #if it is not marked as viewable, mark it as such
        for i in range(len(motes)):
            if tuple(notifParams.macAddress) == tuple(motes[i]):
                if not (motesCorrectType[i]):
                    motesCorrectType[i] = True
                    dc2369aData().set('motesCorrectType', motesCorrectType)
                    self.updateMotesCB()
                break  #if it is already marked as valid we can quit the for loop

        #only want to do anything if more then 1 mote
        if numMotes < 1:
            return

        #check to see that the address is associated with a displayed mote
        moteIndex = 0
        for i in range(numMotes):
            tempMote = dc2369aData().getDisplayedMote(i)
            if tuple(notifParams.macAddress) == tuple(tempMote.getAddress()):
                moteIndex = i
                break
            elif i == (numMotes - 1):
                return  #if it is not displayed, then we can quit

        #parse the data
        try:
            parsedData = self._parseData(notifParams.data)
        except ValueError as err:
            output = "Could not parse received data {0}".format(
                FormatUtils.formatBuffer(notifParams.data))
            print output
            log.error(output)
            return

        # log data
        output = []
        output += ["Received data:"]
        for (k, v) in parsedData.items():
            output += ["- {0:<15}: 0x{1:x} ({1})".format(k, v)]
        output = '\n'.join(output)
        log.debug(output)

        #grab mote
        tempMote = dc2369aData().getDisplayedMote(moteIndex)
        #if there is no mote yet we have nothing to do
        if tempMote == None:
            return

        #record current
        current = self.converters.convertCurrent(parsedData['current'])
        tempMote.setCurrent(current)

        #record charge
        charge = self.converters.convertCharge(parsedData['charge'])
        tempMote.setCharge(charge)

        dc2369aData().editDisplayedMote(tempMote, moteIndex)
Esempio n. 8
0
    def _notifDataCallback(self, notifName, notifParams):

        # only accept data from mote selected in the optionbox
        selectedMote = dc2126aData().get('selectedMote')

        if not selectedMote:
            return

        if tuple(notifParams.macAddress) != tuple(selectedMote):
            return

        if notifParams.dstPort != WKP_DC2126A:
            return

        # parse data
        try:
            parsedData = self._parseData(notifParams.data)
        except ValueError as err:
            output = "Could not parse received data {0}".format(
                FormatUtils.formatBuffer(notifParams.data))
            print output
            log.error(output)
            return

        # log
        output = []
        output += ["Received data:"]
        for (k, v) in parsedData.items():
            output += ["- {0:<15}: 0x{1:x} ({1})".format(k, v)]
        output = '\n'.join(output)
        log.debug(output)

        # handle data
        if parsedData['cmdId'] == CMDID_REPORT:

            # record temperature
            temperature = self.converters.convertTemperature(
                parsedData['temperature'])
            dc2126aData().set('temperature', temperature)

            # record adcValue
            adcValue = self.converters.convertAdcValue(parsedData['adcValue'])
            dc2126aData().set('adcValue', adcValue)

            # record energysource
            energysource = self.converters.convertEnergySource(
                notifParams.macAddress, adcValue)
            dc2126aData().set('energysource', energysource)

        elif parsedData['cmdId'] == CMDID_CONFIGURATION:

            # show new CFG values
            self.displayConfigurationCB(parsedData)

        elif parsedData['cmdId'] == ERR_NO_SERVICE:

            # display error
            self.displayErrorCB(
                'Cannot change configuration, no service information.')

        elif parsedData['cmdId'] == ERR_NOT_ENOUGH_BW:

            # display error
            self.displayErrorCB(
                "Not enough bandwidth (current setting: {}ms)".format(
                    parsedData['bw']))

        else:

            # display error
            self.displayErrorCB("received unexpected cmdId {0}".format(
                parsedData['cmdId']))
Esempio n. 9
0
    def _notifDataCallback(self,notifName,notifParams):
        
        # only accept data from mote selected in the optionbox
        selectedMote = dc2126aData().get('selectedMote')
        
        if not selectedMote:
            return

        if tuple(notifParams.macAddress) != tuple(selectedMote):
            return
        
        if notifParams.dstPort!=WKP_DC2126A:
            return
        
        # parse data
        try:
            parsedData = self._parseData(notifParams.data)
        except ValueError as err:
            output  = "Could not parse received data {0}".format(
                FormatUtils.formatBuffer(notifParams.data)
            )
            print output
            log.error(output)
            return
        
        # log
        output  = []
        output += ["Received data:"]
        for (k,v) in parsedData.items():
            output += ["- {0:<15}: 0x{1:x} ({1})".format(k,v)]
        output  = '\n'.join(output)
        log.debug(output)
        
        # handle data
        if   parsedData['cmdId']==CMDID_REPORT:
            
            # record temperature
            temperature = self.converters.convertTemperature(parsedData['temperature'])
            dc2126aData().set('temperature',temperature)
            
            # record adcValue
            adcValue = self.converters.convertAdcValue(parsedData['adcValue'])
            dc2126aData().set('adcValue',adcValue)
            
            # record energysource
            energysource = self.converters.convertEnergySource(notifParams.macAddress,adcValue)
            dc2126aData().set('energysource',energysource)
        
        elif parsedData['cmdId']==CMDID_CONFIGURATION:
            
            # show new CFG values 
            self.displayConfigurationCB(parsedData)
            
        elif parsedData['cmdId']==ERR_NO_SERVICE:
            
            # display error
            self.displayErrorCB('Cannot change configuration, no service information.')
        
        elif parsedData['cmdId']==ERR_NOT_ENOUGH_BW:
            
            # display error
            self.displayErrorCB("Not enough bandwidth (current setting: {}ms)".format(parsedData['bw']))
        
        else:
            
            # display error
            self.displayErrorCB("received unexpected cmdId {0}".format(parsedData['cmdId']))
Esempio n. 10
0
    def serialize(self, commandArray, fieldsToFill):

        # log
        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ["serialize ..."]
            output += ["- commandArray:     {0}".format(commandArray)]
            output += ["- fieldsToFill:     {0}".format(fieldsToFill)]
            output = '\n'.join(output)
            log.debug(output)

        # validate input
        if type(commandArray) != types.ListType and type(
                commandArray) != types.TupleType:
            raise TypeError("First parameter should be a list or tuple, not " +
                            str(type(commandArray)))

        # initialize the output
        byteArray = []

        for cmdCounter in range(len(commandArray)):

            # packet payload
            definition = self.ApiDef.getDefinition(
                ApiDefinition.ApiDefinition.COMMAND,
                commandArray[:cmdCounter + 1])

            fields = [
                ApiDefinition.Field(fieldRaw, self.ApiDef.fieldOptions)
                for fieldRaw in definition['request']
            ]

            for field in fields:
                thisFieldByteArray = []
                if field.name in ApiDefinition.ApiDefinition.RESERVED:
                    thisFieldByteArray.append(
                        self.ApiDef.subcommandNameToId(
                            ApiDefinition.ApiDefinition.COMMAND,
                            commandArray[:cmdCounter + 1],
                            commandArray[cmdCounter + 1]))
                else:
                    val = fieldsToFill[field.name]

                    if field.format == ApiDefinition.FieldFormats.STRING:
                        thisFieldByteArray += [ord(car) for car in val]

                    elif field.format == ApiDefinition.FieldFormats.BOOL:
                        thisFieldByteArray.append(val)

                    elif field.format == ApiDefinition.FieldFormats.INT:
                        thisFieldByteArray += [
                            operator.mod(int(val >> (8 * i)), 0x100)
                            for i in xrange(field.length - 1, -1, -1)
                        ]

                    elif field.format == ApiDefinition.FieldFormats.INTS:
                        if field.length == 1:
                            temp = struct.pack('>b', int(val))
                        elif field.length == 2:
                            temp = struct.pack('>h', int(val))
                        elif field.length == 4:
                            temp = struct.pack('>i', int(val))
                        else:
                            raise SystemError('field with format=' +
                                              field.format + ' and length=' +
                                              str(field.length) +
                                              ' unsupported.')
                        for i in range(len(temp)):
                            thisFieldByteArray.append(ord(temp[i]))

                    elif field.format == ApiDefinition.FieldFormats.HEXDATA:
                        thisFieldByteArray += val

                    else:
                        raise SystemError('unknown field format=' +
                                          field.format)

                    # padding
                    while len(thisFieldByteArray) < field.length:
                        thisFieldByteArray = [0x00] + thisFieldByteArray

                byteArray = byteArray + thisFieldByteArray

        cmdId = self.ApiDef.nameToId(ApiDefinition.ApiDefinition.COMMAND,
                                     commandArray)

        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ["... serialize into"]
            output += ["- cmdId:            {0}".format(cmdId)]
            output += [
                "- byteArray:        {0}".format(
                    FormatUtils.formatBuffer(byteArray))
            ]
            output = '\n'.join(output)
            log.debug(output)

        return cmdId, byteArray
Esempio n. 11
0
    def deserialize(self, type, id, byteArray):
        notRcOk = False
        returnFields = {}
        nameArray = [self.ApiDef.idToName(type, id)]
        index = 0

        # log
        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ["deserialize ..."]
            output += ["- type:             {0}".format(type)]
            output += ["- id:               {0}".format(id)]
            output += [
                "- byteArray:        {0}".format(
                    FormatUtils.formatBuffer(byteArray))
            ]
            output = '\n'.join(output)
            log.debug(output)

        continueParsing = True
        while continueParsing:

            fieldDefs = self.ApiDef.getResponseFields(type, nameArray)

            for fieldDef in fieldDefs:

                fieldMissing = False

                # isolate the piece of the byteArray corresponding to this field
                if fieldDef.length:
                    # this field has an expected length

                    thisFieldArray = byteArray[index:index + fieldDef.length]
                    index += fieldDef.length

                    if len(thisFieldArray) == 0:
                        # field missing: allowed
                        fieldMissing = True
                    elif len(thisFieldArray) < fieldDef.length:
                        # incomplete field: not allowed
                        raise CommandError(
                            CommandError.TOO_FEW_BYTES,
                            "incomplete field {0}".format(fieldDef.name),
                        )

                else:
                    thisFieldArray = byteArray[index:]
                    index = len(byteArray)

                    if len(thisFieldArray) < 1:
                        # too few bytes
                        fieldMissing = True

                # find thisFieldValue
                if fieldMissing:
                    thisFieldValue = None
                else:
                    if fieldDef.format == ApiDefinition.FieldFormats.STRING:
                        thisFieldValue = ''
                        for byte in thisFieldArray:
                            thisFieldValue += chr(byte)

                    elif fieldDef.format == ApiDefinition.FieldFormats.BOOL:
                        if len(thisFieldArray
                               ) == 1 and thisFieldArray[0] == 0x00:
                            thisFieldValue = False
                        elif len(thisFieldArray
                                 ) == 1 and thisFieldArray[0] == 0x01:
                            thisFieldValue = True
                        else:
                            raise CommandError(
                                CommandError.VALUE_NOT_IN_OPTIONS,
                                "field=" + fieldDef.name + " value=" +
                                str(thisFieldValue))

                    elif fieldDef.format == ApiDefinition.FieldFormats.INT:
                        thisFieldValue = 0
                        for i in range(len(thisFieldArray)):
                            thisFieldValue += thisFieldArray[i] * pow(
                                2, 8 * (len(thisFieldArray) - i - 1))

                    elif fieldDef.format == ApiDefinition.FieldFormats.INTS:
                        tempList = [chr(i) for i in thisFieldArray]
                        tempString = ''.join(tempList)
                        if len(thisFieldArray) == 1:
                            (thisFieldValue, ) = struct.unpack_from(
                                '>b', tempString)
                        elif len(thisFieldArray) == 2:
                            (thisFieldValue, ) = struct.unpack_from(
                                '>h', tempString)
                        elif len(thisFieldArray) == 4:
                            (thisFieldValue, ) = struct.unpack_from(
                                '>i', tempString)
                        else:
                            raise SystemError('field with format=' +
                                              fieldDef.format +
                                              ' and length=' +
                                              str(fieldDef.length) +
                                              ' unsupported.')

                    elif fieldDef.format == ApiDefinition.FieldFormats.HEXDATA:
                        thisFieldValue = thisFieldArray

                    else:
                        raise SystemError('unknown field format=' +
                                          fieldDef.format)

                    # make sure thisFieldValue in fieldDef.options
                    if fieldDef.options.validOptions:
                        if thisFieldValue not in fieldDef.options.validOptions:
                            raise CommandError(
                                CommandError.VALUE_NOT_IN_OPTIONS,
                                "field=" + fieldDef.name + " value=" +
                                str(thisFieldValue))

                if fieldDef.name in ApiDefinition.ApiDefinition.RESERVED:
                    # the subcommand specifier cannot be missing
                    if thisFieldValue == None:
                        raise CommandError(
                            CommandError.TOO_FEW_BYTES,
                            "reserved field missing {0}".format(fieldDef.name),
                        )
                    idNextCommand = thisFieldValue
                else:
                    returnFields[fieldDef.name] = thisFieldValue

                # stop if not RC_OK
                if  (
                        (ApiDefinition.ApiDefinition.RC in returnFields) and
                        (
                            returnFields[ApiDefinition.ApiDefinition.RC]!= \
                                ApiDefinition.ApiDefinition.RC_OK
                        )
                   ):
                    notRcOk = True
                    break

            # continue if subCommand
            if ((not notRcOk) and continueParsing
                    and self.ApiDef.hasSubcommands(type, nameArray)):
                # find name of subCommand
                nameArray.append(
                    self.ApiDef.subcommandIdToName(type, nameArray,
                                                   idNextCommand))
                continueParsing = True
            else:
                continueParsing = False

            # stop if not RC_OK
            if (continueParsing and notRcOk):
                continueParsing = False

            # stop if end of packet reached
            if (continueParsing and index >= len(byteArray)):
                continueParsing = False

        if log.isEnabledFor(logging.DEBUG):
            output = []
            output += ["... deserialized into"]
            output += ["- nameArray:        {0}".format(nameArray)]
            output += ["- returnFields:     {0}".format(returnFields)]
            output = '\n'.join(output)
            log.debug(output)

        return nameArray, returnFields