 /**********************************************************
 *                                                         *
 *                      SENDHS                             *
 *                SEND record to HS                        *
 * This procedure make request to the HS for send processing
 * with appropriate parms.                                 *
 * This parms are :                                        *
 *                  - FMH;                                 *
 *                  - Send_data;                           *
 *                  - Confirm;                             *
 *                  - Confirmed;                           *
 *                  - Flash;                               *
 *                  - PREP_TO_RCV_FLUSH;                   *
 *                  - PREP_TO_RCV_CONFIRM_SH;              *
 *                  - PREP_TO_RCV_CONFIRM_LG;              *
 *                  - Req_to_send;                         *
 *                  - Deallocate_confirm;                  *
 *                  - Deallocate_flush;                    *
 *                  - Deallocate_abend;                    *
 *                                                         *
 * INPUT : pointer to RCB.                                 *
 *                                                         *
 * OUTPUT: - 0 - OK;                                       *
 *         - 1 - an invalid request;                       *
 *         - 2 - a return code is in RPL.                  *
 *                                                         *
 *                                                         *
 * CopyRight 1995. Nicholas Poljakov all rights reserved.  *
 *                                                         *
 **********************************************************/
#include <stdio.h>
#include <malloc.h>
#include <rcb.h>
#include <dall.h>
#include <scb.h>
#include <prefix.h>
#include <include.h>
#include <string.h>
#include <state1.h>

#define PRF_SIZ 31

int sk_r_wt(void *);
int SendBlock(void *, void *);
int setrc(void *, void *);
int sendhs(void *);
int sendbm(void *, void *);
int sendat(void *);
int rtsend(void *);
unsigned long rmfmh5(void *, void *);
int recwait(void *);
int rcvru(void *, void *);
int rcvhs(void *, void *, void *, void *);
int ralloc(void *, void *);
int psrm(int, void *, void *);
int ps_conv(int, void *);
int proterr(void *, unsigned long);
int preptrcv(void *, void *);
int post_rcb(void *);
struct repass *postopen(void *);
int phsrec(void *);
int pfmh5(void *);
int opndst(void *);
int obtsess(void *, unsigned char);
int Lrf_handler(void *);
int get_sess(void *, void *);
int get_attr(void *);
int fsm_error(unsigned char, void *);
int fsm_conv(unsigned char, unsigned char, void *);
int flush (void *);
int dcp(void *);
int dealloc(void *);
int crtp(void *);
int conv(void *);
int chkparm(void *, void *);
int check_end(unsigned int, void *);
struct rqb *call_appl(void *);
int buffmng(unsigned char, void *, void *, void *, unsigned, unsigned char, unsigned);
unsigned long attltck(void *);
unsigned long attacheck(void *);
char *cgetmem(int, int);
int sendhsf(void *);
int opndst(void *);
int alloc_rcb(void *, void *);
int allocate(void *);
int clsdst(void *);
int short sem_no;

sendhsf(p_rcb)
struct rcb *p_rcb;
{
        struct scb *p_scb;
        struct prefix *p_prf;
        struct prefix *t_prf;
        struct prefix *tt_prf;
        struct segprf *p_sp;
        struct segprf *t_sp;
        struct rqb *p_rqb;
        struct deallocate *p_dal;
        char p1;
        char *p;
        char *p_rh;
        char *p_ru;
        unsigned int cnt;
        unsigned int cnt1;
        char *buff;
        int rc;
        unsigned char type;
        int i;
        unsigned char dsc;

        rc = 0;
        cnt1 = 0;

        if (p_rcb -> p_scb == NULL) {
             rc = 2;
             goto sd_exit;
        }
        p_scb = p_rcb -> p_scb;

