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 ''
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))
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))
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)
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)
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)
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
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)
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)