Exemplo n.º 1
0
    def main(self):
        devices = eval(self.config.get("settings", "devices"))
        self.add_outgoing_paths(self.config.get("settings", "id"), devices)

        try:
            acceptnet = eval(self.config.get("settings", "acceptnet"))
            netport = int(self.config.get("settings", "netport"))
            gpsport = int(self.config.get("settings", "gpsport"))
            idfreq = self.config.get("settings", "idfreq")
            if idfreq == "Never":
                idfreq = 0
            else:
                idfreq = int(idfreq)
        except Exception as e:
            printlog("Repeater  : Failed to parse network info: %s" % e)
            acceptnet = False

        if acceptnet:
            self.repeater.socket = self.repeater.listen_on(netport)
            self.repeater.gps_socket = self.repeater.listen_on(gpsport)

        self.repeater.repeat()

        while True:
            try:
                time.sleep(0.25)
            except KeyboardInterrupt:
                self.repeater.stop()
                break
Exemplo n.º 2
0
 def handler(frame):
     self.condition.acquire()
     try:
         self.__repeat(transport, frame)
     except Exception as e:
         printlog("Repeater  : Exception during __repeat: %s" % e)
     self.condition.release()
Exemplo n.º 3
0
 def load_devices(self):
     try:
         l = eval(self.config.get("settings", "devices"))
         for d, r in l:
             self.dev_list.add_item(d, r)
     except Exception as e:
         printlog(("Unable to load devices: %s" % e))
Exemplo n.º 4
0
    def __init__(self):
        RepeaterUI.__init__(self)

        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_default_size(450, 380)
        self.window.connect("delete_event", self.ev_delete)
        self.window.connect("destroy", self.sig_destroy)
        self.window.set_title("D-RATS Repeater Proxy")

        vbox = gtk.VBox(False, 5)

        self.tabs = gtk.Notebook()
        self.tabs.append_page(self.make_settings(), gtk.Label("Settings"))
        # FIXME: later
        # self.tabs.append_page(self.make_monitor(), gtk.Label("Monitor"))
        self.tabs.show()

        vbox.pack_start(self.tabs, 1, 1, 1)
        vbox.pack_start(self.make_bottom_buttons(), 0, 0, 0)
        vbox.show()

        self.window.add(vbox)
        self.window.show()

        #gobject.timeout_add(1000, self.update)

        try:
            if self.config.get("settings", "state") == "True":
                self.button_on(None, None)
        except Exception as e:
            printlog(e)
Exemplo n.º 5
0
 def __send_job(self, job, id):
     printlog(
         "RPC", "       : Sending job `%s' to %s" %
         (job.get_desc(), job.get_dest()))
     frame = self.__job_to_frame(job, id)
     job.frame = frame
     self._sm.outgoing(self, frame)
     printlog("RPC", "       : Job sent")
Exemplo n.º 6
0
    def write_raw(self, data):
        f = DDT2RawData()
        f.data = data
        f.type = self.T_DEF

        printlog("Chat","      : Sending raw: %s" % data)

        self._sm.outgoing(self, f)
Exemplo n.º 7
0
    def __job_state(self, job, state, _result, id):
        printlog("RPC","       : Job state: %s for %i: %s" % (state, id, _result))

        if state == "running":
            return

        result = encode_dict(_result)
        f = self.__send_job_status(id, job.get_dest(), state, result)
        self._sm.outgoing(self, f)
Exemplo n.º 8
0
 def ping_station(self, station):
     f = DDT2EncodedFrame()
     f.d_station = station
     f.type = self.T_PNG_REQ
     f.data = "Ping Request"
     f.set_compress(False)
     self._sm.outgoing(self, f)
     printlog("Chat","      : pinging %s" % f.d_station)
     self._emit("ping-request", f.s_station, f.d_station, "Request")
Exemplo n.º 9
0
    def _repeat(self):
        while self.enabled:
            self.condition.acquire()
            self.accept_new()
            self.accept_new_gps()
            self.condition.release()

            time.sleep(0.5)

        printlog("Repeater  : Repeater thread ended")
Exemplo n.º 10
0
    def __worker(self):
        for id, (ts, att, job) in self.__jobs.items():
            if job.frame and not job.frame.sent_event.isSet():
                # Reset timer until the block is sent
                self.__jobs[id] = (time.time(), att, job)
            elif (time.time() - ts) > self.__t_retry:
                printlog("RPC","       : Cancelling job %i due to timeout" % id)
                del self.__jobs[id]
                job.set_state("timeout")

        return True
