00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include "sim-internal.h"
00009
00010 static void decode_7bit(const uint8_t *inp, size_t len)
00011 {
00012 uint8_t out[len + 1];
00013 unsigned int i;
00014
00015 for(i = 0; i <= len; i++) {
00016 int ipos = i - (i >> 3);
00017 int offset = (i & 0x7);
00018
00019 out[i] = (inp[ipos] & (0x7F >> offset)) << offset;
00020 if( 0 == offset )
00021 continue;
00022
00023 out[i] |= (inp[ipos - 1] &
00024 (0x7F << (8 - offset)) & 0xFF) >> (8 - offset);
00025 }
00026
00027 out[len] = '\0';
00028 printf(" \"%s\"\n", out);
00029 }
00030
00031 static uint8_t hi_nibble(uint8_t byte)
00032 {
00033 return byte >> 4;
00034 }
00035
00036 static uint8_t lo_nibble(uint8_t byte)
00037 {
00038 return byte & 0xf;
00039 }
00040
00041 const char *number_type(uint8_t type)
00042 {
00043 switch(type & GSM_NUMBER_TYPE_MASK) {
00044 case GSM_NUMBER_UNKNOWN:
00045 return "unknown";
00046 case GSM_NUMBER_INTL:
00047 return "international";
00048 case GSM_NUMBER_NATIONAL:
00049 return "national";
00050 case GSM_NUMBER_NET_SPEC:
00051 return "network specific";
00052 case GSM_NUMBER_SUBSCR:
00053 return "subscriber";
00054 case GSM_NUMBER_ABBREV:
00055 return "abbreviated";
00056 case GSM_NUMBER_ALNUM:
00057 return "alphanumeric";
00058 case GSM_NUMBER_RESERVED:
00059 default:
00060 return "reserved";
00061 }
00062 }
00063 const char *number_plan(uint8_t type)
00064 {
00065 switch(type & GSM_PLAN_MASK) {
00066 case GSM_PLAN_UNKNOWN:
00067 return "unknown";
00068 case GSM_PLAN_ISDN:
00069 return "ISDN";
00070 case GSM_PLAN_X121:
00071 return "X.121";
00072 case GSM_PLAN_TELEX:
00073 return "telex";
00074 case GSM_PLAN_NATIONAL:
00075 return "national";
00076 case GSM_PLAN_PRIVATE:
00077 return "private";
00078 case GSM_PLAN_ERMES:
00079 return "ERMES";
00080 default:
00081 return "reserved";
00082 }
00083 }
00084
00085 const char *fmt_number(uint8_t type, uint8_t len, const uint8_t *ptr)
00086 {
00087 static char buf[768];
00088 char *o = buf;
00089 uint8_t i;
00090
00091 if ( GSM_NUMBER_INTL == (type & GSM_NUMBER_TYPE_MASK) )
00092 *o = '+', o++;
00093
00094 for(i = 0; i < len; i++, ptr++) {
00095 if ( *ptr == 0xff )
00096 continue;
00097 switch(lo_nibble(*ptr)) {
00098 case 0 ... 9:
00099 o += sprintf(o, "%1x", lo_nibble(*ptr));
00100 break;
00101 case 0xa:
00102 *o = '*', o++;
00103 break;
00104 case 0xb:
00105 *o = '#', o++;
00106 break;
00107 default:
00108 break;
00109 }
00110 if ( hi_nibble(*ptr) != 0xf )
00111 o += sprintf(o, "%1x", hi_nibble(*ptr));
00112 if ( 0 == i || 1 == ((i - 1) % 2) )
00113 *o = ' ', o++;
00114 }
00115 *o = '\0';
00116 return buf;
00117 }
00118
00119 void _sms_decode(struct _sms *sms, const uint8_t *ptr)
00120 {
00121 const uint8_t *end = ptr + 176;
00122
00123 memset(sms, 0, sizeof(*sms));
00124
00125 sms->status = *ptr, ptr++;
00126
00127 switch( sms->status & 0x7 ) {
00128 case SIM_SMS_STATUS_FREE:
00129
00130 return;
00131 case SIM_SMS_STATUS_READ:
00132 printf("sms: Status: READ\n");
00133 break;
00134 case SIM_SMS_STATUS_UNREAD:
00135 printf("sms: Status: UNREAD\n");
00136 break;
00137 case SIM_SMS_STATUS_SENT:
00138 printf("sms: Status: SENT\n");
00139 break;
00140 case SIM_SMS_STATUS_UNSENT:
00141 printf("sms: Status: UNSENT\n");
00142 break;
00143 default:
00144 printf("sms: Status: unknown status 0x%.1x\n",
00145 sms->status & 0x7);
00146 return;
00147 }
00148
00149 sms->smsc_len = ptr[0] - 1;
00150 sms->smsc_type = ptr[1];
00151 ptr += 2;
00152 sms->smsc = ptr;
00153 ptr += sms->smsc_len;
00154 printf(" SMSC: type %s/%s\n",
00155 number_type(sms->smsc_type),
00156 number_plan(sms->smsc_type));
00157 printf(" SMSC: %s\n",
00158 fmt_number(sms->smsc_type, sms->smsc_len, sms->smsc));
00159
00160 sms->sms_deliver = *ptr, ptr++;
00161 if ( (sms->sms_deliver & SMS_TP_MTI) ) {
00162 printf(" Not an SMS-DELIVER 0x%.2x\n", sms->sms_deliver);
00163 return;
00164 }
00165 printf(" SMS-DELIVER");
00166 if ( 0 == (sms->sms_deliver & SMS_TP_MMS) )
00167 printf(" MMS");
00168 if ( sms->sms_deliver & SMS_TP_SRI )
00169 printf(" SRI");
00170 if ( sms->sms_deliver & SMS_TP_UDHI )
00171 printf(" UDHI");
00172 if ( sms->sms_deliver & SMS_TP_RP )
00173 printf(" RP");
00174 printf("\n");
00175
00176 sms->sender_len = (ptr[0] + 1) >> 1;
00177 sms->sender_type = ptr[1];
00178 ptr += 2;
00179 sms->sender = ptr;
00180 ptr += sms->sender_len;
00181 printf(" Sender: type %s/%s\n",
00182 number_type(sms->sender_type),
00183 number_plan(sms->sender_type));
00184 printf(" Sender: %s\n",
00185 fmt_number(sms->sender_type, sms->sender_len, sms->sender));
00186
00187 sms->tp_pid = ptr[0];
00188 sms->tp_dcs = ptr[1];
00189 ptr += 2;
00190 printf(" TP-PID = 0x%.2x, TP-DCS = 0x%.2x\n", sms->tp_pid, sms->tp_dcs);
00191
00192 memcpy(sms->timestamp, ptr, 7), ptr += 7;
00193 printf(" Timestamp: 20%1x%1x-%1x%1x-%1x%1x %1x%1x:%1x%1x:%1x%1x\n",
00194 lo_nibble(sms->timestamp[0]),
00195 hi_nibble(sms->timestamp[0]),
00196 lo_nibble(sms->timestamp[1]),
00197 hi_nibble(sms->timestamp[1]),
00198 lo_nibble(sms->timestamp[2]),
00199 hi_nibble(sms->timestamp[2]),
00200 lo_nibble(sms->timestamp[3]),
00201 hi_nibble(sms->timestamp[3]),
00202 lo_nibble(sms->timestamp[4]),
00203 hi_nibble(sms->timestamp[4]),
00204 lo_nibble(sms->timestamp[5]),
00205 hi_nibble(sms->timestamp[5]));
00206
00207 sms->uda = ptr[0], ptr++;
00208 sms->data = ptr;
00209 decode_7bit(sms->data, sms->uda);
00210 printf("\n");
00211 }