/*
        This file is part of the cFos project,
        Copyright (c) 1993 by Martin Winkler, Christoph Lders

        This file contains CAPI call routines.


        You are allowed to use, copy, distribute, publish, redistribute
        and/or modify this program under the terms of the 'cFos public
        licence and warranty'.

        This program 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 COPYING.CF for the 'cFos public license and warranty'.
*/

#include "vars.h"

byte smsgbuf [2][MSGLEN];
word smsgnr=0;

#define msglen     (*(word *) (smsgbuf [in_event]))
#define msgapplid  (*(word *) (smsgbuf [in_event]+2))
#define msgcmdsub  (*(word *) (smsgbuf [in_event]+4))
#define msgnum     (*(word *) (smsgbuf [in_event]+6))

#define msgbyte(i)   (smsgbuf [in_event][i])
#define msgword(i)   (*(word *) (smsgbuf [in_event]+i))
#define msgdword(i)  (*(dword *) (smsgbuf [in_event]+i))

#define ISPLCI(msgcmd) ((msgbits [msgcmd] & 4) != 0)

/* header len = 8 */
static void makeheader (word len, word cmdsub) {
   msglen = len;
   msgapplid = applid;
   msgcmdsub = cmdsub;
   msgnum = smsgnr;
}

static void simplemessage (word cmdsub, word xdata) {
//   word cpu_flags = mycli ();
   makeheader (10, cmdsub);
   msgword (8)  = xdata;
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_listen_b3_req (word plci) {
   simplemessage (0x81, plci);
}

void capi_select_b2_protocol_req (word cport, byte prot, byte usrrate) {
//   word cpu_flags = mycli ();
   int isv110 = (prot == 0x08) || (prot == 0x09) || (prot == 0x0a);

   makeheader (isv110 ? 20 : 19, 0x40);
   msgword (8)  = plci [cport];
   msgbyte (10) = prot;                   /* b2 prot */
   msgbyte (11) = isv110 ? 8 : 7;         /* len of following dlpd */
   msgword (12) = sreg [cport][22];       /* data len */
   msgbyte (14) = sreg [cport][23];       /* linkadr a */
   msgbyte (15) = sreg [cport][24];       /* linkadr b */
   msgbyte (16) = sreg [cport][25];       /* mod size */
   msgbyte (17) = sreg [cport][26];       /* win size */
   msgbyte (18) = isv110 ? usrrate : 0;   /* xid size/v110 user rate */
   msgbyte (19) = 0;                      /* (xid size) */
   api_putmsg ();
//   myseti (cpu_flags);
}

static int fill_b3_protocol (word cport, word offset) {
   if ((sreg [cport][21] == 1) || (sreg [cport][21] == 4)) {
      msgbyte (offset) = 0;
      return 1;
   }
   else {
      msgbyte (offset)    = 13;
      msgword (offset+1)  = sreg [cport][30];
      msgword (offset+3)  = sreg [cport][31];
      msgword (offset+5)  = sreg [cport][32];
      msgword (offset+7)  = sreg [cport][33];
      msgword (offset+9)  = sreg [cport][34];
      msgword (offset+11) = sreg [cport][35];
      msgbyte (offset+13) = sreg [cport][36];
      return 14;
   }
}

void capi_select_b3_protocol_req (word cport, word plci) {
   word len;
//   word cpu_flags = mycli ();
   msgword (8)  = plci;
   msgbyte (10) = (byte) sreg [cport][21];      /* b3-prot */
   len = fill_b3_protocol (cport, 11);
   makeheader (11+len, 0x80);
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_connect_b3_req (word cport, word plci) {
   word len;
//   word cpu_flags = mycli ();
   msgword (8)  = plci;
   len = fill_b3_protocol (cport, 10);
   makeheader (10+len, 0x82);
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_disconnect_b3_req (word cport, word ncci) {
   word len;
//   word cpu_flags = mycli ();
   msgword (8) = ncci;
   len = fill_b3_protocol (cport, 10);
   makeheader (10+len, 0x84);
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_disconnect_req (word plci, byte reason) {
//   word cpu_flags = mycli ();
   makeheader (11, 0x04);
   msgword (8)  = plci;
   msgbyte (10) = reason;
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_data_b3_req (word ncci, word cnt, void _FAR * p, byte num, word flags) {
//   word cpu_flags = mycli ();

   makeheader (19, 0x86);
   msgword (8)  = ncci;
   msgword (10) = cnt;
   msgdword (12) = (dword) p;
   msgbyte (16) = num;
   msgword (17) = flags;
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_listen_req (void) {
//   word cpu_flags = mycli ();
   makeheader (17, 0x05);
   msgbyte (8)  = sreg[0][40];      /* controller */
   msgword (9)  = sreg[0][41];      /* infomask lo */
   msgword (11) = sreg[0][42];      /* infomask hi */
   msgword (13) = sreg[0][13];      /* serviced eaz */
   msgword (15) = sreg[0][14];      /* serviced si */
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_info_req (word plci) {
//   word cpu_flags = mycli ();
   makeheader (14, 0x07);
   msgword (8)  = plci;
   msgword (10) = sreg[0][41];      /* infomask lo */
   msgword (12) = sreg[0][42];      /* infomask hi */
   api_putmsg ();
//   myseti (cpu_flags);
}

static word makedestaddr (word cport, word offset) {
   msgbyte (offset) = diallen [cport]+1;
   msgbyte (offset+1) = 0x83;
   memcpy3 ((char*) (smsgbuf [in_event]+offset+2), (char*) dialnumber [cport], msgbyte (offset)-1);
   return msgbyte (offset) + 1;
}

void capi_connect_req (word cport, int spv) {
   word len;
//   word cpu_flags = mycli ();

   msgbyte (8)   = sreg[0][40];                     /* controller */
   msgbyte (9)   = (byte) sreg[cport][15];              /* b channel id */
   msgword (10)  = sreg[0][41];                     /* infomask lo */
   msgword (12)  = sreg[0][42] | (spv ? 1<<14 : 0); /* infomask hi */
   msgbyte (14)  = (byte) sreg[cport][16];              /* SI */
   msgbyte (15)  = (byte) sreg[cport][17];              /* ASI */
   msgbyte (16)  = (byte) sreg[cport][18];              /* EAZ */
   len = makedestaddr (cport, 17);
   makeheader (17+len, 0x02);
   api_putmsg ();
//   myseti (cpu_flags);
}

#if 0
void capi_connect_info_req (word cport, word plci) {
   word len;
//   word cpu_flags = mycli ();

   msgword (8)   = plci;
   len = makedestaddr (cport, 10);
   makeheader (10+len, 0x09);
   api_putmsg ();
//   myseti (cpu_flags);
}
#endif

void capi_data_b3_resp (word cport) {
//   word cpu_flags = mycli ();

   makeheader (11, 0x0386);
   msgword (8) = ncci [cport];
   msgbyte (10) = b3number [cport];

   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_resp (word cport, word msgcmd) {
   word len;
//   word cpu_flags = mycli ();
   if (msgcmd == 2) {    /* connect_resp */
      makeheader (11, 0x03*256+msgcmd);
      msgword (8) = (ISPLCI (msgcmd) ? plci [cport] : ncci [cport]);
      msgbyte (10) = 0;
   }
   else if (msgcmd == 0x86) {    /* data_b3_resp */
      capi_data_b3_resp (cport);
//      myseti (cpu_flags);
      return;                    /* api_putmsg has been already called */
   }
   else if (msgcmd == 0x82) {    /* connect_b3_resp */
      len = fill_b3_protocol (cport, 11);
      msgword (8) = ncci [cport];
      msgbyte (10) = disco [cport] != 0 ? 0xff : 0;
      makeheader (11+len, 0x03*256+msgcmd);
   }
   else if (msgcmd != 0xff) {    /* manufacturer_resp */
      makeheader (10, 0x03*256+msgcmd);
      msgword (8) = (ISPLCI (msgcmd) ? plci [cport] : ncci [cport]);
   }
   else {
      makeheader (8, 0x03*256+msgcmd);
   }
   api_putmsg ();
//   myseti (cpu_flags);
}

void capi_ans (word plci, byte val) {
//   word cpu_flags = mycli ();
   makeheader (11, 0x0302);
   msgword (8) = plci;
   msgbyte (10) = val;
   api_putmsg ();
//   myseti (cpu_flags);
}

/* --- eof capi.c */
