Example #1
0
 def deserialize(self):
     """Turns a sequence of bytes into a message dictionary."""
     if self.msgbytes is None:
         raise LLRPError('No message bytes to deserialize.')
     data = ''.join(self.msgbytes)
     msgtype, length, msgid = struct.unpack(self.full_hdr_fmt,
                                            data[:self.full_hdr_len])
     ver = (msgtype >> 10) & BITMASK(3)
     msgtype = msgtype & BITMASK(10)
     try:
         name = Message_Type2Name[msgtype]
         logger.debug('deserializing %s command', name)
         decoder = Message_struct[name]['decode']
     except KeyError:
         raise LLRPError('Cannot find decoder for message type '
                         '{}'.format(msgtype))
     body = data[self.full_hdr_len:length]
     try:
         self.msgdict = {name: dict(decoder(body))}
         self.msgdict[name]['Ver'] = ver
         self.msgdict[name]['Type'] = msgtype
         self.msgdict[name]['ID'] = msgid
         logger.debug('done deserializing %s command', name)
     except LLRPError:
         logger.exception('Problem with %s message format', name)
         return ''
     return ''
Example #2
0
    def get_tx_power(self, tx_power):
        """Validates tx_power against self.tx_power_table

        @param tx_power: index into the self.tx_power_table list; if tx_power
        is 0 then the max power from self.tx_power_table
        @return: a tuple: tx_power_index, power_dbm from self.tx_power_table
        @raise: LLRPError if the requested index is out of range
        """
        assert len(self.tx_power_table) > 0

        logger.debug('requested tx_power: %s', tx_power)
        min_power = self.tx_power_table.index(min(self.tx_power_table))
        max_power = self.tx_power_table.index(max(self.tx_power_table))

        if tx_power == 0:
            # tx_power = 0 means max power
            max_power_dbm = max(self.tx_power_table)
            tx_power = self.tx_power_table.index(max_power_dbm)
            return tx_power, max_power_dbm

        try:
            power_dbm = self.tx_power_table[tx_power]
            return tx_power, power_dbm
        except IndexError:
            raise LLRPError('Invalid tx_power: requested={},'
                            ' min_available={}, max_available={}'.format(
                                self.tx_power, min_power, max_power))
Example #3
0
 def getStateName(_, state):
     try:
         return [
             st_name for st_name, st_num in LLRPClient.getStates()
             if st_num == state
         ][0]
     except IndexError:
         raise LLRPError('unknown state {}'.format(state))
Example #4
0
    def parseCapabilities(self, capdict):
        def find_p(p, arr):
            m = p(arr)
            for idx, val in enumerate(arr):
                if val == m: return idx

        # check requested antenna set
        gdc = capdict['GeneralDeviceCapabilities']
        if max(self.antennas) > gdc['MaxNumberOfAntennaSupported']:
            reqd = ','.join(map(str, self.antennas))
            avail = ','.join(
                map(str, range(1, gdc['MaxNumberOfAntennaSupported'] + 1)))
            logger.warn(
                'Invalid antenna set specified: requested=%s,'
                ' available=%s; ignoring invalid antennas', reqd, avail)
            self.antennas = [ant for ant in self.antennas \
                            if ant <= gdc['MaxNumberOfAntennaSupported']]

        # check requested Tx power
        logger.debug('requested tx_power: %s', self.tx_power)
        bandtbl = capdict['RegulatoryCapabilities']['UHFBandCapabilities']
        bandtbl = {k: v for k, v in bandtbl.items() \
            if k.startswith('TransmitPowerLevelTableEntry')}
        self.tx_power_table = [
            0,
        ] * (len(bandtbl) + 1)
        for k, v in bandtbl.items():
            idx = v['Index']
            self.tx_power_table[idx] = int(v['TransmitPowerValue']) / 100.0
        logger.debug('tx_power_table: %s', self.tx_power_table)
        if self.tx_power == 0:
            # tx_power = 0 means max power
            self.tx_power = find_p(max, self.tx_power_table)
        elif self.tx_power not in range(len(self.tx_power_table)):
            raise LLRPError('Invalid tx_power: requested={},' \
                    ' max_available={}, min_available={}'.format(self.tx_power,
                        find_p(max, self.tx_power_table),
                        find_p(min, self.tx_power_table)))
        logger.debug('set tx_power: %s (%s dBm)', self.tx_power,
                     self.tx_power_table[self.tx_power])

        # fill UHFC1G2RFModeTable & check requested modulation & Tari
        match = False  # have we matched the user's requested values yet?
        regcap = capdict['RegulatoryCapabilities']
        logger.info('requested modulation: %s', self.modulation)
        for v in regcap['UHFBandCapabilities']['UHFRFModeTable'].values():
            match = v['Mod'] == Modulation_Name2Type[self.modulation]
            if self.tari:
                match = match and (v['MaxTari'] == self.tari)
            if match:
                self.reader_mode = dict(v)
        if not self.reader_mode:
            taristr = ' and Tari={}'.format(self.tari) if self.tari else ''
            logger.warn('Could not find reader mode matching '\
                    'modulation=%s%s', self.modulation, taristr)
            self.reader_mode = dict(regcap['UHFBandCapabilities']\
                    ['UHFRFModeTable']['UHFC1G2RFModeTableEntry0'])
        logger.info('using reader mode: %s', self.reader_mode)
