Skip to content

Commit

Permalink
bugfix: invalidate state when remote service died
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Dec 31, 2021
1 parent 1bff5d8 commit deea8a9
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 22 deletions.
3 changes: 2 additions & 1 deletion app/src/main/cpp/libnciclient/ipc_handle_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,9 @@ Java_cc_ioctl_nfcdevicehost_ipc_daemon_IpcNativeHandler_getKernelArchitecture
(JNIEnv *env, jclass) {
struct utsname uts = {};
if (uname(&uts) != 0) {
int err = errno;
env->ThrowNew(env->FindClass("java/lang/RuntimeException"),
("uname() failed: " + std::string(strerror(errno))).c_str());
("uname() failed: " + std::string(strerror(err))).c_str());
return nullptr;
}
return env->NewStringUTF(uts.machine);
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/ncihostd/elfsym/ProcessView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ int ProcessView::readProcess(int pid) {
return errno;
}
if (read(fd, buffer, 256) != 256) {
int err = errno;
close(fd);
return errno;
return err;
}
close(fd);
if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
Expand Down
17 changes: 12 additions & 5 deletions app/src/main/cpp/ncihostd/service/front/NciHostDaemonImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ NciHostDaemonImpl::getHistoryIoOperations(uint32_t start, uint32_t count) {
return {result};
}

