/** * Main entry point for Program Utility. * * Process option flags and execute commands. * * @param argc * @param argv * @return */ int main( int argc, char *argv[] ) { int iExitCode = EXIT_SUCCESS; UCHAR ucMBAddr = 1; ULONG ulOptFlags = 0; UCHAR ucBank = 0; UCHAR ucStartThread = FALSE; CHAR *pucVersion; UCHAR ucStatus; int c; int timeout; char *infile = NULL; char *outfile = NULL; char *endptr; opterr = 0; ucPort = 2; /* Default to first USB serial dongle */ printf("Secure Bootloader Program Utility\n\n"); /* * Process command line options */ while ((c = getopt(argc, argv, "a:b:ce:fklp:s:uvDV")) != -1) { switch (c) { case 'a': ulOptFlags |= FLAG_ADD_HEADER; pucVersion = optarg; break; case 'b': ucBank = strtoul(optarg, NULL, 0); break; case 'c': ulOptFlags |= FLAG_CHECK_HEADER; break; case 'e': ulOptFlags |= FLAG_ENCRYPT; pBlowfishKeyString = optarg; break; case 'f': ulOptFlags |= FLAG_LOCK_FILE; ucBank = BANK_F; ucStartThread = TRUE; break; case 'k': ulOptFlags |= FLAG_CREATE_KEYFILE; break; case 'l': ulOptFlags |= FLAG_LOCK_FILE; ucBank = BANK_BOOT; ucStartThread = TRUE; break; case 'p': ucPort = strtoul(optarg, &endptr, 0); /* If argument is not a pure number, it must be a string */ if (endptr) { ucPort = 255; devString = optarg; } break; case 's': ulOptFlags |= FLAG_SIGN; pRSAKeyFile = optarg; break; case 'u': ulOptFlags |= FLAG_UPLOAD; ucStartThread = TRUE; break; case 'v': ulOptFlags |= FLAG_GET_VERSION; ucStartThread = TRUE; break; case 'D': debugflags = 1; break; case 'V': ulOptFlags |= FLAG_VALIDATE; ucStartThread = TRUE; break; case '?': if (optopt == 'v') fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (isprint(optopt)) fprintf(stderr, "Unknown option `-%c'.\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: abort(); break; } } if (optind < argc) { infile = argv[optind++]; } if (optind < argc) { outfile = argv[optind++]; } if (argc < 2) { print_usage(); } if ((ulOptFlags & FLAG_ADD_HEADER) && (ulOptFlags & FLAG_CREATE_KEYFILE)) { printf("Error: cannot specify both -a and -k options\n"); abort(); } if ((ulOptFlags & FLAG_CREATE_KEYFILE) && (infile == 0)) { /* Request to upload keyfile */ ucStartThread = TRUE; } /* * Enable signal handlers */ if( !bSetSignal( SIGQUIT, vSigShutdown ) || !bSetSignal( SIGINT, vSigShutdown ) || !bSetSignal( SIGTERM, vSigShutdown ) ) { fprintf( stderr, "%s: can't install signal handlers: %s!\n", PROG, strerror( errno ) ); iExitCode = EXIT_FAILURE; } else if (ucStartThread) { DEBUG_PUTSTRING("Starting MobBus thread"); if( eMBInit( MB_RTU, 0x0A, ucPort, 115200, MB_PAR_EVEN ) != MB_ENOERR ) { fprintf( stderr, "%s: can't initialize modbus stack!\n", PROG ); iExitCode = EXIT_FAILURE; } else { /* Register Callbacks */ (void)eMBRegisterCB(MB_FUNC_BOOT_GETHEADER, cmd_getheader_callback); (void)eMBRegisterCB(MB_FUNC_BOOT_PREPAREFLASH, cmd_prepareflash_callback); (void)eMBRegisterCB(MB_FUNC_BOOT_UPLOADBLOCK, cmd_uploadblock_callback); (void)eMBRegisterCB(MB_FUNC_BOOT_VALIDATEIMAGE, cmd_validatesig_callback); (void)eMBRegisterCB(MB_FUNC_BOOT_SETKEYS, cmd_setkeys_callback); (void)eMBRegisterCB(MB_FUNC_BOOT_LOCK, cmd_lockfile_callback); (void)eMBRegisterIllegalFuncCB(cmd_illegalfunc_callback); (void)eMBRegisterTimeoutCB( cmd_timeout_callback ); /* Start polling thread */ vSetPollingThreadState(STOPPED); if (bCreatePollingThread() != TRUE) { printf("Can't start protocol stack! Already running?\n"); } //vMBPortTimersEnable( ); } } if (iExitCode == EXIT_SUCCESS) { vSetPollingThreadState(RUNNING); /* Process commands and options */ if (ulOptFlags & FLAG_GET_VERSION) { timeout = 10; ucStatus = cmd_getheader(ucMBAddr, ucBank); while ((ucStatus == BOOT_TIMEOUT) && (--timeout)) { ucStatus = cmd_getheader(ucMBAddr, ucBank); } if ((ucStatus != BOOT_OK) && (ucStatus != BOOT_BANKEMPTY)) { fprintf(stderr, "Get Version Failed: %s", cmd_errorString(ucStatus)); } } else if (ulOptFlags & FLAG_UPLOAD) { if (infile) { util_upload(ucMBAddr, infile, ucBank); } else { fprintf(stderr, "Upload: missing filename\n"); } } else if (ulOptFlags & FLAG_ADD_HEADER) { if (infile && outfile) { util_addheader(infile, outfile, pucVersion, pRSAKeyFile, pBlowfishKeyString); } else { fprintf(stderr, "Add Header: missing filenames\n"); } } else if (ulOptFlags & FLAG_CREATE_KEYFILE) { util_createkeyfile(ucMBAddr, infile, pRSAKeyFile, pBlowfishKeyString); } else if (ulOptFlags & FLAG_LOCK_FILE) { timeout = 10; ucStatus = cmd_lockfile(ucMBAddr, ucBank); while ((ucStatus == BOOT_TIMEOUT) && (--timeout)) { ucStatus = cmd_lockfile(ucMBAddr, ucBank); } if (ucStatus != BOOT_OK) { fprintf(stderr, "Lock Failed: %s", cmd_errorString(ucStatus)); } else { printf("Lock Successful\n"); } } if (ulOptFlags & FLAG_CHECK_HEADER) { if (infile) { util_checkheader(infile); } else { fprintf(stderr, "Check Header: missing filename\n"); } } if (ulOptFlags & FLAG_VALIDATE) { cmd_validatesig(ucMBAddr); } /* Release hardware resources. */ if (ucStartThread) { ( void )eMBClose( ); } iExitCode = EXIT_SUCCESS; } return iExitCode; }
/* ----------------------- Start implementation -----------------------------*/ int _tmain( int argc, _TCHAR * argv[] ) { int iExitCode; TCHAR cCh; BOOL bDoExit; for (int Num = REG_INPUT_NREGS; Num >= 0; Num--) { usRegInputBuf[Num] = Num; } for (int Num = INPUT_STATUS_NREGS; Num >= 0; Num--) { ucInputStatusBuf[Num] = 1; } ucInputStatusBuf[0] = 255; for (int Num = 0; Num < REG_HOLDING_NREGS; Num++) { usRegHoldingBuf[Num] = Num; } for (int Num = 0; Num < INPUT_COIL_NREGS; Num++) { ucInputCoilBuf[Num] = 0; } ucInputCoilBuf[0] = 255; if( eMBTCPInit( MB_TCP_PORT_USE_DEFAULT ) != MB_ENOERR ) { _ftprintf( stderr, _T( "%s: can't initialize modbus stack!\r\n" ), PROG ); iExitCode = EXIT_FAILURE; } else { /* Create synchronization primitives and set the current state * of the thread to STOPPED. */ InitializeCriticalSection( &hPollLock ); eSetPollingThreadState( STOPPED ); /* CLI interface. */ _tprintf( _T( "Type 'q' for quit or 'h' for help!\r\n" ) ); bDoExit = FALSE; do { _tprintf( _T( "> " ) ); cCh = _gettchar( ); switch ( cCh ) { case _TCHAR( 'q' ): bDoExit = TRUE; break; case _TCHAR( 'd' ): eSetPollingThreadState( SHUTDOWN ); break; case _TCHAR( 'e' ): if( bCreatePollingThread( ) != TRUE ) { _tprintf( _T( "Can't start protocol stack! Already running?\r\n" ) ); } break; case _TCHAR( 's' ): switch ( eGetPollingThreadState( ) ) { case RUNNING: _tprintf( _T( "Protocol stack is running.\r\n" ) ); break; case STOPPED: _tprintf( _T( "Protocol stack is stopped.\r\n" ) ); break; case SHUTDOWN: _tprintf( _T( "Protocol stack is shuting down.\r\n" ) ); break; } break; case _TCHAR( 'h' ): _tprintf( _T( "FreeModbus demo application help:\r\n" ) ); _tprintf( _T( " 'd' ... disable protocol stack.\r\n" ) ); _tprintf( _T( " 'e' ... enabled the protocol stack\r\n" ) ); _tprintf( _T( " 's' ... show current status\r\n" ) ); _tprintf( _T( " 'q' ... quit applicationr\r\n" ) ); _tprintf( _T( " 'h' ... this information\r\n" ) ); _tprintf( _T( "\r\n" ) ); _tprintf( _T( "Copyright 2006 Christian Walter <*****@*****.**>\r\n" ) ); break; default: if( cCh != _TCHAR('\n') ) { _tprintf( _T( "illegal command '%c'!\r\n" ), cCh ); } break; } /* eat up everything untill return character. */ while( cCh != '\n' ) { cCh = _gettchar( ); } } while( !bDoExit ); /* Release hardware resources. */ ( void )eMBClose( ); iExitCode = EXIT_SUCCESS; } return iExitCode; }