Subversion Repositories factorylink.mb_plus

Rev

Blame | Last modification | View Log | Download

/*
 ******************************************************************************
 *  Copyright 1995 DeltaLink b.v. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Mailbox Communication Interface
 *
 * File         :   mciq.c
 *
 * Version      :   3.00
 * 
 * Developed by :   Leon Westervoort.
 *
 */

#include  <stdlib.h>
#include  <string.h>
#include  <stdio.h>
#include  <stdarg.h>

#include  <flib.h>                  /* FactoryLink definitions */

#include  <mci3.h>                  /* Mailbox Communication Interface definitions */
#include  <mci3_int.h>              /* Mailbox Communication Interface definitions */
#include  <format3.h>               /* Mailbox Communication Interface definitions */


/*
 * FUNCTION:  Mci_Q_Init
 *
 * PURPOSE:   Initialize the queue by removing every message exept for query messages.
 *            The number of active elements in the queue will always be set to 0 so
 *            that the query commands will be handled.
 *
 */
int Mci_Q_Init( MCISYSTEM *system )
{
  MBXMSG  *msg;
  int     
          ret;
  uint    i,
          index,
          num,
          num_ret;

  /* determine the number of elements in the queue */

  if( ( ret = Mci_Q_Num( system, &num )) != GOOD )
    return ret;

  if( !num ) return GOOD;

  /* allocate mailbox messages to hold information */

  if( ( msg = ( MBXMSG *)calloc( num, sizeof( MBXMSG))) == NULL)
    return FLE_OUT_OF_MEMORY;

  /* query all messages from the queue at once */

  if( fl_query_mbx( system->task_id,
                    system->mbx,
                    msg,
                    0,
                    num,
                    &num_ret) == ERROR) {

    free( msg);
    return fl_errno( system->task_id);
  }

  /*
   * process all messages that have been read
   */
  for( i = index = 0; i < num_ret; i++) {

    /* check if the message is a query and if so leave it in the queue */

    if( (( MCITYPE *)&msg[ i].mm_type)->type == MCI_QUERY_CMD) {
    
      index++;
      continue;
    }

    /* remove the message from the queue */

    if( fl_read_app_mbx( system->task_id,
                         system->task_id,
                         system->mbx,
                         &msg[ i],
                         index) != GOOD) {

      free( msg);

      return fl_errno( system->task_id);
    }
  }

  free( msg);

  return GOOD;
}

/*
 * FUNCTION:  Mci_Q_Query
 *
 * PURPOSE:   This function gets all information about the message in the receive
 *            mailbox specified by the index parameter in the MCIMSG structure except for
 *            the data. Only active MCI message can be queried with this function.
 *
 */
int Mci_Q_Query( MCISYSTEM *system, MCIDS *ds )
{
  /*
   * check first if an active message will be queried
   */
  if( ds->msg.i >= _Mci_q_num_active)
    return MCI_WRONG_INDEX;

  return Mci_Qi_Query( system, ds);
}

/*
 * FUNCTION:  Mci_Qi_Query
 *
 * PURPOSE:   This function gets all information about the message in the receive
 *            mailbox specified by the index parameter in the MCIMSG structure except for
 *            the data.
 *
 */
int Mci_Qi_Query( MCISYSTEM *system, MCIDS *ds )
{
  uint nr;

  /*
   * do the FactoryLink query
   */
  if( fl_query_mbx( system->task_id,
                    system->mbx,
                    &ds->msg.mbx,
                    ds->msg.i,
                    1,
                    &nr) != GOOD)
    return fl_errno( system->task_id);

  if( !nr ) return MCI_NO_QUERY;

  return GOOD;
}

/*
 * FUNCTION: Mci_Q_Num
 *
 * PURPOSE: This function gets the number of message in the receive mailbox.
 *
 */
int Mci_Q_Num( MCISYSTEM *system, uint *np )
{
  /*
   * do the FactoryLink count
   */
  if( fl_count_mbx( system->task_id,
                    system->mbx,
                    np ) != GOOD )
    return fl_errno( system->task_id );

  return GOOD;
}

/*
 * FUNCTION:  Mci_Q_Ds_Num_Srch
 *
 * PURPOSE:   Check if there are message present in the mailbox queue with the same 
 *            MCI message control tag and MCI type. This function searches only the
 *            active MCI messages currently present in the queue.
 *
 */
