2 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
\r
4 * This file is part of <ciss>
\r
5 * Written by <Sungjoon Won> <sungjoon.won@samsung.com>, <Jungmin Kim> <jm15.kim@samsung.com>
\r
7 * PROPRIETARY/CONFIDENTIAL
\r
9 * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").
\r
10 * You shall not disclose such Confidential Information and shall use it only in accordance
\r
11 * with the terms of the license agreement you entered into with SAMSUNG ELECTRONICS.
\r
12 * SAMSUNG make no representations or warranties about the suitability of the software,
\r
13 * either express or implied, including but not limited to the implied warranties of merchantability,
\r
14 * fitness for a particular purpose, or non-infringement.
\r
15 * SAMSUNG shall not be liable for any damages suffered by licensee as a result of using,
\r
16 * modifying or distributing this software or its derivatives.
\r
20 #include "ciss-util.h"
\r
21 #include "ciss-tapi-request.h"
\r
22 #include "ciss-parser.h"
\r
23 #include "ciss-converter.h"
\r
25 static int __ciss_find_si_fields(char *user_input, char *sc, char *sia, char *sib, char *sic)
\r
42 sc_len = strspn(input, "0123456789");
\r
43 DBG("\n [CISS-ENGINE] sc_len : %d", sc_len);
\r
44 if (sc_len > MAX_SC_LEN)
\r
47 memcpy(sc, input, sc_len);
\r
51 if (input[sc_len] == '*') {
\r
52 /* check if there is an SIA field */
\r
53 sia_offset = sc_len + 1;
\r
54 sia_len = strspn((input + sia_offset), "+1234567890");
\r
55 /* check if there is an SIB field */
\r
56 if (input[sia_offset + sia_len] == '*') {
\r
57 sib_offset = sia_offset + sia_len + 1;
\r
58 sib_len = strspn (input + sib_offset, "+1234567890");
\r
59 /* check if there is an SIC field */
\r
60 if (input[sib_offset + sib_len] == '*') {
\r
61 sic_offset = sib_offset + sib_len + 1;
\r
62 sic_len = strspn(input + sic_offset, "+1234567890");
\r
67 if ((sia_len > 0) && (sia_len <= MAX_SIA_LEN)) {
\r
68 memcpy(sia, input + sia_offset, sia_len);
\r
69 sia[sia_len] = '\0';
\r
72 if ((sib_len > 0) && (sib_len <= MAX_SIB_LEN)) {
\r
73 memcpy(sib, input + sib_offset, sib_len);
\r
74 sib[sib_len] = '\0';
\r
77 if ((sic_len > 0) && (sic_len <= MAX_SIC_LEN)) {
\r
78 memcpy(sic, input + sic_offset, sic_len);
\r
79 sic[sic_len] = '\0';
\r
82 /* NOTE: A NULL value for the SIA, SIB and SIC are
\r
83 also valid and so return TRUE
\r
85 if ((sib_len > MAX_SIB_LEN) ||
\r
86 (sia_len > MAX_SIA_LEN) ||
\r
87 (sic_len > MAX_SIC_LEN))
\r
92 static unsigned char __ciss_parse_req_string(ciss_mmi_context_t *mmi_ctx, int *error_code)
\r
94 char sups_str[MAX_DIALED_DIGITS];
\r
95 char *user_sc = NULL;
\r
96 char bsg[MAX_SIA_LEN + 1];
\r
97 unsigned char ss_str_len;
\r
98 unsigned char ss_operation;
\r
99 unsigned char tapi_flavor = 0;
\r
100 unsigned char ss_type = 0xff;
\r
101 TelSsTeleService_t tapi_bsg;
\r
102 char sia[MAX_SIA_LEN + 1];
\r
103 char sib[MAX_SIB_LEN + 1];
\r
104 char sic[MAX_SIC_LEN + 1];
\r
105 char ss_code[MAX_SC_LEN + 1];
\r
107 ss_operation = NULL_SS_OPERATION;
\r
108 memset(sia, '\0', sizeof(sia));
\r
109 memset(sib, '\0', sizeof(sib));
\r
110 memset(sic, '\0', sizeof(sic));
\r
111 memset(ss_code, '\0', sizeof(ss_code));
\r
112 memset(bsg, '\0', sizeof(bsg));
\r
113 memset(sups_str, '\0', MAX_DIALED_DIGITS);
\r
115 /* user inputs must be in the g_form
\r
116 ** "**123*456*789*012#SEND"
\r
118 ** | | | | | |------>send key
\r
119 ** | | | | |--------->sic
\r
120 ** | | | |------------->sib
\r
121 ** | | |----------------->sia
\r
122 ** | |--------------------->sc
\r
123 ** |------------------------>operation
\r
126 /* STEP 1: Find the SS operation */
\r
127 memcpy(sups_str, mmi_ctx->user_string, mmi_ctx->user_string_length);
\r
128 /* get the length of the user input */
\r
129 ss_str_len = mmi_ctx->user_string_length;
\r
131 /* this may be a nomal call origination with CLIR
\r
133 if (((memcmp(sups_str, "*31#", 4) == 0) ||
\r
134 (memcmp(sups_str, "#31#", 4) == 0)) &&
\r
135 (sups_str[ss_str_len - 1] != '#'))
\r
136 return NULL_SS_OPERATION;
\r
138 /* check the first character */
\r
139 if (sups_str[0] == '*') {
\r
140 /* possible combinations are
\r
142 *03* - pwd registration
\r
143 **41* - registration
\r
144 **03* - pwd registration
\r
145 *#41* - interrogation
\r
147 if (ISDIGIT(sups_str [1])) {
\r
148 /* next char is a digit, can be activation or pwd_reg */
\r
149 if (!strncmp(sups_str, "*03*", strlen("*03*"))) {
\r
150 DBG("\n [CISS-ENGINE] registerPassword");
\r
151 ss_operation = registerPassword;
\r
152 user_sc = sups_str + 4;
\r
154 DBG("\n [CISS-ENGINE] activateSS");
\r
155 ss_operation = activateSS; /* eg: *41* for Activation */
\r
156 user_sc = sups_str + 1;
\r
158 } else if ((sups_str[1] == '#') && ISDIGIT(sups_str[2])) {
\r
159 /* now the combination is *#41 */
\r
160 DBG("\n [CISS-ENGINE] interrogateSS");
\r
161 ss_operation = interrogateSS;
\r
162 user_sc = sups_str + 2;
\r
163 } else if (sups_str[1] == '*') {
\r
164 /* possible combinations are
\r
165 **41* - registration
\r
166 **03* - pwd registration
\r
168 if (ISDIGIT(sups_str[2])) {
\r
169 if (!strncmp(sups_str, "**03*", strlen("**03*"))) {
\r
170 DBG("\n [CISS-ENGINE] registerPassword");
\r
171 ss_operation = registerPassword;
\r
172 user_sc = sups_str + 5;
\r
174 DBG("\n [CISS-ENGINE] registerSS");
\r
175 ss_operation = registerSS;
\r
176 user_sc = sups_str + 2;
\r
180 } else if (sups_str[0] == '#') {
\r
181 /* possible combinations are
\r
183 #41* - deactivation
\r
185 if (ISDIGIT(sups_str[1])) {
\r
186 DBG("\n [CISS-ENGINE] deactivateSS");
\r
187 ss_operation = deactivateSS;
\r
188 user_sc = sups_str + 1;
\r
189 } else if ((sups_str[1] == '#') && (ISDIGIT(sups_str[2]))) {
\r
190 /* Additional added a check to verify whether third character in USSD String is a digit or not.
\r
191 If 3rd Character is not a digit then should send USSD Request not Erase SS Operation
\r
193 DBG("\n [CISS-ENGINE] eraseSS");
\r
194 ss_operation = eraseSS;
\r
195 user_sc = sups_str + 2;
\r
197 } else if ((ss_str_len == 2) && (ISUSSDDIGIT(sups_str[0]) && ISDIGIT(sups_str[1]))) {
\r
198 DBG("\n [CISS-ENGINE] processUnstructuredSS_Request");
\r
199 ss_operation = processUnstructuredSS_Request;
\r
200 return ss_operation;
\r
201 } else if ((ss_str_len == 1) && (ISDIGIT(sups_str[0]))) {
\r
202 DBG("\n [CISS-ENGINE] processUnstructuredSS_Request");
\r
203 ss_operation = processUnstructuredSS_Request;
\r
204 return ss_operation;
\r
207 if (ss_operation != NULL_SS_OPERATION) {
\r
208 /* By now the operation must have been identified */
\r
209 /* STEP 2: Find the SI fields */
\r
210 if (!__ciss_find_si_fields(user_sc, ss_code, sia, sib, sic)) {
\r
211 /*Added code for UI display for password too long for call barring */
\r
212 /* Since SIB,SIC field length is 4 */
\r
213 if (strlen(ss_code)!= 0) {
\r
214 if (!_ciss_convert_sc_to_tapi_flavor(ss_code, &tapi_flavor, &ss_type)) {
\r
215 ss_operation = NULL_SS_OPERATION;
\r
216 } else if (ss_type == TAPI_SS_TYPE_BARRING) {
\r
217 DBG("\n [CISS-ENGINE] Too long password");
\r
218 ss_operation = NULL_SS_OPERATION;
\r
219 *error_code = CISS_ERR_CB_PWD_TOO_LONG;
\r
220 return ss_operation;
\r
223 /* End of password too long added code */
\r
224 ss_operation = NULL_SS_OPERATION;
\r
227 DBG("\n [CISS-ENGINE] sia = %s, sib = %s, sic = %s", sia, sib, sic);
\r
229 /* added for FDN check */
\r
230 strncpy(mmi_ctx->ss_code, ss_code, MAX_SC_LEN);
\r
231 /* by now SIA, SIB, SIC fields must have been separated out */
\r
232 /* STEP 3: Convert SC to network SC and update the
\r
233 sups_user_data field
\r
235 if ((ss_operation != registerPassword) &&
\r
236 (ss_operation != NULL_SS_OPERATION)) {
\r
237 if (!_ciss_convert_sc_to_tapi_flavor(ss_code, &tapi_flavor, &ss_type))
\r
238 ss_operation = NULL_SS_OPERATION;
\r
240 mmi_ctx->ss_flavor = tapi_flavor;
\r
241 mmi_ctx->ss_type = ss_type;
\r
244 /* by now the translation of SC must be complete */
\r
245 /* STEP 4: Check for BSG . This may be in SIA, SIB or SIC */
\r
246 if (ss_operation != NULL_SS_OPERATION) {
\r
247 if ((ss_operation != registerPassword)&&
\r
248 ((ss_type == TAPI_SS_TYPE_FORWARDING)||
\r
249 (ss_type == TAPI_SS_TYPE_BARRING))) {
\r
250 /* BSG is in SIB */
\r
251 if (ss_operation == interrogateSS)
\r
252 strncpy(bsg, sia, MAX_SIA_LEN);
\r
254 strncpy(bsg, sib, MAX_SIB_LEN);
\r
255 } else if (ss_type == TAPI_SS_TYPE_WAITING) {
\r
256 /* MSN:SISO changed for the validation of the #43**11# kind of strings */
\r
257 if ((sib[0] !=0) || (sic[0] != 0))
\r
258 ss_operation = NULL_SS_OPERATION;
\r
260 /* BSG is in SIA */
\r
261 strncpy(bsg, sia, MAX_SIA_LEN);
\r
265 /* by now BSG must be identified */
\r
266 /* STEP 5: Convert BSG to net BSG */
\r
267 /* validation of the #43**11# kind of strings */
\r
268 if ((ss_operation != registerPassword) &&
\r
269 (ss_operation != NULL_SS_OPERATION)) {
\r
271 if (_ciss_convert_bsg_to_tapi_bsg(bsg, &tapi_bsg))
\r
272 mmi_ctx->tapi_bsg = tapi_bsg;
\r
274 ss_operation = NULL_SS_OPERATION;
\r
278 /* STEP 6: Convert DN(divert number), if any */
\r
279 if (ss_operation != NULL_SS_OPERATION) {
\r
280 if (ss_type == TAPI_SS_TYPE_FORWARDING) {
\r
281 if (sia[0] != '\0') {
\r
282 strncpy(mmi_ctx->divert_number, sia, strlen(sia));
\r
283 mmi_ctx->divert_number[strlen(sia)] = '\0';
\r
285 /* else the length of the DN will be 0 */
\r
289 /* STEP 7: Set the NR(no reply) timer */
\r
290 if (((ss_operation == activateSS) || (ss_operation == registerSS)) &&
\r
291 (ss_type == TAPI_SS_TYPE_FORWARDING) &&
\r
292 ((tapi_flavor == TAPI_SS_FORWARD_WHEN_ALL_FORWARDING_EV) ||
\r
293 (tapi_flavor == TAPI_SS_FORWARD_WHEN_ALL_CONDITIONAL_EV) ||
\r
294 (tapi_flavor == TAPI_SS_FORWARD_WHEN_NO_ANSWER_EV))) {
\r
295 if (sic[0] != '\0')
\r
296 mmi_ctx->nr_timer = atoi(sic);
\r
298 mmi_ctx->nr_timer = 0;
\r
301 /* STEP 8: Check is activation is also registration? */
\r
302 if (ss_operation == activateSS) {
\r
303 if (mmi_ctx->divert_number[0] > 0)
\r
304 ss_operation = registerSS;
\r
305 else if (mmi_ctx->nr_timer != 0)
\r
306 ss_operation = registerSS;
\r
309 /* STEP 9: copy the password */
\r
310 /* for barring operations other than register*/
\r
311 if (ss_operation != NULL_SS_OPERATION) {
\r
312 /*Added code for UI display for password too long for call barring */
\r
313 /* Since SIA feild length is 40 */
\r
314 if ((ss_type == TAPI_SS_TYPE_BARRING) ||
\r
315 (ss_operation == registerPassword)) {
\r
316 if (strlen(sia) > 4) {
\r
317 DBG("\n [CISS-ENGINE] Too long password");
\r
318 ss_operation = NULL_SS_OPERATION;
\r
319 *error_code = CISS_ERR_CB_PWD_TOO_LONG;
\r
320 return ss_operation;
\r
324 /* End of password too long added code */
\r
325 if ((ss_type == TAPI_SS_TYPE_BARRING) &&
\r
326 (ss_operation != registerPassword)) {
\r
327 if (ss_operation != interrogateSS) {
\r
328 if (strlen(sia) < 4) {
\r
329 DBG("\n [CISS-ENGINE] Pwd Too Short : %d",strlen(sia));
\r
330 ss_operation = NULL_SS_OPERATION;
\r
331 *error_code = CISS_ERR_CB_PWD_TOO_SORT;
\r
332 return ss_operation;
\r
333 } else if (strlen(sia) > 4) {
\r
334 DBG("\n [CISS-ENGINE] Pwd Too long : %d",strlen(sia));
\r
335 ss_operation = NULL_SS_OPERATION;
\r
336 *error_code = CISS_ERR_CB_PWD_TOO_LONG;
\r
337 return ss_operation;
\r
339 strncpy(mmi_ctx->ss_password, sia, CISS_MAX_PASSWORD_LEN);
\r
340 mmi_ctx->ss_password[CISS_MAX_PASSWORD_LEN] = '\0';
\r
346 /* copy old_pwd, new_pwd, new_pwd_again */
\r
347 if (ss_operation == registerPassword) {
\r
348 if ((strlen(sia) != 4) ||
\r
349 (strlen(sib) != 4) ||
\r
350 (strlen(sic) != 4)) {
\r
351 DBG("\n [CISS-ENGINE] Pwd Length Incorrect : %d %d %d", strlen(sia), strlen(sib), strlen(sic));
\r
352 memset(mmi_ctx->ss_password, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
353 memset(mmi_ctx->ss_new_password, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
354 memset(mmi_ctx->ss_new_password2, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
355 strncpy(mmi_ctx->ss_password,sia, CISS_MAX_PASSWORD_LEN);
\r
356 strncpy(mmi_ctx->ss_new_password,sib, CISS_MAX_PASSWORD_LEN);
\r
357 strncpy(mmi_ctx->ss_new_password2,sic, CISS_MAX_PASSWORD_LEN);
\r
359 memset(mmi_ctx->ss_password, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
360 memset(mmi_ctx->ss_new_password, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
361 memset(mmi_ctx->ss_new_password2, '\0', CISS_MAX_PASSWORD_LEN + 1);
\r
362 strncpy(mmi_ctx->ss_password,sia, CISS_MAX_PASSWORD_LEN);
\r
363 strncpy(mmi_ctx->ss_new_password,sib, CISS_MAX_PASSWORD_LEN);
\r
364 strncpy(mmi_ctx->ss_new_password2,sic, CISS_MAX_PASSWORD_LEN);
\r
368 if (ss_operation == NULL_SS_OPERATION) {
\r
369 /* check if it is an Unstructured SS data */
\r
370 if ((ss_str_len <= MAX_USS_CHAR) &&
\r
371 (ss_str_len > 2) &&
\r
372 (sups_str[ss_str_len - 1] == '#'))
\r
373 ss_operation = processUnstructuredSS_Request;
\r
375 return (ss_operation);
\r
378 int _ciss_parse_req_string(char *pszSS, ciss_mmi_context_t *mmi_ctx)
\r
381 memset(mmi_ctx, 0x0, sizeof(ciss_mmi_context_t));
\r
382 DBG("\n [CISS-ENGINE] received string = %s", pszSS);
\r
383 mmi_ctx->user_string_length = strlen(pszSS);
\r
384 if (mmi_ctx->user_string_length > 0)
\r
385 memcpy(mmi_ctx->user_string, pszSS, mmi_ctx->user_string_length);
\r
387 DBG("\n [CISS-ENGINE] User String Length should be non-zero");
\r
388 return CISS_ERR_UNKNOWN;
\r
391 int error_code = CISS_ERR_NONE;
\r
392 mmi_ctx->opcode = __ciss_parse_req_string(mmi_ctx, &error_code);
\r
393 DBG("\n [CISS-ENGINE] Parsed opcode = %d", mmi_ctx->opcode);
\r
394 DBG("\n [CISS-ENGINE] Parsed SSCode = %x", mmi_ctx->ss_flavor);
\r
395 DBG("\n [CISS-ENGINE] Parsed SStype = %x", mmi_ctx->ss_type);
\r
396 DBG("\n [CISS-ENGINE] Parsed BS Code = %x ", mmi_ctx->tapi_bsg);
\r
397 DBG("\n [CISS-ENGINE] Parsed NR Timer = %d", mmi_ctx->nr_timer);
\r
398 DBG("\n [CISS-ENGINE] Parsed Divert no = %s", mmi_ctx->divert_number);
\r
399 DBG("\n [CISS-ENGINE] Parsed SS Pwd = %s", mmi_ctx->ss_password);
\r
400 DBG("\n [CISS-ENGINE] Parsed SS New Pwd = %s", mmi_ctx->ss_new_password);
\r
401 DBG("\n [CISS-ENGINE] Parsed SS New Pwd cnf = %s", mmi_ctx->ss_new_password2);
\r
402 if ((mmi_ctx->opcode == NULL_SS_OPERATION) &&
\r
403 (error_code == CISS_ERR_NONE))
\r
404 error_code = CISS_ERR_ILLEGAL_SS_OPER;
\r