半导体:Gem/Secs基本协议库的开发(2)

发布时间:2023年12月17日

距离上一篇 《半导体:Gem/Secs基本协议库的开发(1)》的分享已经过去快一年的时间了,这期间有很多朋友给我留言或者直接私信我需要SEComEnabler.SEComSimulator.exe 模拟调试软件的,本篇仍然要先说一声sorry,不过在下一篇,我举起我的小拇指发誓,一定给大家附上。请添加图片描述
不过本文篇幅会比较长,事情定然没有那么简单。作者在一番思索之后,决定给大家一个完整的项目作为参考。本文将只会在较短的时间内免开,有需要的朋友动动你发财的小手,哈哈!
直接附上源码,上干货!!

【codes】

// JcHsms.pro

QT -= gui

TEMPLATE = lib
DEFINES += JCHSMS_LIBRARY

CONFIG += c++11

CONFIG     += c++11 no_debug_release

win32:CONFIG(release, debug|release){
    DESTDIR     = $${PWD}/../../../../deploy/lib/Release
}
else:win32:CONFIG(debug, debug|release){
    DESTDIR     = $${PWD}/../../../../deploy/lib/Debug
}

OBJECTS_DIR = $${PWD}/../../../../build/$${TARGET}/obj
MOC_DIR     = $${PWD}/../../../../build/$${TARGET}/moc


# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    JcHsms.cpp \
    hsmsdatamanager.cpp \
    hsmsdeviceunique.cpp \
    hsmsmessage.cpp \
    hsmsmessagedispatcher.cpp \
    hsmsmessageheader.cpp \
    secs2item.cpp

HEADERS += \
    JcHsms_global.h \
    JcHsms.h \
    hsmsdatamanager.h \
    hsmsdeviceunique.h \
    hsmsincludes.h \
    hsmsmessage.h \
    hsmsmessagedispatcher.h \
    hsmsmessageheader.h \
    secs2item.h

