예제 #1
0
    def run(self, suites_to_run, pause=False, write_output=True):
        for test_suite in self.test_suites:
            # Skip test suites that we don't want to run
            if suites_to_run != [] and (not test_suite in suites_to_run):
                continue

            print("[+] Testing suite: '%s'" % test_suite)
            summary = TestSummary(suite=test_suite, pause=pause)

            # Get all metadata files associated with the suite
            get_mtime = lambda f: os.stat(os.path.join(self.test_suites_directory, test_suite, f)).st_mtime
            metadata_files = [os.path.join(self.test_suites_directory, test_suite, x) for x in sorted(os.listdir(os.path.join(self.test_suites_directory, test_suite)), key=get_mtime) if x.endswith('.sigmf-meta')]

            # Parse metadata files
            for metadata_file in metadata_files:
                print("[+] %s" % metadata_file)
                data_file = os.path.splitext(metadata_file)[0] + '.sigmf-data'
                # Load sigmf data TODO abstract
                f = open(metadata_file, 'r')
                sigmf = SigMFFile(metadata=f.read())
                if not sigmf.validate():
                    raise Exception("Invalid SigMF format")
                global_meta = sigmf.get_global_info()
                capture_meta = sigmf.get_capture_info(0)
                f.close()

                # Initialize test parameters
                sample_rate = global_meta["core:sample_rate"]

                # Get LoRa configuration
                capture_freq = capture_meta["core:frequency"]
                if "lora:frequency_offset" in capture_meta:
                    frequency_offset = capture_meta["lora:frequency_offset"]
                else:
                    frequency_offset = 0
                transmit_freq = capture_meta["lora:frequency"]
                sf = capture_meta["lora:sf"]
                cr = capture_meta["lora:cr"]
                bw = int(capture_meta["lora:bw"])
                prlen = capture_meta["lora:prlen"]
                crc = capture_meta["lora:crc"]
                implicit = capture_meta["lora:implicit"]
                lora_config = LoRaConfig(transmit_freq, sf, cr, bw, prlen, crc, implicit)

                # Get test case configuration
                payload = capture_meta["test:expected"]
                times = capture_meta["test:times"]
                test = Test(payload, times)

                # Build flowgraph
                tb = gr.top_block()
                file_source = blocks.file_source(gr.sizeof_gr_complex, data_file, False)
                lora_receiver = lora.lora_receiver(sample_rate, capture_freq, [868100000], bw, sf, False, 4, True, reduced_rate=False, decimation=1)
                throttle = blocks.throttle(gr.sizeof_gr_complex, sample_rate, True)
                message_socket_sink = lora.message_socket_sink("127.0.0.1", 40868, 2)
                freq_xlating_fir_filter = filter.freq_xlating_fir_filter_ccc(1, (firdes.low_pass(1, sample_rate, 200000, 100000, firdes.WIN_HAMMING, 6.67)), frequency_offset, sample_rate)

                # Make connections
                tb.connect((file_source, 0), (throttle, 0))
                tb.connect((throttle, 0), (freq_xlating_fir_filter, 0))
                tb.connect((freq_xlating_fir_filter, 0), (lora_receiver, 0))
                tb.msg_connect((lora_receiver, 'frames'), (message_socket_sink, 'in'))
                tb.start()
                tb.wait()

                decoded_data = self.server.get_payloads(times)  # Output from the flowgraph
                summary.add(TestResult(decoded_data=decoded_data, lora_config=lora_config, test=test), print_intermediate=True)
            # Finally, export the result for the suite
            summary.export_summary(path=self.reports_directory, write_output=write_output)
