cdma 复制短息到uim卡的实现


     首先, 在ril.cpp 中  。 把短信pdu 写到uim卡上的函数为:


    static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {


    RIL_CDMA_SMS_WriteArgs rcsw;


    int32_t  t;


    uint32_t ut;


    uint8_t  uct;


    status_t status;


    int32_t  digitCount;






    memset(&rcsw, 0, sizeof(rcsw));






    status = p.readInt32(&t);


    rcsw.status = t;






    status = p.readInt32(&t);


    rcsw.message.uTeleserviceID = (int) t;






    status = p.read(&uct,sizeof(uct));


    rcsw.message.bIsServicePresent = (uint8_t) uct;






    status = p.readInt32(&t);


    rcsw.message.uServicecategory = (int) t;






    status = p.readInt32(&t);


    rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;






    status = p.readInt32(&t);


    rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;






    status = p.readInt32(&t);


    rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;






    status = p.readInt32(&t);


    rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;






    status = p.read(&uct,sizeof(uct));


    rcsw.message.sAddress.number_of_digits = (uint8_t) uct;






    for(digitCount = 0 ; digitCount < rcsw.message.sAddress.number_of_digits; digitCount ++) {


        status = p.read(&uct,sizeof(uct));


        rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;


    }






    status = p.readInt32(&t);


    rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;






    status = p.read(&uct,sizeof(uct));


    rcsw.message.sSubAddress.odd = (uint8_t) uct;






    status = p.read(&uct,sizeof(uct));


    rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;






    for(digitCount = 0 ; digitCount < rcsw.message.sSubAddress.number_of_digits; digitCount ++) {


        status = p.read(&uct,sizeof(uct));


        rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;


    }






    status = p.readInt32(&t);


    rcsw.message.uBearerDataLen = (int) t;






    for(digitCount = 0 ; digitCount < rcsw.message.uBearerDataLen; digitCount ++) {


        status = p.read(&uct, sizeof(uct));


        rcsw.message.aBearerData[digitCount] = (uint8_t) uct;


    }






    if (status != NO_ERROR) {


        goto invalid;


    }






    startRequest;


    appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \


            message.uServicecategory=%d, message.sAddress.digit_mode=%d, \


            message.sAddress.number_mode=%d, \


            message.sAddress.number_type=%d, ",


            printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,


            rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,


            rcsw.message.sAddress.number_mode,


            rcsw.message.sAddress.number_type);


    closeRequest;






    printRequest(pRI->token, pRI->pCI->requestNumber);






    s_callbacks[pRI->client_id].onRequest(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI);






#ifdef MEMSET_FREED


    memset(&rcsw, 0, sizeof(rcsw));


#endif






    return;






invalid:


    invalidCommandBlock(pRI);


    return;






}


  对应的 ril.java 中的函数为 :
    public void writeSmsToRuim(int status, String pdu, Message response) {
        status = translateStatus(status);


        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM,
                response);


        rr.mp.writeInt(status);
        //rr.mp.writeString(pdu);
        constructCdmaWriteSmsRilRequest(rr,IccUtils.hexStringToBytes(pdu));


        if (Config.LOGD) {
            riljLog(pdu);
            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
                    + requestToString(rr.mRequest)
                    + " " + status);
        }


        send(rr);
    }