# Default rules for deployment.
unix {
    target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target
// JcHsms_global.h

/****************************************
 *         JcHsms_gloab
 ****************************************/

#ifndef JCHSMS_GLOBAL_H
#define JCHSMS_GLOBAL_H

#  define Q_DECL_EXPORT __declspec(dllexport)
#  define Q_DECL_IMPORT __declspec(dllimport)

#if defined(JCHSMS_LIBRARY)
#  define JCHSMS_EXPORT Q_DECL_EXPORT
#else
#  define JCHSMS_EXPORT Q_DECL_IMPORT
#endif

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <stack>

/// follows depends on Qt
#include <QByteArray>
#include <QDateTime>
#include <QString>
#include <QDebug>
#include <QSet>
#include <QtEndian>


/*---------------------------------------------------------------------------*/
/*  system header files                                                      */
/*---------------------------------------------------------------------------*/
#if defined(_DEBUG) && defined(WIN32) && defined(LEAK_CHECK)
#define _CRTDBG_MAP_ALLOC
#endif

#if defined(_DEBUG) && defined(WIN32) && defined(LEAK_CHECK)
#include <crtdbg.h>
#endif
#include <ctype.h>
#include <limits.h>
#ifdef _MSC_VER
#include <tchar.h>
#else
typedef char TCHAR;
#define _T(x)        x

#define _stprintf  sprintf
#define _stscanf   scanf
#define _tcscat    strcat
#define _tcschr    strchr
#define _tcsstr    strstr
#define _tcscmp    strcmp
#define _tcscpy    strcpy
#define _tcsdup    strdup
#define _tcsftime  strftime
#define _tcslen    strlen
#define _tcsncpy   strncpy
#define _tcsrchr   strrchr
#define _tcstol    strtol
#define _tcstoul   strtoul
#define _tcstod    strtod
#define _tprintf   printf
#define _ttoi      atoi
#define _vtprintf   vprintf
#define _vstprintf  vsprintf
#define _vsntprintf vsnprintf
#define _sntprintf  snprintf

#endif

#ifdef __GNUC__
/* disable warning for undefined cuserid(); */
#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif
#include <unistd.h>
#endif


/*****************************************************************************/
/*                                                                           */
/*  Symbol                                                                   */
/*                                                                           */
/*****************************************************************************/

/*---------------------------------------------------------------------------*/
/*  Define Driver version                                                    */
/*---------------------------------------------------------------------------*/
#define JC_HSMS_DRIVER_VERSION 1.0.0.20221129_base

/*---------------------------------------------------------------------------*/
/*  Define data types                                                        */
/*---------------------------------------------------------------------------*/
#if !defined(_MSC_VER) && !defined(VOID)
#define VOID    void
//typedef signed char     CHAR;
typedef signed long     LONG;
typedef signed short    SHORT;
#endif

#ifndef NULL
#define NULL    0
#endif

#ifndef UCHAR
typedef signed int      INT;
typedef unsigned char   UCHAR;
typedef unsigned short  USHORT;
typedef unsigned int    UINT;
typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef void *          PTR;
#endif
#ifndef ULONG
typedef unsigned long   ULONG;
#endif

#ifndef BOOLEAN
typedef unsigned char   BOOLEAN;
typedef short           SHORTINT;
typedef long            LONGINT;
typedef unsigned short  SHORTCARD;
typedef unsigned long   LONGCARD;
typedef LONGCARD        CARDINAL;
typedef double          LONGREAL;
typedef LONGINT         INTEGER;
typedef float           REAL;
#endif

#ifdef uchar
typedef unsigned char   uchar;
typedef unsigned char   byte;
typedef unsigned short  word;
typedef unsigned short  ushort;
typedef unsigned int    uint;
typedef unsigned long   ulong;
#endif

#if _MSC_VER
typedef __int64             LONGLONG;
typedef unsigned __int64    ULONGLONG;
#elif __GNUC__
typedef long long           LONGLONG;
typedef unsigned long long  ULONGLONG;
#else
#error no support 64 bit data type; // LongLong ?
#endif

#ifdef BITSET
typedef unsigned long   BITSET;
typedef char * ADDRESS;
typedef int  (*PFI)();                  /* pointer to function returning int */
typedef void (*PFV)();                  /* pointer to function with no return*/

#endif

/*---------------------------------------------------------------------------*/
/*  redefine global tokens                                                    */
/*---------------------------------------------------------------------------*/
#define GLOBAL
#ifndef EXTERN
#define EXTERN       extern
#endif
#define PROTOTYPE    extern

/*----------------------------------------------------------------------------*/
/*  limit values                                                              */
/*----------------------------------------------------------------------------*/
#ifdef MSDOS
#define MAX_INT       32767
#define MAX_UINT      0xFFFF
#define MAX_INTSTR    "32767"
#define MAX_UINTSTR   "65535"
#else
#define MAX_INT       2147483647
#define MAX_UINT      0xFFFFFFFF
#define MAX_INTSTR    "2147483647"
#define MAX_UINTSTR   "4294967295"
#endif

#define MAX_SHORT     32767
#define MAX_LONG      2147483647
#define MAX_USHORT    0xFFFF
#define MAX_ULONG     0xFFFFFFFF
#define MAX_SHORTCARD 0xFFFF
#define MAX_LONGCARD  0xFFFFFFFF
#define MAX_SHORTSTR  "32767"
#define MAX_LONGSTR   "2147483647"
#define MAX_USHORTSTR "65535"
#define MAX_ULONGSTR  "4294967295"
#define MIN_REAL      ((REAL)1.40129846432481707e-45)
#define MAX_REAL      ((REAL)3.40282346638528860e+38)
#define MIN_LONGREAL  4.94065645841246544e-324
#define MAX_LONGREAL  1.79769313486231470e+308
#define MAX_LLSTR     "9223372036854775807"

/*****************************************************************************/
/*  Define ASCII codes                                                       */
/*****************************************************************************/
#ifdef WIN32
#define DIR_SEPARATOR_STRING  _TX("\\")
#define DIR_SEPARATOR_CHAR    '\\'
#else
#define DIR_SEPARATOR_STRING  _TX("/")
#define DIR_SEPARATOR_CHAR    '/'
#endif

#define TAB          '\t'       /* C definition of ASCII tab                 */
#define NEWLINE      '\n'       /* C definition of ASCII newline             */
#define BACKSPACE    '\b'       /* C definition of ASCII backspace           */
#define SPACE        ' '        /* white space character                     */

#define ESC          0x1B       /* Standard definition ASCII escape          */
#define BS           0x08       /* Standard definition ASCII backspace       */
#define CR           0x0D       /* Standard definition ASCII carriage return */
#define FF           0x0C       /* Standard definition ASCII form feed       */
#define BEL          0x07       /* Standard definition ASCII bell            */
#define HT           0x09       /* Standard definition ASCII horizontal tab  */
#define LF           0x0A       /* Standard definition ASCII line feed       */
#define VT           0x0B       /* Standard definition ASCII virtical tab    */
#define SUB          0x1A
#define RS           0x1E

/*****************************************************************************/
/*                                                                           */
/*  function macros                                                          */
/*                                                                           */
/*****************************************************************************/

#ifndef max
#define max(a, b)              ((a) >= (b) ? (a) : (b))
#endif
#ifndef min
#define min(a, b)              ((a) <= (b) ? (a) : (b))
#endif
#ifndef Max
#define Max(a, b)              ((a) >= (b) ? (a) : (b))
#endif
#ifndef Min
#define Min(a, b)              ((a) <= (b) ? (a) : (b))
#endif
#if 0
#ifndef MAX
#define MAX(a, b)              ((a) >= (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b)              ((a) <= (b) ? (a) : (b))
#endif
#ifndef abs
#define abs(n)                 ((n) > 0 ? (n) : -(n))
#endif
#ifndef ABS
#define ABS(n)                 ((n) > 0 ? (n) : -(n))
#endif
#endif

/* word operation */
#define byte_high(a)           (((a) >> 8) & 0x00FF)
#define byte_low(a)            ((a) & 0x00FF)
#define HIGH(c)                (((c) >> 8) & 0x00FF)
#define LOW(c)                 ((c) & 0x00FF)
#define high(c)                (((c) >> 8) & 0x00FF)
#define low(c)                 ((c) & 0x00FF)
#define btow(h,l)              (((WORD)((BYTE)(h)) << 8) | (BYTE)(l))

/* long word operation  */
#define word_high(a)           (((a) >> 16) & 0xFFFF)
#define word_low(a)            ((a) & 0xFFFF)

/* convert byte and integer */
#ifdef _M_IX86
#define BUF_TO_SHORT(a,b)      (((USHORT)(b) << 8) | ((USHORT)(a) & 0xFF))
#define SHORT_TO_BUF(w,a,b)    (*((BYTE *)(b)) = ((USHORT)(w) >> 8) & 0xFF, \
                                *((BYTE *)(a)) = (USHORT)(w) & 0xFF)
#define BUF_TO_LONG(a,b,c,d)   (((ULONG)(d) << 24) | (((ULONG)(c) << 16) & 0xFF0000) | \
                                (((ULONG)(b) << 8) & 0xFF00) | ((ULONG)(a) & 0xFF))
#define LONG_TO_BUF(l,a,b,c,d) (*((BYTE *)(d)) = (BYTE)((ULONG)(l) >> 24), \
                                *((BYTE *)(c)) = (BYTE)((ULONG)(l) >> 16), \
                                *((BYTE *)(b)) = (BYTE)((ULONG)(l) >> 8 ), \
                                *((BYTE *)(a)) = (BYTE)((ULONG)(l) & 0xFF))
#else
#define BUF_TO_SHORT(a,b)      (((USHORT)(a) << 8) | ((USHORT)(b) & 0xFF))
#define SHORT_TO_BUF(w,a,b)    (*((BYTE *)(a)) = (((USHORT)(w)) >> 8) & 0xFF, \
                                *((BYTE *)(b)) = ((USHORT)(w)) & 0xFF)
#define BUF_TO_LONG(a,b,c,d)   (((ULONG)(a) << 24) | \
                                (((ULONG)(b) << 16) && 0xFF0000) | \
                                (((ULONG)(c) << 8) & 0xFF00) | ((ULONG)(d) & 0xFF))
