Example #1
0
 def from_data(cls, data):
     or_valueerror(len(data) == 11)
     src_callsign, src_module, dest_module, _ = struct.unpack('8sccB', data)
     src_callsign = DSTARCallsign(src_callsign)
     src_module = DSTARModule(src_module)
     dest_module = DSTARModule(dest_module)
     or_valueerror(str(dest_module) == ' ')
     return cls(src_callsign, src_module)
Example #2
0
 def from_data(cls, data):
     or_valueerror(len(data) == 14)
     src_callsign, src_module, dest_module, nack = struct.unpack(
         '8scc4s', data)
     src_callsign = DSTARCallsign(src_callsign)
     src_module = DSTARModule(src_module)
     dest_module = DSTARModule(dest_module)
     or_valueerror(str(dest_module) != ' ')
     or_valueerror(nack == 'NAK\x00')
     return cls(src_callsign, src_module, dest_module)
Example #3
0
    def from_data(cls, data):
        # Same size with disconnect
        # if (len(data) == 11):
        #     raise NotImplementedError

        or_valueerror(len(data) == 14)
        src_callsign, src_module, dest_module, ack = struct.unpack(
            '8scc4s', data)
        src_callsign = DSTARCallsign(src_callsign)
        src_module = DSTARModule(src_module)
        dest_module = DSTARModule(dest_module)
        or_valueerror(str(dest_module) != ' ')
        or_valueerror(ack == 'ACK\x00')
        return cls(src_callsign, src_module, dest_module,
                   1)  # XXX Could it be revision 0?
Example #4
0
 def from_data(cls, data):
     or_valueerror(len(data) == 11)
     src_callsign, src_module, dest_module, src_revision = struct.unpack(
         '8sccB', data)
     src_callsign = DSTARCallsign(src_callsign)
     src_module = DSTARModule(src_module)
     dest_module = DSTARModule(dest_module)
     or_valueerror(str(dest_module) != ' ')
     if src_revision == 11:
         revision = 1
     elif (str(src_callsign).startswith('XRF')):
         revision = 2
     else:
         revision = 0
     return cls(src_callsign, src_module, dest_module, revision)
Example #5
0
 def from_data(cls, data):
     or_valueerror(len(data) == 9)
     src_callsign, _ = struct.unpack('8sc', data)
     src_callsign = DSTARCallsign(src_callsign)
     return cls(src_callsign)  # XXX Get module?