Exemplo n.º 11
0
    def accept_new_gps(self):
        if not self.gps_socket:
            return

        try:
            (csocket, addr) = self.gps_socket.accept()
        except:
            return

        printlog("Repeater  : Accepted new GPS client %s:%i" % addr)
        self.gps_sockets.append(csocket)
Exemplo n.º 12
0
    def RPC_get_version(self, job):
        result = {}

        result["version"] = DRATS_VERSION
        result["os"] = self.__config.platform.os_version_string()
        result["pyver"] = ".".join([str(x) for x in sys.version_info[:3]])
        try:
            import gtk
            result["pygtkver"] = ".".join([str(x) for x in gtk.pygtk_version])
            result["gtkver"] = ".".join([str(x) for x in gtk.gtk_version])
        except ImportError:
            result["pygtkver"] = result["gtkver"] = "Unknown"
            printlog("RPC", "       : RPC_get_version: %s" % result)

        return result
Exemplo n.º 13
0
    def auth_exchange(self, pipe):
        username = password = None
        count = 0

        def readline(_s):
            data = ""
            while "\r\n" not in data:
                try:
                    _d = _s.read(32)
                except socket.timeout:
                    continue

                if _d == "":
                    break

                data += _d
            return data.strip()

        while (not username or not password) and count < 3:
            line = readline(pipe)
            if not line:
                continue
            try:
                cmd, value = line.split(" ", 1)
            except Exception as e:
                printlog("Repeater  : Unable to read auth command: `%s': %s" %
                         (line, e))

                pipe.write("501 Invalid Syntax\r\n")
                break

            cmd = cmd.upper()

            if cmd == "USER" and not username and not password:
                username = value
            elif cmd == "PASS" and username and not password:
                password = value
            else:
                pipe.write("201 Protocol violation\r\n")
                break

            if username and not password:
                pipe.write("102 %s okay\r\n" % cmd)

        if not username or not password:
            printlog("Repeater  : Negotiation failed with client")

        return username, password
Exemplo n.º 14
0
    def accept_new(self):
        if not self.socket:
            return

        try:
            (csocket, addr) = self.socket.accept()
        except:
            return

        printlog("Repeater  : Accepted new client %s:%i" % addr)

        path = comm.SocketDataPath(csocket)
        tport = transport.Transporter(path,
                                      authfn=self.auth_user,
                                      warmup_timeout=0)
        self.add_new_transport(tport)
Exemplo n.º 15
0
def handle_exception(exctyp, value, tb):

    # this eventually starts the initial window with the list of errors and the
    # buttons to open log or ignore errors

    global IGNORE_ALL

    if exctyp is KeyboardInterrupt or IGNORE_ALL:
        return original_excepthook(exctyp, value, tb)

    gtk.gdk.pointer_ungrab()
    gtk.gdk.keyboard_ungrab()

    _trace = traceback.format_exception(exctyp, value, tb)
    trace = os.linesep.join(_trace)

    printlog("D-Rats", "---- GUI Exception ----\n%s\n---- End ----\n" % trace)

    msg = """
<b><big>D-RATS has encountered an error.</big></b>
This may be non-fatal, so you may click <b>Ignore</b> below to attempt to continue running.  Otherwise, click 'Quit' to terminate D-RATS now. If you are planning to file a bug for this issue, please click <b>Debug Log</b> below and include the contents in the bug tracker.
If you need to ignore all additional warnings for this session, click <b>Ignore All</b>.  However, please reproduce and report the issue when possible.
"""

    def extra(dialog):
        dialog.add_button(_("Debug Log"), gtk.RESPONSE_HELP)
        dialog.add_button(_("Ignore"), gtk.RESPONSE_CLOSE)
        dialog.add_button(_("Ignore All"), -1)
        dialog.add_button(gtk.STOCK_QUIT, gtk.RESPONSE_CANCEL)
        dialog.set_default_response(gtk.RESPONSE_CANCEL)

    while True:
        r = utils.make_error_dialog(msg,
                                    trace,
                                    gtk.BUTTONS_NONE,
                                    gtk.MESSAGE_ERROR,
                                    extra=extra)
        if r == gtk.RESPONSE_CANCEL:
            sys.exit(1)
        elif r == gtk.RESPONSE_CLOSE:
            break
        elif r == -1:
            IGNORE_ALL = True
            break
        elif r == gtk.RESPONSE_HELP:
            p = dplatform.get_platform()
            p.open_text_file(p.config_file("debug.log"))