예제 #2
0
    def run(self, suites_to_run, pause=False, write_output=True):
        for test_suite in self.test_suites:
            # Skip test suites that we don't want to run
            if suites_to_run != [] and (not test_suite in suites_to_run):
                continue

            print("[+] Testing suite: '%s'" % test_suite)
            summary = TestSummary(suite=test_suite, pause=pause)

            # Get all metadata files associated with the suite
            get_mtime = lambda f: os.stat(
                os.path.join(self.test_suites_directory, test_suite, f)
            ).st_mtime
            metadata_files = [
                os.path.join(self.test_suites_directory, test_suite, x)
                for x in sorted(os.listdir(
                    os.path.join(self.test_suites_directory, test_suite)),
                                key=get_mtime) if x.endswith('.sigmf-meta')
            ]

            # Parse metadata files
            for metadata_file in metadata_files:
                print("[+] %s" % metadata_file)
                data_file = os.path.splitext(metadata_file)[0] + '.sigmf-data'
                # Load sigmf data TODO abstract
                f = open(metadata_file, 'r')
                sigmf = SigMFFile(metadata=f.read())
                if not sigmf.validate():
                    raise Exception("Invalid SigMF format")
                global_meta = sigmf.get_global_info()
                capture_meta = sigmf.get_capture_info(0)
                f.close()

                # Initialize test parameters
                sample_rate = global_meta["core:sample_rate"]

                # Get LoRa configuration
                capture_freq = capture_meta["core:frequency"]
                if "lora:frequency_offset" in capture_meta:
                    frequency_offset = capture_meta["lora:frequency_offset"]
                else:
                    frequency_offset = 0
                transmit_freq = capture_meta["lora:frequency"]
                sf = capture_meta["lora:sf"]
                cr = capture_meta["lora:cr"]
                bw = int(capture_meta["lora:bw"])
                prlen = capture_meta["lora:prlen"]
                crc = capture_meta["lora:crc"]
                implicit = capture_meta["lora:implicit"]
                lora_config = LoRaConfig(transmit_freq, sf, cr, bw, prlen, crc,
                                         implicit)

                # Get test case configuration
                payload = capture_meta["test:expected"]
                times = capture_meta["test:times"]
                test = Test(payload, times)

                # Build flowgraph
                tb = gr.top_block()
                file_source = blocks.file_source(gr.sizeof_gr_complex,
                                                 data_file, False)
                lora_receiver = lora.lora_receiver(sample_rate,
                                                   capture_freq, [868100000],
                                                   bw,
                                                   sf,
                                                   False,
                                                   4,
                                                   True,
                                                   reduced_rate=False,
                                                   decimation=1)
                throttle = blocks.throttle(gr.sizeof_gr_complex, sample_rate,
                                           True)
                message_socket_sink = lora.message_socket_sink(
                    "127.0.0.1", 40868, 2)
                freq_xlating_fir_filter = filter.freq_xlating_fir_filter_ccc(
                    1, (firdes.low_pass(1, sample_rate, 200000, 100000,
                                        firdes.WIN_HAMMING, 6.67)),
                    frequency_offset, sample_rate)

                # Make connections
                tb.connect((file_source, 0), (throttle, 0))
                tb.connect((throttle, 0), (freq_xlating_fir_filter, 0))
                tb.connect((freq_xlating_fir_filter, 0), (lora_receiver, 0))
                tb.msg_connect((lora_receiver, 'frames'),
                               (message_socket_sink, 'in'))
                tb.start()
                tb.wait()

                decoded_data = self.server.get_payloads(
                    times)  # Output from the flowgraph
                summary.add(TestResult(decoded_data=decoded_data,
                                       lora_config=lora_config,
                                       test=test),
                            print_intermediate=True)
            # Finally, export the result for the suite
            summary.export_summary(path=self.reports_directory,
                                   write_output=write_output)
