예제 #1
0
    def test_mult_types_gui_queue_receiver(self):
        nc = setup()

        # construct inner request
        startRequest = control_signals_pb2.StartRequest()
        startRequest.port = 0
        startRequest.channels = 0xDEADBEEF

        # construct request wrapper containing inner
        requestWrapper1 = control_signals_pb2.RequestWrapper()
        requestWrapper1.sequence = 1
        requestWrapper1.start.MergeFrom(startRequest)  # can't assign directly for some reason, need to merge

        serialized1 = requestWrapper1.SerializeToString()

        # construct inner request
        stopRequest = control_signals_pb2.StopRequest()
        stopRequest.port = 0
        stopRequest.channels = 0xDEADBEEF

        # construct request wrapper containing inner
        requestWrapper2 = control_signals_pb2.RequestWrapper()
        requestWrapper2.sequence = 2
        requestWrapper2.stop.MergeFrom(stopRequest)  # can't assign directly for some reason, need to merge

        serialized2 = requestWrapper2.SerializeToString()

        # pass the serialized message wrappers to the network controller
        # "from" the GUI
        from_gui_queue.put(serialized1)
        from_gui_queue.put(serialized2)

        time.sleep(0.5) # wait for nc to read from queue
        assert from_gui_queue.empty()
예제 #2
0
    def handle_read(self):
        # read 16 bit length header
        size = bytearray(2)
        try:
            self.recv_into(size)
        except socket.error as serr:
            logging.error('ControlClient: failed to connect, error is %s',
                          serr)
            self.connected = False
            self.handle_close()
            return

        length = (size[1] << 8) + size[0]
        print length
        logging.debug('ControlClient: received length header: %s', length)

        # read the message content
        msg = self.recv(length)
        logging.debug('ControlClient: received message: %s', msg)

        # TODO: (probably not necessary) put onto incoming_queue and have another thread handle the parsing

        # construct a container protobuf and parse into from serialized message
        ackWrapper = control_signals_pb2.RequestWrapper()
        ackWrapper.ParseFromString(msg)

        sequence = ackWrapper.sequence

        if sequence in self.sent_dict.keys():
            serialized_acked_request = self.sent_dict.pop(sequence)
            logging.debug('ControlClient: ACKed request popped %s',
                          serialized_acked_request)
            self.control_protobuf_conn.send(msg)
            self.ack_msg_from_cc_event.set()
예제 #3
0
    def handle_write(self):
        # notify NetworkController that we are connected
        self.connected_event.set()

        # grab request to be sent from the incoming connection
        serialized_req_wrap = self.control_protobuf_conn.recv()
        logging.debug(
            'ControlClient: handle_write() retrieved msg from outgoing queue')

        # parse the request for storage in sent_dict
        request_wrapper = control_signals_pb2.RequestWrapper()
        request_wrapper.ParseFromString(serialized_req_wrap)

        length = np.uint16(len(serialized_req_wrap))
        logging.debug(
            'ControlClient: sending message length %d over control socket',
            length)
        self.send(length)

        logging.debug(
            'ControlClient: sending Request message over control socket')
        sent = self.send(serialized_req_wrap)
        logging.debug('ControlClient: sent message bytes: %d', sent)

        logging.debug('ControlClient: adding request %d to sent_dict',
                      request_wrapper.sequence)
        if request_wrapper.sequence not in self.sent_dict.keys():
            self.sent_dict[request_wrapper.sequence] = serialized_req_wrap
        else:
            raise RuntimeWarning(
                'ControlClient: requestWrapper with sequence %d already in sent_dict'
                % request_wrapper.sequence)
예제 #4
0
    def test_gui_queue_receiver(self):
        nc = setup()

        startRequest = control_signals_pb2.StartRequest()
        startRequest.port = 1
        startRequest.channels = 0xDEADBEEF

        requestWrapper = control_signals_pb2.RequestWrapper()
        requestWrapper.sequence = 1
        requestWrapper.start.MergeFrom(startRequest) # can't assign directly for some reason, need to merge

        from_gui_queue.put(requestWrapper.SerializeToString())

        time.sleep(0.5) # wait for nc to read from queue
        assert from_gui_queue.empty()
