 /********************************************************
 *                                                       *
 *         Process RECords from HS                       *
 *                                                       *
 *  This subroutine will be invoked upon receiving the   *
 *  FMH-5 or FMH-7 records.                              *
 *                                                       *
 * INPUT : pointer to "segprf" structure.                *
 *                                                       *
 * CopyRight 1995. Nicholas Poljakov all rights reserved.*
 *                                                       *
 ********************************************************/
#include <stdio.h>
#include <malloc.h>
#include <fmhcom.h>
#include <fmh7.h>
#include <scb.h>
#include <rcb.h>
#include <lucb.h>
#include <psp.h>
#include <include.h>
#include <rpl.h>
#include <string.h>
#include <state1.h>

#define TYPE5 5
#define TYPE7 7

struct psp psp_ini;
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 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 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 pfmh7(void *);

phsrec(s_ptr)
char *s_ptr;
{
    struct FMH7 *p_fmh7;
    struct segprf *p_sp;
    struct rqb *p_rqb;
    struct lucb *p_lu;
    struct scb *p_scb;
    struct rpl *p_rpl;
    struct rcb *p_rcb;
    struct fmhcom *p_fmh;
    unsigned char p;
    unsigned char p1;
    int i;

#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, "phsrec");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

    p_sp = (struct segprf *)s_ptr;
    p_rqb = (char *)s_ptr + 12;

    /* Search for the SCB and the RCB for that request */

    p_lu = psp_ini.lucb_list_ptr;
    p_scb = p_lu -> scb_list;
    while (p_scb != NULL) {
        if ((i = memcmp(p_rqb -> th.ra.wa.area, p_scb -> lu_name, 8)) == 0) {
            break;
        }
        p_scb = p_scb -> next;
    }
    if (p_scb == NULL) {
        return (-1); /* SCB not found! */
    }

    if ((p_fmh = calloc(1, sizeof(struct fmhcom))) == NULL) {
        return (-2); /* Can't allocate memory */
    }
    p_fmh7 = (char *)s_ptr + 31;
    p_fmh -> ru = p_fmh7;
    p_fmh -> lu_name = &((*p_rqb).th.ra.wa.area);
    p_fmh -> p_scb = p_scb;
    p = p_fmh7 -> type;
    p = p & 0x7f;

    switch (p) {
        case TYPE5 :
                     {
                        pfmh5(p_fmh);
                        break;
                     }
        case TYPE7 :
                     {
                        pfmh7(p_fmh);
                        break;
                     }
        default :
                     {
                        /* Invalid header */
                        p_rcb = p_scb -> p_rcb;
                        if (p_rcb != NULL) {
                            p1 = ALLOC_FAIL_NO_RETRY;
                            fsm_error(p1, p_rcb);
                        }
                        p_rpl = p_scb -> p_rpl;
                        clsdst(p_rpl);
                        free(p_rpl);
                        p_scb -> p_rpl = NULL;
                        p_scb -> p_rcb = NULL;
                        p_scb -> use = FREE;
                     }
     }
     free(p_fmh);
     return (0);
}
int pfmh7(s_ptr)
char *s_ptr;
{
    struct fmhcom *p_fmh;
    struct FMH7 *p_fmh7;
    struct scb *p_scb;
    struct rcb *p_rcb;
    struct lucb *p_lucb;
    char p1;
    unsigned long sense;

    p_fmh = (struct fmhcom *)s_ptr;
    p_fmh7 = (struct FMH7 *)p_fmh -> ru;
    p_scb = p_fmh -> p_scb;
    p_lucb = psp_ini.lucb_list_ptr;
    p_rcb = p_scb -> p_rcb;
    if (p_rcb == NULL) {
        return;
    }
    /*
     * RCB has been found
     */
#if OS_TYPE == 0 /* MS-DOS */
    post_rcb(p_rcb);  /* break out post state */
    p1 = p_fmh7 -> sense[0];
    p_fmh7 -> sense[0] = p_fmh7 -> sense[3];
    p_fmh7 -> sense[3] = p1;
    p1 = p_fmh7 -> sense[1];
    p_fmh7 -> sense[1] = p_fmh7 -> sense[2];
    p_fmh7 -> sense[2] = p1;
#endif
    memcpy(&sense, p_fmh7 -> sense, 4);
        if((sense == 0x1008600b) ||
           (sense == 0x08640000) ||
           (sense == 0x08640001) ||
           (sense == 0x08640002) ||
           (sense == 0x08890000) ||
           (sense == 0x08890001))
                          {
                            p1 = CONV_FAIL_PROTOCOL;
                            fsm_error(p1, p_rcb);
                            p_rcb -> sense = sense;
                            goto pfmh_exit;
                          }
        if((sense == 0x10086041))
                          {
                            p1 = SYNC_LEVEL_NOT_SUPPTD;
                            fsm_error(p1, p_rcb);
                            goto pfmh_exit;
                          }
        if((sense == 0x10086021) ||
           (sense == 0x10086031) ||
           (sense == 0x10086032) ||
           (sense == 0x084b6031))
                          {
                            p1 = ALLOC_FAIL_RETRY;
                            fsm_error(p1, p_rcb);
                            goto pfmh_exit;
                          }
        if((sense == 0x10086034) ||
           (sense == 0x080f6051) ||
           (sense == 0x084c0000))
                          {
                            p1 = ALLOC_FAIL_NO_RETRY;
                            fsm_error(p1, p_rcb);
                            goto pfmh_exit;
                          }
        p1 = CONV_FAIL_SON;
        fsm_error(p1, p_rcb);

    pfmh_exit:
	       return 0;
}