Example #5
0
File: llrp.py Project: nneil/sllurp
    def startAccess (self, readWords=None, writeWords=None, *args):
        m = Message_struct['AccessSpec']
        accessSpecID = 1
        if readWords:
            opSpecParam = {
                'OpSpecID': 0,
                'MB': 0,
                'WordPtr': 0,
                'WordCount': readWords,
                'AccessPassword': 0,
            }
        elif writeWords:
            opSpecParam = {
                'OpSpecID': 0,
                'MB': 0,
                'WordPtr': 0,
                'AccessPassword': 0,
                'WriteDataWordCount': writeWords,
                'WriteData': '\xff\xff', # XXX allow user-defined pattern
            }
        else:
            raise LLRPError('startAccess requires readWords or writeWords.')
        accessSpec = {
            'Type': m['type'],
            'AccessSpecID': accessSpecID,
            'AntennaID': 0, # all antennas
            'ProtocolID': AirProtocol['EPCGlobalClass1Gen2'],
            'C': False, # disabled by default
            'ROSpecID': 0, # all ROSpecs
            'AccessSpecStopTrigger': {
                # 1 = stop after OperationCountValue accesses
                'AccessSpecStopTriggerType': 0,
                'OperationCountValue': 1,
            },
            'AccessCommand': {
                'TagSpecParameter': {
                    'C1G2TargetTag': { # XXX correct values?
                        'MB': 0,
                        'M': 1,
                        'Pointer': 0,
                        'MaskBitCount': 0,
                        'TagMask': 0,
                        'DataBitCount': 0,
                        'TagData': 0
                    }
                },
                'OpSpecParameter': opSpecParam,
            },
            'AccessReportSpec': {
                'AccessReportTrigger': 1 # report at end of access
            }
        }

        d = defer.Deferred()
        d.addCallback(self.send_ENABLE_ACCESSSPEC, accessSpecID)
        d.addErrback(self.panic, 'ADD_ACCESSSPEC failed')

        self.send_ADD_ACCESSSPEC(accessSpec, onCompletion=d)
Example #6
0
 def serialize(self):
     if self.msgdict is None:
         raise LLRPError('No message dict to serialize.')
     name = self.msgdict.keys()[0]
     logger.debug('serializing %s command', name)
     ver = self.msgdict[name]['Ver'] & BITMASK(3)
     msgtype = self.msgdict[name]['Type'] & BITMASK(10)
     msgid = self.msgdict[name]['ID']
     try:
         encoder = Message_struct[name]['encode']
     except KeyError:
         raise LLRPError('Cannot find encoder for message type '
                         '{}'.format(name))
     data = encoder(self.msgdict[name])
     self.msgbytes = struct.pack(self.full_hdr_fmt, (ver << 10) | msgtype,
                                 len(data) + self.full_hdr_len,
                                 msgid) + data
     logger.debug('serialized bytes: %s', hexlify(self.msgbytes))
     logger.debug('done serializing %s command', name)
Example #7
0
 def __init__(self, msgdict=None, msgbytes=None):
     if not (msgdict or msgbytes):
         raise LLRPError('Provide either a message dict or a sequence' \
                 ' of bytes.')
     if msgdict:
         self.msgdict = LLRPMessageDict(msgdict)
         if not msgbytes:
             self.serialize()
     if msgbytes:
         self.msgbytes = msgbytes
         if not msgdict:
             self.deserialize()
     self.peername = None