예제 #5
0
def recv_request_wrapper(control_conn):
    # synchronously read in the msg length header
    length = ''
    while length == '':
        length = control_conn.recv(2)
        print length
    print 'ControlServer: received length header: %s' % length

    # read in the message content
    msg = control_conn.recv(int(length))

    # construct a reply container and parse from the received message
    requestWrapper = control_signals_pb2.RequestWrapper()
    requestWrapper.ParseFromString(msg)
    print 'ControlServer: received request message:\n%s' % requestWrapper

    return requestWrapper
예제 #6
0
    def test_control_socket_send_request(self):
        nc = setup()

        # Simulate message from GUI
        # first construct the inner request
        startRequest = control_signals_pb2.StartRequest()
        startRequest.port = 1
        startRequest.channels = 0xDEADBEEF

        # then insert it into a request wrapper
        requestWrapper = control_signals_pb2.RequestWrapper()
        requestWrapper.sequence = 1
        requestWrapper.start.MergeFrom(startRequest)

        # finally, serialize to send across boundary
        serialized = requestWrapper.SerializeToString()

        # setup a server socket to listen for control client connection
        server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_sock.bind(('localhost', 10001))
        server_sock.listen(1)
        print 'listening on %s:%d' % ('localhost', 10001)

        # tell the network controller to attempt a connection to the server socket
        nc.connect_control_port()

        conn, addr = server_sock.accept()
        print 'accepted connection from %s:%d' % (addr[0], addr[1])

        # load request into queue to be sent over control socket by ControlClient
        from_gui_queue.put(serialized)

        received = recv_request_wrapper(conn)

        startMessage = control_signals_pb2.StartRequest()
        startMessage.MergeFrom(received.start)

        # check that we received a StartRequest back and it has the same fields
        assert received.HasField('start')
        assert startMessage.port == 1
        assert startMessage.channels == 0xDEADBEEF

        nc.close_control_port()
        server_sock.close()
        conn.close()
예제 #7
0
global to_gui_queue
global gui_data_queue

stg_queue = mp.Queue()
from_gui_queue = mp.Queue()
to_gui_queue = mp.Queue()
gui_data_queue = mp.Queue()
nc = NetworkController(stg_queue, from_gui_queue, to_gui_queue, gui_data_queue)

# construct the initial start streaming request
startRequest = control_signals_pb2.StartRequest()
startRequest.port = 10002
startRequest.channels = 0xFFFFFFFF
startRequest.rate = 200000

# then insert it into a request wrapper
requestWrapper = control_signals_pb2.RequestWrapper()
requestWrapper.sequence = 1
requestWrapper.start.MergeFrom(startRequest)

# finally, serialize to send across boundary
serialized = requestWrapper.SerializeToString()

# tell the network controller to attempt a connection to the control server
nc.connect_control_port()

# load request into queue to be sent over control socket by ControlClient
from_gui_queue.put(serialized)

