NamedPipeCommands.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. *
  3. * Copyright (c) 2022 Project CHIP Authors
  4. * All rights reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "NamedPipeCommands.h"
  19. #include <errno.h>
  20. #include <fcntl.h>
  21. #include <lib/support/CodeUtils.h>
  22. #include <pthread.h>
  23. #include <sys/stat.h>
  24. #include <sys/types.h>
  25. #include <unistd.h>
  26. static constexpr const size_t kChipEventCmdBufSize = 256;
  27. CHIP_ERROR NamedPipeCommands::Start(std::string & path, NamedPipeCommandDelegate * delegate)
  28. {
  29. VerifyOrReturnError(!mStarted, CHIP_NO_ERROR);
  30. VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
  31. mStarted = true;
  32. mDelegate = delegate;
  33. mChipEventFifoPath = path;
  34. // Creating the named file(FIFO)
  35. VerifyOrReturnError((mkfifo(path.c_str(), 0666) == 0) || (errno == EEXIST), CHIP_ERROR_OPEN_FAILED);
  36. VerifyOrReturnError(
  37. pthread_create(&mChipEventCommandListener, nullptr, EventCommandListenerTask, reinterpret_cast<void *>(this)) == 0,
  38. CHIP_ERROR_UNEXPECTED_EVENT);
  39. return CHIP_NO_ERROR;
  40. }
  41. CHIP_ERROR NamedPipeCommands::Stop()
  42. {
  43. VerifyOrReturnError(mStarted, CHIP_NO_ERROR);
  44. mStarted = false;
  45. mDelegate = nullptr;
  46. VerifyOrReturnError(pthread_cancel(mChipEventCommandListener) == 0, CHIP_ERROR_CANCELLED);
  47. // Wait further for the thread to terminate if we had previously created it.
  48. VerifyOrReturnError(pthread_join(mChipEventCommandListener, nullptr) == 0, CHIP_ERROR_SHUT_DOWN);
  49. VerifyOrReturnError(unlink(mChipEventFifoPath.c_str()) == 0, CHIP_ERROR_WRITE_FAILED);
  50. mChipEventFifoPath.clear();
  51. return CHIP_NO_ERROR;
  52. }
  53. void * NamedPipeCommands::EventCommandListenerTask(void * arg)
  54. {
  55. char readbuf[kChipEventCmdBufSize];
  56. NamedPipeCommands * self = reinterpret_cast<NamedPipeCommands *>(arg);
  57. for (;;)
  58. {
  59. int fd = open(self->mChipEventFifoPath.c_str(), O_RDONLY);
  60. if (fd == -1)
  61. {
  62. ChipLogError(NotSpecified, "Failed to open Event FIFO");
  63. break;
  64. }
  65. ssize_t readBytes = read(fd, readbuf, kChipEventCmdBufSize);
  66. readbuf[readBytes - 1] = '\0';
  67. ChipLogProgress(NotSpecified, "Received payload: \"%s\"", readbuf);
  68. // Process the received command request from event fifo
  69. self->mDelegate->OnEventCommandReceived(readbuf);
  70. close(fd);
  71. }
  72. return nullptr;
  73. }