【鸿蒙南向开发】OpenHarmerny 短彩信之Framework系统源码解析

简介

短彩信系统框架层,以OpenHarmerny SystemAbility 系统常驻服务,为上层提供JS API 接口,下层适配不同硬件厂商Modem。提供短彩信系统框架功能业务,提供短信收发和彩信编解码基础能力;主要功能有GSM/CDMA短信收发、短信PDU(Protocol data unit,协议数据单元)编解码、Wap Push接收处理 、小区广播接收、彩信通知、 彩信编解码和SIM卡短信记录增删改查等。

架构图

image.png

Framework框架图

短彩信服务通过safwk组件实现SystemAbility 注册、启动等相关接口;短彩信Framework由接口管理类、短信发送管理类、短信接收管理类,和彩信编解码工具类组成。

  • 接口管理类:SmsInterfaceManager 负责对外提供短信发送、SIM卡短信记录操作和配置相关接口,负责创建SmsSendManager 、SmsReceiveManager和smsMiscManager 对象。
  • 短信发送管理类: SmsSendManager创建GSM(GsmSmsSender) 、CDMA(CdmaSmsSender) 和网络策略管理(SmsNetworkPolicyManager)对象,并根据网络制式调度对应的GSM或CDMA对象发送短信。
  • 短信接收管理类: SmsReceiveManager 负责短信接收,监听来自RIL层的新短信信息;创建GSM(GsmSmsReceiveHandler) 和CDMA(CdmaSmsReceiveHandler) 对象;创建SmsWapPushHandler 和SmsCellBroadcastHandler 对象。
  • 彩信编解码类:负责彩信PDU的编解码处理。
  • Misc管理类:负责Sim卡短信操作、小区广播配置、短信服务中心地址配置和默认卡槽配置等

代码结构

Interfaces对外提供暴露接口,包括JS 接口定义,napi native C++ 的JS接口封装;frameworks 包括Native 接口定义和彩信编解码对外暴露的工具; sa_profile 提供SystemAbility 启动配置文件; sercives 包含了短信框架内部服务相关代码包括Gsm/Cdma Pdu 编解码工具和接收处理业务逻辑代码。

/base/telephony/sms_mms
├─ frameworks        # 短彩信内部框架接口层
├─ interfaces        # 对外暴露的接口
│ ├─ innerkits
│ └─ kits
├─ sa_profile        # 启动配置文件
├─ services         # 服务内部代码
│ ├─ include        # 头文件目录
│ ├─ cdma         # CDMA制式源文件
│ └─ gsm          # GSM制式源文件
├─ test           # 单元测试目录
└─ utils          # 通用工具相关

发送短信时序图

应用程序调用API发送短信,经过参数判断、鉴权、长短信拆分、PDU编码;添加到发送队列,调用RIL发送短信接口发送短信到接收端。并将发送状态返回应用调用者,完成一次短信发送过程。

  1. 上层应用调用发送短信的API JS接口,调用JS Napi 接口;

  2. JS Napi 调用Native 层C++ SendMessage 跨IPC 到SmsInterfaceManager对象;

  3. SmsInterfaceManager根据过滤策略来过滤掉短信和参数合法性检查;

  4. SmsInterfaceManager进行鉴权检查;

  5. SmsInterfaceManager调用TextBasedSmsDelivery或TextBasedSmsDelivery到SmsSendManager;

  6. SmsSendManager调用搜网服务来获取SIM卡和网络状态;

  7. GSM网络将创建GsmSmsSender,CDMA网络将创建CdmaSmsSender;

  8. GsmSmsSender或CdmaSmsSender将短信拆分并进行PDU编码然后放到队列中;

  9. 通过接口将短信发送到RIL层;

  10. 如果返回的状态失败将启动重发机制;

  11. 返回应用层发送的状态信息;

image.png

发送短信时序图

短信接收时序图

  1. SmsReceiveManager创建GsmSmsReceiveHandler和CdmaSmsReceiveHandler;

  2. GsmSmsReceiveHandler和CdmaSmsReceiveHandler分别注册事件到RIL层;

  3. RIL Adapter上报短信事件;

  4. GsmSmsReceiveHandler或CdmaSmsReceiveHandler调用SmsBaseMessage解析PDU数据。

  5. GsmSmsReceiveHandler和CdmaSmsReceiveHandler过滤无效短信;根据PDU头部信息将多段消息合并;

  6. 拦截黑名单短信;

  7. 将接收处理状态应答到RIL;

  8. 广播发送接收处理的短信信息到广播接收者;

image.png

接收短信时序图

代码分析

1.SmsService 启动