Exemplo n.º 16
0
    def stop(self):
        self.enabled = False

        self.condition.acquire()
        self.condition.notify()
        self.condition.release()

        if self.repeat_thread:
            printlog("Repeater  : Stopping repeater")
            self.repeat_thread.join()

        for p in self.paths:
            printlog("Repeater  : Stopping")
            p.disable()

        if self.socket:
            self.socket.close()
Exemplo n.º 17
0
    def incoming_data(self, frame):
        if frame.type == self.T_RPCREQ:
            try:
                job = self.__decode_rpccall(frame)
            except UnknownRPCCall as e:
                printlog(
                    "RPC",
                    "       : incoming data : unable to execute RPC from %s: %s"
                    % (frame.s_station, e))
                return

            job.connect("state-change", self.__job_state, frame.seq)
            result = job.do(self.__rpcactions)
            if result is not None:
                job.set_state("complete", result)

        elif frame.type == self.T_RPCACK:
            if frame.seq in self.__jobs:
                ts, att, job = self.__jobs[frame.seq]
                del self.__jobs[frame.seq]
                job.set_state("complete", decode_dict(frame.data))
            else:
                printlog("RPC",
                         "       : incoming data : Unknown job %i" % frame.seq)

        else:
            printlog(
                "RPC", "       : incoming data : Unknown RPC frame type %i" %
                frame.type)
Exemplo n.º 18
0
    def RPC_file_pull(self, job):
        result = {}

        if not self.__config.getboolean("prefs", "allow_remote_files"):
            result["rc"] = "Remote file transfers not enabled"
            return result

        dir = self.__config.get("prefs", "download_dir")
        path = os.path.join(dir, job.get_file())
        printlog("RPC", "       : Remote requested %s" % path)
        if os.path.exists(path):
            result["rc"] = "OK"
            self.emit("rpc-send-file", job.get_dest(), self.__port, path,
                      job.get_file())
        else:
            result["rc"] = "File not found"

        event = main_events.Event(None, job.get_dest() + " " + \
                                      _("Requested file %s") % job.get_file())
        self.emit("event", event)

        return result
Exemplo n.º 19
0
    def auth_user(self, pipe):
        host, port = pipe._socket.getpeername()

        if not self.reqauth:
            pipe.write("100 Authentication not required\r\n")
            return True
        elif self.trustlocal and host == "127.0.0.1":
            pipe.write("100 Authentication not required for localhost\r\n")
            return True

        auth_fn = dplatform.get_platform().config_file("users.txt")
        try:
            auth = open(auth_fn)
            lines = auth.readlines()
            auth.close()
        except Exception as e:
            printlog("Repeater  : Failed to open %s: %s" % (auth_fn, e))

        pipe.write("101 Authorization required\r\n")
        username, password = self.auth_exchange(pipe)

        lno = 1
        for line in lines:
            line = line.strip()
            try:
                u, p = line.split(" ", 1)
                u = u.upper()
            except Exception as e:
                printlog(
                    "Repeater  : Failed to parse line %i in users.txt: %s" %
                    (lno, line))
                continue

            if u == username and p == password:
                printlog(("Authorized user %s" % u))
                pipe.write("200 Authorized\r\n")
                return True

        printlog("Repeater  : User %s failed to authenticate" % username)
        pipe.write("500 Not authorized\r\n")
        return False
Exemplo n.º 20
0
if __name__ == "__main__":
    import sys

    if not opts.debug:
        if opts.logpath:
            f = open(opts.logpath + "/repeater.log", "a", 0)
        else:
            p = dplatform.get_platform()
            #f = file(p.config_file("repeater.log"), "w", 0)
            f = open(p.config_file("repeater.log"), "a", 0)
        if f:
            sys.stdout = f
            sys.stderr = f
        else:
            printlog("Repeater  : Failed to open log")

    if opts.console:
        r = RepeaterConsole()
        r.main()
    else:
        import gtk
        import gobject
        from d_rats.miscwidgets import make_choice
        from d_rats import miscwidgets
        from d_rats.config import prompt_for_port

        gobject.threads_init()

        g = RepeaterGUI()
        gtk.main()
