880 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") )); |
884 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") )); |
881 iParseInfo.iLimit = KErrNotFound; |
885 iParseInfo.iLimit = KErrNotFound; |
882 TDunDecodeInfo oldInfo = iDecodeInfo; |
886 TDunDecodeInfo oldInfo = iDecodeInfo; |
883 iDecodeInfo.iDecodeBuffer.Zero(); |
887 iDecodeInfo.iDecodeBuffer.Zero(); |
884 // Find start of decode command from input buffer |
888 // Find start of decode command from input buffer |
885 TBool extendedCmd = EFalse; |
|
886 TInt startIndex = iDecodeInfo.iDecodeIndex; |
889 TInt startIndex = iDecodeInfo.iDecodeIndex; |
887 startIndex = FindStartOfDecodedCommand( iInputBuffer, |
890 startIndex = FindStartOfDecodedCommand( iInputBuffer, startIndex ); |
888 startIndex, |
|
889 extendedCmd ); |
|
890 if ( startIndex < 0 ) |
891 if ( startIndex < 0 ) |
891 { |
892 { |
892 RestoreOldDecodeInfo( aPeek, oldInfo ); |
893 RestoreOldDecodeInfo( aPeek, oldInfo ); |
893 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") )); |
894 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") )); |
894 return EFalse; |
895 return EFalse; |
895 } |
896 } |
896 // Find end of decode command from input buffer |
897 // Find end of decode command from input buffer |
897 TBool extendedEnd = EFalse; |
|
898 TBool oneCharCmd = EFalse; |
|
899 TBool specialCmd = EFalse; |
898 TBool specialCmd = EFalse; |
900 TInt endIndex = KErrNotFound; |
899 TInt endIndex = KErrNotFound; |
901 if ( extendedCmd ) |
900 specialCmd = CheckSpecialCommand( startIndex, endIndex ); |
902 { |
901 if ( !specialCmd ) |
903 if( iAtSpecialCmdHandler->IsCompleteSubCommand(iInputBuffer, startIndex, endIndex) == EFalse ) |
902 { |
904 { |
903 FindSubCommand( startIndex, endIndex ); |
905 extendedEnd = CheckExtendedCommand( startIndex, endIndex ); |
|
906 } |
|
907 } |
|
908 else |
|
909 { |
|
910 specialCmd = CheckSpecialCommand( startIndex, endIndex ); |
|
911 if ( !specialCmd ) |
|
912 { |
|
913 CheckBasicCommand( startIndex, endIndex, oneCharCmd ); |
|
914 } |
|
915 } |
904 } |
916 if ( endIndex < startIndex ) |
905 if ( endIndex < startIndex ) |
917 { |
906 { |
918 RestoreOldDecodeInfo( aPeek, oldInfo ); |
907 RestoreOldDecodeInfo( aPeek, oldInfo ); |
919 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") )); |
908 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") )); |
1173 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") )); |
1085 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") )); |
1174 return EFalse; |
1086 return EFalse; |
1175 } |
1087 } |
1176 |
1088 |
1177 // --------------------------------------------------------------------------- |
1089 // --------------------------------------------------------------------------- |
1178 // Checks extended command |
1090 // Saves character decode state for a found character |
1179 // --------------------------------------------------------------------------- |
1091 // --------------------------------------------------------------------------- |
1180 // |
1092 // |
1181 TInt CDunAtCmdHandler::CheckBasicCommand( TInt aStartIndex, |
1093 void CDunAtCmdHandler::SaveFoundCharDecodeState( TChar aCharacter, |
1182 TInt& aEndIndex, |
1094 TBool aAddSpecial ) |
1183 TBool& aOneCharCmd ) |
1095 { |
1184 { |
1096 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState()") )); |
1185 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand()") )); |
1097 iDecodeInfo.iPrevExists = ETrue; |
|
1098 iDecodeInfo.iPrevChar = aCharacter; |
|
1099 if ( aAddSpecial ) |
|
1100 { |
|
1101 iDecodeInfo.iSpecialFound = |
|
1102 iAtSpecialCmdHandler->IsCompleteSubCommand( aCharacter ); |
|
1103 } |
|
1104 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState() complete") )); |
|
1105 } |
|
1106 |
|
1107 // --------------------------------------------------------------------------- |
|
1108 // Saves character decode state for a not found character |
|
1109 // --------------------------------------------------------------------------- |
|
1110 // |
|
1111 void CDunAtCmdHandler::SaveNotFoundCharDecodeState() |
|
1112 { |
|
1113 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState()") )); |
|
1114 iDecodeInfo.iPrevExists = EFalse; |
|
1115 // Note: don't set iAssignFound or iInQuotes here |
|
1116 iDecodeInfo.iSpecialFound = EFalse; |
|
1117 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState() complete") )); |
|
1118 } |
|
1119 |
|
1120 // --------------------------------------------------------------------------- |
|
1121 // Find quotes within subcommands |
|
1122 // --------------------------------------------------------------------------- |
|
1123 // |
|
1124 TBool CDunAtCmdHandler::FindSubCommandQuotes( TChar aCharacter, |
|
1125 TInt aStartIndex, |
|
1126 TInt& aEndIndex ) |
|
1127 { |
|
1128 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes()") )); |
|
1129 if ( aCharacter == '"' ) |
|
1130 { |
|
1131 if ( iParseInfo.iLimit < 0 ) // Only first the first '"' |
|
1132 { |
|
1133 iParseInfo.iLimit = aEndIndex - aStartIndex; |
|
1134 } |
|
1135 iDecodeInfo.iInQuotes ^= ETrue; // EFalse to ETrue or ETrue to EFalse |
|
1136 SaveFoundCharDecodeState( aCharacter, EFalse ); |
|
1137 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (quote) complete") )); |
|
1138 return ETrue; |
|
1139 } |
|
1140 // The next ones are those that are not in quotes. |
|
1141 // We still need to save the iParseInfo.iLimit and skip non-delimiter characters. |
|
1142 if ( aCharacter == '=' ) |
|
1143 { |
|
1144 if ( iParseInfo.iLimit < 0 ) // Only first the first '"' |
|
1145 { |
|
1146 iParseInfo.iLimit = aEndIndex - aStartIndex; |
|
1147 } |
|
1148 iDecodeInfo.iAssignFound = ETrue; |
|
1149 SaveFoundCharDecodeState( aCharacter, EFalse ); |
|
1150 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (equals) complete") )); |
|
1151 return ETrue; |
|
1152 } |
|
1153 if ( iDecodeInfo.iInQuotes ) |
|
1154 { |
|
1155 SaveNotFoundCharDecodeState(); |
|
1156 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (in quotes) complete") )); |
|
1157 return ETrue; |
|
1158 } |
|
1159 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (not found) complete") )); |
|
1160 return EFalse; |
|
1161 } |
|
1162 |
|
1163 // --------------------------------------------------------------------------- |
|
1164 // Check if in next subcommand's extended border |
|
1165 // --------------------------------------------------------------------------- |
|
1166 // |
|
1167 TBool CDunAtCmdHandler::IsExtendedBorder( TChar aCharacter, |
|
1168 TInt aStartIndex, |
|
1169 TInt& aEndIndex ) |
|
1170 { |
|
1171 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder()") )); |
|
1172 TInt expectedIndex = 0; // "+CMD" when iDecodeInfo.iFirstDecode is EFalse |
|
1173 TInt extendedIndex = aEndIndex - aStartIndex; // absolute index to the extended character |
|
1174 if ( iDecodeInfo.iFirstDecode ) |
|
1175 { |
|
1176 expectedIndex = 2; // "AT+CMD" |
|
1177 } |
|
1178 if ( extendedIndex == expectedIndex ) |
|
1179 { |
|
1180 iDecodeInfo.iExtendedIndex = aEndIndex; |
|
1181 SaveFoundCharDecodeState( aCharacter ); |
|
1182 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border) complete") )); |
|
1183 return EFalse; |
|
1184 } |
|
1185 aEndIndex--; |
|
1186 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (border) complete") )); |
|
1187 return ETrue; |
|
1188 } |
|
1189 |
|
1190 // --------------------------------------------------------------------------- |
|
1191 // Finds subcommand with alphanumeric borders |
|
1192 // --------------------------------------------------------------------------- |
|
1193 // |
|
1194 TBool CDunAtCmdHandler::FindSubCommandAlphaBorder( TChar aCharacter, |
|
1195 TInt& aEndIndex ) |
|
1196 { |
|
1197 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder()") )); |
|
1198 if ( iDecodeInfo.iAssignFound && !iDecodeInfo.iInQuotes ) |
|
1199 { |
|
1200 // Check the special case when assigning a number with "basic" command |
|
1201 // and there is no delimiter after it. In this case <Numeric>|<Alpha> |
|
1202 // border must be detected but only for a "basic" command, not for |
|
1203 // extended. |
|
1204 if ( iDecodeInfo.iExtendedIndex<0 && iDecodeInfo.iPrevExists && |
|
1205 iDecodeInfo.iPrevChar.IsDigit() && aCharacter.IsAlpha() ) |
|
1206 { |
|
1207 aEndIndex--; |
|
1208 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (N|A) complete") )); |
|
1209 return ETrue; |
|
1210 } |
|
1211 // The code below is for the following type of cases: |
|
1212 // (do not check alphanumeric borders if "=" set without quotes): |
|
1213 // AT+CMD=a |
|
1214 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (skip) complete") )); |
|
1215 return EFalse; |
|
1216 } |
|
1217 if ( !iDecodeInfo.iPrevExists || !aCharacter.IsAlpha() ) |
|
1218 { |
|
1219 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (not found) complete") )); |
|
1220 return EFalse; |
|
1221 } |
|
1222 if ( iDecodeInfo.iPrevChar.IsAlpha() ) |
|
1223 { |
|
1224 // The check below detects the following type of cases |
|
1225 // (note that special handling is needed to separate the Alpha|Alpha boundary): |
|
1226 // AT&FE0 |
|
1227 if ( iDecodeInfo.iSpecialFound ) |
|
1228 { |
|
1229 // Special command was found before and this is Alpha|Alpha boundary -> end |
|
1230 aEndIndex--; |
|
1231 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (special) complete") )); |
|
1232 return ETrue; |
|
1233 } |
|
1234 // The code below is for the following type of cases |
|
1235 // (note there is no border between C|M, for example -> continue): |
|
1236 // ATCMD |
|
1237 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (continue) complete") )); |
|
1238 return EFalse; |
|
1239 } |
|
1240 // The code below is for skipping the following type of cases: |
|
1241 // AT+CMD [the '+' must be skipped] |
|
1242 if ( aEndIndex-1 == iDecodeInfo.iExtendedIndex ) |
|
1243 { |
|
1244 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (extended) complete") )); |
|
1245 return EFalse; |
|
1246 } |
|
1247 // The code below is for the following type of cases: |
|
1248 // ATCMD?ATCMD |
|
1249 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (boundary) complete") )); |
|
1250 aEndIndex--; |
|
1251 return ETrue; |
|
1252 } |
|
1253 |
|
1254 // --------------------------------------------------------------------------- |
|
1255 // Finds subcommand |
|
1256 // --------------------------------------------------------------------------- |
|
1257 // |
|
1258 TInt CDunAtCmdHandler::FindSubCommand( TInt aStartIndex, TInt& aEndIndex ) |
|
1259 { |
|
1260 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") )); |
1186 aEndIndex = aStartIndex; |
1261 aEndIndex = aStartIndex; |
1187 aOneCharCmd = EFalse; |
1262 TBool found = EFalse; |
1188 TBool inQuotes = EFalse; |
|
1189 TInt length = iInputBuffer.Length(); |
1263 TInt length = iInputBuffer.Length(); |
1190 iDecodeInfo.iPrevExists = EFalse; |
1264 iDecodeInfo.iAssignFound = EFalse; |
1191 if ( aStartIndex < length ) |
1265 iDecodeInfo.iInQuotes = EFalse; |
1192 { |
1266 iDecodeInfo.iExtendedIndex = KErrNotFound; |
1193 TChar character = iInputBuffer[aStartIndex]; |
1267 SaveNotFoundCharDecodeState(); |
1194 if ( IsOneCharacterCommand(aStartIndex) ) |
1268 iAtSpecialCmdHandler->ResetComparisonBuffer(); // just to be sure |
1195 { |
1269 for ( ; aEndIndex<length; aEndIndex++ ) |
1196 aOneCharCmd = ETrue; |
1270 { |
1197 // Without "endIndex++" here |
1271 TChar character = iInputBuffer[aEndIndex]; |
1198 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (X) complete") )); |
1272 found = FindSubCommandQuotes( character, aStartIndex, aEndIndex ); |
|
1273 if ( found ) |
|
1274 { |
|
1275 continue; |
|
1276 } |
|
1277 if ( character == '?' ) |
|
1278 { |
|
1279 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (?) complete") )); |
1199 return KErrNone; |
1280 return KErrNone; |
1200 } |
1281 } |
1201 } |
1282 // The check below detects the following type of cases: |
1202 for ( ; aEndIndex<length; aEndIndex++ ) |
1283 // ATCMD<delimiter> |
1203 { |
1284 if ( IsDelimiterCharacter(character) ) |
1204 TChar character = iInputBuffer[aEndIndex]; |
1285 { |
1205 if ( character == '"' ) |
1286 aEndIndex--; |
1206 { |
1287 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (delimiter) complete") )); |
1207 if ( iDecodeInfo.iPrevExists && iParseInfo.iLimit<0 ) |
1288 return KErrNone; |
|
1289 } |
|
1290 // The check below detects the following type of cases: |
|
1291 // ATCMD+CMD [first + as delimiter] |
|
1292 // AT+CMD+CMD [second + as delimiter] |
|
1293 if ( IsExtendedCharacter(character) ) |
|
1294 { |
|
1295 found = IsExtendedBorder( character, aStartIndex, aEndIndex ); |
|
1296 if ( !found ) |
1208 { |
1297 { |
1209 iParseInfo.iLimit = aEndIndex - aStartIndex; |
1298 continue; |
1210 } |
1299 } |
1211 inQuotes ^= ETrue; // EFalse to ETrue or ETrue to EFalse |
1300 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (extended) complete") )); |
1212 iDecodeInfo.iPrevExists = ETrue; |
|
1213 iDecodeInfo.iPrevChar = character; |
|
1214 continue; |
|
1215 } |
|
1216 if ( inQuotes ) |
|
1217 { |
|
1218 continue; |
|
1219 } |
|
1220 if ( character == '?' ) |
|
1221 { |
|
1222 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (?) complete") )); |
|
1223 return KErrNone; |
1301 return KErrNone; |
1224 } |
1302 } |
1225 if ( character.IsSpace() || IsExtendedCharacter(character) ) |
1303 found = FindSubCommandAlphaBorder( character, aEndIndex ); |
1226 { |
1304 if ( found ) |
1227 aEndIndex--; |
1305 { |
1228 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (S or extended) complete") )); |
1306 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (alpha sub) complete") )); |
1229 return KErrNone; |
1307 return KErrNone; |
1230 } |
1308 } |
1231 if ( !iDecodeInfo.iPrevExists ) |
1309 SaveFoundCharDecodeState( character ); |
1232 { |
|
1233 iDecodeInfo.iPrevExists = ETrue; |
|
1234 iDecodeInfo.iPrevChar = character; |
|
1235 continue; |
|
1236 } |
|
1237 if ( IsOneCharacterCommand(aEndIndex) ) |
|
1238 { |
|
1239 aEndIndex--; |
|
1240 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (one char) complete") )); |
|
1241 return KErrNone; |
|
1242 } |
|
1243 if ( character.IsAlpha() && !iDecodeInfo.iPrevChar.IsAlpha() ) |
|
1244 { |
|
1245 aEndIndex--; |
|
1246 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (boundary) complete") )); |
|
1247 return KErrNone; |
|
1248 } |
|
1249 iDecodeInfo.iPrevExists = ETrue; |
|
1250 iDecodeInfo.iPrevChar = character; |
|
1251 } |
1310 } |
1252 aEndIndex--; |
1311 aEndIndex--; |
1253 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckBasicCommand() (not found) complete") )); |
1312 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (not found) complete") )); |
1254 return KErrNotFound; |
1313 return KErrNotFound; |
1255 } |
|
1256 |
|
1257 // --------------------------------------------------------------------------- |
|
1258 // Check if any one character command |
|
1259 // --------------------------------------------------------------------------- |
|
1260 // |
|
1261 TBool CDunAtCmdHandler::IsOneCharacterCommand( TInt aIndex ) |
|
1262 { |
|
1263 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand()") )); |
|
1264 if ( aIndex<0 || aIndex>=iInputBuffer.Length() ) |
|
1265 { |
|
1266 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() (index out of bounds) complete") )); |
|
1267 return EFalse; |
|
1268 } |
|
1269 TChar character = iInputBuffer[aIndex]; |
|
1270 if ( character==',' || character==';' || character=='@' || character=='!' || |
|
1271 IsOneCharacterACommand(aIndex) ) |
|
1272 { |
|
1273 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() complete") )); |
|
1274 return ETrue; |
|
1275 } |
|
1276 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterCommand() (not found) complete") )); |
|
1277 return EFalse; |
|
1278 } |
|
1279 |
|
1280 // --------------------------------------------------------------------------- |
|
1281 // Check if one character "A" command |
|
1282 // --------------------------------------------------------------------------- |
|
1283 // |
|
1284 TBool CDunAtCmdHandler::IsOneCharacterACommand( TInt aIndex ) |
|
1285 { |
|
1286 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand()") )); |
|
1287 if ( aIndex<0 || aIndex>=iInputBuffer.Length() ) |
|
1288 { |
|
1289 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (index out of bounds) complete") )); |
|
1290 return EFalse; |
|
1291 } |
|
1292 if ( iInputBuffer[aIndex]!='a' && iInputBuffer[aIndex]!='A' ) |
|
1293 { |
|
1294 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (not found) complete") )); |
|
1295 return EFalse; |
|
1296 } |
|
1297 TBool prevAlpha = EFalse; |
|
1298 TBool nextAlpha = EFalse; |
|
1299 TBool nextSlash = EFalse; |
|
1300 TInt length = iInputBuffer.Length(); |
|
1301 if ( iDecodeInfo.iPrevExists && iDecodeInfo.iPrevChar.IsAlpha() ) |
|
1302 { |
|
1303 prevAlpha = ETrue; |
|
1304 } |
|
1305 if ( aIndex+1 < length ) |
|
1306 { |
|
1307 TChar nextChar = iInputBuffer[aIndex+1]; |
|
1308 if ( nextChar.IsAlpha() ) |
|
1309 { |
|
1310 nextAlpha = ETrue; |
|
1311 } |
|
1312 if ( nextChar == '/' ) |
|
1313 { |
|
1314 nextSlash = ETrue; |
|
1315 } |
|
1316 } |
|
1317 if ( prevAlpha || nextAlpha || nextSlash ) |
|
1318 { |
|
1319 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (not found) complete") )); |
|
1320 return EFalse; |
|
1321 } |
|
1322 FTRACE(FPrint( _L("CDunAtCmdHandler::IsOneCharacterACommand() (complete) complete") )); |
|
1323 return ETrue; |
|
1324 } |
1314 } |
1325 |
1315 |
1326 // --------------------------------------------------------------------------- |
1316 // --------------------------------------------------------------------------- |
1327 // Check if "A/" command |
1317 // Check if "A/" command |
1328 // --------------------------------------------------------------------------- |
1318 // --------------------------------------------------------------------------- |