예제 #3
0
def run_gui():
    window_input = WindowInput()
    capture_data_input = CaptureData()
    capture_text_blocks = dict()
    window_text_blocks = dict()
    f = SigMFFile()
    capture_selector_dict = dict()

    layout = [
        [
            Text('This is the APL SIGMF tool to archive RF datasets',
                 size=(80, 1))
        ],
        [
            Text('Enter your data and signal captures below. You must include',
                 auto_size_text=True),
            Text('required',
                 text_color='red',
                 font=DEFAULT_FONT + ('italic', ),
                 auto_size_text=True),
            Text('fields.', size=(50, 1), auto_size_text=True)
        ], [Text('_' * 150, auto_size_text=True)]
    ]

    layout.append([Text('Global Data', font=('Arial', 12, 'bold'))])
    num_components = 0
    line = []
    for el in window_input.iter_core():
        size = (30, 1) if len(line) == 0 else (None, None)
        auto_size = True if len(line) == 0 else (10, 1)
        line.extend([
            Text(el,
                 justification='right',
                 size=size,
                 text_color='red' if el in window_input.req_tags else None,
                 auto_size_text=auto_size)
        ])
        if el in window_input.el_multiline:
            window_text_blocks.update({
                el:
                Multiline(window_input.el_text.get(el, ''),
                          key=el,
                          tooltip=window_input.el_tooltips.get(el, None),
                          size=(30, 2))
            })
        elif el in window_input.el_selector:
            window_text_blocks.update({
                el:
                Combo(values=window_input.el_selector[el],
                      key=el,
                      size=window_input.el_size.get(el, (None, None)))
            })
        elif el in window_input.el_checkbox:
            window_text_blocks.update({
                el:
                Checkbox(window_input.el_text.get(el, ''),
                         key=el,
                         size=window_input.el_size.get(el, (None, None)))
            })
        else:
            window_text_blocks.update({
                el:
                InputText(window_input.el_text.get(el, ''),
                          key=el,
                          tooltip=window_input.el_tooltips.get(el, None))
            })
        line.append(window_text_blocks[el])

        if el in window_input.el_units:
            line.append(Text(window_input.el_units[el]))

        num_components += 1
        if num_components < window_input.first_line_size:
            continue
        layout.append(line)
        line = []

    for el1, el2 in window_input.iter_x_secondary(2):
        line = []
        for el, size in zip([el1, el2], [30, 22]):
            if el is None:
                continue
            color = 'red' if el in window_input.req_tags else None
            window_text_blocks.update({
                el:
                InputText(window_input.el_text.get(el, ''),
                          key=el,
                          tooltip=window_input.el_tooltips.get(el, None))
            })
            line.extend([
                Text(el,
                     justification='right',
                     size=(size, 1),
                     text_color=color), window_text_blocks[el]
            ])
            if el in window_input.el_units:
                line.append(Text(window_input.el_units[el], size=(5, 1)))
            else:
                line.append(Text('', size=(5, 1)))
        layout.append(line)

    layout.extend(
        [[Text('_' * 150, auto_size_text=True)],
         [Text('Individual Capture Data', font=('Arial', 12, 'bold'))],
         [
             Text('Capture Selector', auto_size_text=True), combo_button,
             Text('', size=(10, 1)),
             Button('Add Capture', enable_events=True),
             Button('Remove Capture', enable_events=True, size=(15, 1)),
             Button('Clear Capture', enable_events=True, size=(15, 1))
         ]])

    for el1, el2, el3 in capture_data_input.iter_x(3):
        line = []
        for el in [el1, el2, el3]:
            if el is None:
                continue
            capture_text_blocks.update({
                el:
                InputText(key=el,
                          tooltip=capture_data_input.el_tooltips.get(el, None))
            })
            color = 'red' if el in capture_data_input.req_tags else None
            line.extend([
                Text(el, justification='right', size=(20, 1),
                     text_color=color), capture_text_blocks[el]
            ])
            if el in capture_data_input.el_units:
                line.append(Text(capture_data_input.el_units[el], size=(5, 1)))
            else:
                line.append(Text('', size=(5, 1)))
        layout.append(line)

    window_text_blocks.update(
        {WindowInput.DATA_FILE: InputText('', key=WindowInput.DATA_FILE)})
    layout.extend([[Text('_' * 150, auto_size_text=True)],
                   [Text('Data Location', font=('Arial', 12, 'bold'))],
                   [
                       Text(WindowInput.DATA_FILE,
                            size=(30, 1),
                            justification='right',
                            text_color='red'),
                       window_text_blocks[WindowInput.DATA_FILE],
                       FileBrowse()
                   ],
                   [
                       Text(WindowInput.OUTPUT_FOLDER,
                            size=(30, 1),
                            justification='right'),
                       InputText('', key=WindowInput.OUTPUT_FOLDER),
                       FolderBrowse(), submit_button
                   ],
                   [
                       Text(WindowInput.LOAD_PATH,
                            size=(30, 1),
                            justification='right'),
                       InputText('', key=WindowInput.LOAD_PATH),
                       FileBrowse(file_types=(("Archive Files", "*.sigmf"), )),
                       load_button
                   ], [validate_button, Button('View Data')]])

    window = Window('APL SigMF Archive Creator',
                    auto_size_buttons=False,
                    default_element_size=(20, 1),
                    auto_size_text=False,
                    default_button_element_size=(10, 1)).Layout(layout)

    while True:
        validate_button.Update(text='Update')
        load_button.Update(text='Load')
        submit_button.Update(text='Save Archive')

        window.Refresh()
        event, values = window.Read()
        print(event, values)
        if event == 'Load Archive':
            load_path = values[WindowInput.LOAD_PATH]
            if load_path == '':
                show_error('No archive file provided')
                continue

            load_button.Update(text='Loading...')
            window.Refresh()
            print('reading from ', values[WindowInput.LOAD_PATH])
            f = fromarchive(values[WindowInput.LOAD_PATH])
            update_global_screen(window_input, window_text_blocks,
                                 f.get_global_info(), f)
            capture_selector_dict = {}
            for capture in f.get_captures():
                add_capture(capture_data_input,
                            capture,
                            capture_selector_dict,
                            f,
                            from_archive=True)

        elif event == 'Data Type Help':
            PopupOK(
                'Format: <TypeCharacters><ElementBitSize>_<Endianness>\n\n'
                '\tTypeCharacters:\n'
                '\t\tUnsigned data: \"u\"\n'
                '\t\tComplex data: \"c\"\n'
                '\t\tFixedpoint data: \"f\"\n'
                '\tElementBitSize:\n'
                '\t\t32 bits, 16 bits, or 8 bits\n'
                '\tEndianness:\n'
                '\t\tl: Little Endian\n'
                '\t\tb: Big Endian\n\n\n\n'
                'Example: \"uc32_l\"\n'
                'Unsigned complex data where each element is 32 bits, or 64 bits total, formatted in little endian.',
                title='Data Type Help')
        elif event == 'Update':
            validate_button.Update(text='Validating...')
            window.Refresh()
            window_data_type_dict = {}
            added = True
            for el in window_input.iter():
                req_field = True if el in window_input.req_tags else False
                el_type = window_input.el_types.get(el, None)
                el_unit = window_input.el_units.get(el, None)
                if el in window_input.partial_component_list:
                    added = added and add_sigmf_field(update_dictionary,
                                                      values,
                                                      el,
                                                      window_data_type_dict,
                                                      window_input.get_tag(el),
                                                      required=req_field,
                                                      type=el_type,
                                                      unit=el_unit)
                else:
                    added = added and add_sigmf_field(
                        SigMFFile.set_global_field,
                        values,
                        el,
                        f,
                        window_input.get_tag(el),
                        required=req_field,
                        type=el_type,
                        unit=el_unit)

            data_type_str = ''
            data_type_str += 'c' if bool(
                window_data_type_dict[WindowInput.DATA_TYPE_COMPLEX]) else ''
            data_type_str += 'f' if not bool(window_data_type_dict[
                WindowInput.DATA_TYPE_FIXEDPOINT]) else ''
            data_type_str += 'u' if bool(
                window_data_type_dict[WindowInput.DATA_TYPE_UNSIGNED]) else ''
            data_type_str += str(
                window_data_type_dict[WindowInput.DATA_SAMPLE_SIZE]) + '_'
            data_type_str += 'l' if window_data_type_dict[
                WindowInput.DATA_BYTE_ORDER] == 'little endian' else 'b'
            data_type_dict = {SigMFFile.DATATYPE_KEY: data_type_str}
            added = added and add_sigmf_field(SigMFFile.set_global_field,
                                              data_type_dict,
                                              SigMFFile.DATATYPE_KEY,
                                              f,
                                              SigMFFile.DATATYPE_KEY,
                                              required=True)
            print('HERE: ', window_data_type_dict)
            added = added and add_sigmf_field(SigMFFile.set_data_file,
                                              values,
                                              WindowInput.DATA_FILE,
                                              f,
                                              required=True) and added
            if not added:
                # requirement not given
                continue

            if validate_data(f):
                submit_button.Update(disabled=False,
                                     button_color=DEFAULT_BUTTON_COLOR)
        elif event == 'Capture Combo':
            capture_dict = capture_selector_dict[values['Capture Combo']]
            update_capture_screen(capture_data_input, capture_text_blocks,
                                  capture_dict)
        elif event == 'Add Capture':
            add_capture(capture_data_input, values, capture_selector_dict, f)

        elif event == 'Remove Capture':
            capture_dict = dict()
            added = add_sigmf_field(update_dictionary,
                                    values,
                                    CaptureData.START_INDEX,
                                    capture_dict,
                                    SigMFFile.START_INDEX_KEY,
                                    required=True,
                                    type=int)
            if not added:
                # requirement not given
                continue

            captures = []
            for capture in f._metadata[SigMFFile.CAPTURE_KEY]:
                if capture[SigMFFile.START_INDEX_KEY] != capture_dict[
                        SigMFFile.START_INDEX_KEY]:
                    captures.append(capture)
            f._metadata[SigMFFile.CAPTURE_KEY] = captures

            annotations = []
            for annotation in f._metadata[SigMFFile.ANNOTATION_KEY]:
                if annotation[SigMFFile.START_INDEX_KEY] != capture_dict[
                        SigMFFile.START_INDEX_KEY]:
                    annotations.append(annotation)
            f._metadata[SigMFFile.ANNOTATION_KEY] = annotations

            new_values = list(combo_button.Values)
            rm_val = 'Capture {}'.format(
                capture_dict[SigMFFile.START_INDEX_KEY])
            if rm_val in capture_selector_dict:
                capture_selector_dict.pop(rm_val)
            if rm_val in new_values:
                new_values.remove(rm_val)
                combo_button.Update(values=new_values, set_to_index=0)
                capture_dict = capture_selector_dict.get(
                    combo_button.DefaultValue, None)
                update_capture_screen(capture_data_input, capture_text_blocks,
                                      capture_dict)
        elif event == 'Clear Capture':
            update_capture_screen(capture_data_input, capture_text_blocks,
                                  None)
        elif event == 'View Data':
            PopupOK('Current data:\n', f.dumps(pretty=True), title='')
        elif event == 'Save Archive':
            output_folder = values[WindowInput.OUTPUT_FOLDER]
            if output_folder == '':
                show_error('No output folder provided')
                continue
            elif len(capture_selector_dict.keys()) == 0:
                show_error('No capture data specified')
            submit_button.Update(text='Saving...')
            window.Refresh()
            archive_file = output_folder + '/' + os.path.basename(
                f.data_file).split('.')[0] + SIGMF_ARCHIVE_EXT
            f.archive(archive_file)
            PopupOK('Saved archive as \n', archive_file, title='')
        elif event in ['Cancel', None, 'Exit']:
            window.Close()
            break

    window.Close()