Exemplo n.º 21
0
    def add_outgoing_paths(self, id, paths):
        reqauth = self.config.get("settings", "require_auth") == "True"
        trustlocal = self.config.get("settings", "trust_local") == "True"
        gps_okay_ports = self.config.get("tweaks", "allow_gps").split(",")
        printlog("Repeater  : Repeater id is %s" % id)
        self.repeater = Repeater(id, reqauth, trustlocal, gps_okay_ports)
        for dev, param in paths:
            to = 0
            if dev.startswith("net:"):
                try:
                    net, host, port = dev.split(":", 2)
                    port = int(port)
                except Exception as e:
                    printlog(("Invalid net string: %s (%s)" % (dev, e)))
                    continue

                printlog("Repeater  : Socket %s %i (%s)" % (host, port, param))

                if param:
                    path = comm.SocketDataPath((host, port, id, param))
                else:
                    path = comm.SocketDataPath((host, port))
            elif dev.startswith("tnc:"):
                try:
                    tnc, port, device = dev.split(":", 2)
                    device = int(device)
                except Exception as e:
                    printlog("Repeater  : Invalid tnc string: %s (%s)" %
                             (dev, e))
                    continue
                printlog("Repeater  : TNC %s %i" %
                         (dev.replace("tnc:", ""), int(param)))
                path = comm.TNCDataPath((dev.replace("tnc:", ""), int(param)))
            else:
                printlog("Repeater  : Serial: %s %i" % (dev, int(param)))
                path = comm.SerialDataPath((dev, int(param)))
                to = 3

            path.connect()
            tport = transport.Transporter(path, warmup_timout=to, name=dev)
            self.repeater.add_new_transport(tport)
Exemplo n.º 22
0
    o.add_option("-c",
                 "--config",
                 dest="config",
                 help="Use alternate configuration directory")
    o.add_option("-p",
                 "--profile",
                 dest="profile",
                 action="store_true",
                 help="Enable profiling")
    (opts, args) = o.parse_args()

    # import the platform module - this will setup all the proper parameters for the different OSs
    from d_rats import dplatform

    if opts.config:
        printlog("D-Rats",
                 "    : re-config option found -- Reconfigure D-rats")
        dplatform.get_platform(opts.config)

    # import the D-Rats main application
    from d_rats import mainapp

    #stores away the value of sys.excepthook
    install_excepthook()

    import libxml2
    libxml2.debugMemory(1)

    # create the mainapp with the basic options
    app = mainapp.MainApp(safe=opts.safe)

    printlog("D-Rats", "    : reloading app\n\n")
Exemplo n.º 23
0
    def RPC_pos_report(self, job):
        result = {}
        mycall = self.__config.get("user", "callsign")
        rqcall = job.get_station()

        printlog("RPC", "       : Position request for `%s'" % rqcall)
        printlog("RPC", "       : Self=%s" % format(self))

        if rqcall == mycall or rqcall == ".":
            rqcall = None
        try:
            #obtaining current position from config or local gps
            fix = self.emit("get-current-position", rqcall)
            #result = fix.to_NMEA_GGA()
            result["rc"] = "True"
            result["msg"] = fix.to_APRS(
                symtab=self.__config.get("settings", "aprssymtab"),
                symbol=self.__config.get("settings", "aprssymbol"))

        except Exception as e:
            printlog(
                "RPC",
                "       : Case KO : Exception while getting position of %s: " %
                rqcall)
            log_exception()
            fix = None
            result["rc"] = "False"
            result["msg"] = " No data for station '%s'" % job.get_station()

        if fix:
            #sending the position to transport // but this is broken!!
            printlog("RPC", "       : port is           : %s" % self.__port)
            printlog("RPC", "       : fix is            : %s" % fix)
            printlog("RPC",
                     "       : fix in NMEA GGA is: %s" % fix.to_NMEA_GGA())
            printlog("RPC", "       : fix in APRS is: %s" % result)

            #self.emit("user-send-chat","CQCQCQ", self.__port, fix.to_NMEA_GGA(), True)
            self.emit("user-send-chat", "CQCQCQ", self.__port, result["msg"],
                      True)
        return None
Exemplo n.º 24
0
 def handler(obj, *args):
     printlog("RPC", "       : Proxy emit %s: %s" % (signal, args))
     gobject.idle_add(self.emit, signal, *args)
