diff options
author | Jack Zielke <kg4gjy@takeovertheworld.org> | 2009-05-26 05:17:06 (GMT) |
---|---|---|
committer | Jack Zielke <kg4gjy@takeovertheworld.org> | 2009-05-26 05:17:06 (GMT) |
commit | e448924bf5a22bbebdb663d3b5796fe483814a27 (patch) | |
tree | 3047a7c29d57ca5d636f303bb28448fb7649d8a1 | |
parent | 430617045da709023a9f2cc9f4bffdecd3c3728a (diff) |
version 6 - no journal, can cancel message queue, show acks
-rw-r--r-- | activity/activity.info | 2 | ||||
-rwxr-xr-x | aprs.py | 207 |
2 files changed, 162 insertions, 47 deletions
diff --git a/activity/activity.info b/activity/activity.info index 34c38f0..636e501 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = APRS-XO -activity_version= 5 +activity_version= 6 service_name = org.laptop.APRSXO icon = activity-aprs-xo exec = sugar-activity aprs.APRSActivity @@ -40,9 +40,11 @@ RECV_BUFFER = 4096 MAXLINES = 50 MAXRETRIES = 15 -MAX_MSG_QUEUE = 10 +MAX_MSG_QUEUE = 25 MAX_PER_CALL_QUEUE = 2 +FILTER = "m/300" + bundle = ActivityBundle(activity.get_bundle_path()) VERSION = bundle.get_activity_version() del bundle @@ -67,6 +69,9 @@ class APRSActivity(activity.Activity): self.message_list = {} self.seen_bulletins = {} self.message_marks = {} + self.input_watch = [] + self.output_watch = [] + self.current_message = {} titlefont = pango.FontDescription('Sans bold 8') mediumfont = pango.FontDescription('Sans 6.5') @@ -142,18 +147,6 @@ class APRSActivity(activity.Activity): aboutbox.pack_start(sitebox, False, False, 0) sitebox.show() -# infobox = gtk.VBox(False, 4) - -## infolabel = gtk.Label("With a ham license you can communicate worldwide with wireless and radio.\nWithout a ham license you can only communicate with other XO's on the\nInternet.") -# infolabel = gtk.Label("With a ham license you can communicate worldwide with wireless and radio.") -# infolabel.set_alignment(0, 0) -# infolabel.modify_font(smallfont) -# infobox.pack_start(infolabel, False, False, 0) -# infolabel.show() - -# aboutbox.pack_start(infobox, False, False, 0) -# infobox.show() - leftwin.pack_start(aboutbox, False, False, 0) aboutbox.show() @@ -397,12 +390,12 @@ class APRSActivity(activity.Activity): self.messageview = gtk.TextView() self.messagebuffer = self.messageview.get_buffer() - connectbutton = gtk.Button() - connectbutton.set_label("Connect") - connectbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#00b20d")) - connectbutton.connect("clicked", self.connect_aprs) - leftwin.pack_start(connectbutton, False, False, 12) - connectbutton.show() + self.connectbutton = gtk.Button() + self.connectbutton.set_label("Connect") + self.connectbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#00b20d")) + self.connectbutton.connect("clicked", self.connect_aprs) + leftwin.pack_start(self.connectbutton, False, False, 12) + self.connectbutton.show() win.pack_start(leftwin, False, False, 0) leftwin.show() @@ -413,8 +406,10 @@ class APRSActivity(activity.Activity): rightwintopbox = gtk.HBox(False, 4) clearbutton = gtk.Button() - clearbutton.set_label(" Clear ") - clearbutton.connect("clicked", self.clear_message) +# clearbutton.set_label(" Clear ") +# clearbutton.connect("clicked", self.clear_message) + clearbutton.set_label(" Cancel Messages ") + clearbutton.connect("clicked", self.clear_msg_queue) rightwintopbox.pack_start(clearbutton, False, False, 20) clearbutton.show() @@ -515,11 +510,9 @@ class APRSActivity(activity.Activity): self.calltext.grab_focus() def clear_status(self, button=None): -# self.statusbuffer.delete(self.statusbuffer.get_start_iter(), self.statusbuffer.get_end_iter()) self.statusbuffer.set_text("") def clear_message(self, button=None): -# self.messagebuffer.delete(self.messagebuffer.get_start_iter(), self.messagebuffer.get_end_iter()) self.messagebuffer.set_text("") def connect_aprs(self, button): @@ -535,7 +528,12 @@ class APRSActivity(activity.Activity): return False self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.status_write("Connecting ") - iplist = socket.gethostbyname_ex(HOST)[2] + try: + iplist = socket.gethostbyname_ex(HOST)[2] + except socket.error, msg: + self.status_write(msg[1]) + self.sock = None + return False server = random.choice(iplist) self.status_write("to %s\n" % server) try: @@ -543,7 +541,7 @@ class APRSActivity(activity.Activity): except socket.error, msg: self.status_write(msg[1]) self.sock = None - return + return False self.status_write("Connected\n") button.set_label("Disconnect") @@ -560,7 +558,7 @@ class APRSActivity(activity.Activity): self.disconnect_aprs(button) if (self.calltext.get_text() != "" and self.passtext.get_text() != ""): - sendme = "user %s pass %s vers aprs_xo %d filter m/300\n" % (self.calltext.get_text(), self.passtext.get_text(), VERSION) + sendme = "user %s pass %s vers aprs_xo %d filter %s\n" % (self.calltext.get_text(), self.passtext.get_text(), VERSION, FILTER) else: sendme = "user %s vers aprs_xo %d\n" % (self.calltext.get_text(), VERSION) self.sock.sendall(sendme) @@ -571,12 +569,15 @@ class APRSActivity(activity.Activity): if (response.find("# logresp") == -1): self.status_write("invalid response.\n") self.disconnect_aprs(button) -# if (response.find("unverified") == -1): -# self.rawbox.show() + + if (response.find("unverified") != -1): + sendme = "# filter %s\n" % FILTER + self.sock.sendall(sendme) + self.status_write("%s\n" % sendme) self.status_write("\n") - self.input_watch = gobject.io_add_watch(self.sock, gobject.IO_IN, self.recv_data) + self.input_watch.append(gobject.io_add_watch(self.sock, gobject.IO_IN, self.recv_data)) # send banner sendme = "%s>APRS-XO v%s\n" % (self.calltext.get_text(), VERSION) @@ -585,39 +586,62 @@ class APRSActivity(activity.Activity): self.status_write("APRS-XO v%s\n\n" % VERSION) self.send_beacon() - self.output_watch = gobject.timeout_add(10 * 60 * 1000, self.send_beacon) + self.output_watch.append(gobject.timeout_add(10 * 60 * 1000, self.send_beacon)) else: self.disconnect_aprs(button) - gobject.source_remove(self.input_watch) - gobject.source_remove(self.output_watch) def disconnect(self): - # for test server only - if(HOST == "192.168.50.6"): - self.sock.sendall("q") + if (self.sock != None): + # for test server only + if(HOST == "192.168.50.6"): + self.sock.sendall("q") - self.sock.close() - self.sock = None + self.sock.close() + self.sock = None def disconnect_aprs(self, button): self.disconnect() + self.clear_msg_queue() self.status_write("Disconnected\n") + + # stop input watcher - just in case + for source in self.input_watch: + try: + gobject.source_remove(source) + except: + pass + + # stop beacon + for source in self.output_watch: + try: + gobject.source_remove(source) + except: + pass + + self.input_watch = [] + self.output_watch = [] + + # TODO clear message queue + button.set_label("Connect") button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#00b20d")) -# self.rawbox.hide() def recv_data(self, sock, condition): + if (self.sock == None): + return False while 1: try: recv_data = sock.recv(RECV_BUFFER) except: self.status_write("Server closed connection.\n") self.sock = None + self.disconnect_aprs(self.connectbutton) return False if not recv_data: self.status_write("Server closed connection.\n") self.sock = None + self.disconnect_aprs(self.connectbutton) return False else: # sometimes more than one packet comes in @@ -642,6 +666,8 @@ class APRSActivity(activity.Activity): return True def send_beacon(self): + if (self.sock == None): + return False if (self.beaconbutton.get_active()): beacon = "=%s%s.%s%sX%s%s.%s%sA%s" % (self.latDDtext.get_text(), self.latMMtext.get_text(), self.latmmtext.get_text(), self.latcombo.get_active_text(), self.lonDDDtext.get_text(), self.lonMMtext.get_text(), self.lonmmtext.get_text(), self.loncombo.get_active_text(), self.stationtext.get_text()) if (self.send_data(beacon)): @@ -651,12 +677,15 @@ class APRSActivity(activity.Activity): return False def send_data(self, msg): + if (self.sock == None): + return False path = "%s>APOLPC:" % self.calltext.get_text() try: self.sock.sendall("%s%s\n" % (path, msg)) except: self.status_write("Problem sending packet\n") self.sock = None + self.disconnect_aprs(self.connectbutton) return False self.status_write("%s\n" % path) self.status_write("%s\n\n" % msg) @@ -691,9 +720,6 @@ class APRSActivity(activity.Activity): adjustment = self.messagewindow.get_vadjustment() adjustment.set_value(adjustment.upper) - def set_location(self, widget, data=None): - self.location = data - def set_site(self, widget, data=None): self.site = data self.clipboard() @@ -885,7 +911,6 @@ class APRSActivity(activity.Activity): # self.beaconbutton.set_active(self.metadata.get('beacon', "")) def msg_check(self, data): - # a better message decoder firstcheck = data.find("::") secondcheck = data[firstcheck+11:firstcheck+12] thirdcheck = data.find("{") @@ -915,13 +940,25 @@ class APRSActivity(activity.Activity): ackid = "%s-%s" % (fromcall, replyack) if (ackid in self.recv_acks): if (self.recv_acks[ackid] == 0): + count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) count_end = count_start.forward_search(">", gtk.TEXT_SEARCH_TEXT_ONLY) self.messagebuffer.delete(count_start, count_end[0]) + + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + queue_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + line_end.forward_to_line_end() + queue_start.forward_to_line_end() + queue_start.backward_chars(12) + self.messagebuffer.delete(queue_start, line_end) + + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + line_end.forward_to_line_end() + self.messagebuffer.insert(line_end, " <*ACKED*>") + self.send_msg_queue(fromcall) self.recv_acks[ackid] = 1 message = data[firstcheck+12:thirdcheck] -# ackmessage = ":%s:ack%s" % (fromcall, sequence) ackmessage = ":%s:ack%s" % (fromcall, data[thirdcheck + 1:]) self.send_data(ackmessage) id = "%s-%s" % (fromcall, sequence) @@ -945,9 +982,22 @@ class APRSActivity(activity.Activity): ackid = "%s-%s" % (fromcall, sequence) if (ackid in self.recv_acks): if (self.recv_acks[ackid] == 0): + count_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) count_end = count_start.forward_search(">", gtk.TEXT_SEARCH_TEXT_ONLY) self.messagebuffer.delete(count_start, count_end[0]) + + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + queue_start = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + line_end.forward_to_line_end() + queue_start.forward_to_line_end() + queue_start.backward_chars(12) + self.messagebuffer.delete(queue_start, line_end) + + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[ackid]) + line_end.forward_to_line_end() + self.messagebuffer.insert(line_end, " <*ACKED*>") + self.send_msg_queue(fromcall) self.recv_acks[ackid] = 1 else: @@ -969,6 +1019,7 @@ class APRSActivity(activity.Activity): except: self.status_write("Problem sending message\n") self.sock = None + self.disconnect_aprs(self.connectbutton) return False self.status_write("%s\n" % msg) self.rawtext.set_text("") @@ -1060,8 +1111,15 @@ class APRSActivity(activity.Activity): self.messagebuffer.delete(count_start, count_end) line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + queue_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + line_end.forward_to_line_end() + queue_start.forward_to_line_end() + queue_start.backward_chars(12) + self.messagebuffer.delete(queue_start, line_end) + + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) line_end.forward_to_line_end() - self.messagebuffer.insert(line_end, " * TIMEOUT *") + self.messagebuffer.insert(line_end, " <-timeout->") self.send_msg_queue(tocall) return False @@ -1130,7 +1188,7 @@ class APRSActivity(activity.Activity): self.queue_list[call] = [] self.queue_list[call].append(sequence) self.message_list[id] = message - self.message_write("%s To:%s> %s * QUEUED *\n" % (time.strftime("%m/%d %H:%M", time.localtime()), call, message)) + self.message_write("%s To:%s> %s <-queued->\n" % (time.strftime("%m/%d %H:%M", time.localtime()), call, message)) # if a message is received before the next lines are run there will be problems... iter = self.messagebuffer.get_iter_at_line(self.messagebuffer.get_line_count() - 2) iter.forward_chars(15 + len(call)) @@ -1143,11 +1201,15 @@ class APRSActivity(activity.Activity): if (self.queue_list[call] == []): del self.queue_list[call] return False + sequence = self.queue_list[call].pop(0) id = "%s-%s" % (call, sequence) message = self.message_list[id] del self.message_list[id] + # record this so cancel can work on current messages + self.current_message[call] = sequence + # send message isbulletin = self.bulletin_check(call) if (isbulletin): @@ -1160,12 +1222,65 @@ class APRSActivity(activity.Activity): self.recv_acks["%s-%s" % (call, sequence)] = 0 gobject.timeout_add(7 * 1000, self.msg_timer, call, message, sequence, 2, 7) - # clear "QUEUED" and add the counter + # reset the timestamp + line_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + date_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + length = line_start.get_line_offset() + line_start.backward_chars(length) + date_end.backward_chars(length) + date_end.forward_chars(11) + self.messagebuffer.delete(line_start, date_end) + + line_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + length = line_start.get_line_offset() + line_start.backward_chars(length) + self.messagebuffer.insert(line_start, time.strftime("%m/%d %H:%M", time.localtime())) + + # clear "<-queued->" line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) queue_start = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) line_end.forward_to_line_end() queue_start.forward_to_line_end() queue_start.backward_chars(11) self.messagebuffer.delete(queue_start, line_end) + + # add <-sending-> + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + line_end.forward_to_line_end() + self.messagebuffer.insert(line_end, " <-sending->") + + # add the counter iter = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) self.messagebuffer.insert(iter, " 1/%s" % MAXRETRIES) + + def cancel_message(self, id): + self.recv_acks[id] = 1 + + # remove status + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + line_end.forward_to_line_end() + status_start = line_end.backward_search("<", gtk.TEXT_SEARCH_TEXT_ONLY) + self.messagebuffer.delete(status_start[0], line_end) + + # add <-cancelled-> + line_end = self.messagebuffer.get_iter_at_mark(self.message_marks[id]) + line_end.forward_to_line_end() + self.messagebuffer.insert(line_end, " <-cancelled->") + + # leave counter and timestamp alone + + def clear_msg_queue(self, button=None): + if (self.queue_list != {}): + for call in self.queue_list: + for sequence in self.queue_list[call]: + id = "%s-%s" % (call, sequence) + del self.message_list[id] + self.cancel_message(id) + self.queue_list = {} + + if (self.current_message != {}): + for call in self.current_message: + sequence = self.current_message[call] + id = "%s-%s" % (call, sequence) + self.cancel_message(id) + self.current_message = {} |