4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include "user_request.h"
31 #include "core_object.h"
34 struct private_object_data {
35 struct tcore_sim_operations *ops;
37 enum tel_sim_type type; /**< Provides the SIM card type*/
38 enum tel_sim_status sim_status; /**< Provides the card status*/
39 struct tel_sim_imsi imsi; /**< Provides IMSI information*/
40 gboolean b_sim_changed; /**< Provides SIM card Identification- 0:no changed, 1:changed*/
41 gboolean b_cphs; /**< Whether current SIM is for CPHS or not*/
43 enum tel_sim_file_id language_file; /**<Provides Current cached language EF address */
44 enum tel_sim_file_id cf_file; /**<Provides Current cached call forwarding EF address */
45 enum tel_sim_file_id mw_file; /**<Provides Current cached message waiting EF address */
46 enum tel_sim_file_id mb_file; /**<Provides Current cached mailbox number EF address */
48 void *userdata; /**< free use data*/
52 static TReturn _dispatcher(CoreObject *o, UserRequest *ur)
54 enum tcore_request_command command;
55 struct private_object_data *po = NULL;
57 CORE_OBJECT_CHECK_RETURN(o, CORE_OBJECT_TYPE_SIM, TCORE_RETURN_EINVAL);
59 po = tcore_object_ref_object(o);
61 return TCORE_RETURN_ENOSYS;
63 command = tcore_user_request_get_command(ur);
66 case TREQ_SIM_VERIFY_PINS:
67 if (!po->ops->verify_pins)
68 return TCORE_RETURN_ENOSYS;
70 return po->ops->verify_pins(o, ur);
73 case TREQ_SIM_VERIFY_PUKS:
74 if (!po->ops->verify_puks)
75 return TCORE_RETURN_ENOSYS;
77 return po->ops->verify_puks(o, ur);
80 case TREQ_SIM_CHANGE_PINS:
81 if (!po->ops->change_pins)
82 return TCORE_RETURN_ENOSYS;
84 return po->ops->change_pins(o, ur);
87 case TREQ_SIM_GET_FACILITY_STATUS:
88 if (!po->ops->get_facility_status)
89 return TCORE_RETURN_ENOSYS;
91 return po->ops->get_facility_status(o, ur);
94 case TREQ_SIM_DISABLE_FACILITY:
95 if (!po->ops->disable_facility)
96 return TCORE_RETURN_ENOSYS;
98 return po->ops->disable_facility(o, ur);
101 case TREQ_SIM_ENABLE_FACILITY:
102 if (!po->ops->enable_facility)
103 return TCORE_RETURN_ENOSYS;
105 return po->ops->enable_facility(o, ur);
108 case TREQ_SIM_GET_LOCK_INFO:
109 if (!po->ops->get_lock_info)
110 return TCORE_RETURN_ENOSYS;
112 return po->ops->get_lock_info(o, ur);
115 case TREQ_SIM_TRANSMIT_APDU:
116 if (!po->ops->transmit_apdu)
117 return TCORE_RETURN_ENOSYS;
119 return po->ops->transmit_apdu(o, ur);
122 case TREQ_SIM_GET_ATR:
123 if (!po->ops->get_atr)
124 return TCORE_RETURN_ENOSYS;
126 return po->ops->get_atr(o, ur);
129 case TREQ_SIM_SET_LANGUAGE:
130 case TREQ_SIM_SET_CALLFORWARDING:
131 if (!po->ops->update_file)
132 return TCORE_RETURN_ENOSYS;
134 return po->ops->update_file(o, ur);
137 case TREQ_SIM_GET_ECC:
138 case TREQ_SIM_GET_LANGUAGE:
139 case TREQ_SIM_GET_ICCID:
140 case TREQ_SIM_GET_MAILBOX:
141 case TREQ_SIM_GET_CALLFORWARDING:
142 case TREQ_SIM_GET_MESSAGEWAITING:
143 case TREQ_SIM_GET_CPHS_INFO:
144 case TREQ_SIM_GET_MSISDN:
145 case TREQ_SIM_GET_SPN:
146 case TREQ_SIM_GET_SPDI:
147 case TREQ_SIM_GET_OPL:
148 case TREQ_SIM_GET_PNN:
149 case TREQ_SIM_GET_CPHS_NETNAME:
150 case TREQ_SIM_GET_OPLMNWACT:
151 if (!po->ops->read_file)
152 return TCORE_RETURN_ENOSYS;
154 return po->ops->read_file(o, ur);
157 case TREQ_SIM_REQ_AUTHENTICATION:
158 if (!po->ops->req_authentication)
159 return TCORE_RETURN_ENOSYS;
161 return po->ops->req_authentication(o, ur);
168 return TCORE_RETURN_SUCCESS;
171 static void _clone_hook(CoreObject *src, CoreObject *dest)
173 struct private_object_data *src_po = NULL;
174 struct private_object_data *dest_po = NULL;
179 dest_po = calloc(sizeof(struct private_object_data), 1);
181 tcore_object_link_object(dest, NULL);
185 src_po = tcore_object_ref_object(src);
186 dest_po->ops = src_po->ops;
188 tcore_object_link_object(dest, dest_po);
191 static void _free_hook(CoreObject *o)
193 struct private_object_data *po = NULL;
195 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
197 po = tcore_object_ref_object(o);
200 tcore_object_link_object(o, NULL);
204 static void _reverse(char* p_in, int length)
206 int i, j = length - 1;
207 for (i = 0; i < j; i++) {
214 static char* _acitoa(int n, char* str, int b)
219 str[i++] = "0123456789ABCDEF"[n % b];
220 } while ((n /= b) > 0);
229 /*******************************************************************************
230 Convert Digit to BCD (BCD to Digit)
238 1032547698 0123456789
240 ********************************************************************************/
242 * This function is used to Convert Digit to BCD (Digit to BCD)
245 * @param[out] bcdCode - BCD output
246 * @param[in] digits - Digit input
247 * @param[in] digitLen - digit length
248 * @Interface Synchronous.
252 static void _digit_to_bcd(char* bcdCode, char* digits, int digitLen)
255 unsigned char higher, lower;
257 // 0123456789 -> 1032547698
258 for (i = 0, j = 0; i < digitLen; i = i + 2, j++) {
259 if (digits[i] == '*')
261 else if (digits[i] == '#')
263 else if (toupper((int) digits[i]) == 'P')
265 else if ((digits[i]) == '?')
268 digit = (int) digits[i];
270 lower = digit & 0x0F;
272 if (digitLen != i + 1) {
273 if (digits[i + 1] == '*')
275 else if (digits[i + 1] == '#')
277 else if (toupper((int) digits[i + 1]) == 'P')
279 else if (digits[i + 1] == '?')
282 digit = (int) digits[i + 1];
283 higher = digit & 0x0F;
287 bcdCode[j] = (higher << 4) | lower;
292 * This function is used to Convert BCD to Digit (BCD to Digit)
295 * @param[out] digit - Digit output output
296 * @param[in] bcdCode - BCD Input
297 * @param[in] bcdLen - BCD length
298 * @Interface Synchronous.
302 static unsigned long _bcd_to_digit(char* digit, char* bcdCode, int bcdLen)
306 unsigned char higher, lower;
307 unsigned long digitLen = 0;
309 // 0123456789 <- 1032547698
310 memset((void*) digit, 0, bcdLen * 2);
312 for (i = 0; i < bcdLen; i++) {
313 higher = (bcdCode[i] >> 4) & 0x0F; // get high nibble
316 higher = '*'; // =0x2A
317 else if (higher == 0x0B)
318 higher = '#'; // =0x23
319 else if (higher == 0x0C)
320 higher = 'P'; // =0x70, DTMF Control digit
321 else if (higher == 0x0D)
323 else if (higher == 0x0F)
328 higher = (char) toupper(*c);
331 lower = bcdCode[i] & 0x0F; // get low nibble
335 else if (lower == 0x0B)
337 else if (lower == 0x0C)
338 lower = 'P'; //DTMF Control digit
339 else if (lower == 0x0D)
341 else if (lower == 0x0F)
346 lower = (char) toupper(*c);
348 digit[i * 2] = lower;
349 digit[i * 2 + 1] = higher;
352 digitLen = (unsigned long) strlen(digit);
357 * This function is used to get(decode) string name
359 * @return length of string
360 * @param[out] palpha_id - Alpha string
361 * @param[in] pRecord - Input raw data
362 * @param[in] alphaIDMaxLen - Max size of alpha id array
363 * @Interface Synchronous.
367 static unsigned long _get_string(unsigned char* palpha_id, unsigned char* pRecord, unsigned long alphaIDMaxLen)
369 unsigned long i, alphaIDLen = 0;
370 unsigned char *pAlphaID = (unsigned char*) palpha_id;
372 memset((void*) pAlphaID, 0, alphaIDMaxLen);
374 if (pRecord[0] == 0xFF)
377 for (i = 0; i < alphaIDMaxLen; i++) {
378 if (pRecord[0] <= 0x7F && pRecord[i] == 0xFF)
381 pAlphaID[i] = pRecord[i];
388 * This function is used to set(encode) string name
390 * @return length of string
391 * @param[in] palpha_id - Alpha string input
392 * @param[out] pRecord - output raw data
393 * @param[in] alphaIDMaxLen - Max size of alpha id array
394 * @Interface Synchronous.
398 static void _set_string(unsigned char* pRecord, unsigned char* palpha_id, unsigned long alphaIDMaxLen)
401 unsigned char* pAlphaID = (unsigned char*) palpha_id;
403 memset((void*) pRecord, 0xFF, alphaIDMaxLen);
405 for (i = 0; i < alphaIDMaxLen; i++)
406 pRecord[i] = pAlphaID[i];
409 static gboolean _is_empty(unsigned char* p_in, int in_length)
412 for (i = 0; i < in_length; i++) {
416 dbg("current index has empty data");
417 return TRUE; // this is empty record.
421 * This function is used to get BCD length
423 * @return length of string
424 * @param[in] pBcdData - BCD Input data
425 * @param[in] bcdMaxLen - BCD Max data Length
426 * @Interface Synchronous.
430 static int _get_valid_bcd_byte(unsigned char* pBcdData, int bcdMaxLen)
432 int i, bcd_length = 0;
434 for (i = 0; i < bcdMaxLen; i++) {
435 if (pBcdData[i] == 0xFF)
444 * This function is used to get unpacked 8bit Format from GSM 7bit packed string.
446 * @return the length of unpacked characters .
447 * @param[out] out_string Specifies the unpacked output string
448 * @param[in] in_string Contains the input string to be unpacked
449 * @param[in] in_string_len Contains the input string length
452 static int _unpack_7bit28bit(unsigned char* pInString, unsigned int inStringLen, unsigned char * pOutString)
455 unsigned int pos = 0;
456 unsigned short shift = 0;
458 outlen = (short int) ((inStringLen * 8) / 7);
460 for (i = 0; pos < inStringLen; i++, pos++) {
461 pOutString[i] = (pInString[pos] << shift) & 0x7F;
464 /* except the first byte, a character contains some bits from the previous byte.*/
465 pOutString[i] |= pInString[pos - 1] >> (8 - shift);
473 /* a possible extra complete character is available */
475 pOutString[i] = pInString[pos] >> 1;
479 /*If a character is '\r'(13), change it to space(32) */
480 for (i = 0; i < outlen; i++)
481 if (pOutString[i] == 13) pOutString[i] = 32;
483 pOutString[outlen] = '\0';
485 dbg( "unpack is done with outlen[%d] and array index[%d], out string[%s]", outlen, i, pOutString);
486 return (unsigned int) (i);
489 static int _ucs2_to_utf8(int in_length, unsigned char *in_data, int *out_length, unsigned char *out_data)
493 if (in_length == 0 || in_data == NULL || out_data == NULL) {
494 dbg( "Unicode Decode Failed as text length is 0");
498 if (0 != (in_length % 2)) {
499 dbg( " ##### Unicode decoding failed due to invalid text length [%d]", in_length);
503 for (i = 0; i < in_length; i++) {
504 out_data[i] = in_data[j];
507 *out_length = (in_length / 2);
513 * According to ETSI 102.221 ( 3GPP specification refers it ), EF-ICCID is coded by BCD, left justified and padded with 'F'.
514 * This EF is mandatory and byte length is fixed with 10 bytes. So actual maximum length of ICCID is 20 digits.
516 gboolean tcore_sim_decode_iccid(struct tel_sim_iccid *p_out, unsigned char *p_in, int in_length)
521 if (p_in == NULL || p_out == NULL)
524 if (in_length == 0 || in_length > 10)
527 memset((void*) p_out->iccid, 0, SIM_ICCID_LEN_MAX+1);
529 bcd_byte = _get_valid_bcd_byte(p_in, in_length);
530 dbg( "ICCID valid bcd byte is[%d]", bcd_byte);
532 char_length = _bcd_to_digit(p_out->iccid, (char*) p_in, bcd_byte);
533 dbg( "ICCID string length is[%d]", char_length);
535 *(p_out->iccid+char_length) = '\0';
541 * This function is used to decode EFLP (2G)
543 gboolean tcore_sim_decode_lp(struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
547 memset((void*) p_out, 0xFF, sizeof(struct tel_sim_language));
548 p_out->language_count = 0;
553 * Description of problem: language decoding was not correctly done if we used 7layers's test SIM
554 * Patch Description : The tested SIM at 7layers has 3 language codes like [ff][ff][01].
555 In this case we could not decode 3rd language code.
556 So, the below 2 lines checking the UNSPECIFIED language are commented.
559 if (in_length > SIM_LANG_CNT_MAX)
560 in_length = SIM_LANG_CNT_MAX;
562 for (i = 0; i < in_length; i++) {
564 * Description of problem: Language decoding was not correctly done if we used some test SIM
565 * Patch Description : Test SIM at some place has 3 language codes like [ff][ff][01].
566 * In this case we could not decode 3rd language code.
567 * So, the below 2 lines checking the UNSPECIFIED language are commented.
572 p_out->language[p_out->language_count] = (enum tel_sim_language_type) p_in[i];
573 dbg( "p_out->language[%d]=[%d] ", i, p_out->language[p_out->language_count]);
574 p_out->language_count++;
576 dbg( "in_length %d, lang_cnt %d ", in_length, p_out->language_count);
581 * This function is used to encode EFLP (2G)
583 char* tcore_sim_encode_lp( int *out_length, struct tel_sim_language *p_in)
586 char *tmp_out = NULL;
588 if ( out_length == NULL || p_in == NULL ){
589 dbg("out_length or p_in is null");
593 tmp_out = (char*)malloc(p_in->language_count);
594 memset((void*) tmp_out, 0xff, p_in->language_count);
596 for (i = 0; i < p_in->language_count; i++)
597 tmp_out[i] = p_in->language[i];
604 * This function is used to decode LI (3G)
606 gboolean tcore_sim_decode_li(enum tel_sim_file_id file_id, struct tel_sim_language *p_out, unsigned char *p_in, int in_length)
609 unsigned short defaultLi;
610 unsigned char tempLi[3] = { 0, 0, 0 };
612 memset((void*) p_out, 0xFF, sizeof(struct tel_sim_language));
613 p_out->language_count = 0;
619 * Description of problem: language decoding was not correctly done if we used 7layers's test SIM
620 * Patch Description : TS31.102 If the EFLI has the value 'FFFF' in its highest priority position,
621 then the preferred language selection shall be the language preference in the EFPL
623 if (/*TODO g_sim.CardType == SIM_TYPE_USIM && */(file_id == SIM_EF_USIM_LI || file_id == SIM_EF_LP)) {
625 defaultLi = ((defaultLi << 8) & 0xFF00) + p_in[1];
627 if (defaultLi == 0xFFFF) // 1st language is default.
631 if (in_length > SIM_LANG_CNT_MAX)
632 in_length = SIM_LANG_CNT_MAX;
634 for (i = 0; i < in_length; i++) {
635 tempLi[0] = p_in[i++];
638 Description of problem: language decoding was not correctly done if we used 7layers's test SIM
639 Patch Description : The tested SIM at specific test lab has 3 language codes like [ff][ff][ff][ff][64][65].
640 In this case we could not decode 3rd language code.
641 So, the below 2 lines checking the UNSPECIFIED language are commented.
643 if (tempLi[0] == 0xFF || tempLi[1] == 0xFF) //this is always 2 bytes
646 p_out->language[p_out->language_count] = SIM_LANG_UNSPECIFIED;
648 if (tempLi[0] == 'e') {
651 p_out->language[p_out->language_count] = SIM_LANG_ENGLISH;
654 p_out->language[p_out->language_count] = SIM_LANG_SPANISH;
657 p_out->language[p_out->language_count] = SIM_LANG_GREEK;
660 } else if (tempLi[0] == 'd') {
663 p_out->language[p_out->language_count] = SIM_LANG_GERMAN;
667 p_out->language[p_out->language_count] = SIM_LANG_DANISH;
670 } else if (tempLi[0] == 'i' && tempLi[1] == 't') {
671 p_out->language[p_out->language_count] = SIM_LANG_ITALIAN;
672 } else if (tempLi[0] == 'f' && tempLi[1] == 'r') {
673 p_out->language[p_out->language_count] = SIM_LANG_FRENCH;
674 } else if (tempLi[0] == 'n' && tempLi[1] == 'l') {
675 p_out->language[p_out->language_count] = SIM_LANG_DUTCH;
676 } else if (tempLi[0] == 's' && tempLi[1] == 'v') {
677 p_out->language[p_out->language_count] = SIM_LANG_SWEDISH;
678 } else if (tempLi[0] == 'f' && tempLi[1] == 'i') {
679 p_out->language[p_out->language_count] = SIM_LANG_FINNISH;
680 } else if (tempLi[0] == 'n' && tempLi[1] == 'o') {
681 p_out->language[p_out->language_count] = SIM_LANG_NORWEGIAN;
682 } else if (tempLi[0] == 't' && tempLi[1] == 'r') {
683 p_out->language[p_out->language_count] = SIM_LANG_TURKISH;
684 } else if (tempLi[0] == 'h' && tempLi[1] == 'u') {
685 p_out->language[p_out->language_count] = SIM_LANG_HUNGARIAN;
686 } else if (tempLi[0] == 'p') {
689 p_out->language[p_out->language_count] = SIM_LANG_POLISH;
692 p_out->language[p_out->language_count] = SIM_LANG_PORTUGUESE;
695 } else if (tempLi[0] == 'k' && tempLi[1] == 'o') {
696 p_out->language[p_out->language_count] = SIM_LANG_KOREAN;
697 } else if (tempLi[0] == 'z' && tempLi[1] == 'h') {
698 p_out->language[p_out->language_count] = SIM_LANG_CHINESE;
699 } else if (tempLi[0] == 'r' && tempLi[1] == 'u') {
700 p_out->language[p_out->language_count] = SIM_LANG_RUSSIAN;
701 } else if (tempLi[0] == 'j' && tempLi[1] == 'a') {
702 p_out->language[p_out->language_count] = SIM_LANG_JAPANESE;
705 dbg( "count %d & Codes %d ", p_out->language_count, p_out->language[p_out->language_count]);
706 p_out->language_count++;
709 if (p_out->language_count == 0) {
710 dbg( "p_out->language_count = %d ", p_out->language_count);
719 * This function is used to encode EFLI (3G)
721 char* tcore_sim_encode_li( int *out_length, struct tel_sim_language *p_in)
724 char *tmp_out = NULL;
725 char *LanguageCode[] = { "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el",
726 "tr", "hu", "pl", "ko", "zh", "ru", "ja" };
728 if ( out_length == NULL || p_in == NULL ){
729 dbg("out_length or p_in is null");
733 tmp_out = (char*)malloc((p_in->language_count) *2);
734 memset((void*) tmp_out, 0xff, (p_in->language_count)*2);
736 for (i = 0; i < p_in->language_count; i++) {
737 if (p_in->language[i] < SIM_LANG_UNSPECIFIED) {
738 strncpy((char *) &tmp_out[i * 2], LanguageCode[p_in->language[i]], 2);
739 dbg( "sim_encode_li: p_out[%s]:[%x][%x]", tmp_out, tmp_out[i*2], tmp_out[(i*2)+1]);
746 gboolean tcore_sim_decode_imsi(struct tel_sim_imsi *p_out, unsigned char *p_in, int in_length)
751 dbg( "Func Entrance");
753 if ((NULL == p_out) || (NULL == p_in))
757 According to 3GPP specification, the length of raw IMSI data is 9 bytes.
758 first byte is length of IMSI
759 second byte byte has parity nibble, so second byte has one digit of IMSI. other byte has two digit of IMSI
761 if ((in_length == 0) || (in_length == 0xff) || (4 > in_length) || (9 <in_length)) {
762 dbg("No valid IMSI present to convert - length:[%x]", in_length);
765 dbg("imsi length[%d], input data length[%d]", p_in[0], in_length);
767 /* Decode IMSI value from nibbles */
768 for (i = 1; i < in_length; i++) {
769 if (i == 1) { /* first byte, ignore lower nibble */
770 imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
771 } else if (i == p_in[0]+1) { /* last byte */
772 imsi_raw[j++] = (p_in[i] & 0x0F)+ '0';
773 if (p_in[0]%2) /* count the last one if odd digits */
774 imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
776 imsi_raw[j++] = (p_in[i] & 0x0F) + '0';
777 imsi_raw[j++] = ((p_in[i] & 0xF0) >> 4) + '0';
780 /* Terminate string */
782 dbg("imsi_raw[%s], size[%d]", imsi_raw, strlen(imsi_raw));
784 memcpy(p_out->plmn, imsi_raw, 5);
785 p_out->plmn[5] = '\0';
786 memcpy(p_out->msin, imsi_raw+5, strlen(imsi_raw)-5);
787 p_out->msin[strlen(imsi_raw)-5] = '\0';
789 dbg("p_out->plmn[%s], p_out->msin[%s]", p_out->plmn, p_out->msin);
794 gboolean tcore_sim_decode_sst(struct tel_sim_sst *p_sst, unsigned char *p_in, int in_length)
796 unsigned char sstByte, rast, mask = 0;
797 char simServiceID = 1; // set "CHV1 disable function"
801 memset((void*)p_sst, 0, sizeof(struct tel_sim_sst));
803 if (in_length == 0 || in_length > SIM_SST_LEN_MAX)
806 // get count of SIM service id. one byte has four service status.
807 svc_count = in_length * 4;
809 /*3GPP 11.11 SST shows 50 kinds of service types. current sim_ss_s has also 50 elements*/
810 if (svc_count > SIM_SST_SERVICE_CNT_MAX)
811 svc_count = SIM_SST_SERVICE_CNT_MAX;
813 p_index = (char*)p_sst;
815 for (i = 0; i < svc_count; i++) {
816 sstByte = p_in[(simServiceID - 1) / 4];
817 rast = simServiceID - 4 * (simServiceID / 4);
839 p_index += sizeof(char);
840 simServiceID++; // next service id
845 gboolean tcore_sim_decode_spn(struct tel_sim_spn *p_spn, unsigned char *p_in, int in_length)
852 p_spn->display_condition = p_in[0];
853 dbg( "The display condition is [%d]", p_spn->display_condition);
855 for (i = 1; i < SIM_SPN_LEN_MAX + 1; i++) {
857 break; /* loop break*/
859 p_spn->spn[i - 1] = p_in[i];
860 dbg( "EF-SPN name[%d][%c]", i, p_in[i]);
862 p_spn->spn[i-1] = '\0';
867 gboolean tcore_sim_decode_spdi(struct tel_sim_spdi *p_spdi, unsigned char *p_in, int in_length)
869 int i, Src_plmn_start_len, total_data_len;
875 dbg("file is exist but there is no valid records");
876 p_spdi->plmn_count = 0;
877 memset(p_spdi->list, 0x00, sizeof(unsigned char)*7*SIM_SPDI_PLMN_MAX);
881 //Display info tag('A3')
882 if (p_in[0] == 0xA3) {
883 total_data_len = p_in[1];
884 //PLMN list tag('80')
885 if (p_in[2] == 0x80) {
886 p_spdi->plmn_count = p_in[3] / 3;
891 * each plmn entry 3byte
893 if (p_spdi->plmn_count > SIM_SPDI_PLMN_MAX)
894 p_spdi->plmn_count = SIM_SPDI_PLMN_MAX;
896 Src_plmn_start_len = 4;
898 dbg( "p_spdi->num_of_plmn_entries[%d]", p_spdi->plmn_count);
900 for (i = 0; i < p_spdi->plmn_count; i++) {
901 unsigned char packetInDigit[3 * 2 + 1];
902 _bcd_to_digit((char*) packetInDigit, (char*) &p_in[Src_plmn_start_len], 3);
903 // get MCC (mobile country code)
904 memcpy(p_spdi->list[i].plmn, &(packetInDigit[0]), 6);
905 p_spdi->list[i].plmn[6] = '\0';
906 dbg( "SPDI PLMN[%d][%s]", i, p_spdi->list[i].plmn);
908 Src_plmn_start_len = Src_plmn_start_len + 3;
912 dbg("Current EF-SPDI has invalid data");
915 dbg("Current EF-SPDI has invalid data");
919 gboolean tcore_sim_decode_msisdn(struct tel_sim_msisdn *p_msisdn, unsigned char *p_in, int in_length)
921 int X; // alpha id max length
923 int bcd_byte; // dialing number max length
925 memset((void*) p_msisdn, 0, sizeof(struct tel_sim_msisdn));
930 if (_is_empty(p_in, in_length) == TRUE) {
931 memset(p_msisdn, 0, sizeof(struct tel_sim_msisdn));
935 X = in_length - 14; // get alpha id max length
938 value_length = _get_string((unsigned char *)p_msisdn->name, p_in, X);
939 p_msisdn->name[value_length] = '\0';
942 // get dialing number length
943 // p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes.
944 // Convert to digit length and subtract TON/NPI length.
945 if (p_in[X] != 0xFF) {
946 dbg( "Dialing number Length %d, BCD length 0x%x ", (p_in[X] - 1) * 2, p_in[X]);
949 p_msisdn->ton = (p_in[X + 1] >> 4) & 0x07;
951 // get actual dialing number length
952 bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
953 dbg( "bcd_byte[%x]", bcd_byte);
955 // get dialing number/SSC string
956 value_length = _bcd_to_digit((char*) p_msisdn->num, (char*) &p_in[X + 2], bcd_byte); // actual dialing number length in BCD.
957 p_msisdn->num[value_length] = '\0';
958 dbg( "p_msisdn->num[%s]", p_msisdn->num);
963 gboolean tcore_sim_decode_xdn(struct tel_sim_dialing_number *p_xdn, unsigned char *p_in, int in_length)
965 int X; // alpha id max length
966 int bcd_byte; // dialing number max length
968 memset((void*) p_xdn, 0, sizeof(struct tel_sim_dialing_number));
973 if (_is_empty(p_in, in_length) == TRUE) {
974 return FALSE; // this is empty record
977 X = in_length - 14; // get alpha id max length
980 p_xdn->AlphaIdLength = _get_string((unsigned char *)p_xdn->AlphaId, p_in, X);
981 p_xdn->AlphaIDMaxLength = X;
984 // get dialing number length
985 // p_in[X] is BCD length of dialing number length plus TON/NPI 1 bytes.
986 // Convert to digit length and subtract TON/NPI length.
987 if (p_in[X] != 0xFF) {
988 p_xdn->DiallingNumMaxLength = (p_in[X] - 1) * 2;
989 dbg( "Dialing number Length %d, BCD length 0x%x ", p_xdn->DiallingNumMaxLength, p_in[X]);
991 if (p_xdn->DiallingNumMaxLength > SIM_XDN_NUMBER_LEN_MAX) {
993 this may be broken record.
994 p_xdn->b_used = FALSE;
995 memset((void*)p_xdn, 0, sizeof(tapi_sim_dialing_number_info_t));
998 ADN record cannot have more than 20 digits. Anyway we can restrict this as per 31.102
999 X+1 Length of BCD number/SSC contents M 1 byte
1000 X+2 TON and NPI M 1 byte
1001 X+3 to X+12 Dialing Number/SSC String M 10 bytes
1002 X+13 Capability/Configuration1 Identifier M 1 byte
1003 X+14 Extension1 Record Identifier M 1 byte
1005 Anyway we are doing this check @
1006 bcd_byte = _get_valid_bcd_byte (&p_in[X+2], TAPI_SIM_XDN_DIALING_NUMBER_LEN/2);
1007 by using the 20/2; so don`t return false.
1009 if (p_in[X] == 0x00)
1010 p_xdn->DiallingNumMaxLength = 0;
1012 p_xdn->DiallingNumMaxLength = SIM_XDN_NUMBER_LEN_MAX;
1016 p_xdn->TypeOfNumber = (p_in[X + 1] >> 4) & 0x07;
1017 p_xdn->NumberingPlanIdent = p_in[X + 1] & 0x0F;
1019 // get actual dialing number length
1020 bcd_byte = _get_valid_bcd_byte(&p_in[X + 2], SIM_XDN_NUMBER_LEN_MAX / 2);
1021 dbg( "bcd_byte[%x]", bcd_byte);
1023 // get dialing number/SSC string
1024 p_xdn->DiallingnumLength = _bcd_to_digit((char*) p_xdn->DiallingNum, (char*) &p_in[X + 2], bcd_byte); // actual dialing number length in BCD.
1025 dbg( "p_xdn->DiallingnumLength[%x]", p_xdn->DiallingnumLength);
1026 dbg( "p_xdn->DiallingNum[%s]", p_xdn->DiallingNum);
1027 // get Capability/Configuration id
1028 p_xdn->CapaConfigId = p_in[X + 12];
1029 // get Extension1 id
1030 p_xdn->Ext1RecordId = p_in[X + 13];
1035 gboolean tcore_sim_encode_xdn(char *p_out, int out_length, struct tel_sim_dialing_number *p_xdn)
1038 char bcdCode[SIM_XDN_NUMBER_LEN_MAX / 2];
1040 memset((void*) p_out, 0xFF, out_length);
1042 X = out_length - 14; // get alpha id max length
1044 if (X < p_xdn->AlphaIdLength)
1045 return FALSE; // alpha id is too big
1047 if (p_xdn->DiallingnumLength > SIM_XDN_NUMBER_LEN_MAX) // this is digit length
1048 return FALSE; // dialing number is too big
1050 _set_string((unsigned char *)p_out, (unsigned char *)p_xdn->AlphaId, p_xdn->AlphaIdLength);
1052 // set length of BCD number/SSC contents
1053 // p_xdn->diallingnumLen is maximum digit length. = 20 bytes.
1054 // convert to BCD length and add 1 byte.
1055 p_out[X] = ((p_xdn->DiallingnumLength + 1) / 2) + 1;
1058 p_out[X + 1] = 0x80;
1059 p_out[X + 1] |= (p_xdn->TypeOfNumber & 0x07) << 4;
1060 p_out[X + 1] |= p_xdn->NumberingPlanIdent & 0x0F;
1062 // set dialing number/SSC string
1063 memset((void*) bcdCode, 0xFF, SIM_XDN_NUMBER_LEN_MAX / 2);
1065 _digit_to_bcd((char*) bcdCode, (char*) p_xdn->DiallingNum, p_xdn->DiallingnumLength);
1067 memcpy((void*) &p_out[X + 2], bcdCode, SIM_XDN_NUMBER_LEN_MAX / 2);
1069 // set Capability/Configuration Identifier
1070 p_out[X + 12] = (unsigned char) p_xdn->CapaConfigId;
1071 // set extension1 record Identifier
1072 p_out[X + 13] = (unsigned char) p_xdn->Ext1RecordId;
1077 gboolean tcore_sim_decode_ecc(struct tel_sim_ecc_list *p_ecc, unsigned char *p_in, int in_length)
1079 int bcd_byte; // dialing number max length
1081 int valid_ecc_length;
1082 memset((void*)p_ecc, 0x00, sizeof(struct tel_sim_ecc_list));
1084 if(in_length%3 != 0) {
1085 dbg("error - invalid data length");
1089 for(i=0; i < in_length/3; i++){
1090 //get the BCD length of the ECC
1091 bcd_byte = _get_valid_bcd_byte((unsigned char*) p_in+(i*3), 3);
1093 valid_ecc_length = _bcd_to_digit(p_ecc->ecc[p_ecc->ecc_count].ecc_num, (char *)p_in+(i*3), bcd_byte);
1094 p_ecc->ecc[p_ecc->ecc_count].ecc_num[valid_ecc_length] = '\0';
1101 gboolean tcore_sim_decode_ust(struct tel_sim_ust *p_ust, unsigned char *p_in, int in_length)
1106 memset((void*) p_ust, 0, sizeof(struct tel_sim_ust));
1107 p_index = (char*)p_ust;
1109 /* UST service is described to 74(1 byte includes 8 service status) in 31.102 r7.
1110 current sim_ust_s has 64 services. so in_length should be under 8 byte. */
1111 if (in_length > SIM_UST_BYTE_LEN_MAX)
1112 in_length = SIM_UST_BYTE_LEN_MAX;
1114 for (i = 0; i < in_length; i++) {
1115 mask = 0x01; // reset mast to check first bit
1117 for (j = 0; j < 8; j++) {
1118 if (p_in[i] & mask) {
1121 p_index += sizeof(char);
1128 gboolean tcore_sim_decode_est(struct tel_sim_est *p_est, unsigned char *p_in, int in_length)
1130 memset((void*) p_est, 0, sizeof(struct tel_sim_est));
1133 p_est->bFdnEnabled = TRUE;
1135 p_est->bBdnEnabled = TRUE;
1137 p_est->bAclEnabled = TRUE;
1142 gboolean tcore_sim_decode_uecc(struct tel_sim_ecc *p_ecc, unsigned char* p_in, int in_length)
1144 int bcd_byte; // dialing number max length
1145 unsigned char eccServiceCategory;
1147 if (_is_empty(p_in, in_length) == TRUE) {
1148 memset(p_ecc, 0, sizeof(struct tel_sim_ecc));
1152 //get the BCD length of the ECC
1153 bcd_byte = _get_valid_bcd_byte(&p_in[0], SIM_ECC_BYTE_LEN_MAX);
1155 //get the ECC codes in digits and the length as well
1156 _bcd_to_digit((char*) p_ecc->ecc_num, (char*) &p_in[0], bcd_byte);
1158 //get the alpha identifier of ECC (
1159 _get_string((unsigned char*) p_ecc->ecc_string, (unsigned char*) &p_in[3], in_length - 3);
1161 eccServiceCategory = p_in[in_length - 1] & 0x1F; // Check for the first 5 bits
1164 Assign the service category
1165 3GPP TS24.008 Emergency Service Category Value.
1166 Bit 8,7,6 are spare, 5~1 bit is used.
1167 The meaning of the Emergency Category Value is derived from the following settings
1168 (see 3GPP TS 22.101 clause 10):
1170 Bit 2 Ambulance 0x02
1171 Bit 3 Fire Brigade 0x04
1172 Bit 4 Marine Guard 0x08
1173 Bit 5 Mountain Rescue 0x10
1174 Bit 6 manually initiated eCall
1175 Bit 7 automatically initiated eCall
1176 Bit 8 is spare and set to "0"
1178 switch (eccServiceCategory) {
1180 p_ecc->ecc_category = SIM_ECC_POLICE;
1183 p_ecc->ecc_category = SIM_ECC_AMBULANCE;
1186 p_ecc->ecc_category = SIM_ECC_FIREBRIGADE;
1189 p_ecc->ecc_category = SIM_ECC_MARAINEGUARD;
1192 p_ecc->ecc_category = SIM_ECC_MOUTAINRESCUE;
1195 p_ecc->ecc_category = SIM_ECC_SPARE;
1201 gboolean tcore_sim_decode_gid( struct tel_sim_gid *p_gid, unsigned char* p_in, int in_length)
1205 memset((void*) p_gid, 0, sizeof(struct tel_sim_gid ));
1210 /*regarding 31.102, EF-GID data byte is not defined. currently 10.*/
1211 if (in_length >= SIM_GROUP_IDENTIFIER_LEN_MAX)
1212 in_length = SIM_GROUP_IDENTIFIER_LEN_MAX;
1214 for (i = 0; i < in_length; i++) {
1215 if (p_in[i] == 0xFF)
1218 p_gid->szGroupIdentifier[i] = p_in[i];
1219 p_gid->GroupIdentifierLen++;
1224 gboolean tcore_sim_decode_mbi(struct tel_sim_mbi *p_mbi, unsigned char *p_in, int in_length)
1227 for (i = 0; i < in_length; i++) {
1228 dbg( " \t0x%04X.", p_in[i]);
1231 /* EF-MBI is defined 4 mandatory, 1 optional byte in 31.102 */
1232 if (in_length == 0 || in_length > SIM_MAIL_BOX_IDENTIFIER_LEN_MAX)
1235 if ( _is_empty(p_in, in_length) == TRUE) {
1236 return FALSE; // this is empty record
1239 p_mbi->VoiceMailBoxIdentifier = p_in[0];
1240 p_mbi->FaxMailBoxIdentifier = p_in[1];
1241 p_mbi->EmailMailBoxIdentifier = p_in[2];
1242 p_mbi->OtherMailBoxIdentifier = p_in[3];
1244 // 5th byte is optional
1246 p_mbi->VideoMailBoxIdentifier = p_in[4];
1251 gboolean tcore_sim_encode_mbi(char *p_out, int out_length, struct tel_sim_mbi *p_mbi)
1253 p_out[0] = p_mbi->VoiceMailBoxIdentifier;
1254 p_out[1] = p_mbi->FaxMailBoxIdentifier;
1255 p_out[2] = p_mbi->EmailMailBoxIdentifier;
1256 p_out[3] = p_mbi->OtherMailBoxIdentifier;
1258 if (out_length == 5)
1259 p_out[4] = p_mbi->VideoMailBoxIdentifier;
1264 gboolean tcore_sim_decode_cff(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length)
1266 struct tel_sim_cphs_cf p_cff = {0,};
1271 dbg( "flag(0)=%x, packetlen=%d ", (unsigned int)p_in[0], in_length);
1272 dbg( "flag(1)=%x", p_in[1]);
1274 if ((p_in[0] & 0x0F) == 0x0A) {
1275 p_cff.bCallForwardUnconditionalLine1 = TRUE;
1276 cfis->voice1 = TRUE;
1278 if ((p_in[0] & 0xF0) == 0xA0) {
1279 p_cff.bCallForwardUnconditionalLine2 = TRUE;
1280 cfis->voice2 = TRUE;
1283 if (in_length > 1) {
1284 if ((p_in[1] & 0x0F) == 0x0A) {
1285 p_cff.bCallForwardUnconditionalFax = TRUE;
1288 if ((p_in[1] & 0xF0) == 0xA0) {
1289 p_cff.bCallForwardUnconditionalData = TRUE;
1294 dbg("Line1 = %d, line2 = %d, Fax = %d, Data = %d ",
1295 p_cff.bCallForwardUnconditionalLine1,
1296 p_cff.bCallForwardUnconditionalLine2,
1297 p_cff.bCallForwardUnconditionalFax,
1298 p_cff.bCallForwardUnconditionalData);
1302 char* tcore_sim_encode_cff(const struct tel_sim_callforwarding *cff)
1306 unsigned char* pTemp = (unsigned char*) cff;
1307 unsigned char present = 0x0A;
1308 unsigned char absent = 0x05;
1310 p_out = calloc(SIM_CPHS_CALL_FORWARDING_LEN_MAX+1, 1);
1312 for (i = 0; i < SIM_CPHS_CALL_FORWARDING_LEN_MAX; i++) {
1316 for (j = 0; j < 2; j++) {
1318 p_out[i] = p_out[i] | present;
1320 p_out[i] = p_out[i] | absent;
1322 pTemp += sizeof(gboolean);
1323 present = present << 4;
1324 absent = absent << 4;
1327 p_out[SIM_CPHS_CALL_FORWARDING_LEN_MAX] = '\0';
1331 gboolean tcore_sim_decode_csp(struct tel_sim_cphs_csp *p_csp, unsigned char *p_in, int in_length)
1334 unsigned char byteSignificance = 0x00;
1335 unsigned char mask = 0x80;
1340 memset((void*) p_csp, 0, sizeof(struct tel_sim_cphs_csp));
1342 /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional. */
1343 for (i = 0, j = 0; i < SIM_CPHS_CSP_LEN_MAX || j < SIM_CPHS_CSP_LEN_MAX; i++, j++) {
1344 p_csp->ServiceProfileEntry[j].CustomerServiceGroup = (enum tel_sim_cphs_csp_group) p_in[i];
1345 byteSignificance = p_in[++i];
1348 switch (p_csp->ServiceProfileEntry[j].CustomerServiceGroup) {
1350 for (k = 0; k < 5; k++) {
1351 switch (byteSignificance & mask) {
1353 p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingUnconditional = TRUE;
1356 p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserBusy = TRUE;
1359 p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnNoReply = TRUE;
1362 p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserNotReachable = TRUE;
1365 p_csp->ServiceProfileEntry[j].u.CallOffering.bCallTransfer = TRUE;
1375 for (k = 0; k < 5; k++) {
1376 switch (byteSignificance & mask) {
1378 p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllOutgoingCalls = TRUE;
1381 p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCalls = TRUE;
1384 p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCallsExceptHplmn = TRUE;
1387 p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllIncomingCallsRoamingOutsideHplmn = TRUE;
1390 p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfIncomingCallsWhenRoaming = TRUE;
1400 for (k = 0; k < 5; k++) {
1401 switch (byteSignificance & mask) {
1403 p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bMultiPartyService = TRUE;
1406 p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroup = TRUE;
1409 p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bAdviceOfCharge = TRUE;
1412 p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bPreferentialClosedUserGroup = TRUE;
1415 p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroupOutgoingAccess = TRUE;
1425 for (k = 0; k < 4; k++) {
1426 switch (byteSignificance & mask) {
1428 p_csp->ServiceProfileEntry[j].u.CallComplete.bCallHold = TRUE;
1431 p_csp->ServiceProfileEntry[j].u.CallComplete.bCallWaiting = TRUE;
1434 p_csp->ServiceProfileEntry[j].u.CallComplete.bCompletionOfCallToBusySubscriber = TRUE;
1437 p_csp->ServiceProfileEntry[j].u.CallComplete.bUserUserSignalling = TRUE;
1447 for (k = 0; k < 7; k++) {
1448 switch (byteSignificance & mask) {
1450 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileTerminated = TRUE;
1453 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileOriginated = TRUE;
1456 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageCellBroadcast = TRUE;
1459 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageReplyPath = TRUE;
1462 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageDeliveryConf = TRUE;
1465 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageProtocolIdentifier = TRUE;
1468 p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageValidityPeriod = TRUE;
1478 for (k = 0; k < 1; k++) {
1479 switch (byteSignificance & mask) {
1481 p_csp->ServiceProfileEntry[j].u.CphsTeleservices.bAlternativeLineService = TRUE;
1491 for (k = 0; k < 1; k++) {
1492 switch (byteSignificance & mask) {
1494 p_csp->ServiceProfileEntry[j].u.CphsFeatures.bStringServiceTable = TRUE;
1504 for (k = 0; k < 8; k++) {
1505 switch (byteSignificance & mask) {
1507 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationPresent = TRUE;
1510 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationRestrict = TRUE;
1513 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationPresent = TRUE;
1516 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bMaliciousCallIdentifier = TRUE;
1519 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationSend = TRUE;
1522 p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationBlock = TRUE;
1532 for (k = 0; k < 6; k++) {
1533 switch (byteSignificance & mask) {
1535 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForGprs = TRUE;
1538 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForHighSpeedCsd = TRUE;
1541 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceGroupCall = TRUE;
1544 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceBroadcastService = TRUE;
1547 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleSubscriberProfile = TRUE;
1550 p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleBand = TRUE;
1560 for (k = 0; k < 8; k++) {
1561 switch (byteSignificance & mask) {
1563 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForManualSelection = TRUE;
1566 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForVoiceMail = TRUE;
1569 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsAndPaging = TRUE;
1572 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsWithEmialType = TRUE;
1575 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForFaxCalls = TRUE;
1578 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForDataCalls = TRUE;
1581 p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForChangeLanguage = TRUE;
1591 for (k = 0; k < 8; k++) {
1592 switch (byteSignificance & mask) {
1601 p_csp->ServiceProfileEntry[j].u.InformationNumbers.bInformationNumbers = TRUE;
1617 gboolean tcore_sim_encode_csp(unsigned char *p_out, int out_length, struct tel_sim_cphs_csp *p_csp)
1619 unsigned char i, j = 0;
1621 if (out_length == 0)
1624 memset((void*) p_out, 0xFF, out_length);
1626 /* current telephony supports 22 byte cphs-csp data. 18 byte is mandatory, the other is optional.*/
1627 for (i = 0, j = 0; i < 22 || j < 22; i++, j++) {
1628 p_out[i] = (unsigned char) p_csp->ServiceProfileEntry[j].CustomerServiceGroup;
1631 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingUnconditional) << 7)
1632 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserBusy) << 6)
1633 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnNoReply) << 5)
1634 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallForwardingOnUserNotReachable) << 4)
1635 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallOffering.bCallTransfer) << 3);
1639 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllOutgoingCalls) << 7)
1640 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCalls) << 6)
1641 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfOutgoingInternationalCallsExceptHplmn) << 5)
1642 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfAllIncomingCallsRoamingOutsideHplmn) << 4)
1643 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallRestriction.bBarringOfIncomingCallsWhenRoaming) << 3);
1647 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bMultiPartyService) << 7)
1648 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroup) << 6)
1649 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bAdviceOfCharge) << 5)
1650 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bPreferentialClosedUserGroup) << 4)
1651 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.OtherSuppServices.bClosedUserGroupOutgoingAccess) << 3);
1655 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCallHold) << 7)
1656 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCallWaiting) << 6)
1657 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bCompletionOfCallToBusySubscriber) << 5)
1658 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.CallComplete.bUserUserSignalling) << 4);
1662 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileTerminated) << 7)
1663 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageMobileOriginated) << 6)
1664 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageCellBroadcast) << 5)
1665 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageReplyPath) << 4)
1666 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageDeliveryConf) << 3)
1667 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageProtocolIdentifier) << 2)
1668 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.Teleservices.bShortMessageValidityPeriod) << 1);
1672 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CphsTeleservices.bAlternativeLineService) << 7);
1676 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.CphsFeatures.bStringServiceTable) << 7);
1680 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationPresent) << 7)
1681 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationRestrict) << 5)
1682 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bConnectedLineIdentificationPresent) << 4)
1683 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bMaliciousCallIdentifier) << 3)
1684 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationSend) << 1)
1685 + ((unsigned char) p_csp->ServiceProfileEntry[j].u.NumberIdentifiers.bCallingLineIdentificationBlock);
1689 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForGprs) << 7)
1690 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForHighSpeedCsd) << 6)
1691 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceGroupCall) << 5)
1692 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForVoiceBroadcastService) << 4)
1693 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleSubscriberProfile) << 3)
1694 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.PhaseServices.bMenuForMultipleBand) << 2);
1698 p_out[++i] = (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForManualSelection) << 7)
1699 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForVoiceMail) << 6)
1700 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsAndPaging) << 5)
1701 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForMoSmsWithEmialType) << 4)
1702 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForFaxCalls) << 3)
1703 + (((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForDataCalls) << 2)
1704 + ((unsigned char) p_csp->ServiceProfileEntry[j].u.ValueAddedServices.bRestrictMenuForChangeLanguage);
1708 if (p_csp->ServiceProfileEntry[j].u.InformationNumbers.bInformationNumbers)
1721 gboolean tcore_sim_decode_vmwf(struct tel_sim_cphs_mw *p_vmwf, unsigned char* p_in, unsigned long in_length)
1724 unsigned char* pTemp = (unsigned char*) p_vmwf;
1725 unsigned char mask = 0x0F;
1726 unsigned char voiceMsgFlg = 0;
1731 /* current telephony supports 2 byte cphs-vmwf data*/
1732 for (i = 0; i < SIM_CPHS_VMWF_LEN_MAX; i++) {
1733 voiceMsgFlg = p_in[i];
1734 for (j = 0; j < 2; j++) {
1735 if ((voiceMsgFlg & mask) == 0x0A) {
1737 } else if ((voiceMsgFlg & mask) == 0x05) {
1738 *pTemp = 0; // FALSE
1740 pTemp += sizeof(gboolean);
1741 voiceMsgFlg = voiceMsgFlg >> 4;
1747 gboolean tcore_sim_decode_mwis(struct tel_sim_mw *pMwis, unsigned char *p_in, int in_length)
1750 unsigned char type = 0;
1751 unsigned char mask = 0x01;
1756 memset((void*) pMwis, 0, sizeof(struct tel_sim_mw));
1758 type = p_in[0]; //0x07
1761 for (i = 0; i < 5; i++) {
1762 switch (type & mask) {
1764 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_VOICE;
1767 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_FAX;
1770 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_EMAIL;
1773 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_OTHER;
1776 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_VIDEO;
1779 pMwis->IndicatorType = pMwis->IndicatorType | SIM_MWIS_NONE;
1785 pMwis->voice_count = p_in[1];
1786 pMwis->fax_count = p_in[2];
1787 pMwis->email_count = p_in[3];
1788 pMwis->other_count = p_in[4];
1791 pMwis->video_count = p_in[5];
1796 gboolean tcore_sim_encode_mwis( char *p_out, int out_length, struct tel_sim_mw *pMwis)
1798 if (out_length == 0)
1801 memset((void*) p_out, 0xFF, out_length);
1804 p_out[0] = (unsigned char) pMwis->IndicatorType;
1805 p_out[1] = pMwis->voice_count;
1806 p_out[2] = pMwis->fax_count;
1807 p_out[3] = pMwis->email_count;
1808 p_out[4] = pMwis->other_count;
1810 if (out_length == 6)
1811 p_out[5] = pMwis->video_count;
1816 gboolean tcore_sim_encode_vmwf(char *p_out, int out_length, struct tel_sim_cphs_mw *p_vmwf)
1819 unsigned char* pTemp = (unsigned char*) p_vmwf;
1820 unsigned char present = 0x0A;
1821 unsigned char absent = 0x05;
1823 if (out_length == 0)
1826 for (i = 0; i < 2; i++) {
1832 for (j = 0; j < 2; j++) {
1834 p_out[i] = p_out[i] | present; //TRUE
1836 p_out[i] = p_out[i] | absent; //TRUE
1838 pTemp += sizeof(gboolean);
1839 present = present << 4;
1840 absent = absent << 4;
1846 gboolean tcore_sim_decode_ons(unsigned char* p_out,unsigned char* p_in, int in_length)
1849 memset((void*) p_out, 0, SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1854 if (_is_empty(p_in, in_length) == TRUE) {
1858 /* current telephony supports 25 byte cphs-operator name string.*/
1859 if (in_length >= SIM_CPHS_OPERATOR_NAME_LEN_MAX)
1860 in_length = SIM_CPHS_OPERATOR_NAME_LEN_MAX;
1862 length = _get_string(p_out, p_in, in_length);
1863 p_out[length] = '\0';
1864 dbg( "Operator Name is (%s) & Length (%d) ", p_out, length);
1869 gboolean tcore_sim_decode_cfis(struct tel_sim_callforwarding *cfis, unsigned char *p_in, int in_length)
1871 int bcd_byte; // dialing number max length
1873 struct tel_sim_cfis p_cfis = {0,};
1878 if (_is_empty(p_in, in_length) == TRUE) {
1879 dbg("empty record. all data is set 0xff");
1880 return TRUE; // this is empty record
1883 p_cfis.MspNumber = p_in[i++];
1884 p_cfis.Status = p_in[i++];
1887 p_cfis.TypeOfNumber = (p_in[++i] >> 4) & 0x07;
1888 p_cfis.NumberingPlanIdent = p_in[i++] & 0x0F;
1890 // get actual dialing number length
1891 /* current telephony supports 20 byte dialing number format. */
1892 bcd_byte = _get_valid_bcd_byte(&p_in[i], SIM_XDN_NUMBER_LEN_MAX / 2);
1894 // get dialing number/SSC string
1895 p_cfis.DiallingnumLen = _bcd_to_digit((char*) p_cfis.DiallingNum, (char*) &p_in[i], bcd_byte); // actual dialing number length in BCD.
1896 dbg( "Dialing number Length %d \n", p_cfis.DiallingnumLen);
1898 i = i + SIM_XDN_NUMBER_LEN_MAX / 2;
1900 // get Capability/Configuration id
1901 // p_cfis.CapaConfig2Id = p_in[i++];
1903 // get Extension1 id
1904 // p_cfis.Ext7RecordId = p_in[i];
1906 dbg( "MspNumber 0x%x", p_cfis.MspNumber);
1907 dbg( "Status 0x%x", p_cfis.Status);
1908 dbg( "DiallingnumLen %d", p_cfis.DiallingnumLen);
1909 dbg( "TypeOfNumber %d", p_cfis.TypeOfNumber);
1910 dbg( "NumberingPlanIdent %d", p_cfis.NumberingPlanIdent);
1911 dbg( "Dialing number[%s]", p_cfis.DiallingNum);
1913 if(p_cfis.Status & 0x01)
1914 cfis->voice1 = TRUE;
1915 if(p_cfis.Status & 0x02)
1917 if(p_cfis.Status & 0x04)
1919 if(p_cfis.Status & 0x08)
1921 if(p_cfis.Status & 0x0a)
1922 cfis->allbearer = TRUE;
1926 char* tcore_sim_encode_cfis(int *out_length, const struct tel_sim_callforwarding *p_cfis)
1928 char *encoded_o = NULL;
1929 encoded_o = calloc(16, 1); // EF-CFIS record length is 16
1932 Bytes Description M/O Length
1933 1 MSP number M 1 byte
1934 2 CFU indicator status M 1 byte
1935 3 Length of BCD number M 1 byte
1936 4 TON and NPI M 1 byte
1937 5 to 14 Dialing Number M 10 bytes
1938 15 Capability/Configuration2 Record Identifier M 1 byte
1939 16 Extension 7 Record Identifier M 1 byte
1941 encoded_o[0] = 0x01; //default profile
1944 encoded_o[1] = encoded_o[1] | 0x01;
1946 encoded_o[1] = encoded_o[1] | 0x02;
1948 encoded_o[1] = encoded_o[1] | 0x04;
1950 encoded_o[1] = encoded_o[1] | 0x08;
1951 if(p_cfis->allbearer )
1952 encoded_o[1] = encoded_o[1] | 0x0a;
1954 memset(&encoded_o[2], 0xff, 14);
1960 gboolean tcore_sim_decode_dynamic_flag(struct tel_sim_cphs_dflag *p_df, unsigned char *p_in, int in_length)
1965 memset((void*) p_df, 0, sizeof(struct tel_sim_cphs_dflag));
1967 switch (p_in[0] & 0x01) {
1969 p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE2;
1973 p_df->DynamicFlags = SIM_DYNAMIC_FLAGS_LINE1;
1982 gboolean tcore_sim_decode_dynamic2_flag(struct tel_sim_cphs_dflag2 *p_d2f, unsigned char *p_in, int in_length)
1987 memset((void*) p_d2f, 0, sizeof(struct tel_sim_cphs_dflag2));
1989 switch (p_in[0] & 0x01) {
1991 p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_UNLOCKED;
1994 p_d2f->Dynamic2Flag = SIM_PIN2_ACCESSIBLE_FLAGS_LOCKED;
2002 gboolean tcore_sim_encode_dynamic_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag *p_df)
2004 if (out_length == 0 || out_length > 1)
2007 memset((void*) p_out, 0xFF, out_length);
2008 p_out[0] = p_df->DynamicFlags;
2012 gboolean tcore_sim_encode_dynamic2_flag(char *p_out, int out_length, struct tel_sim_cphs_dflag2 *p_d2f)
2014 if (out_length == 0 || out_length > 1)
2017 memset((void*) p_out, 0xFF, out_length);
2018 p_out[0] = p_d2f->Dynamic2Flag;
2022 gboolean tcore_sim_decode_cphs_info(struct tel_sim_cphs_info *pCphsInfo, unsigned char *p_in, int in_length)
2025 unsigned char mask = 0x03;
2026 unsigned char* pTemp = (unsigned char*) &pCphsInfo->CphsServiceTable;
2028 memset((void*) pCphsInfo, 0, sizeof(struct tel_sim_cphs_info));
2033 /*CPHS info EF has 3 bytes data.*/
2034 if (in_length >= SIM_CPHS_INFO_LEN_MAX)
2035 in_length = SIM_CPHS_INFO_LEN_MAX;
2039 pCphsInfo->CphsPhase = SIM_CPHS_PHASE1;
2042 pCphsInfo->CphsPhase = SIM_CPHS_PHASE2;
2045 pCphsInfo->CphsPhase = SIM_CPHS_PHASE_RFU;
2049 dbg( "Cphs Phase %d \n", pCphsInfo->CphsPhase);
2051 for (i = 1; i < in_length; i++) { //CPHS SST is only 2 bytes
2052 mask = 0x03; // reset mast to check first bit
2053 for (j = 0; j < 4; j++) {
2054 if (p_in[i] & mask) {
2057 dbg( "Byte (%d), service (%d) ", i+1, *pTemp);
2058 pTemp += sizeof(gboolean);
2065 gboolean tcore_sim_decode_short_ons(unsigned char *p_out, unsigned char *p_in, int in_length)
2069 memset(p_out, 0x00, SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
2071 if (_is_empty(p_in, in_length) == TRUE){
2072 return FALSE; // this is empty record
2075 /*CPHS specification shows current EF include 10 bytes */
2079 if(in_length > SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX)
2080 in_length = SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX;
2082 length = _get_string( p_out, p_in, in_length );
2083 p_out[length] = '\0';
2084 dbg( "Operator short Name is (%s) & length (%d)", p_out, length);
2088 gboolean tcore_sim_decode_information_number(struct tel_sim_cphs_info_number *p_info, unsigned char* p_in, int in_length)
2095 for (i = 0; i < in_length; i++) {
2096 dbg( " \t0x%04X.", p_in[i]);
2099 if (_is_empty(p_in, in_length) == TRUE) {
2100 return FALSE; // this is empty record
2103 p_info->AlphaIdLength = p_in[0];
2106 p_info->IndexLevelIndicator = (enum tel_sim_cphs_index_level) (p_in[1] & 0x0F);
2109 p_info->PremiumServiceIndicator = TRUE;
2112 p_info->PremiumServiceIndicator = TRUE;
2114 _get_string(p_info->Alpha_id, &p_in[2], p_info->AlphaIdLength);
2116 p_info->DiallingnumLength = p_in[2 + p_info->AlphaIdLength] * 2;
2117 p_info->TypeOfNumber = (p_in[3 + p_info->AlphaIdLength] >> 4) & 0x07;
2118 p_info->NumberingPlanIdentity = p_in[3 + p_info->AlphaIdLength] & 0x0F;
2120 // get dialing number/SSC string
2121 _bcd_to_digit((char*) p_info->DiallingnumLength, (char*) &p_in[4 + p_info->AlphaIdLength], p_info->DiallingnumLength / 2); // actual dialing number length in BCD.
2122 // get Extension1 id
2123 p_info->Ext1RecordId = p_in[4 + p_info->AlphaIdLength + p_info->DiallingnumLength / 2];
2128 gboolean tcore_sim_decode_opl(struct tel_sim_opl *p_opl, unsigned char *p_in, int in_length)
2130 unsigned char packetInDigit[3 * 2 + 1];
2132 if (_is_empty(p_in, in_length) == TRUE) {
2133 memset(p_opl, 0x00, sizeof(struct tel_sim_opl));
2134 return FALSE; // this is empty record
2136 _bcd_to_digit((char*) packetInDigit, (char*) &p_in[0], 3);
2137 dbg( "AFTER _bcd_to_digit 4th[0x%x]", packetInDigit[3]);
2140 memcpy(&p_opl->plmn, &(packetInDigit[0]), 3);
2142 if (packetInDigit[3] == 0x00){
2143 memcpy(&(p_opl->plmn[3]), &(packetInDigit[3 + 1]), 2);
2144 p_opl->plmn[5] = '\0';
2146 memcpy(&(p_opl->plmn[3]), &(packetInDigit[3]), 3);
2147 p_opl->plmn[6] = '\0';
2150 dbg( " PLMN Code[%s]", p_opl->plmn);
2151 p_opl->lac_from = (*(p_in+3) << 8) | (*(p_in+4) & 0x00ff);
2152 dbg( " Start value of the LAC range[%x]", p_opl->lac_from);
2153 p_opl->lac_to = (*(p_in+5) << 8) | (*(p_in+6) & 0x00ff);
2154 dbg( " End value of the LAC range[%x]", p_opl->lac_to);
2155 p_opl->rec_identifier = p_in[7];
2156 dbg( " PNN Record identifier[%x]", p_opl->rec_identifier);
2160 gboolean tcore_sim_decode_pnn(struct tel_sim_pnn *p_pnn, unsigned char* p_in, int in_length)
2162 int f_name_len = 0, s_name_len = 0;
2163 int cvt_leng = 0, s_name_base = 0;
2165 if (_is_empty(p_in, in_length) == TRUE) {
2166 memset(p_pnn, 0x00, sizeof(struct tel_sim_pnn));
2167 return FALSE; // this is empty record
2170 /*Full name for network IEI(Information Element Identifier),0x43*/
2171 if (p_in[0] == 0x43) {
2172 dbg( " Full name of network IEI exist");
2173 //f_name_part includes information byte.
2174 f_name_len = (int)p_in[1] - 1;
2176 /* 3rd byte information element(according to TS 24.008 for Network Name)
2178 7 6 5 : coding scheme
2180 3 2 1 : number of spare bits in last octet
2182 Coding Scheme (octet 3, bits 5-7)
2183 0 0 0 Cell Broadcast data coding scheme, GSM default alphabet, language unspecified, defined in 3GPP TS 23.038 [8b]
2184 0 0 1 UCS2 (16 bit) [72]
2188 if ((p_in[2] & 0x01110000) >> 4 == 0) {
2190 // In case of GSM7, 35byte packing data will be converted 40 bytes unpacking string.
2191 if (f_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
2192 f_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
2194 _unpack_7bit28bit(p_in + 3, f_name_len, (unsigned char *) (p_pnn->full_name));
2195 } else if ((p_in[2] & 0x01110000) >> 4 == 1) {
2197 /* current telephony supports 40 bytes network name string */
2198 if (f_name_len > SIM_NW_FULL_NAME_LEN_MAX)
2199 f_name_len = SIM_NW_FULL_NAME_LEN_MAX;
2201 _ucs2_to_utf8(f_name_len, p_in + 3, (int*) &cvt_leng, (unsigned char *) (p_pnn->full_name));
2203 dbg( "DCS:unknown");
2206 dbg( " Full name of network contents[%s]", p_pnn->full_name);
2208 s_name_base = (int)p_in[1] +2;
2209 dbg( " short name base byte [0x%02x]", s_name_base);
2211 /*Short Name for network IEI(Information Element Identifier), 0x45*/
2212 if (p_in[s_name_base] == 0x45) {
2213 dbg( " Short name of network IEI exist");
2214 //s_name_part includes information byte.
2215 s_name_len = p_in[s_name_base +1] -1;
2217 if ((p_in[s_name_base + 2] & 0x01110000) >> 4 == 0) {
2219 // In case of GSM7, 35byte packing data will be converted 40 bytes unpacking string.
2220 if (s_name_len > (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8)
2221 s_name_len = (SIM_NW_FULL_NAME_LEN_MAX * 7) / 8;
2223 _unpack_7bit28bit(p_in + s_name_base + 3, s_name_len, (unsigned char *) (p_pnn->short_name));
2224 } else if ((p_in[s_name_base +2] & 0x01110000) >> 4 == 1) {
2226 if (s_name_len > SIM_NW_FULL_NAME_LEN_MAX)
2227 s_name_len = SIM_NW_FULL_NAME_LEN_MAX;
2229 _ucs2_to_utf8(s_name_len, p_in + s_name_base+ 3, (int*) &cvt_leng, (unsigned char *) (p_pnn->short_name));
2231 dbg( "DCS:unknown");
2234 dbg( " Short name of network contents[%s]", p_pnn->short_name);
2241 gboolean tcore_sim_decode_oplmnwact(struct tel_sim_oplmnwact_list *p_list, unsigned char *p_in, int in_length)
2243 unsigned long m = 0;
2244 //unsigned long k, j, m = 0;
2245 // unsigned char mask = 0x00;
2247 //current raw data can include invalid OPLMN data(ex: ff ff ff 00 00). so we can`t decide the number of OPLMN records directly.
2248 int rawOplmnWactCount = 0;
2251 memset((void*) p_list, 0, sizeof(struct tel_sim_oplmnwact_list));
2253 rawOplmnWactCount = in_length / 5;
2255 dbg( "rawOplmnWactCount[%d]", rawOplmnWactCount);
2257 for (i = 0; i < rawOplmnWactCount; i++) {
2258 unsigned char packetInDigit[3 * 2 + 1];
2260 //Regarding current IPC data, even if there`s no OPLMN value, IPC data is sending with 'ff ff ff 00 00'. so we should check for validation.
2261 if (p_in[m] == 0xff) {
2262 p_list->opwa_count = m / 5;
2263 dbg("OPLMN(MCC+MNC) value is not found at p_in[m]=[%lu].So OPLMN count is [%d]", m, p_list->opwa_count);
2267 _bcd_to_digit((char*) packetInDigit, (char*) &p_in[m], 3);
2268 dbg( "AFTER _bcd_to_digit 4th[0x%x]", packetInDigit[3]);
2271 memcpy(&p_list->opwa[i].plmn, &(packetInDigit[0]), 3);
2273 if (packetInDigit[3] == 0x00){
2274 memcpy(&(p_list->opwa[i].plmn[3]), &(packetInDigit[3 + 1]), 2);
2275 p_list->opwa[i].plmn[5] = '\0';
2277 memcpy(&(p_list->opwa[i].plmn[3]), &(packetInDigit[3]), 3);
2278 p_list->opwa[i].plmn[6] = '\0';
2280 dbg( "[%d] OPLMN PLMN Code[%s]", i, p_list->opwa[i].plmn);
2282 if(p_in[m+3] & 0x80)
2283 p_list->opwa[i].b_umts = 1;
2285 if(p_in[m+4] & 0x80)
2286 p_list->opwa[i].b_gsm = 1;
2291 p_list->opwa_count = rawOplmnWactCount;
2292 dbg( "OPLMN count is p_list->opwa_count[%d]", p_list->opwa_count);
2297 enum tel_sim_status tcore_sim_get_status(CoreObject *o)
2299 struct private_object_data *po = NULL;
2300 po = tcore_object_ref_object(o);
2302 dbg("po access fail");
2305 return po->sim_status;
2308 gboolean tcore_sim_set_status(CoreObject *o, enum tel_sim_status status)
2310 struct private_object_data *po = NULL;
2311 po = tcore_object_ref_object(o);
2313 dbg("po access fail");
2316 po->sim_status = status;
2321 gboolean tcore_sim_get_identification(CoreObject *o)
2323 struct private_object_data *po = NULL;
2324 po = tcore_object_ref_object(o);
2326 dbg("po access fail");
2329 return po->b_sim_changed;
2332 gboolean tcore_sim_set_identification(CoreObject *o, gboolean b_changed)
2334 struct private_object_data *po = NULL;
2335 po = tcore_object_ref_object(o);
2337 dbg("po access fail");
2340 po->b_sim_changed = b_changed;
2345 enum tel_sim_type tcore_sim_get_type(CoreObject *o)
2347 struct private_object_data *po = NULL;
2348 po = tcore_object_ref_object(o);
2350 dbg("po access fail");
2356 gboolean tcore_sim_set_type(CoreObject *o, enum tel_sim_type type)
2358 struct private_object_data *po = NULL;
2359 po = tcore_object_ref_object(o);
2361 dbg("po access fail");
2368 struct tel_sim_imsi* tcore_sim_get_imsi(CoreObject *o)
2370 struct tel_sim_imsi *tmp_imsi;
2371 struct private_object_data *po = NULL;
2372 po = tcore_object_ref_object(o);
2374 dbg("po access fail");
2377 tmp_imsi = calloc(sizeof(struct tel_sim_imsi), 1);
2378 memcpy(tmp_imsi, &po->imsi, sizeof(struct tel_sim_imsi));
2382 gboolean tcore_sim_set_imsi(CoreObject *o, struct tel_sim_imsi *imsi)
2384 struct private_object_data *po = NULL;
2385 po = tcore_object_ref_object(o);
2387 dbg("po access fail");
2390 memcpy(&po->imsi, imsi, sizeof(struct tel_sim_imsi));
2394 gboolean tcore_sim_get_cphs_status(CoreObject *o){
2395 struct private_object_data *po = NULL;
2396 po = tcore_object_ref_object(o);
2398 dbg("po access fail");
2404 gboolean tcore_sim_set_cphs_status(CoreObject *o, gboolean b_support){
2405 struct private_object_data *po = NULL;
2406 po = tcore_object_ref_object(o);
2408 dbg("po access fail");
2411 po->b_cphs = b_support;
2415 gboolean tcore_sim_link_userdata(CoreObject *o, void *userdata)
2417 struct private_object_data *po = NULL;
2418 po = tcore_object_ref_object(o);
2420 dbg("po access fail");
2423 po->userdata = userdata;
2427 void* tcore_sim_ref_userdata(CoreObject *o)
2429 struct private_object_data *po = NULL;
2430 po = tcore_object_ref_object(o);
2431 if (!po || !po->userdata) {
2432 dbg("po access fail");
2435 return po->userdata;
2438 static void tcore_sim_initialize_context(CoreObject *o)
2440 struct tcore_sim_operations *tmp_ops = NULL;
2441 struct private_object_data *po = NULL;
2442 po = tcore_object_ref_object(o);
2444 dbg("po access fail");
2451 free(po->p_cache);*/
2453 memset(po, 0x00, sizeof(struct private_object_data));
2457 po->sim_status = SIM_STATUS_UNKNOWN;
2458 po->language_file = SIM_EF_INVALID;
2459 po->cf_file = SIM_EF_INVALID;
2460 po->mw_file = SIM_EF_INVALID;
2461 po->mb_file = SIM_EF_INVALID;
2464 CoreObject *tcore_sim_new(TcorePlugin *p, const char *name,
2465 struct tcore_sim_operations *ops, TcoreHal *hal)
2467 CoreObject *o = NULL;
2468 struct private_object_data *po = NULL;
2473 o = tcore_object_new(p, name, hal);
2477 po = calloc(sizeof(struct private_object_data), 1);
2479 tcore_object_free(o);
2485 tcore_object_set_type(o, CORE_OBJECT_TYPE_SIM);
2486 tcore_object_link_object(o, po);
2487 tcore_object_set_free_hook(o, _free_hook);
2488 tcore_object_set_clone_hook(o, _clone_hook);
2489 tcore_object_set_dispatcher(o, _dispatcher);
2491 tcore_sim_initialize_context(o);
2496 void tcore_sim_free(CoreObject *o)
2498 struct private_object_data *po = NULL;
2500 CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_SIM);
2502 po = tcore_object_ref_object(o);
2507 tcore_object_free(o);