 /********************************************************
 *                                                       *
 *                    RMFMH5                             *
 *              processing the FMH-5 by RM               *
 *                                                       *
 * INPUT : "fmhcom" record from PS.                      *
 *                                                       *
 * OUTPUT: the "cma" record to PS.                       *
 *                                                       *
 * CopyRight 1995. Nicholas Poljakov all rights reserved.*
 ********************************************************/
#include <state1.h>
#include <fmhcom.h>
#include <tcb.h>
#include <rcb.h>
#include <scb.h>
#include <fmh5.h>
#include <lucb.h>
#include <arcb.h>
#include <rcballoc.h>
#include <partner.h>
#include <mode.h>
#include <psp.h>
#include <rpl.h>
#include <memory.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

extern struct psp psp_ini;
unsigned long attacheck(void *);
int psrm(int, void *, void *);

unsigned long rmfmh5(s_ptr, ar)
char *s_ptr;
struct cma { /* RM fills this structure */
             struct tcb *p_tcb;
             struct rcb *p_rcb;
           } *ar;
{
    struct tcb *p_tcb;
    struct tcb *temp_tcb;
    struct rcb *p_rcb;
    struct scb *p_scb;
    struct lucb *p_lucb;
    struct fmhcom *p_fmh;
    struct FMH5 *p_fmh5;
    struct pnlu *p_pnlu;
    struct mode *p_mode;
    struct rpl  *p_rpl;
    struct id {
                 char id_n[4];
                 unsigned long id_id;
              } id_ar;
    struct arcb a_rcb;
    struct rcballoc rcb_a;
    char *p;
    unsigned long sense;
    char name[8];
    unsigned int code;
    int i, cnt;

#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, "rmfmh5");
pnum = 1;
drec = ar;
lenr = 10;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

    p_fmh = s_ptr;

    p = p_fmh -> ru;
    if ((sense = attacheck(p)) != OK) {
        goto Ret;
    }

    /*
     * Seek SCB for that LU_NAME
     */

    p_lucb = psp_ini.lucb_list_ptr;
    p_scb = p_fmh -> p_scb;

    /*
     *  Allocate TCB and RCB.
     */
    if (p_scb -> use != FREE) {
        sense = 0x1008600b; /* parallel-session not allow !!!*/
        goto Ret;
    }
    p_scb -> use = IN_USE;
    if (p_lucb -> cur_tps == p_lucb -> max_tps) {
        sense = 0x084b6031; /* Allocation_error--Trans_pgm_not_aval_retry */
        goto Ret;
    }
    if ((p_tcb = calloc(1, sizeof(struct tcb))) == NULL) {
        sense = 0x1008600b; /* SCB was not found */
        goto Ret;
    }
    p_lucb -> cur_tps++;
    if (p_lucb -> tcb_list_ptr == NULL) {
       p_lucb -> tcb_list_ptr = p_tcb;
    }
    else
    {
       temp_tcb = p_lucb -> tcb_list_ptr;
       while (temp_tcb -> next != NULL) {
           temp_tcb = temp_tcb -> next;
       }
       temp_tcb -> next = p_tcb;
       p_tcb -> prev = temp_tcb;
    }
    p_tcb -> p_lucb = p_lucb;

    /* Set tcb_id */

    memcpy(id_ar.id_n, "TPxx", 4);
    id_ar.id_id = p_tcb;
    memcpy(p_tcb -> tcb_id, &id_ar, 8);

    /* Set tp_name */

    p_fmh5 = p_fmh -> ru;
    p = &(p_fmh5 -> tpname);
    cnt = p_fmh5 -> lntpn;
    memset(p_tcb -> tp_name, 0, 64);
    for (i = 0; i < cnt; i++) {
        p_tcb -> tp_name[i] = *(p + i);
    }

    /* Fill the ALLOCATE_RCB record */

    memcpy(a_rcb.lu_name, p_fmh -> lu_name, 8);
    a_rcb.p_tcb = p_tcb;
    /*
     * Seek partner_lu
     */
    p_pnlu = p_lucb -> pluptr;
    while (p_pnlu != NULL) {
        p_mode = p_pnlu -> m_ptr;
        if (memcmp(p_pnlu -> lu_name, a_rcb.lu_name, 8) == 0) {
            goto here_you_are;
        }
        p_pnlu = p_pnlu -> next;
    }
    if (p_pnlu == NULL) {
        sense = 0x1008600b;
        goto Ret;
    }
here_you_are :
    memcpy(a_rcb.mode_name, p_mode -> name, 8);
    /*
     * the ALLOCATE_RCB record is complete.
     */
    code = ALLOCATE_RCB;
    psrm(code, &a_rcb, &rcb_a);
    if (rcb_a.rc != OK) {
        sense = 0x1008600b;
        goto Ret;
    }
    /*
     * Fill "cma" structure.
     */
    ar -> p_tcb = p_tcb;
    ar -> p_rcb = rcb_a.rcb_ptr;

    /*
     * Set pointer to RCB in SCB
     */
    p_scb -> p_rcb = rcb_a.rcb_ptr;
    p_rcb = rcb_a.rcb_ptr;
    p_rcb -> conv_state = Rcv;   /* New RCB in receive state */
    p_rcb -> p_scb = p_scb;      /* Link to SCB */
    p_rpl = p_scb -> p_rpl;
    p_rcb -> p_partner = p_pnlu; /* Pointer to Partner_LU */
    p_rcb -> sess_corl = p_rpl -> arg;
    /*
     * Set the sense data and return
     */
    sense = 0x00000000;
Ret:
    return(sense);
}