Example #8
0
    def startAccess(self,
                    readWords=None,
                    writeWords=None,
                    target=None,
                    accessStopParam=None,
                    accessSpecID=1,
                    param=None,
                    *args):
        m = Message_struct['AccessSpec']
        if not target:
            target = {
                'MB': 0,
                'Pointer': 0,
                'MaskBitCount': 0,
                'TagMask': '',
                'DataBitCount': 0,
                'TagData': ''
            }

        opSpecParam = {
            'OpSpecID': 0,
            'AccessPassword': 0,
        }

        if readWords:
            opSpecParam['MB'] = readWords['MB']
            opSpecParam['WordPtr'] = readWords['WordPtr']
            opSpecParam['WordCount'] = readWords['WordCount']
            if 'OpSpecID' in readWords:
                opSpecParam['OpSpecID'] = readWords['OpSpecID']
            if 'AccessPassword' in readWords:
                opSpecParam['AccessPassword'] = readWords['AccessPassword']

        elif writeWords:
            opSpecParam['MB'] = writeWords['MB']
            opSpecParam['WordPtr'] = writeWords['WordPtr']
            opSpecParam['WriteDataWordCount'] = \
                writeWords['WriteDataWordCount']
            opSpecParam['WriteData'] = writeWords['WriteData']
            if 'OpSpecID' in writeWords:
                opSpecParam['OpSpecID'] = writeWords['OpSpecID']
            if 'AccessPassword' in writeWords:
                opSpecParam['AccessPassword'] = writeWords['AccessPassword']

        elif param:
            # special parameters like C1G2Lock
            opSpecParam = param

        else:
            raise LLRPError('startAccess requires readWords or writeWords.')

        if not accessStopParam:
            accessStopParam = {}
            accessStopParam['AccessSpecStopTriggerType'] = 1
            accessStopParam['OperationCountValue'] = 5

        accessSpec = {
            'Type': m['type'],
            'AccessSpecID': accessSpecID,
            'AntennaID': 0,  # all antennas
            'ProtocolID': AirProtocol['EPCGlobalClass1Gen2'],
            'C': False,  # disabled by default
            'ROSpecID': 0,  # all ROSpecs
            'AccessSpecStopTrigger': accessStopParam,
            'AccessCommand': {
                'TagSpecParameter': {
                    'C1G2TargetTag': {  # XXX correct values?
                        'MB': target['MB'],
                        'M': 1,
                        'Pointer': target['Pointer'],
                        'MaskBitCount': target['MaskBitCount'],
                        'TagMask': target['TagMask'],
                        'DataBitCount': target['DataBitCount'],
                        'TagData': target['TagData']
                    }
                },
                'OpSpecParameter': opSpecParam,
            },
            'AccessReportSpec': {
                'AccessReportTrigger': 1  # report at end of access
            }
        }

        d = defer.Deferred()
        d.addCallback(self.send_ENABLE_ACCESSSPEC, accessSpecID)
        d.addErrback(self.panic, 'ADD_ACCESSSPEC failed')

        self.send_ADD_ACCESSSPEC(accessSpec, onCompletion=d)
Example #9
0
    def startAccess(self,
                    readWords=None,
                    writeWords=None,
                    accessStopParam=None,
                    target=None,
                    accessSpecID=1,
                    *args):
        #logger.info(accessStopParam)
        #logger.info(writeWords)
        if not target:
            logger.info("define default target")
            target = {
                'MB': 1,  # EPC = 1, userMem = 3
                'M': 1,
                'Pointer': 0,
                'MaskBitCount': 0,  #16*2,
                'TagMask':
                '',  #'\x00\xFF\xFF\x00',#\xFF\xFF\xFF\xFF', #TODO make this useful
                'DataBitCount': 0,  #16*2,
                'TagData':
                '',  #'\xF1\x65\x34\x00',  # \xF1\x65\x34\x00\x00\x34\xB0\x07' # tag 269 needs 34000269
            }

        opSpecParam = []
        for i in range(len(writeWords) if writeWords else 1):
            opSpecParam.append({
                'OpSpecID': 2 + i,
                'AccessPassword': 0,
            })

        if readWords:
            opSpecParam[0]['MB'] = readWords['MB']
            opSpecParam[0]['WordPtr'] = readWords['WordPtr']
            opSpecParam[0]['WordCount'] = readWords['WordCount']
            if 'OpSpecID' in readWords:
                opSpecParam[0]['OpSpecID'] = readWords['OpSpecID']

        elif writeWords is not None:
            for i in range(len(writeWords)):
                opSpecParam[i]['MB'] = writeWords[i]['MB']
                opSpecParam[i]['WordPtr'] = writeWords[i]['WordPtr']
                opSpecParam[i]['WriteDataWordCount'] = writeWords[i][
                    'WriteDataWordCount']
                opSpecParam[i]['WriteData'] = writeWords[i]['WriteData']
                #if 'OpSpecID' in writeWords:
                #    opSpecParam[i]['OpSpecID'] = writeWords[i]['OpSpecID']
            logger.info("len(writeWords) = %i", len(writeWords))
        else:
            raise LLRPError('startAccess requires readWords or writeWords.')

        accessSpec = {
            'Type': Message_struct['AccessSpec']['type'],
            'AccessSpecID': accessSpecID,
            'AntennaID': 0,  # all antennas
            'ProtocolID': AirProtocol['EPCGlobalClass1Gen2'],
            'C': False,  # disabled by default
            'ROSpecID': 0,  # all ROSpecs
            'AccessSpecStopTrigger': accessStopParam,
            'AccessCommand': {
                'TagSpecParameter': {
                    'C1G2TargetTag': target,
                },
                'OpSpecParameter': opSpecParam,
            },
            'AccessReportSpec': {
                'AccessReportTrigger': 1  # report at end of access
            }
        }

        d = defer.Deferred()
        d.addCallback(self.send_ENABLE_ACCESSSPEC, accessSpecID)
        d.addErrback(self.panic, 'ADD_ACCESSSPEC failed')

        self.send_ADD_ACCESSSPEC(accessSpec, onCompletion=d)