/*

                     RCB_ALLOCATED

     Perfoms further processing of the ALLOCATE request.
     It is invoked when PS receives an RCB_ALLOCATED
     recod  from RM.

  CopyRight 1995. Nicholas Poljakov all rights reserved.

 */

#include <stdio.h>
#include <malloc.h>
#include <alloc.h>
#include <tcb.h>
#include <mode.h>
#include <lucb.h>
#include <arcb.h>
#include <state1.h>
#include <rcballoc.h>
#include <rcb.h>
#include <fmh5.h>
#include <string.h>
int sk_r_wt(void *);
int SendBlock(void *, void *);
int setrc(void *, void *);
int sendhsf(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 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 *);

ralloc(rcb_alloc, pptr)
struct rcballoc *rcb_alloc;
struct allocate *pptr;
{
   char p1;
   char p2;
   struct rcb *rcb_ptr;
   struct FMH5 *hdr;
/*   struct LUOW1 *lu_ptr; */
   char *header;
   int  tpn_lt;
/*   int  fq_lu;   */
   char *p;
   int  i;
   int  tl;
   unsigned int type;

#if OS_TYPE == 1
/*********  Trace facility **********/
unsigned int rtype;   /* type of record */
unsigned int pnum;    /* point number */
char pname[8];        /* name of module */
char *drec;       /* record for dump */
int  lenr;            /* record length */

rtype = INPROC;
strcpy(pname, "ralloc");
pnum = 1;
lenr = sizeof(struct rcballoc);
drec = rcb_alloc;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

   rcb_ptr = rcb_alloc->rcb_ptr;

   switch (rcb_alloc -> rc) {
        case OK :
                {
                   pptr->prim_rc = OK;
                   p1 = 'S';
                   p2 = Allocate;
                   fsm_conv(p1, p2, rcb_ptr);
                   pptr->conv_id = rcb_ptr->rcb_id;

               /*  Initialize allocated RCB */

                   rcb_ptr->fill = 0;
                   rcb_ptr->max_length = MAX_LEN;
                   rcb_ptr->locks = SHORT;
                   rcb_ptr->verb_code = Allocate;
                   rcb_ptr->verb_ptr = pptr;

               /* Build the FMH-5 (attach) header */

                  tpn_lt = pptr -> tp_lt;
                  tl = sizeof(struct FMH5) + tpn_lt;
                  if ((header = calloc(1, tl)) == NULL) {
                     printf("Allocation corrupted. Ralloc/n");
                     return(-1);
                  }
		  hdr = (struct FMH5 *)header;
                  hdr -> length = tl;
                  hdr->flag1 = 0;
                  hdr->flag1 = hdr->flag1|FM5TYPE5;
                  hdr->type[0] = 2;
                  hdr->type[1] = 0xff;
                  hdr->flag2 = 0; /*PIP not present */
                  hdr->rsctp = FM5BASIC; /* basic conv.*/
                  hdr->rsrv1 = 0;
                  hdr->flag3 = FM5NONE; /*sync. level */
                  hdr->lntpn = tpn_lt;
                  hdr->lnflp = 3;
                  p = &(*hdr).tpname;
                  for (i = 0; i < tpn_lt; i++) {
                       p[i] = pptr -> tp_name[i];
                  }
                  p[i] = 0x00;  /* Lenth access sec. subfields */

              /* Set fully qualified Lu network name
               * Next sets fields LUOW, used only in
               * sync. point level.

                  fq_lu = 8 + 2;
                  lu_ptr = &p[i + 1];
                  lu_ptr -> lnfqn = fq_lu - 1;
                  lu_ptr -> lnluw = fq_lu;
                  lu_ptr -> fqnam = 0x04;   SLU identifier (why SLU ?)                  p = &(*lu_ptr).fqnam;
                  p++;
                  for (i = 0; i < fq_lu - 1; i++) {
                       p[i] = pptr -> p_lu_name[i];
                  }
              */

              /* Fill buffer pool with FMH-5 and ALLOCATE data */
                  p1 = 'A';
                  type = Fmh;
                  buffmng(p1, hdr, NULL, rcb_ptr, tl, 0, type);

                  if (pptr->return_control == WHEN_SESSION_ALLOCATED) {
                    p1 = ATTACH;
                    switch (obtsess(rcb_ptr, p1)) {
                        case 0  : {
                                     pptr -> prim_rc = OK;
                                     break;
                                  }
                        case -1 : {
                                     pptr -> prim_rc = ALLOCATION_FAILURE_NO_RETRY;
                                     break;
                                   }
                        case -2 :  {
                                     pptr -> prim_rc = SYNC_LEVEL_NOT_SUPPORTED;
                                     break;
                                   }
                    }
                  }
                  goto norm_exit;
                }
        case UNSUCCESSFUL :
                {
                    pptr->prim_rc = UNSUCCESSFUL;
                    return(0);
                }
        case SYNC_LEVEL_NOT_SUPPORTED :
                {
                    p1 = 's';
                    p2 = Allocate;
                    fsm_conv(p1, p2, rcb_ptr);
               /*  Initialize allocated RCB */

                   rcb_ptr->fill = 0;
                   rcb_ptr->max_length = MAX_LEN;
                   rcb_ptr->locks = SHORT;
                   rcb_ptr->verb_code = Allocate;
                   rcb_ptr->verb_ptr = pptr;

                   p1 = 'r';
                   p2 = ALLOCATION_ERROR_RC;
                   fsm_conv(p1, p2, rcb_ptr);
                   pptr->sec_rc = SYNC_LEVEL_NOT_SUPPORTED_BY_LU;
                   break;
                }

    }
                 pptr->prim_rc = ALLOCATION_ERROR;
                 p1 = 'r';
                 p2 = ALLOCATION_ERROR_RC;
                 fsm_conv(p1, p2, rcb_ptr);
    norm_exit :  return(0);
}