#define LONG_TO_BUF(l,a,b,c,d) (*((BYTE *)(a)) = (BYTE)((ULONG)(l) >> 24), \
                                *((BYTE *)(b)) = (BYTE)((ULONG)(l) >> 16), \
                                *((BYTE *)(c)) = (BYTE)((ULONG)(l) >> 8), \
                                *((BYTE *)(d)) = (BYTE)((ULONG)(l) & 0xFF))
#endif

#define BUFPTR_TO_SHORT(p)     BUF_TO_SHORT(*((BYTE *)p), *(((BYTE *)p)+1))
#define SHORT_TO_BUFPTR(l, p)  SHORT_TO_BUF((l), ((BYTE *)p), (((BYTE *)p)+1))
#define BUFPTR_TO_LONG(p)      BUF_TO_LONG(*(((BYTE *)p)+0), *(((BYTE *)p)+1),   \
                                           *(((BYTE *)p)+2), *(((BYTE *)p)+3))
#define LONG_TO_BUFPTR(l, p)   LONG_TO_BUF((l), ((BYTE *)p), (((BYTE *)p)+1),    \
                                                (((BYTE *)p)+2), (((BYTE *)p)+3))

#define BCD_TO_BYTE(x)         (((((x) >> 4)  & 0xF) * 10)  + ((x) & 0xF))
#define BCD_TO_SHORT(x)        (((((x) >> 12) & 0xF) * 1000) +                \
                                ((((x) >> 8)  & 0xF) * 100) +                 \
                                ((((x) >> 4)  & 0xF) * 10)  + ((x) & 0xF))
#define BYTE_TO_BCD(x)         (((((x) % 100)   / 10)   << 4) + ((x) % 10))
#define SHORT_TO_BCD(x)        ((((x)          / 1000) << 12) +               \
                                ((((x) % 1000) / 100)  << 8) +                \
                                ((((x) % 100)  / 10)   << 4) + ((x) % 10))

/* check even and odd  */
#define is_odd(x)              ((x) & 1)
#define is_even(x)             (!((x) & 1))
#define ODD(x)                 (((x) & 01))

#define bound_word(p)          ((((p) + 1) / 2) * 2)
#define bound_long(p)          ((((p) + 1) / 4) * 4)

#define EQUALSTR(s, c)        ((*s == *c) && (strcmp(s, c) == 0))

/*---------------------------------------------------------------------------*/
/*  define boolean                                                           */
/*---------------------------------------------------------------------------*/
#ifndef TRUE
#define TRUE         1
#endif
#ifndef FALSE
#define FALSE        0
#endif
#ifndef SUCCESS
#define SUCCESS      0
#endif

#ifndef OK
#define OK           0
#endif
#ifndef NG
#define NG           1
#endif

#ifndef YES
#define YES          1
#endif
#ifndef NO
#define NO           0
#endif

#ifndef ON
#define ON           1
#endif
#ifndef OFF
#define OFF          0
#endif

#ifndef FAILURE
#define FAILURE      (-1)
#endif

#define BEE_SUCCESS  0
#define BEE_ERROR    (-1)

#ifndef LOOP
#define LOOP    for(;;)
#endif

#ifndef BIG_ENDIAN
#define BIG_ENDIAN     1234
#define LITTLE_ENDIAN  4321
#endif

#if defined(WIN32) || defined(WIN64)
#   define ENDIAN        LITTLE_ENDIAN
#else
#   if defined(_M_IX86) || defined(__386__) || defined(i386)
#       define ENDIAN    LITTLE_ENDIAN
#   else
#       define ENDIAN    BIG_ENDIAN
#   endif
#endif

#define NOT_ACHIEVE  false

enum ItemFormatCode {
    UNKNOWN = -1,          /// unknown
    LIST = 0,              /// LIST (length in elements)
    Binary = 8,            /// Binary
    Boolean = 9,           /// Boolean
    ASCII = 16,            /// ASCII : Non-printing characters are equipment-specific
    JIS8 = 17,             /// JIS-8
    MC = 18,               /// Multi-byte charactor : UNICODE
    I8 = 24,               /// 8-byte integer (signed)
    I1 = 25,               /// 1-byte integer (signed)
    I2 = 26,               /// 2-byte integer (signed)
    I4 = 28,               /// 4-byte integer (signed)
    F8 = 32,               /// 8-byte floating poing
    F4 = 36,               /// 4-byte floating poing
    U8 = 40,               /// 8-byte integer (unsigned)
    U1 = 41,               /// 1-byte integer (unsigned)
    U2 = 42,               /// 2-byte integer (unsigned)
    U4 = 44,               /// 4-byte integer (unsigned)
    STRUCT = 070,
    ARRAY = 0100,
    VECTOR = 0170
};

enum SelectStatus{
    ConnectEstablished = 0,
    AlreadyActive = 1,
    NotReady = 2,
    ConnectExhaust = 3
};

enum DeselectStatus{
    CommunicationEnded = 0,
    CommunicationNotEstablished = 1,
    CommunicationBusy = 2
};

enum ReasonCode{
    STypeNotSupported = 1,
    PTypeNotSupported = 2,
    TransactionNotOpen = 3,
    EntityNotSelected = 4
};

enum WBit{ NeedReply = 1, NoReply = 0 };

enum MessageType{
    ErrorMessageType = -1,
    DataMessage = 0,
    SelectReq = 1,
    SelectRsp = 2,
    DeselectReq = 3,
    DeselectRsp = 4,
    LinktestReq = 5,
    LinktestRsp = 6,
    RejectReq = 7,
    SeparateReq = 9
};

#endif // JCHSMS_GLOBAL_H

// JcHsms.h

/****************************************
 *         JcHsms
 ****************************************/

#ifndef JCHSMS_H
#define JCHSMS_H
#pragma execution_character_set("utf-8")

#include "JcHsms_global.h"
#include "hsmsdeviceunique.h"

#define HSMS_LENGTHBYTE_LEN      (4)
#define HSMS_MESSAGEHEADER_LEN  (0xa)
#define HSMS_MESSAGE_MIN_LEN    (HSMS_LENGTHBYTE_LEN + HSMS_MESSAGEHEADER_LEN)

class HsmsMessageHeader;
class HsmsMessageDispatcher;
class Secs2Item;
class HsmsMessage;
struct HsmsDeviceUnique;
class HsmsDataManager;