int Mci_Q_Ds_Num_Srch( MCISYSTEM *system, MCIDS *local, uint n )
{
  MBXMSG  *msgen;                         /* pointer to array to hold all messages */
  TAG     cmp_ds;
  uint    nr, 
          i;

  /* allocate mailbox message to hold information */

  if( ( msgen = ( MBXMSG *)calloc( n, sizeof( MBXMSG))) == NULL)
    return FLE_OUT_OF_MEMORY;

  /* read mailbox message information */

  if( fl_query_mbx( system->task_id,
                    system->mbx,
                    msgen,                  /* pointer to array of messages */
                    0,                      /* index in queue */
                    n,      /* number of msg to read */
                    &nr) == ERROR) {

    free( msgen);
    return fl_errno( system->task_id);
  }

  /* search for the dataset control tag with the same type*/

  for( i = local->msg.i; i < nr; i++) {

    /* check first were the dataset came form */

    if( Mci_Get_Station_Id( local) != ( uchar)(( MCITYPE *)&msgen[ i].mm_type)->station_id)
      cmp_ds = _Mci_R_ds[ local->ds_index];
    else
      cmp_ds = _Mci_L_ds[ local->ds_index];

    /* compare the two MBXCTRL Tags */

    if( ( MCI_CMPTAG( &cmp_ds, ( TAG *)&msgen[ i].mm_user2) == GOOD ) &&
        ( Mci_Get_Type( local) == (( MCITYPE *)&msgen[ i].mm_type)->type )
      ) {

      Mci_Set_Index( local, i);

      free( msgen);

      return GOOD;
    }
  }

  free( msgen);

  return MCI_NOT_FOUND;
}

/*
 * FUNCTION:  Mci_Q_Ds_Tot_Srch
 *
 * PURPOSE:   Check if there are message present in the mailbox queue with the same 
 *            MCI message control tag and MCI type. This function searches only the
 *            active MCI messages currently present in the queue.
 *
 */
int Mci_Q_Ds_Tot_Srch( MCISYSTEM *system, MCIDS *local )
{
  uint    num;
  int     ret;

  /* first check on the amount of messages present in queue */

  if( ( ret = Mci_Q_Num( system, &num)) != GOOD)
    return ret;

  if( num == 0) return FLE_NO_MESSAGES;

  /* call the search function */

  return Mci_Q_Ds_Num_Srch( system, local, num);
}

/*
 * FUNCTION:  Mci_Q_Msg_Remove
 *
 * PURPOSE:   Removes the current MCI message from the queue with
 *            the same index as specified on the dataset. No check on the
 *            dataset will be done, it will be always discarded.
 *
 */
int Mci_Q_Msg_Remove( MCISYSTEM *system, MCIDS *ds )
{
  MSG null_buf;

  /*
   *  check the origination of this dataset and if from a trigger then it does not have to be read
   *  from the mailbox queue
   */
  if( Mci_Get_Org( ds) == MCI_ORG_TRIGGER ||
      Mci_Get_Org( ds) == MCI_ORG_QUERY
    ) 
    return GOOD;

  /*
   * check if the index lies in the range of active MCI messages
   */
  if( Mci_Get_Index( ds) >= _Mci_q_num_active )
    return MCI_WRONG_INDEX;

  /* set a null buffer so the message will be discarded */

  memset( &null_buf, 0x00, sizeof( MSG));

  Mci_Set_T_Buffer( ds, &null_buf);

  /*
   * do the reading from the receive mailbox which is specified in the MCI
   * message 
   */
  if( fl_read_app_mbx( Mci_Sys_Get_Task_Id( system ),
                       Mci_Sys_Get_Task_Id( system ),     /* task id of owner receive mailbox */
                       Mci_Sys_Get_Mbx( system ),         /* mailbox tag to receive from */
                       &ds->msg.mbx,                      /* mailbox message to receive in */
                       ds->msg.i) != GOOD) {              /* index in receive queue */

    return fl_errno( Mci_Sys_Get_Task_Id( system ));
  }

  /* update the number of active messages in the queue */

  _Mci_q_num_active--;

  return GOOD;
}


/*
 * FUNCTION: Mci_Q_Num_Mbx
 *
 * PURPOSE: This function gets the number of message in the receive mailbox.
 *
 */
int Mci_Q_Num_Mbx( MCISYSTEM *system, TAG mbx, uint *np )
{

  /*
   * do the FactoryLink count
   */
  if( fl_count_mbx( system->task_id,
                    mbx,
                    np ) != GOOD )
    return fl_errno( system->task_id );

  return GOOD;
}