服务入口类 SmsService.cpp 继承safwk组件的SystemAblility类;由SA系统服务管理框架(samgr)拉起服务。采用telephony.cfg + profile.xml + libtel_sms_mms.z.so的方式由init进程执行对应的telephony.cfg文件拉起SmsService SystemAbility对应的telephony进程,并执行void SmsService::OnStart()

class SmsService : public SystemAbility, public SmsInterfaceStub {
    DECLARE_DELAYED_SINGLETON(SmsService)
    DECLARE_SYSTEM_ABILITY(SmsService) // necessary
public:
    void OnStart() override;
    void OnStop() override;
private:
    constexpr static uint32_t CONNECT_SERVICE_WAIT_TIME = 2000; // ms
    bool Init();
    bool registerToService_ = false;
    ServiceRunningState state_ = ServiceRunningState::STATE_NOT_START;
};
} // namespace Telephony
} // namespace OHOS

2.模块初始化

SmsService 服务启动后,调用OnStart() 函数;并创建服务内部类,初始化内部资源,包括SmsInterfaceManager、SmsSendManager、SmsReceiveManager 对象创建和初始化

void SmsService::OnStart()
{
    TELEPHONY_LOGI("SmsService::OnStart start service Enter.");
    if (state_ == ServiceRunningState::STATE_RUNNING) {
        TELEPHONY_LOGE("msService has already started.");
        return;
    }
    if (!Init()) {
        TELEPHONY_LOGE("failed to init SmsService");
        return;
    }
    state_ = ServiceRunningState::STATE_RUNNING;
    TELEPHONY_LOGI("SmsService::OnStart start service Exit.");
}

bool SmsService::Init()
{
    if (!registerToService_) {
        WaitCoreServiceToInit();
    }
    return true;
}

//等待核心服务完成初始化,并调用InitModule 初始化内部内部代码
void SmsService::WaitCoreServiceToInit()
{
    std::thread connectTask([&]() {
        while (true) {
            TELEPHONY_LOGI("connect core service ...");
            if (CoreManagerInner::GetInstance().IsInitFinished()) {
                InitModule();
                TELEPHONY_LOGI("SmsService Connection successful");
                break;
            }
       std::this_thread::sleep_for(milliseconds(CONNECT_SERVICE_WAIT_TIME));
       }
    });
    connectTask.detach();
}

3.服务对外提供Native IPC 接口实现

SmsService.cpp 继承SmsInterfaceStub.cpp ;SmsInterfaceStub 是native层对外接口IPC服务端代码,继承了并实现了IPC 对外接口ISmsServiceInterface用于跨进程对外提供navtive C++ API 接口; OnRemoteRequest() 是服务端的请求入口,通过请求Id 遍历memberFuncMap_ 调用对应的实现方法

int SmsInterfaceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option){
    int32_t result = 0;
    std::u16string myDescripter = SmsInterfaceStub::GetDescriptor();
    std::u16string remoteDescripter = data.ReadInterfaceToken();
    if (myDescripter == remoteDescripter) {
        auto itFunc = memberFuncMap_.find(code);
        if (itFunc != memberFuncMap_.end()) {
            auto memberFunc = itFunc->second;
            if (memberFunc != nullptr) {
                (this->*memberFunc)(data, reply, option);
            } else {
                TELEPHONY_LOGE("memberFunc is nullptr");
            }
        } else {
            TELEPHONY_LOGE("itFunc was not found");
        }
    } else {
        TELEPHONY_LOGE("descriptor checked fail");
        return result;
}

// 添加memberFuncMap 请求处理函数
SmsInterfaceStub::SmsInterfaceStub()
{
    memberFuncMap_[TEXT_BASED_SMS_DELIVERY] = &SmsInterfaceStub::OnSendSmsTextRequest;
    memberFuncMap_[DATA_BASED_SMS_DELIVERY] = &SmsInterfaceStub::OnSendSmsDataRequest;
    memberFuncMap_[SET_SMSC_ADDRESS] = &SmsInterfaceStub::OnSetSmscAddr;
    memberFuncMap_[GET_SMSC_ADDRESS] = &SmsInterfaceStub::OnGetSmscAddr;
    memberFuncMap_[ADD_SIM_MESSAGE] = &SmsInterfaceStub::OnAddSimMessage;
    memberFuncMap_[DEL_SIM_MESSAGE] = &SmsInterfaceStub::OnDelSimMessage;
    memberFuncMap_[UPDATE_SIM_MESSAGE] = &SmsInterfaceStub::OnUpdateSimMessage;
    memberFuncMap_[GET_ALL_SIM_MESSAGE] = &Sms
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值