Add default Smack manifest for org.tizen.ciss.spec
[pkgs/c/ciss.git] / src / ciss-parser.c
1 /*\r
2  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved \r
3  *\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
6  *\r
7  * PROPRIETARY/CONFIDENTIAL\r
8  *\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
17  *\r
18  */\r
19 \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
24 \r
25 static int __ciss_find_si_fields(char *user_input, char *sc, char *sia, char *sib, char *sic)\r
26 {\r
27         char  *input;\r
28         int sia_offset = 0;\r
29         int sib_offset = 0;\r
30         int sic_offset = 0;\r
31         int sia_len = 0;\r
32         int sib_len = 0;\r
33         int sic_len = 0;\r
34         int sc_len = 0;\r
35 \r
36         /*\r
37         123*456*789*012#\r
38         |    |   |   |\r
39         sc  sia sib  sic\r
40         */\r
41         input = user_input;\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
45                 return false;\r
46         else {\r
47                 memcpy(sc, input, sc_len);\r
48                 sc[sc_len] = '\0';\r
49         }\r
50 \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
63                         }\r
64                 }\r
65         }\r
66 \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
70         }\r
71 \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
75         }\r
76 \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
80         }\r
81 \r
82         /* NOTE: A NULL value for the SIA, SIB and SIC are\r
83                also valid and so return TRUE\r
84         */\r
85         if ((sib_len > MAX_SIB_LEN) ||\r
86             (sia_len > MAX_SIA_LEN) ||\r
87             (sic_len > MAX_SIC_LEN))\r
88                 return false;\r
89     return TRUE;\r
90 }\r
91 \r
92 static unsigned char __ciss_parse_req_string(ciss_mmi_context_t *mmi_ctx, int *error_code)\r
93 {\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
106 \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
114 \r
115         /* user inputs must be in the g_form\r
116         ** "**123*456*789*012#SEND"\r
117         **  |  |   |   |   |  |\r
118         **  |  |   |   |   |  |------>send key\r
119         **  |  |   |   |   |--------->sic\r
120         **  |  |   |   |------------->sib\r
121         **  |  |   |----------------->sia\r
122         **  |  |--------------------->sc\r
123         **  |------------------------>operation\r
124         */\r
125 \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
130         /* special case */\r
131         /* this may be a nomal call origination with CLIR\r
132         */\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
137 \r
138         /* check the first character */\r
139         if (sups_str[0] == '*') {\r
140                 /* possible combinations are\r
141                   *41*  - activation\r
142                   *03*  - pwd registration\r
143                   **41* - registration\r
144                   **03* - pwd registration\r
145                   *#41* - interrogation\r
146                 */\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
153                         } else {\r
154                                 DBG("\n [CISS-ENGINE] activateSS");\r
155                                 ss_operation = activateSS;  /* eg: *41* for Activation */\r
156                                 user_sc = sups_str + 1;\r
157                         }\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
167                         */\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
173                                 } else {\r
174                                         DBG("\n [CISS-ENGINE] registerSS");\r
175                                         ss_operation = registerSS;\r
176                                         user_sc = sups_str + 2;\r
177                                 }\r
178                         }\r
179                 }\r
180         } else if (sups_str[0] == '#') {\r
181                 /* possible combinations are\r
182                    ##41* - erasure\r
183                    #41* - deactivation\r
184                 */\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
192                 */\r
193                         DBG("\n [CISS-ENGINE] eraseSS");\r
194                         ss_operation = eraseSS;\r
195                         user_sc = sups_str + 2;\r
196                 }\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
205         }\r
206 \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
221                                 }\r
222                         }\r
223                         /* End of password too long added code */\r
224                         ss_operation = NULL_SS_OPERATION;\r
225                 }\r
226 \r
227                 DBG("\n [CISS-ENGINE] sia = %s, sib = %s, sic = %s", sia, sib, sic);\r
228         }\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
234         */\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
239                 else {\r
240                         mmi_ctx->ss_flavor = tapi_flavor;\r
241                         mmi_ctx->ss_type = ss_type;\r
242                 }\r
243         }\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
253                         else\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
259                         else\r
260                                 /* BSG is in  SIA */\r
261                                 strncpy(bsg, sia, MAX_SIA_LEN);\r
262                 } else\r
263                         bsg[0] = '\0';\r
264 \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
270                         /* special case */\r
271                         if (_ciss_convert_bsg_to_tapi_bsg(bsg, &tapi_bsg))\r
272                                 mmi_ctx->tapi_bsg = tapi_bsg;\r
273                         else\r
274                                 ss_operation = NULL_SS_OPERATION;\r
275                 }\r
276         }\r
277 \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
284                         }\r
285                         /* else the length of the DN will be 0 */\r
286                 }\r
287         }\r
288 \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
297                 else\r
298                         mmi_ctx->nr_timer = 0;\r
299         }\r
300 \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
307         }\r
308 \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
321                         }\r
322                 }\r
323 \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
338                                 } else {\r
339                                         strncpy(mmi_ctx->ss_password, sia, CISS_MAX_PASSWORD_LEN);\r
340                                         mmi_ctx->ss_password[CISS_MAX_PASSWORD_LEN] = '\0';\r
341                                 }\r
342                         }\r
343                 }\r
344         }\r
345 \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
358                 } else {\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
365                 }\r
366         }\r
367 \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
374         }\r
375         return (ss_operation);\r
376 }\r
377 \r
378 int _ciss_parse_req_string(char *pszSS, ciss_mmi_context_t *mmi_ctx)\r
379 {\r
380         DBG("Enter");\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
386         else {\r
387                 DBG("\n [CISS-ENGINE] User String Length should be non-zero");\r
388                 return CISS_ERR_UNKNOWN;\r
389         }\r
390 \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
405 \r
406         return error_code;\r
407 }\r
408 \r