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 */ 28int 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 48static 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 57static 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 70static 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 97static 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 */ 134int 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 */ 145int at_tok_nexthexint(char **p_cur, int *p_out) 146{ 147 return at_tok_nextint_base(p_cur, p_out, 16, 1); 148} 149 150int 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 173int 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 */ 185int at_tok_hasmore(char **p_cur) 186{ 187 return ! (*p_cur == NULL || **p_cur == '\0'); 188} 189 190 191