Example #6
0
def dv_encoder():
    parser = argparse.ArgumentParser(
        description='D-STAR encoder. Encodes samples into streams.')
    parser.add_argument('-v',
                        '--verbose',
                        default=False,
                        action='store_true',
                        help='enable debug output')
    parser.add_argument('-m',
                        '--mode',
                        default='3200',
                        help='Codec 2 mode (2400 or 3200)')
    parser.add_argument('-f',
                        '--fec',
                        default=False,
                        action='store_true',
                        help='enable FEC')
    parser.add_argument('input', help='name of file to encode (WAV format)')
    parser.add_argument('output', help='name of file to write (DVTool format)')
    args = parser.parse_args()

    logging.basicConfig(
        format='%(asctime)s [%(levelname)7s] %(name)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=logging.DEBUG if args.verbose else logging.INFO)
    logger = logging.getLogger(os.path.basename(sys.argv[0]))

    if args.mode not in ('2400', '3200'):
        logger.error('mode can be either 2400 or 3200')
        sys.exit(1)
    if args.fec:
        logger.error('FEC is not implemented')
        sys.exit(1)

    wavef = wave.open(args.input, 'r')
    if (wavef.getnchannels() != 1 or wavef.getsampwidth() != 2
            or wavef.getframerate() != 8000):
        logger.error(
            'input file must have 1 channel, 16 bits/sample, and 8000 samples/sec'
        )
        sys.exit(1)

    version = 0x01
    if args.mode == '2400':
        version |= 0x02
    # if args.fec:
    #     version &= 0x04
    dstar_header = DSTARHeader(0, 0, version, DSTARCallsign('NOCALL'),
                               DSTARCallsign('NOCALL'),
                               DSTARCallsign('NOCALL'),
                               DSTARCallsign('NOCALL'), DSTARSuffix('    '))
    header = DVHeaderPacket(0, 0, 0, 0, dstar_header)
    stream = [header]
    packet_id = 0

    mode = pydv.codec2.MODE_2400 if (args.mode
                                     == '2400') else pydv.codec2.MODE_3200
    state = pydv.codec2.init_state(mode)
    while True:
        data = wavef.readframes(160)
        if len(data) < 160:
            break

        dvcodec = pydv.codec2.encode(state, data)
        dstar_frame = DSTARFrame(
            dvcodec, '\x55\x2d\x16' if (packet_id % 21 == 0) else '')
        packet = DVFramePacket(0, 0, 0, 0, packet_id % 21, dstar_frame)
        stream.append(packet)

        packet_id += 1

    # Mark last packet
    packet = stream[-1]
    packet.packet_id |= 64

    wavef.close()

    with DVToolFile(args.output) as f:
        f.write(stream)
Example #7
0
def dv_recorder():
    parser = argparse.ArgumentParser(description='D-STAR recorder. Connects to reflector and records traffic.')
    parser.add_argument('-v', '--verbose', default=False, action='store_true', help='enable debug output')
    parser.add_argument('-p', '--protocol', default='auto', help='network protocol (dextra, dplus, or auto)')
    parser.add_argument('callsign', help='your callsign')
    parser.add_argument('reflector', help='reflector\'s callsign')
    parser.add_argument('module', help='reflector\'s module')
    parser.add_argument('address', help='reflector\'s hostname or IP address')
    args = parser.parse_args()

    logging.basicConfig(format='%(asctime)s [%(levelname)7s] %(name)s: %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        level=logging.DEBUG if args.verbose else logging.INFO)
    logger = logging.getLogger(os.path.basename(sys.argv[0]))

    try:
        callsign = DSTARCallsign(args.callsign)
        reflector_callsign = DSTARCallsign(args.reflector)
        reflector_module = DSTARModule(args.module)
        if args.protocol == 'dextra':
            connection_class = DExtraConnection
        elif args.protocol == 'dextraopen':
            connection_class = DExtraOpenConnection
        elif args.protocol == 'dplus':
            connection_class = DPlusConnection
        elif args.protocol == 'auto':
            if str(reflector_callsign).startswith('REF'):
                connection_class = DPlusConnection
            elif str(reflector_callsign).startswith('ORF')
                connection_class = DExtraOpenConnection
            else:
                connection_class = DExtraConnection
        else:
            raise ValueError
        reflector_address = NetworkAddress(args.address, connection_class.DEFAULT_PORT)
    except ValueError:
        parser.print_help()
        sys.exit(1)

    try:
        stream_id = None
        with connection_class(callsign, DSTARModule(' '), reflector_callsign, reflector_module, reflector_address) as conn:
            try:
                while True:
                    packet = conn.read()
                    if isinstance(packet, DVHeaderPacket):
                        if packet.stream_id != stream_id:
                            stream_id = packet.stream_id
                            stream = [packet]
                    elif isinstance(packet, DVFramePacket):
                        if packet.stream_id == stream_id:
                            stream.append(packet)
                            if packet.is_last:
                                with DVToolFile('%s.dvtool' % stream_id) as f:
                                    f.write(stream)
                                stream_id = None
                    else:
                        pass
            except (DisconnectedError, KeyboardInterrupt):
                pass
    except Exception as e:
        logger.error(str(e))
        sys.exit(1)
Example #8
0
File: dplus.py Project: narspt/pydv
 def from_data(cls, data):
     or_valueerror(len(data) == 28)
     login, callsign, _, serial = struct.unpack('4s8s8s8s', data[4:])
     or_valueerror(login == '\x1c\xc0\x04\x00')
     callsign = DSTARCallsign(callsign)
     return cls(callsign, serial)
Example #9
0
def dv_player():
    parser = argparse.ArgumentParser(description='D-STAR player. Connects to reflector and plays back recordings.')
    parser.add_argument('-v', '--verbose', default=False, action='store_true', help='enable debug output')
    parser.add_argument('-p', '--protocol', default='auto', help='network protocol (dextra, dextraopen, dplus, or auto)')
    parser.add_argument('callsign', help='your callsign')
    parser.add_argument('reflector', help='reflector\'s callsign')
    parser.add_argument('module', help='reflector\'s module')
    parser.add_argument('address', help='reflector\'s hostname or IP address')
    parser.add_argument('input', help='name of file to play back (DVTool format)')
    args = parser.parse_args()

    logging.basicConfig(format='%(asctime)s [%(levelname)7s] %(name)s: %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        level=logging.DEBUG if args.verbose else logging.INFO)
    logger = logging.getLogger(os.path.basename(sys.argv[0]))

    try:
        callsign = DSTARCallsign(args.callsign)
        reflector_callsign = DSTARCallsign(args.reflector)
        reflector_module = DSTARModule(args.module)
        if args.protocol == 'dextra':
            connection_class = DExtraConnection
        elif args.protocol == 'dextraopen':
            connection_class = DExtraOpenConnection
        elif args.protocol == 'dplus':
            connection_class = DPlusConnection
        elif args.protocol == 'auto':
            if str(reflector_callsign).startswith('REF'):
                connection_class = DPlusConnection
            elif str(reflector_callsign).startswith('ORF')
                connection_class = DExtraOpenConnection
            else:
                connection_class = DExtraConnection
        else:
            raise ValueError
        reflector_address = NetworkAddress(args.address, connection_class.DEFAULT_PORT)
    except ValueError:
        parser.print_help()
        sys.exit(1)

    try:
        with DVToolFile(args.input) as f:
            stream = f.read()
    except Exception as e:
        logger.error(str(e))
        sys.exit(1)

    header = stream[0]
    header.dstar_header.my_callsign = callsign
    header.dstar_header.my_suffix = DSTARSuffix('    ')
    header.dstar_header.ur_callsign = DSTARCallsign('CQCQCQ')
    header.dstar_header.repeater_1_callsign = DSTARCallsign(str(reflector_callsign)[:7] + str(reflector_module))
    header.dstar_header.repeater_2_callsign = DSTARCallsign(str(reflector_callsign)[:7] + 'G')
    stream_id = random.getrandbits(16)

    try:
        with connection_class(callsign, DSTARModule(' '), reflector_callsign, reflector_module, reflector_address) as conn:
            try:
                for packet in stream:
                    packet.stream_id = stream_id
                    conn.write(packet)
            except (DisconnectedError, KeyboardInterrupt):
                pass
    except Exception as e:
        logger.error(str(e))
        sys.exit(1)