def createSetValuesPDU(header, parameter=[], references=[]): if not isinstance(header, Header): raise TypeError('Parameter "header" must be of type "Header".') length = 2 pdu = [] if parameter: parameterAPDU = createSetParametersAPDU(parameter) length += len(parameterAPDU) if references: referencesAPDU = createSetReferencesAPDU(references) length += len(referencesAPDU) pdu.extend( [header.startDelimiter, length, header.destAddr, header.sourceAddr]) if parameter: pdu.extend(parameterAPDU) if references: pdu.extend(referencesAPDU) crc = calcuteCrc(pdu) pdu.extend(bytes(crc)) arr = array.array('B', pdu) # TODO: arr.tostring() for I/O! return arr
def createGetValuesPDU(klass, header, protocolData=[], measurements=[], parameter=[], references=[], strings=[]): if not isinstance(header, Header): raise TypeError('Parameter "header" must be of type "Header".') length = 2 pdu = [] if protocolData: protocolAPDU = createGetProtocolDataAPDU(protocolData) length += len(protocolAPDU) if measurements: measurementAPDU = createGetMeasuredDataAPDU(klass, measurements) length += len(measurementAPDU) if parameter: parameterAPDU = createGetParametersAPDU(parameter) length += len(parameterAPDU) if references: referencesAPDU = createGetReferencesAPDU(references) length += len(referencesAPDU) if strings: stringsAPDU = createGetStringsAPDU(strings) length += len(stringsAPDU) pdu.extend( [header.startDelimiter, length, header.destAddr, header.sourceAddr]) if protocolData: pdu.extend(protocolAPDU) if parameter: pdu.extend(parameterAPDU) if measurements: pdu.extend(measurementAPDU) if references: pdu.extend(referencesAPDU) if strings: pdu.extend(stringsAPDU) crc = calcuteCrc(pdu) pdu.extend(bytes(crc)) arr = array.array('B', pdu) # TODO: arr.tostring() for I/O! return arr
def createResponse(request): """The actual 'simulation' function. """ result = [] length = 2 pdus = [] #klasses = [] for a in request.APDUs: klass = a.klass ack = a.ack data = a.data dataItemsByName = dict([(a, (b, c)) for a, b ,c in DATA_POOL[klass]]) if ack not in defs.CLASS_CAPABILITIES[klass]: raise defs.IllegalOperationError("%s-Operation not supported." % defs.operationToString(ack)) dataItemsById = dict([(v[2], (k, v[3], v[4])) for k, v in dataitems.DATAITEMS_FOR_CLASS[klass].items()]) apduLength = 0 length += 2 pdu = [] if ack == defs.OS_SET: pass # Ack = OK, Length = 0 is inherently generated! else: for item in data: name, acess, _ = dataItemsById[item] #print "KLASS: %s NAME: %s " % (klass, name) value, info = dataItemsByName[name] if ack == defs.OS_GET: apduLength += 1 # Currently only 8-bit data values. value = 0xff if value is None else value pdu.append(value) elif ack == defs.OS_INFO: sif = info.head & 0b11 pdu.append(info.head) if sif in (0, 1): apduLength += 1 # Unscaled value, i.e. no info scale field. else: apduLength += 4 pdu.append(info.unit) pdu.append(info.zero) pdu.append(info.range) pdus.append((klass, apduLength, pdu, )) length += apduLength if request.da == defs.CONNECTION_REQ_ADDR: da = getParameterValue('unit_addr') # Handle connection address. else: da = request.da result.extend([defs.SD_DATA_REPLY, length, request.sa, da]) for pdu in pdus: klass, apduLength, pdu = pdu result.append(klass) result.append(apduLength & 0x3f) result.extend(pdu) crc = calcuteCrc(result) result.extend((utils.hiByte(crc), utils.loByte(crc), )) return bytearray(result)
def createGetInfoPDU(klass, header, measurements=[], parameter=[], references=[]): ## To be defensive, at most 15 datapoints should be requested at once (min.frame length = 70 bytes). if not isinstance(header, Header): raise TypeError('Parameter "header" must be of type "Header".') length = 2 pdu = [] if measurements: if klass == defs.APDUClass.MEASURED_DATA: measurementsAPDU = createGetInfoAPDU(defs.APDUClass.MEASURED_DATA, measurements) if klass == defs.APDUClass.SIXTEENBIT_MEASURED_DATA: measurementsAPDU = createGetInfoAPDU( defs.APDUClass.SIXTEENBIT_MEASURED_DATA, measurements) length += len(measurementsAPDU) if parameter: parameterAPDU = createGetInfoAPDU( defs.APDUClass.CONFIGURATION_PARAMETERS, parameter) length += len(parameterAPDU) if references: referencesAPDU = createGetInfoAPDU(defs.APDUClass.REFERENCE_VALUES, references) length += len(referencesAPDU) pdu.extend( [header.startDelimiter, length, header.destAddr, header.sourceAddr]) if measurements: pdu.extend(measurementsAPDU) if parameter: pdu.extend(parameterAPDU) if references: pdu.extend(referencesAPDU) crc = calcuteCrc(pdu) pdu.extend(bytes(crc)) arr = array.array('B', pdu) # TODO: arr.tostring() for I/O! return arr
def createSetCommandsPDU(header, commands): if not isinstance(header, Header): raise TypeError('Parameter "header" must be of type "Header".') length = 2 pdu = [] commandsAPDU = createSetCommandsAPDU(commands) length += len(commandsAPDU) pdu.extend( [header.startDelimiter, length, header.destAddr, header.sourceAddr]) pdu.extend(commandsAPDU) crc = calcuteCrc(pdu) pdu.extend(bytes(crc)) arr = array.array('B', pdu) # TODO: arr.tostring() for I/O! return arr
def createResponse(request): """The actual 'simulation' function. """ result = [] length = 2 pdus = [] #klasses = [] for a in request.APDUs: klass = a.klass ack = a.ack data = a.data dataItemsByName = dict([(a, (b, c)) for a, b, c in DATA_POOL[klass]]) if ack not in defs.CLASS_CAPABILITIES[klass]: raise defs.IllegalOperationError("%s-Operation not supported." % defs.operationToString(ack)) dataItemsById = dict([ (v[2], (k, v[3], v[4])) for k, v in dataitems.DATAITEMS_FOR_CLASS[klass].items() ]) apduLength = 0 length += 2 pdu = [] if ack == defs.OS_SET: pass # Ack = OK, Length = 0 is inherently generated! else: for item in data: name, acess, _ = dataItemsById[item] #print("KLASS: %s NAME: %s " % (klass, name)) value, info = dataItemsByName[name] if ack == defs.OS_GET: if klass == 11: apduLength += 2 # 16-bit data values. value1 = 0xff if value is None else value pdu.append(value1) value2 = 0xff if value is None else value pdu.append(value2) else: apduLength += 1 # 8-bit data values. value1 = 0xff if value is None else value pdu.append(value) elif ack == defs.OS_INFO: sif = info.head & 0b11 pdu.append(info.head) if sif in (0, 1): apduLength += 1 # Unscaled value, i.e. no info scale field. else: apduLength += 4 pdu.append(info.unit) pdu.append(info.zero) pdu.append(info.range) pdus.append(( klass, apduLength, pdu, )) length += apduLength if request.da == defs.CONNECTION_REQ_ADDR: da = getParameterValue('unit_addr') # Handle connection address. else: da = request.da result.extend([defs.SD_DATA_REPLY, length, request.sa, da]) for pdu in pdus: klass, apduLength, pdu = pdu result.append(klass) result.append(apduLength & 0x3f) result.extend(pdu) crc = calcuteCrc(result) result.extend(( utils.hiByte(crc), utils.loByte(crc), )) return bytearray(result)
def test06(self): self.assertEqual(calcuteCrc(TEST_VECTORS[5]), RESULTS[5])