调用了 constructCdmaWriteSmsRilRequest 这个函数,具体实现为:


    private void
    constructCdmaWriteSmsRilRequest(RILRequest rr, byte[] pdu) {
        int address_nbr_of_digits;
        int subaddr_nbr_of_digits;
        int bearerDataLength;
        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
        DataInputStream dis = new DataInputStream(bais);


        try {
//            int status = dis.readInt();
//            rr.mp.writeInt(status); //status
            int teleServiceId = dis.readInt();
            rr.mp.writeInt(teleServiceId); //teleServiceId ,int
            byte servicePresent =  (byte)dis.readByte();
            rr.mp.writeByte(servicePresent); //servicePresent, byte
            int serviceCategory = dis.readInt();
            rr.mp.writeInt(serviceCategory); //serviceCategory, int
            int address_digit_mode = dis.readInt();
            rr.mp.writeInt(address_digit_mode); //address_digit_mode, int
            int address_nbr_mode = dis.readInt();
            rr.mp.writeInt(address_nbr_mode); //address_nbr_mode,int
            int address_ton = dis.readInt();
            rr.mp.writeInt(address_ton); //address_ton,int
            int address_nbr_plan = dis.readInt();
            rr.mp.writeInt(address_nbr_plan); //address_nbr_plan,int
            address_nbr_of_digits = (byte) dis.readByte();//byte
            rr.mp.writeByte((byte) address_nbr_of_digits);
            for(int i=0; i < address_nbr_of_digits; i++){
                rr.mp.writeByte(dis.readByte()); // address_orig_bytes[i]
            }
            int subaddressType = dis.readInt();//int
            rr.mp.writeInt(subaddressType); //subaddressType
            byte subaddr_odd = (byte) dis.readByte();
            rr.mp.writeByte(subaddr_odd); //subaddr_odd
            subaddr_nbr_of_digits = (byte) dis.readByte();
            rr.mp.writeByte((byte) subaddr_nbr_of_digits);
            for(int i=0; i < subaddr_nbr_of_digits; i++){
                rr.mp.writeByte(dis.readByte()); //subaddr_orig_bytes[i]
            }


            bearerDataLength = dis.readInt();
            rr.mp.writeInt(bearerDataLength);
            for(int i=0; i < bearerDataLength; i++){
                rr.mp.writeByte(dis.readByte()); //bearerData[i]
            }


            riljLog(" teleServiceId="+ teleServiceId + " servicePresent=" + servicePresent
                + " serviceCategory=" + serviceCategory +" address_digit_mode=" + address_digit_mode+ " address_nbr_mode="
                + address_nbr_mode + " address_ton=" + address_ton + " address_nbr_plan=" + address_nbr_plan + " address_nbr_of_digits="
                 + address_nbr_of_digits + " subaddressType=" + subaddressType + " subaddr_odd= " + subaddr_odd + " subaddr_nbr_of_digits="
                + subaddr_nbr_of_digits + " bearerDataLength=" + bearerDataLength);
        }catch (IOException ex){
            if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: "
                    + ex);
        }finally{
            try{
                if(null != bais){
                    bais.close();
                }


                if(null != dis){
                    dis.close();
                }
            }catch(IOException e){


            }


        }
    }


    所以在我们对短信pdu打包的过程中,需要对应相应的数据和类型。   
    在SmsMessage.java (frameworks\base\telephony\java\com\android\internal\telephony\cdma)这个类中。 有对短信pdu打包的函数:
    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
            boolean statusReportRequested, SmsHeader smsHeader) {


        /**
         * TODO(cleanup): Do we really want silent failure like this?
         * Would it not be much more reasonable to make sure we don't
         * call this function if we really want nothing done?
         */
        if (message == null || destAddr == null) {
            return null;
        }


        UserData uData = new UserData();
        uData.payloadStr = message;
        uData.userDataHeader = smsHeader;
        return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
    }


    其中privateGetSubmitPdu  函数的具体实现为:


        /**
     * Creates BearerData and Envelope from parameters for a Submit SMS.
     * @return byte stream for SubmitPdu.
     */
    private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
            UserData userData) {
       // 此处省略部分代码 
        //…................................
        //…................................


        try {
            /**
             * TODO(cleanup): reference a spec and get rid of the ugly comments
             */
            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeInt(envelope.teleService);
            dos.writeByte(0); //servicePresent
            dos.writeInt(0); //serviceCategory
            dos.writeInt(destAddr.digitMode);
            dos.writeInt(destAddr.numberMode);
            dos.writeInt(destAddr.ton); // number_type
            dos.writeInt(destAddr.numberPlan);
            dos.writeByte(destAddr.numberOfDigits);
            dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
            // Subaddress is not supported.
            dos.writeInt(0); //subaddressType
            dos.writeByte(0); //subaddr_odd
            dos.writeByte(0); //subaddr_nbr_of_digits
            dos.writeInt(encodedBearerData.length);
            dos.write(encodedBearerData, 0, encodedBearerData.length);
            dos.close();


            SubmitPdu pdu = new SubmitPdu();
            pdu.encodedMessage = baos.toByteArray();
            pdu.encodedScAddress = null;
            return pdu;
        } catch(IOException ex) {
            Log.e(LOG_TAG, "creating SubmitPdu failed: ", ex);
        }
        return null;
    }


调用 getSubmitPdu 这个函数,可以得到一个 SubmitPdu 对象, 里面的encodedMessage 这个成员, 正是我们打包的pdu byte 数组 。 调用 
SmsManager.getDefault().copyMessageToIcc(null, pdu.encodedMessage, SmsManager.STATUS_ON_ICC_SENT, subscription);
方法就可以实现 复制短信到uim卡 。具体实现:
    private boolean copyToSim(MessageItem msgItem, int subscription) {


        int boxId = msgItem.mBoxId;


        String address = msgItem.mAddress;


        String text = msgItem.mBody;


        long timestamp = msgItem.mDate != 0 ? msgItem.mDate : System.currentTimeMillis();






        ArrayList<String> messages = SmsManager.getDefault().divideMessage(text);


        boolean ret = true;


        for (String message : messages) {


            if (Sms.isOutgoingFolder(boxId)) {


                SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(null, address, message, false);


                ret &= SmsManager.getDefault().copyMessageToIcc(null, pdu.encodedMessage,


                        SmsManager.STATUS_ON_ICC_SENT, subscription);


            } else {


                byte[] pdu = MessageUtils.getDeliveryPdu(null, address, message, timestamp);


                ret &= SmsManager.getDefault().copyMessageToIcc(null, pdu,


                        SmsManager.STATUS_ON_ICC_READ, subscription);


            }


            if (!ret) {


                break;


            }


        }


        return ret;


    }
  函数getDeliveryPdu , 是在短信的 MessageUtils 中实现的方法。打包过程,和 privateGetSubmitPdu 这个方法一样 。
注: 参数SmsManager.STATUS_ON_ICC_SENT, SmsManager.STATUS_ON_ICC_READ,  是代表发送还是接受的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值