CHRE: "chre" socket server, client and slpi-chre的交互流程

本文详细解析了CHRE框架中的主机端(chre/host/)代码,特别是`chre/host/msm/daemon/chre_daemon.cc`中的RX/TX线程。TX线程负责处理来自socket客户端的请求,RX线程则处理来自slpi的数据。通过`SocketServer`服务,客户端的消息经过`handleNanoappMessage`处理并调用nanoApp的handleEvent函数。整个流程涉及事件循环、消息队列以及客户端回调函数的交互,深入阐述了CHRE中AP与slpi_chre之间的通信机制。
摘要由CSDN通过智能技术生成

Chre整体框架 

chre/host/路径下代码的含义

host是站在slpi chre的角度去看,指的是AP。

A collection of CHRE-related code that runs on the host processor. Note that   "host" in this case refers to CHRE's perspective of host, i.e. it's the applications processor, as opposed to the Android build perspective, where host
refers to the PC making the build.

chre/host/msm/daemon/chre_daemon.cc

The daemon that hosts CHRE on the SLPI via FastRPC.
 * Several threads are required for this functionality:
 *   - Main thread: blocked waiting on SIGINT/SIGTERM, and requests graceful
 *     shutdown of CHRE when caught
 *   - Monitor thread: persistently blocked in a FastRPC call to the SLPI that
 *     only returns when CHRE exits or the SLPI crashes

 *   - Reverse monitor thread: after initializing the SLPI-side monitor for this
 *     process, blocks on a condition variable. If this thread exits, CHRE on
 *     the SLPI side will be notified and shut down (this is only possible if
 *     this thread is not blocked in a FastRPC call).

 *   - Message to host (RX) thread: blocks in FastRPC call, waiting on incoming
 *     message from CHRE
 *   - Message to CHRE (TX) thread: blocks waiting on outbound queue, delivers
 *     messages to CHRE over FastRPC

这里只关心 RX/ TX thread

TX thead

tx thread指的是有socket client he socket server连接,socket service通过TX thread接收到client的请求。

server.run("chre", true, onMessageReceivedFromClient);//意思是启动socket server:chre,并通过onMessageReceivedFromClient处理来着连接到chre的请求。

::android::chre::SocketServer server;

void SocketServer::run(const char *socketName, bool allowSocketCreation,
                       ClientMessageCallback clientMessageCallback) {
  mClientMessageCallback = clientMessageCallback;//下面会用到mClientMessageCallback

 {
    mSockFd = socket_local_server(socketName,
                                  ANDROID_SOCKET_NAMESPACE_RESERVED,
                                  SOCK_SEQPACKET);
  }

{
    int ret = listen(mSockFd, kMaxPendingConnectionRequests);
   {
      serviceSocket();
    }
    close(mSockFd);
  }
}

void SocketServer::serviceSocket() {
  LOGI("Ready to accept connections");
  while (!sSignalReceived) {
    int ret = ppoll(mPollFds, 1 + kMaxActiveClients, nullptr, &signalMask);

    if (mPollFds[kListenIndex].revents & POLLIN) {
      acceptClientConnection();
    }

    for (size_t i = 1; i <= kMaxActiveClients; i++) {
      if (mPollFds[i].revents & POLLIN) {
        handleClientData(mPollFds[i].fd);
      }
    }
  }
}

 

void SocketServer::handleClientData(int clientSocket) {
  const ClientData& clientData = mClients[clientSocket];
  uint16_t clientId = clientData.clientId;

  ssize_t packetSize = recv(
      clientSocket, mRecvBuffer.data(), mRecvBuffer.size(), MSG_DONTWAIT);
    LOGV("Got %zd byte packet from client %" PRIu16, packetSize, clientId);
    mClientMessageCallback(clientId, mRecvBuffer.data(), packetSize);
  }
}

mClientMessageCallback就是注册的onMessageReceivedFromClient

void onMessageReceivedFromClient(uint16_t clientId, void *data, size_t length) {
  constexpr size_t kMaxPayloadSize = 1024 * 1024;  // 1 MiB

  // This limitation is due to FastRPC, but there's no case where we should come
  // close to this limit...
  static_assert(kMaxPayloadSize <= INT32_MAX,
                "SLPI uses 32-bit signed integers to represent message size");
  if (!HostProtocolHost::mutateHostClientId(data, length, clientId)) {
    LOGE("Couldn't set host client ID in message container!");
  } else {
    LOGV("Delivering message from host (size %zu)", length);
    log_buffer(static_cast<const uint8_t *>(data), length);
    int ret = chre_slpi_deliver_message_from_host(
        static_cast<const unsigned char *>(data), static_cast<int>(length));
  }
}

只是进行了简单数据验证:mutateHostClientId,然后通过fatRPC调入slpi_chre环境另一个cpu/dsp

chre/platform/slpi/host_link.cc

/**
 * FastRPC method invoked by the host to send a message to the system
 *
 * @param buffer
 * @param size
 *
 * @return 0 on success, nonzero on failure
 */
extern "C" int chre_slpi_deliver_message_from_host(const unsigned char *message,
                                                   int messageLen) {
  if (!HostProtocolChre::decodeMessageFromHost(
      message, static_cast<size_t>(messageLen))) {
    LOGE("Failed to decode/handle message");
  } 

}

 下面以两种类型的Message为例,对具体NanoApp的message和对整个chre的message

bool HostProtocolChre::decodeMes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值