Пример #1
0
GCD_RCB *
gcd_new_rcb( GCD_CCB *ccb, i2 len )
{
    GCD_RCB *rcb;

    /*
    ** Adjust length to reserve header space.
    **
    ** The majority of RCB allocations are for default
    ** buffer sizes or no buffers.  Re-use free RCB with
    ** same buffer size if available.
    */
    if ( len == 0 )
	rcb = (GCD_RCB *)QUremove( GCD_global.rcb_q.q_next );
    else  if ( len < 0 )
    {
	/*
	** Use the negotiated TL protocol buffer size from 
	** the CCB (TL header length already included) and
	** provide space for the NL header.
	*/
	len = ccb->max_buff_len + (u_i2)GCD_global.nl_hdr_sz;
	rcb = (GCD_RCB *)QUremove( ccb->rcb_q.q_next );
    }
    else
    {
	/*
	** NL protocol restricts the size of buffers which
	** may be sent.  Provide space for TL header by
	** increasing requested buffer length.  Space is
	** also provided for the NL header.
	*/
	len = min( len + (u_i2)GCD_global.tl_hdr_sz, ccb->max_buff_len ) +
	      (u_i2)GCD_global.nl_hdr_sz;
	rcb = NULL;	/* RCB must be allocated */
    }

    if ( rcb )
	MEfill( sizeof( GCD_RCB ), 0, rcb );
    else
    {
	rcb = (GCD_RCB *)MEreqmem( 0, sizeof( GCD_RCB ) + len, TRUE, NULL );

    	if ( ! rcb )
	{
	    gcu_erlog( 0, GCD_global.language, 
	    	       E_GC4808_NO_MEMORY, NULL, 0, NULL );
	    return( NULL );
	}

	if ( GCD_global.gcd_trace_level >= 6 )
	    TRdisplay( "%4d    GCD new RCB[%d] (%p)\n", ccb->id, len, rcb );
    }

    rcb->ccb = ccb;

    if ( len )
    {
	rcb->buffer = (u_i1 *)rcb + sizeof( GCD_RCB );
	rcb->buf_max = (u_i2)len;
	gcd_init_rcb( rcb );
    }

    return( rcb );
}
Пример #2
0
static void 
dmtl_data( GCD_RCB *rcb )
{
    GCD_CCB	*ccb = rcb->ccb;
    DAM_TL_HDR	hdr;
    STATUS	status = E_GC480A_PROTOCOL_ERROR;
    u_i2	pkt_type;

    /*
    ** Breaking from the switch will shutdown the connection.
    ** If status is not changed, connection will be aborted
    ** with protocol error (set to OK for simple shutdown).
    ** Set the rcb to NULL if not used for new request.
    **
    ** Return directly in the switch for any other result
    ** (but make sure RCB is used or freed).
    */
    switch( (pkt_type = read_hdr( rcb, &hdr )) )
    {
    case DAM_TL_CR :
    case DAM_TL_CC :
    case DAM_TL_DC :
	/*
	** The Connection Request packet is expected only
	** initially and should be passed to dmtl_accept().
	**
	** The Connection Confirm packet is never expected.
	**
	** We only send a Disconnect Request when aborting
	** the connection and we don't wait for a response,
	** so we don't expect a Disconnect Confirmation.
	*/
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD unexpected DMTL packet: 0x%x\n",
		       ccb->id, pkt_type );
	break;

    case DAM_TL_DT : /* Data */
	if ( ccb->tl.msg_service )  
	{
	    if ( GCD_global.gcd_trace_level >= 3 )
		TRdisplay( "%4d    GCD DMTL received data\n", ccb->id );

	    /*
	    ** Pass to MSG Layer and exit successfully.
	    */
	    (*ccb->tl.msg_service->data)( rcb );
	    return;
	}
	break;

    case DAM_TL_INT: /* Interrupt */
	if ( ccb->tl.msg_service )
	{
	    if ( GCD_global.gcd_trace_level >= 3 )
		TRdisplay( "%4d    GCD DMTL interrupt\n", ccb->id );

	    /*
	    ** Notify MSG Layer and exit successfully.
	    ** Need to free RCB as we are expected to
	    ** consume the RCB.
	    */
	    gcd_del_rcb( rcb );
	    (*ccb->tl.msg_service->intr)( ccb );
	    return;
	}
	break;

    case DAM_TL_DR : /* Disconnect */
	if ( ccb->tl.gcc_service )
	{
	    if ( GCD_global.gcd_trace_level >= 3 )
		TRdisplay( "%4d    GCD DMTL disconnecting\n", ccb->id );

	    gcd_init_rcb( rcb );
	    hdr.msg_id = DAM_TL_DC;
	    build_hdr( rcb, &hdr );
	    (*ccb->tl.gcc_service->send)( rcb );
	    rcb = NULL;		/* Passed to GCC */
	    status = OK;	/* Shutdown, don't abort */
	}
	break;

    default : 
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD invalid DMTL packet: ID=0x%x Type=0x%x\n",
		       ccb->id, hdr.tl_id, hdr.msg_id );
	break;
    }

    dmtl_shutdown( ccb, rcb, status );
    return;
}
Пример #3
0
static void
send_dr( GCD_CCB *ccb, GCD_RCB *rcb, STATUS error )
{
    DAM_TL_HDR	hdr;

    if ( ! ccb->tl.gcc_service )	/* Already shutdown? */
    {
	/*
	** Consume RCB if provided.
	*/
	if ( rcb )  gcd_del_rcb( rcb );
	return;
    }

    if ( GCD_global.gcd_trace_level >= 3 )
	TRdisplay( "%4d    GCD DMTL aborting connection: 0x%x\n", 
		    ccb->id, error );

    /*
    ** If RCB provided, initialize since it may 
    ** have contained data.  Allocate otherwise.
    ** Allow room for error parameter.
    */
    if ( rcb )
	gcd_init_rcb( rcb );
    else  if ( ! (rcb = gcd_new_rcb( ccb, (CV_N_I1_SZ * 2) + CV_N_I4_SZ )) )  
	return;

    /*
    ** Return error code to client when provided.
    */
    if ( error != OK  &&  error != FAIL )
    {
	DAM_TL_PARAM	param;
	STATUS		status;

	param.param_id = DAM_TL_DP_ERR;
	CV2N_I1_MACRO( &param.param_id,
		       &rcb->buf_ptr[ rcb->buf_len ], &status );
	rcb->buf_len += CV_N_I1_SZ;
	    
	param.pl1 = CV_N_I4_SZ;
	CV2N_I1_MACRO( &param.pl1,
		       &rcb->buf_ptr[ rcb->buf_len ], &status );
	rcb->buf_len += CV_N_I1_SZ;
		
	CV2N_I4_MACRO( &error, 
		       &rcb->buf_ptr[ rcb->buf_len ], &status );
	rcb->buf_len += CV_N_I4_SZ;
    }

    /*
    ** Add TL packet header and send packet.
    */
    hdr.tl_id = ccb->tl.packet_id;
    hdr.msg_id = DAM_TL_DR;
    build_hdr( rcb, &hdr );
    (*ccb->tl.gcc_service->send)( rcb );

    return;
}
Пример #4
0
static bool
dmtl_accept( GCC_SRVC *gcc_service, GCD_RCB *rcb )
{
    GCD_CCB	*ccb = rcb->ccb;
    DAM_TL_HDR	hdr;
    STATUS	status = OK;
    u_i1	*rcb_ptr;
    u_i4	rcb_len;
    u_i1	*msg_parms = NULL;
    u_i2	msg_len = 0;
    u_i1	size = DAM_TL_PKT_MIN;

    if ( GCD_global.gcd_trace_level >= 4 )
	TRdisplay( "%4d    GCD DMTL testing new connection\n", ccb->id );

    /*
    ** Save RCB settings in case we don't accept
    ** the connection and need to restore the RCB.
    */
    rcb_ptr = rcb->buf_ptr;
    rcb_len = rcb->buf_len;

    /*
    ** Validate the packet header and request type.
    ** If invalid, refuse GCC request.  We accept
    ** both the JDBC TL and DAM-TL packet ID's for
    ** now.  The protocol level parameter will tell
    ** which TL should handle this request.
    */
    read_hdr( rcb, &hdr );
    if ( (hdr.tl_id != DAM_TL_ID_1  &&  hdr.tl_id != DAM_TL_ID_2)  ||  
	 hdr.msg_id != DAM_TL_CR )
    {
	rcb->buf_ptr = rcb_ptr;
	rcb->buf_len = rcb_len;
	return( FALSE );
    }

    /*
    ** Read the TL Connection Request parameters.
    **
    ** The DAM-TL protocol is a super-set of the JDBC TL
    ** protocol.  We should be able to read JDBC connect
    ** parms, so if there is an error we will accept the
    ** GCC connection and then abort the TL connection.
    **
    ** We refuse the connection if the protocol level and
    ** packet header ID indicate that this is for JDBC TL.
    */
    if ( (status = read_cr_parms( rcb, &size, &msg_parms, &msg_len )) == OK  &&
         hdr.tl_id == DAM_TL_ID_1 && ccb->tl.proto_lvl < DAM_TL_PROTO_2 )
    {
	rcb->buf_ptr = rcb_ptr;
	rcb->buf_len = rcb_len;
	return( FALSE );
    }

    /*
    ** We will service this connection from GCC,
    ** though we may detect an error and abort
    ** the client connection.
    **
    ** We must respond to this request with the
    ** same TL packet ID as the original request.
    ** Subsequent packets must have the packet
    ** ID appropriate for the protocol level.
    */
    if ( GCD_global.gcd_trace_level >= 4 )
	TRdisplay( "%4d    GCD DMTL servicing request\n", ccb->id );

    ccb->tl.gcc_service = gcc_service;
    ccb->tl.packet_id = hdr.tl_id;

    /*
    ** Validate connection parameters.
    */
    for( ; status == OK; )
    {
	if ( ccb->tl.proto_lvl < DAM_TL_PROTO_1  ||  size < DAM_TL_PKT_MIN )
	{
	    if ( GCD_global.gcd_trace_level >= 1 )
		TRdisplay( "%4d    GCD invalid param value: (%d,%d)\n",
			   ccb->id, ccb->tl.proto_lvl, size );
	    status = E_GC480A_PROTOCOL_ERROR;
	    break;
	}

	/*
	** Negotiate connection parameters.
	*/
	if ( ccb->tl.proto_lvl > DAM_TL_DFLT_PROTO )
	    ccb->tl.proto_lvl = DAM_TL_DFLT_PROTO;
	if ( size > DAM_TL_PKT_DEF )  size = DAM_TL_PKT_DEF;
	ccb->max_buff_len = 1 << size;

	if ( GCD_global.gcd_trace_level >= 4 )
	{
	    TRdisplay( "%4d        protocol level: %d\n", 
		       ccb->id, ccb->tl.proto_lvl );
	    TRdisplay( "%4d        buffer size: %d\n", 
		       ccb->id, ccb->max_buff_len );
	}

	/*
	** Initialize our MSG Service Provider.
	*/
	if ( (status = (*gcd_dam_service.init)( &dmtl_msg_service, ccb, 
						&msg_parms, &msg_len )) != OK )
	    break;

	/*
	** OK, we are ready to accept the connection.  Inform the GCC
	** Service provider and verify that the connection should be
	** accepted.
	*/
	ccb->tl.msg_service = &gcd_dam_service;
	status = (*gcc_service->accept)( &gcd_dmtl_service, ccb );
	break;
    }

    if ( status != OK )
    {
	if ( GCD_global.gcd_trace_level >= 3 )
	    TRdisplay( "%4d    GCD DMTL rejecting connection: 0x%x\n", 
	    		ccb->id, status );

	dmtl_shutdown( ccb, rcb, status );
    }
    else
    {
	if ( GCD_global.gcd_trace_level >= 3 )
	    TRdisplay( "%4d    GCD DMTL accepting connection\n", ccb->id );

	/*
	** Build and send TL Connection Confirmation packet.
	** We use the same packet header ID as was passed in.
	*/
	gcd_init_rcb( rcb );
	build_cc_parms( rcb, size, msg_parms, msg_len );
	hdr.tl_id = ccb->tl.packet_id;
	hdr.msg_id = DAM_TL_CC;
	build_hdr( rcb, &hdr );
	(*ccb->tl.gcc_service->send)( rcb );
    }

    /*
    ** Subsequent communications must use the packet ID appropriate
    ** for the negotiated protocol level.
    **
    ** Whether the connection was accepted or rejected, we assumed
    ** responsibility for servicing the current request, so return
    ** the appropriate indication.
    */
    ccb->tl.packet_id = DAM_TL_ID_2;
    return( TRUE );
}