diff --git a/core/Makefile.am b/core/Makefile.am index 42586686..92aaded0 100644 --- a/core/Makefile.am +++ b/core/Makefile.am @@ -1,5 +1,6 @@ AM_CFLAGS = -I./ \ -I../utils \ + -I../gnss \ -I../location \ -I./data-items \ -I./data-items/common \ diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp index 319f1d7a..dc08a76e 100644 --- a/core/SystemStatusOsObserver.cpp +++ b/core/SystemStatusOsObserver.cpp @@ -41,6 +41,9 @@ namespace loc_core { SystemStatusOsObserver::SystemStatusOsObserver(const MsgTask* msgTask) : mAddress("SystemStatusOsObserver"), +#ifdef USE_GLIB + mBackHaulConnectReqCount(0), +#endif mClientIndex(IndexFactory :: createClientIndex()), mDataItemIndex(IndexFactory :: createDataItemIndex()) { @@ -506,6 +509,65 @@ void SystemStatusOsObserver::turnOff(DataItemId dit) } } +#ifdef USE_GLIB +bool SystemStatusOsObserver::connectBackhaul() +{ + bool result = false; + + if (mContext.mFrameworkActionReqObj != NULL) { + struct HandleConnectBackhaul : public LocMsg { + HandleConnectBackhaul(IFrameworkActionReq* fwkActReq) : + mFwkActionReqObj(fwkActReq) {} + virtual ~HandleConnectBackhaul() {} + void proc() const { + LOC_LOGD("HandleConnectBackhaul"); + mFwkActionReqObj->connectBackhaul(); + } + IFrameworkActionReq* mFwkActionReqObj; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleConnectBackhaul(mContext.mFrameworkActionReqObj)); + result = true; + } + else { + ++mBackHaulConnectReqCount; + LOC_LOGE("Framework action request object is NULL.Caching connect request: %d", + mBackHaulConnectReqCount); + result = false; + } + return result; + +} + +bool SystemStatusOsObserver::disconnectBackhaul() +{ + bool result = false; + + if (mContext.mFrameworkActionReqObj != NULL) { + struct HandleDisconnectBackhaul : public LocMsg { + HandleDisconnectBackhaul(IFrameworkActionReq* fwkActReq) : + mFwkActionReqObj(fwkActReq) {} + virtual ~HandleDisconnectBackhaul() {} + void proc() const { + LOC_LOGD("HandleDisconnectBackhaul"); + mFwkActionReqObj->disconnectBackhaul(); + } + IFrameworkActionReq* mFwkActionReqObj; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleDisconnectBackhaul(mContext.mFrameworkActionReqObj)); + } + else { + if (mBackHaulConnectReqCount > 0) { + --mBackHaulConnectReqCount; + } + LOC_LOGE("Framework action request object is NULL.Caching disconnect request: %d", + mBackHaulConnectReqCount); + result = false; + } + return result; +} +#endif /****************************************************************************** Helpers ******************************************************************************/ diff --git a/core/SystemStatusOsObserver.h b/core/SystemStatusOsObserver.h index 985e5c99..6892f226 100644 --- a/core/SystemStatusOsObserver.h +++ b/core/SystemStatusOsObserver.h @@ -85,6 +85,12 @@ public: // To set the framework action request object inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) { mContext.mFrameworkActionReqObj = frameworkActionReqObj; +#ifdef USE_GLIB + if (mBackHaulConnectReqCount > 0) { + connectBackhaul(); + mBackHaulConnectReqCount = 0; + } +#endif } // IDataItemSubscription Overrides @@ -103,6 +109,10 @@ public: // IFrameworkActionReq Overrides virtual void turnOn(DataItemId dit, int timeOut = 0); virtual void turnOff(DataItemId dit); +#ifdef USE_GLIB + virtual bool connectBackhaul(); + virtual bool disconnectBackhaul(); +#endif private: SystemContext mContext; @@ -117,6 +127,10 @@ private: ObserverReqCache mReqDataCache; void cacheObserverRequest(ObserverReqCache& reqCache, const list& l, IDataItemObserver* client); +#ifdef USE_GLIB + // Cache the framework action request for connect/disconnect + int mBackHaulConnectReqCount; +#endif // Helpers void sendFirstResponse(const list& l, IDataItemObserver* to); diff --git a/core/observer/IFrameworkActionReq.h b/core/observer/IFrameworkActionReq.h index c7b3ebdc..4be947ff 100644 --- a/core/observer/IFrameworkActionReq.h +++ b/core/observer/IFrameworkActionReq.h @@ -70,6 +70,24 @@ public: */ virtual void turnOff (DataItemId dit) = 0; +#ifdef USE_GLIB + /** + * @brief Setup WWAN backhaul + * @details Setup WWAN backhaul + * + * @param None + */ + virtual bool connectBackhaul() = 0; + + /** + * @brief Disconnects the WWANbackhaul + * @details Disconnects the WWANbackhaul, only if it was setup by us + * + * @param None + */ + virtual bool disconnectBackhaul() = 0; +#endif + /** * @brief Destructor * @details Destructor diff --git a/core/observer/IOsObserver.h b/core/observer/IOsObserver.h index 3db8a85e..40d76717 100644 --- a/core/observer/IOsObserver.h +++ b/core/observer/IOsObserver.h @@ -90,6 +90,10 @@ public: // IFrameworkActionReq Overrides inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){} inline virtual void turnOff (DataItemId /*dit*/) {} +#ifdef USE_GLIB + inline virtual bool connectBackhaul() {} + inline virtual bool disconnectBackhaul() {} +#endif /** * @brief Destructor diff --git a/gnss/XtraSystemStatusObserver.cpp b/gnss/XtraSystemStatusObserver.cpp index ce08f648..ac402207 100644 --- a/gnss/XtraSystemStatusObserver.cpp +++ b/gnss/XtraSystemStatusObserver.cpp @@ -231,4 +231,128 @@ void XtraSystemStatusObserver::notify(const list& dlist) mMsgTask->sendMsg(new (nothrow) handleOsObserverUpdateMsg(this, dlist)); } +#ifdef USE_GLIB +bool XtraSystemStatusObserver::connectBackhaul() +{ + return mSystemStatusObsrvr->connectBackhaul(); +} +bool XtraSystemStatusObserver::disconnectBackhaul() +{ + return mSystemStatusObsrvr->disconnectBackhaul(); +} + +// XtraHalListenerSocket class +// TBD - this will be removed once bidirectional socket changes in +// xtra-daemon will be implemented +void XtraHalListenerSocket::receiveData(const int socketFd) { + string data; + array buf; + const char* bin_msg_conn_backhaul = "connectBackhaul"; + const char* bin_msg_disconn_backhaul = "disconnectBackhaul"; + + while (true) { + ssize_t len = recv(socketFd, buf.data(), buf.size(), 0); + if (len > 0) { + LOC_LOGd("received %lu bytes", len); + data.append(buf.data(), len); + + size_t pos = data.find("\n"); + if (pos == string::npos) { + continue; + } + + if (!strncmp(data.c_str(), bin_msg_conn_backhaul, + sizeof(bin_msg_conn_backhaul) - 1)) { + mSystemStatusObsrvr->connectBackhaul(); + } else if (!strncmp(data.c_str(), bin_msg_disconn_backhaul, + sizeof(bin_msg_disconn_backhaul) - 1)) { + mSystemStatusObsrvr->disconnectBackhaul(); + } + else { + LOC_LOGw("unknown event: %s", data.c_str()); + } + break; + + } else { + LOC_LOGd("XtraHalListenerSocket connection broken."); + break; + } + } +} + +void XtraHalListenerSocket::startListenerThread() { + mThread = new (std::nothrow) LocThread(); + if (!mThread) { + LOC_LOGe("create thread failed"); + } + mRunning = true; + if (!mThread->start("XtraHalListenerSocketThread", this, true)) { + delete mThread; + mThread = NULL; + } + + LOC_LOGd("Create listener socket in XtraHalListenerSocket"); + // create socket + int socketFd; + if ((socketFd = ::socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + LOC_LOGe("create socket error. reason:%s", strerror(errno)); + return; + } + + const char* socketPath = "/data/vendor/location/xtra/socket_xtra_locnetiface"; + unlink(socketPath); + + struct sockaddr_un addr = { .sun_family = AF_UNIX }; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketPath); + + umask(0157); + + if (::bind(socketFd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + LOC_LOGe("bind socket error. reason:%s", strerror(errno)); + return; + } + + // set up connection + if (::listen(socketFd, 5/*backlog*/) < 0) { + LOC_LOGe("cannot bind socket. reason:%s", strerror(errno)); + return; + } + mSocketFd = socketFd; + +} + +bool XtraHalListenerSocket::run() { + // infinite while loop till mRunning is false when stopListenXtraDaemon + // is called + while (mRunning) { + int clientFd = -1; + LOC_LOGd("XtraHalListenerSocket - waiting for msg..."); + if ( (clientFd = ::accept(mSocketFd, NULL, NULL)) < 0) { + LOC_LOGe("connection error. reason:%s", strerror(errno)); + } else { + LOC_LOGd("XtraHalListenerSocket - receiving data ..."); + receiveData(clientFd); + if (::close(clientFd)) { + LOC_LOGe("close connection fail."); + } + clientFd = -1; + } + } + + // return false once we reach there + return false; +} + +void XtraHalListenerSocket::stopListenXtraDaemon() { + if (mSocketFd >= 0) { + if (::close(mSocketFd)) { + LOC_LOGe("close hal connection fail."); + } + mSocketFd = -1; + } + mRunning = false; + mThread->stop(); +} + +#endif diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h index 42f49b53..6a001d9f 100644 --- a/gnss/XtraSystemStatusObserver.h +++ b/gnss/XtraSystemStatusObserver.h @@ -31,17 +31,72 @@ #include #include +#ifdef USE_GLIB +#include +#endif using namespace std; using loc_core::IOsObserver; using loc_core::IDataItemObserver; using loc_core::IDataItemCore; +#ifdef USE_GLIB +// XtraHalListenerSocket class +// listener socket for getting msgs from xtra-daemon in LE for invoking +// LocNetIface functions +// TBD - this will be removed once bidirectional socket changes in +// xtra-daemon will be implemented +class XtraHalListenerSocket: public LocRunnable { +public : + // constructor & destructor + XtraHalListenerSocket(IOsObserver* sysStatObs) : + mThread(NULL), + mRunning(false) { + mSystemStatusObsrvr = sysStatObs; + mRunning = true; + // create listener socket in a thread + startListenerThread(); + } + XtraHalListenerSocket() {} + inline virtual ~XtraHalListenerSocket() { + if (mThread) { + stopListenXtraDaemon(); + delete mThread; + mThread = NULL; + } + } + + // Overrides of LocRunnable methods + // This method will be repeated called until it returns false; or + // until thread is stopped. + virtual bool run(); + + // The method to be run before thread loop (conditionally repeatedly) + // calls run() + inline virtual void prerun() {} + + // The method to be run after thread loop (conditionally repeatedly) + // calls run() + inline virtual void postrun() {} + +private: + IOsObserver* mSystemStatusObsrvr; + int mSocketFd; + LocThread* mThread; + bool mRunning; + void startListenerThread(); + void stopListenXtraDaemon(); + void receiveData(const int socketFd); +}; +#endif class XtraSystemStatusObserver : public IDataItemObserver { public : // constructor & destructor inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask): +#ifdef USE_GLIB + mHalListenerSocket(sysStatObs), +#endif mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask) { subscribe(true); } @@ -52,6 +107,12 @@ public : inline virtual void getName(string& name); virtual void notify(const list& dlist); +#ifdef USE_GLIB + // IFrameworkActionReq functions reqd + virtual bool connectBackhaul(); + virtual bool disconnectBackhaul(); +#endif + bool updateLockStatus(uint32_t lock); bool updateConnectionStatus(bool connected, uint32_t type); bool updateTac(const string& tac); @@ -65,6 +126,12 @@ private: bool sendEvent(const stringstream& event); IOsObserver* mSystemStatusObsrvr; const MsgTask* mMsgTask; +#ifdef USE_GLIB + // XtraHalListenerSocket class + // TBD - this will be removed once bidirectional socket changes in + // xtra-daemon will be implemented + XtraHalListenerSocket mHalListenerSocket; +#endif };