        do {
             p_prf = p_rcb -> first_out;
             if (p_prf == NULL) {
                    rc = 1;
                     goto sd_exit;
                  }
             cnt = 0;
                        do {    /* for send state */
                             type = p_prf ->type;
                             switch (type)
                                    {
                                        case Fmh :
                                        {
                                            cnt += p_prf -> lt_text;
                                            break;
                                         }
                                         case Send_data :
                                         {
                                            if (( cnt + p_prf -> lt_text) > MAX_RU )
                                                    goto DOEX;
                                            cnt += p_prf -> lt_text;
                                            break;
                                         }
                                         default :
                                            goto DOEX;
                                    } /* end of switch */
                             p_prf = p_prf -> next;
			   } while (p_prf != NULL );
             DOEX:

                          if ((p_sp = calloc(1,(cnt + PRF_SIZ))) == NULL) {
                              rc = 1;
                              goto sd_exit;
                          }
                 p = p_sp;
                 p_sp -> len = cnt + 3;
                 p_rqb = p + 12;
                 p_ru = p + PRF_SIZ;
                 p_rh = p + 28 ;
                 p_prf = p_rcb -> first_out;
                 cnt1 = 0;
                 dsc = 0;
                 p_rqb -> th.ra.wa.hh.hscb = p_rcb -> sess_corl;
                 p_rqb -> th.ra.wa.rqba.rclass = cnt;
                 p_rqb -> th.ra.stcb = APPL_CODE;
                 p_rqb -> th.ra.code = p_rqb -> th.ra.code & 0xbf; /* TOP */
                 p_rqb -> th.ra.wa.rqba.rsrlen = sem_no;
                 p_rqb -> th.ra.rparm.parm.parm1 = 1; /* Send */

                 do {
                       type = p_prf -> type;
                       switch (type)
                            {
                              case Confirm :
                                     { *p_rh |=0x01;
                                       *(p_rh + 1) |=0xa0;
                                       dsc = 1;
                                       break;
                                     }
                              case COnfirmed :
                                     {
                                        *p_rh |= 0x81;
                                        *(p_rh + 1) |= 0xa0;
                                        dsc = 1;
                                         break;
                                      }
                              case Request_to_send :
                                      {
                                        *p_rh |= 0x0b;
                                        *(p_rh + 1) |= 0x80;
                                        dsc = 1;
                                        break;
                                      }
                              case Fmh :
                                       {
                                         *p_rh |= 0x0a;
                                         memcpy( p_ru,p_prf->text,p_prf->lt_text);
                                         p_ru += p_prf ->lt_text;
                                         cnt1 += p_prf -> lt_text;
                                         break;
                                       }
                              case Send_data :
                                       {
                                         if (( cnt1 + p_prf ->lt_text ) > cnt )
                                                goto FULLSG;
                                         *(p_rh + 1) |=0x90;
                                         memcpy( p_ru,p_prf->text,p_prf->lt_text);
                                         p_ru += p_prf ->lt_text;
                                         cnt1 += p_prf -> lt_text;
                                         break;
                                       }
                              case Flush :
                                       {
                                        *(p_rh + 1) |= 0x90;
                                        dsc = 1;
                                        break;
                                       }
                              case PREP_TO_RCV_FLUSH :
                                       {
                                        *p_rh |= 0x01;
                                        *(p_rh + 1) |= 0x90;
                                        *(p_rh + 2) |= 0x20;
                                        dsc = 1;
                                        break;
                                       }
                              case PREP_TO_RCV_CONFIRM_SH :
                                       {
                                        *p_rh |= 0x01;
                                        *(p_rh + 1) |= 0xa0;
                                        *(p_rh + 2) |= 0x20;
                                        dsc = 1;
                                        break;
                                       }
                              case PREP_TO_RCV_CONFIRM_LG :
                                       {
                                        *p_rh |= 0x01;
                                        *(p_rh + 1) |= 0xb0;
                                        *(p_rh + 2) |= 0x20;
                                        dsc = 1;
                                        break;
                                       }
                              case Deallocate_confirm :
                                       {
                                        *p_rh |= 0x01;
                                        *(p_rh + 1) |= 0xa0;
                                        *(p_rh + 2) |= 0x01;
                                        dsc = 1;
                                        break;
                                       }
                              case Deallocate_flush :
                                       {
                                        *p_rh |= 0x01;
                                        *(p_rh + 1) |= 0xb0;
                                        *(p_rh + 2) |= 0x01;
                                        dsc = 1;
                                        break;
                                       }
                            }     /* end of switch */

                         t_prf = p_prf;
                         p_prf = p_prf -> next;
                         buffmng( 'D',t_prf,&((*p_rcb).first_out),p_rcb,0,0,0);
		    } while ((p_prf != NULL) && (cnt1 <= cnt) && (dsc == 0 ));

   FULLSG:
        call_appl(p_rqb);
        free(p_sp);

	   } while ( (p_rcb -> first_out) != NULL );


sd_exit:
         switch (rc) {
            case 0 :
                      {
                          p1 = RESET;
                          fsm_error(p1, p_rcb);
                          break;
                      }
            case 1 :
                      {
                          p1 = ALLOC_FAIL_RETRY;
                          fsm_error(p1, p_rcb);
                          break;
                      }
            case 2 :
                      {
                          p1 = ALLOC_FAIL_NO_RETRY;
                          fsm_error(p1, p_rcb);
                          break;
                      }
          }
         return (rc);
}
