Example #1
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;
}
Example #2
0
void
gcd_msg_cursor( GCD_CCB *ccb )
{
    DAM_ML_CUR	cursor;
    STMT_ID	stmt_id;
    GCD_SCB	*scb;
    GCD_PCB	*pcb;
    STATUS	status;
    u_i2	pos_anchor = MSG_POS_CURRENT;	/* Default to NEXT */
    i4		pos_offset = 1;
    u_i4	pre_fetch = 1;
    bool	incomplete = FALSE;
    bool	got_id = FALSE;

    if ( ! gcd_get_i2( ccb, (u_i1 *)&cursor.cursor_op ) )
    {
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD no cursor op specified\n", ccb->id );
	gcd_sess_abort( ccb, E_GC480A_PROTOCOL_ERROR );
	return;
    }

    if ( GCD_global.gcd_trace_level >= 3 )
	TRdisplay( "%4d    GCD Cursor operation: %s\n", 
		   ccb->id, gcu_lookup( curMap, cursor.cursor_op ) );

    if ( ! (pcb = gcd_new_pcb( ccb ))  ||
         ! (pcb->rcb = gcd_new_rcb( ccb, -1 )) )
    {
	if ( pcb )  gcd_del_pcb( pcb );
	gcd_sess_abort( ccb, E_GC4808_NO_MEMORY );
	return;
    }

    while( ccb->msg.msg_len )
    {
	DAM_ML_PM	cp;
	u_i1		u_i1_val;
	u_i2		u_i2_val;
	u_i4		u_i4_val;

	incomplete = TRUE;
	if ( ! gcd_get_i2( ccb, (u_i1 *)&cp.param_id ) )  break;
	if ( ! gcd_get_i2( ccb, (u_i1 *)&cp.val_len ) )  break;

	switch( cp.param_id )
	{
	case MSG_CUR_STMT_ID :
	    if ( cp.val_len != (CV_N_I4_SZ * 2)  ||
	         ! gcd_get_i4( ccb, (u_i1 *)&stmt_id.id_high )  ||
		 ! gcd_get_i4( ccb, (u_i1 *)&stmt_id.id_low ) )
		break;

	    incomplete = FALSE;
	    got_id = TRUE;
	    break;
	
	case MSG_CUR_PRE_FETCH :
	    switch( cp.val_len )
	    {
	    case 1 : 
		if ( gcd_get_i1( ccb, (u_i1 *)&u_i1_val ) )
		{
		    pre_fetch = max( pre_fetch, u_i1_val );
		    incomplete = FALSE;
		}
		break;

	    case 2 :
		if ( gcd_get_i2( ccb, (u_i1 *)&u_i2_val ) )
		{
		    pre_fetch = max( pre_fetch, u_i2_val );
		    incomplete = FALSE;
		}
		break;

	    case 4 :
		if ( gcd_get_i4( ccb, (u_i1 *)&u_i4_val ) )
		{
		    pre_fetch = max( pre_fetch, u_i4_val );
		    incomplete = FALSE;
		}
		break;
	    }
	    break;

	case MSG_CUR_POS_ANCHOR :
	    switch( cp.val_len )
	    {
	    case 1 : 
		if ( gcd_get_i1( ccb, (u_i1 *)&u_i1_val ) )
		{
		    pos_anchor = (u_i2)u_i1_val;
		    incomplete = FALSE;
		}
		break;

	    case 2 :
		if ( gcd_get_i2( ccb, (u_i1 *)&u_i2_val ) )
		{
		    pos_anchor = (u_i2)u_i2_val;
		    incomplete = FALSE;
		}
		break;

	    case 4 :
		if ( gcd_get_i4( ccb, (u_i1 *)&u_i4_val ) )
		{
		    pos_anchor = (u_i2)u_i2_val;
		    incomplete = FALSE;
		}
		break;
	    }
	    break;

	case MSG_CUR_POS_OFFSET :
	    if ( cp.val_len != CV_N_I4_SZ  ||
		 ! gcd_get_i4( ccb, (u_i1 *)&pos_offset ) )
		break;

	    incomplete = FALSE;
	    break;
	
	default :
	    if ( GCD_global.gcd_trace_level >= 3 )
		TRdisplay( "%4d    GCD     unkown parameter ID %d\n",
			   ccb->id, cp.param_id );
	    break;
	}

	if ( incomplete )  break;
    }

    if ( incomplete )
    {
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD unable to read all cursor parameters %d\n",
		       ccb->id );
	status = E_GC480A_PROTOCOL_ERROR;
    }
    else  if ( ! got_id )
    {
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD no cursor ID for cursor message\n", 
			ccb->id );
	status = E_GC480A_PROTOCOL_ERROR;
    }
    else
	status = OK;

    if ( status != OK )
    {
	gcd_del_pcb( pcb );
	gcd_sess_abort( ccb, status );
	return;
    }

    if ( ! (scb = gcd_find_stmt( ccb, &stmt_id )) )
    {
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD no active statement for cursor ID\n", 
			ccb->id );
	gcd_sess_error( ccb, &pcb->rcb, E_GC4811_NO_STMT );
	gcd_send_done( ccb, &pcb->rcb, pcb );
	gcd_del_pcb( pcb );
	gcd_msg_pause( ccb, TRUE );
	return;
    }

    switch( cursor.cursor_op )
    {
    case MSG_CUR_CLOSE :
	ccb->sequence = CLOSE_CURSOR;
	pcb->scb = scb;
	crsr_close_sm( (PTR)pcb );
	break;
    
    case MSG_CUR_FETCH :
	ccb->sequence = FETCH_INIT;
	ccb->api.stmt = scb->handle;		/* Activate statement */
	pcb->scb = scb;
	pcb->data.data.reference = pos_anchor;
	pcb->data.data.offset = pos_offset;
	pcb->data.data.max_row = pre_fetch;

	crsr_fetch_sm( (PTR)pcb );
	break;

    default :
	if ( GCD_global.gcd_trace_level >= 1 )
	    TRdisplay( "%4d    GCD invalid cursor op: %d\n", 
			ccb->id, cursor.cursor_op );
	gcd_del_pcb( pcb );
	gcd_sess_abort( ccb, E_GC480A_PROTOCOL_ERROR );
    }

    return;
}