From 07db01d9af3ac18a2be12bbf58904a6d6fb749f6 Mon Sep 17 00:00:00 2001 From: Kevin Tang Date: Fri, 5 Apr 2019 19:46:29 -0700 Subject: LocIpc derefs nullptr if stopping blocking listener LocIpcRunnable is created only for nonBlocking listeners. But stopListening would use LocIpcRunnable not knowing if this is a blocking or nonblocking listener. LocIpcRunnable is no longer a shared resource between the two threads. We use a copy of string to keep the needed socket name. Change-Id: Ib5c57a89f630807d6d03f3fbc698a56b9ffddf4d CRs-Fixed: 2431397 --- utils/LocIpc.cpp | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'utils/LocIpc.cpp') diff --git a/utils/LocIpc.cpp b/utils/LocIpc.cpp index 7347b78..4178d52 100644 --- a/utils/LocIpc.cpp +++ b/utils/LocIpc.cpp @@ -33,6 +33,8 @@ #include #include "LocIpc.h" +using std::string; + namespace loc_util { #ifdef LOG_TAG @@ -47,7 +49,7 @@ namespace loc_util { class LocIpcRunnable : public LocRunnable { friend LocIpc; public: - LocIpcRunnable(LocIpc& locIpc, const std::string& ipcName) + LocIpcRunnable(LocIpc& locIpc, const string& ipcName) : mLocIpc(locIpc), mIpcName(ipcName) {} bool run() override { if (!mLocIpc.startListeningBlocking(mIpcName)) { @@ -58,17 +60,17 @@ public: } private: LocIpc& mLocIpc; - const std::string mIpcName; + const string mIpcName; }; -bool LocIpc::startListeningNonBlocking(const std::string& name) { - mRunnable = new LocIpcRunnable(*this, name); - std::string threadName("LocIpc-"); +bool LocIpc::startListeningNonBlocking(const string& name) { + auto runnable = new LocIpcRunnable(*this, name); + string threadName("LocIpc-"); threadName.append(name); - return mThread.start(threadName.c_str(), mRunnable); + return mThread.start(threadName.c_str(), runnable); } -bool LocIpc::startListeningBlocking(const std::string& name) { +bool LocIpc::startListeningBlocking(const string& name) { bool stopRequested = false; int fd = socket(AF_UNIX, SOCK_DGRAM, 0); @@ -90,13 +92,14 @@ bool LocIpc::startListeningBlocking(const std::string& name) { LOC_LOGe("bind socket error. reason:%s", strerror(errno)); } else { mIpcFd = fd; + mIpcName = name; // inform that the socket is ready to receive message onListenerReady(); ssize_t nBytes = 0; - std::string msg = ""; - std::string abort = LOC_MSG_ABORT; + string msg = ""; + string abort = LOC_MSG_ABORT; while (1) { msg.resize(LOC_MSG_BUF_LEN); nBytes = ::recvfrom(fd, (void*)(msg.data()), msg.size(), 0, NULL, NULL); @@ -147,20 +150,19 @@ bool LocIpc::startListeningBlocking(const std::string& name) { } void LocIpc::stopListening() { - const char *socketName = nullptr; - if (mIpcFd >= 0) { - std::string abort = LOC_MSG_ABORT; - socketName = (reinterpret_cast(mRunnable))->mIpcName.c_str(); - send(socketName, abort); + string abort = LOC_MSG_ABORT; + if (!mIpcName.empty()) { + send(mIpcName.c_str(), abort); + } mIpcFd = -1; } - if (mRunnable) { - mRunnable = nullptr; + if (!mIpcName.empty()) { + mIpcName.clear(); } } -bool LocIpc::send(const char name[], const std::string& data) { +bool LocIpc::send(const char name[], const string& data) { return send(name, (const uint8_t*)data.c_str(), data.length()); } @@ -195,7 +197,7 @@ bool LocIpc::sendData(int fd, const sockaddr_un &addr, const uint8_t data[], uin result = false; } } else { - std::string head = LOC_MSG_HEAD; + string head = LOC_MSG_HEAD; head.append(std::to_string(length)); if (::sendto(fd, head.c_str(), head.length(), 0, (struct sockaddr*)&addr, sizeof(addr)) < 0) { -- cgit v1.2.3 From 2ba3f04c57196968d815eb6eb226531895a47190 Mon Sep 17 00:00:00 2001 From: Bhavna Sharma Date: Thu, 24 Jan 2019 20:27:39 -0800 Subject: LocIpc redesign LocIpc now doesn't have any impelementation of sockets, but a framework that provides threading for any sockets that can be wrapped into LocIpcSender and LocIpcRever APIs. Also updated XtraSystemStatusObserver to using the new LocIpc and LocIpcLocalSender and LocIpcLocalRecver. Change-Id: I506c77198f9ce1e7d4dfd5e596dc0ac21d928e34 CRs-Fixed: 2443124 --- utils/LocIpc.cpp | 462 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 312 insertions(+), 150 deletions(-) (limited to 'utils/LocIpc.cpp') diff --git a/utils/LocIpc.cpp b/utils/LocIpc.cpp index 4178d52..ecaff01 100644 --- a/utils/LocIpc.cpp +++ b/utils/LocIpc.cpp @@ -30,10 +30,14 @@ #include #include #include +#include +#include +#include #include -#include "LocIpc.h" +#include +#include -using std::string; +using namespace std; namespace loc_util { @@ -42,188 +46,346 @@ namespace loc_util { #endif #define LOG_TAG "LocSvc_LocIpc" -#define LOC_MSG_BUF_LEN 8192 -#define LOC_MSG_HEAD "$MSGLEN$" -#define LOC_MSG_ABORT "LocIpcMsg::ABORT" +#define SOCK_OP_AND_LOG(buf, length, opable, rtv, exe) \ + if (nullptr == (buf) || 0 == (length)) { \ + LOC_LOGe("Invalid inputs: buf - %p, length - %d", (buf), (length)); \ + } else if (!(opable)) { \ + LOC_LOGe("Invalid object: operable - %d", (opable)); \ + } else { \ + rtv = (exe); \ + if (-1 == rtv) { \ + LOC_LOGw("failed reason: %s", strerror(errno)); \ + } \ + } -class LocIpcRunnable : public LocRunnable { -friend LocIpc; -public: - LocIpcRunnable(LocIpc& locIpc, const string& ipcName) - : mLocIpc(locIpc), mIpcName(ipcName) {} - bool run() override { - if (!mLocIpc.startListeningBlocking(mIpcName)) { - LOC_LOGe("listen to socket failed"); +const char Sock::MSG_ABORT[] = "LocIpc::Sock::ABORT"; +const char Sock::LOC_IPC_HEAD[] = "$MSGLEN$"; +ssize_t Sock::send(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const { + ssize_t rtv = -1; + SOCK_OP_AND_LOG(buf, len, isValid(), rtv, sendto(buf, len, flags, destAddr, addrlen)); + return rtv; +} +ssize_t Sock::recv(const shared_ptr& dataCb, int flags, struct sockaddr *srcAddr, + socklen_t *addrlen, int sid) const { + ssize_t rtv = -1; + if (-1 == sid) { + sid = mSid; + } // else it sid would be connection based socket id for recv + SOCK_OP_AND_LOG(dataCb.get(), mMaxTxSize, isValid(), rtv, + recvfrom(dataCb, sid, flags, srcAddr, addrlen)); + return rtv; +} +ssize_t Sock::sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const { + ssize_t rtv = -1; + if (len <= mMaxTxSize) { + rtv = ::sendto(mSid, buf, len, flags, destAddr, addrlen); + } else { + std::string head(LOC_IPC_HEAD + to_string(len)); + rtv = ::sendto(mSid, head.c_str(), head.length(), flags, destAddr, addrlen); + if (rtv > 0) { + for (size_t offset = 0; offset < len && rtv > 0; offset += rtv) { + rtv = ::sendto(mSid, (char*)buf + offset, min(len - offset, (size_t)mMaxTxSize), + flags, destAddr, addrlen); + } + rtv = (rtv > 0) ? (head.length() + len) : -1; } - - return false; } -private: - LocIpc& mLocIpc; - const string mIpcName; -}; - -bool LocIpc::startListeningNonBlocking(const string& name) { - auto runnable = new LocIpcRunnable(*this, name); - string threadName("LocIpc-"); - threadName.append(name); - return mThread.start(threadName.c_str(), runnable); + return rtv; } +ssize_t Sock::recvfrom(const shared_ptr& dataCb, int sid, int flags, + struct sockaddr *srcAddr, socklen_t *addrlen) const { + ssize_t nBytes = -1; + std::string msg(mMaxTxSize, 0); + + if ((nBytes = ::recvfrom(sid, (void*)msg.data(), msg.size(), flags, srcAddr, addrlen)) > 0) { + if (strncmp(msg.data(), MSG_ABORT, sizeof(MSG_ABORT)) == 0) { + LOC_LOGi("recvd abort msg.data %s", msg.data()); + nBytes = 0; + } else if (strncmp(msg.data(), LOC_IPC_HEAD, sizeof(LOC_IPC_HEAD) - 1)) { + // short message + msg.resize(nBytes); + dataCb->onReceive(msg.data(), nBytes); + } else { + // long message + size_t msgLen = 0; + sscanf(msg.data() + sizeof(LOC_IPC_HEAD) - 1, "%zu", &msgLen); + msg.resize(msgLen); + for (size_t msgLenReceived = 0; (msgLenReceived < msgLen) && (nBytes > 0); + msgLenReceived += nBytes) { + nBytes = ::recvfrom(sid, &(msg[msgLenReceived]), msg.size() - msgLenReceived, + flags, srcAddr, addrlen); + } + if (nBytes > 0) { + nBytes = msgLen; + dataCb->onReceive(msg.data(), nBytes); + } + } + } -bool LocIpc::startListeningBlocking(const string& name) { - bool stopRequested = false; - int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + return nBytes; +} +ssize_t Sock::sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen) { + return send(MSG_ABORT, sizeof(MSG_ABORT), flags, destAddr, addrlen); +} - if (fd < 0) { - LOC_LOGe("create socket error. reason:%s", strerror(errno)); - return false; +class LocIpcLocalSender : public LocIpcSender { +protected: + shared_ptr mSock; + struct sockaddr_un mAddr; + inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const { + return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr)); } - - if ((unlink(name.c_str()) < 0) && (errno != ENOENT)) { - LOC_LOGw("unlink socket error. reason:%s", strerror(errno)); +public: + inline LocIpcLocalSender(const char* name) : LocIpcSender(), + mSock(make_shared((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))), + mAddr({.sun_family = AF_UNIX, {}}) { + if (mSock != nullptr && mSock->isValid()) { + snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name); + } } +}; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name.c_str()); - - umask(0157); +class LocIpcLocalRecver : public LocIpcLocalSender, public LocIpcRecver { +protected: + inline virtual ssize_t recv() const override { + socklen_t size = sizeof(mAddr); + return mSock->recv(mDataCb, 0, (struct sockaddr*)&mAddr, &size); + } +public: + inline LocIpcLocalRecver(const shared_ptr& listener, const char* name) : + LocIpcLocalSender(name), LocIpcRecver(listener, *this) { - if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("bind socket error. reason:%s", strerror(errno)); - } else { - mIpcFd = fd; - mIpcName = name; + if ((unlink(mAddr.sun_path) < 0) && (errno != ENOENT)) { + LOC_LOGw("unlink socket error. reason:%s", strerror(errno)); + } - // inform that the socket is ready to receive message - onListenerReady(); - - ssize_t nBytes = 0; - string msg = ""; - string abort = LOC_MSG_ABORT; - while (1) { - msg.resize(LOC_MSG_BUF_LEN); - nBytes = ::recvfrom(fd, (void*)(msg.data()), msg.size(), 0, NULL, NULL); - if (nBytes < 0) { - LOC_LOGe("cannot read socket. reason:%s", strerror(errno)); - break; - } else if (0 == nBytes) { - continue; - } + umask(0157); + if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) { + LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno)); + mSock->close(); + } + } + inline virtual ~LocIpcLocalRecver() { unlink(mAddr.sun_path); } + inline virtual const char* getName() const override { return mAddr.sun_path; }; + inline virtual void abort() const override { + if (isSendable()) { + mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } + } +}; - if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) { - LOC_LOGi("recvd abort msg.data %s", msg.data()); - stopRequested = true; - break; +class LocIpcInetTcpSender : public LocIpcSender { +protected: + shared_ptr mSock; + const string mName; + sockaddr_in mAddr; + mutable bool mFirstTime; + inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const { + if (mFirstTime) { + mFirstTime = false; + ::connect(mSock->mSid, (const struct sockaddr*)&mAddr, sizeof(mAddr)); + } + return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } +public: + inline LocIpcInetTcpSender(const char* name, int32_t port) : LocIpcSender(), + mSock(make_shared((nullptr == name) ? -1 : (::socket(AF_INET, SOCK_STREAM, 0)))), + mName((nullptr == name) ? "" : name), + mAddr({.sin_family=AF_INET, .sin_port=htons(port), .sin_addr={htonl(INADDR_ANY)}}), + mFirstTime(true) { + if (mSock != nullptr && mSock->isValid() && nullptr != name) { + struct hostent* hp = gethostbyname(name); + if (nullptr != hp) { + memcpy((char*)&(mAddr.sin_addr.s_addr), hp->h_addr_list[0], hp->h_length); } + } + } +}; - if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) { - // short message - msg.resize(nBytes); - onReceive(msg); - } else { - // long message - size_t msgLen = 0; - sscanf(msg.data(), LOC_MSG_HEAD"%zu", &msgLen); - msg.resize(msgLen); - size_t msgLenReceived = 0; - while ((msgLenReceived < msgLen) && (nBytes > 0)) { - nBytes = recvfrom(fd, (void*)&(msg[msgLenReceived]), - msg.size() - msgLenReceived, 0, NULL, NULL); - msgLenReceived += nBytes; - } - if (nBytes > 0) { - onReceive(msg); - } else { - LOC_LOGe("cannot read socket. reason:%s", strerror(errno)); - break; - } +class LocIpcInetTcpRecver : public LocIpcInetTcpSender, public LocIpcRecver { + mutable int32_t mConnFd; +protected: + inline virtual ssize_t recv() const override { + socklen_t size = sizeof(mAddr); + if (-1 == mConnFd && mSock->isValid()) { + if (::listen(mSock->mSid, 3) < 0 || + (mConnFd = accept(mSock->mSid, (struct sockaddr*)&mAddr, &size)) < 0) { + mSock->close(); + mConnFd = -1; } } + return mSock->recv(mDataCb, 0, (struct sockaddr*)&mAddr, &size, mConnFd); } +public: + inline LocIpcInetTcpRecver(const shared_ptr& listener, const char* name, + int32_t port) : + LocIpcInetTcpSender(name, port), LocIpcRecver(listener, *this), mConnFd(-1) { + if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) { + LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno)); + mSock->close(); + } + } + inline virtual ~LocIpcInetTcpRecver() { if (-1 != mConnFd) ::close(mConnFd); } + inline virtual const char* getName() const override { return mName.data(); }; + inline virtual void abort() const override { + if (isSendable()) { + mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } + } +}; - if (::close(fd)) { - LOC_LOGe("cannot close socket:%s", strerror(errno)); +#ifdef NOT_DEFINED +class LocIpcQcsiSender : public LocIpcSender { +protected: + inline virtual bool isOperable() const override { + return mService != nullptr && mService->isServiceRegistered(); + } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t msgId) const override { + return mService->sendIndToClient(msgId, data, length); } - unlink(name.c_str()); + inline LocIpcQcsiSender(shared_ptr& service) : mService(service) {} +public: + inline virtual ~LocIpcQcsi() {} +}; - return stopRequested; -} +class LocIpcQcsiRecver : public LocIpcQcsiSender, public LocIpcRecver { +protected: + inline virtual ssize_t recv() const override { return mService->recv(); } +public: + inline LocIpcQcsiRecver(unique_ptr& service) : + LocIpcQcsiSender(service), LocIpcRecver(mService->getDataCallback(), *this) { + } + // only the dele + inline ~LocIpcQcsiRecver() {} + inline virtual const char* getName() const override { return mService->getName().data(); }; + inline virtual void abort() const override { if (isSendable()) mService->abort(); } + shared_ptr getSender() { return make_pare(mService); } +}; +#endif -void LocIpc::stopListening() { - if (mIpcFd >= 0) { - string abort = LOC_MSG_ABORT; - if (!mIpcName.empty()) { - send(mIpcName.c_str(), abort); +class LocIpcRunnable : public LocRunnable { + bool mAbortCalled; + LocIpc& mLocIpc; + unique_ptr mIpcRecver; +public: + inline LocIpcRunnable(LocIpc& locIpc, unique_ptr& ipcRecver) : + mAbortCalled(false), + mLocIpc(locIpc), + mIpcRecver(move(ipcRecver)) {} + inline bool run() override { + if (mIpcRecver != nullptr) { + mLocIpc.startBlockingListening(*(mIpcRecver.get())); + if (!mAbortCalled) { + LOC_LOGw("startListeningBlocking() returned w/o stopBlockingListening() called"); + } } - mIpcFd = -1; + // return false so the calling thread exits while loop + return false; } - if (!mIpcName.empty()) { - mIpcName.clear(); + inline void abort() { + mAbortCalled = true; + if (mIpcRecver != nullptr) { + mIpcRecver->abort(); + } } -} +}; -bool LocIpc::send(const char name[], const string& data) { - return send(name, (const uint8_t*)data.c_str(), data.length()); +bool LocIpc::startNonBlockingListening(unique_ptr& ipcRecver) { + if (ipcRecver != nullptr && ipcRecver->isRecvable()) { + std::string threadName("LocIpc-"); + threadName.append(ipcRecver->getName()); + mRunnable = new LocIpcRunnable(*this, ipcRecver); + return mThread.start(threadName.c_str(), mRunnable); + } else { + LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle"); + return false; + } } -bool LocIpc::send(const char name[], const uint8_t data[], uint32_t length) { - - bool result = true; - int fd = ::socket(AF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) { - LOC_LOGe("create socket error. reason:%s", strerror(errno)); +bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) { + if (ipcRecver.isRecvable()) { + // inform that the socket is ready to receive message + ipcRecver.onListenerReady(); + while (ipcRecver.recvData()); + return true; + } else { + LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle"); return false; } - - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name); - - result = sendData(fd, addr, data, length); - - (void)::close(fd); - return result; } +void LocIpc::stopNonBlockingListening() { + if (mRunnable) { + mRunnable->abort(); + mRunnable = nullptr; + } +} -bool LocIpc::sendData(int fd, const sockaddr_un &addr, const uint8_t data[], uint32_t length) { +void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) { + if (ipcRecver.isRecvable()) { + ipcRecver.abort(); + } +} - bool result = true; +bool LocIpc::send(LocIpcSender& sender, const uint8_t data[], uint32_t length, int32_t msgId) { + return sender.sendData(data, length, msgId); +} - if (length <= LOC_MSG_BUF_LEN) { - if (::sendto(fd, data, length, 0, - (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - } - } else { - string head = LOC_MSG_HEAD; - head.append(std::to_string(length)); - if (::sendto(fd, head.c_str(), head.length(), 0, - (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - } else { - size_t sentBytes = 0; - while(sentBytes < length) { - size_t partLen = length - sentBytes; - if (partLen > LOC_MSG_BUF_LEN) { - partLen = LOC_MSG_BUF_LEN; - } - ssize_t rv = ::sendto(fd, data + sentBytes, partLen, 0, - (struct sockaddr*)&addr, sizeof(addr)); - if (rv < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - break; - } - sentBytes += rv; - } - } - } - return result; +shared_ptr LocIpc::getLocIpcLocalSender(const char* localSockName) { + return make_shared(localSockName); +} +unique_ptr LocIpc::getLocIpcLocalRecver(const shared_ptr& listener, + const char* localSockName) { + return make_unique(listener, localSockName); +} +static void* sLibQrtrHandle = nullptr; +static const char* sLibQrtrName = "libloc_socket.so"; +shared_ptr LocIpc::getLocIpcQrtrSender(int service, int instance) { + typedef shared_ptr (*creator_t) (int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util22createLocIpcQrtrSenderEii"); + return (nullptr == creator) ? nullptr : creator(service, instance); +} +unique_ptr LocIpc::getLocIpcQrtrRecver(const shared_ptr& listener, + int service, int instance) { + typedef unique_ptr (*creator_t)(const shared_ptr&, int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEii"); + return (nullptr == creator) ? nullptr : creator(listener, service, instance); +} +shared_ptr LocIpc::getLocIpcQsockSender(int service, int instance) { + typedef shared_ptr (*creator_t) (int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util23createLocIpcQsockSenderEii"); + return (nullptr == creator) ? nullptr : creator(service, instance); +} +unique_ptr LocIpc::getLocIpcQsockRecver(const shared_ptr& listener, + int service, int instance) { + typedef unique_ptr (*creator_t)(const shared_ptr&, int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util23createLocIpcQsockRecverERKSt10shared_ptrINS_15ILocIpcListenerEEii"); + return (nullptr == creator) ? nullptr : creator(listener, service, instance); +} +shared_ptr LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) { + return make_shared(serverName, port); +} +unique_ptr LocIpc::getLocIpcInetTcpRecver(const shared_ptr& listener, + const char* serverName, int32_t port) { + return make_unique(listener, serverName, port); +} +pair, unique_ptr> + LocIpc::getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr& listener, int instance) { + typedef pair, unique_ptr> (*creator_t)(const shared_ptr&, int); + static void* sLibEmuHandle = nullptr; + static creator_t creator = (creator_t)dlGetSymFromLib(sLibEmuHandle, "libloc_emu.so", + "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPairERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi"); + return (nullptr == creator) ? + make_pair, unique_ptr>(nullptr, nullptr) : + creator(listener, instance); } } -- cgit v1.2.3