1 /* //device/system/reference-ril/at_tok.c 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "at_tok.h" 19 #include <string.h> 20 #include <ctype.h> 21 #include <stdlib.h> 22 23 /** 24 * Starts tokenizing an AT response string 25 * returns -1 if this is not a valid response string, 0 on success. 26 * updates *p_cur with current position 27 */ 28 int at_tok_start(char **p_cur) 29 { 30 if (*p_cur == NULL) { 31 return -1; 32 } 33 34 // skip prefix 35 // consume "^[^:]:" 36 37 *p_cur = strchr(*p_cur, ':'); 38 39 if (*p_cur == NULL) { 40 return -1; 41 } 42 43 (*p_cur)++; 44 45 return 0; 46 } 47 48 static void skipWhiteSpace(char **p_cur) 49 { 50 if (*p_cur == NULL) return; 51 52 while (**p_cur != '\0' && isspace(**p_cur)) { 53 (*p_cur)++; 54 } 55 } 56 57 static void skipNextComma(char **p_cur) 58 { 59 if (*p_cur == NULL) return; 60 61 while (**p_cur != '\0' && **p_cur != ',') { 62 (*p_cur)++; 63 } 64 65 if (**p_cur == ',') { 66 (*p_cur)++; 67 } 68 } 69 70 static char * nextTok(char **p_cur) 71 { 72 char *ret = NULL; 73 74 skipWhiteSpace(p_cur); 75 76 if (*p_cur == NULL) { 77 ret = NULL; 78 } else if (**p_cur == '"') { 79 (*p_cur)++; 80 ret = strsep(p_cur, "\""); 81 skipNextComma(p_cur); 82 } else { 83 ret = strsep(p_cur, ","); 84 } 85 86 return ret; 87 } 88 89 90 /** 91 * Parses the next integer in the AT response line and places it in *p_out 92 * returns 0 on success and -1 on fail 93 * updates *p_cur 94 * "base" is the same as the base param in strtol 95 */ 96 97 static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns) 98 { 99 char *ret; 100 101 if (*p_cur == NULL) { 102 return -1; 103 } 104 105 ret = nextTok(p_cur); 106 107 if (ret == NULL) { 108 return -1; 109 } else { 110 long l; 111 char *end; 112 113 if (uns) 114 l = strtoul(ret, &end, base); 115 else 116 l = strtol(ret, &end, base); 117 118 *p_out = (int)l; 119 120 if (end == ret) { 121 return -1; 122 } 123 } 124 125 return 0; 126 } 127 128 /** 129 * Parses the next base 10 integer in the AT response line 130 * and places it in *p_out 131 * returns 0 on success and -1 on fail 132 * updates *p_cur 133 */ 134 int at_tok_nextint(char **p_cur, int *p_out) 135 { 136 return at_tok_nextint_base(p_cur, p_out, 10, 0); 137 } 138 139 /** 140 * Parses the next base 16 integer in the AT response line 141 * and places it in *p_out 142 * returns 0 on success and -1 on fail 143 * updates *p_cur 144 */ 145 int at_tok_nexthexint(char **p_cur, int *p_out) 146 { 147 return at_tok_nextint_base(p_cur, p_out, 16, 1); 148 } 149 150 int at_tok_nextbool(char **p_cur, char *p_out) 151 { 152 int ret; 153 int result; 154 155 ret = at_tok_nextint(p_cur, &result); 156 157 if (ret < 0) { 158 return -1; 159 } 160 161 // booleans should be 0 or 1 162 if (!(result == 0 || result == 1)) { 163 return -1; 164 } 165 166 if (p_out != NULL) { 167 *p_out = (char)result; 168 } 169 170 return ret; 171 } 172 173 int at_tok_nextstr(char **p_cur, char **p_out) 174 { 175 if (*p_cur == NULL) { 176 return -1; 177 } 178 179 *p_out = nextTok(p_cur); 180 181 return 0; 182 } 183 184 /** returns 1 on "has more tokens" and 0 if no */ 185 int at_tok_hasmore(char **p_cur) 186 { 187 return ! (*p_cur == NULL || **p_cur == '\0'); 188 } 189 190 191