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

📄 secs2prg.c

📁 SECS I, SECS II协议通讯源码
💻 C
字号:
/*
 * secs2prg.c
 *
 * default service & process program load/save
 * SPs are defined in stream 2,
 * PPs are defined in stream 7
 *
 *
 * Code by David Lindauer, CIMple technologies
 *
 */
#include <string.h>
#include <stdio.h>
#include "menus.h"
#include "secs2.h"
#include "logic.h"

extern FILE *preset_bitfile;
extern char secs_model[SECS2_MODLEN+1];
extern char secs_softrev[SECS2_SOFTLEN+1];
extern int receive_number;
extern BYTE AutoYear[DAYSPERYEAR];
extern BYTE AutoCounts[MaxAutoCycles];
extern ACYCLE AutoCycles[MaxAutoCycles][MaxItemsPerAutoCycle];
extern int auto_happen_limit;
extern BOOL autostart_hold;

/* Used during service program i/o */
static BYTE *ppl_countpos, *ppl_datapos;

// PPID validator for autostart year
BOOL PpvAutoYear(PTEXT ppid)
{
  if (!strncmp(ppid,"AUTOSTART ",10)) {
    if (!strncmp(&ppid[10],"  YEAR",6)) {
      // If we get here we are piddling with the year data
      // so save pointers we need later
      ppl_datapos = (BYTE *) &AutoYear[0];
      return(TRUE);
   }
  }
  return(FALSE);
}
// Process program loader for autostart year
BYTE PplAutoYear(int request)
{
  BYTE retcode = ACKC7_OK;
  uint i;

  switch(request) {
    case PP_LOAD:
            // Send the host the service program
            IF_BINARY(DAYSPERYEAR);
            for (i=0; i< DAYSPERYEAR; i++)
              SB(*(ppl_datapos++));
            break;
    case PP_SEND:
            // Get data from the host
            if (FV(FM_BINARY) != DAYSPERYEAR) {
              // Bad data length, report as an error and pretend we looked
              // at the rest of the stream
              retcode = ACKC7_BADLENGTH;
              receive_number = RECEIVE_COMPLETE;
            }
            else {
              // Start by validating the data
              Secs2bSetBookmark();
              for (i=0; i< DAYSPERYEAR; i++)
                if (RB() > MaxAutoCycles + AU_STOPCYCLE) {
                  retcode = ACKC7_BADFORMAT;
                  receive_number = RECEIVE_COMPLETE;
                  break;
                }
              // And if that's ok get the data, we also make sure there isn't
              // garbage tacked on the end before accepting it
              if ((retcode == ACKC7_OK) && (receive_number == RECEIVE_COMPLETE)) {
                Secs2bRestoreBookmark();
                autostart_hold = TRUE;
                for (i=0; i< DAYSPERYEAR; i++)
                  *(ppl_datapos++) = (BYTE) RB();
                autostart_hold = FALSE;
              }
            }
            break;
  }
  return(retcode);
}
// PPID validator for autostart cycle
BOOL PpvAutoCycle(PTEXT ppid)
{
  int number = 256;

  sscanf(&ppid[14],"%x",&number);

  // OOPS, not a valid cycle number or bad format
  if (strncmp(&ppid[0],"AUTOSTART CYCL",14) || (number >= MaxAutoCycles))
    return(FALSE);

  // Otherwise init for the cycle data
  ppl_countpos = (BYTE *) &AutoCounts[number];
  ppl_datapos = (BYTE *) &AutoCycles[number][0];
  return(TRUE);
}
// Routine to handle CYCLE program requests
BYTE PplAutoCycle(int request)
{
  BYTE retcode = ACKC7_OK;
  uint i, abslength, inlength;

  switch(request) {
    case PP_LOAD:
            // Send the host the service program
            IF_BINARY(*ppl_countpos*sizeof(ACYCLE)+1);
            SB(*ppl_countpos);
            for (i=0; i< *ppl_countpos; i++) {
              int j;
              for (j=sizeof(ACYCLE)-1; j>=0; j--)
                SB(*(ppl_datapos+j));
              ppl_datapos += 4;
            }
            break;
    case PP_SEND:
            // Get data from the host
            abslength = FV(FM_BINARY);
            inlength = RB();
            if ((inlength != (abslength-1)/sizeof(ACYCLE))
                || (inlength >= MaxItemsPerAutoCycle)) {
              // Bad data length, report as an error and pretend we looked
              // at the rest of the stream
              retcode = ACKC7_BADLENGTH;
              receive_number = RECEIVE_COMPLETE;
            }
            else {
              int j;
              ACYCLE temp;
              // Start by validating the data
              Secs2bSetBookmark();
              for (i=0; i< inlength; i++) {
                for (j = sizeof(ACYCLE)-1; j>= 0; j--)
                  ((BYTE *)&temp)[j] = (BYTE) RB();
                if ((temp.day >= DAYSPERYEAR) || (temp.min >= 60)
                    || (temp.hr >=24) || (temp.todo >= (uint) auto_happen_limit)) {
                  retcode = ACKC7_BADFORMAT;
                  receive_number = RECEIVE_COMPLETE;
                  break;
                }
              }
              if ((retcode == ACKC7_OK) && (receive_number == RECEIVE_COMPLETE)) {
                // if validated all right update count and data
                autostart_hold = TRUE;
                *ppl_countpos = (BYTE) inlength;
                Secs2bRestoreBookmark();
                for (i=0; i< inlength; i++) {
                  for (j=sizeof(ACYCLE)-1; j>= 0; j--)
                    *(ppl_datapos+j) = (BYTE) RB();
                  ppl_datapos += 4;
                }
                autostart_hold = FALSE;
              }
            }
            break;
  }
  return(retcode);
}
// PPID validator for a save file request
BOOL PpvSaveFile(PTEXT ppid)
{
  int number = 256;

  sscanf(&ppid[14],"%x",&number);

  // OOPS, not a valid cycle number or bad format
  if (strncmp(&ppid[0],"SAVED NAMES   ",14) || (number >= MaxSavedPresetFiles))
    return(FALSE);

  // Otherwise init for the cycle data
  ppl_countpos = (BYTE *) number;
  return(TRUE);
}
// Process program loader for autostart year
BYTE PplSaveFile(int request)
{
  BYTE retcode = ACKC7_OK;
  int i, number = (int) ppl_countpos;

  switch(request) {
    case PP_LOAD: {
              // Send data to the host
              int length;
              // Get the program length, 0 = no program
              if (!(length = (int)PresetFileLength(number)))
                if (PresetReadOpen(number)) {
                  // Send out the model & revision number
                  for (i=0; i< SECS2_MODLEN; i++)
                    SB(secs_model[i]);
                  for (i=0; i< SECS2_SOFTLEN; i++)
                    SB(secs_softrev[i]);
                  // Assume is less than 4G!, read the file & send it out
                  // Note this does not keep either the save_id or the checksum!
                  IF_BINARY(length);
                  for (i=0; i<length; i++);
                    SB((BYTE)ByteIn(preset_bitfile));
                  PresetFileClose();
                }

                else
                  // File has bad format
                  IF_BINARY(0);
              else
                // File not there
                IF_BINARY(0);
            }
            break;
    case PP_SEND: {
              int length;
              CTEXT temp[1+MAX(SECS2_SOFTLEN, SECS2_MODLEN)];

              // Get length from the host, ensure there is a header
              if ((length = FV(FM_BINARY) - SECS2_MODLEN - SECS2_SOFTLEN -2) > 0) {
                // Validate the modlen & softlen
                for (i=0; i< SECS2_MODLEN; i++)
                  temp[i] = (BYTE) RB();
                if (!strncmp(temp, secs_model, SECS2_MODLEN)) {
                  for (i=0; i< SECS2_SOFTLEN; i++)
                    temp[i] = (BYTE) RB();
                  if (!strncmp(temp, secs_softrev, SECS2_SOFTLEN)) {
                    // Validated ok, open the file
                    if (PresetWriteOpen(number)) {
                      // File opened ok, write it & close it
                      for (i=0; i< length; i++)
                        ByteOut(RB(), preset_bitfile);
                      PresetFileClose();
                    }
                    else {
                      // Can't open file
                      receive_number = RECEIVE_COMPLETE;
                      retcode = ACKC7_NOT_GRANTED;
                    }
                  }
                  else {
                    // Bad softrev
                    receive_number = RECEIVE_COMPLETE;
                    retcode = ACKC7_BADFORMAT;
                  }
                }
                else {
                  // Bad model
                  receive_number = RECEIVE_COMPLETE;
                  retcode = ACKC7_BADFORMAT;
                }
              }
              else {
                // too short
                receive_number = RECEIVE_COMPLETE;
                retcode = ACKC7_BADLENGTH;
              }
            }
            break;
  }
  return(retcode);
}

⌨️ 快捷键说明

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