1 /*
2  * Copyright (C) 2021 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.os.RemoteException;
20 import android.telephony.Rlog;
21 
22 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
23 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
24 
25 import java.util.ArrayList;
26 
27 /**
28  * A holder for IRadioMessaging.
29  * Use getAidl to get IRadioMessaging and call the AIDL implementations of the HAL APIs.
30  */
31 public class RadioMessagingProxy extends RadioServiceProxy {
32     private static final String TAG = "RadioMessagingProxy";
33     private volatile android.hardware.radio.messaging.IRadioMessaging mMessagingProxy = null;
34 
35     /**
36      * Set IRadioMessaging as the AIDL implementation for RadioServiceProxy
37      * @param halVersion Radio HAL version
38      * @param messaging IRadioMessaging implementation
39      *
40      * @return updated HAL version
41      */
setAidl(HalVersion halVersion, android.hardware.radio.messaging.IRadioMessaging messaging)42     public HalVersion setAidl(HalVersion halVersion,
43             android.hardware.radio.messaging.IRadioMessaging messaging) {
44         HalVersion version = halVersion;
45         try {
46             version = RIL.getServiceHalVersion(messaging.getInterfaceVersion());
47         } catch (RemoteException e) {
48             Rlog.e(TAG, "setAidl: " + e);
49         }
50         mHalVersion = version;
51         mMessagingProxy = messaging;
52         mIsAidl = true;
53 
54         Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion);
55         return mHalVersion;
56     }
57 
58     /**
59      * Get the AIDL implementation of RadioMessagingProxy
60      * @return IRadioMessaging implementation
61      */
getAidl()62     public android.hardware.radio.messaging.IRadioMessaging getAidl() {
63         return mMessagingProxy;
64     }
65 
66     /**
67      * Reset RadioMessagingProxy
68      */
69     @Override
clear()70     public void clear() {
71         super.clear();
72         mMessagingProxy = null;
73     }
74 
75     /**
76      * Check whether a RadioMessaging implementation exists
77      * @return true if there is neither a HIDL nor AIDL implementation
78      */
79     @Override
isEmpty()80     public boolean isEmpty() {
81         return mRadioProxy == null && mMessagingProxy == null;
82     }
83 
84     /**
85      * Call IRadioMessaging#acknowledgeIncomingGsmSmsWithPdu
86      * @param serial Serial number of request
87      * @param success True on successful receipt (RP-ACK) and false on failed receipt (RP-ERROR)
88      * @param ackPdu Acknowledgement TPDU in hexadecimal format
89      * @throws RemoteException
90      */
acknowledgeIncomingGsmSmsWithPdu(int serial, boolean success, String ackPdu)91     public void acknowledgeIncomingGsmSmsWithPdu(int serial, boolean success, String ackPdu)
92             throws RemoteException {
93         if (isEmpty()) return;
94         if (isAidl()) {
95             mMessagingProxy.acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
96         } else {
97             mRadioProxy.acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
98         }
99     }
100 
101     /**
102      * Calls IRadioMessaging#acknowledgeLastIncomingCdmaSms
103      * @param serial Serial number of request
104      * @param success True on successful receipt
105      * @param cause Failure cause if success is false
106      * @throws RemoteException
107      */
acknowledgeLastIncomingCdmaSms(int serial, boolean success, int cause)108     public void acknowledgeLastIncomingCdmaSms(int serial, boolean success, int cause)
109             throws RemoteException {
110         if (isEmpty()) return;
111         if (isAidl()) {
112             android.hardware.radio.messaging.CdmaSmsAck msg =
113                     new android.hardware.radio.messaging.CdmaSmsAck();
114             msg.errorClass = success;
115             msg.smsCauseCode = cause;
116             mMessagingProxy.acknowledgeLastIncomingCdmaSms(serial, msg);
117         } else {
118             android.hardware.radio.V1_0.CdmaSmsAck msg =
119                     new android.hardware.radio.V1_0.CdmaSmsAck();
120             msg.errorClass = success ? 0 : 1;
121             msg.smsCauseCode = cause;
122             mRadioProxy.acknowledgeLastIncomingCdmaSms(serial, msg);
123         }
124     }
125 
126     /**
127      * Calls IRadioMessaging#acknowledgeLastIncomingGsmSms
128      * @param serial Serial number of request
129      * @param success True on successful receipt
130      * @param cause Failure cause if success is false
131      * @throws RemoteException
132      */
acknowledgeLastIncomingGsmSms(int serial, boolean success, int cause)133     public void acknowledgeLastIncomingGsmSms(int serial, boolean success, int cause)
134             throws RemoteException {
135         if (isEmpty()) return;
136         if (isAidl()) {
137             mMessagingProxy.acknowledgeLastIncomingGsmSms(serial, success, cause);
138         } else {
139             mRadioProxy.acknowledgeLastIncomingGsmSms(serial, success, cause);
140         }
141     }
142 
143     /**
144      * Call IRadioMessaging#deleteSmsOnRuim
145      * @param serial Serial number of request
146      * @param index Record index of the message to delete
147      * @throws RemoteException
148      */
deleteSmsOnRuim(int serial, int index)149     public void deleteSmsOnRuim(int serial, int index) throws RemoteException {
150         if (isEmpty()) return;
151         if (isAidl()) {
152             mMessagingProxy.deleteSmsOnRuim(serial, index);
153         } else {
154             mRadioProxy.deleteSmsOnRuim(serial, index);
155         }
156     }
157 
158     /**
159      * Call IRadioMessaging#deleteSmsOnSim
160      * @param serial Serial number of request
161      * @param index Record index of the message to delete
162      * @throws RemoteException
163      */
deleteSmsOnSim(int serial, int index)164     public void deleteSmsOnSim(int serial, int index) throws RemoteException {
165         if (isEmpty()) return;
166         if (isAidl()) {
167             mMessagingProxy.deleteSmsOnSim(serial, index);
168         } else {
169             mRadioProxy.deleteSmsOnSim(serial, index);
170         }
171     }
172 
173     /**
174      * Call IRadioMessaging#getCdmaBroadcastConfig
175      * @param serial Serial number of request
176      * @throws RemoteException
177      */
getCdmaBroadcastConfig(int serial)178     public void getCdmaBroadcastConfig(int serial) throws RemoteException {
179         if (isEmpty()) return;
180         if (isAidl()) {
181             mMessagingProxy.getCdmaBroadcastConfig(serial);
182         } else {
183             mRadioProxy.getCdmaBroadcastConfig(serial);
184         }
185     }
186 
187     /**
188      * Call IRadioMessaging#getGsmBroadcastConfig
189      * @param serial Serial number of request
190      * @throws RemoteException
191      */
getGsmBroadcastConfig(int serial)192     public void getGsmBroadcastConfig(int serial) throws RemoteException {
193         if (isEmpty()) return;
194         if (isAidl()) {
195             mMessagingProxy.getGsmBroadcastConfig(serial);
196         } else {
197             mRadioProxy.getGsmBroadcastConfig(serial);
198         }
199     }
200 
201     /**
202      * Call IRadioMessaging#getSmscAddress
203      * @param serial Serial number of request
204      * @throws RemoteException
205      */
getSmscAddress(int serial)206     public void getSmscAddress(int serial) throws RemoteException {
207         if (isEmpty()) return;
208         if (isAidl()) {
209             mMessagingProxy.getSmscAddress(serial);
210         } else {
211             mRadioProxy.getSmscAddress(serial);
212         }
213     }
214 
215     /**
216      * Call IRadioMessaging#reportSmsMemoryStatus
217      * @param serial Serial number of request
218      * @param available Whether or not storage is available
219      * @throws RemoteException
220      */
reportSmsMemoryStatus(int serial, boolean available)221     public void reportSmsMemoryStatus(int serial, boolean available) throws RemoteException {
222         if (isEmpty()) return;
223         if (isAidl()) {
224             mMessagingProxy.reportSmsMemoryStatus(serial, available);
225         } else {
226             mRadioProxy.reportSmsMemoryStatus(serial, available);
227         }
228     }
229 
230     /**
231      * Call IRadioMessaging#responseAcknowledgement
232      * @throws RemoteException
233      */
234     @Override
responseAcknowledgement()235     public void responseAcknowledgement() throws RemoteException {
236         if (isEmpty()) return;
237         if (isAidl()) {
238             mMessagingProxy.responseAcknowledgement();
239         } else {
240             mRadioProxy.responseAcknowledgement();
241         }
242     }
243 
244     /**
245      * Call IRadioMessaging#sendCdmaSms
246      * @param serial Serial number of request
247      * @param pdu CDMA-SMS in internal pseudo-PDU format
248      * @throws RemoteException
249      */
sendCdmaSms(int serial, byte[] pdu)250     public void sendCdmaSms(int serial, byte[] pdu) throws RemoteException {
251         if (isEmpty()) return;
252         if (isAidl()) {
253             mMessagingProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessageAidl(pdu));
254         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
255             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendCdmaSms_1_6(
256                     serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
257         } else {
258             mRadioProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
259         }
260     }
261 
262     /**
263      * Call IRadioMessaging#sendCdmaSmsExpectMore
264      * @param serial Serial number of request
265      * @param pdu CDMA-SMS in internal pseudo-PDU format
266      * @throws RemoteException
267      */
sendCdmaSmsExpectMore(int serial, byte[] pdu)268     public void sendCdmaSmsExpectMore(int serial, byte[] pdu) throws RemoteException {
269         if (isEmpty()) return;
270         if (isAidl()) {
271             mMessagingProxy.sendCdmaSmsExpectMore(
272                     serial, RILUtils.convertToHalCdmaSmsMessageAidl(pdu));
273         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
274             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendCdmaSmsExpectMore_1_6(
275                     serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
276         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
277             ((android.hardware.radio.V1_5.IRadio) mRadioProxy).sendCdmaSmsExpectMore(
278                     serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
279         } else {
280             mRadioProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
281         }
282     }
283 
284     /**
285      * Call IRadioMessaging#sendImsSms
286      * @param serial Serial number of request
287      * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
288      *                or NULL for default SMSC
289      * @param gsmPdu SMS in PDU format as an ASCII hex string less the SMSC address
290      * @param cdmaPdu CDMA-SMS in internal pseudo-PDU format
291      * @param retry Whether this is a retry; 0 == not retry, nonzero = retry
292      * @param messageRef MessageRef from RIL_SMS_RESPONSE corresponding to failed MO SMS
293      *                   if retry is nonzero
294      * @throws RemoteException
295      */
sendImsSms(int serial, String smscPdu, String gsmPdu, byte[] cdmaPdu, int retry, int messageRef)296     public void sendImsSms(int serial, String smscPdu, String gsmPdu, byte[] cdmaPdu, int retry,
297             int messageRef) throws RemoteException {
298         if (isEmpty()) return;
299         if (isAidl()) {
300             android.hardware.radio.messaging.ImsSmsMessage msg =
301                     new android.hardware.radio.messaging.ImsSmsMessage();
302             msg.tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
303             msg.retry = (byte) retry >= 1;
304             msg.messageRef = messageRef;
305             if (gsmPdu != null) {
306                 msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[]{
307                         RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, gsmPdu)};
308                 msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[0];
309             }
310             if (cdmaPdu != null) {
311                 msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[0];
312                 msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[]{
313                         RILUtils.convertToHalCdmaSmsMessageAidl(cdmaPdu)};
314             }
315             mMessagingProxy.sendImsSms(serial, msg);
316         } else {
317             android.hardware.radio.V1_0.ImsSmsMessage msg =
318                     new android.hardware.radio.V1_0.ImsSmsMessage();
319             msg.tech = android.hardware.radio.V1_0.RadioTechnologyFamily.THREE_GPP;
320             msg.retry = (byte) retry >= 1;
321             msg.messageRef = messageRef;
322             if (gsmPdu != null) {
323                 msg.gsmMessage.add(RILUtils.convertToHalGsmSmsMessage(smscPdu, gsmPdu));
324             }
325             if (cdmaPdu != null) {
326                 msg.cdmaMessage.add(RILUtils.convertToHalCdmaSmsMessage(cdmaPdu));
327             }
328             mRadioProxy.sendImsSms(serial, msg);
329         }
330     }
331 
332     /**
333      * Call IRadioMessaging#sendSms
334      * @param serial Serial number of request
335      * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
336      *                or NULL for default SMSC
337      * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
338      * @throws RemoteException
339      */
sendSms(int serial, String smscPdu, String pdu)340     public void sendSms(int serial, String smscPdu, String pdu) throws RemoteException {
341         if (isEmpty()) return;
342         if (isAidl()) {
343             mMessagingProxy.sendSms(serial, RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, pdu));
344         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
345             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendSms_1_6(
346                     serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
347         } else {
348             mRadioProxy.sendSms(serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
349         }
350     }
351 
352     /**
353      * Call IRadioMessaging#sendSmsExpectMore
354      * @param serial Serial number of request
355      * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
356      *                or NULL for default SMSC
357      * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
358      * @throws RemoteException
359      */
sendSmsExpectMore(int serial, String smscPdu, String pdu)360     public void sendSmsExpectMore(int serial, String smscPdu, String pdu) throws RemoteException {
361         if (isEmpty()) return;
362         if (isAidl()) {
363             mMessagingProxy.sendSmsExpectMore(serial,
364                     RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, pdu));
365         } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
366             ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendSmsExpectMore_1_6(serial,
367                     RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
368         } else {
369             mRadioProxy.sendSMSExpectMore(serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
370         }
371     }
372 
373     /**
374      * Call IRadioMessaging#setCdmaBroadcastActivation
375      * @param serial Serial number of request
376      * @param activate Whether to activate or turn off the reception of CDMA Cell Broadcast SMS;
377      *                 true = activate, false = turn off
378      * @throws RemoteException
379      */
setCdmaBroadcastActivation(int serial, boolean activate)380     public void setCdmaBroadcastActivation(int serial, boolean activate) throws RemoteException {
381         if (isEmpty()) return;
382         if (isAidl()) {
383             mMessagingProxy.setCdmaBroadcastActivation(serial, activate);
384         } else {
385             mRadioProxy.setCdmaBroadcastActivation(serial, activate);
386         }
387     }
388 
389     /**
390      * Call IRadioMessaging#setCdmaBroadcastConfig
391      * @param serial Serial number of request
392      * @param configs Setting of CDMA cell broadcast config
393      * @throws RemoteException
394      */
setCdmaBroadcastConfig(int serial, CdmaSmsBroadcastConfigInfo[] configs)395     public void setCdmaBroadcastConfig(int serial, CdmaSmsBroadcastConfigInfo[] configs)
396             throws RemoteException {
397         if (isEmpty()) return;
398         if (isAidl()) {
399             ArrayList<android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo> halConfigs =
400                     new ArrayList<>();
401             for (CdmaSmsBroadcastConfigInfo config: configs) {
402                 for (int i = config.getFromServiceCategory(); i <= config.getToServiceCategory();
403                         i++) {
404                     android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo info =
405                             new android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo();
406                     info.serviceCategory = i;
407                     info.language = config.getLanguage();
408                     info.selected = config.isSelected();
409                     halConfigs.add(info);
410                 }
411             }
412             mMessagingProxy.setCdmaBroadcastConfig(serial, halConfigs.stream().toArray(
413                     android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[]::new));
414         } else {
415             ArrayList<android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo> halConfigs =
416                     new ArrayList<>();
417             for (CdmaSmsBroadcastConfigInfo config: configs) {
418                 for (int i = config.getFromServiceCategory(); i <= config.getToServiceCategory();
419                         i++) {
420                     android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo info =
421                             new android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo();
422                     info.serviceCategory = i;
423                     info.language = config.getLanguage();
424                     info.selected = config.isSelected();
425                     halConfigs.add(info);
426                 }
427             }
428             mRadioProxy.setCdmaBroadcastConfig(serial, halConfigs);
429         }
430     }
431 
432     /**
433      * Call IRadioMessaging#setGsmBroadcastActivation
434      * @param serial Serial number of request
435      * @param activate Whether to activate or turn off the reception of GSM/WCDMA Cell Broadcast
436      *                 SMS; true = activate, false = turn off
437      * @throws RemoteException
438      */
setGsmBroadcastActivation(int serial, boolean activate)439     public void setGsmBroadcastActivation(int serial, boolean activate) throws RemoteException {
440         if (isEmpty()) return;
441         if (isAidl()) {
442             mMessagingProxy.setGsmBroadcastActivation(serial, activate);
443         } else {
444             mRadioProxy.setGsmBroadcastActivation(serial, activate);
445         }
446     }
447 
448     /**
449      * Call IRadioMessaging#setGsmBroadcastConfig
450      * @param serial Serial number of request
451      * @param configInfo Setting of GSM/WCDMA cell broadcast config
452      * @throws RemoteException
453      */
setGsmBroadcastConfig(int serial, SmsBroadcastConfigInfo[] configInfo)454     public void setGsmBroadcastConfig(int serial, SmsBroadcastConfigInfo[] configInfo)
455             throws RemoteException {
456         if (isEmpty()) return;
457         if (isAidl()) {
458             android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs =
459                     new android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[
460                             configInfo.length];
461             android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo info;
462             for (int i = 0; i < configInfo.length; i++) {
463                 info = new android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo();
464                 info.fromServiceId = configInfo[i].getFromServiceId();
465                 info.toServiceId = configInfo[i].getToServiceId();
466                 info.fromCodeScheme = configInfo[i].getFromCodeScheme();
467                 info.toCodeScheme = configInfo[i].getToCodeScheme();
468                 info.selected = configInfo[i].isSelected();
469                 configs[i] = info;
470             }
471             mMessagingProxy.setGsmBroadcastConfig(serial, configs);
472         } else {
473             ArrayList<android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo> configs =
474                     new ArrayList<>();
475             android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo info;
476             for (int i = 0; i < configInfo.length; i++) {
477                 info = new android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo();
478                 info.fromServiceId = configInfo[i].getFromServiceId();
479                 info.toServiceId = configInfo[i].getToServiceId();
480                 info.fromCodeScheme = configInfo[i].getFromCodeScheme();
481                 info.toCodeScheme = configInfo[i].getToCodeScheme();
482                 info.selected = configInfo[i].isSelected();
483                 configs.add(info);
484             }
485             mRadioProxy.setGsmBroadcastConfig(serial, configs);
486         }
487     }
488 
489     /**
490      * Call IRadioMessaging#setSmscAddress
491      * @param serial Serial number of request
492      * @param smsc Short Message Service Center address to set
493      * @throws RemoteException
494      */
setSmscAddress(int serial, String smsc)495     public void setSmscAddress(int serial, String smsc) throws RemoteException {
496         if (isEmpty()) return;
497         if (isAidl()) {
498             mMessagingProxy.setSmscAddress(serial, smsc);
499         } else {
500             mRadioProxy.setSmscAddress(serial, smsc);
501         }
502     }
503 
504     /**
505      * Call IRadioMessaging#writeSmsToRuim
506      * @param serial Serial number of request
507      * @param status Status of message on SIM. One of:
508      *               SmsManager.STATUS_ON_ICC_READ
509      *               SmsManager.STATUS_ON_ICC_UNREAD
510      *               SmsManager.STATUS_ON_ICC_SENT
511      *               SmsManager.STATUS_ON_ICC_UNSENT
512      * @param pdu SMS in PDU format as a byte array
513      * @throws RemoteException
514      */
writeSmsToRuim(int serial, int status, byte[] pdu)515     public void writeSmsToRuim(int serial, int status, byte[] pdu) throws RemoteException {
516         if (isEmpty()) return;
517         if (isAidl()) {
518             android.hardware.radio.messaging.CdmaSmsWriteArgs args =
519                     new android.hardware.radio.messaging.CdmaSmsWriteArgs();
520             args.status = RILUtils.convertToHalSmsWriteArgsStatusAidl(status);
521             args.message = RILUtils.convertToHalCdmaSmsMessageAidl(pdu);
522             mMessagingProxy.writeSmsToRuim(serial, args);
523         } else {
524             android.hardware.radio.V1_0.CdmaSmsWriteArgs args =
525                     new android.hardware.radio.V1_0.CdmaSmsWriteArgs();
526             args.status = RILUtils.convertToHalSmsWriteArgsStatus(status);
527             args.message = RILUtils.convertToHalCdmaSmsMessage(pdu);
528             mRadioProxy.writeSmsToRuim(serial, args);
529         }
530     }
531 
532     /**
533      * Call IRadioMessaging#writeSmsToSim
534      * @param serial Serial number of request
535      * @param status Status of message on SIM. One of:
536      *               SmsManager.STATUS_ON_ICC_READ
537      *               SmsManager.STATUS_ON_ICC_UNREAD
538      *               SmsManager.STATUS_ON_ICC_SENT
539      *               SmsManager.STATUS_ON_ICC_UNSENT
540      * @param smsc SMSC address
541      * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
542      * @throws RemoteException
543      */
writeSmsToSim(int serial, int status, String smsc, String pdu)544     public void writeSmsToSim(int serial, int status, String smsc, String pdu)
545             throws RemoteException {
546         if (isEmpty()) return;
547         if (isAidl()) {
548             android.hardware.radio.messaging.SmsWriteArgs args =
549                     new android.hardware.radio.messaging.SmsWriteArgs();
550             args.status = RILUtils.convertToHalSmsWriteArgsStatusAidl(status);
551             args.smsc = smsc;
552             args.pdu = pdu;
553             mMessagingProxy.writeSmsToSim(serial, args);
554         } else {
555             android.hardware.radio.V1_0.SmsWriteArgs args =
556                     new android.hardware.radio.V1_0.SmsWriteArgs();
557             args.status = RILUtils.convertToHalSmsWriteArgsStatus(status);
558             args.smsc = smsc;
559             args.pdu = pdu;
560             mRadioProxy.writeSmsToSim(serial, args);
561         }
562     }
563 }
564