class JCHSMS_EXPORT JcHsms : public HsmsDeviceUnique
{
public:
    JcHsms(uint16_t sessionID,QString mdln,QString softrev);

    HsmsMessage interpretMessage(const QByteArray& source);
    HsmsMessage originateMessage(const HsmsMessageHeader& header,const Secs2Item& item);
};

#endif // JCHSMS_H

// JcHsms.cpp

#include "JcHsms.h"
#include "hsmsdatamanager.h"
#include "hsmsdeviceunique.h"
#include "hsmsmessageheader.h"
#include "secs2item.h"
#include "hsmsmessage.h"

#define JCHSMS_DLL_VERSION "1.0.0.20221027_base"

JcHsms::JcHsms(uint16_t sessionID, QString mdln, QString softrev)
    :HsmsDeviceUnique(sessionID,mdln,softrev)
{

}

HsmsMessage JcHsms::interpretMessage(const QByteArray &source)
{
    return HsmsMessage(source);
}

HsmsMessage JcHsms::originateMessage(const HsmsMessageHeader& header,
                                     const Secs2Item& item)
{
    HsmsMessage hm;
    hm.AddLength(HSMS_MESSAGEHEADER_LEN + item.toByteArray().length() );
    hm.AddHeader(header);
    hm.AddItem(item);
    hm.toByteArray();

    return hm;
}
// hsmsdatamanager.h

/****************************************
 *         HsmsDataManager
 ****************************************/
#ifndef HSMSDATAMANAGER_H
#define HSMSDATAMANAGER_H

#include "JcHsms_global.h"

class JCHSMS_EXPORT HsmsDataManager
{
public:

    typedef struct EquipmentStatusData
    {
        EquipmentStatusData(){}
        EquipmentStatusData( ItemFormatCode fmt,QVariant val)
            : _fmt(fmt),_val(val){}

        ItemFormatCode _fmt;
        QVariant _val;
    }ESD;
    typedef QMap<uint32_t,ESD> QSsdMap;

    static HsmsDataManager &Instance();

    QSsdMap GetSsdMap();
    void UpdateSsdMap(const uint32_t& svid,const ESD& esd);
    void AddItem2SsdMap(const uint32_t& svid,const ESD& initesd);
    void RemoveItemFromSsdMap(const uint32_t& svid);

private:
    HsmsDataManager();
    void InitSsdMap();
private:
    QSsdMap SSDMap;
};

#endif // HSMSDATAMANAGER_H

// hsmsdatamanager.cpp

#include "hsmsdatamanager.h"

/****************************************
 *         HsmsDataManager
 ****************************************/
HsmsDataManager &HsmsDataManager::Instance()
{
    static HsmsDataManager hsmsDtMgr;
    return hsmsDtMgr;
}

HsmsDataManager::QSsdMap HsmsDataManager::GetSsdMap()
{
    return SSDMap;
}

void HsmsDataManager::UpdateSsdMap(const uint32_t &svid, const HsmsDataManager::ESD &esd)
{
    std::mutex _mutex;
    _mutex.lock();
    this->SSDMap.remove(svid);
    this->SSDMap[svid] = esd;
    _mutex.unlock();
}

void HsmsDataManager::AddItem2SsdMap(const uint32_t &svid, const HsmsDataManager::ESD &initesd)
{
    if(SSDMap.find(svid) != SSDMap.end()){
        UpdateSsdMap(svid,initesd);
    }else{
        SSDMap.insert(svid,initesd);
    }
}

void HsmsDataManager::RemoveItemFromSsdMap(const uint32_t &svid)
{
    if(SSDMap.find(svid) != SSDMap.end()){
        SSDMap.remove(svid);
    }
}

void HsmsDataManager::InitSsdMap()
{
    /// SSD
    /// 1001 I4      设备状态:0=ready 1=homing 2=warning 3=runing
    /// 1002 Boolean 正压气源1报警
    /// 1003 Boolean 正压气源2报警
    /// 1004 Boolean 负压气源报警
    /// 1005 I4      loadport 状态 0=ready 1=homing 2=warning 3=runing
    /// 1006 I4      robot 状态
    /// 1007 I4      aligner 状态
    /// 1008 I4      code scanner 状态
    /// 1009 I4      axis-X 状态
    /// 1010 I4      axis-Y 状态
    /// 1011 I4      axis-Z 状态
    /// 1012 I4      axis-T 状态
    /// 1013 I4      测距仪 状态
    /// 1014 I4      主检相机 状态
    /// 1015 I4      review相机 状态
    /// 1016 I4      FFU状态
    /// 1017 I4      离子泵状态
    /// 1018 I4      左侧门1状态
    /// 1019 I4      左侧门2状态
    /// 1020 I4      右侧门1状态
    /// 1021 I4      右侧门2状态
    /// 1022 F4      机台温度 4-byte float
    /// 1023 F4      机台湿度 4-byte float
    SSDMap.insert(1001,ESD (I4,QVariant(0)));

    for(int svid = 1002; svid <= 1004; ++svid)
        SSDMap.insert(svid,ESD(Boolean,QVariant(false)));

    for(int svid = 1005; svid <= 1021; ++svid)
        SSDMap.insert(svid,ESD (I4,QVariant(0)));

    for(int svid = 1022; svid <= 1023;++svid)
        SSDMap.insert(svid,ESD(F4,QVariant(1.01)));
}

HsmsDataManager::HsmsDataManager()
{
    InitSsdMap();
}

// hsmsdeviceunique.h

/****************************************
 *         HsmsDeviceUnique
 ****************************************/

#ifndef HSMSDEVICEUNIQUE_H
#define HSMSDEVICEUNIQUE_H

#include "JcHsms_global.h"

struct JCHSMS_EXPORT HsmsDeviceUnique
{
    HsmsDeviceUnique(uint16_t sessionID,QString mdln,QString softrev);

    static uint16_t unique_sessionID;  // Equipment id or device id, be unique.
    static QString  unique_MDLN;       // Equipment Model Type, 20bytes max
    static QString  unique_SOFTREV;    // Software revision code, 20bytes max
};

#endif // HSMSDEVICEUNIQUE_H