Exemplo n.º 25
0
    def incoming_data(self, frame):
        printlog("Chat","      : Got chat frame: %s" % frame)
        if frame.type == self.T_DEF:
            fix = gps.parse_GPS(frame.data)
            if fix and fix.valid:
                self._incoming_gps(fix)
            else:
                self._incoming_chat(frame)

        elif frame.type == self.T_PNG_REQ:
            self._emit("ping-request",
                       frame.s_station, frame.d_station, "Request")

            if frame.d_station == "CQCQCQ":
                delay = random.randint(0,50) / 10.0
                printlog("Chat","      : Broadcast ping, waiting %.1f sec" % delay)
                time.sleep(delay)
            elif frame.d_station != self._sm.station:
                return # Not for us

            frame.d_station = frame.s_station
            frame.type = self.T_PNG_RSP

            try:
                frame.data = self.pingfn()
            except Exception as e:
                printlog("Chat","      : Ping function failed: %s" % e)
                return

            self._sm.outgoing(self, frame)

            try:
                s, m = self.emit("get-current-status")
                self.advertise_status(s, m)
            except Exception as e:
                printlog("Chat","      : Exception while getting status for ping reply:")
                utils.log_exception()

            self._emit("ping-response",
                       frame.s_station,
                       frame.d_station,
                       six.text_type(frame.data, "utf-8"))
        elif frame.type == self.T_PNG_RSP:
            printlog("Chat","      : PING OUT")
            self._emit("ping-response",
                       frame.s_station, frame.d_station, frame.data)
        elif frame.type == self.T_PNG_ERQ:
            self._emit("ping-request", frame.s_station, frame.d_station,
                       "%s %i %s" % (_("Echo request of"),
                                     len(frame.data),
                                     _("bytes")))

            if frame.d_station == "CQCQCQ":
                delay = random.randint(0, 100) / 10.0
                printlog("Chat","      : Broadcast ping echo, waiting %.1f sec" % delay)
                time.sleep(delay)
            elif frame.d_station != self._sm.station:
                return # Not for us

            frame.d_station = frame.s_station
            frame.type = self.T_PNG_ERS

            self._sm.outgoing(self, frame)

            self._emit("ping-response", frame.s_station, frame.d_station,
                       "%s %i %s" % (_("Echo of"),
                                    len(frame.data),
                                    _("bytes")))
        elif frame.type == self.T_PNG_ERS:
            self._emit("ping-response", frame.s_station, frame.d_station,
                       "%s %i %s" % (_("Echo of"),
                                     len(frame.data),
                                     _("bytes")))
            if frame.s_station in self.__ping_handlers:
                cb, data = self.__ping_handlers[frame.s_station]
                try:
                    cb(*data)
                except Exception:
                    printlog("Chat","      : Exception while running ping callback")
                    utils.log_exception()
        elif frame.type == self.T_STATUS:
            try:
                s = int(frame.data[0])
            except Exception:
                printlog("Chat","      : Unable to parse station status: %s" % {frame.s_station :
                                                                  frame.data})
                s = 0

            self._emit("station-status", frame.s_station, s, frame.data[1:])
Exemplo n.º 26
0
    def __repeat(self, transport, frame):
        if frame.d_station == "!":
            return

        if frame.s_station == frame.d_station == "CQCQCQ" and \
                frame.session == 1 and \
                frame.data.startswith("$") and \
                self.__should_repeat_gps(transport, frame):
            for s in self.gps_sockets:
                s.send(frame.data)

        srcinfo = self.calls.get(frame.s_station, None)
        if srcinfo is None and frame.s_station != "CQCQCQ":

            printlog("Repeater  : Adding new station %s to port %s" %
                     (frame.s_station, transport))
            self.calls[frame.s_station] = CallInfo(frame.s_station, transport)
        elif srcinfo:
            if srcinfo.last_transport() != transport:
                printlog("Repeater  : Station %s moved to port %s" %
                         (frame.s_station, transport))

            srcinfo.just_heard(transport)

        dstinfo = self.calls.get(frame.d_station, None)
        if dstinfo is not None:
            if not dstinfo.last_transport().enabled:
                printlog("Repeater  : Last transport for %s is dead" %
                         frame.d_station)
            elif dstinfo.last_heard() < self.__call_timeout:
                printlog("Repeater  : Delivering frame to %s at %s" %
                         (frame.d_station, dstinfo.last_transport()))
                dstinfo.last_transport().send_frame(frame.get_copy())
                return
            else:
                printlog("Repeater  : Last port for %s was %i sec ago (>%i sec)" % \
                    (frame.d_station,
                     dstinfo.last_heard(),
                     self.__call_timeout))

        printlog("Repeater  : Repeating frame to %s on all ports" %
                 frame.d_station)
        for path in self.paths[:]:
            if path == transport:
                continue
            if not path.enabled:
                printlog("Repeater  : Found a stale path, removing...")
                path.disable()
                self.paths.remove(path)
            else:
                path.send_frame(frame.get_copy())