⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stream5.c

📁 SECS I, SECS II协议通讯源码
💻 C
字号:
/*
 * stream 5.c
 *
 * SECS2 alarm functionality
 *
 * Code by David Lindauer, CIMple technologies
 *
 */
#include "secs2.h"
#include <string.h>

extern SA_STRUC secs_alarmlist[];
extern int enquire_list[NUMBER_ENQUIRIES];
extern uint language;
extern BOOL communicating;
extern BOOL send_nothing;

/* Number of alarms */
static int number_alarms;

/* ALARM REPORT SEND,
 * Note that this one is sent asynchronously from the equipment
 */
static void S5f1(void)
{
  int i;

  for (i=0; i<number_alarms; i++) {
    if ((BOOL)(secs_alarmlist[i].alstate) != *secs_alarmlist[i].value) {
      // Something has changed, register it
      secs_alarmlist[i].alstate = (BYTE) *secs_alarmlist[i].value;
      if (secs_alarmlist[i].enabled &&
          (secs_alarmlist[i].alstate || secs_alarmlist[i].clearable)) {
        int temp;

        // Can't send alarm if disabled or just went off and is not clearable
        // But if we are here we can send it, so lock out parsing responses
        // from the host
        Secs2LockSend();

        // Initialize the send header for this stream and func
        Secs2bInitheader(TRUE,TRUE,ST_ALARMS,SA_REPORT);

        // Send the data as per the specs
        IF_LIST(3);
        IF_BINARY(1);
        SB((BYTE)((secs_alarmlist[i].alstate ? 0x80 : 0x00)
                + secs_alarmlist[i].alcd));
        IF_UWORD(1);
        SW(i);
        IF_ASCII(temp = MIN(40,strlen(secs_alarmlist[i].text[language])));
        SA(secs_alarmlist[i].text[language],temp);

        // Mark the data as sendable and release the lock
        Secs2bFlagSent();
        Secs2UnlockSend();
        break;
      }
    }
  }
}
/* ALARM REPORT ACKNOWLEDGE,
 * Note this is required to be sent by the host in the specs.
 * The SECS1 MRA routines will notify the host if he doesn't send it,
 * Here we just peek at the values and send an error on bad format
 * Picky, picky picky!
 */
static void S5f2(void)
{
  send_nothing = TRUE;
  if (FV(FM_BINARY) != 1)
    Secs2BaddataError();
  // If the following is non-zero there was an error, but we don't check
  RB();

}
// Enable/disable alarm send
static void S5f3(void)
{
  int i, pos, aled, alid;
  BYTE retcode = ACKC5_ACCEPTED;

  // Check the format
  if ((pos = FV(FM_LIST)) != 2)
    Secs2BaddataError();
  if ((pos = FV(FM_BINARY)) != 1)
    Secs2BaddataError();
  aled = RB() & ALED_ENABLE;
  if ((pos = FV(FM_UWORD)/2) == 0)
    alid = -1;
  else
    if (pos == 1)
      alid = RW();
    else
      Secs2BaddataError();

  // BAD ALID
  if (alid >= number_alarms)
    // Error if invalid ALID
    retcode = ACKC5_UNACCEPTED;
  else
    if (alid == -1)
      // ALID had zero length, change all according to aled
      for (i=0; i<number_alarms; i++)
        if (aled)
          secs_alarmlist[i].enabled = TRUE;
        else
          secs_alarmlist[i].enabled = FALSE;
    else
        // There was an ALED, change just that one
        if (aled)
          secs_alarmlist[alid].enabled = TRUE;
        else
          secs_alarmlist[alid].enabled = FALSE;

  // Put out return code
  IF_BINARY(1);
  SB(retcode);
}
// List Alarms Request
static void S5f5(void)
{
  int i,entries;

  // Verify format and read in entries
  entries = FV(FM_UWORD)/2;
  if (entries > NUMBER_ENQUIRIES)
    Secs2ToomuchdataError();

  for (i=0; i<entries; i++)
    enquire_list[i] = RW();

  // If no request, send all
  if (entries == 0) {
    IF_LIST(number_alarms);
    for (i=0; i<number_alarms; i++) {
      int temp;
      IF_LIST(3);
      secs_alarmlist[i].alstate = (BYTE) *secs_alarmlist[i].value;
      IF_BINARY(1);
      SB((BYTE)((secs_alarmlist[i].alstate ? 0x80 : 0x00)
              + secs_alarmlist[i].alcd));
      IF_UWORD(1);
      SW(i);
      IF_ASCII(temp = MIN(40,strlen(secs_alarmlist[i].text[language])));
      SA(secs_alarmlist[i].text[language],temp);
    }
  }
  else {
    // Send data according to specs
    IF_LIST(entries);
    for (i=0; i<entries; i++) {
      int temp,thisentry;
      thisentry = enquire_list[i];
      IF_LIST(3);
      if (thisentry >= number_alarms) {
        // Invalid request, send zero length data
        IF_BINARY(0);
        IF_UWORD(1);
        SW(thisentry);
        IF_ASCII(0);
      }
      else {
        // Valid request, pull data from tables
        secs_alarmlist[thisentry].alstate = (BYTE) *secs_alarmlist[thisentry].value;
        IF_BINARY(1);
        SB((BYTE)((secs_alarmlist[thisentry].alstate ? 0x80 : 0x00)
                + secs_alarmlist[thisentry].alcd));
        IF_UWORD(1);
        SW(thisentry);
        IF_ASCII(temp = MIN(40,strlen(secs_alarmlist[thisentry].text[language])));
        SA(secs_alarmlist[thisentry].text[language],temp);
      }
    }
  }
}
// List enabled alarm request
static void S5f7(void)
{
  int i,count=0;

  // Make sure there is only a header
  Secs2CheckHeaderOnly();

  // Count number of alarms we will send
  for (i=0; i< number_alarms; i++)
    if (secs_alarmlist[i].enabled)
      count++;

  IF_LIST(count);
  if (count)
    for (i=0; i<number_alarms; i++)
      if (secs_alarmlist[i].enabled) {
        int temp;
        // Register the state, now S5F1 will not send the alarm
        secs_alarmlist[i].alstate = (BYTE) *secs_alarmlist[i].value;
        // Send the data off according to the specs
        IF_LIST(3);
        IF_BINARY(1);
	SB((BYTE)((secs_alarmlist[i].alstate ? 0x80 : 0x00)
                + secs_alarmlist[i].alcd));
        IF_UWORD(1);
        SW(i);
        IF_ASCII(temp = MIN(40,strlen(secs_alarmlist[i].text[language])));
        SA(secs_alarmlist[i].text[language],temp);
      }
}
// List of all valid stream five functions
static PASSFUNC Stream5funcs[] = {
  { SA_ALMACK, S5f2 },
  { SA_ENABLE, S5f3 },
  { SA_REQUEST, S5f5 },
  { SA_LISTENABLED, S5f7 },
  { 0, 0 } };

/* Function handler dispatch */
void Stream5(int number)
{
  Secs2FuncDispatch(number, Stream5funcs);
}
/* Stream 5 init routine
* Count the number of alarm specifiers
*/
void Stream5Init(BOOL power_up)
{
  BOOL done = FALSE;

  if (power_up) {
    number_alarms = 0;
    while (!done)
      if (secs_alarmlist[++number_alarms].text == 0)
        done = TRUE;
  }
}
/*
* A seperate process to monitor changing alarm values and notify host
* dynamically
*/
void AlarmSendoff(void)
{
  while(TRUE) {
    Pause();
    // IF establish communications is working we are communicating
    if (communicating)
      S5f1();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -