//  Benthos.h contains function prototypes for Benthos ATM885 Acoustic Modem
//  15Jul08  LAR added Sreg2 to ACM struct
//  09Jan09  LAR added d_pitch to ACM modem struct (stand on tail in drift)
//  22Jan09  LAR added s_modinfo.power to change acoustic power
//  13Feb09  LAR added OpenAcLnk2 which changes power settings of REMOTE
//                     ACM->rempwr records the setting
//  24Jul09  LAR augmented struct s_modinfo to add minpwr,pmargn,nsub
//                Changes size of ACM struct & ACDIAG message as a byproduct.
//           LAR created OpenAcLnk3 from OpenAcLnk2 to change power adjust
//  25Jul09  LAR changed def. of ACM->ber from Bit error Rate to actual
//                bit errors in the ATX response.
//  01Aug09  LAR added GetModemInfo & mod acm_dbase to handle mult modems
//  28Mar10  LAR dft_pit in ACM modem struct is no longer used.The pitch
//                is spec'd for all modems by EEPROM ee_acm_ptch.  Drf_pit
//                is left in the s_modeminfo so format of ACDIAC messages will
//                remain the same.
//  30Nov15  LAR Removed btmsk from struct ACM. No bit masking is now 
//               available to get individual 246 byte sub-blocks
//************************************************************************
//#include <tat332.h>  //pick up some useful typedefs

// RS232 comms with acoustic modem
short acm_off(void);    //turn OFF ac.modem
short start_acm(void);  //one try to power up and initialize acm
short acm_Power_Up(void);  //multiple tries to power up acm & verify awake
short ack_acm(void);       //send AT to modem & look for '0' returned
void Transparent_ACM( void );  //Transparent COMM to LOC Modem
void test_acm(void);    //test ac modem functions
void menu_acm(void);    //menu of ACM choices
void GetModemInfo( short Index );
void acm_dbase(void);  //manage modem database
void menu_acm_dbase(void);  //menu of modem database fns
void menu_acm_low(void);    //menu of lowlevel ACM choices
void acm_remote(void);  //functions for remote modem
void menu_acm_rem(void);    //menu of remote ACM choices
void debug_string( char string[], short nchar);
short tgetac(TUPort  *tup, char * str, short n, short to, short gap_s );
short cmd_acm(char s_cmd[],char s_rply[],short maxlen,short to_secs,short gap_s); //send s_cmd to remote modem
short all_Sregs( short remID ); //Fill global REMrep with S-register status
short GetSreg( short remID,short regno,short *value,short Ntry );  //Read specified S register
short GetBaud( short remID, short*baud,short Ntry );  //Get acoustic baud rate
short RemRange( short remote_ID , short *meters , short Ntries ); //range to remote modem
short DataBy(short remID , long *nbytes ,short Ntry);  //# data bytes in remote modem
short GetBatt(short remID ,float *xmitV,short Ntry); //read remote battery
short AmbAGC(void) ;  //Ambient AGC level
short LinkQ(short remID,short *nbytes,struct acm_param *acm);  //get data from remote modem
short SetBaud(short RemID,short baud,struct acm_param *acm,short Ntry);  //Set acoustic baud rate on remote
short SetPower( short RemID , short level , short Ntry );  //Set acoustic output level on remote
short SetSreg( short RemID,short regno,short value,short Ntry );  //Set specified S register on remote
short LOCmode(void);  
short WhatBlock( struct acm_param *ACM );//set ACM->this_blk to next block
void Adjust4NxtDive(struct acm_param *ACM);
short XferBlk(struct acm_param *ACM);  //02Mar09 get blk ACM->this_blk from ACM->remID
short XferSubBlk(short subindex,struct acm_param *ACM);  //24Jul09 get data
                                                         //using sub-blocks of 256 bytes
short ParseBuf( struct acm_param *ACM );  //05Mar09 parse message buffer
short OpenAcLnk3( void );   //Try to open Acoustic Link to ACM->modem
//void note_to_cf1( uchar *bufptr );         //ASCII not to CF1 with ID=0xba
void buf_to_cf1V( long nbytes , uchar *ptr);  //buffer to CF1 'V' file
void lifo_acdiag(void); //** queue up acm struct message
//void lifo_acdat(struct all_param *all); //** queue up acm data message
void lifo_acenergy(short REMid,short xmits); //** queue up acm energy usage
void lifo_acraw(void); //** queue up RAW acm data messages
void lifo_accmd(char cmd[],short ncmd,char rep[],
                short nrep); //** queue up acm command&reply message
void comma2space( char * bptr );  //replace commas in bptr with spaces
void ChangeShort(char label[], short *ptr);
void dbg_ac_test( void );

//
enum { NEW_BLK , OLD_BLK };  //acoustic data xfer modes


//***data structure for modem info
struct s_modinfo 
{ //info for acoustic modem  (20 bytes/modem as of 24Jul09)
  //set by GS via Iridium cmd_6
  short id;    //Modem Address ID  0,..99.  Don't try to communicate if
               //   id is not in this range.
  short baud;    //-1=auto-select fastest baud , 0=use current remote baud
                 //   or set baud to legal 140,300,600,800,1066,1200,2400
  short ib_new;  //index (in REMOTE flash) of first 4K block of new data
  short nb_new;  //max # of 4K blks of new data to transfer starting
                 //   with block ib_new
                 //      0 to transfer no new data
  short ib_rpt;  //index of 1st old block to repeat
  short nb_rpt;  //number of old blks to repeat (0 is OK)
  short dft_pit; //28Mar10 this entry is not used. Pitch angle is spec'd by
                 //  EEPROM ee_acm_ptch.  In do_acm  GetModemInfo copies the
                 //  value from ee_acm_ptch into
                 //  drft_pit item so format of ACDIAG message won't change 
  short minpwr;  //Don't adjust REMOTE Xmit Power (Sreg6) below minpwr
  short pmargn;  //Increase REMOTE Xmit pwr by pmargn steps above lowest
                 //successful level
  short nsub;    //If 1<=nsub<=15 this is the number of sub-blocks to send 
                 //per xfer using AT$BS;REMOTE Sreg57 is set to this value.
                 //The transfer of a 4K block is broken into 4096/(256*nsub)
                 //transfers each with 256*nsub bytes.nsub={1,2,4,8}.
                 //If nsub=16 use AT$BB to xfer a full 4K block
}; // end s_modinfo

