1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import android.app.PendingIntent; 20 import android.content.Context; 21 import android.util.Log; 22 23 import com.android.internal.util.HexDump; 24 25 import java.util.ArrayList; 26 import java.util.List; 27 28 import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 29 30 /** 31 * IccSmsInterfaceManager to provide an inter-process communication to 32 * access Sms in Icc. 33 */ 34 public abstract class IccSmsInterfaceManager extends ISms.Stub { 35 protected PhoneBase mPhone; 36 protected Context mContext; 37 protected SMSDispatcher mDispatcher; 38 39 protected IccSmsInterfaceManager(PhoneBase phone){ 40 mPhone = phone; 41 mContext = phone.getContext(); 42 } 43 44 protected void enforceReceiveAndSend(String message) { 45 mContext.enforceCallingPermission( 46 "android.permission.RECEIVE_SMS", message); 47 mContext.enforceCallingPermission( 48 "android.permission.SEND_SMS", message); 49 } 50 51 /** 52 * Send a data based SMS to a specific application port. 53 * 54 * @param destAddr the address to send the message to 55 * @param scAddr is the service center address or null to use 56 * the current default SMSC 57 * @param destPort the port to deliver the message to 58 * @param data the body of the message to send 59 * @param sentIntent if not NULL this <code>PendingIntent</code> is 60 * broadcast when the message is successfully sent, or failed. 61 * The result code will be <code>Activity.RESULT_OK<code> for success, 62 * or one of these errors:<br> 63 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 64 * <code>RESULT_ERROR_RADIO_OFF</code><br> 65 * <code>RESULT_ERROR_NULL_PDU</code><br> 66 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 67 * the extra "errorCode" containing a radio technology specific value, 68 * generally only useful for troubleshooting.<br> 69 * The per-application based SMS control checks sentIntent. If sentIntent 70 * is NULL the caller will be checked against all unknown applications, 71 * which cause smaller number of SMS to be sent in checking period. 72 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 73 * broadcast when the message is delivered to the recipient. The 74 * raw pdu of the status report is in the extended data ("pdu"). 75 */ 76 public void sendData(String destAddr, String scAddr, int destPort, 77 byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 78 mPhone.getContext().enforceCallingPermission( 79 "android.permission.SEND_SMS", 80 "Sending SMS message"); 81 if (Log.isLoggable("SMS", Log.VERBOSE)) { 82 log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + 83 destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + 84 sentIntent + " deliveryIntent=" + deliveryIntent); 85 } 86 mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); 87 } 88 89 /** 90 * Send a text based SMS. 91 * 92 * @param destAddr the address to send the message to 93 * @param scAddr is the service center address or null to use 94 * the current default SMSC 95 * @param text the body of the message to send 96 * @param sentIntent if not NULL this <code>PendingIntent</code> is 97 * broadcast when the message is successfully sent, or failed. 98 * The result code will be <code>Activity.RESULT_OK<code> for success, 99 * or one of these errors:<br> 100 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 101 * <code>RESULT_ERROR_RADIO_OFF</code><br> 102 * <code>RESULT_ERROR_NULL_PDU</code><br> 103 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 104 * the extra "errorCode" containing a radio technology specific value, 105 * generally only useful for troubleshooting.<br> 106 * The per-application based SMS control checks sentIntent. If sentIntent 107 * is NULL the caller will be checked against all unknown applications, 108 * which cause smaller number of SMS to be sent in checking period. 109 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 110 * broadcast when the message is delivered to the recipient. The 111 * raw pdu of the status report is in the extended data ("pdu"). 112 */ 113 public void sendText(String destAddr, String scAddr, 114 String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { 115 mPhone.getContext().enforceCallingOrSelfPermission( 116 "android.permission.SEND_SMS", 117 "Sending SMS message"); 118 if (Log.isLoggable("SMS", Log.VERBOSE)) { 119 log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + 120 " text='"+ text + "' sentIntent=" + 121 sentIntent + " deliveryIntent=" + deliveryIntent); 122 } 123 mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); 124 } 125 126 /** 127 * Send a multi-part text based SMS. 128 * 129 * @param destAddr the address to send the message to 130 * @param scAddr is the service center address or null to use 131 * the current default SMSC 132 * @param parts an <code>ArrayList</code> of strings that, in order, 133 * comprise the original message 134 * @param sentIntents if not null, an <code>ArrayList</code> of 135 * <code>PendingIntent</code>s (one for each message part) that is 136 * broadcast when the corresponding message part has been sent. 137 * The result code will be <code>Activity.RESULT_OK<code> for success, 138 * or one of these errors: 139 * <code>RESULT_ERROR_GENERIC_FAILURE</code> 140 * <code>RESULT_ERROR_RADIO_OFF</code> 141 * <code>RESULT_ERROR_NULL_PDU</code>. 142 * The per-application based SMS control checks sentIntent. If sentIntent 143 * is NULL the caller will be checked against all unknown applications, 144 * which cause smaller number of SMS to be sent in checking period. 145 * @param deliveryIntents if not null, an <code>ArrayList</code> of 146 * <code>PendingIntent</code>s (one for each message part) that is 147 * broadcast when the corresponding message part has been delivered 148 * to the recipient. The raw pdu of the status report is in the 149 * extended data ("pdu"). 150 */ 151 public void sendMultipartText(String destAddr, String scAddr, List<String> parts, 152 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { 153 mPhone.getContext().enforceCallingPermission( 154 "android.permission.SEND_SMS", 155 "Sending SMS message"); 156 if (Log.isLoggable("SMS", Log.VERBOSE)) { 157 int i = 0; 158 for (String part : parts) { 159 log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr + 160 ", part[" + (i++) + "]=" + part); 161 } 162 } 163 mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts, 164 (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); 165 } 166 167 /** 168 * create SmsRawData lists from all sms record byte[] 169 * Use null to indicate "free" record 170 * 171 * @param messages List of message records from EF_SMS. 172 * @return SmsRawData list of all in-used records 173 */ 174 protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) { 175 int count = messages.size(); 176 ArrayList<SmsRawData> ret; 177 178 ret = new ArrayList<SmsRawData>(count); 179 180 for (int i = 0; i < count; i++) { 181 byte[] ba = messages.get(i); 182 if (ba[0] == STATUS_ON_ICC_FREE) { 183 ret.add(null); 184 } else { 185 ret.add(new SmsRawData(messages.get(i))); 186 } 187 } 188 189 return ret; 190 } 191 192 /** 193 * Generates an EF_SMS record from status and raw PDU. 194 * 195 * @param status Message status. See TS 51.011 10.5.3. 196 * @param pdu Raw message PDU. 197 * @return byte array for the record. 198 */ 199 protected byte[] makeSmsRecordData(int status, byte[] pdu) { 200 byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH]; 201 202 // Status bits for this record. See TS 51.011 10.5.3 203 data[0] = (byte)(status & 7); 204 205 System.arraycopy(pdu, 0, data, 1, pdu.length); 206 207 // Pad out with 0xFF's. 208 for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) { 209 data[j] = -1; 210 } 211 212 return data; 213 } 214 215 protected abstract void log(String msg); 216 217 } 218