www.pudn.com > slow.zip > v8.C


/********************************************************* 
********************************************************** 
	v8.c 
********************************************************** 
**********************************************************/ 
/* Modem for MIPS   AJF	  January 1995 
   Procedures for starting sessions (V.8) */ 
 
#include  
#include  
 
#include  
#include  
 
#include "modem.h" 
 
#define MAXBYTES 8 
 
typedef unsigned long long u64bit; 
 
static u64bit menu; 
 
static void txloop(), putmenu(u64bit); 
static uint computemodes(vmode); 
static bool samemsg(u64bit, u64bit); 
static void norm(u64bit&); 
static void rxloop(); 
static u64bit getmsg(); 
static int getbyte(); 
 
 
global void startsession() 
  { my_alarm(10);   /* 10 sec timeout */ 
    menu = 0; 
    setduplex(SAMPLERATE/5);	/* 0.2 secs */ 
    coroutine *txco = new coroutine(txloop); 
    coroutine *rxco = new coroutine(rxloop); 
    inparallel(txco, rxco); 
    delete txco; delete rxco; 
    my_alarm(0);    /* cancel alarm */ 
    infomsg("V.8 negotiation O.K."); 
  } 
 
static void txloop() 
  { inittx_fsk(V21o); 
    uint m = computemodes(veemode); 
    u64bit msg = ((u64bit) 0xe0c1 << 48) | ((u64bit) m << 24); 
    while (menu == 0) putmenu(msg); 
    unless (samemsg(menu, msg)) giveup("Negotiation failed (V.8)"); 
    putasync(0); putasync(0); putasync(0);	/* send CJ */ 
    sendpause(0.075); flushoutput(); 
    callco(currentco -> creator); 
  } 
 
static void putmenu(u64bit msg) 
  { // fprintf(stderr, ">>> %08x %08x\r\n", (uint) (msg >> 32), (uint) msg); 
    putasync(-1);		/* 10 `1' bits */ 
    while (msg) 
      { putasync(msg >> 56); 
	msg <<= 8; 
      } 
  } 
 
static uint computemodes(vmode m)	/* work out modulation octets, given vmode */ 
  { switch (m) 
      { default:	return 0x051010; 
	case V21o:	return 0x051090; 
	case V23o:	return 0x051014; 
	case V32o:	return 0x051110; 
	case V34o:	return 0x451010; 
      } 
  } 
 
static bool samemsg(u64bit m1, u64bit m2) 
  { norm(m1); norm(m2); 
    return (m1 == m2); 
  } 
 
static void norm(u64bit &m) 
  { until ((m == 0) || (m & 0xff)) m >>= 8;	/* position at bottom om word */ 
    while ((m & 0xff) == 0x10) m >>= 8;		/* discard extension octets with no bits set */ 
  } 
 
static void rxloop() 
  { initrx_fsk(V21o); 
    u64bit m1 = getmsg(); 
    int n = 0; 
    while (n < 5) 
      { u64bit m2 = getmsg(); 
	if (m1 == m2) n++; else n = 0; 
	m1 = m2; 
      } 
    menu = m1; 
    for (;;) getasync(); 
  } 
 
static u64bit getmsg() 
  { int b; u64bit msg = 0; 
    do b = getbyte(); until (b == 0xe0);	/* look for sync word */ 
    do 
      { msg = (msg << 8) | b; 
	b = getbyte(); 
      } 
    until (b == 0xe0); 
    until (msg >> 56) msg <<= 8; 
    // fprintf(stderr, "<<< %08x %08x\r\n", (uint) (msg >> 32), (uint) msg); 
    return msg; 
  } 
 
static int getbyte() 
  { int b; 
    do b = getasync(); while (b < 0);	/* ignore timeouts */ 
    return b; 
  }