def parse_text(self): """ Parses and Extracts the components of an ASCII-Encoded Frame. """ frame_so_far = '' for char in self.frame: if '>' in char and not self.source: self.source = aprs.Callsign(frame_so_far) frame_so_far = '' elif ':' in char: if not self.path: if ',' in frame_so_far: self.destination = aprs.Callsign( frame_so_far.split(',')[0]) self.path = [] for path in frame_so_far.split(',')[1:]: self.path.append(aprs.Callsign(path)) frame_so_far = '' elif not self.destination: self.destination = aprs.Callsign(frame_so_far) frame_so_far = '' else: frame_so_far = ''.join([frame_so_far, char]) else: frame_so_far = ''.join([frame_so_far, char]) else: frame_so_far = ''.join([frame_so_far, char]) self.text = frame_so_far
def __init__(self, target="localhost", port=7000, source_callsign='SP3SAT', destination_callsign='PWSAT2-0'): self.context = zmq.Context.instance() self.sock = self.context.socket(zmq.PUB) self.sock.connect("tcp://%s:%d" % (target, port)) time.sleep(1) self.aprs_frame = aprs.Frame() self.aprs_frame.source = aprs.Callsign(source_callsign) self.aprs_frame.destination = aprs.Callsign(destination_callsign)
def send(self, frame): self.aprs_frame.source = aprs.Callsign(self.source_callsign) self.aprs_frame.destination = aprs.Callsign(self.destination_callsign) payload = frame.build() self.aprs_frame.text = Wrap(ensure_string(payload)) buff = array.array('B', self.aprs_frame.encode_kiss()) msg = ensure_string(buff) self.sock.send(msg)
def main(): frame = aprs.Frame() frame.source = aprs.Callsign('W2GMD-14') frame.destination = aprs.Callsign('PYKISS') frame.path = [aprs.Callsign('WIDE1-1')] frame.text = '>Hello World!' ki = kiss.TCPKISS(host='localhost', port=1234) ki.start() ki.write(frame.encode_kiss())
def main(): frame = aprs.Frame() frame.source = aprs.Callsign('ZR6AIC-14') frame.destination = aprs.Callsign('ZR6AIC-5') frame.path = [aprs.Callsign('WIDE1-1')] frame.info = '>Hello World!' ki = kiss2.TCPKISS(host='localhost', port=8001) ki.start() ki.write(frame.encode_ax25())
def main(): frame = aprs.Frame() frame.source = aprs.Callsign('W2GMD-14') frame.destination = aprs.Callsign('PYKISS') frame.path = [aprs.Callsign('WIDE1-1')] frame.text = '>Hello World!' ki = kiss.SerialKISS(port='/dev/cu.AP510-DevB', speed='9600') ki.start() ki.write(frame.encode_kiss())
def test_write(self): ks = kiss.SerialKISS(port=self.random_serial_port, speed='9600') ks.interface = dummyserial.Serial(port=self.random_serial_port) ks._write_handler = ks.interface.write frame = aprs.Frame() frame.source = aprs.Callsign(self.random(6)) frame.destination = aprs.Callsign(self.random(6)) frame.path = [ aprs.Callsign(self.random(6)), aprs.Callsign(self.random(6)) ] frame.text = ' '.join([self.random(), 'test_write', self.random()]) self._logger.debug('frame="%s"', frame) frame_encoded = frame.encode_kiss() self._logger.debug('frame_encoded="%s"', frame_encoded) ks.write(frame_encoded)
def _extract_kiss_path(self, start): """ Extracts path from raw APRS KISS frame. """ for i in range(2, start): path_call = aprs.Callsign(self.frame[i * 7:]) if path_call: if ord(self.frame[i * 7 + 6]) & 0x80: path_call.digi = True self.path.append(path_call)
def main2(): frame = kiss.strip_df_start(x) for frame_slice in range(0, frame_len): # Is address field length correct? # Find the first ODD Byte followed by the next boundary: if (frame[frame_slice] & 0x01 and ((frame_slice + 1) % 7) == 0): i = int((frame_slice + 1) / 7) # Less than 2 callsigns? if 1 < i < 11: # For frames <= 70 bytes if frame_len >= frame_slice + 2: if (frame[frame_slice + 1] & 0x03 == 0x03 and frame[frame_slice + 2] in [0xF0, 0xCF]): text = frame[frame_slice + 3:] print('Text={}'.format(text)) dest = aprs.Callsign(frame) dest2 = aprs.Callsign2(frame, True) print('{}'.format(dest)) print("{}".format(dest2.callsign)) src = aprs.Callsign(frame[7:]) src2 = aprs.Callsign2(frame[7:], True) print("{}".format(src)) print("{}".format(src2.callsign)) path = [] for x in range(2, 1): path_call = aprs.Callsign(frame[x * 7:]) if path_call: if frame[x * 7 + 6] & 0x80: path_call.digi = True path.append(path_call) print("{}".format(path))
def test_write_and_read(self): """Tests writing-to and reading-from a Dummy Serial port.""" frame = aprs.Frame() frame.source = aprs.Callsign(self.random(6)) frame.destination = aprs.Callsign(self.random(6)) frame.path = [ aprs.Callsign(self.random(6)), aprs.Callsign(self.random(6)) ] frame.text = ' '.join( [self.random(), 'test_write_and_read', self.random()]) self._logger.debug('frame="%s"', frame) frame_encoded = frame.encode_kiss() self._logger.debug('frame_encoded="%s"', frame_encoded) frame_escaped = kiss.escape_special_codes(frame_encoded) self._logger.debug('frame_escaped="%s"', frame_escaped) frame_kiss = ''.join( [kiss.FEND, kiss.DATA_FRAME, frame_escaped, kiss.FEND]) self._logger.debug('frame_kiss="%s"', frame_kiss) ks = kiss.SerialKISS(port=self.random_serial_port, speed=self.random_baudrate) ks.interface = dummyserial.Serial( port=self.random_serial_port, baudrate=self.random_baudrate, ds_responses={frame_encoded: frame_kiss}) ks._write_handler = ks.interface.write ks.write(frame_encoded) read_data = ks._read_handler(len(frame_kiss))
def parse_callsign_ax25(raw_callsign: bytes, kiss_call: bool = False) -> AprsCallsign: """ Extracts a Callsign and SSID from a AX.25 Encoded APRS Frame. :param frame: AX.25 Encoded APRS Frame. :type frame: str """ parsed_callsign = aprs.Callsign() _callsign = bytes() digi = False for _chunk in raw_callsign[:6]: chunk = _chunk & 0xFF if chunk & 1: # aprx: /* Bad address-end flag ? */ raise aprs.BadCallsignError('Bad address-end flag.') # Shift by one bit: chunk = chunk >> 1 chr_chunk = chr(chunk) if chr_chunk.isalnum(): _callsign += bytes([chunk]) # 7th byte carries SSID or digi: seven_chunk = raw_callsign[6] & 0xFF ssid = (seven_chunk >> 1) & 0x0F # Limit it to 4 bits. # FIXME gba@20170809: This works for KISS frames, but not otherwise. # Should consult: https://github.com/chrissnell/GoBalloon/blob/master/ax25/encoder.go if kiss_call: if seven_chunk >> 1 & 0x80: digi = True else: if seven_chunk & 0x80: digi = True parsed_callsign.set_callsign(_callsign) parsed_callsign.set_ssid(ssid) parsed_callsign.set_digi(digi) return parsed_callsign
def parse_callsign_text(raw_callsign: bytes) -> AprsCallsign: """ Parses an AX.25/APRS Callsign & SSID from a plain-text AX.25/APRS Frame. """ parsed_callsign: AprsCallsign = aprs.Callsign() _callsign = raw_callsign ssid = b'0' digi = False if b'*' in _callsign: _callsign = _callsign.strip(b'*') digi = True if b'-' in _callsign: _callsign, ssid = _callsign.split(b'-') parsed_callsign.set_callsign(_callsign) parsed_callsign.set_ssid(ssid) parsed_callsign.set_digi(digi) return parsed_callsign
def handle_message(self, message): self._logger.debug('Handling message="%s"', message) if message.get('type') == 'message' and message.get('data'): message_data = message['data'] aprs_frame = aprs.Frame(message_data) if aprsgate.reject_frame(aprs_frame): return for channel in self.out_channels: gate_dir, gate_id, gate_tag = channel.split('_') # Don't re-gate my own frames. (anti-loop) for frame_path in aprs_frame.path: if gate_id in str(frame_path): return aprs_frame.path.append(aprs.Callsign(gate_id)) self._logger.debug('Sending to channel=%s frame="%s"', channel, aprs_frame) self.redis_conn.publish(channel, aprs_frame)
def __init__(self, host='localhost', port=8001): self.kiss = UDPKISS(host, port) self.frame = aprs.Frame() self.frame.source = self.frame.destination = aprs.Callsign("PWSAT2-0") self.frame.text = ""
def _extract_kiss_destination(self): """ Extracts a Destination Callsign of a KISS-Encoded Frame. """ self.destination = aprs.Callsign(self.frame)
def _extract_kiss_source(self): """ Extracts a Source Callsign of a KISS-Encoded Frame. """ self.source = aprs.Callsign(self.frame[7:])
def cli(): """Tracker Command Line interface for APRS.""" parser = argparse.ArgumentParser() parser.add_argument('-d', '--debug', help='Enable debug logging', action='store_true') parser.add_argument('-c', '--callsign', help='callsign', required=True) parser.add_argument('-p', '--passcode', help='passcode', required=True) parser.add_argument('-s', '--serial_port', help='serial_port', required=True) parser.add_argument('-b', '--serial_speed', help='serial_speed', default=9600) parser.add_argument('-i', '--interval', help='interval', default=0) opts = parser.parse_args() gps_p = aprstracker.SerialGPSPoller(opts.serial_port, opts.serial_speed) gps_p.start() time.sleep(aprstracker.GPS_WARM_UP) aprs_i = aprs.TCP(opts.callsign, opts.passcode) aprs_i.start() try: while 1: aprs_latitude = None aprs_longitude = None gps_latitude = gps_p.gps_props['latitude'] gps_longitude = gps_p.gps_props['longitude'] if gps_latitude is not None: aprs_latitude = aprs.dec2dm_lat(gps_latitude) if gps_longitude is not None: aprs_longitude = aprs.dec2dm_lng(gps_longitude) if aprs_latitude is not None and aprs_longitude is not None: frame = aprstracker.LocationFrame() frame.source = aprs.Callsign(opts.callsign) frame.destination = aprs.Callsign('APYSTR') frame.latitude = aprs_latitude frame.longitude = aprs_longitude frame.course = 0 frame.speed = 0 frame.altitude = gps_p.gps_props.get('altitude', 0) frame.symboltable = '/' frame.symbolcode = '>' frame.make_frame() aprs_i.send(frame) if opts.interval == 0: break else: time.sleep(opts.interval) except KeyboardInterrupt: gps_p.stop() finally: gps_p.stop()