diff --git a/hcore/deviceManager/deviceManager.cpp b/hcore/deviceManager/deviceManager.cpp index 3852ae1..2b2857a 100644 --- a/hcore/deviceManager/deviceManager.cpp +++ b/hcore/deviceManager/deviceManager.cpp @@ -8,15 +8,15 @@ #include #include -std::vector> +std::vector> DeviceManager::interoceptorDeviceSpecs; -std::vector> +std::vector> DeviceManager::extrospectorDeviceSpecs; -std::vector> - DeviceManager::sensorDeviceSpecs; +std::vector> + DeviceManager::senseDeviceSpecs; std::ostream& operator<<( - std::ostream& os, const DeviceManager::SensorDeviceSpec& spec) + std::ostream& os, const SenseDeviceSpec& spec) { os << "Device: " << spec.sensorType << ", Implexor: " << spec.implexor << ", API: " << spec.api diff --git a/hcore/deviceManager/deviceSpecp.yy b/hcore/deviceManager/deviceSpecp.yy index 6200c25..74424aa 100644 --- a/hcore/deviceManager/deviceSpecp.yy +++ b/hcore/deviceManager/deviceSpecp.yy @@ -38,9 +38,9 @@ void yyerror(const char *message) %union { char* str; char chr; - DeviceManager::SensorDeviceSpec* sensorSpec; - DeviceManager::InteroceptorDeviceSpec* interoceptorSpec; - DeviceManager::ExtrospectorDeviceSpec* extrospectorSpec; + SenseDeviceSpec* sensorSpec; + InteroceptorDeviceSpec* interoceptorSpec; + ExtrospectorDeviceSpec* extrospectorSpec; std::vector* stringVector; } @@ -72,31 +72,31 @@ sensor_spec: interoceptor_spec: KEYWORD_SPECTYPE_INTEROSPECTOR PIPE spec_body { - auto spec = std::make_unique( - *static_cast($3)); + auto spec = std::make_unique( + *static_cast($3)); spec->sensorType = $1; DeviceManager::interoceptorDeviceSpecs.push_back(std::move(spec)); - DeviceManager::sensorDeviceSpecs.push_back(*spec); + DeviceManager::senseDeviceSpecs.push_back(*spec); delete $3; } ; extrospector_spec: KEYWORD_SPECTYPE_EXTROSPECTOR PIPE spec_body { - auto spec = std::make_unique( - *static_cast($3)); + auto spec = std::make_unique( + *static_cast($3)); spec->sensorType = $1; DeviceManager::extrospectorDeviceSpecs.push_back(std::move(spec)); - DeviceManager::sensorDeviceSpecs.push_back(*spec); + DeviceManager::senseDeviceSpecs.push_back(*spec); delete $3; } ; spec_body: STRING PIPE STRING LPAREN opt_params RPAREN PIPE STRING LPAREN opt_params RPAREN PIPE STRING { - $$ = new DeviceManager::SensorDeviceSpec(); + $$ = new SenseDeviceSpec(); $$->sensorType = '\0'; $$->implexor = std::string($1); $$->api = std::string($3); diff --git a/hcore/include/deviceManager/deviceManager.h b/hcore/include/deviceManager/deviceManager.h index 262ad0e..fac09b8 100644 --- a/hcore/include/deviceManager/deviceManager.h +++ b/hcore/include/deviceManager/deviceManager.h @@ -7,32 +7,11 @@ #include #include #include +#include class DeviceManager { public: - struct SensorDeviceSpec - { - char sensorType; - std::string implexor; - std::string api; - std::vector apiParams; - std::string provider; - std::vector providerParams; - std::string deviceSelector; - - friend std::ostream& operator<<( - std::ostream& os, const SensorDeviceSpec& spec); - }; - - struct InteroceptorDeviceSpec : public SensorDeviceSpec - { - }; - - struct ExtrospectorDeviceSpec : public SensorDeviceSpec - { - }; - static DeviceManager& getInstance() { static DeviceManager instance; @@ -56,8 +35,8 @@ public: interoceptorDeviceSpecs; static std::vector> extrospectorDeviceSpecs; - static std::vector> - sensorDeviceSpecs; + static std::vector> + senseDeviceSpecs; }; #endif // DEVICEMANAGER_H diff --git a/hcore/include/senseApis/senseApiManager.h b/hcore/include/senseApis/senseApiManager.h index 4002f87..eaca6db 100644 --- a/hcore/include/senseApis/senseApiManager.h +++ b/hcore/include/senseApis/senseApiManager.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace hk { namespace sense_api { @@ -24,6 +25,8 @@ public: SenseApiLib& loadSenseApiLib(const std::string& libraryPath); std::optional> getSenseApiLib( const std::string& libraryPath); + std::optional> getSenseApiLibByApiName( + const std::string& apiName); void unloadSenseApiLib(const std::string& libraryPath); void initializeSenseApiLib(SenseApiLib& lib); @@ -34,6 +37,11 @@ public: void initializeAllSenseApiLibs(void); void finalizeAllSenseApiLibs(void); + void attachAllSenseDevicesFromSpecs(void); + void attachSenseDevice(const SenseDeviceSpec& spec); + void detachSenseDevice(const SenseDeviceSpec& spec); + void detachAllSenseDevices(void); + std::string stringifyLibs() const; private: diff --git a/hcore/senseApis/senseApiManager.cpp b/hcore/senseApis/senseApiManager.cpp index 1a53311..9f40804 100644 --- a/hcore/senseApis/senseApiManager.cpp +++ b/hcore/senseApis/senseApiManager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace fs = std::filesystem; @@ -117,6 +118,19 @@ SenseApiManager::getSenseApiLib(const std::string& libraryPath) return std::nullopt; } +std::optional> +SenseApiManager::getSenseApiLibByApiName(const std::string& apiName) +{ + auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(), + [&apiName](const std::unique_ptr& lib) { + return lib->getSenseApiDesc()->name == apiName; + } + ); + + if (it != senseApiLibs.end()) { return **it; } + return std::nullopt; +} + void SenseApiManager::unloadSenseApiLib(const std::string& libraryPath) { auto it = std::find_if(senseApiLibs.begin(), senseApiLibs.end(), @@ -193,5 +207,61 @@ void SenseApiManager::finalizeAllSenseApiLibs(void) } } +void SenseApiManager::attachSenseDevice( + const SenseDeviceSpec& spec) +{ + auto libOpt = getSenseApiLibByApiName(spec.api); + if (!libOpt) + { + throw std::runtime_error( + std::string(__func__) + ": No library found for API '" + + spec.api + "'"); + } + auto& lib = libOpt.value().get(); + if (!lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq) + { + throw std::runtime_error( + std::string(__func__) + ": attachDeviceReq() is NULL for library '" + + lib.libraryPath + "'"); + } + CSenseDeviceSpec cSpec(spec); + lib.getSenseApiDesc()->sal_mgmt_libOps->attachDeviceReq(&cSpec); +} + +void SenseApiManager::detachSenseDevice( + const SenseDeviceSpec& spec) +{ + auto libOpt = getSenseApiLibByApiName(spec.api); + if (!libOpt) + { + throw std::runtime_error( + std::string(__func__) + ": No library found for API '" + + spec.api + "'"); + } + auto& lib = libOpt.value().get(); + if (!lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq) + { + throw std::runtime_error( + std::string(__func__) + ": detachDeviceReq() is NULL for library '" + + lib.libraryPath + "'"); + } + CSenseDeviceSpec cSpec(spec); + lib.getSenseApiDesc()->sal_mgmt_libOps->detachDeviceReq(&cSpec); +} + +void SenseApiManager::attachAllSenseDevicesFromSpecs(void) +{ + for (const auto& spec : DeviceManager::senseDeviceSpecs) { + attachSenseDevice(spec.get()); + } +} + +void SenseApiManager::detachAllSenseDevices(void) +{ + for (const auto& spec : DeviceManager::senseDeviceSpecs) { + detachSenseDevice(spec.get()); + } +} + } // namespace sense_api } // namespace hk diff --git a/include/user/senseApiDesc.h b/include/user/senseApiDesc.h index 9e7fcc8..67d1603 100644 --- a/include/user/senseApiDesc.h +++ b/include/user/senseApiDesc.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -18,8 +19,8 @@ struct CExportedImplexorApiDesc typedef int (sal_mho_initializeRdyFn)(void); typedef int (sal_mho_finalizeRdyFn)(void); -typedef int (sal_mho_attachDeviceAckFn)(void); -typedef int (sal_mho_detachDeviceAckFn)(void); +typedef int (sal_mho_attachDeviceAckFn)(const CSenseDeviceSpec *const desc); +typedef int (sal_mho_detachDeviceAckFn)(const CSenseDeviceSpec *const desc); struct Csal_mgmt_hkOps { @@ -35,8 +36,8 @@ struct Csal_mgmt_hkOps typedef int (sal_mlo_initializeIndFn)(void); typedef int (sal_mlo_finalizeIndFn)(void); -typedef int (sal_mlo_attachDeviceReqFn)(void); -typedef int (sal_mlo_detachDeviceReqFn)(void); +typedef int (sal_mlo_attachDeviceReqFn)(const CSenseDeviceSpec *const desc); +typedef int (sal_mlo_detachDeviceReqFn)(const CSenseDeviceSpec *const desc); struct Csal_mgmt_libOps { diff --git a/include/user/senseDeviceSpec.h b/include/user/senseDeviceSpec.h new file mode 100644 index 0000000..1735b3c --- /dev/null +++ b/include/user/senseDeviceSpec.h @@ -0,0 +1,100 @@ +#ifndef SENSORDEVICESPEC_H +#define SENSORDEVICESPEC_H + +#include +#include + +#ifdef __cplusplus +#include +#include +#include +#endif // __cplusplus + +#ifdef __cplusplus +struct SenseDeviceSpec +{ + char sensorType; + std::string implexor; + std::string api; + std::vector apiParams; + std::string provider; + std::vector providerParams; + std::string deviceSelector; + + friend std::ostream& operator<<( + std::ostream& os, const SenseDeviceSpec& spec); +}; + +struct InteroceptorDeviceSpec : public SenseDeviceSpec +{ +}; + +struct ExtrospectorDeviceSpec : public SenseDeviceSpec +{ +}; +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" { +#endif + +struct CSenseDeviceSpec +{ +#ifdef __cplusplus + CSenseDeviceSpec(const SenseDeviceSpec& spec) + : sensorType(spec.sensorType), + implexor(strdup(spec.implexor.c_str())), + api(strdup(spec.api.c_str())), + provider(strdup(spec.provider.c_str())), + deviceSelector(strdup(spec.deviceSelector.c_str())) + { + apiParams = new char*[spec.apiParams.size() + 1]; + for (size_t i = 0; i < spec.apiParams.size(); ++i) + { + apiParams[i] = strdup(spec.apiParams[i].c_str()); + } + apiParams[spec.apiParams.size()] = nullptr; + + providerParams = new char*[spec.providerParams.size() + 1]; + for (size_t i = 0; i < spec.providerParams.size(); ++i) + { + providerParams[i] = strdup(spec.providerParams[i].c_str()); + } + providerParams[spec.providerParams.size()] = nullptr; + } + + ~CSenseDeviceSpec(void) + { + free(implexor); + free(api); + free(provider); + free(deviceSelector); + + for (size_t i = 0; apiParams[i] != nullptr; ++i) + { + free(apiParams[i]); + } + delete[] apiParams; + + for (size_t i = 0; providerParams[i] != nullptr; ++i) + { + free(providerParams[i]); + } + delete[] providerParams; + } +#endif + + char sensorType; + char *implexor; + char *api; + char **apiParams; + char *provider; + char **providerParams; + char *deviceSelector; +}; + +#ifdef __cplusplus +} +#endif + +#endif // SENSORDEVICESPEC_H diff --git a/m4/sense_api_opts.m4 b/m4/sense_api_opts.m4 index 065ba96..6ca08ba 100644 --- a/m4/sense_api_opts.m4 +++ b/m4/sense_api_opts.m4 @@ -14,6 +14,8 @@ AC_ARG_ENABLE([senseapi-xcbxorg], AC_MSG_ERROR(m4_normalize([XCB library not found. Sense API XCB/Xorg requires the XCB dev headers and shlib.])) ]) + AC_SUBST([XCB_CFLAGS]) + AC_SUBST([XCB_LIBS]) ] )], [enable_senseapi_xcbxorg=no] diff --git a/main.cpp b/main.cpp index 468e59a..dc26c45 100644 --- a/main.cpp +++ b/main.cpp @@ -90,9 +90,9 @@ static int initializeHarikoff(int argc, char **argv, char **envp) DeviceManager::getInstance().parseAllDeviceSpecs(); std::cout << DeviceManager::stringifyDeviceSpecs() << std::endl; sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions(); - sense_api::SenseApiManager::getInstance().initializeAllSenseApiLibs(); std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs() << std::endl; + sense_api::SenseApiManager::getInstance().initializeAllSenseApiLibs(); /* Start the threads */ for (const auto& [id, componentThread] diff --git a/senseApis/xcbXorg/Makefile.am b/senseApis/xcbXorg/Makefile.am index 10bbcff..fe2ea93 100644 --- a/senseApis/xcbXorg/Makefile.am +++ b/senseApis/xcbXorg/Makefile.am @@ -1,5 +1,6 @@ pkglib_LTLIBRARIES=libxcbXorg.la libxcbXorg_la_SOURCES=xcbXorg.cpp +libxcbXorg_la_LDFLAGS=$(XCB_LIBS) -xcbXorg.$(OBJEXT): CPPFLAGS+=-Wno-c++20-extensions -xcbXorg.l$(OBJEXT): CPPFLAGS+=-Wno-c++20-extensions +xcbXorg.$(OBJEXT): CPPFLAGS+=$(XCB_CFLAGS) -Wno-c++20-extensions +xcbXorg.l$(OBJEXT): CPPFLAGS+=$(XCB_CFLAGS) -Wno-c++20-extensions diff --git a/senseApis/xcbXorg/xcbXorg.cpp b/senseApis/xcbXorg/xcbXorg.cpp index 51e93fa..110851d 100644 --- a/senseApis/xcbXorg/xcbXorg.cpp +++ b/senseApis/xcbXorg/xcbXorg.cpp @@ -1,8 +1,19 @@ #include #include #include +#include +#include #include "xcbXorg.h" +struct XcbConnectionInfo { + std::unique_ptr connection; + int screenNumber; + + XcbConnectionInfo() + : connection(nullptr, &xcb_disconnect), screenNumber(0) {} +}; + +static XcbConnectionInfo xcbConn; static CExportedImplexorApiDesc xcbXorgExportedImplexorApis[] = { @@ -43,27 +54,41 @@ const CSenseApiDesc *HK_GET_SENSE_API_DESC_FN_NAME(void) static sal_mlo_initializeIndFn xcbXorg_initializeInd; int xcbXorg_initializeInd(void) { - std::cerr << "XcbXorg::sal_mlo_initializeInd\n"; + xcbConn.connection.reset( + xcb_connect(nullptr, &xcbConn.screenNumber)); + + if (xcb_connection_has_error(xcbConn.connection.get())) + { + throw std::runtime_error( + std::string(__func__) + ": Failed to connect to X server"); + } + + std::cout << __func__ << ": Connected to X server, screen number " + << xcbConn.screenNumber << "\n"; return 0; } static sal_mlo_finalizeIndFn xcbXorg_finalizeInd; int xcbXorg_finalizeInd(void) { - std::cerr << "XcbXorg::sal_mlo_finalizeInd\n"; + if (!xcbConn.connection) { + return 0; + } + xcbConn.connection.reset(); + std::cout << __func__ << ": Disconnected from X server\n"; return 0; } static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq; -int xcbXorg_attachDeviceReq(void) +int xcbXorg_attachDeviceReq(const CSenseDeviceSpec *const desc) { - std::cerr << "XcbXorg::sal_mlo_attachDeviceReq\n"; + std::cout << __func__ << "\n"; return 0; } static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq; -int xcbXorg_detachDeviceReq(void) +int xcbXorg_detachDeviceReq(const CSenseDeviceSpec *const spec) { - std::cerr << "XcbXorg::sal_mlo_detachDeviceReq\n"; + std::cout << __func__ << "\n"; return 0; }