//=============================================================================
//                       HelloWorld demo script
//=============================================================================

/*/////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

 Figure 1.  message format for this protocol
                                    
      +---------------+---------------+---------------+---------------+
  OCT |       0               1               2               3       |
      +---------------------------------------------------------------+
      |7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0|
      +---------------+---------------+---------------+---------------+
      |               | m |                           |               |
      |     Header    | s |    Sequence number        | Content type  |
      |               | g |                           |               |
      +---------------+---------------+---------------+---------------+
      |                            Content                            |
      +---------------+---------------+---------------+---------------+

      Header: One byte flag to identify this message, always be 0xfe

      Msg   : packet type, 2 bit
               
              possible values  0 - command  
              
                               2 - report

      Sequence number:
       
              Sequence number for this packet
               
      Content type:
       
              One byte field, identify the type of the content
              
              possible values  1 - octet stream
                               
                               2 - ip address
              
                               3 - bcd data (positive BCD)
              
                               4 - string with typeof attribute
              
                               5 - array with fixed size
              
                               6 - array with unfixed size
              
                               7 - timestamp
              

 Figure 1.1  format for content field ( octet stream )

  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |     Length    |           octet stream ...          
      +---------------+---------------+---------------+---------------+

      Length: The length of octet stream
      
      
 Figure 1.2  format for content field ( ipaddress A.B.C.D )


  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |       A       |       B       |       C       |       D       |
      +---------------+---------------+---------------+---------------+


 Figure 1.3  format for content field ( positive bcd )

  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |     Length    |          PhoneNumber (bcd data) ...                   
      +---------------+---------------+---------------+---------------+

      Length: The length of bytes of the BCD octet

          The BCD(Binary Coded Decimal) format is the following: 
      
                    7 6 5 4 3 2 1 0
                   +---------------+
          OCTET 0  |Digit1 | Digit2|
                   +---------------+
          OCTET 1  |Digit3 | Digit4|
                   +---------------+
          ...      


 Figure 1.4  format for content field ( string with typeof attribute )

  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |     Length    |           string (end with zero) ...          
      +---------------+---------------+---------------+---------------+

      Length: The length of the string(do not count the zero byte)
      


 Figure 1.5  format for content field ( uint array with fixed size = 2 )

  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |   IdentifierId_1 (MSB-LSB)    |   IdentifierId_2 (MSB-LSB)    |
      +---------------+---------------+---------------+---------------+


 Figure 1.6  format for content field ( int array with unfixed size )

  OCT         0               1               2               3             
      +---------------+---------------+---------------+---------------+----
      |IdentifierIdNum|   IdentifierId_1 (MSB-LSB)    |    ......
      +---------------+---------------+---------------+---------------+----



 Figure 1.7  format for content field ( timestamp )

  OCT         0               1               2               3       
      +---------------+---------------+---------------+---------------+
      |               timestamp (high byte -> low byte)               |
      +---------------+---------------+---------------+---------------+

              
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////*/


#include "..\Include\sys.h"
#include "share.h"
#include "Lib.h"


#define PROTOCOL_ROOT msg

#define NETWORK_TRANMODE    H_TO_L      // default value is L_TO_H

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//pre define struct header

struct tOctetStream;
struct tIpAddress;
struct tBCDStream;
struct tTypeOFString;
struct tFixedArray;
struct tUnFixedArray;
struct tTimestamp;

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// ROOT

struct msg	
{
    BYTE        Header;                 // Framing header
    UINT2       PacketType: 2 {         // Type of this packet
                    enum description {
                        0,   // Command
                        1,   // Ack
                        2,   // Report
                    };
                    string Dump(dynamic& curItem)
                    {
                       String str;
                       str=sysGetEnumComment(curItem,"Description","Equal","-");
                       sysSetTitle(0,str);
                       return str;
                    }
                };
    UINT2       SequenceNumber: 14 ;
    BYTE        ContentType {            // Type of following content
                    enum description {
                        1,   // Packet (octet stream)
                        2,   // Packet (ip address)
                        3,   // Packet (bcd stream)
                        4,   // Packet (string with typeof attribute)
                        5,   // Packet (array with fixed size)
                        6,   // Packet (array with unfixed size)
                        7,   // Packet (timestamp)
                    };
                    string Dump(dynamic& curItem)
                    {
                       String str;
                       str=sysGetEnumComment(curItem,"Description","Equal","-");
                       sysSetTitle(1,str);
                       return str;
                    }
                };   
    
