LocIpc.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  2. *
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are
  5. * met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above
  9. * copyright notice, this list of conditions and the following
  10. * disclaimer in the documentation and/or other materials provided
  11. * with the distribution.
  12. * * Neither the name of The Linux Foundation, nor the names of its
  13. * contributors may be used to endorse or promote products derived
  14. * from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  17. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  20. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  23. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  24. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  25. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  26. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. */
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <errno.h>
  32. #include <netinet/in.h>
  33. #include <netdb.h>
  34. #include <loc_misc_utils.h>
  35. #include <log_util.h>
  36. #include <LocIpc.h>
  37. #include <algorithm>
  38. using namespace std;
  39. namespace loc_util {
  40. #ifdef LOG_TAG
  41. #undef LOG_TAG
  42. #endif
  43. #define LOG_TAG "LocSvc_LocIpc"
  44. #define SOCK_OP_AND_LOG(buf, length, opable, rtv, exe) \
  45. if (nullptr == (buf) || 0 == (length)) { \
  46. LOC_LOGe("Invalid inputs: buf - %p, length - %u", (buf), (length)); \
  47. } else if (!(opable)) { \
  48. LOC_LOGe("Invalid object: operable - %d", (opable)); \
  49. } else { \
  50. rtv = (exe); \
  51. if (-1 == rtv) { \
  52. LOC_LOGw("failed reason: %s", strerror(errno)); \
  53. } \
  54. }
  55. const char Sock::MSG_ABORT[] = "LocIpc::Sock::ABORT";
  56. const char Sock::LOC_IPC_HEAD[] = "$MSGLEN$";
  57. ssize_t Sock::send(const void *buf, uint32_t len, int flags, const struct sockaddr *destAddr,
  58. socklen_t addrlen) const {
  59. ssize_t rtv = -1;
  60. SOCK_OP_AND_LOG(buf, len, isValid(), rtv, sendto(buf, len, flags, destAddr, addrlen));
  61. return rtv;
  62. }
  63. ssize_t Sock::recv(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb, int flags,
  64. struct sockaddr *srcAddr, socklen_t *addrlen, int sid) const {
  65. ssize_t rtv = -1;
  66. if (-1 == sid) {
  67. sid = mSid;
  68. } // else it sid would be connection based socket id for recv
  69. SOCK_OP_AND_LOG(dataCb.get(), mMaxTxSize, isValid(), rtv,
  70. recvfrom(recver, dataCb, sid, flags, srcAddr, addrlen));
  71. return rtv;
  72. }
  73. ssize_t Sock::sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr,
  74. socklen_t addrlen) const {
  75. ssize_t rtv = -1;
  76. if (len <= mMaxTxSize) {
  77. rtv = ::sendto(mSid, buf, len, flags, destAddr, addrlen);
  78. } else {
  79. std::string head(LOC_IPC_HEAD + to_string(len));
  80. rtv = ::sendto(mSid, head.c_str(), head.length(), flags, destAddr, addrlen);
  81. if (rtv > 0) {
  82. for (size_t offset = 0; offset < len && rtv > 0; offset += rtv) {
  83. rtv = ::sendto(mSid, (char*)buf + offset, min(len - offset, (size_t)mMaxTxSize),
  84. flags, destAddr, addrlen);
  85. }
  86. rtv = (rtv > 0) ? (head.length() + len) : -1;
  87. }
  88. }
  89. return rtv;
  90. }
  91. ssize_t Sock::recvfrom(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb,
  92. int sid, int flags, struct sockaddr *srcAddr, socklen_t *addrlen) const {
  93. std::string msg(mMaxTxSize, 0);
  94. ssize_t nBytes = ::recvfrom(sid, (void*)msg.data(), msg.size(), flags, srcAddr, addrlen);
  95. if (nBytes > 0) {
  96. if (strncmp(msg.data(), MSG_ABORT, sizeof(MSG_ABORT)) == 0) {
  97. LOC_LOGi("recvd abort msg.data %s", msg.data());
  98. nBytes = -100;
  99. } else if (strncmp(msg.data(), LOC_IPC_HEAD, sizeof(LOC_IPC_HEAD) - 1)) {
  100. // short message
  101. msg.resize(nBytes);
  102. dataCb->onReceive(msg.data(), nBytes, &recver);
  103. } else {
  104. // long message
  105. size_t msgLen = 0;
  106. sscanf(msg.data() + sizeof(LOC_IPC_HEAD) - 1, "%zu", &msgLen);
  107. msg.resize(msgLen);
  108. for (size_t msgLenReceived = 0; (msgLenReceived < msgLen) && (nBytes > 0);
  109. msgLenReceived += nBytes) {
  110. nBytes = ::recvfrom(sid, &(msg[msgLenReceived]), msg.size() - msgLenReceived,
  111. flags, srcAddr, addrlen);
  112. }
  113. if (nBytes > 0) {
  114. nBytes = msgLen;
  115. dataCb->onReceive(msg.data(), nBytes, &recver);
  116. }
  117. }
  118. }
  119. return nBytes;
  120. }
  121. ssize_t Sock::sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen) {
  122. return send(MSG_ABORT, sizeof(MSG_ABORT), flags, destAddr, addrlen);
  123. }
  124. class LocIpcLocalSender : public LocIpcSender {
  125. protected:
  126. shared_ptr<Sock> mSock;
  127. struct sockaddr_un mAddr;
  128. inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); }
  129. inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
  130. return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
  131. }
  132. public:
  133. inline LocIpcLocalSender(const char* name) : LocIpcSender(),
  134. mSock(nullptr),
  135. mAddr({.sun_family = AF_UNIX, {}}) {
  136. int fd = -1;
  137. if (nullptr != name) {
  138. fd = ::socket(AF_UNIX, SOCK_DGRAM, 0);
  139. if (fd >= 0) {
  140. timeval timeout;
  141. timeout.tv_sec = 2;
  142. timeout.tv_usec = 0;
  143. setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
  144. }
  145. }
  146. mSock.reset(new Sock(fd));
  147. if (mSock != nullptr && mSock->isValid()) {
  148. snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name);
  149. }
  150. }
  151. };
  152. class LocIpcLocalRecver : public LocIpcLocalSender, public LocIpcRecver {
  153. protected:
  154. inline virtual ssize_t recv() const override {
  155. socklen_t size = sizeof(mAddr);
  156. return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
  157. }
  158. public:
  159. inline LocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener, const char* name) :
  160. LocIpcLocalSender(name), LocIpcRecver(listener, *this) {
  161. if ((unlink(mAddr.sun_path) < 0) && (errno != ENOENT)) {
  162. LOC_LOGw("unlink socket error. reason:%s", strerror(errno));
  163. }
  164. umask(0157);
  165. if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) {
  166. LOC_LOGe("bind socket error. sock fd: %d: %s, reason: %s", mSock->mSid,
  167. mAddr.sun_path, strerror(errno));
  168. mSock->close();
  169. }
  170. }
  171. inline virtual ~LocIpcLocalRecver() { unlink(mAddr.sun_path); }
  172. inline virtual const char* getName() const override { return mAddr.sun_path; };
  173. inline virtual void abort() const override {
  174. if (isSendable()) {
  175. mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr));
  176. }
  177. }
  178. };
  179. class LocIpcInetSender : public LocIpcSender {
  180. protected:
  181. int mSockType;
  182. shared_ptr<Sock> mSock;
  183. const string mName;
  184. sockaddr_in mAddr;
  185. inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); }
  186. virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
  187. return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
  188. }
  189. public:
  190. inline LocIpcInetSender(const LocIpcInetSender& sender) :
  191. mSockType(sender.mSockType), mSock(sender.mSock),
  192. mName(sender.mName), mAddr(sender.mAddr) {
  193. }
  194. inline LocIpcInetSender(const char* name, int32_t port, int sockType) : LocIpcSender(),
  195. mSockType(sockType),
  196. mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_INET, mSockType, 0)))),
  197. mName((nullptr == name) ? "" : name),
  198. mAddr({.sin_family = AF_INET, .sin_port = htons(port),
  199. .sin_addr = {htonl(INADDR_ANY)}}) {
  200. if (mSock != nullptr && mSock->isValid() && nullptr != name) {
  201. struct hostent* hp = gethostbyname(name);
  202. if (nullptr != hp) {
  203. memcpy((char*)&(mAddr.sin_addr.s_addr), hp->h_addr_list[0], hp->h_length);
  204. }
  205. }
  206. }
  207. unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) override {
  208. return make_unique<SockRecver>(listener, *this, mSock);
  209. }
  210. };
  211. class LocIpcInetTcpSender : public LocIpcInetSender {
  212. protected:
  213. mutable bool mFirstTime;
  214. virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
  215. int connStatus = 0;
  216. if (mFirstTime) {
  217. connStatus = ::connect(mSock->mSid, (const struct sockaddr*)&mAddr, sizeof(mAddr));
  218. if (0 == connStatus) {
  219. mFirstTime = false;
  220. }
  221. }
  222. if (0 == connStatus) {
  223. return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
  224. }
  225. return 0;
  226. }
  227. public:
  228. inline LocIpcInetTcpSender(const char* name, int32_t port) :
  229. LocIpcInetSender(name, port, SOCK_STREAM),
  230. mFirstTime(true) {}
  231. };
  232. class LocIpcInetRecver : public LocIpcInetSender, public LocIpcRecver {
  233. int32_t mPort;
  234. protected:
  235. virtual ssize_t recv() const = 0;
  236. public:
  237. inline LocIpcInetRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
  238. int32_t port, int sockType) :
  239. LocIpcInetSender(name, port, sockType), LocIpcRecver(listener, *this),
  240. mPort(port) {
  241. if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) {
  242. LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno));
  243. mSock->close();
  244. }
  245. }
  246. inline virtual ~LocIpcInetRecver() {}
  247. inline virtual const char* getName() const override { return mName.data(); };
  248. inline virtual void abort() const override {
  249. if (isSendable()) {
  250. mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr));
  251. }
  252. }
  253. inline virtual unique_ptr<LocIpcSender> getLastSender() const override {
  254. return make_unique<LocIpcInetSender>(static_cast<const LocIpcInetSender&>(*this));
  255. }
  256. };
  257. class LocIpcInetTcpRecver : public LocIpcInetRecver {
  258. mutable int32_t mConnFd;
  259. protected:
  260. inline virtual ssize_t recv() const override {
  261. socklen_t size = sizeof(mAddr);
  262. if (-1 == mConnFd && mSock->isValid()) {
  263. if (::listen(mSock->mSid, 3) < 0 ||
  264. (mConnFd = accept(mSock->mSid, (struct sockaddr*)&mAddr, &size)) < 0) {
  265. mSock->close();
  266. mConnFd = -1;
  267. }
  268. }
  269. ssize_t nBytes = mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size, mConnFd);
  270. if (0 == nBytes) {
  271. // tcp connection closed, accept new connection for next recv
  272. // But do not exit the receiver thread by returning 0 bytes.
  273. mConnFd = -1;
  274. nBytes = 100;
  275. }
  276. return nBytes;
  277. }
  278. public:
  279. inline LocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
  280. int32_t port) :
  281. LocIpcInetRecver(listener, name, port, SOCK_STREAM), mConnFd(-1) {}
  282. inline virtual ~LocIpcInetTcpRecver() { if (-1 != mConnFd) ::close(mConnFd);}
  283. };
  284. class LocIpcInetUdpRecver : public LocIpcInetRecver {
  285. protected:
  286. inline virtual ssize_t recv() const override {
  287. socklen_t size = sizeof(mAddr);
  288. return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
  289. }
  290. public:
  291. inline LocIpcInetUdpRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
  292. int32_t port) :
  293. LocIpcInetRecver(listener, name, port, SOCK_DGRAM) {}
  294. inline virtual ~LocIpcInetUdpRecver() {}
  295. };
  296. class LocIpcRunnable : public LocRunnable {
  297. bool mAbortCalled;
  298. LocIpc& mLocIpc;
  299. unique_ptr<LocIpcRecver> mIpcRecver;
  300. public:
  301. inline LocIpcRunnable(LocIpc& locIpc, unique_ptr<LocIpcRecver>& ipcRecver) :
  302. mAbortCalled(false),
  303. mLocIpc(locIpc),
  304. mIpcRecver(std::move(ipcRecver)) {}
  305. inline virtual bool run() override {
  306. if (mIpcRecver != nullptr) {
  307. mLocIpc.startBlockingListening(*(mIpcRecver.get()));
  308. if (!mAbortCalled) {
  309. LOC_LOGw("startListeningBlocking() returned w/o stopBlockingListening() called");
  310. }
  311. }
  312. // return false so the calling thread exits while loop
  313. return false;
  314. }
  315. inline virtual void interrupt() override {
  316. mAbortCalled = true;
  317. if (mIpcRecver != nullptr) {
  318. mIpcRecver->abort();
  319. }
  320. }
  321. };
  322. bool LocIpc::startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver) {
  323. if (ipcRecver != nullptr && ipcRecver->isRecvable()) {
  324. std::string threadName = generateThreadName(ipcRecver->getName());
  325. return mThread.start(threadName.c_str(), make_shared<LocIpcRunnable>(*this, ipcRecver));
  326. } else {
  327. LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
  328. return false;
  329. }
  330. }
  331. bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) {
  332. if (ipcRecver.isRecvable()) {
  333. // inform that the socket is ready to receive message
  334. ipcRecver.onListenerReady();
  335. while (ipcRecver.recvData());
  336. return true;
  337. } else {
  338. LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
  339. return false;
  340. }
  341. }
  342. void LocIpc::stopNonBlockingListening() {
  343. mThread.stop();
  344. }
  345. void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) {
  346. if (ipcRecver.isRecvable()) {
  347. ipcRecver.abort();
  348. }
  349. }
  350. bool LocIpc::send(LocIpcSender& sender, const uint8_t data[], uint32_t length, int32_t msgId) {
  351. return sender.sendData(data, length, msgId);
  352. }
  353. std::string LocIpc::generateThreadName(const std::string& recverName) {
  354. std::string threadName("Ipc-");
  355. int recverNameLen = recverName.length();
  356. // Total thread name length is 16 letters.
  357. // Concatenate with up to 11 chars starting from the last char of the ipc name.
  358. threadName.append(recverName.substr(recverNameLen <= 11 ? 0 : (recverNameLen - 11)));
  359. return threadName;
  360. }
  361. shared_ptr<LocIpcSender> LocIpc::getLocIpcLocalSender(const char* localSockName) {
  362. return make_shared<LocIpcLocalSender>(localSockName);
  363. }
  364. unique_ptr<LocIpcRecver> LocIpc::getLocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener,
  365. const char* localSockName) {
  366. return make_unique<LocIpcLocalRecver>(listener, localSockName);
  367. }
  368. static void* sLibQrtrHandle = nullptr;
  369. static const char* sLibQrtrName = "libloc_socket.so";
  370. shared_ptr<LocIpcSender> LocIpc::getLocIpcQrtrSender(int service, int instance) {
  371. typedef shared_ptr<LocIpcSender> (*creator_t) (int, int);
  372. static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName,
  373. "_ZN8loc_util22createLocIpcQrtrSenderEii");
  374. return (nullptr == creator) ? nullptr : creator(service, instance);
  375. }
  376. unique_ptr<LocIpcRecver> LocIpc::getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
  377. int service, int instance,
  378. const shared_ptr<LocIpcQrtrWatcher>& watcher) {
  379. typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int,
  380. const shared_ptr<LocIpcQrtrWatcher>& watcher);
  381. static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName,
  382. #ifdef USE_GLIB
  383. "_ZN8loc_util22createLocIpcQrtrRecverERKSt10shared_ptrINS_15ILocIpcListenerEEiiRKS0_INS_17LocIpcQrtrWatcherEE");
  384. #else
  385. "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEiiRKNS1_INS_17LocIpcQrtrWatcherEEE");
  386. #endif
  387. return (nullptr == creator) ? nullptr : creator(listener, service, instance, watcher);
  388. }
  389. shared_ptr<LocIpcSender> LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) {
  390. return make_shared<LocIpcInetTcpSender>(serverName, port);
  391. }
  392. unique_ptr<LocIpcRecver> LocIpc::getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener,
  393. const char* serverName, int32_t port) {
  394. return make_unique<LocIpcInetTcpRecver>(listener, serverName, port);
  395. }
  396. shared_ptr<LocIpcSender> LocIpc::getLocIpcInetUdpSender(const char* serverName, int32_t port) {
  397. return make_shared<LocIpcInetSender>(serverName, port, SOCK_DGRAM);
  398. }
  399. unique_ptr<LocIpcRecver> LocIpc::getLocIpcInetUdpRecver(const shared_ptr<ILocIpcListener>& listener,
  400. const char* serverName, int32_t port) {
  401. return make_unique<LocIpcInetUdpRecver>(listener, serverName, port);
  402. }
  403. pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>
  404. LocIpc::getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener, int instance) {
  405. typedef pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> (*creator_t)(const shared_ptr<ILocIpcListener>&, int);
  406. static void* sLibEmuHandle = nullptr;
  407. static creator_t creator = (creator_t)dlGetSymFromLib(sLibEmuHandle, "libloc_emu.so",
  408. #ifdef USE_GLIB
  409. "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPair"\
  410. "ERKSt10shared_ptrIN8loc_util15ILocIpcListenerEEi");
  411. #else
  412. "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPair"\
  413. "ERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi");
  414. #endif
  415. return (nullptr == creator) ?
  416. make_pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>(nullptr, nullptr) :
  417. creator(listener, instance);
  418. }
  419. }