#!/bin/env python
#
# Copyright 2005 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#

import sys,tty,select,termios
import varicode_table

# start phase somewhere
p=False

# setup polling input
kbrd_fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(kbrd_fd)
tty.setraw(sys.stdin.fileno())
kbrd=select.poll()
kbrd.register(kbrd_fd,select.POLLIN)

# create varicode table
varicode=varicode_table.build_vctable()

# open pipe for output
pskfh = open("/tmp/pskpipe","w")

# clear byte out accumulator
out=[]

# write some idle to sync first, current state of phase is False
# so last bit written must be 0, i.e., 0xAA (10101010)
for i in range(0,7):
  pskfh.write(chr(0xaa))
  pskfh.flush()

key='a' # define key for following test
while ord(key)!=3:   # do untill ctrl-c
  kstat = kbrd.poll(260)   # wait 260 mSec for key event, send idle if none
  if kstat == [(kbrd_fd, select.POLLIN)]:
    key = sys.stdin.read(1)
    if key=='\x7f': key='\x08' # ^H mapped to 'backspace' key
    if key=='\r':              # make return look good on stdout
      sys.stdout.write('\r\n')
      sys.stdout.flush()
    else:
      sys.stdout.write(key)
      sys.stdout.flush()
    if ord(key)==3:        # special case for ctrl-c exit, don't send
      char='00000000'
    else:
      char=varicode[ord(key)]+'00'  # lookup ascii->varicode, add spacing
  else: char = '00000000'    # no key pressed in time, send idle

  # convert varicode to phase shifts
  for i in range(0,len(char)):
    if char[i]=='0':	# phase change
      p=not p
    if p==False: out+='0'
    else: out+='1'
    if len(out)==8: # do we have a full byte?
      c = (int(out[0])<<7) + (int(out[1])<<6) + (int(out[2])<<5) + \
          (int(out[3])<<4) + (int(out[4])<<3) + (int(out[5])<<2) + \
          (int(out[6])<<1) + int(out[7])
      pskfh.write(chr(c))
      pskfh.flush()
      out=[]	# clear byte out for next byte

# clean up residual in 'out' if any
if len(out) != 0:
  for i in range(len(out),8):
    if out[i-1]=='0': out+='1'
    else: out+='0'
# then write it
  c = (int(out[0])<<7) + (int(out[1])<<6) + (int(out[2])<<5) + \
      (int(out[3])<<4) + (int(out[4])<<3) + (int(out[5])<<2) + \
      (int(out[6])<<1) + int(out[7])
  pskfh.write(chr(c))
  pskfh.flush()

# phase of idle character depends on last bit of out
  if out[7]=='0': ic=0xaa
  else: ic = 0x55
else:
  ic = 0xaa


# and some idle after ctrl-c
for i in range(0,7):
  pskfh.write(chr(ic))
  pskfh.flush()

pskfh.close()
termios.tcsetattr(kbrd_fd, termios.TCSADRAIN, old_settings)

