merge from master branch's latest code.
[apps/core/preloaded/ciss.git] / src / ciss-parser.c
1 /*\r
2  * Copyright 2012  Samsung Electronics Co., Ltd\r
3  *\r
4  * Licensed under the Flora License, Version 1.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.tizenopensource.org/license\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 #include "ciss-util.h"\r
18 #include "ciss-tapi-request.h"\r
19 #include "ciss-parser.h"\r
20 #include "ciss-converter.h"\r
21 \r
22 static int __ciss_find_si_fields(char *user_input, char *sc, char *sia, char *sib, char *sic)\r
23 {\r
24         char  *input;\r
25         int sia_offset = 0;\r
26         int sib_offset = 0;\r
27         int sic_offset = 0;\r
28         int sia_len = 0;\r
29         int sib_len = 0;\r
30         int sic_len = 0;\r
31         int sc_len = 0;\r
32 \r
33         input = user_input;\r
34         sc_len = strspn(input, "0123456789");\r
35         DBG("\n [CISS-ENGINE] sc_len : %d", sc_len);\r
36         if (sc_len > MAX_SC_LEN) {\r
37                 return FALSE;\r
38         } else {\r
39                 memcpy(sc, input, sc_len);\r
40                 sc[sc_len] = '\0';\r
41         }\r
42 \r
43         if (input[sc_len] == '*') {     /* 1st Seperator */\r
44                 sia_offset = sc_len + 1;\r
45                 sia_len = strspn((input + sia_offset), "+1234567890");\r
46                 if (input[sia_offset + sia_len] == '*') {       /* 2nd Seperator */\r
47                         sib_offset = sia_offset + sia_len + 1;\r
48                         sib_len = strspn(input + sib_offset, "+1234567890");\r
49                         if (input[sib_offset + sib_len] == '*') {       /* 3rd Seperator */\r
50                                 sic_offset = sib_offset + sib_len + 1;\r
51                                 sic_len = strspn(input + sic_offset, "+1234567890");\r
52                         }\r
53                 }\r
54         }\r
55 \r
56         if ((sia_len > 0) && (sia_len <= MAX_SIA_LEN)) {\r
57                 memcpy(sia, input + sia_offset, sia_len);\r
58                 sia[sia_len] = '\0';\r
59         }\r
60 \r
61         if ((sib_len > 0) && (sib_len <= MAX_SIB_LEN)) {\r
62                 memcpy(sib, input + sib_offset, sib_len);\r
63                 sib[sib_len] = '\0';\r
64         }\r
65 \r
66         if ((sic_len > 0) && (sic_len <= MAX_SIC_LEN)) {\r
67                 memcpy(sic, input + sic_offset, sic_len);\r
68                 sic[sic_len] = '\0';\r
69         }\r
70 \r
71         if ((sib_len > MAX_SIB_LEN) ||\r
72                         (sia_len > MAX_SIA_LEN) ||\r
73                         (sic_len > MAX_SIC_LEN)) {\r
74                 return FALSE;\r
75         }\r
76         return TRUE;\r
77 }\r
78 \r
79 static unsigned char __ciss_parse_mmi_string(ciss_mmi_context_t *mmi_ctx, int *error_code)\r
80 {\r
81         char   sups_str[MAX_DIALED_DIGITS];\r
82         char   *user_sc = NULL;\r
83         char   bsg[MAX_SIA_LEN + 1];\r
84         unsigned char   ss_str_len;\r
85         unsigned char   ss_operation;\r
86         unsigned char   tapi_flavor = 0;\r
87         unsigned char     ss_type = 0xff;\r
88         TelSsClass_t tapi_bsg;\r
89         char sia[MAX_SIA_LEN + 1];\r
90         char sib[MAX_SIB_LEN + 1];\r
91         char sic[MAX_SIC_LEN + 1];\r
92         char ss_code[MAX_SC_LEN + 1];\r
93 \r
94         ss_operation = NULL_SS_OPERATION;\r
95         memset(sia, '\0', sizeof(sia));\r
96         memset(sib, '\0', sizeof(sib));\r
97         memset(sic, '\0', sizeof(sic));\r
98         memset(ss_code, '\0', sizeof(ss_code));\r
99         memset(bsg, '\0', sizeof(bsg));\r
100         memset(sups_str, '\0', MAX_DIALED_DIGITS);\r
101 \r
102         /* Refer to 3GPP TS 22.030\r
103         ** "**123*456*789*012#SEND"\r
104         **  |  |   |   |   |  |\r
105         **  |  |   |   |   |  |------> send key\r
106         **  |  |   |   |   |---------> sic\r
107         **  |  |   |   |-------------> sib\r
108         **  |  |   |-----------------> sia\r
109         **  |  |---------------------> sc\r
110         **  |------------------------> operation\r
111         */\r
112 \r
113         memcpy(sups_str, mmi_ctx->user_string, mmi_ctx->user_string_length);\r
114         ss_str_len = mmi_ctx->user_string_length;\r
115 \r
116         if (((memcmp(sups_str, "*31#", 4) == 0) ||\r
117                         (memcmp(sups_str, "#31#", 4) == 0)) &&\r
118                         (sups_str[ss_str_len - 1] != '#')) {\r
119                 return NULL_SS_OPERATION;\r
120         }\r
121 \r
122         if (sups_str[0] == '*') {\r
123                 if (ISDIGIT(sups_str [1])) {\r
124                         if (!strncmp(sups_str, "*03*", strlen("*03*"))) {\r
125                                 DBG("\n [CISS-ENGINE] registerPassword");\r
126                                 ss_operation = registerPassword;\r
127                                 user_sc = sups_str + 4;\r
128                         } else {\r
129                                 DBG("\n [CISS-ENGINE] activateSS");\r
130                                 ss_operation = activateSS;\r
131                                 user_sc = sups_str + 1;\r
132                         }\r
133                 } else if ((sups_str[1] == '#') && ISDIGIT(sups_str[2])) {\r
134                         DBG("\n [CISS-ENGINE] interrogateSS");\r
135                         ss_operation = interrogateSS;\r
136                         user_sc = sups_str + 2;\r
137                 } else if (sups_str[1] == '*') {\r
138                         if (ISDIGIT(sups_str[2])) {\r
139                                 if (!strncmp(sups_str, "**03*", strlen("**03*"))) {\r
140                                         DBG("\n [CISS-ENGINE] registerPassword");\r
141                                         ss_operation = registerPassword;\r
142                                         user_sc = sups_str + 5;\r
143                                 } else {\r
144                                         DBG("\n [CISS-ENGINE] registerSS");\r
145                                         ss_operation = registerSS;\r
146                                         user_sc = sups_str + 2;\r
147                                 }\r
148                         }\r
149                 }\r
150         } else if (sups_str[0] == '#') {\r
151                 if (ISDIGIT(sups_str[1])) {\r
152                         DBG("\n [CISS-ENGINE] deactivateSS");\r
153                         ss_operation = deactivateSS;\r
154                         user_sc = sups_str + 1;\r
155                 } else if ((sups_str[1] == '#') && (ISDIGIT(sups_str[2]))) {\r
156                         DBG("\n [CISS-ENGINE] eraseSS");\r
157                         ss_operation = eraseSS;\r
158                         user_sc = sups_str + 2;\r
159                 }\r
160         } else if ((ss_str_len == 2) && (ISUSSDDIGIT(sups_str[0]) && ISDIGIT(sups_str[1]))) {\r
161                 DBG("\n [CISS-ENGINE] processUnstructuredSS_Request");\r
162                 ss_operation = processUnstructuredSS_Request;\r
163                 return ss_operation;\r
164         } else if ((ss_str_len == 1) && (ISDIGIT(sups_str[0]))) {\r
165                 DBG("\n [CISS-ENGINE] processUnstructuredSS_Request");\r
166                 ss_operation = processUnstructuredSS_Request;\r
167                 return ss_operation;\r
168         }\r
169 \r
170         if (ss_operation != NULL_SS_OPERATION) {\r
171                 if (!__ciss_find_si_fields(user_sc, ss_code, sia, sib, sic)) {\r
172                         if (strlen(ss_code)!= 0) {\r
173                                 if (!_ciss_convert_sc_to_tapi_flavor(ss_code, &tapi_flavor, &ss_type)) {\r
174                                         ss_operation = NULL_SS_OPERATION;\r
175                                 } else if (ss_type == CISS_SERVICE_BARRING) {\r
176                                         DBG("\n [CISS-ENGINE] Too long password");\r
177                                         ss_operation = NULL_SS_OPERATION;\r
178                                         *error_code = CISS_ERR_CB_PWD_TOO_LONG;\r
179                                         return ss_operation;\r
180                                 }\r
181                         }\r
182                         ss_operation = NULL_SS_OPERATION;\r
183                 }\r
184 \r
185                 DBG("\n [CISS-ENGINE] sia = %s, sib = %s, sic = %s", sia, sib, sic);\r
186         }\r
187 \r
188         strncpy(mmi_ctx->ss_code, ss_code, MAX_SC_LEN);\r
189         if ((ss_operation != registerPassword) &&\r
190                         (ss_operation != NULL_SS_OPERATION)) {\r
191                 if (!_ciss_convert_sc_to_tapi_flavor(ss_code, &tapi_flavor, &ss_type)) {\r
192                         ss_operation = NULL_SS_OPERATION;\r
193                 } else {\r
194                         mmi_ctx->ss_flavor = tapi_flavor;\r
195                         mmi_ctx->ss_type = ss_type;\r
196                 }\r
197         }\r
198 \r
199         if (ss_operation != NULL_SS_OPERATION) {\r
200                 if ((ss_operation != registerPassword)&&\r
201                                 ((ss_type == CISS_SERVICE_FORWARDING)||\r
202                                  (ss_type == CISS_SERVICE_BARRING))) {\r
203                                 strncpy(bsg, sib, MAX_SIB_LEN);\r
204                 } else if (ss_type == CISS_SERVICE_WAITING) {\r
205                         if ((sib[0] !=0) || (sic[0] != 0)) {\r
206                                 ss_operation = NULL_SS_OPERATION;\r
207                         } else {\r
208                                 strncpy(bsg, sia, MAX_SIA_LEN);\r
209                         }\r
210                 } else {\r
211                         bsg[0] = '\0';\r
212                 }\r
213 \r
214                 if ((ss_operation != registerPassword) &&\r
215                                 (ss_operation != NULL_SS_OPERATION)) {\r
216                         if (_ciss_convert_bsg_to_tapi_bsg(bsg, &tapi_bsg)) {\r
217                                 mmi_ctx->tapi_bsg = tapi_bsg;\r
218                         } else {\r
219                                 ss_operation = NULL_SS_OPERATION;\r
220                         }\r
221                 }\r
222         }\r
223 \r
224         if (ss_operation != NULL_SS_OPERATION) {\r
225                 if (ss_type == CISS_SERVICE_FORWARDING) {\r
226                         if (sia[0] != '\0') {\r
227                                 strncpy(mmi_ctx->forward_number, sia, strlen(sia));\r
228                                 mmi_ctx->forward_number[strlen(sia)] = '\0';\r
229                         }\r
230                 }\r
231         }\r
232 \r
233         if (((ss_operation == activateSS) || (ss_operation == registerSS)) &&\r
234                         (ss_type == CISS_SERVICE_FORWARDING) &&\r
235                         ((tapi_flavor == CISS_FLAVOR_FORWARD_ALL_FLAVORS) ||\r
236                          (tapi_flavor == CISS_FLAVOR_FORWARD_ALL_CONDITIONAL_FLAVORS) ||\r
237                          (tapi_flavor == TAPI_SS_CF_WHEN_CFNRy))) {\r
238                 if (sic[0] != '\0') {\r
239                         mmi_ctx->nr_timer = atoi(sic);\r
240                 } else {\r
241                         mmi_ctx->nr_timer = 0;\r
242                 }\r
243         }\r
244 \r
245         if (ss_operation == activateSS) {\r
246                 if (mmi_ctx->forward_number[0] > 0) {\r
247                         ss_operation = registerSS;\r
248                 } else if (mmi_ctx->nr_timer != 0) {\r
249                         ss_operation = registerSS;\r
250                 }\r
251         }\r
252 \r
253         if (ss_operation != NULL_SS_OPERATION) {\r
254                 if ((ss_type == CISS_SERVICE_BARRING) ||\r
255                                 (ss_operation == registerPassword)) {\r
256                         if (strlen(sia) > 4) {\r
257                                 DBG("\n [CISS-ENGINE] Too long password");\r
258                                 ss_operation = NULL_SS_OPERATION;\r
259                                 *error_code = CISS_ERR_CB_PWD_TOO_LONG;\r
260                                 return ss_operation;\r
261                         }\r
262                 }\r
263 \r
264                 if ((ss_type == CISS_SERVICE_BARRING) &&\r
265                                 (ss_operation != registerPassword)) {\r
266                         if (ss_operation != interrogateSS) {\r
267                                 if (strlen(sia) < 4) {\r
268                                         DBG("\n [CISS-ENGINE] Pwd Too Short : %d",strlen(sia));\r
269                                         ss_operation = NULL_SS_OPERATION;\r
270                                         *error_code = CISS_ERR_CB_PWD_TOO_SORT;\r
271                                         return ss_operation;\r
272                                 } else if (strlen(sia) > 4) {\r
273                                         DBG("\n [CISS-ENGINE] Pwd Too long : %d",strlen(sia));\r
274                                         ss_operation = NULL_SS_OPERATION;\r
275                                         *error_code = CISS_ERR_CB_PWD_TOO_LONG;\r
276                                         return ss_operation;\r
277                                 } else {\r
278                                         strncpy(mmi_ctx->ss_password, sia, CISS_MAX_PASSWORD_LEN);\r
279                                         mmi_ctx->ss_password[CISS_MAX_PASSWORD_LEN] = '\0';\r
280                                 }\r
281                         }\r
282                 }\r
283         }\r
284 \r
285         if (ss_operation == registerPassword) {\r
286                 if ((strlen(sia) != 4) ||\r
287                                 (strlen(sib) != 4) ||\r
288                                 (strlen(sic) != 4)) {\r
289                         DBG("\n [CISS-ENGINE] Pwd Length Incorrect : %d %d %d", strlen(sia), strlen(sib), strlen(sic));\r
290                         memset(mmi_ctx->ss_password, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
291                         memset(mmi_ctx->ss_new_password, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
292                         memset(mmi_ctx->ss_new_password2, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
293                         strncpy(mmi_ctx->ss_password,sia, CISS_MAX_PASSWORD_LEN);\r
294                         strncpy(mmi_ctx->ss_new_password,sib, CISS_MAX_PASSWORD_LEN);\r
295                         strncpy(mmi_ctx->ss_new_password2,sic, CISS_MAX_PASSWORD_LEN);\r
296                 } else {\r
297                         memset(mmi_ctx->ss_password, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
298                         memset(mmi_ctx->ss_new_password, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
299                         memset(mmi_ctx->ss_new_password2, '\0', CISS_MAX_PASSWORD_LEN + 1);\r
300                         strncpy(mmi_ctx->ss_password,sia, CISS_MAX_PASSWORD_LEN);\r
301                         strncpy(mmi_ctx->ss_new_password,sib, CISS_MAX_PASSWORD_LEN);\r
302                         strncpy(mmi_ctx->ss_new_password2,sic, CISS_MAX_PASSWORD_LEN);\r
303                 }\r
304         }\r
305 \r
306         if (ss_operation == NULL_SS_OPERATION) {\r
307                 if ((ss_str_len <= MAX_USS_CHAR) &&\r
308                                 (ss_str_len > 2) &&\r
309                                 (sups_str[ss_str_len - 1] == '#')) {\r
310                         ss_operation = processUnstructuredSS_Request;\r
311                 }\r
312         }\r
313         return (ss_operation);\r
314 }\r
315 \r
316 int _ciss_parse_req_string(char *pszSS, ciss_mmi_context_t *mmi_ctx)\r
317 {\r
318         DBG("Enter");\r
319         memset(mmi_ctx, 0x0, sizeof(ciss_mmi_context_t));\r
320         DBG("\n [CISS-ENGINE] received string = %s", pszSS);\r
321         mmi_ctx->user_string_length = strlen(pszSS);\r
322         if (mmi_ctx->user_string_length > 0) {\r
323                 memcpy(mmi_ctx->user_string, pszSS, mmi_ctx->user_string_length);\r
324         } else {\r
325                 DBG("\n [CISS-ENGINE] User String Length should be non-zero");\r
326                 return CISS_ERR_UNKNOWN;\r
327         }\r
328 \r
329         int error_code = CISS_ERR_NONE;\r
330         mmi_ctx->opcode = __ciss_parse_mmi_string(mmi_ctx, &error_code);\r
331         if (mmi_ctx->opcode == processUnstructuredSS_Request) {\r
332                 mmi_ctx->ussd_type = TAPI_SS_USSD_TYPE_USER_INIT;\r
333         }\r
334         DBG(" [CISS-ENGINE] Parsed opcode = 0x%x", mmi_ctx->opcode);\r
335         DBG(" [CISS-ENGINE] Parsed SSCode = 0x%x", mmi_ctx->ss_flavor);\r
336         DBG(" [CISS-ENGINE] Parsed SStype = 0x%x", mmi_ctx->ss_type);\r
337         DBG(" [CISS-ENGINE] Parsed BS Code = 0x%x  ", mmi_ctx->tapi_bsg);\r
338         DBG(" [CISS-ENGINE] Parsed NR Timer = %d", mmi_ctx->nr_timer);\r
339         DBG(" [CISS-ENGINE] Parsed Forwarded No = %s", mmi_ctx->forward_number);\r
340         DBG(" [CISS-ENGINE] Parsed SS Pwd = %s", mmi_ctx->ss_password);\r
341         DBG(" [CISS-ENGINE] Parsed SS New Pwd = %s", mmi_ctx->ss_new_password);\r
342         DBG(" [CISS-ENGINE] Parsed SS New Pwd cnf = %s", mmi_ctx->ss_new_password2);\r
343         if ((mmi_ctx->opcode == NULL_SS_OPERATION) &&\r
344                         (error_code == CISS_ERR_NONE)) {\r
345                 error_code = CISS_ERR_ILLEGAL_SS_OPER;\r
346         }\r
347 \r
348         return error_code;\r
349 }\r
350 \r