# Copyright(C) 2007 VTT Technical Research Centre of Finland
#
# This file is part of NOEN framework.
#
# NOEN framework is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2.
#
# NOEN framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: 6 byte integer writin for nano seconds
import struct
# Protocol version
protocolVersion = 0x02
# IDs
initialBinary = 0xFF
projectChange = 0x00
input1 = 0x0A
input2 = 0x0B
input3 = 0x0C
outputType = 0x10
output1 = 0x11
output2 = 0x12
output3 = 0x13
# Endians
littleEndian = [0x00, '<']
bigEndian = [0xFF, '>']
# Time resolutions
nanoSeconds = 0x00
microSeconds = 0x01
milliSeconds = 0x02
seconds = 0x03
minutes = 0x04
timeTypes = ['Q','I','I','I','I']
#timeResolution = milliseconds
# Datatypes:
# boolean(1), 1 byte, 0x00 = false, 0x01 = true
# integer(2), 1 byte
# integer(3), 2 byte
# integer(4), 3 byte
# integer(5), 4 byte
# integer(6), 8 byte
# float(7), 4 byte
# teksti(8)
# binary(9)
dataTypeLengths = [0,1,1,2,3,4,8,4,0,0]
dataTypes = ['','b','b','h','BBB','i','i','f','s','s']
# formatInitialData
# Initial binary: <0xFF><Order><protocol version><L><Project name><L><Version>
# <L><Test case number><L><Target><L><Description><time resolution><time><nnn>
def formatInitialData(project, version, testcaseNumber, target, description, timeResolution, time, id):
format = bigEndian[1] + 'BBBB' + \
str(len(project)) + 'sB' + \
str(len(version)) + 'sB' + \
str(len(testcaseNumber)) + 'sB' + \
str(len(target)) + 'sB' + \
str(len(description)) + 'sB' + 'IBBB'
return struct.pack(format, initialBinary, bigEndian[0], protocolVersion,\
len(project), project,\
len(version), version,\
len(testcaseNumber), testcaseNumber,\
len(target), target,\
len(description), description,\
timeResolution,\
time, id[0], id[1], id[2])
# formatInputData
# <0x0A><input number><datatype number><L*><data><time>
def formatInputData(inputNumber,dataType,data,time,timeResolution):
if dataType == 8 or dataType == 9:
format = bigEndian[1] + 'BHBH' + str(len(data)) + 's' + timeTypes[timeResolution]
#print "Number: " + str(inputNumber) + " Format: " + str(format)
return struct.pack(format, input1, inputNumber,\
dataType, len(data), data, time)
else:
if dataType == 4:
format = bigEndian[1] + 'BHB' + dataTypes[dataType] + timeTypes[timeResolution]
#print "Number: " + str(inputNumber) + " Format: " + str(format)
return struct.pack(format, input1, inputNumber,\
dataType, data[0],data[1],data[2], time)
else:
format = bigEndian[1] + 'BHB' + dataTypes[dataType] + timeTypes[timeResolution]
#print "Number: " + str(inputNumber) + " Format: " + str(format)
return struct.pack(format, input1, inputNumber,\
dataType, data, time)
# formatInput2Data
# <0x0B><input number><datatype number><number of inputs><data><time><data><time>
def formatInput2Data(firstInputNumber,dataType,dataTimes):
#if dataType == 8 or dataType == 9:
# format = 'BHBH' + str(len(data)) + 'sI'
# return struct.pack(format, input1, inputNumber,\
# dataType, len(data), data, time)
#else:
if dataType == 4:
format = bigEndian[1] + 'BHBH'
input2Data = struct.pack(format, input2, firstInputNumber,\
dataType, len(dataTimes)).rstrip('\n')
format = bigEndian[1] + dataTypes[dataType] + 'I'
for data,time in dataTimes:
input2Data += struct.pack(format,data[0],data[1],data[2],time).rstrip('\n')
else:
format = bigEndian[1] + 'BHBH'
input2Data = struct.pack(format, input2, firstInputNumber,\
dataType, len(dataTimes)).rstrip('\n')
format = bigEndian[1] + dataTypes[dataType] + 'I'
for data,time in dataTimes:
input2Data += struct.pack(format,data,time).rstrip('\n')
return input2Data
# formatInput3Data
# <0x0C><input number><datatype number><number of inputs><data><data><data><data>
def formatInput3Data(firstInputNumber,dataType,datas):
#if dataType == 8 or dataType == 9:
# format = 'BHBH' + str(len(data)) + 'sI'
# return struct.pack(format, input1, inputNumber,\
# dataType, len(data), data, time)
#else:
if dataType == 4:
format = bigEndian[1] + 'BHBH'
input3Data = struct.pack(format, input3, firstInputNumber,\
dataType, len(datas)).rstrip('\n')
format = dataTypes[dataType]
for data in datas:
input3Data += struct.pack(format,data[0],data[1],data[2]).rstrip('\n')
else:
format = bigEndian[1] + 'BHBH'
input3Data = struct.pack(format, input3, firstInputNumber,\
dataType, len(datas)).rstrip('\n')
format = dataTypes[dataType]
for data in datas:
input3Data += struct.pack(format,data).rstrip('\n')
return input3Data
# formatOutputType
# <0x10><output type number><L><output type name><datatype number>
def formatOutputType(outputTypeNumber,outputTypeName,dataType):
format = bigEndian[1] + 'BBB' + str(len(outputTypeName)) + 'sB'
return struct.pack(format,outputType,outputTypeNumber,len(outputTypeName),outputTypeName,dataType)
# formatOutputData
# <0x11><output number><output type><L*><data><time>
def formatOutput1Data(outputNumber,outputType,dataType,data,time):
if dataType == 9 or dataType == 8:
format = bigEndian[1] + 'BHBH' + str(len(data)) + 'sI'
return struct.pack(format,output1,outputNumber,\
outputType,len(data),data,time)
else:
if dataType == 4:
format = bigEndian[1] + 'BHB' + dataTypes[dataType] + 'I'
return struct.pack(format,output1,outputNumber,\
outputType,data[0],data[1],data[2],time)
else:
format = bigEndian[1] + 'BHB' + dataTypes[dataType] + 'I'
return struct.pack(format,output1,outputNumber,\
outputType,data,time)
# formatOutput2Data
# <0x12><output number><output type><number of outputs><data><time><data><time>
def formatOutput2Data(outputNumber,outputType,dataType,dataTimes):
#if dataType == 9 or dataType == 8:
# format = 'BHBB' + str(len(data)) + 'sI'
# return struct.pack(format,output1,outputNumber,\
# outputType,len(data),data,time)
#else:
if dataType == 4:
format = bigEndian[1] + 'BHBH'
output2Data = struct.pack(format,output2,outputNumber,\
outputType,len(dataTimes))
format = bigEndian[1] + dataTypes[dataType] + 'I'
for data,time in dataTimes:
output2Data += struct.pack(format,data[0],data[1],data[2],time).rstrip('\n')
else:
format = bigEndian[1] + 'BHBH'
output2Data = struct.pack(format,output2,outputNumber,\
outputType,len(dataTimes))
format = bigEndian[1] + dataTypes[dataType] + 'I'
for data,time in dataTimes:
output2Data += struct.pack(format,data,time).rstrip('\n')
return output2Data
# formatOutput2Data
# <0x12><output number><output type><number of outputs><data><time><data><time>
def formatOutput3Data(outputNumber,outputType,dataType,datas):
#if dataType == 9 or dataType == 8:
# format = 'BHBB' + str(len(data)) + 'sI'
# return struct.pack(format,output1,outputNumber,\
# outputType,len(data),data,time)
#else:
if dataType == 4:
format = bigEndian[1] + 'BHBH'
output3Data = struct.pack(format,output3,outputNumber,\
outputType,len(datas))
format = bigEndian[1] + dataTypes[dataType]
for data in datas:
output3Data += struct.pack(format,data[0],data[1],data[2]).rstrip('\n')
else:
format = bigEndian[1] + 'BHBH'
output3Data = struct.pack(format,output3,outputNumber,\
outputType,len(datas))
format = bigEndian[1] + dataTypes[dataType]
for data in datas:
output3Data += struct.pack(format,data).rstrip('\n')
return output3Data
def intToBytes(intValue):
bytes = struct.pack('>I',intValue)
bytes = struct.unpack('>BBBB',bytes)
return bytes
def formatProjectChange(id):
format = bigEndian[1] + 'BBBB'
return struct.pack(format,projectChange,id[0],id[1],id[2])
# writeData
# opens binary file for writing and writes sample binaryfile
def writeData():
binFile = file('binarySample.dat', 'wb')
#binFile.write(struct.pack('>2sBH2s','AA',255,255,'AA'))
#binFile.write(struct.pack('2sBHBH2s','TT',10,1,8,11,'TT'))
binFile.write(formatInitialData('Project Name', '1.0.1', '1.1', 'Target', 'Description', microSeconds,12345,[3,2,1]).rstrip('\n'))
binFile.write(formatInputData(1,8,'test text data',1234567890,microSeconds).rstrip('\n'))
binFile.write(formatInitialData('Project 2 Name', '1.0.0', '1.11', 'Target2', 'Description2', nanoSeconds,12345,[3,2,2]).rstrip('\n'))
binFile.write(formatProjectChange([3,2,1]).rstrip('\n'))
binFile.write(formatInputData(2,7,1.234,123456789,microSeconds).rstrip('\n'))
binFile.write(formatInput2Data(3,5,[[1,12345],[420,987654],[153,666],[144000,616],[715517,7331]]))
binFile.write(formatInput3Data(8,5,[1,420,153,144000,715517]))
binFile.write(formatInputData(13,4,[0,0,1],123456789,microSeconds).rstrip('\n'))
binFile.write(formatInput2Data(14,4,[[[255,255,42],12345],[[0,0,255],852]]))
binFile.write(formatInput3Data(16,4,[[127,255,255],[0,1,164]]))
binFile.write(formatOutputType(5,'datarate',4).rstrip('\n'))
binFile.write(formatOutputType(6,'Output text message',8).rstrip('\n'))
binFile.write(formatOutputType(7,'3 byte integer',4).rstrip('\n'))
binFile.write(formatOutputType(8,'1 byte integer',2).rstrip('\n'))
binFile.write(formatOutputType(9,'2 byte int',3).rstrip('\n'))
binFile.write(formatOutput1Data(1,6,8,'output text',1234566).rstrip('\n'))
binFile.write(formatOutput1Data(2,3,5,9999,1234566).rstrip('\n'))
binFile.write(formatOutput2Data(3,3,5,[[123,456],[789,101],[234,56789],[9854,45789],[10000,9899999]]))
binFile.write(formatOutput3Data(8,9,3,[123,789,234,9876,1000]))
binFile.write(formatOutput1Data(13,7,4,[147,255,0x2B],1234566).rstrip('\n'))
binFile.write(formatOutput1Data(14,7,4,[0,0,1],1234567).rstrip('\n'))
binFile.write(formatOutput1Data(15,7,4,[255,255,254],1234568).rstrip('\n'))
binFile.write(formatOutput1Data(16,7,4,[128,0,1],1234569).rstrip('\n'))
binFile.write(formatOutput1Data(17,8,2,-1,1234570).rstrip('\n'))
binFile.write(formatOutput2Data(18,7,4,[[[255,255,42],12345],[[0,0,255],852]]))
binFile.write(formatOutput3Data(20,7,4,[[255,255,42],[0,0,255]]))
binFile.write(formatProjectChange([3,2,2]).rstrip('\n'))
binFile.write(formatInputData(1,8,'nanoseconds test:2199023255552',2199023255552,nanoSeconds).rstrip('\n'))
binFile.close()
print 'binary data written!'
def writeTestBinary():
binFile = file('binarySample.txt', 'wb')
binFile.write(formatOutput3Data(8,3,2,[123,789,234,9876,1000]))
print 'binary data written!'
def writeDataToRows():
binFile = file('binarySample.txt', 'wb')
#binFile.write(struct.pack('>2sBH2s','AA',255,255,'AA'))
#binFile.write(struct.pack('2sBHBH2s','TT',10,1,8,11,'TT'))
binFile.write(formatInitialData('Project Name', '1.0.1', '1.1', 'Target', 'Description', microSeconds,12345,[3,2,1]))
binFile.write(formatInputData(1,8,'test text data',1234567890))
binFile.write(formatInitialData('Project 2 Name', '1.0.0', '1.11', 'Target2', 'Description2', microSeconds,12345,[3,2,2]))
binFile.write(formatProjectChange([3,2,1]))
binFile.write(formatInputData(2,7,1.234,123456789))
binFile.write(formatInput2Data(3,5,[[1,12345],[420,987654],[153,666],[144000,616],[715517,7331]]))
binFile.write(formatInput3Data(3,5,[1,420,153,144000,715517]))
binFile.write(formatOutputType(5,'datarate',4))
binFile.write(formatOutputType(6,'Output text message',8))
binFile.write(formatOutput1Data(1,6,8,'output text',1234566))
binFile.write(formatOutput1Data(2,3,5,9999,1234566))
binFile.write(formatOutput2Data(3,3,5,[[123,456],[789,101],[234,56789],[9854,45789],[10000,9899999]]))
binFile.write(formatOutput3Data(3,3,5,[123,789,234,9876,1000]))
binFile.close()
print 'binary data written to rows!'
writeData()
#writeTestBinary()
#writeDataToRows()