Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve transcript for external programs #425

Merged
merged 3 commits into from
Apr 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified data/decodings/homematic_complete
Binary file not shown.
36 changes: 27 additions & 9 deletions data/decodings/homematic_complete.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <string.h>

#define SHORTEN_PREAMBLE_TO_32 0

typedef unsigned char byte;
typedef unsigned short uint16;

Expand Down Expand Up @@ -39,12 +41,19 @@ void print_binary(byte inpt)
else putchar('0');
}

void print_preamble_nibbles(int count)
{
int i;
for (i = 0; i < count; i++)
printf("1010");
}

int find_preamble_start_in_bit(char *string, int len)
{
char homematic_sync[]="11101001110010101110100111001010";
char homematic_sync[] = "11101001110010101110100111001010";
for(int i = 0, j = 0; i < len; i++)
{
if(string[i]==homematic_sync[j])
if(string[i] == homematic_sync[j])
{
j++;
if(j == 32 && i>= 63) return i-63;
Expand Down Expand Up @@ -103,18 +112,19 @@ void xor_lfsr(char *string)

int main(int argc, char **argv)
{
int i, j, max, offset, len;
byte dec[256]={0}, enc[256]={0}, crc_ok;
char string[2048]={0};
int i, j, max, offset, len, preamble_additional_length;
byte dec[1024]={0}, enc[1024]={0}, crc_ok;
char string[65536]={0};
uint16 crcvalue;
offset = 8; // Preamble + Sync

// Copy data (argv[2]) to string if length is ok, shorten to multiple of 8 bit
if (strlen(argv[2]) > 256*8 || strlen(argv[2]) < 4) return -1;
if (strlen(argv[2]) > 8192*8 || strlen(argv[2]) < 4) return -1;
len = strlen(argv[2]);

i = find_preamble_start_in_bit(argv[2], len);
if(i < 0) return 0; // preamble+sync not found or wrong length
preamble_additional_length = i;

len = (len-i)-(len-i)%8;
memcpy(string, argv[2]+i, len);
Expand All @@ -130,7 +140,7 @@ int main(int argc, char **argv)
for (i = 0; i < strlen(string)-3; i+=8)
enc[i/8] = str2byte(&string[i]);
max = i/8;
memcpy(&dec, &enc, 256);
memcpy(&dec, &enc, 1024);

// Check CRC
crcvalue = crc(&dec[8], max-2-8);
Expand Down Expand Up @@ -167,6 +177,10 @@ int main(int argc, char **argv)
dec[max-2] = 0xD0;
}

// Prepend preamble longer than 32 bits
if(0 == SHORTEN_PREAMBLE_TO_32 && preamble_additional_length > 0)
print_preamble_nibbles(preamble_additional_length/4);

for(i = 0; i < max; i++)
print_binary(dec[i]);
}
Expand All @@ -176,7 +190,7 @@ int main(int argc, char **argv)
for (i = 0; i < strlen(string)-3; i+=8)
dec[i/8] = str2byte(&string[i]);
max = i/8;
memcpy(&enc, &dec, 256);
memcpy(&enc, &dec, 1024);

/*
* byte[] Dec = new byte[Enc.Length];
Expand All @@ -201,7 +215,7 @@ int main(int argc, char **argv)
enc[max-2] = (crcvalue >> 8) & 0xFF;

// Convert to string
memset(string, 0, 2048);
memset(string, 0, 65536);
for(i = 0; i < max; i++)
{
for(j = 0; j < 8; j++)
Expand All @@ -211,6 +225,10 @@ int main(int argc, char **argv)
// Apply datawhitening
xor_lfsr(string+64);

// Prepend preamble longer than 32 bits
if(0 == SHORTEN_PREAMBLE_TO_32 && preamble_additional_length > 0) // Add preamble longer than 32 bits
print_preamble_nibbles(preamble_additional_length/4);

// Print bits and duplicate last bit
printf("%s%c\n", string, string[strlen(string)-1]);
}
Expand Down
16 changes: 8 additions & 8 deletions data/ui/simulator_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>178</width>
<height>62</height>
<width>1066</width>
<height>767</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
Expand Down Expand Up @@ -180,8 +180,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>100</width>
<height>30</height>
<width>1066</width>
<height>767</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
Expand Down Expand Up @@ -237,7 +237,7 @@
</property>
<widget class="QWidget" name="tab_simulation">
<attribute name="title">
<string>Messages</string>
<string>Status</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
Expand Down Expand Up @@ -445,7 +445,7 @@ QGroupBox::indicator:checked {
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Transcript</string>
<string>Messages</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
Expand All @@ -454,7 +454,7 @@ QGroupBox::indicator:checked {
<bool>true</bool>
</property>
<property name="placeholderText">
<string>You will find the transcript of the simulation here.</string>
<string>Here you will find all messages that were sent and received during simulation.</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -514,7 +514,7 @@ QGroupBox::indicator:checked {
</widget>
<widget class="QWidget" name="tab_device">
<attribute name="title">
<string>SDR Status</string>
<string>Devices</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
Expand Down
13 changes: 8 additions & 5 deletions src/urh/controller/dialogs/SimulatorDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,22 @@ def update_buttons(self):
self.ui.btnLogAll.setEnabled(not all_items_selected)
self.ui.btnLogNone.setEnabled(any_item_selected)

def __get_full_transcript(self) -> list:
return self.simulator.transcript.get_for_all_participants(all_rounds=True,
use_bit=self.ui.radioButtonTranscriptBit.isChecked())

def update_view(self):
for device_message in filter(None, map(str.rstrip, self.simulator.device_messages())):
self.ui.textEditDevices.append(device_message)

for log_msg in filter(None, map(str.rstrip, self.simulator.read_log_messages())):
self.ui.textEditSimulation.append(log_msg)

for line in self.simulator.get_full_transcript(start=self.current_transcript_index,
use_bit=self.ui.radioButtonTranscriptBit.isChecked()):
transcript = self.__get_full_transcript()
for line in transcript[self.current_transcript_index:]:
self.ui.textEditTranscript.append(line)

self.current_transcript_index = len(self.simulator.transcript)
self.current_transcript_index = len(transcript)
current_repeat = str(self.simulator.current_repeat + 1) if self.simulator.is_simulating else "-"
self.ui.lblCurrentRepeatValue.setText(current_repeat)

Expand Down Expand Up @@ -219,8 +223,7 @@ def emit_editing_finished_signals(self):
self.sniff_settings_widget.emit_editing_finished_signals()

def update_transcript_view(self):
transcript = self.simulator.get_full_transcript(start=0, use_bit=self.ui.radioButtonTranscriptBit.isChecked())
self.ui.textEditTranscript.setText("\n".join(transcript))
self.ui.textEditTranscript.setText("\n".join(self.__get_full_transcript()))

def closeEvent(self, event: QCloseEvent):
self.timer.stop()
Expand Down
35 changes: 10 additions & 25 deletions src/urh/simulator/Simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
from urh.simulator.SimulatorRule import SimulatorRule, SimulatorRuleCondition, ConditionType
from urh.simulator.SimulatorSleepAction import SimulatorSleepAction
from urh.simulator.SimulatorTriggerCommandAction import SimulatorTriggerCommandAction
from urh.simulator.Transcript import Transcript
from urh.util import util, HTMLFormatter
from urh.util.Logger import logger
from urh.util.ProjectManager import ProjectManager


class Simulator(QObject):
TRANSCRIPT_FORMAT = "{0} ({1}->{2}): {3}"

simulation_started = pyqtSignal()
simulation_stopped = pyqtSignal()

Expand All @@ -45,7 +44,7 @@ def __init__(self, simulator_config: SimulatorConfiguration, modulators,
self.modulators = modulators # type: list[Modulator]
self.backend_handler = BackendHandler()

self.transcript = [] # type: list[tuple[Participant, Participant, Message, int]]
self.transcript = Transcript()

self.current_item = None
self.last_sent_message = None
Expand All @@ -68,10 +67,6 @@ def __initialize_counters(self):
if isinstance(item, SimulatorCounterAction):
item.reset_value()

def __add_newline_to_transcript(self):
if len(self.transcript) > 0 and self.transcript[-1] != ("", "", "", ""):
self.transcript.append(("", "", "", ""))

def start(self):
self.reset()

Expand Down Expand Up @@ -134,7 +129,7 @@ def stop(self, msg=""):
self.simulation_stopped.emit()

def restart(self):
self.__add_newline_to_transcript()
self.transcript.start_new_round()
self.reset()
self.log_message("<b>Restarting simulation</b>")

Expand Down Expand Up @@ -255,7 +250,7 @@ def simulate(self):
command = self.__fill_counter_values(self.current_item.command)
self.log_message("Calling {}".format(command))
if self.current_item.pass_transcript:
transcript = "\n".join(self.get_full_transcript())
transcript = "\n".join(self.transcript.get_for_all_participants(all_rounds=False))
result, rc = util.run_command(command, transcript, use_stdin=True, return_rc=True)
else:
result, rc = util.run_command(command, param=None, detailed_output=True, return_rc=True)
Expand Down Expand Up @@ -292,7 +287,7 @@ def simulate(self):
elif self.current_item is None:
self.current_repeat += 1
next_item = self.simulator_config.rootItem
self.__add_newline_to_transcript()
self.transcript.start_new_round()

else:
raise ValueError("Unknown action {}".format(type(self.current_item)))
Expand Down Expand Up @@ -328,7 +323,7 @@ def process_message(self):
new_message.plain_bits[start:end] = checksum + array.array("B", [0] * (
(end - start) - len(checksum)))

self.transcript.append((msg.source, msg.destination, new_message, msg.index()))
self.transcript.append(msg.source, msg.destination, new_message, msg.index())
self.send_message(new_message, msg.repeat, sender, msg.modulator_index)
self.log_message("Sending message " + msg.index())
self.log_message_labels(new_message)
Expand Down Expand Up @@ -373,7 +368,7 @@ def process_message(self):
decoded_msg = Message(received_msg.decoded_bits, 0,
received_msg.message_type, decoder=received_msg.decoder)
msg.send_recv_messages.append(decoded_msg)
self.transcript.append((msg.source, msg.destination, decoded_msg, msg.index()))
self.transcript.append(msg.source, msg.destination, decoded_msg, msg.index())
self.log_message("Received message " + msg.index() + ": ")
self.log_message_labels(decoded_msg)
return
Expand Down Expand Up @@ -483,16 +478,6 @@ def receive_message(self, sniffer):
self.log_message("Receive timeout")
return None

def get_transcript(self, participant: Participant):
result = []
for source, destination, msg, _ in self.transcript:
if participant == destination:
result.append("->" + msg.plain_bits_str)
elif participant == source:
result.append("<-" + msg.plain_bits_str)

return "\n".join(result)

def get_full_transcript(self, start=0, use_bit=True):
result = []
for source, destination, msg, msg_index in self.transcript[start:]:
Expand All @@ -514,9 +499,9 @@ def generate_message_from_template(self, template_msg: SimulatorMessage):
assert valid
result = self.expression_parser.evaluate_node(node)
elif lbl.value_type_index == 3:
transcript = self.get_transcript(template_msg.source
if template_msg.source.simulate
else template_msg.destination)
transcript = self.transcript.get_for_participant(template_msg.source
if template_msg.source.simulate
else template_msg.destination)

if template_msg.destination.simulate:
direction = "->" if template_msg.source.simulate else "<-"
Expand Down
52 changes: 52 additions & 0 deletions src/urh/simulator/Transcript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from urh.signalprocessing.Message import Message
from urh.signalprocessing.Participant import Participant


class Transcript(object):
FORMAT = "{0} ({1}->{2}): {3}"

def __init__(self):
self.__data = []

def append(self, source: Participant, destination: Participant, msg: Message, index: int):
if len(self.__data) == 0:
self.__data.append([])

self.__data[-1].append((source, destination, msg, index))

def start_new_round(self):
if len(self.__data) == 0 or len(self.__data[-1]) > 0:
self.__data.append([])

def clear(self):
self.__data.clear()

def get_for_all_participants(self, all_rounds: bool, use_bit=True) -> list:
result = []
if len(self.__data) == 0:
return result

rng = range(0, len(self.__data)) if all_rounds else range(len(self.__data)-1, len(self.__data))

for i in rng:
for source, destination, msg, msg_index in self.__data[i]:
data = msg.plain_bits_str if use_bit else msg.plain_hex_str
result.append(self.FORMAT.format(msg_index, source.shortname, destination.shortname, data))

if i != len(self.__data) - 1:
result.append("")

return result

def get_for_participant(self, participant: Participant) -> str:
if len(self.__data) == 0:
return ""

result = []
for source, destination, msg, _ in self.__data[-1]:
if participant == destination:
result.append("->" + msg.plain_bits_str)
elif participant == source:
result.append("<-" + msg.plain_bits_str)

return "\n".join(result)
12 changes: 6 additions & 6 deletions src/urh/ui/ui_simulator_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def setupUi(self, DialogSimulator):
self.scrollAreaRX.setWidgetResizable(True)
self.scrollAreaRX.setObjectName("scrollAreaRX")
self.scrollAreaWidgetContentsRX = QtWidgets.QWidget()
self.scrollAreaWidgetContentsRX.setGeometry(QtCore.QRect(0, 0, 178, 62))
self.scrollAreaWidgetContentsRX.setGeometry(QtCore.QRect(0, 0, 1066, 767))
self.scrollAreaWidgetContentsRX.setObjectName("scrollAreaWidgetContentsRX")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContentsRX)
self.verticalLayout_6.setObjectName("verticalLayout_6")
Expand All @@ -76,7 +76,7 @@ def setupUi(self, DialogSimulator):
self.scrollAreaTX.setWidgetResizable(True)
self.scrollAreaTX.setObjectName("scrollAreaTX")
self.scrollAreaWidgetContentsTX = QtWidgets.QWidget()
self.scrollAreaWidgetContentsTX.setGeometry(QtCore.QRect(0, 0, 100, 30))
self.scrollAreaWidgetContentsTX.setGeometry(QtCore.QRect(0, 0, 1066, 767))
self.scrollAreaWidgetContentsTX.setObjectName("scrollAreaWidgetContentsTX")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContentsTX)
self.verticalLayout_8.setObjectName("verticalLayout_8")
Expand Down Expand Up @@ -283,15 +283,15 @@ def retranslateUi(self, DialogSimulator):
self.checkBoxCaptureFullRX.setText(_translate("DialogSimulator", "Capture complete RX"))
self.btnSaveRX.setToolTip(_translate("DialogSimulator", "Save current capture"))
self.btnSaveRX.setText(_translate("DialogSimulator", "Save"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_simulation), _translate("DialogSimulator", "Messages"))
self.textEditTranscript.setPlaceholderText(_translate("DialogSimulator", "You will find the transcript of the simulation here."))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_simulation), _translate("DialogSimulator", "Status"))
self.textEditTranscript.setPlaceholderText(_translate("DialogSimulator", "Here you will find all messages that were sent and received during simulation."))
self.radioButtonTranscriptBit.setText(_translate("DialogSimulator", "Bit &view"))
self.radioButtonTranscriptHex.setText(_translate("DialogSimulator", "Hex view"))
self.btnOpenInAnalysis.setText(_translate("DialogSimulator", "Open in Analysis"))
self.btnSaveTranscript.setText(_translate("DialogSimulator", "..."))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("DialogSimulator", "Transcript"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("DialogSimulator", "Messages"))
self.textEditDevices.setPlaceholderText(_translate("DialogSimulator", "After starting the simulation you will the log messages of your configured SDRs here."))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_device), _translate("DialogSimulator", "SDR Status"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_device), _translate("DialogSimulator", "Devices"))
self.btnStartStop.setText(_translate("DialogSimulator", "Start"))
self.tabWidgetSimulatorSettings.setTabText(self.tabWidgetSimulatorSettings.indexOf(self.tabSimulation), _translate("DialogSimulator", "Simulation"))

Expand Down