time.sleep(1)
assert nc.data_client.connected
예제 #8
0
    def read_ack_messages(self):
        while not self.stop_event.is_set():
            if self.nc_control_conn.poll():
                ack = self.nc_control_conn.recv()
                ack_wrapper = control_signals_pb2.RequestWrapper()
                ack_wrapper.ParseFromString(ack)
                logging.info('NetworkController: received ACK message %s',
                             ack_wrapper)

                if ack_wrapper.sequence in self.sent_dict.keys():
                    msg = self.sent_dict.pop(ack_wrapper.sequence)
                else:
                    msg = {}
                    raise RuntimeWarning(
                        'NetworkController: received unexpected ACK from ControlClient'
                    )

                if ack_wrapper.HasField(
                        'start') and not self.data_client.connected:
                    logging.info(
                        'NetworkController: received start ACK, starting data client'
                    )
                    start_request = control_signals_pb2.StartRequest()
                    start_request.MergeFrom(ack_wrapper.start)
                    # make sure that we're getting the channels we expect
                    if start_request.channels != msg['channels']:
                        raise RuntimeWarning(
                            'NetworkController: active channels in ACK differ from requested'
                        )

                    # send header info to SC and notify
                    active_channels = self.get_channels_from_bitmask(
                        start_request.channels)
                    bytes_per_sample = (len(active_channels) + 4) * 2
                    chunk_size = min(
                        113, int(msg['rate'] * bytes_per_sample * 0.00001))
                    print 'received timestamp %d' % start_request.timestamp
                    header = (start_request.timestamp, start_request.channels,
                              chunk_size, start_request.rate)
                    self.file_header_sender.send(header)
                    self.file_header_available_event.set()

                    data_connect_success, data_serr = self.connect_data_port(
                        self.host, start_request.port, chunk_size,
                        active_channels)

                    logging.debug(
                        'NetworkController: data_connect_success = %s',
                        data_connect_success)

                    if data_connect_success:
                        # construct a success reply message
                        reply_msg = msg
                        reply_msg['success'] = True
                        reply_msg[
                            'message'] = 'Successfully connected control and data ports to host %s' % self.host
                        reply_msg['timestamp'] = start_request.timestamp
                        reply_msg['chunk'] = chunk_size

                        # send an ACK message to GUI and notify its receiver
                        self.gui_control_conn.send(reply_msg)
                        self.control_msg_from_nc_event.set()

                    else:
                        # construct a failure reply message
                        reply_msg = msg
                        reply_msg['success'] = False
                        reply_msg['message'] = 'Failed to connect DataClient to %s:%d, error is %s' % \
                                               (self.host, start_request.port, data_serr)

                        self.gui_control_conn.send(reply_msg)
                        self.control_msg_from_nc_event.set()

                elif ack_wrapper.HasField(
                        'stop') and self.data_client.connected:
                    data_port_disconnected = self.close_data_port()
                    self.close_control_port()
                    control_port_disconnected = self.control_client_disconnected_event.wait(
                        timeout=5.0)

                    if data_port_disconnected and control_port_disconnected:
                        reply_msg = msg
                        reply_msg['success'] = True
                        reply_msg[
                            'message'] = 'Control and Data clients disconnected successfully'
                        self.gui_control_conn.send(reply_msg)
                        self.control_msg_from_nc_event.set()
                    else:
                        reply_msg = msg
                        reply_msg['success'] = False
                        reply_msg[
                            'message'] = 'Unable to disconnect properly or control client disconnect timed out'
                        self.gui_control_conn.send(reply_msg)
                        self.control_msg_from_nc_event.set()

                else:
                    logging.warning(
                        'NetworkController: received an unexpected ACK type %s',
                        ack_wrapper)

            else:
                while not self.stop_event.is_set():
                    if self.ack_msg_from_cc_event.wait(1.0):
                        self.ack_msg_from_cc_event.clear()
                        break
