srcp.c

Go to the documentation of this file.
00001 // ////////////////////////////////////////////////////////////////////////////
00002 // ////////////////////////////////////////////////////////////////////////////
00014     #define     SRCP_C
00015 
00016 
00017 // ////////////////////////////////////////////////////////////////////////////
00018 // Includes
00019 // ////////////////////////////////////////////////////////////////////////////
00020 
00021     #include    "srcp.h"
00022     #include    "stringtable.h"
00023     #include    "dialog.h"
00024     #include    "sralloc.h"
00025     #include    "error.h"
00026 
00027 
00028 // ////////////////////////////////////////////////////////////////////////////
00029 // Local Defines
00030 // ////////////////////////////////////////////////////////////////////////////
00031 
00032 // Maximum SRCP device, which can be configured in parallel (eWicht cache)
00033 #define MAX_SRCP_DEVICES            6
00034 
00035 // Entries in the server cache (currently only for GLs)
00036 #define SERVER_CACHE_ENTRIES        11
00037 
00038 
00039 #define DEVICE_PRM_PTR(deviceptr)  ((BYTE *)(&deviceptr[1]))
00040 #define DEVICE_PROTO_PTR(devptr)   ((BYTE *)(DEVICE_PRM_PTR(devptr) + offsetof(sGL, au8Proto)))
00041 #define DEVICE_NAME_PTR(devptr)    ((BYTE *)(DEVICE_PRM_PTR(devptr) + offsetof(sGL, au8Name)))
00042 
00043 
00044 // ////////////////////////////////////////////////////////////////////////////
00045 // Local enumerator typedefs
00046 // ////////////////////////////////////////////////////////////////////////////
00047 
00048 // SRCP Handshake return codes
00049 typedef enum
00050 {
00051     SRCP_HR_ERROR = 0,
00052     SRCP_HR_IN_PROGRESS,
00053     SRCP_HR_FINISHED
00054 } SRCP_HANDSHAKE_RETCODE;
00055 
00056 
00057 // States of SRCP in "Operating Mode"
00058 typedef enum
00059 {
00060     SRCP_STARTUP = 0,
00061     SRCP_MAIN,
00062     SRCP_PREPARE_MAIN,
00063     SRCP_SELECT_EEPROM_SET_TO_SAVE,
00064     SRCP_ENTER_NAME,
00065     SRCP_SELECT_PROTOCOL,
00066     SRCP_PROTOCOL_SELECTED,
00067     SRCP_SELECT_DEVICE_ADDRESS,
00068     SRCP_SELECT_SERVER_CACHE,
00069     SRCP_SELECT_EEPROMSET,
00070     SRCP_INIT_DEVICE,
00071     SRCP_WAIT_FOR_IDLE_DEVICE,
00072     SRCP_INIT_POWER,
00073     SRCP_WAIT_FOR_IDLE_POWER_DEVICE,
00074     SRCP_ERROR,
00075     SRCP_ACK_ERROR
00076 } SRCP_SM;
00077 
00078 
00079 // States of SRCP in the "Handshaking Mode"
00080 typedef enum
00081 {
00082     SRCP_HS_WAIT_FOR_WELCOME = 0,
00083     SRCP_HS_SET_VERSION,
00084     SRCP_HS_WAIT_VERSION,
00085     SRCP_HS_SET_MODE,
00086     SRCP_HS_WAIT_MODE,
00087     SRCP_HS_GO,
00088     SRCP_HS_WAIT_GO,
00089     SRCP_HS_GOING,
00090     SRCP_HS_ERROR
00091 } SRCP_HANDSHAKE_SM;
00092 
00093 
00094 // SRCP device groups
00095 typedef enum
00096 {
00097     SRCP_DT_NOT_DEFINED = 0,
00098     SRCP_DT_GL,
00099     SRCP_DT_SM,
00100     SRCP_DT_GA,
00101     SRCP_DT_FB,
00102     SRCP_DT_TIME,
00103     SRCP_DT_POWER,
00104     SRCP_DT_SERVER,
00105     SRCP_DT_SESSION,
00106     SRCP_DT_LOCK,
00107     SRCP_DT_DESCRIPTION
00108 } SRCP_DEVTYPE;
00109 
00110 
00111 // SRCP commands
00112 typedef enum
00113 {
00114     SRCP_CMD_INFO = 0,
00115     SRCP_CMD_GET,
00116     SRCP_CMD_SET,
00117     SRCP_CMD_INIT,
00118     SRCP_CMD_TERM,
00119     SRCP_CMD_CHECK,
00120     SRCP_CMD_WAIT,
00121     SRCP_CMD_RESET,
00122     SRCP_CMD_VERIFY,
00123     SRCP_CMD_GETDESC
00124 } SRCP_COMMANDS;
00125 
00126 
00127 // Enumerator for system device states
00128 typedef enum
00129 {
00130 // The unsynchronized states:
00131     SRCP_DS_DISABLED = 0,   // Doing nothing.
00132     SRCP_DS_UNKNOWN,        // Initial state of each new device.
00133 
00134 // The synchronized states:
00135     SRCP_DS_NOT_DEFINED,    // Server does not know anything.
00136     SRCP_DS_IDLE            // The destination state!
00137 } SRCP_DEVICESTATE;
00138 
00139 
00140 typedef enum 
00141 {
00142     SRCPC_SM_CONNECT_COMMAND = 0,
00143     SRCPC_SM_CONNECT_WAIT_COMMAND,
00144     SRCPC_SM_CONNECTED_COMMAND,
00145     SRCPC_SM_CONNECT_WAIT_INFO,
00146     SRCPC_SM_CONNECTED_INFO,
00147     SRCPC_SM_CONNECTED,
00148     SRCPC_SM_DELAY_CLOSING,
00149     SRCPC_SM_CLOSING,
00150     SRCPC_SM_WAIT_FOR_CLOSING,
00151     SRCPC_SM_ERROR_CONNECT,
00152     SRCPC_SM_CLOSED
00153 } SM_SRCP_CONNECTING;
00154 
00155 
00156 // ////////////////////////////////////////////////////////////////////////////
00157 // Local structure typedefs
00158 // ////////////////////////////////////////////////////////////////////////////
00159 
00160 typedef struct __attribute__((__packed__)) srcpsocket_struct
00161 {
00162     BYTE        u8Socket;
00163     BOOL        bCommand;
00164 } SSRCPSOCKET;
00165 
00166 
00167 typedef struct __attribute__((__packed__)) _srcpnet_state
00168 {
00169     SSRCPSOCKET sCommand;
00170     SSRCPSOCKET sInfo;
00171 } SSRCPSTATE;
00172 
00173 
00174 typedef struct __attribute__((__packed__))
00175 {
00176     BYTE u8Bus;
00177     SRCP_DEVTYPE eDevType;
00178 
00179     union
00180     {
00181         struct
00182         {
00183             DWORD u32Addr;
00184             BYTE au8Proto[4];
00185             BYTE u8Port;
00186         } sGA;
00187 
00188         struct
00189         {
00190             DWORD u32Addr;
00191             BYTE au8Proto[4];
00192             SHORT s16MaxV;
00193             BYTE u8MaxSteps;
00194             BYTE u8NrFunc;
00195             DWORD u32FuncAllocMask;
00196         } sGL;
00197 
00198         struct
00199         {
00200             DWORD u32Addr;
00201             SRCP_DEVTYPE eDevType;
00202         } sLock;
00203     } uStat;
00204 
00205     union
00206     {
00207         BOOL bPowerState;   // TRUE means ON, FALSE means OFF
00208         struct
00209         {
00210             BYTE u8Value;
00211                 #define     GAPORT_INACTIVE 0x00
00212                 #define     GAPORT_ACTIVE   0x01
00213         } sGA;
00214 
00215         struct
00216         {
00217             BYTE u8Dir;
00218                 #define     DIR_BACKWARD    0x00
00219                 #define     DIR_FORWARD     0x01
00220                 #define     DIR_ESTOP       0x02
00221                 #define     DIR_UNCHANGED   0x03
00222             SHORT s16ActV;
00223             DWORD u32FuncBitField;
00224             BYTE u8FuncGroup;   // The displayed function group (0=1-4,1=5-8,2=9-12)
00225             SHORT s16ServerV;   // This value indicates the servers speed.
00226         } sGL;
00227 
00228         struct
00229         {
00230             DWORD u32SessionId;
00231         } sLock;
00232     } uDyn;
00233 } SRCP_PRM;
00234 
00235 
00236 typedef struct __attribute__((__packed__))
00237 {
00238     DWORD   u32Seconds;
00239     WORD    u16Milliseconds;
00240 } SRCP_TIME;
00241 
00242 
00243 typedef struct __attribute__((__packed__))
00244 {
00245     SRCP_DEVTYPE eDevType;
00246     SRCP_DEVICESTATE eDevState;
00247     WORD u16LastErrorCode;
00248     SRCP_TIME sLastUpdate;
00249     struct
00250     {
00251         BYTE bNewData : 1;
00252     } sFlags;
00253     BYTE u8Bus;
00254     // Device specific (sPower, sLock, sGA, sGL) 
00255     // structure starts here.
00256 } SRCP_DEVICE;
00257 
00258 
00259 typedef struct __attribute__((__packed__))
00260 {
00261     BOOL bPowerState;   // TRUE means ON, FALSE means OFF
00262 } sPower;
00263 
00264 
00265 typedef struct __attribute__((__packed__))
00266 {
00267     DWORD u32Addr;  // This field is fixed to this position!!!
00268     DWORD u32Duration;
00269     DWORD u32SessionId;
00270     SRCP_DEVTYPE eDevType;
00271 } sLock;
00272 
00273 
00274 typedef struct __attribute__((__packed__))
00275 { 
00276     DWORD u32Addr;  // This field is fixed to this position!
00277     BYTE au8Proto[SRCP_PROTO_MAXLEN+1];// This field is fixed to this position!
00278     BYTE au8Name[SRCP_NAME_MAXLEN+1]; // This field is fixed to this position!
00279     BYTE u8MinPort;
00280     BYTE u8MaxPort;
00281     BYTE u8Port;
00282     DWORD s32Delay;
00283     BYTE u8Value;
00284         #define     GAPORT_INACTIVE 0x00
00285         #define     GAPORT_ACTIVE   0x01
00286 } sGA;
00287 
00288 
00289 typedef struct __attribute__((__packed__))
00290 { 
00291     DWORD u32Addr;  // This field is fixed to this position!
00292     BYTE au8Proto[SRCP_PROTO_MAXLEN+1];// This field is fixed to this position!
00293     BYTE au8Name[SRCP_NAME_MAXLEN+1]; // This field is fixed to this position!
00294     BYTE u8MaxSteps;
00295     BYTE u8NrFunc;
00296     SHORT s16MaxV;
00297     struct
00298     {
00299         BYTE u5Res : 5;
00300         BYTE bUnit : 1;
00301         BYTE u2Dir : 2;
00302             #define     DIR_BACKWARD    0x00
00303             #define     DIR_FORWARD     0x01
00304             #define     DIR_ESTOP       0x02
00305             #define     DIR_UNCHANGED   0x03
00306     } sGLFlags;
00307 
00308     SHORT s16ActV;
00309     DWORD u32FuncBitField;
00310     DWORD u32FuncAllocMask;
00311     DWORD u32FuncToggleMask;
00312     BYTE u8FuncGroup;   // The displayed function group (0=1-4,1=5-8,2=9-12)
00313     SHORT s16ServerV;   // This value indicates the servers speed.
00314 } sGL;
00315 
00316 
00317 typedef struct __attribute__((__packed__))
00318 {
00319     BYTE    u8BusNr;
00320     DWORD   u32Address;
00321     BYTE    au8Proto[SRCP_PROTO_MAXLEN+1];
00322     BYTE    u8MaxSteps;
00323     BYTE    u8NrFunc;
00324 } sServerCacheEntry;
00325 
00326 
00327 typedef struct __attribute__((__packed__))
00328 {
00329     BYTE    u8BusNr;
00330     DWORD   u32Address;
00331     BYTE    au8Proto[SRCP_PROTO_MAXLEN+1];
00332     BYTE    au8Name[SRCP_NAME_MAXLEN+1];
00333 
00334     union
00335     {
00336         struct
00337         {
00338             BYTE u8MaxSteps;
00339             BYTE u8NrFunc;
00340             WORD u16MaxV;
00341             DWORD u32FunctionToggleMask;
00342         } sGLSpec;
00343         
00344         struct
00345         {
00346             BYTE u8MinP;
00347             BYTE u8MaxP;
00348             long s32Delay;
00349         } sGASpec;
00350     } uSpec;
00351 } sStaticDeviceData;
00352 
00353 
00354 // ////////////////////////////////////////////////////////////////////////////
00355 // Local variables
00356 // ////////////////////////////////////////////////////////////////////////////
00357 
00358 static SSRCPSTATE _sSRCPState;
00359 
00360 static SRCP_SM _eSRCPsm;
00361 
00362 static SRCP_COMMANDS _eLastSentCommand;
00363 
00364 static SM_SRCP_CONNECTING _eSRCPCsm;
00365 
00366 // This variable stores the index (for _apsDevices) of the device which has 
00367 // sent the last command.
00368 static SRCP_DEVICE * _pLastCommandDevice;
00369 
00370 SRCP_DEVICE * _apsDevices[MAX_SRCP_DEVICES];
00371 
00372 static BOOL _bSrvReqIsInProgress;
00373 static DWORD _bServerRequestTime;
00374 
00375 static SRCP_DEVICE * _psNewDevice;
00376 static BYTE _u8LastEEPROMSetIdx;
00377 
00378 static SRCP_DEVICE * _psActualDevice;
00379 
00380 static SRCP_HANDSHAKE_SM _eHSState; // State for handshaking
00381 
00382 static BYTE _u8LastSelectedProtoId;
00383 static sStaticDeviceData _sNewDeviceStaticData;
00384 
00385 static BYTE _au8ActiveProtos[MAX_PROTO_SLOTS+2]; // One more for server cache.
00386 static sServerCacheEntry * _apsSelectCache;
00387 static BYTE * _pActiveEEPROMSetList;
00388 
00389 #pragma udata SRCPGLCache
00390 static sServerCacheEntry _asServerCache[SERVER_CACHE_ENTRIES];
00391 #pragma udata
00392 
00393 
00394 // ////////////////////////////////////////////////////////////////////////////
00395 // Local function prototypes
00396 // ////////////////////////////////////////////////////////////////////////////
00397 
00398 // Connection and handshake functions
00399 void _startHandShake(void);
00400 SRCP_HANDSHAKE_RETCODE _eHandShake(SSRCPSOCKET * hSRCP);
00401 
00402 
00403 // View functions
00404 static void _updateView(SRCP_DEVICE * pDev);
00405 static void _displayNoData(void);
00406 static void _displayGLData(SRCP_DEVICE * pDev);
00407 static void _displayGAData(SRCP_DEVICE * pDev);
00408 static void _displayPower(SRCP_DEVICE * pDev);
00409 static void _showServerError(WORD u16Code);
00410 
00411 
00412 // Input functions
00413 static void _updateInput(SRCP_DEVICE * pDev);
00414 static BOOL _bGetGLInput(sGL * pGL);
00415 static BOOL _bGetGAInput(SRCP_DEVICE * pPrm);
00416 
00417 
00418 // SRCP message functions
00419 static BOOL _startParsing(BYTE u8Socket, SRCP_TIME * psTime, WORD * pu16Code);
00420 static BOOL _bParseLine(BYTE u8Socket, WORD u16Code, SRCP_PRM * pPrm);
00421 static BOOL _bTCPDevType(WORD u16Code, SRCP_DEVTYPE * pDev, BYTE * au8Buf);
00422 static void _answerReceived(SRCP_DEVICE* pDev, WORD u16Code, SRCP_TIME* pTime);
00423 static BOOL _bSendSRCPMessage(SRCP_COMMANDS eCommand, SRCP_DEVICE * pDev);
00424 static BOOL _bDevTypeTCP(SRCP_DEVTYPE eDevType, SRCP_COMMANDS eCommand);
00425 static BOOL _bLookForEnd(BYTE u8Socket);
00426 static BOOL _bGetNextWord(BYTE u8Socket, BYTE * pu8Buf, BYTE u8BufSize, 
00427                                                                   BOOL * bEnd);
00428 
00429 // Device functions
00430 static void _deviceSM(SRCP_DEVICE * pDev);
00431 static BOOL _bIsDeviceMatching(SRCP_DEVICE * psDevice, SRCP_PRM * pPrm);
00432 static SRCP_DEVICE * _pGetPowerDevice(BYTE u8Bus);
00433 static void _updateData(SRCP_DEVICE * pDev, WORD u16Code, SRCP_PRM * pNewPrm);
00434 static SRCP_DEVICE* _psAddDevice(SRCP_DEVTYPE eDevType, BYTE u8Bus, void*pPrm);
00435 static BOOL _bIsInitAllowed(SRCP_DEVTYPE eDevType);
00436 static SHORT _s16computeRealSpeed(SHORT s16MaxV, SHORT s16ServerMaxV, 
00437                                                          SHORT s16ServerSpeed);
00438 static SRCP_DEVICE * _psInitializeNewDevice(SRCP_DEVTYPE eDevType, BYTE u8Bus,
00439                                             void * pPrm);
00440 static DWORD _u32GetAddress(SRCP_DEVICE * psDevice);
00441 static void _refreshDeviceList(void);
00442 static SRCP_DEVICE * _pTakeOverDevice(SRCP_DEVICE * pDevice);
00443 static SRCP_DEVICE * _pGetLatestGL(void);
00444 static SRCP_DEVICE * _pGetLatestGA(void);
00445 static void _fillPrmGL(sGL * psNewGL, sStaticDeviceData * psStaticData);
00446 static void _fillPrmGA(sGA * psNewGA, sStaticDeviceData * psStaticData);
00447 static void _getInitData(SRCP_DEVICE * pDev, char * pString);
00448 
00449 
00450 // Protocol parameter functions
00451 static void _getProtoName(BYTE u8ProtoId, BYTE * pString);
00452 static void _getProtoMinMax(BYTE u8ProtoId, WORD* pu16MinAdd, 
00453                                                              WORD* pu16MaxAdd);
00454 static BYTE _u8GenerateActiveProtoList(BOOL bGL, BYTE u8Default);
00455 static void _getProtoFromEEPROM(BYTE u8ProtoId, SPPROTOCOL * psProto);
00456 static BOOL _bGetStaticParameterFromProto(BYTE u8ProtoId, sStaticDeviceData * psPrm);
00457 
00458 
00459 // EEPROM set functions
00460 static BYTE _u8AddEntryToEEPROM(BYTE u8RawQuickIdx, SRCP_DEVICE * pDevice);
00461 static BOOL _bCheckForSelectedSet(sStaticDeviceData * psDeviceData, BOOL bEncoder);
00462 static void _storeNameToEEPROM(BYTE u8EEPROMSetIdx, BYTE *pName);
00463 static BYTE _prepareEEPROMSetInput(BOOL bGL);
00464 static void _destructEEPROMSet(void);
00465 
00466 
00467 // Server cache functions
00468 static void _UpdateServerCache(SRCP_PRM * pPrm, BOOL bAdd);
00469 static BOOL _bPrepareServerCacheInput(void);
00470 static BOOL _bGetStaticParameterFromCache(BYTE u8CacheId, sStaticDeviceData * psPrm);
00471 static void _destructServerCache(void);
00472 
00473 
00474 // ////////////////////////////////////////////////////////////////////////////
00475 // ////////////////////////////////////////////////////////////////////////////
00476 
00477 void SRCP_CancelInputProtoDialog(void)
00478 {
00479     if ((_eSRCPsm == SRCP_SELECT_PROTOCOL)||
00480         (_eSRCPsm == SRCP_SELECT_DEVICE_ADDRESS))
00481     {
00482         InputButtonReset(ALL_BTN);
00483         _eSRCPsm = SRCP_PREPARE_MAIN;
00484     }
00485 }
00486 
00487 // ////////////////////////////////////////////////////////////////////////////
00488 // ////////////////////////////////////////////////////////////////////////////
00489 
00490 void SRCP_CancelInputSetDialog(void)
00491 {
00492     if (_eSRCPsm == SRCP_SELECT_EEPROMSET)
00493     {
00494         InputButtonReset(ALL_BTN);
00495         _eSRCPsm = SRCP_PREPARE_MAIN;
00496     }
00497 }
00498 
00499 // ////////////////////////////////////////////////////////////////////////////
00500 // ////////////////////////////////////////////////////////////////////////////
00501 
00502 void SRCPRestoreToFactory(void)
00503 {
00504     SPPROTOCOL lococonf;
00505     BYTE i = 0;
00506     SPSET eepromset;
00507     WORD address;
00508 
00509 
00510     // ////////////////////////////////////////////////////////////////////////
00511     // Restoring srcp configuration data:
00512     memset((void *)&sPSRCPConfig, 0, sizeof(SPSRCPCONFIG));
00513     // The server cache is standard:
00514     sPSRCPConfig.u8DefaultGLProtoId = SRCP_SERVERCACHE_ID; 
00515     sPSRCPConfig.u8DefaultGAProtoId = MAX_PROTO_SLOTS;
00516     sPSRCPConfig.sFlags.bGAAskForProto = TRUE;
00517     sPSRCPConfig.sFlags.bGLAskForProto = TRUE;
00518     sPSRCPConfig.s32GADelay = 500;  // in milliseconds.
00519 
00520     XEEWriteArray(SRCP_CONFIG_EEPROM_ADD, (BYTE *)&sPSRCPConfig, sizeof(SPSRCPCONFIG));
00521 
00522 
00523     // ////////////////////////////////////////////////////////////////////////
00524     // Restoring loco protocol specific data:
00525 
00526     strcpypgm2ram(lococonf.au8Desc, (ROM char *)"Old Motorola");
00527     strcpypgm2ram(lococonf.au8Proto, (ROM char *)"M 1");
00528     lococonf.sFlags.bGL = TRUE;
00529     lococonf.sFlags.bActive = TRUE;
00530     lococonf.u8Bus = 1;
00531     lococonf.u16MinAdd = 1; 
00532     lococonf.u16MaxAdd = 80;
00533     lococonf.uSpec.sGL.u8MaxSteps = 14;
00534     lococonf.uSpec.sGL.u8NrFunc = 1;
00535     XEEWriteArray(EEPROM_GLS, (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00536 
00537 
00538     strcpypgm2ram(lococonf.au8Desc, (ROM char *)"New Motorola 1");
00539     strcpypgm2ram(lococonf.au8Proto, (ROM char *)"M 2");
00540     lococonf.sFlags.bGL = TRUE;
00541     lococonf.sFlags.bActive = TRUE;
00542     lococonf.u8Bus = 1;
00543     lococonf.u16MinAdd = 1; 
00544     lococonf.u16MaxAdd = 255;
00545     lococonf.uSpec.sGL.u8MaxSteps = 28;
00546     lococonf.uSpec.sGL.u8NrFunc = 5;
00547     XEEWriteArray(EEPROM_GLS + 1*sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00548 
00549 
00550     strcpypgm2ram(lococonf.au8Desc, (ROM char * )"NMRA Base");
00551     strcpypgm2ram(lococonf.au8Proto, (ROM char * )"N 1");
00552     lococonf.sFlags.bGL = TRUE;
00553     lococonf.sFlags.bActive = TRUE;
00554     lococonf.u8Bus = 2;
00555     lococonf.u16MinAdd = 1; 
00556     lococonf.u16MaxAdd = 99;
00557     lococonf.uSpec.sGL.u8MaxSteps = 14;
00558     lococonf.uSpec.sGL.u8NrFunc = 0;
00559     XEEWriteArray(EEPROM_GLS + 2*sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00560 
00561 
00562     strcpypgm2ram(lococonf.au8Desc, (ROM char *) "NMRA Extended 2");
00563     strcpypgm2ram(lococonf.au8Proto, (ROM char *) "N 1");
00564     lococonf.sFlags.bGL = TRUE;
00565     lococonf.sFlags.bActive = TRUE;
00566     lococonf.u8Bus = 2;
00567     lococonf.u16MinAdd = 1; 
00568     lococonf.u16MaxAdd = 99;
00569     lococonf.uSpec.sGL.u8MaxSteps = 28;
00570     lococonf.uSpec.sGL.u8NrFunc = 5;
00571     XEEWriteArray(EEPROM_GLS + 3*sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00572 
00573 
00574     // Delete the other protocol slots.
00575     memset(&lococonf, 0, sizeof(SPPROTOCOL));
00576     lococonf.sFlags.bGL = TRUE;
00577 
00578     for (i = 4; i < MAX_PROTO_SLOTS; i++)
00579     {
00580         XEEWriteArray(EEPROM_GLS + i*sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00581     }
00582 
00583 
00584     // ////////////////////////////////////////////////////////////////////////
00585     // Restoring accessory protocol specific data:
00586     strcpypgm2ram(lococonf.au8Desc, (ROM char *) "Motorola");
00587     strcpypgm2ram(lococonf.au8Proto, (ROM char *) "M");
00588     lococonf.sFlags.bGL = FALSE;
00589     lococonf.sFlags.bActive = TRUE;
00590     lococonf.u8Bus = 5;
00591     lococonf.u16MinAdd = 1; 
00592     lococonf.u16MaxAdd = 324;
00593     lococonf.uSpec.sGA.u8MinP = 0;
00594     lococonf.uSpec.sGA.u8MaxP = 1;
00595     XEEWriteArray(EEPROM_GAS, (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00596 
00597     strcpypgm2ram(lococonf.au8Desc, (ROM char *) "NMRA-DCC");
00598     strcpypgm2ram(lococonf.au8Proto, (ROM char *) "N");
00599     lococonf.sFlags.bGL = FALSE;
00600     lococonf.sFlags.bActive = TRUE;
00601     lococonf.u8Bus = 6;
00602     lococonf.u16MinAdd = 1; 
00603     lococonf.u16MaxAdd = 511;
00604     lococonf.uSpec.sGA.u8MinP = 0;
00605     lococonf.uSpec.sGA.u8MaxP = 1;
00606 
00607     XEEWriteArray(EEPROM_GAS + sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00608 
00609     // Delete the other protocol slots.
00610     memset(&lococonf, 0, sizeof(SPPROTOCOL));
00611 
00612     for (i = 2; i < MAX_PROTO_SLOTS; i++)
00613     {
00614         XEEWriteArray(EEPROM_GAS + i*sizeof(SPPROTOCOL), (BYTE *)&lococonf, sizeof(SPPROTOCOL));
00615     }
00616 
00617 
00618     // Prepare the quick set area.
00619     memset(&eepromset, 0, sizeof(SPSET));
00620     eepromset.sFlags.bGL = TRUE;
00621     address = SRCP_SETS_EEPROM_ADD;
00622     for (i = 0; i < SRCP_GLEEPROMSET_COUNT; i++)
00623     {
00624         XEEWriteArray(address, (BYTE *)&eepromset, sizeof(SPSET));
00625         address += sizeof(SPSET);
00626     }
00627 
00628     eepromset.sFlags.bGL = FALSE;
00629     for (i = 0; i < SRCP_GAEEPROMSET_COUNT; i++)
00630     {
00631         XEEWriteArray(address, (BYTE *)&eepromset, sizeof(SPSET));
00632         address += sizeof(SPSET);
00633     }
00634 
00635 }
00636 
00637 // ////////////////////////////////////////////////////////////////////////////
00638 // ////////////////////////////////////////////////////////////////////////////
00639 
00640 void SRCPLocoDirModeHasChanged(void)
00641 {
00642     if ((_psActualDevice) && (_psActualDevice->eDevType == SRCP_DT_GL))
00643     {
00644         _psActualDevice->sFlags.bNewData = TRUE;
00645     }
00646 }
00647 
00648 // ////////////////////////////////////////////////////////////////////////////
00649 // ////////////////////////////////////////////////////////////////////////////
00650 
00651 void SRCPInitialInit(void)
00652 {
00653     // Get configuration data from EEPROM...
00654     XEEReadArray(SRCP_CONFIG_EEPROM_ADD, (BYTE*)&sPSRCPConfig, sizeof(SPSRCPCONFIG));
00655 
00656     _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
00657     _sSRCPState.sInfo.u8Socket = INVALID_SOCKET;
00658 }
00659 
00660 // ////////////////////////////////////////////////////////////////////////////
00661 // ////////////////////////////////////////////////////////////////////////////
00662 
00663 BOOL SRCPMain(void)
00664 {
00665     // Check for Command and Info messages and feed the device state machine.
00666 
00667     SRCP_TIME time;
00668     WORD code;
00669     BYTE i = 0;
00670 
00671 
00672     // ////////////////////////////////////////////////////////////////////////
00673     // Checking for a hanging server communication...
00674     if ((_bSrvReqIsInProgress == TRUE)&&(_bServerRequestTime < TickGet()))
00675     {
00676         _bSrvReqIsInProgress = FALSE;
00677     }
00678 
00679 
00680     // ////////////////////////////////////////////////////////////////////////
00681     // Check the command socket!
00682     if (TCPWasReset(_sSRCPState.sCommand.u8Socket))
00683     {
00684         _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
00685         SRCPStartDisconnect();
00686         return FALSE;
00687     }
00688 
00689     if (TCPIsGetReady(_sSRCPState.sCommand.u8Socket))
00690     {
00691         if (_pLastCommandDevice && _startParsing(_sSRCPState.sCommand.u8Socket, &time, &code))
00692         {
00693             SRCP_PRM prm;
00694             BOOL ret;
00695 
00696             // We are pretty sure, that the incoming packet belongs to the 
00697             // device the last command was sent to. This will not be  
00698             // checked here!
00699             _bSrvReqIsInProgress = FALSE;  // Acknowledge the sent command.
00700             _answerReceived(_pLastCommandDevice, code, &time);
00701 
00702             if (_bParseLine(_sSRCPState.sCommand.u8Socket,code, &prm))
00703             {
00704                 // Update the data.
00705                 _updateData(_pLastCommandDevice, code, &prm);
00706             }
00707         }
00708     
00709         // Only one command answer is expected. Throw away the rest of the 
00710         // frame.
00711         TCPDiscard(_sSRCPState.sCommand.u8Socket);
00712     }
00713 
00714 
00715     // ////////////////////////////////////////////////////////////////////////
00716     // Check the info socket!
00717     if(TCPWasReset(_sSRCPState.sInfo.u8Socket))
00718     {
00719         _sSRCPState.sInfo.u8Socket = INVALID_SOCKET;
00720         SRCPStartDisconnect();
00721         return FALSE;
00722     }
00723     while (TCPIsGetReady(_sSRCPState.sInfo.u8Socket))
00724     {
00725         // Check all the lines which are included in the received frame.
00726 
00727         // Obtain the time and the code!
00728         if (_startParsing(_sSRCPState.sInfo.u8Socket, &time, &code))
00729         {
00730             SRCP_PRM prm;
00731             if (_bParseLine(_sSRCPState.sInfo.u8Socket, code, &prm))
00732             {
00733                 // Update the internal list cache of server devices.
00734                 if (code == 101)
00735                 {
00736                     // Add to cache.
00737                     _UpdateServerCache(&prm, TRUE);
00738                 }
00739                 else if (code == 102)
00740                 {
00741                     // Remove from cache.
00742                     _UpdateServerCache(&prm, FALSE);
00743                 }
00744 
00745                 // Search for a matching device in the device list.
00746                 for(i = 0; i < MAX_SRCP_DEVICES; i++)
00747                 {
00748                     if (_bIsDeviceMatching(_apsDevices[i], &prm))
00749                     {
00750                         _answerReceived(_apsDevices[i], code, &time);
00751                         _updateData(_apsDevices[i], code, &prm);
00752                     }
00753                 }
00754             }
00755         }
00756     }
00757 
00758 
00759     // ////////////////////////////////////////////////////////////////////////
00760     // Execute all the state machines of the devices if we can send new 
00761     // commands.
00762     i = 0;
00763     while((_bSrvReqIsInProgress == FALSE)&&(i < MAX_SRCP_DEVICES))
00764     {
00765         _deviceSM(_apsDevices[i++]);
00766     }
00767 
00768 
00769     // ////////////////////////////////////////////////////////////////////////
00770     // Check for the power device. This view and input is independent from the
00771     // SRCP state machine. So the power state can be controlled also in error
00772     // states and in the input dialog states.
00773     if (_psActualDevice)
00774     {
00775         SRCP_DEVICE * pPowerDev = _pGetPowerDevice(_psActualDevice->u8Bus);
00776 
00777         if (pPowerDev==NULL)
00778         {
00779             // The power device was disabled! The actual device is strongly
00780             // linked to this power device and can only be used with a well
00781             // configured power device. Disable the actual device.
00782 
00783             _psActualDevice->eDevState = SRCP_DS_DISABLED;
00784         }
00785         else
00786         {
00787             sPower * pPwr = (sPower*)(&pPowerDev[1]);
00788             _updateView(pPowerDev);
00789 
00790             if (pPowerDev->eDevState == SRCP_DS_DISABLED)
00791             {
00792                 // The power device was disabled! The actual device is strongly
00793                 // linked to this power device and can only be used with a well
00794                 // configured power device. Disable the actual device.
00795     
00796                 _psActualDevice->eDevState = SRCP_DS_DISABLED;
00797             }
00798             else if (bInputButtonPushed(PWR_BTN) == TRUE)
00799             {
00800                 // Toggle the power state.
00801                 pPwr->bPowerState = !(pPwr->bPowerState);
00802                 if (_bSendSRCPMessage(SRCP_CMD_SET, pPowerDev) == TRUE)
00803                 {
00804                     InputButtonReset(PWR_BTN);
00805                 }
00806 
00807                 // Retoggle the power state to stay synchronized with the view.
00808                 // The new state comes via an INFO message and updates the 
00809                 // view.
00810                 pPwr->bPowerState = !(pPwr->bPowerState);
00811             }
00812         }
00813     }
00814 
00815 
00816     // ////////////////////////////////////////////////////////////////////////
00817     // The Global SRCP Input and View State Machine
00818     switch (_eSRCPsm)
00819     {
00820     case SRCP_STARTUP:
00821         // This state is only called once after connect and handshake.
00822         InputButtonReset(ALL_BTN);
00823         OutSwitchOffAllLEDs();
00824         _eSRCPsm = SRCP_MAIN;
00825         break;
00826 
00827     case SRCP_MAIN:
00828         if (_psActualDevice)
00829         {
00830             if ((_psActualDevice->eDevType == SRCP_DT_GL) && bInputButtonPushedLong(SEL_BTN))
00831             {
00832                 // The loco select button was pushed for a long time, the user
00833                 // wants to store the loco as a quick or loco db set in eeprom.
00834                 InputButtonReset(ALL_BTN);
00835                 InputEncoderInit(4, 0, SRCP_GLEEPROMSET_COUNT-1, 0);
00836                 _eSRCPsm = SRCP_SELECT_EEPROM_SET_TO_SAVE;
00837                 break;
00838             }
00839             else if ((_psActualDevice->eDevType == SRCP_DT_GA) && bInputButtonPushedLong(ACC_BTN))
00840             {
00841                 // The accessory select button was pushed for a long time, the user
00842                 // wants to store the acc at a quick set in eeprom.
00843                 InputButtonReset(ALL_BTN);
00844                 InputEncoderInit(0, 0, SRCP_GAEEPROMSET_COUNT-1, 0);
00845                 _eSRCPsm = SRCP_SELECT_EEPROM_SET_TO_SAVE;
00846                 break;
00847             }
00848         }
00849 
00850         if (bInputButtonPushed(SEL_BTN) == TRUE)
00851         {
00852             BYTE protoCount;
00853 
00854             // Reset the button for new inputs:
00855             InputButtonReset(ALL_BTN);
00856             OutSetLED(LED_SEL, LED_ON);
00857 
00858             if (_psActualDevice && (_psActualDevice->eDevType==SRCP_DT_GA))
00859             {
00860                 // Switch over to the last known GL set.
00861                 if (_pGetLatestGL())
00862                 {
00863                     _psNewDevice = _pGetLatestGL();
00864                     _eSRCPsm = SRCP_WAIT_FOR_IDLE_DEVICE;
00865                     break;
00866                 }
00867             }
00868 
00869             protoCount = _u8GenerateActiveProtoList(TRUE, sPSRCPConfig.u8DefaultGLProtoId);
00870             if (protoCount==0)
00871             {
00872                 // We never should come in here (at least the server cache is
00873                 // selectable).
00874                 OutSetLED(LED_SEL, LED_OFF);
00875                 break;
00876             }
00877 
00878             if ((sPSRCPConfig.sFlags.bGLAskForProto == TRUE) && (protoCount>1))
00879             {
00880                 InputEncoderInit(0, 0, protoCount-1, 0);
00881                 InputButtonReset(ENC_BTN);
00882                 _eSRCPsm = SRCP_SELECT_PROTOCOL;
00883             }
00884             else
00885             {
00886                 _u8LastSelectedProtoId = sPSRCPConfig.u8DefaultGLProtoId;
00887                 _eSRCPsm = SRCP_PROTOCOL_SELECTED;
00888             }
00889 
00890             break;
00891         }
00892         else if (bInputButtonPushed(ACC_BTN) == TRUE)
00893         {   
00894             BYTE protoCount;
00895 
00896             // Reset the button for new inputs:
00897             InputButtonReset(ALL_BTN);
00898             OutSetLED(LED_ACC, LED_ON);
00899 
00900             if (_psActualDevice && (_psActualDevice->eDevType==SRCP_DT_GL))
00901             {
00902                 // Switch over to the last known GA set.
00903                 if (_pGetLatestGA())
00904                 {
00905                     _psNewDevice = _pGetLatestGA();
00906                     _eSRCPsm = SRCP_WAIT_FOR_IDLE_DEVICE;
00907                     break;
00908                 }
00909             }
00910 
00911             protoCount = _u8GenerateActiveProtoList(FALSE, sPSRCPConfig.u8DefaultGAProtoId);
00912             if (protoCount == 0)
00913             {
00914                 // No entry in the protocol list! Finish up! 
00915                 OutSetLED(LED_ACC, LED_OFF);
00916                 break;
00917             }
00918 
00919             if ((sPSRCPConfig.sFlags.bGAAskForProto == TRUE) && (protoCount>1))
00920             {
00921                 InputEncoderInit(0, 0, protoCount-1, 0);
00922                 InputButtonReset(ENC_BTN);
00923                 _eSRCPsm = SRCP_SELECT_PROTOCOL;
00924             }
00925             else
00926             {
00927                 _u8LastSelectedProtoId = sPSRCPConfig.u8DefaultGAProtoId;
00928                 _eSRCPsm = SRCP_PROTOCOL_SELECTED;
00929             }
00930 
00931             break;
00932         }
00933 
00934 
00935         // Is there a configured device for view?
00936         if (_psActualDevice == NULL)
00937         {
00938             break;
00939         }
00940 
00941         if (_psActualDevice->eDevState == SRCP_DS_DISABLED)
00942         {
00943             // The device is disabled (terminated)!
00944             _displayNoData();
00945             _psActualDevice = NULL;
00946             break;
00947         }
00948 
00949         // Check for changed view of the actual device.
00950         _updateView(_psActualDevice);
00951 
00952         _updateInput(_psActualDevice);
00953 
00954         break;
00955 
00956     case SRCP_SELECT_EEPROM_SET_TO_SAVE:
00957         _u8LastEEPROMSetIdx = 0xFF;
00958         if (bInputButtonPushed(F1_BTN) == TRUE)
00959         {
00960             _u8LastEEPROMSetIdx = 0;
00961         }
00962         else if (bInputButtonPushed(F2_BTN) == TRUE)
00963         {
00964             _u8LastEEPROMSetIdx = 1;
00965         }
00966         else if (bInputButtonPushed(F3_BTN) == TRUE)
00967         {
00968             _u8LastEEPROMSetIdx = 2;
00969         }
00970         else if (bInputButtonPushed(F4_BTN) == TRUE)
00971         {
00972             _u8LastEEPROMSetIdx = 3;
00973         }
00974         else if (bInputButtonPushedOnce(ENC_BTN) == TRUE)
00975         {
00976             _u8LastEEPROMSetIdx = (BYTE) s16InputEncoderGetValue();
00977         }
00978 
00979         if (_u8LastEEPROMSetIdx != 0xFF)
00980         {
00981             BOOL ret;
00982 
00983             ret = bInitInputDialog(DEVICE_NAME_PTR(_psActualDevice), 
00984                                    DIALOG_ALL_LETTERS, 0,
00985                                    SRCP_NAME_MAXLEN,
00986                                    DIALOG_ESC_FLAG | DIALOG_DESCRIPTION_FLAG |
00987                                    DIALOG_NEXT_FLAG | DIALOG_BACKSPACE_FLAG);
00988             
00989             if (ret == TRUE)
00990             {
00991                 _eSRCPsm = SRCP_ENTER_NAME;
00992             }
00993             else
00994             {
00995                 _eSRCPsm = SRCP_MAIN;
00996             }
00997         }
00998         else if (bInputEncoderValueChanged() == TRUE)
00999         {
01000             BYTE setidx = s16InputEncoderGetValue();
01001             lcd_addr1 = 0;
01002             StrTbl_GetString(lcdram_row1, STRTBLID_DATABASE);
01003             // The second row is for the set id.
01004             sprintf(lcdram_row2, StrTbl_cau8GetStringPointer(STRTBLID_POSITION_X), setidx+1);
01005             lcd_addr2 = 0;
01006             lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_ROW2_MASK;
01007         }
01008         break;      
01009 
01010     case SRCP_ENTER_NAME:
01011         if (bHandleInputDialog()==TRUE)
01012         {
01013             BYTE * pName = DEVICE_NAME_PTR(_psActualDevice);
01014             if (FiniDialog(pName) == DIALOG_FINI_OK)
01015             {
01016                 // Store the current device into the quick storage.
01017                 _u8LastEEPROMSetIdx = _u8AddEntryToEEPROM(_u8LastEEPROMSetIdx, _psActualDevice);
01018                 
01019                 // Remember the new name.
01020                 _storeNameToEEPROM(_u8LastEEPROMSetIdx, pName);
01021             }
01022             _eSRCPsm = SRCP_PREPARE_MAIN;
01023         }
01024         break;
01025 
01026     case SRCP_SELECT_PROTOCOL:
01027         // Thats the protocol dialog. The user chooses one of the preconfigured
01028         // protocols.
01029         if (_bCheckForSelectedSet(&_sNewDeviceStaticData, FALSE) == TRUE)
01030         {
01031             // Quick select (via the FX-buttons):
01032             _eSRCPsm = SRCP_INIT_DEVICE;
01033         }       
01034         else if (bInputButtonPushed(ENC_BTN) == TRUE)
01035         {
01036             _u8LastSelectedProtoId = _au8ActiveProtos[s16InputEncoderGetValue()];
01037             _eSRCPsm = SRCP_PROTOCOL_SELECTED;
01038         }   
01039         else if (bInputEncoderValueChanged() == TRUE)
01040         {
01041             BYTE selected = s16InputEncoderGetValue();
01042             lcd_addr1 = 0;
01043             StrTbl_GetString(lcdram_row1, STRTBLID_PROTOCOL);
01044             // The second row is for the protocol name
01045             if (_au8ActiveProtos[selected]==SRCP_SERVERCACHE_ID)
01046             {
01047                 StrTbl_GetString(lcdram_row2, STRTBLID_SERVER_CACHE);
01048             }
01049             else if (_au8ActiveProtos[selected]==SRCP_EEPROMSET_ID)
01050             {
01051                 StrTbl_GetString(lcdram_row2, STRTBLID_DATABASE);
01052             }
01053             else
01054             {
01055                 _getProtoName(_au8ActiveProtos[selected], lcdram_row2);
01056             }
01057             lcd_addr2 = 0;
01058             lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_ROW2_MASK;
01059         }
01060         else if (bInputButtonPushed(ACC_BTN) == TRUE)
01061         {
01062             if (OutGetLEDMode(LED_ACC) == LED_ON)
01063             {
01064                 InputButtonReset(ACC_BTN);
01065             }
01066             _eSRCPsm = SRCP_PREPARE_MAIN;
01067         }
01068         else if (bInputButtonPushed(SEL_BTN) == TRUE)
01069         {
01070             if (OutGetLEDMode(LED_SEL) == LED_ON)
01071             {
01072                 InputButtonReset(SEL_BTN);
01073             }
01074             _eSRCPsm = SRCP_PREPARE_MAIN;
01075         }
01076         break;
01077 
01078     case SRCP_PROTOCOL_SELECTED:
01079         switch(_u8LastSelectedProtoId)
01080         {
01081         case SRCP_SERVERCACHE_ID:
01082             if (_bPrepareServerCacheInput() == TRUE)
01083             {
01084                 _eSRCPsm = SRCP_SELECT_SERVER_CACHE;
01085             }
01086             else
01087             {
01088                 // \todo For test: Force to get into this state!
01089                 _eSRCPsm = SRCP_ERROR;
01090             }
01091             break;
01092 
01093         case SRCP_EEPROMSET_ID:
01094         {
01095             BOOL bGL = FALSE;
01096             BYTE entries;
01097             if (OutGetLEDMode(LED_SEL) == LED_ON)
01098             {
01099                 bGL = TRUE;
01100             }
01101 
01102             entries = _prepareEEPROMSetInput(bGL);
01103 
01104             if (entries == 0)
01105             {
01106                 _eSRCPsm = SRCP_ERROR;
01107             }
01108             else
01109             {
01110                 // Initialize the encoder.
01111                 InputButtonReset(ENC_BTN);
01112                 InputEncoderInit(0, 0, entries-1, 0);
01113                 _eSRCPsm = SRCP_SELECT_EEPROMSET;
01114             }
01115 
01116             break;
01117         }
01118 
01119         default:
01120             if (_bGetStaticParameterFromProto(_u8LastSelectedProtoId, &_sNewDeviceStaticData) == TRUE)
01121             {
01122                 // Fetch the address from user.
01123                 WORD min, max;
01124                 _getProtoMinMax(_u8LastSelectedProtoId, &min, &max);
01125                 InputEncoderInit(1, min, max, 0);
01126         
01127                 lcd_addr1 = 0;
01128                 StrTbl_GetString(lcdram_row1, STRTBLID_ADDRESS);
01129                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK;
01130 
01131                 InputButtonReset(ENC_BTN);
01132                 _eSRCPsm = SRCP_SELECT_DEVICE_ADDRESS;
01133             }
01134             else
01135             {
01136                 // \todo For test: Force to get into this state!
01137                 _eSRCPsm = SRCP_ERROR;
01138             }
01139         }
01140         break;
01141 
01142 
01143     case SRCP_SELECT_DEVICE_ADDRESS:
01144         // Thats the address setting dialog!
01145         if (_bCheckForSelectedSet(&_sNewDeviceStaticData, FALSE) == TRUE)
01146         {
01147             // One of the quick buttons was pushed!
01148             _eSRCPsm = SRCP_INIT_DEVICE;
01149         }
01150         else if (bInputButtonPushedOnce(ENC_BTN) == TRUE)
01151         {
01152             // Selection!
01153             _sNewDeviceStaticData.u32Address = s16InputEncoderGetValue();
01154             _eSRCPsm = SRCP_INIT_DEVICE;
01155         }
01156         else if (bInputEncoderValueChanged() == TRUE)
01157         {
01158             sprintf(lcdram_row2, (ROM char *) "%5hu", s16InputEncoderGetValue());
01159             lcd_status |= LCD_ROW2_MASK;
01160         }
01161         else if (bInputButtonPushed(ACC_BTN) == TRUE)
01162         {
01163             if (OutGetLEDMode(LED_ACC) == LED_ON)
01164             {
01165                 InputButtonReset(ACC_BTN);
01166             }
01167             _eSRCPsm = SRCP_PREPARE_MAIN;
01168         }
01169         else if (bInputButtonPushed(SEL_BTN) == TRUE)
01170         {
01171             if (OutGetLEDMode(LED_SEL) == LED_ON)
01172             {
01173                 InputButtonReset(SEL_BTN);
01174             }
01175             _eSRCPsm = SRCP_PREPARE_MAIN;
01176         }
01177         break;
01178 
01179 
01180     case SRCP_SELECT_EEPROMSET:
01181         if (_bCheckForSelectedSet(&_sNewDeviceStaticData, TRUE) == TRUE)
01182         {
01183             // Quick select (via the FX or the Encoder-buttons):
01184             _eSRCPsm = SRCP_INIT_DEVICE;
01185         }
01186         else if (bInputEncoderValueChanged() == TRUE)
01187         {
01188             SPSET set;
01189             BYTE setidx = _pActiveEEPROMSetList[s16InputEncoderGetValue()];
01190 
01191             // The first row indicates what should be input.
01192             lcd_addr1 = 0;
01193             StrTbl_GetString(lcdram_row1, STRTBLID_DATABASE);
01194 
01195             // The second row is for eeprom set name.
01196             XEEReadArray(SRCP_SETS_EEPROM_ADD + (sizeof(SPSET) * setidx), (BYTE *)&set, sizeof(SPSET));
01197 
01198             strncpy(lcdram_row2, set.au8Name, LCD_CHARS_IN_A_ROW);
01199             lcdram_row2[LCD_CHARS_IN_A_ROW] = 0;
01200             lcd_addr2 = 0;
01201             lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_ROW2_MASK;
01202         }
01203         else if (bInputButtonPushed(ACC_BTN) == TRUE)
01204         {
01205             if (OutGetLEDMode(LED_ACC) == LED_ON)
01206             {
01207                 InputButtonReset(ACC_BTN);
01208             }
01209             _eSRCPsm = SRCP_PREPARE_MAIN;
01210         }
01211         else if (bInputButtonPushed(SEL_BTN) == TRUE)
01212         {
01213             if (OutGetLEDMode(LED_SEL) == LED_ON)
01214             {
01215                 InputButtonReset(SEL_BTN);
01216             }
01217             _eSRCPsm = SRCP_PREPARE_MAIN;
01218         }
01219 
01220         if (_eSRCPsm != SRCP_SELECT_EEPROMSET)
01221         {
01222             // Leaving this state? Destructing the list.
01223             _destructEEPROMSet();
01224         }
01225         break;
01226 
01227 
01228     case SRCP_SELECT_SERVER_CACHE:
01229         if (_bCheckForSelectedSet(&_sNewDeviceStaticData, FALSE) == TRUE)
01230         {
01231             // Quick select (via the FX-buttons):
01232             _eSRCPsm = SRCP_INIT_DEVICE;
01233         }
01234         else if (bInputButtonPushed(ENC_BTN) == TRUE)
01235         {
01236             // Copy the cache data to the initialization structure.
01237             _bGetStaticParameterFromCache(s16InputEncoderGetValue(),&_sNewDeviceStaticData);
01238             _eSRCPsm = SRCP_INIT_DEVICE;
01239         }
01240         else if (bInputEncoderValueChanged() == TRUE)
01241         {
01242             BYTE idx = s16InputEncoderGetValue();
01243 
01244             // The first row indicates what should be input.
01245             lcd_addr1 = 0;
01246             StrTbl_GetString(lcdram_row1, STRTBLID_BUS_ADDRESS);
01247 
01248             // The second row is for the address and bus number.
01249             sprintf(lcdram_row2, (ROM char *) "%-3hhu        %5lu", _apsSelectCache[idx].u8BusNr, _apsSelectCache[idx].u32Address);
01250             lcd_addr2 = 0;
01251             lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_ROW2_MASK;
01252         }
01253         else if (bInputButtonPushed(ACC_BTN) == TRUE)
01254         {
01255             if (OutGetLEDMode(LED_ACC) == LED_ON)
01256             {
01257                 InputButtonReset(ACC_BTN);
01258             }
01259             _eSRCPsm = SRCP_PREPARE_MAIN;
01260         }
01261         else if (bInputButtonPushed(SEL_BTN) == TRUE)
01262         {
01263             if (OutGetLEDMode(LED_SEL) == LED_ON)
01264             {
01265                 InputButtonReset(SEL_BTN);
01266             }
01267             _eSRCPsm = SRCP_PREPARE_MAIN;
01268         }
01269 
01270         if (_eSRCPsm != SRCP_SELECT_SERVER_CACHE)
01271         {
01272             // Leaving this state? Destructing the cache.
01273             _destructServerCache();
01274         }
01275         break;
01276 
01277 
01278     case SRCP_INIT_DEVICE:
01279         if (OutGetLEDMode(LED_ACC) == LED_ON)
01280         {
01281             sGA newGA;
01282             _fillPrmGA(&newGA, &_sNewDeviceStaticData);
01283             _psNewDevice = _psAddDevice(SRCP_DT_GA, _sNewDeviceStaticData.u8BusNr, (void *)&newGA);
01284         }
01285         else
01286         {
01287             sGL newGL;
01288             _fillPrmGL(&newGL, &_sNewDeviceStaticData);
01289             _psNewDevice = _psAddDevice(SRCP_DT_GL, _sNewDeviceStaticData.u8BusNr, (void *)&newGL);
01290         }
01291 
01292         if (_psNewDevice == NULL)
01293         {
01294             PrintCommonError(COMMON_ERROR_OUT_OF_MEMORY);
01295             _eSRCPsm = SRCP_ERROR;
01296             break;
01297         }
01298 
01299         _eSRCPsm = SRCP_WAIT_FOR_IDLE_DEVICE;
01300         // Intended fall through.
01301 
01302 
01303     case SRCP_WAIT_FOR_IDLE_DEVICE:
01304         if (_psNewDevice->u16LastErrorCode)
01305         {
01306             _showServerError(_psNewDevice->u16LastErrorCode);       
01307             // Acknowledge the error:
01308             _psNewDevice->u16LastErrorCode = 0;
01309             _psNewDevice->eDevState = SRCP_DS_DISABLED;
01310             _eSRCPsm = SRCP_ERROR;
01311             break;
01312         }
01313         else if (_psNewDevice->eDevState != SRCP_DS_IDLE)
01314         {
01315             break;
01316         }
01317         
01318         _eSRCPsm = SRCP_INIT_POWER;
01319         // Intended fall through.
01320         
01321 
01322     case SRCP_INIT_POWER:
01323     {
01324         // After we know the protocol and the SRCP bus number (as protocol
01325         // parameter), we can check for a configured POWER device on that bus.
01326         sPower prm;
01327         prm.bPowerState = FALSE;
01328 
01329         // Append the power device to the device list (the function 
01330         // _psAddDevice automatically checks for already configured power 
01331         // device).
01332         if (_psAddDevice(SRCP_DT_POWER, _psNewDevice->u8Bus, (void*)&prm) == NULL)
01333         {
01334             PrintCommonError(COMMON_ERROR_OUT_OF_MEMORY);
01335             _eSRCPsm = SRCP_ERROR;
01336             break;
01337         }
01338         
01339         _eSRCPsm = SRCP_WAIT_FOR_IDLE_POWER_DEVICE;
01340         // Intented fall through.
01341     }
01342     
01343 
01344     case SRCP_WAIT_FOR_IDLE_POWER_DEVICE:
01345     {
01346         // Check whether the power device is already idle (initialized).
01347         SRCP_DEVICE * pPowerDev;
01348 
01349 
01350         // Step 1: Fetch the power device from the device list.
01351         pPowerDev = _pGetPowerDevice(_psNewDevice->u8Bus);
01352         if (pPowerDev==NULL)
01353         {
01354             // We never should come in here!
01355             PrintCommonError(COMMON_ERROR_SRCP_NO_POWER_DEVICE);
01356             _eSRCPsm = SRCP_ERROR;
01357             break;
01358         }
01359 
01360 
01361         // Step 2: Check for errors on the power device.
01362         if (pPowerDev->u16LastErrorCode)
01363         {
01364             _showServerError(pPowerDev->u16LastErrorCode);
01365             pPowerDev->u16LastErrorCode = 0;    // Acknowledge the error.
01366             _eSRCPsm = SRCP_ERROR;
01367             pPowerDev->eDevState = SRCP_DS_DISABLED;
01368             _psNewDevice->eDevState = SRCP_DS_DISABLED;
01369             break;
01370         }
01371 
01372 
01373         // Step 3:
01374         // Check the state of power device (should become idle in short time).
01375         if (pPowerDev->eDevState == SRCP_DS_IDLE)
01376         {
01377             // We can switch from the old to this new device.
01378             _psActualDevice = _pTakeOverDevice(_psNewDevice);
01379             _eSRCPsm = SRCP_PREPARE_MAIN;
01380         }
01381 
01382         break;
01383     }
01384 
01385 
01386     case SRCP_ERROR:
01387         InputButtonReset(ALL_BTN);
01388         _eSRCPsm = SRCP_ACK_ERROR;
01389         break;
01390 
01391 
01392     case SRCP_ACK_ERROR:
01393         if (bInputButtonPushed(ALL_BTN)==FALSE)
01394         {
01395             break;
01396         }
01397         // Intented fall through.
01398 
01399         
01400     case SRCP_PREPARE_MAIN:
01401         if (_psActualDevice == NULL)
01402         {
01403             _displayNoData();
01404         }
01405         else
01406         {
01407             OutSetLED(LED_ACC | LED_SEL, LED_OFF);
01408 
01409             lcd_addr1 = 0;
01410             strncpy(lcdram_row1, DEVICE_NAME_PTR(_psActualDevice), LCD_CHARS_IN_A_ROW);
01411             lcdram_row1[LCD_CHARS_IN_A_ROW] = 0;        
01412             lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK;
01413             lcdram_row2[0] = 0;
01414 
01415             if (_psActualDevice->eDevType == SRCP_DT_GA)
01416             {
01417                 sGA * pGA = (sGA *)(&_psActualDevice[1]);
01418                 InputEncoderInit(pGA->u8Port, pGA->u8MinPort, pGA->u8MaxPort, ENC_ENDSTOP_MASK);
01419             }
01420             else if (_psActualDevice->eDevType == SRCP_DT_GL)
01421             {
01422                 sGL * pGL = (sGL *)(&_psActualDevice[1]);
01423                 pGL->s16ActV = pGL->s16ServerV;
01424             }
01425 
01426             // Mark for new data to ensure updating the view.
01427             _psActualDevice->sFlags.bNewData = TRUE;
01428         }
01429 
01430         _eSRCPsm = SRCP_MAIN;
01431         if (bInputButtonPushed(SEL_BTN) || bInputButtonPushed(ACC_BTN))
01432         {
01433             // The user wants to configure a new device. Go straight to the
01434             // dialog.
01435             break;
01436         }
01437 
01438         InputButtonReset(ALL_BTN);
01439         break;
01440     }
01441 
01442     // All SRCP stuff was handled correctly. Show to application with a TRUE
01443     // return value.
01444     return TRUE;
01445 }
01446 
01447 // ////////////////////////////////////////////////////////////////////////////
01448 // ////////////////////////////////////////////////////////////////////////////
01449 
01450 static SHORT _s16computeRealSpeed(SHORT s16MaxV, SHORT s16ServerMaxV, SHORT s16ServerSpeed)
01451 {
01452     if (s16MaxV == s16ServerMaxV)
01453     {
01454         return s16ServerSpeed;
01455     }
01456     else
01457     {
01458         return (SHORT)(((float)s16ServerSpeed / s16ServerMaxV) * s16MaxV);
01459     }
01460 }
01461 
01462 
01463 // ////////////////////////////////////////////////////////////////////////////
01464 // ////////////////////////////////////////////////////////////////////////////
01465 
01478 static BOOL _bGetNextWord(BYTE u8Socket, BYTE * au8Buf, BYTE u8BufSize, BOOL * bEnd)
01479 {
01480     BYTE i = 0;
01481     BYTE data = 0;
01482     u8BufSize = u8BufSize-1;    // Leave space for the termination character.
01483 
01484     if (*bEnd == TRUE)
01485     {
01486         return FALSE;
01487     }
01488 
01489     // Step 1: Throw away all prepending whitespaces (semicolon, space, tab)
01490     // characters.
01491     do
01492     {
01493         if (TCPGet(u8Socket, &data) == FALSE)
01494         {
01495             return FALSE;
01496         }
01497     } while(data==';' || data==' ' || data==9);
01498 
01499 
01500     // Step 2: Get the word to the next whitespace or line end.
01501     do
01502     {
01503         if (data == '\n')
01504         {
01505             if (i && au8Buf[i-1] == 92)
01506             {
01507                 // Is the line end escaped, than handle this character group
01508                 // (\CRLF or \LF) as whitespace!
01509                 i = i-1;
01510             }
01511             else
01512             {
01513                 // We have reached the end of the line:
01514                 *bEnd = TRUE;
01515             }
01516 
01517             // Maybe after this line is another line!
01518             break;
01519         }
01520 
01521         if ((i < u8BufSize)&&(data>=32)&&(data<=127))
01522         {
01523             // Store the data if buffer space is left.
01524             au8Buf[i++] = data;
01525         }
01526 
01527         if (TCPGet(u8Socket, &data) == FALSE)
01528         {
01529             return FALSE;
01530         }
01531         
01532     } while(data != ';' && data != ' ' && data != 9); 
01533 
01534     au8Buf[i] = 0;      // end as string
01535 
01536     return TRUE;
01537 }
01538 
01539 // ////////////////////////////////////////////////////////////////////////////
01540 // ////////////////////////////////////////////////////////////////////////////
01541 
01542 static BOOL _bLookForEnd(BYTE u8Socket)
01543 {
01544     BYTE data;
01545 
01546     while (TCPGet(u8Socket, &data))
01547     {
01548         if (data == 92)
01549         {
01550             // Backslash found!
01551             // Handle the following (CR)LF as whitespace.
01552             if(TCPGet(u8Socket, &data))
01553             {
01554                 if (data==0x0d)
01555                 {
01556                     if (TCPGet(u8Socket, &data) == FALSE)
01557                     {
01558                         return FALSE;
01559                     }
01560                 }
01561             }
01562             else
01563             {
01564                 return FALSE;
01565             }
01566         }
01567         else if (data == 0x0a)
01568         {
01569             return TRUE;
01570         }
01571     }
01572 
01573     return FALSE;
01574 }
01575 
01576 // ////////////////////////////////////////////////////////////////////////////
01577 // ////////////////////////////////////////////////////////////////////////////
01578 
01579 void SRCP_GetProtoFromEEPROM(BYTE u8ProtoId, SPPROTOCOL * psProto)
01580 {
01581     XEEReadArray(SRCP_PROTOS_EEPROM_ADD + (sizeof(SPPROTOCOL) * u8ProtoId), (BYTE *)psProto, sizeof(SPPROTOCOL));
01582 }
01583 
01584 
01585 // ////////////////////////////////////////////////////////////////////////////
01586 // ////////////////////////////////////////////////////////////////////////////
01587 
01588 void SRCP_WriteSetToEEPROM(BYTE u8SetIdx, SPSET * psSet)
01589 {
01590     XEEWriteArray(SRCP_SETS_EEPROM_ADD + (sizeof(SPSET) * u8SetIdx), (BYTE *)psSet, sizeof(SPSET));
01591 }
01592 
01593 // ////////////////////////////////////////////////////////////////////////////
01594 // ////////////////////////////////////////////////////////////////////////////
01595 
01596 void SRCP_GetSetFromEEPROM(BYTE u8SetIdx, SPSET * psSet)
01597 {
01598     XEEReadArray(SRCP_SETS_EEPROM_ADD + (sizeof(SPSET) * u8SetIdx), (BYTE *)psSet, sizeof(SPSET));
01599 }
01600 
01601 // ////////////////////////////////////////////////////////////////////////////
01602 // ////////////////////////////////////////////////////////////////////////////
01603 
01604 static void _getProtoFromEEPROM(BYTE u8ProtoId, SPPROTOCOL * psProto)
01605 {
01606     // For the internal access only the content data will be used.
01607     XEEReadArray(SRCP_PROTOS_EEPROM_ADD + (sizeof(SPPROTOCOL) * u8ProtoId), (BYTE *)psProto, sizeof(SPPROTOCOL));
01608 }
01609 
01610 // ////////////////////////////////////////////////////////////////////////////
01611 // ////////////////////////////////////////////////////////////////////////////
01612 
01613 void SRCP_WriteProtoToEEPROM(BYTE u8ProtoId, SPPROTOCOL * psProto)
01614 {
01615     SPPROTOCOL proto;
01616     SRCP_GetProtoFromEEPROM(u8ProtoId, &proto);
01617 
01618     if (memcmp((void *)&proto, (void*)psProto, sizeof(SPPROTOCOL)))
01619     {
01620         XEEWriteArray(SRCP_PROTOS_EEPROM_ADD+(sizeof(SPPROTOCOL) * u8ProtoId), (BYTE *)psProto, sizeof(SPPROTOCOL));
01621     }
01622 }
01623 
01624 // ////////////////////////////////////////////////////////////////////////////
01625 // ////////////////////////////////////////////////////////////////////////////
01626 
01627 static void _displayNoData(void)
01628 {
01629     StrTbl_GetString(lcdram_row1, STRTBLID_NO_DEVICE);
01630     lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK;
01631     OutSwitchOffAllLEDs();
01632 }
01633 
01634 // ////////////////////////////////////////////////////////////////////////////
01635 // ////////////////////////////////////////////////////////////////////////////
01636 
01637 static void _displayGLData(SRCP_DEVICE * pDev)
01638 {
01639     BYTE i = 0;
01640     BYTE tmplcd[17];
01641     sGL * pGL = (sGL *)(&pDev[1]);
01642 
01643     if (pGL->u8FuncGroup == 0)
01644     {
01645         SHORT min = 0;
01646         SHORT speed = pGL->s16ActV;
01647 
01648         if (pGL->s16MaxV != pGL->u8MaxSteps)
01649         {
01650             speed = _s16computeRealSpeed(pGL->s16MaxV, pGL->u8MaxSteps, pGL->s16ActV);
01651         }
01652 
01653         sprintf(tmplcd, (ROM char *) "%-5lu       %3hd", pGL->u32Addr, speed);
01654 
01655         if (pGL->s16ActV != pGL->s16ServerV)
01656         {
01657             if (pGL->s16ActV > pGL->s16ServerV)
01658             {
01659                 tmplcd[15] = 0x05;
01660             }
01661             else 
01662             {
01663                 tmplcd[15] = 0x06;
01664             }
01665         }
01666         else
01667         {
01668             tmplcd[15] = 0x20;
01669         }
01670     
01671         if (pGL->sGLFlags.u2Dir == DIR_FORWARD)
01672         {
01673             tmplcd[7] = 0x01;
01674         }
01675         else if (pGL->sGLFlags.u2Dir == DIR_BACKWARD)
01676         {
01677             tmplcd[7] = 0x02;
01678         }
01679 
01680         tmplcd[16] = 0;
01681 
01682 
01683         if (IsEncoderTurning() == FALSE)
01684         {
01685             speed = pGL->s16ActV;
01686             if (sPApplConfig.sFlags.bToggleLocoDirMode == TOGGLEDIRMODE_ZERO)
01687             {
01688                 if (pGL->sGLFlags.u2Dir == DIR_BACKWARD)
01689                 {
01690                     speed = -(speed);
01691                 }
01692                 min = pGL->u8MaxSteps;
01693                 min = -min;
01694             }
01695         
01696             InputEncoderInit(speed, min, pGL->u8MaxSteps, ENC_NOCHANGE_MASK | ENC_ENDSTOP_MASK);
01697         }
01698     }
01699     else if (pGL->u8FuncGroup == 1)
01700     {
01701         strcpypgm2ram(tmplcd, (ROM char *)"F5              ");
01702         if (pGL->u8NrFunc > 6)
01703         {
01704             tmplcd[5] = 'F';
01705             tmplcd[6] = '6';
01706         }
01707         if (pGL->u8NrFunc > 7)
01708         {
01709             tmplcd[9] = 'F';
01710             tmplcd[10] = '7';
01711         }
01712         if (pGL->u8NrFunc > 8)
01713         {
01714             tmplcd[14] = 'F';
01715             tmplcd[15] = '8';
01716         }
01717     }
01718     else
01719     {
01720         strcpypgm2ram(tmplcd, (ROM char *)"F9              ");
01721         if (pGL->u8NrFunc > 10)
01722         {
01723             tmplcd[5] = 'F';
01724             tmplcd[6] = '1';
01725             tmplcd[7] = '0';
01726         }
01727         if (pGL->u8NrFunc > 11)
01728         {
01729             tmplcd[9] = 'F';
01730             tmplcd[10] = '1';
01731             tmplcd[11] = '1';
01732         }
01733         if (pGL->u8NrFunc > 12)
01734         {
01735             tmplcd[13] = 'F';
01736             tmplcd[14] = '1';
01737             tmplcd[15] = '2';
01738         }
01739     }
01740 
01741 
01742     if (strcmp(tmplcd, lcdram_row2))
01743     {
01744         lcd_addr2 = 0;
01745         lcd_status |= LCD_ROW2_MASK;
01746         strcpy(lcdram_row2, tmplcd);
01747     }
01748 
01749 
01750     // Function mask (group dependent)
01751     {
01752         DWORD funcs = pGL->u32FuncBitField & pGL->u32FuncAllocMask;
01753 
01754         // F0 is always displayed at the F0 button:
01755         BYTE led = funcs & 0x01;
01756 
01757         // F1-F4 alternate function group dependent.
01758         if (pGL->u8FuncGroup == 0)
01759         {
01760             led |= funcs & 0x1E;
01761         }
01762         else if (pGL->u8FuncGroup == 1)
01763         {
01764             led |= (funcs >> 4) & 0x1E;
01765         }
01766         else
01767         {
01768             led |= (funcs >> 8) & 0x1E;
01769         }
01770 
01771         OutSetLEDMask(LED_FL | LED_F1 | LED_F2 | LED_F3 | LED_F4, led);
01772     }
01773 }
01774 
01775 // ////////////////////////////////////////////////////////////////////////////
01776 // ////////////////////////////////////////////////////////////////////////////
01777 
01778 static void _displayGAData(SRCP_DEVICE * pDev)
01779 {
01780     sGA * pGA = (sGA *)(&pDev[1]);
01781 
01782     lcd_addr2 = 0;
01783     sprintf(lcdram_row2, (ROM char *) "%-5lu        %3hhu", pGA->u32Addr, pGA->u8Port);
01784     lcd_status |= LCD_ROW2_MASK;
01785 
01786     InputEncoderSetValue(pGA->u8Port, FALSE);
01787 
01788     if (pGA->u8Value == 0)
01789     {
01790         lcdram_row2[7] = 0x03;
01791     }
01792     else
01793     {
01794         lcdram_row2[7] = 0x04;
01795     }
01796 
01797     OutSetLED(LED_FL|LED_F1|LED_F2|LED_F3|LED_F4, LED_OFF);
01798 }
01799 
01800 // ////////////////////////////////////////////////////////////////////////////
01801 // ////////////////////////////////////////////////////////////////////////////
01802 
01803 static void _displayPower(SRCP_DEVICE * pDev)
01804 {
01805     sPower * pPwr = (sPower *)(&pDev[1]);
01806 
01807     if ((OutGetLEDMode(LED_PWR) != LED_BLINK)&&(pPwr->bPowerState==FALSE))
01808     {
01809         OutSetLED(LED_PWR, LED_BLINK);
01810     }
01811     else if ((OutGetLEDMode(LED_PWR) != LED_ON)&&(pPwr->bPowerState))
01812     {
01813         OutSetLED(LED_PWR, LED_ON);
01814     }
01815 }
01816 
01817 // ////////////////////////////////////////////////////////////////////////////
01818 // ////////////////////////////////////////////////////////////////////////////
01819 
01820 static BOOL _bGetGLInput(sGL * pGL)
01821 {
01822     BOOL bChanged = FALSE;
01823     DWORD functionActive = pGL->u32FuncBitField;    // Get the current function flag field.
01824     DWORD functionToggle = pGL->u32FuncToggleMask;
01825     DWORD functionMask;
01826 
01827 
01828     if (pGL == NULL)
01829     {
01830         return FALSE;
01831     }
01832 
01833     if (bInputEncoderValueChanged() == TRUE)
01834     {
01835         SHORT val = s16InputEncoderGetValue();
01836 
01837         if (sPApplConfig.sFlags.bToggleLocoDirMode == TOGGLEDIRMODE_ZERO)
01838         {
01839             if (pGL->s16ActV == 0)
01840             {
01841                 if ((InputEncoderGetDirection() == FALSE) && (pGL->sGLFlags.u2Dir == DIR_BACKWARD))
01842                 {
01843                     pGL->sGLFlags.u2Dir = DIR_FORWARD;
01844                     val = 0;
01845                 }
01846                 else if ((InputEncoderGetDirection() == TRUE) && (pGL->sGLFlags.u2Dir == DIR_FORWARD))
01847                 {
01848                     pGL->sGLFlags.u2Dir = DIR_BACKWARD;
01849                     val = 0;
01850                 }
01851             }
01852             
01853             if (val < 0)
01854             {
01855                 val = -(val);
01856             }
01857         }
01858 
01859         pGL->s16ActV = val;
01860         bChanged = TRUE;
01861     }
01862     if (bInputButtonPushedOnce(ENC_BTN) == TRUE)
01863     {
01864         if (sPApplConfig.sFlags.bToggleLocoDirMode == TOGGLEDIRMODE_CLICK)
01865         {
01866             // Change the direction of the loco:
01867             switch (pGL->sGLFlags.u2Dir)
01868             {
01869             case DIR_FORWARD:
01870                 pGL->sGLFlags.u2Dir = DIR_BACKWARD;
01871                 break;
01872 
01873             case DIR_BACKWARD:
01874                 pGL->sGLFlags.u2Dir = DIR_FORWARD;
01875                 break;
01876             }
01877         }
01878 
01879         pGL->s16ActV = 0;
01880         bChanged = TRUE;
01881         InputButtonReset(ENC_BTN);  
01882     }
01883 
01884 
01885     // Preparing the toggle mask for the actual function group.
01886     functionActive &= ~functionToggle;  // Mask out the toggle bits.
01887     functionMask = 0x02;
01888 
01889     if (pGL->u8FuncGroup==1)
01890     {
01891         functionMask = functionMask << 4;
01892     }
01893     else if (pGL->u8FuncGroup == 2)
01894     {
01895         functionMask = functionMask << 8;
01896     }
01897 
01898 
01899     // Function F1
01900     if ((functionToggle & functionMask) && bInputButtonPressed(F1_BTN))
01901     {
01902         functionActive |= functionMask;
01903         InputButtonReset(F1_BTN);
01904     }
01905     else if (((functionToggle & functionMask) == 0) && bInputButtonPushed(F1_BTN))
01906     {
01907         functionActive ^= functionMask;
01908         InputButtonReset(F1_BTN);
01909     }
01910     functionMask = functionMask << 1;
01911 
01912 
01913 
01914     // Function F2
01915     if ((functionToggle & functionMask) && bInputButtonPressed(F2_BTN))
01916     {
01917         functionActive |= functionMask;
01918         InputButtonReset(F2_BTN);
01919     }
01920     else if (((functionToggle & functionMask) == 0) && bInputButtonPushed(F2_BTN))
01921     {
01922         functionActive ^= functionMask;
01923         InputButtonReset(F2_BTN);
01924     }
01925     functionMask = functionMask << 1;
01926 
01927 
01928 
01929     // Function F3
01930     if ((functionToggle & functionMask) && bInputButtonPressed(F3_BTN))
01931     {
01932         functionActive |= functionMask;
01933         InputButtonReset(F3_BTN);
01934     }
01935     else if (((functionToggle & functionMask) == 0) && bInputButtonPushed(F3_BTN))
01936     {
01937         functionActive ^= functionMask;
01938         InputButtonReset(F3_BTN);
01939     }
01940     functionMask = functionMask << 1;
01941 
01942 
01943 
01944     // Function F4
01945     if ((functionToggle & functionMask) && bInputButtonPressed(F4_BTN))
01946     {
01947         functionActive |= functionMask;
01948         InputButtonReset(F4_BTN);
01949     }
01950     else if (((functionToggle & functionMask) == 0) && bInputButtonPushed(F4_BTN))
01951     {
01952         functionActive ^= functionMask;
01953         InputButtonReset(F4_BTN);
01954     }
01955 
01956 
01957     // Function F0
01958     if (bInputButtonPushed(FL_BTN) == TRUE)
01959     {
01960         if ((bInputButtonPushedLong(FL_BTN) == TRUE)&&(pGL->u8NrFunc > 5)&&
01961             (pGL->u8FuncGroup == 0))
01962         {
01963             // Change the function view!
01964             pGL->u8FuncGroup = 1;
01965         }
01966         else if (pGL->u8FuncGroup == 1)
01967         {
01968             if (pGL->u8NrFunc > 9)
01969             {
01970                 pGL->u8FuncGroup = 2;
01971             }
01972             else
01973             {
01974                 pGL->u8FuncGroup = 0;
01975             }
01976         }
01977         else if (pGL->u8FuncGroup == 2)
01978         {
01979             pGL->u8FuncGroup = 0;
01980         }
01981         else
01982         {
01983             functionActive ^= 0x01;
01984         }
01985 
01986         InputButtonReset(FL_BTN);
01987         bChanged = TRUE;
01988     }
01989 
01990     if (pGL->u32FuncBitField != functionActive)
01991     {
01992         pGL->u32FuncBitField = functionActive;
01993         pGL->u32FuncBitField &= pGL->u32FuncAllocMask;
01994         bChanged = TRUE;
01995     }
01996 
01997     return bChanged;
01998 }
01999 
02002 
02003 static BOOL _bGetGAInput(SRCP_DEVICE * pDev)
02004 {
02005     BOOL bChanged = FALSE;
02006     sGA * pGA = (sGA *)(&pDev[1]);
02007 
02008     if (bInputButtonPushedOnce(ENC_BTN) == TRUE)
02009     {
02010         // Change the port value of the GA:
02011         pGA->u8Value = !(pGA->u8Value);
02012         InputButtonReset(ENC_BTN);
02013         bChanged = TRUE;
02014     }
02015     if (bInputEncoderValueChanged() == TRUE)
02016     {
02017         SRCP_PRM prm;
02018         BYTE i = 0;
02019 
02020         // Switch to another port!
02021         pGA->u8Port = (BYTE) s16InputEncoderGetValue();
02022         pDev->eDevState = SRCP_DS_UNKNOWN;
02023         pDev->sFlags.bNewData = TRUE;
02024     }
02025 
02026     return bChanged;
02027 }
02028 
02031 
02032 static void _showServerError(WORD u16Code)
02033 {
02034     StrTbl_GetString(lcdram_row1, STRTBLID_SERVER_REPORTS);
02035     sprintf(lcdram_row2, 
02036             StrTbl_cau8GetStringPointer(STRTBLID_ERRORCODE),
02037             u16Code);
02038     lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
02039                  LCD_ROW2_MASK | LCD_CENTER2_MASK;
02040 
02041     OutSwitchOffAllLEDs();
02042 }
02043 
02046 
02047 static BOOL _bSendSRCPMessage(SRCP_COMMANDS eCommand, SRCP_DEVICE * pDev)
02048 {
02049     BYTE buf[50];
02050     BOOL bAddress = FALSE;
02051 
02052     if (pDev==NULL)
02053     {
02054         return FALSE;
02055     }
02056 
02057     // Check for undefined messages and devices.... 
02058     if ((eCommand==SRCP_CMD_INFO)||(pDev->eDevType==SRCP_DT_NOT_DEFINED))
02059     {
02060         return FALSE;
02061     }
02062 
02063     // Is there already a SRCP message in progress?
02064     if (_bSrvReqIsInProgress==TRUE)
02065     {
02066         return FALSE;
02067     }
02068 
02069     // Check for a free TCP channel.
02070     if (!TCPIsPutReady(_sSRCPState.sCommand.u8Socket))
02071     {
02072         return FALSE;
02073     }
02074 
02075     // Step 1: Transfer the message string.
02076     switch(eCommand)
02077     {
02078         case SRCP_CMD_GET:
02079             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"GET");
02080             break;
02081 
02082         case SRCP_CMD_SET:
02083             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"SET");
02084             break;
02085 
02086         case SRCP_CMD_INIT:
02087             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"INIT");
02088             break;
02089 
02090         case SRCP_CMD_TERM:
02091             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"TERM");
02092             break;
02093 
02094         case SRCP_CMD_CHECK:
02095             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"CHECK");
02096             break;
02097 
02098         case SRCP_CMD_WAIT:
02099             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"WAIT");
02100             break;
02101 
02102         case SRCP_CMD_RESET:
02103             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"RESET");
02104             break;
02105     }
02106 
02107 
02108     // Step 2: Transfer the bus number.
02109     sprintf(buf, (ROM char *) " %hhu ", pDev->u8Bus);
02110     TCPPutString(_sSRCPState.sCommand.u8Socket, buf);
02111 
02112 
02113     // Step 3: Transfer the device type string.
02114     bAddress = _bDevTypeTCP(pDev->eDevType, eCommand);
02115 
02116     
02117     // Step 4: Check for the lock device and transfer the device type to lock.
02118     if (pDev->eDevType == SRCP_DT_LOCK)
02119     {
02120         sLock * pLock = (sLock *)(&pDev[1]);
02121         TCPPut(_sSRCPState.sCommand.u8Socket, ' ');
02122         bAddress = _bDevTypeTCP(pLock->eDevType, eCommand);
02123     }
02124 
02125 
02126     // Step 5: Transfer the address.
02127     if (bAddress == TRUE)
02128     {
02129         // The address is always located at the same field position regardless
02130         // of the device type.
02131         sprintf(buf, (ROM char *) " %lu", _u32GetAddress(pDev));
02132         TCPPutString(_sSRCPState.sCommand.u8Socket, buf);
02133     }
02134 
02135 
02136     // Step 6: Generate a parameter list (if necessary).
02137     buf[0] = 0;     // Clear the working buffer. 
02138     switch(pDev->eDevType)
02139     {
02140         case SRCP_DT_GL:
02141         {
02142             sGL * pGL = (sGL *)(&pDev[1]);
02143             if (eCommand==SRCP_CMD_INIT)
02144             {
02145                 _getInitData(pDev, buf);
02146             }
02147             else if ((eCommand==SRCP_CMD_CHECK)||(eCommand==SRCP_CMD_SET))
02148             {
02149                 DWORD mask = pGL->u32FuncBitField;
02150                 BYTE i = pGL->sGLFlags.u2Dir;
02151                 BYTE bufindex = sprintf(buf, (ROM char *) "%hhu %hu %hu", i, pGL->s16ActV, pGL->u8MaxSteps);
02152     
02153                 for (i=0; i < pGL->u8NrFunc; i++)
02154                 {
02155                     if (mask &0x01)
02156                     {
02157                         strcpypgm2ram(&buf[bufindex], (ROM char *)" 1");
02158                     }
02159                     else
02160                     {
02161                         strcpypgm2ram(&buf[bufindex], (ROM char *)" 0");
02162                     }
02163                     mask = mask >> 1;
02164                     bufindex+=2;
02165                 }
02166             }
02167             break;
02168         }
02169 
02170         case SRCP_DT_GA:
02171         {
02172             sGA * pGA = (sGA *)(&pDev[1]);
02173             if (eCommand == SRCP_CMD_INIT)
02174             {
02175                 _getInitData(pDev, buf);
02176             }
02177             else if (eCommand==SRCP_CMD_GET)    
02178             {
02179                 sprintf(buf, (ROM char *) "%hhu", pGA->u8Port);
02180             }
02181             else if ((eCommand==SRCP_CMD_CHECK)||(eCommand==SRCP_CMD_SET))  
02182             {
02183                 LONG delay = 1;
02184                 if (pGA->u8Value)
02185                 {
02186                     delay = pGA->s32Delay;
02187                 }
02188 
02189                 sprintf(buf, (ROM char *)"%hhu %hhu %ld", pGA->u8Port, pGA->u8Value, delay);
02190             }
02191             break;
02192         }
02193 
02194         case SRCP_DT_POWER:
02195             if (eCommand == SRCP_CMD_SET)
02196             {
02197                 sPower * pPwr = (sPower*)(&pDev[1]);
02198                 if (pPwr->bPowerState == TRUE)
02199                 {
02200                     strcpypgm2ram(buf, (ROM char *)"ON");
02201                 }
02202                 else
02203                 {
02204                     strcpypgm2ram(buf, (ROM char *)"OFF");
02205                 }
02206             }
02207             break;
02208 
02209         case SRCP_DT_LOCK:
02210             if (eCommand == SRCP_CMD_SET)
02211             {
02212                 sLock * pLock = (sLock *)(&pDev[1]);
02213                 sprintf(buf, (ROM char *) " %u", pLock->u32Duration);
02214             }
02215             break;
02216 
02217         // ToDo:
02218         // Add the parameter lists for other devices like FB and SM.
02219     }
02220 
02221 
02222     if (strlen(buf))
02223     {
02224         TCPPut(_sSRCPState.sCommand.u8Socket, ' ');
02225         TCPPutString(_sSRCPState.sCommand.u8Socket, buf);
02226     }
02227 
02228 
02229 
02230     // Step 7: Complete the transfer with linefeed and flush.
02231     TCPPut(_sSRCPState.sCommand.u8Socket, '\n');
02232     TCPFlush(_sSRCPState.sCommand.u8Socket);
02233     
02234     // Remember the last sent command (which command from which device)
02235     _eLastSentCommand = eCommand;
02236     _pLastCommandDevice = pDev;
02237     _bSrvReqIsInProgress = TRUE;
02238     _bServerRequestTime = TickGet() + 2 * TICKS_PER_SECOND;
02239 
02240     return TRUE;
02241 }
02242 
02245 
02246 static BOOL _bDevTypeTCP(SRCP_DEVTYPE eDevType, SRCP_COMMANDS eCommand)
02247 {
02248     if (eCommand == SRCP_CMD_GETDESC)
02249     {
02250         TCPPutROMString(_sSRCPState.sCommand.u8Socket, 
02251                         (ROM char *)"DESCRIPTION");
02252     }
02253 
02254     switch(eDevType)
02255     {
02256         case SRCP_DT_GL:
02257             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char*)"GL");
02258             return TRUE;    // Address is needed.
02259 
02260         case SRCP_DT_GA:
02261             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"GA");
02262             return TRUE;    // Address is needed.
02263 
02264         case SRCP_DT_POWER:
02265             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"POWER");
02266             break;
02267 
02268         case SRCP_DT_LOCK:
02269             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"LOCK");
02270             break;
02271 
02272         case SRCP_DT_SM:
02273             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"SM");
02274             if ((eCommand == SRCP_CMD_SET)||
02275                 (eCommand == SRCP_CMD_CHECK)||
02276                 (eCommand == SRCP_CMD_GET)||
02277                 (eCommand == SRCP_CMD_VERIFY))
02278             {
02279                 return TRUE;    // Address is needed.
02280             }
02281             break;
02282 
02283         case SRCP_DT_FB:
02284             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"FB");
02285             if ((eCommand == SRCP_CMD_WAIT)||
02286                 (eCommand == SRCP_CMD_GET))
02287             {
02288                 return TRUE;    // Address is needed.
02289             }
02290             break;
02291 
02292         case SRCP_DT_TIME:
02293             TCPPutROMString(_sSRCPState.sCommand.u8Socket, (ROM char *)"TIME");
02294             break;
02295 
02296         case SRCP_DT_SERVER:
02297             TCPPutROMString(_sSRCPState.sCommand.u8Socket,(ROM char *)"SERVER");
02298             break;
02299 
02300         case SRCP_DT_SESSION:
02301             TCPPutROMString(_sSRCPState.sCommand.u8Socket,(ROM char*)"SESSION");
02302             return TRUE;    // Address is needed.
02303 
02304         case SRCP_DT_DESCRIPTION:
02305             TCPPutROMString(_sSRCPState.sCommand.u8Socket, 
02306                                                     (ROM char *)"DESCRIPTION");
02307             break;
02308     }
02309 
02310     return FALSE;
02311 }
02312 
02313 // ////////////////////////////////////////////////////////////////////////////
02314 // ////////////////////////////////////////////////////////////////////////////
02315 
02316 /*
02317 When calling this function, the caller must ensure that received packet is
02318 definitly for this device! That is not checked here!
02319 This function processes the packet and handles the state transitions caused
02320 due the packet code.
02321 */
02322 static void _answerReceived(SRCP_DEVICE *pDev, WORD u16Code, SRCP_TIME * pTime)
02323 {
02324     if ((pDev == NULL) || (pDev->eDevState == SRCP_DS_DISABLED))
02325     {
02326         return;
02327     }
02328 
02329 
02330     // If the time of the message is older than the last update than we are 
02331     // doing nothing.
02332     if (pDev->sLastUpdate.u32Seconds > pTime->u32Seconds)
02333     {
02334         return;
02335     }
02336 
02337     if ((pDev->sLastUpdate.u32Seconds == pTime->u32Seconds) &&
02338         (pDev->sLastUpdate.u16Milliseconds > pTime->u16Milliseconds))
02339     {
02340         return;
02341     }
02342 
02343     // Remember the time of this message 
02344     pDev->sLastUpdate.u32Seconds = pTime->u32Seconds;
02345     pDev->sLastUpdate.u16Milliseconds = pTime->u16Milliseconds;
02346 
02347     switch(u16Code)
02348     {
02349         // 100 (After INIT), 101 
02350         // This INFO codes has the meaning of an existing device. The server
02351         // knows the (initialized) device and sends the parameters of this 
02352         // device. The device state machine is always IDLE than.
02353         case 100:
02354         case 101:
02355             pDev->eDevState = SRCP_DS_IDLE;
02356             break;
02357 
02358         // 102 (After TERM). The server does not know this device anymore.
02359         case 102:
02360             pDev->eDevState = SRCP_DS_DISABLED;
02361             break;
02362 
02363         // 200 (After any successful executed command). 
02364         case 200:
02365             // If it is OK to a TERM command, than the device is in an 
02366             // uninitialized state.
02367             if(_eLastSentCommand == SRCP_CMD_TERM)
02368             {
02369                 pDev->eDevState = SRCP_DS_DISABLED;
02370             }
02371             // If it is OK to a INIT command, than the device is in the 
02372             // idle (initialized) state.
02373             else if(_eLastSentCommand == SRCP_CMD_INIT)
02374             {
02375                 pDev->sFlags.bNewData = TRUE;   // To ensure that the view is refreshed.
02376                 pDev->eDevState = SRCP_DS_IDLE;
02377             }
02378             break;
02379 
02380         case 416:
02381             // ERROR no data
02382             // no information at all is available.
02383             if (_eLastSentCommand == SRCP_CMD_GET)
02384             {
02385                 pDev->eDevState = SRCP_DS_NOT_DEFINED;
02386                 break;
02387             }
02388 
02389         default:
02390             // Action:
02391             // Store this error in the structure.
02392             pDev->u16LastErrorCode = u16Code;
02393             pDev->eDevState = SRCP_DS_DISABLED;
02394     }
02395 }
02396 
02397 // ////////////////////////////////////////////////////////////////////////////
02398 // ////////////////////////////////////////////////////////////////////////////
02399 
02400 static void _deviceSM(SRCP_DEVICE * pDev)
02401 {
02402     // This state machine includes no state transitions.
02403     // All the actions are done state related.
02404     // Precondition for calling this function: The command socket must be free!
02405 
02406     if (pDev == NULL)
02407     {
02408         return;
02409     }
02410 
02411     switch(pDev->eDevState)
02412     {
02413     case SRCP_DS_UNKNOWN:
02414         _bSendSRCPMessage(SRCP_CMD_GET, pDev);
02415         // The answer to this message results in a state change processed by
02416         // the function _answerReceived.
02417         break;
02418 
02419     case SRCP_DS_NOT_DEFINED:
02420         // Synchronized with server, the server does not know anything about
02421         // this device... Try to initialize the device.
02422         if (_bIsInitAllowed(pDev->eDevType)&&(pDev->u16LastErrorCode==0))
02423         {
02424             _bSendSRCPMessage(SRCP_CMD_INIT, pDev);
02425         }
02426         break;
02427 
02428     case SRCP_DS_IDLE:
02429         // Add some generic idle handler code here.
02430         break;
02431     }
02432 }
02433 
02434 // ////////////////////////////////////////////////////////////////////////////
02435 // ////////////////////////////////////////////////////////////////////////////
02436 
02437 static void _updateData(SRCP_DEVICE * pDev, WORD u16Code, SRCP_PRM * pNewPrm)
02438 {
02439     BYTE size;
02440 
02441     if (pDev == NULL)
02442     {
02443         return;
02444     }
02445 
02446     // Only INFO (GET replies) messages will be checked here.
02447     if (u16Code != 100)
02448     {
02449         return;
02450     }
02451 
02452     switch(pDev->eDevType)
02453     {
02454     case SRCP_DT_GL:
02455     {
02456         sGL * pGL = (sGL *)(&pDev[1]); 
02457         DWORD mask;
02458         DWORD funcmask;
02459 
02460         // Speed handling...
02461 
02462         // Set the local maximum speed step to that from server.
02463         pGL->u8MaxSteps = pNewPrm->uStat.sGL.s16MaxV;
02464 
02465         // The element 's16ServerV' is always consistent with the server.
02466         pGL->s16ServerV = pNewPrm->uDyn.sGL.s16ActV;
02467         
02468         if (IsEncoderTurning() == FALSE)
02469         {
02470             pGL->s16ActV = pGL->s16ServerV;
02471         }
02472 
02473         if (pGL->sGLFlags.u2Dir != (pNewPrm->uDyn.sGL.u8Dir & 0x03))
02474         {
02475             pGL->sGLFlags.u2Dir = pNewPrm->uDyn.sGL.u8Dir & 0x03;
02476         }
02477 
02478         mask = pGL->u32FuncAllocMask & pNewPrm->uStat.sGL.u32FuncAllocMask;
02479 
02480         funcmask=mask&(pGL->u32FuncBitField^pNewPrm->uDyn.sGL.u32FuncBitField);
02481 
02482         if (mask & (pGL->u32FuncBitField ^ pNewPrm->uDyn.sGL.u32FuncBitField))
02483         {
02484             pGL->u32FuncBitField &= ~mask;
02485             pGL->u32FuncBitField |= mask & pNewPrm->uDyn.sGL.u32FuncBitField;
02486         }
02487         
02488         pDev->sFlags.bNewData = TRUE;
02489 
02490         break;
02491     }
02492 
02493     case SRCP_DT_GA:
02494         {
02495             sGA * pGA = (sGA *)(&pDev[1]); 
02496             if (pGA->u8Value != pNewPrm->uDyn.sGA.u8Value)
02497             {
02498                 pDev->sFlags.bNewData = TRUE;
02499                 pGA->u8Value = pNewPrm->uDyn.sGA.u8Value;
02500             }
02501             break;
02502         }
02503     case SRCP_DT_POWER:
02504         {
02505             sPower * pPwr = (sPower *)(&pDev[1]);
02506             if (pPwr->bPowerState != pNewPrm->uDyn.bPowerState)
02507             {
02508                 pDev->sFlags.bNewData = TRUE;
02509                 pPwr->bPowerState = pNewPrm->uDyn.bPowerState;
02510             }
02511             break;
02512         }
02513     }
02514 }
02515 
02516 // ////////////////////////////////////////////////////////////////////////////
02517 // ////////////////////////////////////////////////////////////////////////////
02518 
02519 static BOOL _bIsDeviceMatching(SRCP_DEVICE * psDevice, SRCP_PRM * pPrm)
02520 {
02521     BYTE size;
02522     void * pSrcPrm;
02523 
02524     if ((psDevice == NULL) || (pPrm == NULL))
02525     {
02526         return FALSE;
02527     }
02528 
02529     if (psDevice->eDevType != pPrm->eDevType)
02530     {
02531         return FALSE;
02532     }
02533 
02534     if (psDevice->u8Bus != pPrm->u8Bus)
02535     {
02536         return FALSE;
02537     }
02538 
02539     if (psDevice->eDevState == SRCP_DS_DISABLED)
02540     {
02541         return FALSE;
02542     }
02543 
02544     // Check the device dependent parameters.
02545     if (pPrm->eDevType == SRCP_DT_POWER)
02546     {
02547         return TRUE;
02548     }
02549 
02550     pSrcPrm = (void *)(&psDevice[1]); 
02551 
02552     switch(pPrm->eDevType)
02553     {
02554     case SRCP_DT_LOCK:
02555         {
02556             sLock * pLockSrc = (sLock *)pSrcPrm;
02557 
02558             if (pPrm->uStat.sLock.eDevType != pLockSrc->eDevType)
02559             {
02560                 return FALSE;
02561             }
02562 
02563             if (pPrm->uStat.sLock.u32Addr != pLockSrc->u32Addr)
02564             {
02565                 return FALSE;
02566             }
02567         }
02568         break;
02569 
02570     case SRCP_DT_GA:
02571         {
02572             sGA * pGASrc = (sGA *)pSrcPrm;
02573 
02574             if (pPrm->uStat.sGA.u8Port != pGASrc->u8Port)
02575             {
02576                 return FALSE;
02577             }
02578 
02579             if (pPrm->uStat.sGA.u32Addr != pGASrc->u32Addr)
02580             {
02581                 return FALSE;
02582             }
02583         }
02584         break;
02585 
02586     case SRCP_DT_GL:
02587         {
02588             sGL * pGLSrc = (sGL *)pSrcPrm;
02589 
02590             if (pPrm->uStat.sGL.u32Addr != pGLSrc->u32Addr)
02591             {
02592                 return FALSE;
02593             }
02594         }
02595         break;
02596     }
02597 
02598     return TRUE;
02599 }
02600 
02601 // ////////////////////////////////////////////////////////////////////////////
02602 // ////////////////////////////////////////////////////////////////////////////
02603 
02604 static SRCP_DEVICE * _pGetPowerDevice(BYTE u8Bus)
02605 {
02606     BYTE i;
02607     for (i = 0; i < MAX_SRCP_DEVICES; i++)
02608     {
02609         if (_apsDevices[i] && (u8Bus == _apsDevices[i]->u8Bus) &&
02610             (SRCP_DT_POWER == _apsDevices[i]->eDevType))
02611         {
02612             return _apsDevices[i];
02613         }
02614     }
02615     
02616     // Not found!
02617     return NULL;
02618 }
02619 
02620 // ////////////////////////////////////////////////////////////////////////////
02621 // ////////////////////////////////////////////////////////////////////////////
02622 
02623 #define FREQUENT_SRCP_DEVICE_OFFSET     2
02624 
02625 static SRCP_DEVICE* _psAddDevice(SRCP_DEVTYPE eDevType, BYTE u8Bus, void* pPrm)
02626 {
02627     BYTE i, j;
02628     DWORD checkAddress = 0;
02629 
02630     if(pPrm == NULL)
02631     {
02632         return NULL;
02633     }
02634 
02635     _refreshDeviceList();
02636 
02637     if ((eDevType == SRCP_DT_GL)||(eDevType == SRCP_DT_GA)||(eDevType == SRCP_DT_LOCK))
02638     {
02639         checkAddress = *((DWORD *)(pPrm));
02640     }
02641 
02642 
02643     // Step 1: Check if the device is already in the list!
02644     for (i = FREQUENT_SRCP_DEVICE_OFFSET; i < MAX_SRCP_DEVICES; i++)
02645     {
02646         if (_apsDevices[i] == NULL)
02647         {
02648             // Empty device slot found, after refreshing the list it is the
02649             // last one!
02650             break;
02651         }
02652         if (_apsDevices[i]->u8Bus != u8Bus)
02653         {
02654             continue;
02655         }
02656         if (_apsDevices[i]->eDevType != eDevType)
02657         {
02658             continue;
02659         }
02660         if (_u32GetAddress(_apsDevices[i]) != checkAddress)
02661         {
02662             continue;
02663         }
02664 
02665         // Device found! 
02666         // Younger this device to prevent removing from device
02667         // list. Update the stack positions of all other devices.
02668 
02669         if (i>FREQUENT_SRCP_DEVICE_OFFSET)
02670         {
02671             // Temporary store the pointer:
02672             SRCP_DEVICE * pDev = _apsDevices[i];
02673 
02674             // Older all devices which were before the found device.
02675             for (j = i; j > FREQUENT_SRCP_DEVICE_OFFSET; j--)
02676             {
02677                 _apsDevices[j] = _apsDevices[j-1];
02678             }
02679 
02680             _apsDevices[j] = pDev;
02681         }   
02682         
02683         return _apsDevices[j];
02684     }
02685 
02686 
02687     // Step 2: Free the oldest device in list.
02688     if (_apsDevices[MAX_SRCP_DEVICES-1])
02689     {
02690         SRAMfree((BYTE *)_apsDevices[MAX_SRCP_DEVICES-1]);
02691         _apsDevices[MAX_SRCP_DEVICES-1] = NULL;
02692     }
02693 
02694 
02695     // Step 3: Older all devices which were before the found device.
02696     for (j = (MAX_SRCP_DEVICES-1); j > FREQUENT_SRCP_DEVICE_OFFSET; j--)
02697     {
02698         _apsDevices[j] = _apsDevices[j-1];
02699     }
02700 
02701     
02702     // Step 4: Get a new device structure.
02703     _apsDevices[j] = _psInitializeNewDevice(eDevType, u8Bus, pPrm);
02704 
02705     return _apsDevices[j];
02706 }
02707 
02708 // ////////////////////////////////////////////////////////////////////////////
02709 // ////////////////////////////////////////////////////////////////////////////
02710 
02711 static BOOL _startParsing(BYTE u8Socket, SRCP_TIME * psTime, WORD * pu16Code)
02712 {
02713     BYTE wb[16];
02714     BOOL end = FALSE;
02715 
02716     if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02717     {
02718         // Get the time...
02719         char * pDot = strrchr(wb, '.');
02720         if (pDot)
02721         {
02722             *pDot++ = 0;
02723             psTime->u32Seconds = (DWORD) atol(wb);
02724             psTime->u16Milliseconds = (WORD) atoi(pDot);
02725         }
02726         else
02727         {
02728             goto _startParsingError;
02729         }
02730     }
02731     else
02732     {
02733         goto _startParsingError;
02734     }
02735 
02736     if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02737     {
02738         *pu16Code = atoi(wb);
02739         if (*pu16Code == 110)
02740         {
02741             *pu16Code = 100;
02742         }
02743     }
02744     else
02745     {
02746         goto _startParsingError;
02747     }
02748 
02749     // Throw away the message classification string. We just use the code
02750     // for checking the device states.
02751     if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02752     {
02753         return TRUE;
02754     }
02755 
02756 
02757 _startParsingError:
02758     if (end==FALSE)
02759     {
02760         // The end of line was not found. Look for the line end (or the frame 
02761         // end) in the remaining frame data. Maybe other lines will follow up.
02762         _bLookForEnd(u8Socket);
02763     }
02764     return FALSE;
02765 }
02766 
02767 // ////////////////////////////////////////////////////////////////////////////
02768 // ////////////////////////////////////////////////////////////////////////////
02769 
02770 static BOOL _bParseLine(BYTE u8Socket, WORD u16Code, SRCP_PRM * pPrm)
02771 {
02772     BYTE wb[16];
02773     BOOL end = FALSE;
02774     BOOL valid = FALSE;
02775     BOOL address = FALSE;
02776     memset(pPrm, 0, sizeof(SRCP_PRM));
02777 
02778     // Only INFO messages store device related data.
02779     if (u16Code >= 200)
02780     {
02781         goto _parseForLineEnd;
02782     }
02783 
02784 
02785     // Step 1: Fetch the bus number from the received message.
02786     if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02787     {
02788         pPrm->u8Bus = (BYTE) atoi(wb);
02789     }
02790     else
02791     {
02792         goto _parseForLineEnd;
02793     }
02794 
02795 
02796     // Step 2: Fetch the device type string from the received message.
02797     if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end)==FALSE)
02798     {
02799         goto _parseForLineEnd;
02800     }
02801 
02802     address = _bTCPDevType(u16Code, &pPrm->eDevType, wb);
02803 
02804     if (pPrm->eDevType == SRCP_DT_NOT_DEFINED)
02805     {
02806         goto _parseForLineEnd;
02807     }
02808 
02809 
02810     // Step 3: Get the device if locked.
02811     if (pPrm->eDevType == SRCP_DT_LOCK)
02812     {
02813         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end)==FALSE)
02814         {
02815             goto _parseForLineEnd;
02816         }
02817 
02818         address = _bTCPDevType(u16Code, &pPrm->uStat.sLock.eDevType, wb);
02819     
02820         if (pPrm->eDevType == SRCP_DT_NOT_DEFINED)
02821         {
02822             goto _parseForLineEnd;
02823         }
02824     }
02825 
02826 
02827     // Step 4: Parse for the address.
02828     if (address==TRUE)
02829     {
02830         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end)==FALSE)
02831         {
02832             goto _parseForLineEnd;
02833         }
02834 
02835         // All address parameters are at the same field position.
02836         pPrm->uStat.sGL.u32Addr = (DWORD) atol(wb);
02837     }
02838 
02839 
02840     // Step 5: Fetch the device type specific static and dynamic data from the
02841     // received message.
02842     if (u16Code == 101)
02843     {
02844         // Device is initialized! Maybe its worth parsing the line for our 
02845         // server cache.
02846         if (pPrm->eDevType != SRCP_DT_GL)
02847         {
02848             // Only GL devices are currently stored in the cache.
02849             valid = TRUE;
02850             goto _parseForLineEnd;  
02851         }
02852         
02853         // Get the protocol specifier:
02854         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02855         {
02856             // Only M and N protocols are supported at the moment.
02857             if ((wb[0] != 'N') && (wb[0] != 'M'))
02858             {
02859                 goto _parseForLineEnd;
02860             }
02861 
02862             pPrm->uStat.sGL.au8Proto[0] = wb[0];
02863             pPrm->uStat.sGL.au8Proto[1] = ' ';
02864         }
02865 
02866         // Get the protocol version:
02867         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02868         {
02869             // Protocol version is not checked here!
02870             pPrm->uStat.sGL.au8Proto[2] = wb[0];
02871         }
02872 
02873         // Get the number of decoder speed steps:
02874         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02875         {
02876             pPrm->uStat.sGL.u8MaxSteps = atob(wb);
02877         }
02878 
02879         // Get the number of decoder functions:
02880         if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02881         {
02882             pPrm->uStat.sGL.u8NrFunc = atob(wb);
02883         }
02884     }
02885     
02886     if (u16Code != 100)
02887     {
02888         valid = TRUE;
02889         goto _parseForLineEnd;
02890     }
02891 
02892 
02893     switch(pPrm->eDevType)
02894     {
02895         case SRCP_DT_GL:
02896         {
02897             DWORD mask = 0x01;
02898             BYTE i;
02899     
02900             // Get the drive mode.
02901             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02902             {
02903                 pPrm->uDyn.sGL.u8Dir = atob(wb);
02904             }
02905 
02906             // Get the actual speed.
02907             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02908             {
02909                 pPrm->uDyn.sGL.s16ActV = atoi(wb);
02910             }
02911     
02912             // Get the maximum speed.
02913             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02914             {
02915                 pPrm->uStat.sGL.s16MaxV = atoi(wb);
02916             }
02917     
02918             // Get the function values.
02919             for (i = 0; i < MAX_SRCP_FUNCTIONS; i++, mask=mask<<1)
02920             {
02921                 if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02922                 {
02923                     if (wb[0] == '=')
02924                     {
02925                         continue;
02926                     }
02927                     if (wb[0] == '1')
02928                     {
02929                         pPrm->uDyn.sGL.u32FuncBitField |= mask;
02930                     }
02931                     pPrm->uStat.sGL.u32FuncAllocMask |= mask;
02932                 }
02933                 else
02934                 {
02935                     break;
02936                 }
02937             }
02938             break;
02939         }
02940 
02941         case SRCP_DT_GA:
02942             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02943                 pPrm->uStat.sGA.u8Port = atob(wb);
02944 
02945             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end))
02946                 pPrm->uDyn.sGA.u8Value = atob(wb);
02947             break;
02948     
02949         case SRCP_DT_POWER:
02950             if (_bGetNextWord(u8Socket, wb, sizeof(wb), &end)==FALSE)
02951                 goto _parseForLineEnd;
02952 
02953             if (strncmppgm2ram(wb,(ROM char *)"ON",sizeof(wb)-1)==0)
02954                 pPrm->uDyn.bPowerState = TRUE;
02955             else
02956                 pPrm->uDyn.bPowerState = FALSE;
02957             break;
02958     }
02959 
02960     valid = TRUE;
02961     
02962 _parseForLineEnd:
02963     if (end==FALSE)
02964     {
02965         // The end of line was not found. Look for the line end (or the frame 
02966         // end) in the remaining frame data.
02967         _bLookForEnd(u8Socket);
02968     }
02969     return valid;
02970 }
02971 
02972 // ////////////////////////////////////////////////////////////////////////////
02973 // ////////////////////////////////////////////////////////////////////////////
02974 
02975 static BOOL _bTCPDevType(WORD u16Code, SRCP_DEVTYPE * pDev, BYTE * au8Buf)
02976 {
02977     if (strcmppgm2ram(au8Buf,(ROM char *)"FB")==0)
02978     {
02979         *pDev = SRCP_DT_FB;
02980         if (u16Code==100)
02981             return TRUE;
02982     }
02983     else if (strcmppgm2ram(au8Buf,(ROM char *)"GA")==0) 
02984     {
02985         *pDev = SRCP_DT_GA;
02986         return TRUE;
02987     }
02988     if (strcmppgm2ram(au8Buf, (ROM char *) "GL")== 0)
02989     {
02990         *pDev = SRCP_DT_GL;
02991         return TRUE;
02992     }
02993     else if (strcmppgm2ram(au8Buf,(ROM char *)"SM")==0)
02994     {
02995         *pDev = SRCP_DT_SM;
02996         if (u16Code==100)
02997             return TRUE;
02998     }
02999     else if (strcmppgm2ram(au8Buf,(ROM char *)"LOCK")==0)
03000         *pDev = SRCP_DT_LOCK;
03001     else if (strcmppgm2ram(au8Buf,(ROM char *)"POWER")==0)
03002         *pDev = SRCP_DT_POWER;
03003     else if (strcmppgm2ram(au8Buf,(ROM char *)"SESSION")==0)
03004     {
03005         *pDev = SRCP_DT_SESSION;
03006         return TRUE;
03007     }
03008     else if (strcmppgm2ram(au8Buf,(ROM char *)"DESCRIPTION")==0)
03009         *pDev = SRCP_DT_DESCRIPTION;
03010     else if (strcmppgm2ram(au8Buf,(ROM char *)"TIME")==0)
03011         *pDev = SRCP_DT_TIME;
03012     else if (strcmppgm2ram(au8Buf,(ROM char *)"SERVER")==0)
03013         *pDev = SRCP_DT_SERVER;
03014 
03015     return FALSE;
03016 }
03017 
03018 // ////////////////////////////////////////////////////////////////////////////
03019 // ////////////////////////////////////////////////////////////////////////////
03020 
03021 static void _getProtoName(BYTE u8ProtoId, BYTE * pString)
03022 {
03023     // Get data from EEPROM!
03024     SPPROTOCOL conf;
03025     _getProtoFromEEPROM(u8ProtoId, &conf);
03026     strncpy(pString, conf.au8Desc, SRCP_NAME_MAXLEN);
03027     conf.au8Desc[SRCP_NAME_MAXLEN] = 0;
03028     OutConvertNameForDisplay(pString);
03029 }
03030 
03031 // ////////////////////////////////////////////////////////////////////////////
03032 // ////////////////////////////////////////////////////////////////////////////
03033 
03034 static BYTE _u8GenerateActiveProtoList(BOOL bGL, BYTE u8Default)
03035 {
03036     BYTE i = 0;
03037     BYTE protostart, protomax;
03038     BYTE count = 0;
03039     SPPROTOCOL conf;
03040 
03041 
03042     // Step 1: Get the device dependent margins for protocol.
03043     if (bGL == TRUE)
03044     {
03045         protostart = 0;
03046         protomax = MAX_PROTO_SLOTS;
03047     }
03048     else
03049     {
03050         protostart = MAX_PROTO_SLOTS;
03051         protomax = MAX_PROTO_SLOTS * 2;
03052     }
03053 
03054 
03055     // Step 2: Looking for the default protocol and add it to the list. 
03056     if ((bGL == TRUE) && (u8Default == SRCP_SERVERCACHE_ID))
03057     {
03058         _au8ActiveProtos[count++] = SRCP_SERVERCACHE_ID;
03059     }
03060     else if (u8Default == SRCP_EEPROMSET_ID)
03061     {
03062         _au8ActiveProtos[count++] = SRCP_EEPROMSET_ID;
03063     }
03064     else
03065     {
03066         // Get data from EEPROM!
03067         _getProtoFromEEPROM(u8Default, &conf);
03068         if (conf.sFlags.bActive == TRUE)
03069         {
03070             _au8ActiveProtos[count++] = u8Default;
03071         }
03072     }
03073 
03074 
03075     if (u8Default != SRCP_EEPROMSET_ID)
03076     {
03077         _au8ActiveProtos[count++] = SRCP_EEPROMSET_ID;
03078     }
03079 
03080     if ((bGL==TRUE)&&(u8Default != SRCP_SERVERCACHE_ID))
03081     {
03082         _au8ActiveProtos[count++] = SRCP_SERVERCACHE_ID;
03083     }
03084 
03085 
03086     for (i = protostart; i < protomax; i++)
03087     {
03088         if (u8Default == i)
03089         {
03090             // The default protocol is already in the list. 
03091             continue;
03092         }
03093 
03094         // Get data from EEPROM!
03095         _getProtoFromEEPROM(i, &conf);
03096 
03097         if (conf.sFlags.bActive == TRUE)
03098         {
03099             _au8ActiveProtos[count++] = i;
03100         }
03101     }
03102 
03103     return count;
03104 }
03105 
03106 // ////////////////////////////////////////////////////////////////////////////
03107 // ////////////////////////////////////////////////////////////////////////////
03108 
03109 static void _getProtoMinMax(BYTE u8ProtoId, WORD* pu16MinAdd, WORD* pu16MaxAdd)
03110 {
03111     // Get data from EEPROM!
03112     SPPROTOCOL conf;
03113     _getProtoFromEEPROM(u8ProtoId, &conf);
03114     *pu16MinAdd = conf.u16MinAdd;
03115     *pu16MaxAdd = conf.u16MaxAdd;
03116 }
03117 
03118 // ////////////////////////////////////////////////////////////////////////////
03119 // ////////////////////////////////////////////////////////////////////////////
03120 
03121 static BOOL _bGetStaticParameterFromCache(BYTE u8CacheId, sStaticDeviceData * psPrm)
03122 {
03123     if (_apsSelectCache == NULL)
03124     {
03125         PrintCommonError(COMMON_ERROR_NULL_POINTER);
03126         return FALSE;
03127     }
03128 
03129     memset((void*)psPrm, 0, sizeof(sStaticDeviceData));
03130 
03131 
03132     // Copy proto data.
03133     strncpy(psPrm->au8Proto, _apsSelectCache[u8CacheId].au8Proto, SRCP_PROTO_MAXLEN);
03134     psPrm->u8BusNr = _apsSelectCache[u8CacheId].u8BusNr;
03135     psPrm->u32Address = _apsSelectCache[u8CacheId].u32Address;
03136     psPrm->uSpec.sGLSpec.u8MaxSteps = _apsSelectCache[u8CacheId].u8MaxSteps;
03137     psPrm->uSpec.sGLSpec.u8NrFunc = _apsSelectCache[u8CacheId].u8NrFunc;
03138 
03139     return TRUE;
03140 }
03141 
03142 // ////////////////////////////////////////////////////////////////////////////
03143 // ////////////////////////////////////////////////////////////////////////////
03144 
03145 static void _destructServerCache(void)
03146 {
03147     if (_apsSelectCache)
03148     {
03149         SRAMfree((BYTE*)_apsSelectCache);
03150         _apsSelectCache = NULL;
03151     }
03152 }
03153 
03154 // ////////////////////////////////////////////////////////////////////////////
03155 // ////////////////////////////////////////////////////////////////////////////
03156 
03157 static BOOL _bGetStaticParameterFromProto(BYTE u8ProtoId, sStaticDeviceData * psPrm)
03158 {
03159     SPPROTOCOL conf;
03160 
03161     // Get data from EEPROM!
03162     _getProtoFromEEPROM(u8ProtoId, &conf);
03163 
03164     if ((conf.sFlags.bActive == FALSE)||(psPrm == NULL))
03165     {
03166         PrintCommonError(COMMON_ERROR_LOADING_SRCP_PROTOCOL);
03167         return FALSE;
03168     }
03169 
03170     memset((void*)psPrm, 0, sizeof(sStaticDeviceData));
03171 
03172     // Copy proto data.
03173     strncpy(psPrm->au8Proto, conf.au8Proto, SRCP_PROTO_MAXLEN);
03174     psPrm->u8BusNr = conf.u8Bus;
03175 
03176     if (conf.sFlags.bGL == TRUE)
03177     {
03178         psPrm->uSpec.sGLSpec.u8MaxSteps = conf.uSpec.sGL.u8MaxSteps;
03179         psPrm->uSpec.sGLSpec.u8NrFunc = conf.uSpec.sGL.u8NrFunc;
03180     }
03181     else
03182     {
03183         psPrm->uSpec.sGASpec.u8MinP = conf.uSpec.sGA.u8MinP;
03184         psPrm->uSpec.sGASpec.u8MaxP = conf.uSpec.sGA.u8MaxP;
03185     }
03186 
03187     return TRUE;
03188 }
03189 
03190 // ////////////////////////////////////////////////////////////////////////////
03191 // ////////////////////////////////////////////////////////////////////////////
03192 
03193 static void _fillPrmGL(sGL * psNewGL, sStaticDeviceData * psStaticData)
03194 {
03195     if ((psNewGL == NULL) || (psStaticData == NULL))
03196     {
03197         return;
03198     }
03199 
03200     memset(psNewGL, 0, sizeof(sGL));
03201 
03202     // Copy the proto data into the device structure:
03203     strncpy(psNewGL->au8Proto, psStaticData->au8Proto, SRCP_PROTO_MAXLEN);
03204     strncpy(psNewGL->au8Name, psStaticData->au8Name, SRCP_NAME_MAXLEN);
03205     psNewGL->u32Addr = psStaticData->u32Address;
03206     psNewGL->u8MaxSteps = psStaticData->uSpec.sGLSpec.u8MaxSteps;
03207     psNewGL->u8NrFunc = psStaticData->uSpec.sGLSpec.u8NrFunc;
03208     psNewGL->s16MaxV = psStaticData->uSpec.sGLSpec.u16MaxV;
03209 
03210     // Prepare other stuff like function mask and so on.
03211     {
03212         BYTE i = 0;
03213         DWORD mask = 0x01;
03214 
03215         for (i = 0; i < MAX_SRCP_FUNCTIONS, i < psNewGL->u8NrFunc; i++, mask=mask<<1)
03216         {
03217             psNewGL->u32FuncAllocMask |= mask;
03218         }
03219 
03220         psNewGL->u32FuncToggleMask = psStaticData->uSpec.sGLSpec.u32FunctionToggleMask;
03221     }
03222     
03223     if (psNewGL->s16MaxV == 0)
03224     {
03225         psNewGL->s16MaxV = psNewGL->u8MaxSteps;
03226     }
03227     else
03228     {
03229         // Show a unit if a maximum speed is configured.
03230         psNewGL->sGLFlags.bUnit = TRUE;
03231     }
03232 
03233     psNewGL->sGLFlags.u2Dir = DIR_FORWARD;
03234 }
03235 
03236 // ////////////////////////////////////////////////////////////////////////////
03237 // ////////////////////////////////////////////////////////////////////////////
03238 
03239 static void _fillPrmGA(sGA * psNewGA, sStaticDeviceData * psStaticData)
03240 {
03241     if ((psNewGA == NULL) || (psStaticData == NULL))
03242     {
03243         return;
03244     }
03245 
03246     memset(psNewGA, 0, sizeof(sGA));
03247 
03248     // Copy the proto data into the device structure:
03249     strncpy(psNewGA->au8Name, psStaticData->au8Name, SRCP_NAME_MAXLEN);
03250     strncpy(psNewGA->au8Proto, psStaticData->au8Proto, SRCP_PROTO_MAXLEN);
03251     psNewGA->u32Addr = psStaticData->u32Address;
03252     psNewGA->u8MinPort = psStaticData->uSpec.sGASpec.u8MinP;
03253     psNewGA->u8MaxPort = psStaticData->uSpec.sGASpec.u8MaxP;
03254 
03255     if (psStaticData->uSpec.sGASpec.s32Delay == 0)
03256     {
03257         psNewGA->s32Delay = sPSRCPConfig.s32GADelay;
03258     }
03259     else
03260     {
03261         psNewGA->s32Delay = psStaticData->uSpec.sGASpec.s32Delay;
03262     }
03263 
03264     psNewGA->u8Port = psNewGA->u8MinPort;
03265 }
03266 
03267 // ////////////////////////////////////////////////////////////////////////////
03268 // ////////////////////////////////////////////////////////////////////////////
03269 
03270 static void _getInitData(SRCP_DEVICE * pDev, char * pString)
03271 {
03272     if (pDev == NULL)
03273     {
03274         pString[0] = 0;
03275         return;
03276     }
03277 
03278     if (pDev->eDevType == SRCP_DT_GA)
03279     {
03280         sGA * pGA = (sGA *)(&pDev[1]);
03281         strcpy(pString, pGA->au8Proto);
03282     }
03283     else if (pDev->eDevType == SRCP_DT_GL)
03284     {
03285         sGL * pGL = (sGL *)(&pDev[1]);
03286         strcpy(pString, pGL->au8Proto);
03287 
03288         if (strrchr(pString,'M') || strrchr(pString,'N'))
03289         {
03290             // Add parameters (max speed steps and number of functions) to the 
03291             // initialization string if it is a NMRA or Motorola Decoder like 
03292             // described in the SRCP Spec.      
03293             sprintf(&pString[strlen(pString)],(ROM char *)" %hhu %hhu", pGL->u8MaxSteps, pGL->u8NrFunc);
03294         }
03295     }
03296 }
03297 
03298 // ////////////////////////////////////////////////////////////////////////////
03299 // ////////////////////////////////////////////////////////////////////////////
03300 
03301 void _startHandShake(void)
03302 {
03303     _eHSState = SRCP_HS_WAIT_FOR_WELCOME;
03304 }
03305 
03306 // ////////////////////////////////////////////////////////////////////////////
03308 // ////////////////////////////////////////////////////////////////////////////
03309 
03310 SRCP_HANDSHAKE_RETCODE _eHandShake(SSRCPSOCKET * hSRCP)
03311 {
03312     BYTE socket = hSRCP->u8Socket;
03313     WORD code = 0;
03314     SRCP_TIME time;
03315 
03316     switch (_eHSState)
03317     {
03318     case SRCP_HS_WAIT_FOR_WELCOME:
03319 
03320         // For the welcome message we can not use the SRCP parse functions 
03321         // because the message format is completly different.
03322 
03323         if (TCPIsGetReady(socket))
03324         {
03325             // received a frame...
03326             BYTE buf[11];
03327             BOOL end = FALSE;
03328             BOOL valid = FALSE;
03329 
03330             // We still wait for the welcome message with the supported 
03331             // SRCP versions of the server.
03332             while (_bGetNextWord(socket,buf,sizeof(buf),&end))
03333             {
03334                 // Looking for the keyword SRCP or SRCPOTHER. The value of 
03335                 // this key (the following SRCP word) is the supported 
03336                 // version.
03337                 if ((strncmppgm2ram(buf, (ROM char *) "SRCP", 10)==0)||
03338                     (strncmppgm2ram(buf, (ROM char *) "SRCPOTHER", 10)==0))
03339                 {
03340                     if(_bGetNextWord(socket,buf,10,&end)==FALSE)
03341                     {
03342                         break;
03343                     }
03344 
03345                     // eWicht only supports SRCP version 0.8 at this 
03346                     // time. Add more code here for other versions.
03347                     if (strncmppgm2ram(buf,(ROM char *)"0.8",3)==0)
03348                     {
03349                         valid = TRUE;   
03350                         break;              
03351                     }   
03352                 }
03353             }
03354     
03355             if (valid == TRUE)
03356             {
03357                 // eWicht supports this server version, got to the next
03358                 // state.
03359                 _eHSState = SRCP_HS_SET_VERSION;
03360             }
03361             else
03362             {
03363                 // Unsupported SCRP version, close this session.
03364                 StrTbl_GetString(lcdram_row1, STRTBLID_SERVERVERSION);
03365                 StrTbl_GetString(lcdram_row2, STRTBLID_UNKNOWN);
03366                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03367                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03368                 _eHSState = SRCP_HS_ERROR;
03369             }
03370 
03371             TCPDiscard(socket);
03372         }
03373         break;
03374 
03375     case SRCP_HS_SET_VERSION:
03376         if (TCPIsPutReady(socket))
03377         {
03378             // Send the SRCP version to server. As we have seen in the welcome
03379             // message, the server supports it, but we explicitly send the set
03380             // message to prevent errors.
03381             TCPPutROMString(socket, (ROM char *) "SET PROTOCOL SRCP 0.8\n");
03382             TCPFlush(socket);
03383 
03384             _eHSState = SRCP_HS_WAIT_VERSION;
03385         }
03386         break;
03387 
03388     case SRCP_HS_SET_MODE:
03389         if (TCPIsPutReady(socket))
03390         {
03391             // Send the SRCP connection mode to server. 
03392             // It depends on the socket given to this function.
03393 
03394             TCPPutROMString(socket, (ROM char*) "SET CONNECTIONMODE SRCP ");
03395             if (hSRCP->bCommand == TRUE)
03396                 TCPPutROMString(socket, (ROM char*) "COMMAND\n");
03397             else
03398                 TCPPutROMString(socket, (ROM char*) "INFO\n");          
03399             TCPFlush(socket);
03400 
03401             _eHSState = SRCP_HS_WAIT_MODE;
03402         }
03403         break;
03404 
03405     case SRCP_HS_GO:
03406         if (TCPIsPutReady(hSRCP->u8Socket))
03407         {
03408             TCPPutROMString(hSRCP->u8Socket, (ROM char *) "GO\n");
03409             TCPFlush(hSRCP->u8Socket);
03410 
03411             _eHSState = SRCP_HS_WAIT_GO;
03412         }
03413         break;
03414 
03415     case SRCP_HS_WAIT_VERSION:
03416     case SRCP_HS_WAIT_MODE:
03417     case SRCP_HS_WAIT_GO:
03418     {
03419         BOOL ret;
03420         if (TCPIsGetReady(socket)==0)
03421             break;
03422 
03423         // received a frame...
03424         ret = _startParsing(socket, &time, &code);
03425         TCPDiscard(socket);
03426         if (ret==FALSE)
03427             break;
03428 
03429         switch(code)
03430         {
03431             case 200:
03432                 _eHSState = SRCP_HS_GOING;          
03433                 break;
03434             
03435             case 201:
03436                 _eHSState = SRCP_HS_SET_MODE;
03437                 break;
03438 
03439             case 202:
03440                 _eHSState = SRCP_HS_GO;
03441                 break;
03442 
03443             case 400:
03444                 // Oops! The server says in its welcome message, that
03445                 // he supports this SRCP version but than the server 
03446                 // NAKs the explicitly version set?! Sounds like an 
03447                 // implementation error in the server...
03448                 StrTbl_GetString(lcdram_row1, STRTBLID_SRVVERSION);
03449                 StrTbl_GetString(lcdram_row2, STRTBLID_UNKNOWN);
03450                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03451                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03452                 _eHSState = SRCP_HS_ERROR;
03453                 break;
03454 
03455             case 401:
03456                 StrTbl_GetString(lcdram_row1, STRTBLID_SRVMODE);
03457                 StrTbl_GetString(lcdram_row2, STRTBLID_UNKNOWN);
03458                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03459                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03460                 _eHSState = SRCP_HS_ERROR;
03461                 break;
03462 
03463             case 402:
03464                 StrTbl_GetString(lcdram_row1, STRTBLID_SRVUNSUFFICIENT_DATA1);
03465                 StrTbl_GetString(lcdram_row2, STRTBLID_SRVUNSUFFICIENT_DATA2);
03466                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03467                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03468                 _eHSState = SRCP_HS_ERROR;
03469                 break;
03470 
03471             case 403:
03472                 StrTbl_GetString(lcdram_row1, STRTBLID_SRVUNKNOWN_COMMAND1);
03473                 StrTbl_GetString(lcdram_row2, STRTBLID_SRVUNKNOWN_COMMAND2);
03474                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03475                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03476                 _eHSState = SRCP_HS_ERROR;
03477                 break;
03478 
03479             case 500:
03480                 StrTbl_GetString(lcdram_row1, STRTBLID_SRVNO_RESSOURCES1);
03481                 StrTbl_GetString(lcdram_row2, STRTBLID_SRVNO_RESSOURCES2);
03482                 lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03483                              LCD_ROW2_MASK | LCD_CENTER2_MASK;
03484                 _eHSState = SRCP_HS_ERROR;
03485                 break;
03486         }
03487         break;
03488     }
03489 
03490     case SRCP_HS_ERROR:
03491         return SRCP_HR_ERROR;
03492     
03493     case SRCP_HS_GOING:
03494         return SRCP_HR_FINISHED;
03495     }
03496 
03497     return SRCP_HR_IN_PROGRESS;
03498 }
03499 
03500 // ////////////////////////////////////////////////////////////////////////////
03501 // ////////////////////////////////////////////////////////////////////////////
03502 
03503 static BOOL _bIsInitAllowed(SRCP_DEVTYPE eDevType)
03504 {
03505     if ((eDevType==SRCP_DT_SESSION)||
03506         (eDevType==SRCP_DT_SERVER)||
03507         (eDevType==SRCP_DT_DESCRIPTION)||
03508         (eDevType==SRCP_DT_LOCK))
03509     {
03510         return FALSE;
03511     }
03512 
03513     return TRUE;
03514 }
03515 
03516 // ////////////////////////////////////////////////////////////////////////////
03517 // ////////////////////////////////////////////////////////////////////////////
03518 
03519 static void _updateInput(SRCP_DEVICE * pDev)
03520 {
03521     // Is there a configured device for input?
03522     if (pDev == NULL)
03523     {
03524         return;     // No!
03525     }
03526 
03527     if (pDev->eDevState == SRCP_DS_DISABLED)
03528     {
03529         return;
03530     }
03531 
03532     // Is a server request already running?
03533     if (_bSrvReqIsInProgress == TRUE)
03534     {
03535         return;
03536     }
03537 
03538     if (pDev->eDevType == SRCP_DT_GL)
03539     {
03540         sGL tmp;
03541         sGL * pGL = (sGL *)(&pDev[1]);
03542 
03543         // Temporary save the server consistent data.
03544         memcpy((void*)&tmp, (void*)pGL, sizeof(sGL));
03545 
03546         if (_bGetGLInput(pGL) == TRUE)
03547         {
03548             tmp.s16ActV = pGL->s16ActV;
03549             tmp.u8FuncGroup = pGL->u8FuncGroup;
03550 
03551             _bSendSRCPMessage(SRCP_CMD_SET, pDev);
03552 
03553             // Restore the old data to stay consistent with the server.
03554             // The recently sent data will processed by the server and comes
03555             // back via an INFO message.
03556             memcpy((void*)pGL, (void*)&tmp, sizeof(sGL));
03557         }
03558     }
03559     else if (pDev->eDevType == SRCP_DT_GA)
03560     {
03561         sGA tmp;
03562         sGA * pGA = (sGA *)(&pDev[1]);
03563 
03564         // Temporary save the server consistent data.
03565         memcpy((void*)&tmp, (void*)pGA, sizeof(sGA));
03566 
03567         if (_bGetGAInput(pDev) == TRUE)
03568         {
03569             _bSendSRCPMessage(SRCP_CMD_SET, pDev);
03570 
03571             // Restore the old data to stay consistent with the server.
03572             // The recently sent data will processed by the server and comes
03573             // back via an INFO message.
03574             memcpy((void*)pGA, (void*)&tmp, sizeof(sGA));
03575         }
03576     }
03577 }
03578 
03579 // ////////////////////////////////////////////////////////////////////////////
03580 // ////////////////////////////////////////////////////////////////////////////
03581 
03582 static void _updateView(SRCP_DEVICE * pDev)
03583 {
03584     // Is there a configured device for view?
03585     if (pDev == NULL)
03586     {
03587         return;     // No!
03588     }
03589 
03590     if (pDev->eDevState == SRCP_DS_DISABLED)
03591     {
03592         // The device is not idle anymore. That means, that the server or
03593         // another client has terminated the device.
03594         StrTbl_GetString(lcdram_row1, STRTBLID_SERVER_HAS);
03595         StrTbl_GetString(lcdram_row2, STRTBLID_DEVICE_TERMINATED);
03596         lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03597                      LCD_ROW2_MASK | LCD_CENTER2_MASK;
03598 
03599         // Set the device state to disabled.
03600         pDev->eDevState = SRCP_DS_DISABLED;
03601     }
03602     
03603     if (pDev->u16LastErrorCode)
03604     {
03605         _showServerError(pDev->u16LastErrorCode);
03606         pDev->u16LastErrorCode = 0;     // Acknowledge the error.
03607         _eSRCPsm = SRCP_ERROR;
03608         pDev->eDevState = SRCP_DS_DISABLED;
03609     }
03610 
03611 
03612     // New data for the view!
03613     if (pDev->sFlags.bNewData == TRUE)
03614     {
03615         switch(pDev->eDevType)
03616         {
03617             case SRCP_DT_GL:
03618                 _displayGLData(pDev);
03619                 break;
03620     
03621             case SRCP_DT_GA:
03622                 _displayGAData(pDev);
03623                 break;
03624     
03625             case SRCP_DT_POWER:
03626                 _displayPower(pDev);
03627                 break;
03628         }
03629 
03630         pDev->sFlags.bNewData = FALSE;
03631     }
03632 }
03633 
03634 // ////////////////////////////////////////////////////////////////////////////
03635 // ////////////////////////////////////////////////////////////////////////////
03636 
03637 static BYTE _u8AddEntryToEEPROM(BYTE u8RawQuickIdx, SRCP_DEVICE * pDevice)
03638 {
03639     SPSET eepromSet;
03640     BYTE idx = u8RawQuickIdx & SRCP_EEPROMSET_IDX_MASK;
03641     DWORD newAdd = 0;
03642 
03643     if (pDevice == NULL)
03644     {
03645         return 0xFF;
03646     }   
03647 
03648     // Step 1: Load the quick setting from eeprom:
03649     if (pDevice->eDevType == SRCP_DT_GA)
03650     {
03651         idx |= SRCP_EEPROMSET_GA_MASK;
03652     }
03653 
03654     XEEReadArray(SRCP_SETS_EEPROM_ADD+(sizeof(SPSET) * idx), (BYTE *)&eepromSet, sizeof(SPSET));
03655 
03656 
03657     // Step 2: Check the device type and write new settings to quick structure.
03658     if (pDevice->eDevType == SRCP_DT_GA)
03659     {
03660         sGA * pGA = (sGA *)(&pDevice[1]);
03661         eepromSet.uSpec.sGA.u8MinP = pGA->u8MinPort;
03662         eepromSet.uSpec.sGA.u8MaxP = pGA->u8MaxPort;
03663     }
03664     else if (pDevice->eDevType == SRCP_DT_GL)
03665     {
03666         sGL * pGL = (sGL *)(&pDevice[1]);
03667         eepromSet.uSpec.sGL.u8MaxSteps = pGL->u8MaxSteps;
03668         eepromSet.uSpec.sGL.u8NrFunc = pGL->u8NrFunc;
03669     }
03670     else
03671     {
03672         // This device type is not supported for quick set.
03673         return 0xFF;
03674     }
03675     
03676     newAdd = _u32GetAddress(pDevice);
03677     strncpy(eepromSet.au8Proto, DEVICE_PROTO_PTR(pDevice), SRCP_PROTO_MAXLEN);
03678     eepromSet.au8Proto[SRCP_PROTO_MAXLEN] = 0;
03679 
03680     // Step 3: Compare current settings with new settings:
03681     if ((eepromSet.u32Address!=newAdd) || (eepromSet.u8BusNr!=pDevice->u8Bus))
03682     {
03683         // This is a completly new entry!
03684         // Default string "SX"
03685         eepromSet.au8Name[0] = 'S';
03686         eepromSet.au8Name[1] = '1' + u8RawQuickIdx;
03687         eepromSet.au8Name[2] = 0;
03688     }
03689 
03690     // Step 4: Write new settings to EEPROM:
03691     eepromSet.u32Address = newAdd;
03692     eepromSet.u8BusNr = pDevice->u8Bus;
03693     eepromSet.sFlags.bActive = TRUE;
03694 
03695     XEEWriteArray(SRCP_SETS_EEPROM_ADD+(sizeof(SPSET) * idx), (BYTE *)&eepromSet, sizeof(SPSET));
03696 
03697 
03698     // Step 5: Copy the EEPROM set name to the device
03699     {
03700         BYTE * pName = DEVICE_NAME_PTR(pDevice);
03701         strncpy(pName, eepromSet.au8Name, SRCP_NAME_MAXLEN);
03702         pName[SRCP_NAME_MAXLEN] = 0;
03703     }
03704 
03705     // Return the stored EEPROM set index:
03706     return idx;
03707 }
03708 
03709 // ////////////////////////////////////////////////////////////////////////////
03710 // ////////////////////////////////////////////////////////////////////////////
03711 
03712 static BOOL _bCheckForSelectedSet(sStaticDeviceData* psDeviceData, BOOL bEncoder)
03713 {
03714     SPSET set;
03715     BYTE tmpidx;
03716 
03717     if (psDeviceData == NULL)
03718     {
03719         return FALSE;
03720     }
03721 
03722     if (_pActiveEEPROMSetList && (bEncoder == TRUE) && (bInputButtonPushed(ENC_BTN) == TRUE))
03723     {
03724         tmpidx = _pActiveEEPROMSetList[s16InputEncoderGetValue()];
03725     }
03726     else if (u8InputButtonQuickPushed() != 0xFF)
03727     {
03728         tmpidx =  u8InputButtonQuickPushed();
03729     }
03730     else
03731     {
03732         return FALSE;
03733     }
03734 
03735     tmpidx &= SRCP_EEPROMSET_IDX_MASK;
03736     if (OutGetLEDMode(LED_ACC) == LED_ON)
03737     {
03738         // GA is selected.
03739         tmpidx |= SRCP_EEPROMSET_GA_MASK;
03740     }
03741 
03742     // Read the quick data from EEPROM.
03743     XEEReadArray(SRCP_SETS_EEPROM_ADD+(sizeof(SPSET) * tmpidx), (BYTE *)&set, sizeof(SPSET));
03744 
03745     if (set.sFlags.bActive == TRUE)
03746     {
03747         // This quick position is occupied.
03748         memset((void*)psDeviceData, 0, sizeof(sStaticDeviceData));
03749 
03750         psDeviceData->u8BusNr = set.u8BusNr;
03751         psDeviceData->u32Address = set.u32Address;
03752         strncpy(psDeviceData->au8Proto, set.au8Proto, SRCP_PROTO_MAXLEN);
03753         strncpy(psDeviceData->au8Name, set.au8Name, SRCP_NAME_MAXLEN);
03754 
03755         if (tmpidx & SRCP_EEPROMSET_GA_MASK)
03756         {
03757             psDeviceData->uSpec.sGASpec.u8MinP = set.uSpec.sGA.u8MinP;
03758             psDeviceData->uSpec.sGASpec.u8MaxP = set.uSpec.sGA.u8MaxP;
03759             psDeviceData->uSpec.sGASpec.s32Delay = set.uSpec.sGA.s32Delay;
03760         }
03761         else
03762         {
03763             psDeviceData->uSpec.sGLSpec.u8MaxSteps = set.uSpec.sGL.u8MaxSteps;
03764             psDeviceData->uSpec.sGLSpec.u8NrFunc = set.uSpec.sGL.u8NrFunc;
03765             psDeviceData->uSpec.sGLSpec.u16MaxV = set.uSpec.sGL.u16MaxV;
03766             psDeviceData->uSpec.sGLSpec.u32FunctionToggleMask = set.uSpec.sGL.u32FuncToggleMask;
03767         }
03768 
03769         return TRUE;
03770     }
03771 
03772     return FALSE;
03773 }
03774 
03775 // ////////////////////////////////////////////////////////////////////////////
03776 // ////////////////////////////////////////////////////////////////////////////
03777 
03778 static void _storeNameToEEPROM(BYTE u8EEPROMSetIdx, BYTE *pName)
03779 {
03780     SPSET eepromdata;
03781 
03782     if ((pName == NULL)||(u8EEPROMSetIdx == 0xFF))
03783     {
03784         return;
03785     }
03786 
03787     XEEReadArray(SRCP_SETS_EEPROM_ADD+(sizeof(SPSET) * u8EEPROMSetIdx), (BYTE *)&eepromdata, sizeof(SPSET));
03788     strncpy(eepromdata.au8Name, pName, SRCP_NAME_MAXLEN);
03789     eepromdata.au8Name[SRCP_NAME_MAXLEN] = 0;
03790     XEEWriteArray(SRCP_SETS_EEPROM_ADD+(sizeof(SPSET) * u8EEPROMSetIdx), (BYTE *)&eepromdata, sizeof(SPSET));
03791 }
03792 
03793 // ////////////////////////////////////////////////////////////////////////////
03794 // ////////////////////////////////////////////////////////////////////////////
03795 
03796 static void _UpdateServerCache(SRCP_PRM * pPrm, BOOL bAdd)
03797 {
03798     short i = 0;
03799 
03800     // Step 1: Look for an appropriate entry in the cache list.
03801     // Only GLs are currently supported.
03802     if (pPrm->eDevType != SRCP_DT_GL)
03803     {
03804         return;
03805     }
03806 
03807     for (i = 0; i < SERVER_CACHE_ENTRIES; i++)
03808     {
03809         if ((pPrm->u8Bus == _asServerCache[i].u8BusNr) && 
03810             (pPrm->uStat.sGL.u32Addr == _asServerCache[i].u32Address))
03811         {
03812             // Entry is already in the list.
03813             if (bAdd == TRUE)
03814             {
03815                 return;
03816             }
03817 
03818             break;
03819         }
03820     }
03821 
03822 
03823     // Step 2: Reorder Cache.
03824     if (bAdd == TRUE)
03825     {
03826         // Add the device!
03827         for (i = (SERVER_CACHE_ENTRIES-2); i >= 0; i--)
03828         {
03829             if (_asServerCache[i].u8BusNr == 0)
03830             {
03831                 // Entry is empty, skip this step.
03832                 continue;
03833             }
03834 
03835             // Move down in cache
03836             memcpy((void *)&_asServerCache[i+1], (void*)&_asServerCache[i], sizeof(sServerCacheEntry));
03837         }
03838     
03839     
03840         // Step 3: Store new entry in the list.
03841         _asServerCache[0].u8BusNr = pPrm->u8Bus;
03842         _asServerCache[0].u32Address = pPrm->uStat.sGL.u32Addr;
03843         strcpy(_asServerCache[0].au8Proto, pPrm->uStat.sGL.au8Proto);
03844         _asServerCache[0].u8MaxSteps = pPrm->uStat.sGL.u8MaxSteps;
03845         _asServerCache[0].u8NrFunc = pPrm->uStat.sGL.u8NrFunc;
03846     }
03847     else
03848     {
03849         if (SERVER_CACHE_ENTRIES == i)
03850         {
03851             // Not found in cache!
03852             return;
03853         }
03854 
03855         // Remove the device!
03856         _asServerCache[i++].u8BusNr = 0;
03857 
03858         for (; i < SERVER_CACHE_ENTRIES; i++)
03859         {
03860             // The end of cache?
03861             if (_asServerCache[i].u8BusNr == 0)
03862             {
03863                 break;
03864             }
03865 
03866             // Move up in cache
03867             memcpy((void *)&_asServerCache[i-1], (void*)&_asServerCache[i], sizeof(sServerCacheEntry));
03868 
03869             // Free the last index
03870             _asServerCache[i].u8BusNr = 0;
03871         }
03872     }
03873 }
03874 
03875 // ////////////////////////////////////////////////////////////////////////////
03876 // ////////////////////////////////////////////////////////////////////////////
03877 
03878 static BOOL _bPrepareServerCacheInput(void)
03879 {
03880     BYTE entries;
03881 
03882     // Step 1: Check wether the cache is empty:
03883     if (_asServerCache[0].u8BusNr == 0)
03884     {
03885         // Server cache is empty. Give an error message to the user and abort
03886         // the preparation.
03887         lcd_addr1 = 0;
03888         lcd_addr2 = 0;
03889         StrTbl_GetString(lcdram_row1, STRTBLID_SERVER_CACHE);
03890         StrTbl_GetString(lcdram_row2, STRTBLID_IS_EMPTY);
03891         lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
03892                         LCD_ROW2_MASK | LCD_CENTER2_MASK;
03893         return FALSE;
03894     }
03895 
03896 
03897     // Step 2: Get the server cache count:
03898     for (entries = 1; entries < SERVER_CACHE_ENTRIES; entries++)
03899     {
03900         if (_asServerCache[entries].u8BusNr == 0)
03901         {
03902             break;
03903         }
03904     }
03905 
03906 
03907     // Step 3: Get a local copy of the server cache which is stable for the 
03908     // time of input.
03909     _apsSelectCache = (sServerCacheEntry *)(SRAMalloc((sizeof(sServerCacheEntry))*entries));
03910 
03911     if (_apsSelectCache == NULL)
03912     {
03913         PrintCommonError(COMMON_ERROR_OUT_OF_MEMORY);
03914         return FALSE;
03915     }
03916 
03917     memcpy((void*)_apsSelectCache,(void*)_asServerCache,(sizeof(sServerCacheEntry))*entries);
03918 
03919 
03920     // Step 4: Initialize the encoder.
03921     InputButtonReset(ENC_BTN);
03922     InputEncoderInit(0, 0, entries-1, 0);
03923 
03924 
03925     // Done.
03926     return TRUE;    
03927 }
03928 
03929 // ////////////////////////////////////////////////////////////////////////////
03930 // ////////////////////////////////////////////////////////////////////////////
03931 
03932 void SRCPPrepareConnection(void)
03933 {
03934     // Prepare SRCP-Sockets:
03935     _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
03936     _sSRCPState.sCommand.bCommand = TRUE;
03937     _sSRCPState.sInfo.u8Socket = INVALID_SOCKET;
03938     _sSRCPState.sInfo.bCommand = FALSE;
03939 
03940     // Prepare state machine stuff:
03941     _eSRCPCsm = SRCPC_SM_CONNECT_COMMAND;
03942     _eSRCPsm = SRCP_STARTUP;
03943 
03944     _bSrvReqIsInProgress = FALSE;
03945     _psActualDevice = NULL;
03946 
03947     memset(_au8ActiveProtos, 0, sizeof(_au8ActiveProtos));
03948 
03949     memset(_asServerCache, 0 , sizeof(_asServerCache));
03950     _apsSelectCache = NULL;
03951 
03952     memset(_apsDevices, 0, sizeof(_apsDevices));
03953     SRAMInitHeap();
03954 }
03955 
03956 // ////////////////////////////////////////////////////////////////////////////
03957 // ////////////////////////////////////////////////////////////////////////////
03958 
03959 APPL_CONNECTING_RETCODE SRCPHandleServerConnection(void)
03960 {
03961     switch(_eSRCPCsm)
03962     {
03963     case SRCPC_SM_CONNECT_COMMAND:
03964     {
03965         _sSRCPState.sCommand.u8Socket = TCPConnect(ApplGetServerNodeInfo(), ApplGetServerPort().Val);
03966         
03967         if (_sSRCPState.sCommand.u8Socket == INVALID_SOCKET)
03968         {
03969              _eSRCPCsm = SRCPC_SM_ERROR_CONNECT;
03970         }
03971         else
03972         {
03973              _eSRCPCsm = SRCPC_SM_CONNECT_WAIT_COMMAND;
03974         }
03975         break;
03976     }
03977 
03978     case SRCPC_SM_CONNECT_WAIT_COMMAND:
03979         if (TCPWasReset(_sSRCPState.sCommand.u8Socket) || (bInputButtonPushed(ENC_BTN) == TRUE))
03980         {
03981             _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
03982             _eSRCPCsm = SRCPC_SM_CLOSING;
03983         }
03984         else if (TCPIsConnected(_sSRCPState.sCommand.u8Socket))
03985         {
03986             OutSwitchOffAllLEDs();
03987             _startHandShake();
03988             _eSRCPCsm = SRCPC_SM_CONNECTED_COMMAND;
03989         }
03990         break;
03991 
03992     case SRCPC_SM_CONNECTED_COMMAND:
03993         if (TCPWasReset(_sSRCPState.sCommand.u8Socket) || (bInputButtonPushed(ENC_BTN) == TRUE))
03994         {
03995             _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
03996             _eSRCPCsm = SRCPC_SM_CLOSING;
03997         }
03998         else
03999         {
04000             SRCP_HANDSHAKE_RETCODE ret = _eHandShake(&_sSRCPState.sCommand);
04001 
04002             if (ret == SRCP_HR_ERROR)
04003             {
04004                 // Errors occurred during the handshake. Display the error 
04005                 // message to the user (initiated in the Hand Shake Function) 
04006                 // and close all open connections.
04007                 u8ApplTimer = 200;
04008                 _eSRCPCsm = SRCPC_SM_DELAY_CLOSING;
04009             }
04010             else if (ret == SRCP_HR_FINISHED)
04011             {
04012                 // Connect to the INFO socket.
04013                 _sSRCPState.sInfo.u8Socket = TCPConnect(ApplGetServerNodeInfo(), ApplGetServerPort().Val);
04014 
04015                 if (_sSRCPState.sInfo.u8Socket == INVALID_SOCKET)
04016                 {
04017                     _eSRCPCsm = SRCPC_SM_CLOSING;
04018                 }
04019                 else
04020                 {
04021                     _eSRCPCsm = SRCPC_SM_CONNECT_WAIT_INFO;
04022                 }
04023             }
04024         }
04025         break;
04026 
04027     case SRCPC_SM_CONNECT_WAIT_INFO:
04028         if(bInputButtonPushed(ENC_BTN) == TRUE)
04029         {
04030             _eSRCPCsm = SRCPC_SM_CLOSING;
04031         }
04032         else if (TCPIsConnected(_sSRCPState.sInfo.u8Socket))
04033         {
04034             _startHandShake();
04035             _eSRCPCsm = SRCPC_SM_CONNECTED_INFO;
04036         }       
04037         break;
04038 
04039     case SRCPC_SM_CONNECTED_INFO:
04040         if (bInputButtonPushed(ENC_BTN) == TRUE)
04041         {
04042             _eSRCPCsm = SRCPC_SM_CLOSING;
04043         }
04044         else if (TCPWasReset(_sSRCPState.sCommand.u8Socket))
04045         {
04046             _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;         
04047             _eSRCPCsm = SRCPC_SM_CLOSING;
04048         }
04049         else if (TCPWasReset(_sSRCPState.sInfo.u8Socket))
04050         {
04051             _sSRCPState.sInfo.u8Socket = INVALID_SOCKET;            
04052             _eSRCPCsm = SRCPC_SM_CLOSING;
04053         }
04054         else
04055         {
04056             SRCP_HANDSHAKE_RETCODE ret = _eHandShake(&_sSRCPState.sInfo);
04057 
04058             if (ret == SRCP_HR_ERROR)
04059             {
04060                 // Errors occurred during the handshake. Display the error 
04061                 // message to the user (initiated in the Hand Shake Function) 
04062                 // and close all open connections.
04063                 u8ApplTimer = 200;
04064                 _eSRCPCsm = SRCPC_SM_DELAY_CLOSING;
04065             }
04066             else if (ret == SRCP_HR_FINISHED)
04067             {
04068                 _eSRCPCsm = SRCPC_SM_CONNECTED;
04069             }
04070         }
04071         break;
04072 
04073     case SRCPC_SM_DELAY_CLOSING:
04074         if (u8ApplTimer == 0)
04075         {
04076             _eSRCPCsm = SRCPC_SM_CLOSING;
04077         }
04078         break;
04079 
04080     case SRCPC_SM_CLOSING:
04081         if (_sSRCPState.sCommand.u8Socket != INVALID_SOCKET)
04082         {
04083             TCPDisconnect(_sSRCPState.sCommand.u8Socket);
04084         }
04085         if (_sSRCPState.sInfo.u8Socket != INVALID_SOCKET)
04086         {
04087             TCPDisconnect(_sSRCPState.sInfo.u8Socket);
04088         }
04089 
04090         _eSRCPCsm = SRCPC_SM_WAIT_FOR_CLOSING;
04091     
04092         // Intented fall through.
04093 
04094     case SRCPC_SM_WAIT_FOR_CLOSING:
04095         if ((_sSRCPState.sCommand.u8Socket != INVALID_SOCKET) && TCPWasReset(_sSRCPState.sCommand.u8Socket))
04096         {
04097             _sSRCPState.sCommand.u8Socket = INVALID_SOCKET;
04098         }
04099         if ((_sSRCPState.sInfo.u8Socket != INVALID_SOCKET) && TCPWasReset(_sSRCPState.sInfo.u8Socket))
04100         {
04101             _sSRCPState.sInfo.u8Socket = INVALID_SOCKET;
04102         }
04103 
04104         if ((_sSRCPState.sCommand.u8Socket == INVALID_SOCKET) && (_sSRCPState.sInfo.u8Socket == INVALID_SOCKET))
04105         {
04106             _eSRCPCsm = SRCPC_SM_CLOSED;
04107         }            
04108         break;
04109     
04110     case SRCPC_SM_CLOSED:
04111         return APPL_CR_CLOSED;      
04112 
04113     case SRCPC_SM_CONNECTED:
04114         return APPL_CR_CONNECTED;
04115 
04116     case SRCPC_SM_ERROR_CONNECT:
04117         return APPL_CR_ERROR;
04118     }
04119 
04120     return APPL_CR_IN_PROGRESS;
04121 }
04122 
04123 // ////////////////////////////////////////////////////////////////////////////
04124 // ////////////////////////////////////////////////////////////////////////////
04125 
04126 BOOL SRCPIsConnected(void)
04127 {
04128     if ((_sSRCPState.sCommand.u8Socket != INVALID_SOCKET) && 
04129         (_sSRCPState.sInfo.u8Socket != INVALID_SOCKET))
04130     {
04131         return TRUE;
04132     }
04133     else
04134     {
04135         return FALSE;
04136     }
04137 }
04138 
04139 // ////////////////////////////////////////////////////////////////////////////
04140 // ////////////////////////////////////////////////////////////////////////////
04141 
04142 void SRCPStartDisconnect(void)
04143 {
04144     // Clean up the srcp module before completly disconnecting (destructor).
04145     FiniDialog(NULL);
04146 
04147     _eSRCPCsm = SRCPC_SM_CLOSING;
04148 }
04149 
04150 // ////////////////////////////////////////////////////////////////////////////
04151 // ////////////////////////////////////////////////////////////////////////////
04152 
04153 static SRCP_DEVICE * _psInitializeNewDevice(SRCP_DEVTYPE eDevType, BYTE u8Bus,
04154                                             void * pPrm)
04155 {
04156     BYTE size;
04157     SRCP_DEVICE * pDev = NULL;
04158 
04160     // Step 1: Determine the size of the requested device structure.
04161     switch(eDevType)
04162     {
04163         case SRCP_DT_POWER:
04164             size = sizeof(sPower);
04165             break;
04166 
04167         case SRCP_DT_LOCK:
04168             size = sizeof(sLock);
04169             break;
04170 
04171         case SRCP_DT_GL:
04172             size = sizeof(sGL);
04173             break;
04174 
04175         case SRCP_DT_GA:
04176             size = sizeof(sGA);
04177             break;
04178     }
04179 
04180     size += sizeof(SRCP_DEVICE);
04181 
04182 
04184     // Step 2: Allocate and initialize the device structure.
04185 
04186     pDev = (SRCP_DEVICE*)SRAMalloc(size);
04187     if (pDev == NULL)
04188     {
04189         return NULL;
04190     }
04191 
04192     memset(pDev, 0, size);
04193     pDev->eDevType = eDevType;
04194     pDev->eDevState = SRCP_DS_UNKNOWN;
04195     pDev->u8Bus = u8Bus;
04196 
04197     if (pPrm)
04198     {
04199         size -= sizeof(SRCP_DEVICE);
04200         memcpy((void *)&pDev[1], pPrm, size);
04201     }
04202 
04203     return pDev;
04204 }   
04205 
04206 // ////////////////////////////////////////////////////////////////////////////
04207 // ////////////////////////////////////////////////////////////////////////////
04208 
04209 static DWORD _u32GetAddress(SRCP_DEVICE * psDevice)
04210 {
04211     // The address is always located at the same field position regardless
04212     // of the device type.
04213 
04214     if (psDevice == NULL)
04215     {
04216         return 0;
04217     }
04218 
04219     if ((psDevice->eDevType == SRCP_DT_GL)||
04220         (psDevice->eDevType == SRCP_DT_GA)||
04221         (psDevice->eDevType == SRCP_DT_LOCK))
04222     {
04223         return (*((DWORD *)(&psDevice[1])));
04224     }
04225     else
04226     {
04227         return 0;
04228     }
04229 }
04230 
04231 // ////////////////////////////////////////////////////////////////////////////
04232 // ////////////////////////////////////////////////////////////////////////////
04233 
04234 static void _refreshDeviceList(void)
04235 {
04236     BYTE i, j;
04237     BOOL bListIsEmpty = TRUE;
04238 
04239     // Step 1: Check for double pointers in the list and remove them.
04240     for (i = 0; i < MAX_SRCP_DEVICES; i++)
04241     {
04242         if (_apsDevices[i] == NULL)
04243         {
04244             continue;
04245         }
04246 
04247         bListIsEmpty = FALSE;
04248         for (j = 0; j < MAX_SRCP_DEVICES; j++)
04249         {
04250             if ((i!=j) && (_apsDevices[i] == _apsDevices[j]))
04251             {
04252                 _apsDevices[j] = NULL;
04253             }
04254         }
04255     }
04256 
04257     if (bListIsEmpty == TRUE)
04258     {
04259         return;
04260     }
04261 
04262     // Step 2: Remove disabled devices from the device list.
04263     for (i = 0; i < MAX_SRCP_DEVICES; i++)
04264     {
04265         if (_apsDevices[i] == NULL)
04266         {
04267             continue;
04268         }
04269 
04270         if (_apsDevices[i]->eDevState == SRCP_DS_DISABLED)
04271         {
04272             if (_psActualDevice == _apsDevices[i])
04273             {
04274                 _psActualDevice = NULL;
04275             }
04276             SRAMfree((BYTE *)(_apsDevices[i]));
04277             _apsDevices[i] = NULL;
04278         }
04279     }
04280 
04281 
04282     // Step 3: Move all NULL pointers to the end of the list.
04283     for (i = FREQUENT_SRCP_DEVICE_OFFSET; i < MAX_SRCP_DEVICES; i++)
04284     {
04285         if (_apsDevices[i] != NULL)
04286         {
04287             continue;
04288         }
04289         
04290         // Find a valid pointer after this NULL position.
04291         for (j = i+1; j < MAX_SRCP_DEVICES; j++)
04292         {
04293             if (_apsDevices[j] != NULL)
04294             {
04295                 // Move the valid pointer to the NULL position:
04296                 _apsDevices[i] = _apsDevices[j];
04297                 _apsDevices[j] = NULL;
04298                 break;
04299             }
04300         }
04301     }
04302 }
04303 
04304 // ////////////////////////////////////////////////////////////////////////////
04305 // ////////////////////////////////////////////////////////////////////////////
04306 
04307 static SRCP_DEVICE * _pTakeOverDevice(SRCP_DEVICE * pDevice)
04308 {
04309     SRCP_DEVICE * pLastDevice = NULL;
04310     BYTE mainDeviceIdx = 0;
04311 
04312     if (pDevice == NULL)
04313     {
04314         return NULL;
04315     }
04316 
04317     // Check the device type (only GA and GL can be main devices).
04318     if (pDevice->eDevType == SRCP_DT_GA)
04319     {
04320         mainDeviceIdx = 1;
04321     }
04322     else if (pDevice->eDevType != SRCP_DT_GL)
04323     {
04324         return NULL;
04325     }
04326 
04327     // Is the device already stored as frequently used device?
04328     if (pDevice == _apsDevices[mainDeviceIdx])
04329     {
04330         return pDevice;
04331     }
04332 
04333 
04334     // Delete the last main device of the appropriate category.
04335     if (_apsDevices[mainDeviceIdx])
04336     {
04337         // Delete the last device!
04338         SRAMfree((BYTE *)_apsDevices[mainDeviceIdx]);
04339     }
04340 
04341     // Move the new device to the main position.
04342     _apsDevices[mainDeviceIdx] = pDevice;
04343 
04344     _refreshDeviceList();
04345 
04346     return pDevice;
04347 }
04348 
04349 // ////////////////////////////////////////////////////////////////////////////
04350 // ////////////////////////////////////////////////////////////////////////////
04351 
04352 static SRCP_DEVICE * _pGetLatestGL(void)
04353 {
04354     return _apsDevices[0];
04355 }
04356 
04357 // ////////////////////////////////////////////////////////////////////////////
04358 // ////////////////////////////////////////////////////////////////////////////
04359 
04360 static SRCP_DEVICE * _pGetLatestGA(void)
04361 {
04362     return _apsDevices[1];
04363 }
04364 
04365 // ////////////////////////////////////////////////////////////////////////////
04366 // ////////////////////////////////////////////////////////////////////////////
04367 
04368 static BYTE _prepareEEPROMSetInput(BOOL bGL)
04369 {
04370     BYTE listsize, listoffset;
04371     BYTE i, entries;
04372     WORD address;
04373 
04374     // Step 1: Initialize the device dependent margins for eeprom access.
04375     if (bGL == TRUE)
04376     {
04377         listoffset = 0;
04378         listsize = SRCP_GLEEPROMSET_COUNT;
04379     }
04380     else
04381     {
04382         listoffset = SRCP_GLEEPROMSET_COUNT;
04383         listsize = SRCP_GAEEPROMSET_COUNT;
04384     }
04385 
04386 
04387     // Step 2: Allocate the EEPROM set list.
04388     _pActiveEEPROMSetList = SRAMalloc(listsize);
04389 
04390     if (_pActiveEEPROMSetList == NULL)
04391     {
04392         PrintCommonError(COMMON_ERROR_OUT_OF_MEMORY);
04393         return 0;
04394     }
04395 
04396 
04397     // Step 3: Iterate through the eeprom set and find active sets.
04398     address = SRCP_SETS_EEPROM_ADD + (listoffset * sizeof(SPSET));
04399     for (i = listoffset, entries = 0; i < (listsize + listoffset); i++)
04400     {
04401         SPSET set;
04402         XEEReadArray(address, (BYTE *)&set, sizeof(SPSET));
04403         if (set.sFlags.bActive == TRUE)
04404         {
04405             _pActiveEEPROMSetList[entries++] = i;
04406         }
04407         address += sizeof(SPSET);
04408     }
04409 
04410 
04411     // Step 4: Evaluate the amount of sets.
04412     if (entries == 0)
04413     {
04414         lcd_addr1 = 0;
04415         lcd_addr2 = 0;
04416         StrTbl_GetString(lcdram_row1, STRTBLID_DATABASE);
04417         StrTbl_GetString(lcdram_row2, STRTBLID_IS_EMPTY);
04418         lcd_status = LCD_CLR_MASK | LCD_ROW1_MASK | LCD_CENTER1_MASK |
04419                         LCD_ROW2_MASK | LCD_CENTER2_MASK;
04420         return 0;
04421     }
04422 
04423     return entries;
04424 }
04425 
04426 // ////////////////////////////////////////////////////////////////////////////
04427 // ////////////////////////////////////////////////////////////////////////////
04428 
04429 static void _destructEEPROMSet(void)
04430 {
04431     if (_pActiveEEPROMSetList)
04432     {
04433         SRAMfree(_pActiveEEPROMSetList);
04434         _pActiveEEPROMSetList = NULL;
04435     }
04436 }
04437 
04438 // ////////////////////////////////////////////////////////////////////////////
04439 // ////////////////////////////////////////////////////////////////////////////

Generated on Sun Nov 27 20:02:39 2011 for eWicht by  doxygen 1.5.5