/** 文字列入力 * @param[in] cnsl コンソールオブジェクト * @param[out] msg 表示メッセージ * @param[in,out] txt 入力文字列 * @param[in] len txt の大きさ * @return 最後に入力された文字(ターミネータ。マイナス値はエラー。) ************************************************************************* */ int CONSOLE_InputText( CONSOLE *cnsl, const char *msg, char *txt, int len ) { if( !CONSOLE_PutString( cnsl, msg ) ) return CONSOLE_ERROR; if( !CONSOLE_PutString( cnsl, " : " ) ) return CONSOLE_ERROR; return CONSOLE_GetString( cnsl, txt, len, "\r\x1B" ); }
void ProcessRxMessage() { BYTE index; if(rxMessage.flags.bits.broadcast) { CONSOLE_PutString((char *) "\n -------- From group:"); } else { CONSOLE_PutString((char *) "\n -------- From ["); } if(rxMessage.flags.bits.srcPrsnt) { if(rxMessage.flags.bits.altSrcAddr) { CONSOLE_PrintHex(rxMessage.SourceAddress[1]); CONSOLE_PrintHex(rxMessage.SourceAddress[0]); } else { for(index = 0; index < MY_ADDRESS_LENGTH; index++) { CONSOLE_PrintHex(rxMessage.SourceAddress[MY_ADDRESS_LENGTH - 1 - index]); } } CONSOLE_PutString((char *) "] : "); } for(index = 1; index < rxMessage.PayloadSize; index++) { CONSOLE_Put(rxMessage.Payload[index]); } CONSOLE_PutString((char *) "\r\n$$"); // Toggle LED2 to indicate receiving a packet. LED_2 ^= 1; /*******************************************************************/ // Function MiApp_DiscardMessage is used to release the current // received packet. // After calling this function, the stack can start to process the // next received frame /*******************************************************************/ MiApp_DiscardMessage(); }
void TransmitMessage() { uint8_t index; //Send message /******************************************************************/ // First call function MiApp_FlushTx to reset the Transmit buffer. // Then fill the buffer one byte by one byte by calling function // MiApp_WriteData /*******************************************************************/ MiApp_FlushTx(); MiApp_WriteData(TxMessageSize); for(index = 0; index < TxMessageSize; index++) { MiApp_WriteData(TxMessage[index]); } //Unicast Message /*******************************************************************/ // Function MiApp_UnicastConnection is one of the functions to // unicast a message. // The first parameter is the index of connection table for // the peer device. In this lab, the chat is always sent to the // first P2P Connection Entry of the connection table. If that // node is down (eg. student is programming new firmare into it), // the user is prompted to reset the node to re-establish the // connection table with a new peer. // // The second parameter is the boolean to indicate if we need // to secure the frame. If encryption is applied, the // security level and security key are defined in the // configuration file for the transceiver // // Another way to unicast a message is by calling function // MiApp_UnicastAddress. Instead of supplying the index of the // connection table of the peer device, this function requires the // input parameter of destination address directly. /*******************************************************************/ if(MiApp_UnicastConnection(0, true) == false) { //Message TX Failed (peer node 00 was likely being re-programmed by student) //Should reset the node to establish new peer connection to send chat to CONSOLE_PutString((char *) "Transmit to Peer 00 Failed. Press MCLR to establish new connections"); } //Reset Chat Application state variables messagePending = false; transmitPending = false; TxMessageSize = 0; }
void FormatTxMessage() { BYTE inputChar; inputChar = CONSOLE_Get(); CONSOLE_Put(inputChar); if(inputChar == 0x0D) { CONSOLE_PutString((char *) "\r\n$$"); messagePending = true; transmitPending = true; } else if(inputChar == 0x08) { TxMessageSize--; } else { if(TxMessageSize < MAX_MESSAGE_LEN) { TxMessage[TxMessageSize] = inputChar; TxMessageSize++; tickPrevious = MiWi_TickGet(); messagePending = true; } } }
/** コマンド解析 * @param cnsl コンソールオブジェクト * @param cmnd コマンド文字列 * @param res 応答文字列 * @return TRUE:正常、FALSE:切断 ********************************************************************* */ COMMAND_STATUS shell_ParseCommand( CONSOLE *cnsl, char *cmnd, char *res ) { COMMAND_STATUS stat = COMMAND_STATUS_PARSE_ERROR; int ch = -1; int dn; int len; char buff[ SHELL_COMMAND_MAX ]; static char sndbf[ SHELL_RESPONSE_MAX ]; BOOL resEna = TRUE; // ヘッダ番号指定チェック if( isdigit( (int)cmnd[ 0 ] ) ) { // 先頭が数字だったら→3桁のヘッダ番号 strncpy( buff, cmnd, HEAD_NAME_LEN - 1 ); buff[ HEAD_NAME_LEN - 1 ] = 0; ch = PARA_SearchHeader( buff ); // ヘッダからチャネル番号に変換 if( ch < 0 ) { // 自モジュールにヘッダが見つからない。 stat = COMMAND_STATUS_ANOTHER_MODULE; goto EXIT; } cmnd += HEAD_NAME_LEN - 1; } // コマンド解析 LIB_StrToUpperCase( buff, cmnd ); for( dn = 0; mShellCommandTbl[ dn ].Command != NULL; dn++ ) { len = strlen( mShellCommandTbl[ dn ].Command ); if( strncmp( mShellCommandTbl[ dn ].Command, buff, len ) == 0 ) break; // コマンドが見つかった } // コマンド実行 if( mShellCommandTbl[ dn ].Command != NULL ) { // コマンド見つかった res[ 0 ] = 0; stat = mShellCommandTbl[ dn ].Func( cnsl, cmnd + len, res, ch ); // コマンド実行 switch( stat ) { case COMMAND_STATUS_PARSE_ERROR: // コマンド解析エラー strcpy( res, RESPONSE_PARAMETER_ERROR ); break; case COMMAND_STATUS_HEADER_NOT_FOUND: // ヘッダが見つからない strcpy( res, RESPONSE_HEADER_NOT_FOUND ); break; case COMMAND_STATUS_OK: // コマンド実行OK break; case COMMAND_STATUS_ANOTHER_MODULE: // 自分宛てのコマンドでないので応答しない。 case COMMAND_STATUS_DISCONNECT: // 切断された。 case COMMAND_STATUS_TIMEOUT: // 応答タイムアウト。 default: resEna = FALSE; break; } } else { // コマンドエラー if( PARA_IsHost() ) { stat = COMMAND_STATUS_PARSE_ERROR; strcpy( res, RESPONSE_PARAMETER_ERROR ); } else { stat = COMMAND_STATUS_NO_RESPONSE; resEna = FALSE; } } // 応答メッセージ送信 if( resEna ) { sndbf[ 0 ] = 0; shell_MakeResponseHeader( cnsl, sndbf ); // ヘッダ付加 strcat( sndbf, res ); // 応答文字列 if( !CONSOLE_PutString( cnsl, sndbf ) ) stat = COMMAND_STATUS_DISCONNECT; } EXIT: ; return stat; }
/** シェル・メイン * @param cnsl コンソールオブジェクト ********************************************************************* */ void SHELL_Main( CONSOLE *cnsl ) { static char cmnd[ SHELL_COMMAND_MAX ]; static char res[ SHELL_RESPONSE_MAX ]; char *buffp; int keydt; COMMAND_STATUS stat = COMMAND_STATUS_OK; int resmdl; if( PARA_IsHost() ) { // ホストの場合は タイトルと最初のプロンプトを表示 CONSOLE_PutString( cnsl, "===== STD-0001 ===== " __DATE__ " " __TIME__ "¥r¥n" ); stat = COMMAND_STATUS_OK; } else { // スレーブの場合はタイトルと最初のプロンプトは表示しない。 stat = COMMAND_STATUS_NO_RESPONSE; } // CONSOLE_Flash( &cnsl ); for( ;; ) { if( ( stat != COMMAND_STATUS_ANOTHER_MODULE )&& ( stat != COMMAND_STATUS_NO_RESPONSE ) ) { //WDT_LongTimeClear(); // ウォッチドッグ長時間クリア CONSOLE_PutString( cnsl, COMMAND_TEXT_PROMPT ); // プロンプト表示 } cmnd[ 0 ] = 0; keydt = CONSOLE_GetString( cnsl, cmnd, sizeof( cmnd ) - 1, "¥r¥x1B!" COMMAND_TEXT_PROMPT ); // 1行取得 if( keydt < 0 ) break; /* 切断 */ if( keydt != KEY_CR ) continue; if( strlen( cmnd ) == 0 ) continue; buffp = cmnd; if( !PARA_IsHost() ) { // 内部 RS485 のとき内部コマンドSTXとコマンドマークまで削除する。 stat = COMMAND_STATUS_NO_RESPONSE; buffp = H2S_SearchCommand( buffp ); if( buffp == NULL ) continue; // コマンドが見つからなかった。 } stat = shell_ParseCommand( cnsl, buffp, res ); // コマンドの解析と実行 if( stat == COMMAND_STATUS_ANOTHER_MODULE ) { // 他のモジュール宛てだった。 if( PARA_IsHost() ) { // ホストモジュールだったら他のモジュールへ転送 strcpy( res, RESPONSE_PARAMETER_ERROR ); if( !CONSOLE_PutString( cnsl, res ) ) stat = COMMAND_STATUS_DISCONNECT; } } if( stat == COMMAND_STATUS_DISCONNECT ) break; // 切断された } EXIT: ; }
/** 文字列入力 * @param[in] cnsl コンソールオブジェクト * @param[out] data 入力された文字列 * @param len data バッファのサイズ * @param term ターミネータ * @return 最後に入力された文字(マイナス値はエラー) ************************************************************************* */ int CONSOLE_GetString( CONSOLE *cnsl, char *data, UW len, const char *term ) { int rdt = CONSOLE_ERROR; int rlen = 0; len -= 1; #if 0 if( cnsl->EchoBack ) { if( !CONSOLE_PutString( cnsl, data ) ) { rdt = CONSOLE_ERROR; goto EXIT; } } rlen = strlen( data ); if( rlen >= len ) { // 受信データ数を修正 data[ len ] = 0; rlen = len - 1; } #else data[ 0 ] = 0; #endif for( ;; ) { rdt = CONSOLE_GetChar( cnsl ); if( rdt < 0 ) break; if( strchr( term, rdt ) != NULL ) { // ターミネータ if( cnsl->EchoBack ) { if( !CONSOLE_PutString( cnsl, "\r\n" ) ) // CRLFエコーバック rdt = CONSOLE_ERROR; } goto EXIT; } switch( rdt ) { case '\n': // LFだったら無視 break; case '\b': // バックスペースだった if( rlen > 0 ) { if( cnsl->EchoBack ) { if( !CONSOLE_PutString( cnsl, "\b \b" ) ) // エコーバック { rdt = CONSOLE_ERROR; goto EXIT; } } rlen--; // コンパイラにバグ有り:これを2行前に持っていくとでうまく動作しない。 } break; default: // その他(通常文字) if( rlen < len - 1 ) { data[ rlen++ ] = (char)rdt; if( cnsl->EchoBack ) { if( !CONSOLE_PutChar( cnsl, rdt ) ) { rdt = CONSOLE_ERROR; goto EXIT; } } } break; } } EXIT:; data[ rlen ] = 0; // ターミネータ return rdt; }