예제 #9
0
    def recv_from_gui(self):
        while not self.stop_event.is_set():
            if self.gui_control_conn.poll():
                msg = self.gui_control_conn.recv()
                logging.info(
                    'NetworkController: received control message: \n%s', msg)

                if msg['type'] == 'CONNECT':
                    # TODO: input validation
                    self.host = msg['host']
                    self.port = msg['port']

                    success, serr = self.connect_control_port(
                        self.host, self.port)

                    if not success:
                        # ControlClient connect failed, notify GUI
                        reply_msg = msg
                        reply_msg['success'] = False
                        reply_msg['message'] = 'Failed to connect ControlClient to %s:%d, error is %s' % \
                                               (self.host, self.port, serr)
                        self.gui_control_conn.send(reply_msg)
                        self.control_msg_from_nc_event.set()
                    else:
                        # construct a StartRequest protobuf message
                        startRequest = control_signals_pb2.StartRequest()
                        startRequest.port = self.port + 1
                        startRequest.channels = msg['channels']
                        startRequest.rate = msg['rate']

                        # wrap it up and copy sequence number
                        requestWrapper = control_signals_pb2.RequestWrapper()
                        requestWrapper.sequence = msg['seq']
                        requestWrapper.start.MergeFrom(startRequest)

                        # serialize wrapper for sending over Pipe
                        serialized = requestWrapper.SerializeToString()
                        self.nc_control_conn.send(serialized)
                        logging.debug(
                            'NetworkController: sent serialized requestWrapper to CC'
                        )
                        # ControlClient uses asyncore so we don't need to notify it

                        if msg['seq'] not in self.sent_dict.keys():
                            self.sent_dict[msg['seq']] = msg
                        else:
                            raise RuntimeWarning(
                                'NetworkController: control msg with sequence %d already in sent_dict'
                                % msg['seq'])

                        # asyncore client doesn't connect until it tries to recv/send,
                        # so we need to be notified asynchronously
                        control_client_connected = self.control_client_connected_event.wait(
                            timeout=5.0)

                        if not control_client_connected:
                            # ControlClient connect timed out, notify GUI
                            reply_msg = msg
                            reply_msg['success'] = False
                            reply_msg['message'] = 'Timed out while trying to connect ControlClient to %s:%d' % \
                                                   (self.host, self.port)
                            self.gui_control_conn.send(reply_msg)
                            self.control_msg_from_nc_event.set()

                elif msg['type'] == 'DISCONNECT':
                    # construct a StopRequest protobuf message
                    stopRequest = control_signals_pb2.StopRequest()
                    stopRequest.port = self.port + 1
                    stopRequest.channels = 0xffff

                    # wrap it up and copy sequence number
                    requestWrapper = control_signals_pb2.RequestWrapper()
                    requestWrapper.sequence = msg['seq']
                    requestWrapper.stop.MergeFrom(stopRequest)

                    # serialize wrapper for sending over Pipe
                    serialized = requestWrapper.SerializeToString()
                    self.nc_control_conn.send(serialized)
                    logging.debug(
                        'NetworkController: sent serialized requestWrapper to CC'
                    )
                    # ControlClient uses asyncore so we don't need to notify it

                    if msg['seq'] not in self.sent_dict.keys():
                        self.sent_dict[msg['seq']] = msg
                    else:
                        raise RuntimeWarning(
                            'NetworkController: control msg with sequence %d already in sent_dict'
                            % msg['seq'])

            else:
                while not self.stop_event.is_set():
                    if self.control_msg_from_gui_event.wait(1.0):
                        self.control_msg_from_gui_event.clear()
                        break
예제 #10
0
    def test_connection(self):
        print 'Starting Data:test_connection()'
        nc = setup()

        # construct the initial start streaming request
        startRequest = control_signals_pb2.StartRequest()
        startRequest.port = 10002
        startRequest.channels = 0xFFFFFFFF

        # then insert it into a request wrapper
        requestWrapper = control_signals_pb2.RequestWrapper()
        requestWrapper.sequence = 1
        requestWrapper.start.MergeFrom(startRequest)

        # finally, serialize to send across boundary
        serialized = requestWrapper.SerializeToString()

        # setup a server socket to listen for control client connection
        server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_sock.bind(('localhost', 10001))
        server_sock.listen(1)
        print 'ControlServer: listening on %s:%d' % ('localhost', 10001)

        # setup a server socket to listen for data client connection
        sender_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sender_sock.bind(('localhost', 10002))
        sender_sock.listen(1)
        print 'DataServer: listening on %s:%d' % ('localhost', 10002)

        # tell the network controller to attempt a connection to the control server
        nc.connect_control_port()

        control_conn, addr = server_sock.accept()
        print 'ControlServer: accepted connection from %s:%d' % (addr[0], addr[1])

        # load request into queue to be sent over control socket by ControlClient
        from_gui_queue.put(serialized)

        received = recv_request_wrapper(control_conn)

        inner_request = control_signals_pb2.StartRequest()
        inner_request.MergeFrom(received.start)

        assert inner_request.port == 10002

        # construct a reply ACK and send over control connection
        serialized_ack = received.SerializeToString()
        length = sys.getsizeof(serialized_ack)
        control_conn.send(str(length))
        control_conn.send(serialized_ack)

        data_conn, data_addr = sender_sock.accept()
        print 'DataServer: accepted connection from %s:%d' % (data_addr[0], data_addr[1])

        assert data_conn.send('ayy')

        # cleanup and close all connections
        nc.close_control_port()
        sender_sock.close()
        data_conn.close()
        server_sock.close()
        control_conn.close()