struct acm_command  //struct with command string for remote modem
{ short remID;      //modem to which to send command string
  short nbytes;     //bytes in the command string
  char command[41]; //the command string
};

#define MOD_BLK_SZ 9000   //size of buffer to accept modem block

//The order of items in acm_param struct is chosen to put those items
//at the beginning which allow quick assessment of success of the 
//block transfer.
struct acm_param  //structure for Benthos ACM control/data
{ short remID;     //ID of REMOTE Spray is trying to access
  short rem_pkt;   //Packet ID assigned by REMOTE to data packet
  short rempwr;    //remote power setting of the REMOTE. If unable to read
                   //the REMOTE Sreg6, then rempwr = negative of last level
                   //sent to it
  short battV;     //Remote battery voltage (LSB=.01V)     (OpenAcLink)
  long rem_bytes;  //long # data bytes stored in remote flash
  long indx_recd;  //long index of last byte received from remote
                   //this index tracks the latest byte actually received
                   //There may be gaps if not all block transfers are
                   //successful.
  short this_blk;  //index of current 4K block 
  short by_read;   //#bytes actually read into buf
  short blk_secs;  //est. secs to xfer this_blk at current baud 
  short LocBatt;   //LOCAL battery voltage (LSB=.01V)     (OpenAcLink)
  short RdB_tries; //# attempts made in CheckXfer to Read Block
  short RdB_err;   //error on last GetTSData attempt for this block
                   //  0 = success 
                   // -2 = no response from local modem or LOCAL not ON
                   // -4 = unexpected,illegal, or unparsable response
                   // -6 = format was OK but CRC failed
  short StX_tries; //# attempts made in StartXfer to start this_block
  short Xfer_err;  //error of last StartXfer attempt
                   //  0 = success
                   // -1 = illegal remote ID
                   // -2 = no response from local modem or LOCAL not ON
                   // -3 = REMOTE no response
                   // -4 = unexpected,illegal, or unparsable response
                   // -5 = remote data block is empty
  //environment info
  short eb_secs;   //seconds since end of OpenAcLink to end of subblock xfer
                   //granularity depends on int. between CheckXfer calls
  short depth;   //depth in 0.1 dBar
  short range;  //range to remote in meters             (LinkQ & Xfer)
  short Lnk_tries; //number of LinkQ attempts made
  //acoustic link info extracted from LinkQ,OpenAcLink,or Xfer
  short SourceID;  //ID of REMOTE obtained from message (Xfer)
  short baud;   //REMOTE acoustic baud rate (bits/sec)  (LinkQ)
  short ber;    //Bit Errors in ATX  25Jul06 changed from BitErrRate to err count
                //    directly read from ATX message
  short snr;    //signal/noise in 0.1 dB                (LinkQ & Xfer)
  short agc;    //AGC level 0-95                        (LinkQ & Xfer)
  short spd;    //speed of closure bet modems (0.1 kts) (LinkQ & Xfer)
  short mpd;    //multipath delay in 0.1 msec           (LinkQ & Xfer)
  short CRC;    //0 if CRC good, 1 if CRC is bad        (Xfer)
  short ccerr;  //corrected chan err metric (0-14??)    (LinkQ & Xfer)
  short Sreg2;  //=0 if no retry is disabled, =1 if retry enabled (OpenAc)
  short AGCamb; //Ambient noise from AGC   (OpenAcLink) 
  struct s_modinfo modem; //description of modem (20 bytes/modem as of 24Jul09)
  unsigned short us_dummy[4];
  //Params to manage xfer
  short xfer_mode;  //NEW_BLK , OLD_BLK 
  short blk_inc;  //increment between blocks sought from REMOTE
                  //1=ask for every block, 2=get every-other-one
                  //set by ee_acm_binc which is set by Ground Station
  short new_blk;  //first 4K block (0-175) to ask for (to get new data)
                  //increments during acquisition. Always = next NEW block
  short lnew_blk; //last block to ask for. No xfer if new_blk > lnew_blk
  short old_blk;  //first 4K block (0-175) with old data
                  //increments during acquisition. Always = next OLD block
  short lold_blk; //last old block to ask for. No xfer if old_blk > lold_blk
  short end_diag; //diagnostic message has all of struct up to end_diag
  //"invisible" items follow this end_diag line
  #define MAX_MODEMS 5 // max # modems to access in a dive
  //define a database with the information
  //The final element in the database has modlist[last].id=-1
  struct s_modinfo modlist[MAX_MODEMS]; //declared in Benthos.h
  short tst_bytes;  //number of bytes in test message   (LinkQ)
  ulong endLinks; //time(seconds) at end of OpenAcLink
  ulong endXfer;  //time(seconds) at expected end of acoustic transfer
   //data transferred from LOCAL TS ISR buffer  by_read=# bytes read
  short bufsize;       //size of buffer in bytes
  unsigned char *buf;  // points to the data buffer area
  unsigned char *p_wrking;  //temp pointer to start of area being worked on in buf
}; //end acm_param
//*****************************************************************************