    Choice      Content {
                    DeclareMap(ImplicitItem,DataField)  
                    {
                        item  [1]  tOctetStream
                        item  [2]  tIpAddress
                        item  [3]  tBCDStream
                        item  [4]  tTypeOFString
                        item  [5]  tFixedArray
                        item  [6]  tUnFixedArray
                        item  [7]  tTimestamp
                    };
                    ChoiceMap DataField
                      
                    void Translate(String strCurIdent,dynamic& curItem,long nIdxInArr)
                    {
                         sysTranChoiceItem(strCurIdent,curItem,this.ContentType);                     
                    }
                };
};

//////////////////////////////////////////////////////////
struct tOctetStream
{
    string strData {    // octet stream content
    
               void Translate(String strCurIdent,dynamic& curItem,long nIdxInArr)
               {    
                    UINT1  Len;
                    
                    sysFetchValue(strCurIdent,len,     now(),0,  true);
                    sysFetchValue(strCurIdent,curItem, now(),len,true);
                       
                    return;
               } 
           };
};

//////////////////////////////////////////////////////////
struct tIpAddress
{
    OCTET   strIpAddress {
    
                void Translate(String strCurIdent,dynamic& curItem,long nIdxInArr)
                {
                    sysFetchValue(strCurIdent,curItem,now(),4, true);  
                }
                String Dump(dynamic& curItem)
                {
                    int  i;
                    BYTE Address[4];

                    for(i=0;i<4;i=i+1)
                    {
                       strGetAt(this.strIpAddress, i, Address[i]);
                    }
                       
                    return strFormat("%d.%d.%d.%d",Address[0],Address[1],Address[2],Address[3]);
                }
            }; 
};

//////////////////////////////////////////////////////////
struct tBCDStream
{
    String  strPhoneNumber {     // BCD data
    
               void Translate(String strCurIdent,dynamic& curItem,long nIdxInArr)
               {    
                    UINT1  PhoneNumberLen;
                    OCTET  strBCDData;
                    
                    sysFetchValue(strCurIdent,PhoneNumberLen, now(),0,  true);
                    sysFetchValue(strCurIdent,strBCDData,     now(),(PhoneNumberLen+1)/2,true);
  
                    curItem=BCD2STR(strBCDData, true, (PhoneNumberLen%2)? 0:1);
                       
                    return;
               } 
           };
};

//////////////////////////////////////////////////////////
struct tTypeOFString
{
    String  strData  { TypeOF tStringWithLenAndZeroEnd }; // TypeOf string
};

//////////////////////////////////////////////////////////
struct tFixedArray
{
    UINT2   IdentifierId[2];    // IdentifierId Array
};

//////////////////////////////////////////////////////////
struct tUnFixedArray
{
    choice  IdArray {
                DeclareMap( Item , DataField )  
                {
                    IdentifierId  [0]  int2
                };
                ChoiceMap DataField

			    byte  Num;
                sysFetchValue("IdArray", Num, now(), 0, true);

                void Translate(String strCurIdent,dynamic& curItem,long nIdxInArr)
                {
                    int k=0;
                    while (k<Num) 
                    {
                       sysTranChoiceItem(strCurIdent,curItem,0 );                     
                       k=k+1;
                    }
                }    
            };
};

//////////////////////////////////////////////////////////
struct tTimestamp
{
    long    nTimestamp {
                string Dump(dynamic& curItem)
                {
                    return TimestampToDateStream(curItem);
                }
            };
};