// hsmsdeviceunique.cpp

/****************************************
 *         HsmsDeviceUnique
 ****************************************/

#include "hsmsdeviceunique.h"

uint16_t HsmsDeviceUnique::unique_sessionID;
QString  HsmsDeviceUnique::unique_MDLN;
QString  HsmsDeviceUnique::unique_SOFTREV;


HsmsDeviceUnique::HsmsDeviceUnique(uint16_t sessionID, QString mdln, QString softrev)
{
    unique_sessionID = sessionID;
    unique_MDLN = mdln.left(20);
    unique_SOFTREV = softrev.left(20);
}

// hsmsincludes.h

#ifndef HSMSINCLUDES_H
#define HSMSINCLUDES_H

#include "JcHsms_global.h"
#include "JcHsms.h"
#include "hsmsdatamanager.h"
#include "hsmsdeviceunique.h"
#include "hsmsmessage.h"
#include "hsmsmessagedispatcher.h"
#include "hsmsmessageheader.h"
#include "secs2item.h"

#endif // HSMSINCLUDES_H

// hsmsmessage.h

/****************************************
 *         HsmsMessage
 ****************************************/

#ifndef HSMSMESSAGE_H
#define HSMSMESSAGE_H

#include "JcHsms_global.h"
#include "hsmsmessageheader.h"
#include "secs2item.h"

class JCHSMS_EXPORT HsmsMessage
{
public:

    HsmsMessage(){ }
    HsmsMessage(const QByteArray& source);
    HsmsMessage(char* message,int len);
    HsmsMessage(const HsmsMessage& primary);
    const HsmsMessage & operator=(const HsmsMessage &rhs);

    QString SmlString() const;

    void copy(const HsmsMessage& m);

    uint32_t GetLength(const QByteArray& source);
    void AddLength(uint32_t n);

    HsmsMessageHeader GetHeader();
    void AddHeader(HsmsMessageHeader header);
    void AddHeader(uint16_t sessionID,uint8_t stream,uint8_t function,
                   uint8_t stype,uint8_t ptype,uint32_t systembytes);

    Secs2Item GetItem() const;
    void AddItem(Secs2Item item);

    QByteArray toByteArray();

    HsmsMessage dispatch();

private:
     QString SmlInterpret(
            const Secs2Item &item,
            QString &smlString,
            QString &spaceStringfmt) const;

private:
    uint32_t m_bytesLen;
    HsmsMessageHeader m_header;
    Secs2Item m_items;
    QByteArray m_message;

};

#endif // HSMSMESSAGE_H

// hsmsmessage.cpp

#include "hsmsmessage.h"
#include "hsmsmessageheader.h"
#include "secs2item.h"
#include "hsmsmessagedispatcher.h"

/****************************************
 *         HsmsMessage
 ****************************************/
HsmsMessage::HsmsMessage(const QByteArray &source){
    // assert(source.length() >= HSMS_MESSAGE_MIN_LEN);
    if(source.isEmpty() || source.length() < HSMS_MESSAGE_MIN_LEN) return;

    m_message = source;
    m_bytesLen = GetLength(source);
    m_header = HsmsMessageHeader(source.mid(HSMS_LENGTHBYTE_LEN,HSMS_MESSAGEHEADER_LEN));
    m_items = Secs2Item(source.mid(HSMS_MESSAGE_MIN_LEN,source.length() - HSMS_MESSAGE_MIN_LEN));
}

HsmsMessage::HsmsMessage(char *message, int len){
    QByteArray source(message,len);
    m_message = source;
    m_bytesLen = GetLength(source);
    m_header = HsmsMessageHeader(source.mid(HSMS_LENGTHBYTE_LEN,HSMS_MESSAGEHEADER_LEN));
    m_items = Secs2Item(source.mid(HSMS_MESSAGE_MIN_LEN,source.length() - HSMS_MESSAGE_MIN_LEN));
}

HsmsMessage::HsmsMessage(const HsmsMessage &primary)
{
    this->copy(primary);
}

const HsmsMessage & HsmsMessage::operator=(const HsmsMessage &rhs)
{
    if(this == &rhs)
        return *this;
    this->copy(rhs);
    return *this;
}


QString HsmsMessage::SmlString() const
{
    QString smlString;
    QString spaceStringfmt = "  ";

    if(this->GetItem().isEmpty()) {
        return smlString;
    }

    SmlInterpret(this->GetItem(),smlString,spaceStringfmt);

    smlString[smlString.length() -1] = '.';
    return smlString;
}


void HsmsMessage::copy(const HsmsMessage &m)
{
    this->m_bytesLen = m.m_bytesLen;
    this->m_header = m.m_header;
    this->m_items = m.m_items;
    this->m_message = m.m_message;
}

uint32_t HsmsMessage::GetLength(const QByteArray &source){

    uint32_t lenA[4] = {0};
    uint32_t len = 0;
    lenA[0] = static_cast<uint32_t>(source.at(0));
    lenA[1] = static_cast<uint32_t>(source.at(1));
    lenA[2] = static_cast<uint32_t>(source.at(2));
    lenA[3] = static_cast<uint32_t>(source.at(3));
#if ENDIAN == LITTLE_ENDIAN
    for(int i = 0; i < 4;i++) len += (lenA[i] << ((3-i)*8 ));
#else
    for(int i = 0; i < 4;i++) len += (lenA[i] << (i*8 ));
#endif
    return len;
}

void HsmsMessage::AddLength(uint32_t n)
{
    m_bytesLen = n;

}

HsmsMessageHeader HsmsMessage::GetHeader()
{
    return m_header;
}

void HsmsMessage::AddHeader(HsmsMessageHeader header)
{
    m_header = header;
}

void HsmsMessage::AddHeader(uint16_t sessionID, uint8_t stream, uint8_t function,
                            uint8_t stype, uint8_t ptype, uint32_t systembytes)
{
    m_header = HsmsMessageHeader(sessionID,stream,function,stype,ptype,systembytes);
}

Secs2Item HsmsMessage::GetItem() const
{
    return m_items;
}

void HsmsMessage::AddItem(Secs2Item item)
{
    m_items = item;
}

