/* * * Copyright (c) 2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "NamedPipeCommands.h" #include #include #include #include #include #include #include #include static constexpr const size_t kChipEventCmdBufSize = 256; CHIP_ERROR NamedPipeCommands::Start(std::string & path, NamedPipeCommandDelegate * delegate) { VerifyOrReturnError(!mStarted, CHIP_NO_ERROR); VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); mStarted = true; mDelegate = delegate; mChipEventFifoPath = path; // Creating the named file(FIFO) VerifyOrReturnError((mkfifo(path.c_str(), 0666) == 0) || (errno == EEXIST), CHIP_ERROR_OPEN_FAILED); VerifyOrReturnError( pthread_create(&mChipEventCommandListener, nullptr, EventCommandListenerTask, reinterpret_cast(this)) == 0, CHIP_ERROR_UNEXPECTED_EVENT); return CHIP_NO_ERROR; } CHIP_ERROR NamedPipeCommands::Stop() { VerifyOrReturnError(mStarted, CHIP_NO_ERROR); mStarted = false; mDelegate = nullptr; VerifyOrReturnError(pthread_cancel(mChipEventCommandListener) == 0, CHIP_ERROR_CANCELLED); // Wait further for the thread to terminate if we had previously created it. VerifyOrReturnError(pthread_join(mChipEventCommandListener, nullptr) == 0, CHIP_ERROR_SHUT_DOWN); VerifyOrReturnError(unlink(mChipEventFifoPath.c_str()) == 0, CHIP_ERROR_WRITE_FAILED); mChipEventFifoPath.clear(); return CHIP_NO_ERROR; } void * NamedPipeCommands::EventCommandListenerTask(void * arg) { char readbuf[kChipEventCmdBufSize]; NamedPipeCommands * self = reinterpret_cast(arg); for (;;) { int fd = open(self->mChipEventFifoPath.c_str(), O_RDONLY); if (fd == -1) { ChipLogError(NotSpecified, "Failed to open Event FIFO"); break; } ssize_t readBytes = read(fd, readbuf, kChipEventCmdBufSize); readbuf[readBytes - 1] = '\0'; ChipLogProgress(NotSpecified, "Received payload: \"%s\"", readbuf); // Process the received command request from event fifo self->mDelegate->OnEventCommandReceived(readbuf); close(fd); } return nullptr; }