Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Zielke <kg4gjy@takeovertheworld.org>2009-05-26 05:17:06 (GMT)
committer Jack Zielke <kg4gjy@takeovertheworld.org>2009-05-26 05:17:06 (GMT)
commite448924bf5a22bbebdb663d3b5796fe483814a27 (patch)
tree3047a7c29d57ca5d636f303bb28448fb7649d8a1
parent430617045da709023a9f2cc9f4bffdecd3c3728a (diff)
version 6 - no journal, can cancel message queue, show acks
-rw-r--r--activity/activity.info2
-rwxr-xr-xaprs.py207
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
diff --git a/aprs.py b/aprs.py
index b037c5b..ee433f6 100755
--- a/aprs.py
+++ b/aprs.py
@@ -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 = {}