QByteArray HsmsMessage::toByteArray()
{
    if(!m_message.isEmpty())
        return m_message;

    m_message.clear();

    // apped len bytes
    m_message.append( static_cast<char>( (m_bytesLen >> 24) & 0xff));  //[0]
    m_message.append( static_cast<char>( (m_bytesLen >> 16) & 0xff));  //[1]
    m_message.append( static_cast<char>( (m_bytesLen >> 8) & 0xff) );  //[2]
    m_message.append( static_cast<char>( (m_bytesLen >> 0) & 0xff) );  //[3]

    // append message header bytes
    QByteArray headerByteArray = m_header.toByteArray();
    m_message.append(headerByteArray);

    // append secsItems bytes
    QByteArray secsItemsByteArray =  m_items.toByteArray();
    m_message.append(secsItemsByteArray);

    return m_message;
}

HsmsMessage HsmsMessage::dispatch()
{
    HsmsMessageDispatcher dispatcher;
    return dispatcher.deal(*this);
}

QString HsmsMessage::SmlInterpret(
        const Secs2Item &item,
        QString &smlString,
        QString &spaceStringfmt) const
{
    /**
          <L,2
              <A,16 'JC Gem/Secs Test'>
              <A,5 '1.0.1'>
          >.
        */

    if(!item.isList()) {

        int fmt =  item.format();
        QString fmtString;
        QString value;

        smlString += spaceStringfmt;

        switch (ItemFormatCode(fmt) )
        {
        case LIST    : fmtString = "L" ;    break;
        case I1      :{
            fmtString = "I1";
            value.append(QChar(item.toInt8().first()));
            break;
        }
        case I2      :{
            fmtString = "I2";
            value = QString::number(item.toInt16().first());
            break;
        }
        case I4      :{
            fmtString = "I4";
            value = QString::number(item.toInt32().first());
            break;
        }
        case I8      : {
            fmtString = "I8";
            value = QString::number(item.toInt64().first());
            break;
        }
        case JIS8    : {
            fmtString = "J";
            value = QString(item.toJIS8());
            break;
        }
        case ASCII   : {
            fmtString = "A";
            value = item.toASCII();
            break;
        }
        case F4      : {
            fmtString = "F4";
            value = QString::number( item.toFloat().first());
            break;
        }
        case F8      :{
            fmtString = "F8";
            value = QString::number( item.toDouble().first());
            break;
        }
        case U4      :{
            fmtString = "U4";
            value = QString::number( item.toUInt32().first());
            break;
        }
        case U2      : {
            fmtString = "U2";
            value = QString::number( item.toUInt16().first());
            break;
        }
        case U1      : {
            fmtString = "U1";
            value.append(QChar(item.toUInt8().first()));
            break;
        }
        case U8      : {
            fmtString = "U8";
            value = QString::number(item.toUInt64().first());
            break;
        }
        case Binary  : {
            fmtString = "B";
            value = QString(item.toBinary());
            break;
        }
        case MC      : {
            fmtString = "MC";
            break;
        }
        case Boolean : {
            fmtString = "BOOLEAN";
            value = QString::number(item.toBoolean().first());
            break;
        }
        default:
            break;
        }

        smlString += QString("<%1,%2 '%3'>\n").arg(fmtString,QString::number(item.bytes()),value);

        return smlString;
    }else{
        QVector<Secs2Item> v = item.GetItems();

        smlString += QString("<L,%1 \n").arg(QString::number(item.bytes()));

        spaceStringfmt += "  ";

        for(int i =0; i < v.count();++i){
            SmlInterpret(v[i],smlString,spaceStringfmt);
        }
        smlString += ">\n";
    }

    return smlString;

}
// hsmsmessagedispatcher.h

/****************************************
 *         HsmsMessageDispatcher
 ****************************************/

#ifndef HSMSMESSAGEDISPATCHER_H
#define HSMSMESSAGEDISPATCHER_H

#include "JcHsms_global.h"
#include "hsmsmessage.h"

class JCHSMS_EXPORT HsmsMessageDispatcher
{
public:
    HsmsMessageDispatcher();

    void registerDataMessage(uint8_t stream, uint8_t function);
    void unRegisterDataMessage(uint8_t stream, uint8_t function);

    HsmsMessage deal( HsmsMessage primary);
    HsmsMessage dealDataMsg( HsmsMessage primary);

public:
    // active request
    static HsmsMessage linktestReq();
    static HsmsMessage selectReq(uint16_t sessionID);
    static HsmsMessage S1F3(uint16_t sessionID);

private:
    // response for request
    HsmsMessage selectRsp(uint16_t sessionID, uint32_t systemBytes, SelectStatus status);
    HsmsMessage linktestRsp(uint32_t systemBytes);

    HsmsMessage S9F1(HsmsMessage primary, uint16_t sessionID);
    HsmsMessage S9F3(HsmsMessage primary, uint16_t sessionID);
    HsmsMessage S9F5(HsmsMessage primary, uint16_t sessionID);

    HsmsMessage S1F2(HsmsMessage primary, uint16_t sessionID);
    HsmsMessage S1F4(HsmsMessage primary, uint16_t sessionID);
    HsmsMessage S1F14(HsmsMessage primary,uint16_t sessionID,UCHAR type);

private:
    QSet<uint8_t>  m_streamSet;
    QSet<uint8_t>  m_functionSet;
    QSet<uint16_t> m_sfSet;
};
#endif // HSMSMESSAGEDISPATCHER_H

// hsmsmessagedispatcher.cpp

/****************************************
 *         HsmsMessageDispatcher
 ****************************************/

#include "hsmsmessagedispatcher.h"
#include "hsmsdatamanager.h"

HsmsMessage HsmsMessageDispatcher::selectRsp(uint16_t sessionID, uint32_t systemBytes, SelectStatus status)
{
    HsmsMessage message;
    message.AddLength(10);
    sessionID = 0xFFFF;
    HsmsMessageHeader header(sessionID/*sessionID*/,0,status,0,2,systemBytes);
    message.AddHeader(header);
    message.toByteArray();

    return message;
}

HsmsMessage HsmsMessageDispatcher::linktestRsp(uint32_t systemBytes)
{
    HsmsMessage message;
    HsmsMessageHeader header(0xFFFF,0,0,0,6,systemBytes);
    message.AddLength(10);
    message.AddHeader(header);

    return message;
}