/**
* Get the HW service status, eg. connection with daemon, adapter status, etc.
* @tparam TargetHalHandler The target HAL handler type.
* @param halStatus The HW result service status, only valid if the return value is true.
* @param lpcResult the exception result, only valid if the return value is false.
* @param isConnected whether the HW service is connected to the daemon.
* @return true if the HW service supported by the daemon, false otherwise.
*/
template<typename TargetHalHandler>
bool getHwServiceSupportStatus(HwServiceStatus &halStatus, LpcResult &lpcResult, bool &isConnected) {
halStatus = TargetHalHandler::getHwServiceStatus();
Expand Down Expand Up @@ -237,10 +245,8 @@ bool injectIntoVendorHalService(LpcResult &lpcResult, const HwServiceStatus &hal
lpcResult = LpcResult::throwException({1, uint32_t(err), errMsg});
return false;
}
std::string shortName = [&] {
auto s = utils::splitString(soPatchPath, "/");
return s[s.size() - 1];
}();
std::string shortName = soPatchPath.find_last_of('/') == std::string::npos ? soPatchPath :
soPatchPath.substr(soPatchPath.find_last_of('/') + 1);
auto &serviceManager = ServiceManager::getInstance();
SysServicePatch servicePatch;
if (int err = servicePatch.init(shortName, fd.get(), TargetHalHandler::INIT_SYMBOL); err != 0) {
Expand Down Expand Up @@ -330,15 +336,16 @@ TypedLpcResult<bool> NciHostDaemonImpl::initHwServiceConnection(const std::vecto
// hw hal not supported
return tmpResult;
}
LOGV("NxpHalHandler connected: %d", connected);
if (!connected && !injectIntoVendorHalService<NxpHalHandler>(tmpResult, halStatus, soPath_nxphalpatch,
NxpHalHandler::TARGET_SO_NAME, nfcHalHook)) {
return tmpResult;

}
if (!getHwServiceSupportStatus<QtiEsePmHandler>(halStatus, tmpResult, connected)) {
// hw hal not supported
return tmpResult;
}
LOGV("QtiEsePmHandler connected: %d", connected);
if (!connected) {
constexpr uint32_t qtiEseHalHook = T::OPEN | T::CLOSE | T::IOCTL;
std::string shortExeName = halStatus.serviceExecPath
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/cpp/ncihostd/service/hw/BaseHwHalHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,17 @@ void BaseHwHalHandler::workerThread(BaseHwHalHandler *self) {
ssize_t i;
std::vector<uint8_t> buffer(HAL_PACKET_MAX_LENGTH);
while (true) {
errno = 0; // just in case
i = read(self->mFd, buffer.data(), HAL_PACKET_MAX_LENGTH);
if (i > 0) {
self->dispatchHwHalPatchIpcPacket(buffer.data(), i);
} else {
int err = errno;
if (err == EPIPE) {
if (err == EPIPE || err == 0) {
// remote process has closed the connection,
// is the remote process still alive?
if (access(("/proc/" + std::to_string(self->mRemotePid)).c_str(), F_OK) != 0) {
LOGW("remote process %d has died", self->mRemotePid);
// remote process is dead, notify the user
self->dispatchRemoteProcessDeathEvent();
} else {
Expand All @@ -94,11 +96,14 @@ void BaseHwHalHandler::workerThread(BaseHwHalHandler *self) {
LOGE("read() failed with EPIPE, but remote process is still alive");
}
close(self->mFd);
self->mFd = -1;
break;
} else if (err == EINTR) {
continue;
} else {
LOGE("read() failed with %d", err);
close(self->mFd);
self->mFd = -1;
break;
}
}
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/cpp/rpcprotocol/protocol/IpcTransactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ void IpcTransactor::runIpcLooper() {
epoll_event event = {};
if (epoll_wait(epollFd, &event, 1, -1) < 0) {
int err = errno;
LOGE("epoll_wait error: %d %s", err, mName.c_str());
if (err != EINTR) {
LOGE("epoll_wait error: %d %s", err, mName.c_str());
abort();
break;
}
Expand Down Expand Up @@ -349,6 +349,10 @@ int IpcTransactor::sendEventSync(uint32_t sequence, uint32_t proxyId, uint32_t e
}

int IpcTransactor::sendEventAsync(uint32_t sequence, uint32_t proxyId, uint32_t eventId, const SharedBuffer &args) {
if (mSocketFd == -1) {
// no socket, no async events
return EBADFD;
}
SharedBuffer result;
if (!result.ensureCapacity(sizeof(EventTransactionHeader) + args.size(), std::nothrow_t())) {
throw std::bad_alloc();
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/rpcprotocol/utils/FileMemMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ int FileMemMap::mapFilePath(const char *path, bool readOnly, size_t length) {
if (length == 0) {
struct stat64 fileInfo = {};
if (fstat64(fd, &fileInfo) < 0) {
int err = errno;
close(fd);
return errno;
return err;
}
length = size_t(fileInfo.st_size);
}
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/cpp/rpcprotocol/utils/SELinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ bool SELinux::isEnforcing() {
close(fd);
return result == '1';
}
int err = errno;
close(fd);
return errno == EACCES;
return err == EACCES;
}
}

Expand Down Expand Up @@ -93,8 +94,9 @@ int SELinux::getProcessSecurityContext(int pid, std::string *context) {
close(fd);
return 0;
} else {
int err = errno;
close(fd);
return -errno;
return -err;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ public void requestRootToStartDaemon() {
public boolean attachToHalService() throws IOException {
INciHostDaemon daemon = IpcNativeHandler.peekConnection();
if (daemon != null) {
if (!daemon.isHwServiceConnected()) {
INciHostDaemon.DaemonStatus status = daemon.getDaemonStatus();
INciHostDaemon.DaemonStatus status = daemon.getDaemonStatus();
if (!status.nfcHalServiceStatus.isHalServiceAttached || !status.esePmServiceStatus.isHalServiceAttached) {
if (status.nfcHalServiceStatus.halServiceArch > 0 && status.esePmServiceStatus.halServiceArch > 0) {
File nxpNfcPatchFile = NativeInterface.getNfcHalServicePatchFile(
NativeInterface.NfcHalServicePatch.NXP_NFC_HAL_PATCH,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private void submitOperation() {
byte[] bytes = baos.toByteArray();
if (bytes.length > 0) {
INciHostDaemon daemon = IpcNativeHandler.peekConnection();
if (daemon != null && daemon.isHwServiceConnected()) {
if (daemon != null && daemon.isNfcHalHwServiceConnected()) {
ThreadManager.async(() -> {
try {
int result = daemon.deviceDriverWriteRaw(bytes);
Expand Down Expand Up @@ -132,7 +132,7 @@ private void submitOperation() {
return;
}
INciHostDaemon daemon = IpcNativeHandler.peekConnection();
if (daemon != null && daemon.isHwServiceConnected()) {
if (daemon != null && daemon.isNfcHalHwServiceConnected()) {
ThreadManager.async(() -> {
try {
int result = daemon.deviceDriverIoctl0(requestValue, argValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public void onResume() {
Snackbar.make(mBinding.getRoot(), R.string.ui_toast_daemon_is_not_running, Snackbar.LENGTH_LONG)
.setAction(R.string.ui_snackbar_action_view_or_jump, v -> jumpToHomeFragment()).show();
} else {
if (!daemon.isHwServiceConnected()) {
if (!daemon.isNfcHalHwServiceConnected()) {
Snackbar.make(mBinding.getRoot(), R.string.ui_toast_hal_service_not_attached, Snackbar.LENGTH_LONG)
.setAction(R.string.ui_snackbar_action_view_or_jump, v -> jumpToHomeFragment()).show();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public interface INciHostDaemon {

boolean isDeviceSupported();

boolean isHwServiceConnected();

HistoryIoEventList getHistoryIoEvents(int startIndex, int count);

boolean clearHistoryIoEvents();
Expand All @@ -43,6 +41,10 @@ public interface INciHostDaemon {

boolean setNfcDiscoverySoundDisabled(boolean disable);

boolean isAllHwServiceConnected();

boolean isNfcHalHwServiceConnected();

interface OnRemoteEventListener {
void onIoEvent(IoEventPacket event);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,6 @@ public boolean unregisterRemoteEventListener(@NonNull OnRemoteEventListener list
@Override
public native boolean isDeviceSupported();

@Override
public native boolean isHwServiceConnected();

@Override
public native boolean initHwServiceConnection(@NonNull String[] soPath) throws IOException;

Expand Down Expand Up @@ -122,6 +119,18 @@ public boolean unregisterRemoteEventListener(@NonNull OnRemoteEventListener list
@Override
public native boolean setNfcDiscoverySoundDisabled(boolean disable);

@Override
public boolean isAllHwServiceConnected() {
DaemonStatus status = getDaemonStatus();
return status.nfcHalServiceStatus.isHalServiceAttached && status.esePmServiceStatus.isHalServiceAttached;
}

@Override
public boolean isNfcHalHwServiceConnected() {
DaemonStatus status = getDaemonStatus();
return status.nfcHalServiceStatus.isHalServiceAttached;
}

@Override
public HistoryIoEventList getHistoryIoEvents(int startIndex, int count) {
RawHistoryIoEventList raw = ntGetHistoryIoEvents(startIndex, count);
Expand Down

0 comments on commit deea8a9

Please sign in to comment.