HsmsMessage HsmsMessageDispatcher::S9F1(HsmsMessage primary, uint16_t sessionID)
{
    Secs2Item it;
    QByteArray a(static_cast<int>(0), static_cast<char>(0));
    it.AddBinary(a);
    uint32_t sb = primary.GetHeader().GetSystemBytes();

    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,9,1,0,0,sb);
    hm.AddItem(it);

    return hm;
}

HsmsMessage HsmsMessageDispatcher::S9F3(HsmsMessage primary, uint16_t sessionID)
{
    Secs2Item it;
    QByteArray a(static_cast<int>(0), static_cast<char>(0));
    it.AddBinary(a);
    uint32_t sb = primary.GetHeader().GetSystemBytes();

    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,9,3,0,0,sb);
    hm.AddItem(it);

    return hm;
}

HsmsMessage HsmsMessageDispatcher::S9F5(HsmsMessage primary, uint16_t sessionID)
{
    Secs2Item it;
    QByteArray a(static_cast<int>(0), static_cast<char>(0));
    it.AddBinary(a);
    uint32_t sb = primary.GetHeader().GetSystemBytes();

    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,9,5,0,0,sb);
    hm.AddItem(it);

    return hm;
}

HsmsMessage HsmsMessageDispatcher::S1F2(HsmsMessage primary, uint16_t sessionID)
{
    Secs2Item its[2];
    its[0].AddASCII(HsmsDeviceUnique::unique_MDLN.toLatin1().constData());
    its[1].AddASCII(HsmsDeviceUnique::unique_SOFTREV.toLatin1().constData());

    Secs2Item it;
    it.AddItems(its, 2);

    uint32_t sb = primary.GetHeader().GetSystemBytes();

    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,1,2,0,0,sb);
    hm.AddItem(it);
    hm.toByteArray();

    return  hm;
}


bool appendItem_ssd(const HsmsDataManager::EquipmentStatusData& esd,
                    QVector<Secs2Item>& rspItems)
{
    Secs2Item item;
    switch (esd._fmt) {
    case Boolean:   item.AddBoolean(esd._val.toBool()); break;
    case ASCII:     item.AddASCII(esd._val.toString()); break;
    case JIS8:      item.AddJIS8(esd._val.toString().toStdString().c_str()); break;
    case MC :       return NOT_ACHIEVE; break;
    case I1 :       item.AddInt8(esd._val.toChar().toLatin1()); break;
    case I2:        item.AddInt16((short)esd._val.toInt()); break;
    case I4:        item.AddInt32(esd._val.toInt()); break;
    case I8:        item.AddInt64(esd._val.toLongLong()); break;
    case U2:        item.AddUInt16((uint16_t)esd._val.toUInt()); break;
    case U4:        item.AddUInt32((uint32_t)esd._val.toUInt()); break;
    case U8:        item.AddUInt64((uint64_t)esd._val.toULongLong()); break;
    case F4:        item.AddFloat(esd._val.toFloat()); break;
    case F8:        item.AddDouble(esd._val.toDouble()); break;
    default:        return NOT_ACHIEVE; break;
    }
    rspItems.append(item);
    return true;
}

HsmsMessage HsmsMessageDispatcher::S1F4(HsmsMessage primary, uint16_t sessionID)
{
    // Get all svids ,and Get the value
    Secs2Item item = primary.GetItem();
    QVector<Secs2Item> items = item.GetItems();
    QVector<Secs2Item> rspItems;
    const QMap<uint32_t, HsmsDataManager::EquipmentStatusData>& m = HsmsDataManager::Instance().GetSsdMap();

    for(int i = 0; i < items.size();i++){

        Secs2Item item = items[i];
        switch ((ItemFormatCode)item.format() )
        {
        case LIST   : NOT_ACHIEVE; break;
        case I1     : foreach (auto val, item.toInt8())   if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case I2     : foreach (auto val, item.toInt16())  if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case I4     : foreach (auto val, item.toInt32())  if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case I8     : foreach (auto val, item.toInt64())  if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case JIS8   : foreach (auto val, item.toJIS8())   if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case ASCII  : NOT_ACHIEVE; break;
        case F4     : foreach (auto val, item.toFloat())  if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case F8     : foreach (auto val, item.toDouble()) if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case U4     : foreach (auto val, item.toUInt32()) if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case U2     : foreach (auto val, item.toUInt16()) if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case U1     : foreach (auto val, item.toUInt8())  if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case U8     : foreach (auto val, item.toUInt64()) if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case Binary : foreach (auto val, item.toBinary()) if(m.keys().contains(val)) appendItem_ssd(m[val],rspItems); break;
        case MC     : NOT_ACHIEVE; break;
        case Boolean: NOT_ACHIEVE; break;;
        default:
            break;
        }
    }

    Secs2Item it;
    it.AddItems(rspItems);

    uint32_t sb = primary.GetHeader().GetSystemBytes();
    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,1,4,0,0,sb); // S1F4
    hm.AddItem(it);
    hm.toByteArray();

    return hm;
}


HsmsMessage HsmsMessageDispatcher::S1F14(HsmsMessage primary, uint16_t sessionID, UCHAR type)
{
    //<L[2]
    //    1. <B COMMACK>  0: Accepted;1: Denied, try again
    //    2. <L[2]   blongs to S1F13
    //        1.<A MDLN>
    //        2.<A SOFTREV>

    uint32_t sb = primary.GetHeader().GetSystemBytes();
    Secs2Item s1f13 = primary.GetItem();

    Secs2Item tmp;
    uint8_t x[1] = {type};
    tmp.AddUInt8(x,1);

    Secs2Item it ;
    it = it.mergeSECS2Item(tmp,s1f13);

    HsmsMessage hm;
    hm.AddLength(10 + it.toByteArray().length() );
    hm.AddHeader(sessionID,1,14,0,0,sb);
    hm.AddItem(it);
    hm.toByteArray();

    return hm;
}

HsmsMessage HsmsMessageDispatcher::linktestReq()
{
    HsmsMessage message;

    HsmsMessageHeader header;
    header.SetSessionID(0xFFFF);
    header.SetStreamFunction(0, 0);
    header.SetPSType(0, 5);
    uint32_t sb = header.uniqueSystemBytes();
    header.SetSystemBytes(sb);

    message.AddLength(10); // header only
    message.AddHeader(header);

    return message;
}

HsmsMessage HsmsMessageDispatcher::selectReq(uint16_t sessionID)
{
    HsmsMessage message;

    HsmsMessageHeader header;
    header.SetSessionID(sessionID);
    header.SetStreamFunction(0, 0);
    header.SetPSType(0, 1);
    uint32_t sb = header.uniqueSystemBytes();
    header.SetSystemBytes(sb);

    message.AddLength(10);
    message.AddHeader(header); // header only

    return message;
}

HsmsMessage HsmsMessageDispatcher::S1F3(uint16_t sessionID)
{
    HsmsMessage message;
    HsmsMessageHeader header;
    header.SetSessionID(sessionID);
    header.SetStreamFunction(1, 3);
    header.SetPSType(0, 0);
    uint32_t sb = header.uniqueSystemBytes();
    header.SetSystemBytes(sb);

    QVector<Secs2Item> rspItems;
    for(int i =1001; i<= 1023;i++){
        Secs2Item item;
        item.AddUInt32(i);
        rspItems.append(item);
    }
    Secs2Item it;
    it.AddItems(rspItems);

    message.AddLength(10);
    message.AddHeader(header); // header only
    message.AddItem(it);
    message.toByteArray();

    return message;
}


HsmsMessage HsmsMessageDispatcher::dealDataMsg(HsmsMessage primary)
{
    HsmsMessage mess;
    HsmsMessageHeader header = primary.GetHeader();
    uint16_t id = header.GetSessionID();
    if(id != HsmsDeviceUnique::unique_sessionID) {
        mess = S9F1(primary, HsmsDeviceUnique::unique_sessionID);
        return mess;
    }

    uint8_t stream = header.Getstream();
    uint8_t function = header.Getfunction();

    uint16_t sf = stream;
    sf = (sf << 8) + function;
    if(!m_sfSet.contains(sf)){
        if(!m_streamSet.contains(stream)){
            mess = S9F3(primary, id);// unkonwn Stream
        }

        if(!m_functionSet.contains(function)){
            mess = S9F5(primary, id); //unkonw function
        }
        return mess;
    }

    // uint32_t sb = header.GetSystemBytes();
    // qDebug() << "I HsmsDevice recieve S" <<stream<<"F" <<function << " systemBytesID:"<< sb;

    if(stream == 1 && function == 1)
    { // Are You There

        mess = S1F2(primary,id);
    }
    else if(stream == 1 && function == 2)
    {
        qt_noop();
    }
    else if(stream == 1 && function == 3)
    { // SVID
        mess = S1F4(primary,id);
    }
    else if(stream == 1 && function == 4)
    {
        qt_noop();

    }else if(stream == 1 && function == 13)
    {
        mess = S1F14(primary,id,0);

    }else{

        qt_noop();
    }

    return mess;
}


HsmsMessageDispatcher::HsmsMessageDispatcher()
{
    registerDataMessage(0, 0); // select
    registerDataMessage(1, 1); // Are you there
    registerDataMessage(1, 2);
    registerDataMessage(1, 3);
    registerDataMessage(1, 4);
    registerDataMessage(1, 5);
    registerDataMessage(1, 6);
    registerDataMessage(1, 7);
    registerDataMessage(1, 8);
    registerDataMessage(1, 9);
    registerDataMessage(1, 10);
    registerDataMessage(1, 11);
    registerDataMessage(1, 12);
    registerDataMessage(1, 13);
    registerDataMessage(1, 14);
    registerDataMessage(2, 1);
    registerDataMessage(2, 2);
    registerDataMessage(2, 3);
    registerDataMessage(2, 17); // DateTimeRequest
    registerDataMessage(2, 18); // DateTimeRequest
    registerDataMessage(2, 41); // NG
    registerDataMessage(2, 103);// OK
    registerDataMessage(6, 4);
    registerDataMessage(6, 12);
    registerDataMessage(6, 17);
    registerDataMessage(9, 1);  // Unrecognized device ID
    registerDataMessage(9, 3);  // Unrecognized stream type
    registerDataMessage(9, 5);  // Unrecognized function type
}

void HsmsMessageDispatcher::registerDataMessage(uint8_t stream, uint8_t function)
{
    uint16_t x = stream;
    x = (x << 8) + function;
    m_sfSet.insert(x);

    m_streamSet.insert(stream);
    m_functionSet.insert(function);
}

void HsmsMessageDispatcher::unRegisterDataMessage(uint8_t stream, uint8_t function)
{
    uint16_t x = stream;
    x = (x << 8) + function;
    m_sfSet.remove(x);

    bool hasStream = false;
    bool hasFunction = false;
    foreach (const uint16_t &value, m_sfSet)
    {
        uint8_t s = value >> 8;
        uint8_t f = value & 0xff;
        if(s == stream){
            hasStream = true;
        }
        if(f == function){
            hasFunction = true;
        }
    }
    if(!hasStream) m_streamSet.remove(stream);
    if(!hasFunction) m_functionSet.remove(function);
}

HsmsMessage HsmsMessageDispatcher::deal(HsmsMessage primary)
{
    HsmsMessageHeader head = primary.GetHeader();
    uint16_t id = head.GetSessionID();
    uint32_t sb = head.GetSystemBytes();
    MessageType mt = head.GetMessageType();

    HsmsMessage secondary;

    switch (mt) {
    case SelectReq:
        secondary = selectRsp(id,sb,ConnectEstablished);
        break;
    case RejectReq:   break;
    case SelectRsp:   break;
    case DeselectReq: break;
    case DeselectRsp: break;
    case SeparateReq: break;
    case LinktestReq: secondary = linktestRsp(sb); break;
    case DataMessage: secondary = dealDataMsg(primary); break;
    default:
        break;
    }
    return secondary;
}

楼太高了,也避免大家视觉疲劳,接下篇~~

文章来源:https://blog.csdn.net/weixin_39568531/article/details/135020013
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。