DeviceMgmt.cpp (dabd48dd9ad9c05b1ad67e3540385bd69fe20239) | DeviceMgmt.cpp (3ee959ad5e8691e352f1a8424a0dafe0d8ceaff0) |
---|---|
1#include <DeviceMgmt.hpp> 2 3#include <filesystem> 4#include <fstream> 5 6namespace fs = std::filesystem; 7 | 1#include <DeviceMgmt.hpp> 2 3#include <filesystem> 4#include <fstream> 5 6namespace fs = std::filesystem; 7 |
8std::optional<I2CDevice> getI2CDevice(const I2CDeviceTypeMap& dtmap, 9 const SensorBaseConfigMap& cfg) | 8std::optional<I2CDeviceParams> 9 getI2CDeviceParams(const I2CDeviceTypeMap& dtmap, 10 const SensorBaseConfigMap& cfg) |
10{ 11 auto findType = cfg.find("Type"); 12 auto findBus = cfg.find("Bus"); 13 auto findAddr = cfg.find("Address"); 14 15 if (findType == cfg.end() || findBus == cfg.end() || findAddr == cfg.end()) 16 { 17 return std::nullopt; --- 9 unchanged lines hidden (view full) --- 27 } 28 29 auto findDevType = dtmap.find(type->c_str()); 30 if (findDevType == dtmap.end()) 31 { 32 return std::nullopt; 33 } 34 | 11{ 12 auto findType = cfg.find("Type"); 13 auto findBus = cfg.find("Bus"); 14 auto findAddr = cfg.find("Address"); 15 16 if (findType == cfg.end() || findBus == cfg.end() || findAddr == cfg.end()) 17 { 18 return std::nullopt; --- 9 unchanged lines hidden (view full) --- 28 } 29 30 auto findDevType = dtmap.find(type->c_str()); 31 if (findDevType == dtmap.end()) 32 { 33 return std::nullopt; 34 } 35 |
35 return I2CDevice(findDevType->second, *bus, *addr); | 36 return I2CDeviceParams(findDevType->second, *bus, *addr); |
36} 37 38static fs::path i2cBusPath(uint64_t bus) 39{ 40 return {"/sys/bus/i2c/devices/i2c-" + std::to_string(bus)}; 41} 42 43static std::string deviceDirName(uint64_t bus, uint64_t address) 44{ 45 std::ostringstream name; 46 name << bus << "-" << std::hex << std::setw(4) << std::setfill('0') 47 << address; 48 return name.str(); 49} 50 | 37} 38 39static fs::path i2cBusPath(uint64_t bus) 40{ 41 return {"/sys/bus/i2c/devices/i2c-" + std::to_string(bus)}; 42} 43 44static std::string deviceDirName(uint64_t bus, uint64_t address) 45{ 46 std::ostringstream name; 47 name << bus << "-" << std::hex << std::setw(4) << std::setfill('0') 48 << address; 49 return name.str(); 50} 51 |
51bool I2CDevice::present(void) const | 52bool I2CDeviceParams::devicePresent(void) const |
52{ 53 fs::path path = i2cBusPath(bus) / deviceDirName(bus, address); 54 55 if (type->createsHWMon) 56 { 57 path /= "hwmon"; 58 } 59 60 // Ignore errors; anything but a clean 'true' is fine as 'false' 61 std::error_code ec; 62 return fs::exists(path, ec); 63} 64 | 53{ 54 fs::path path = i2cBusPath(bus) / deviceDirName(bus, address); 55 56 if (type->createsHWMon) 57 { 58 path /= "hwmon"; 59 } 60 61 // Ignore errors; anything but a clean 'true' is fine as 'false' 62 std::error_code ec; 63 return fs::exists(path, ec); 64} 65 |
66I2CDevice::I2CDevice(I2CDeviceParams params) : params(params) 67{ 68 if (create() != 0) 69 { 70 throw std::runtime_error("failed to instantiate i2c device"); 71 } 72} 73 74I2CDevice::~I2CDevice() 75{ 76 destroy(); 77} 78 |
|
65int I2CDevice::create(void) const 66{ 67 // If it's already instantiated, there's nothing we need to do. | 79int I2CDevice::create(void) const 80{ 81 // If it's already instantiated, there's nothing we need to do. |
68 if (present()) | 82 if (params.devicePresent()) |
69 { 70 return 0; 71 } 72 73 // Try to create it: 'echo $devtype $addr > .../i2c-$bus/new_device' | 83 { 84 return 0; 85 } 86 87 // Try to create it: 'echo $devtype $addr > .../i2c-$bus/new_device' |
74 fs::path ctorPath = i2cBusPath(bus) / "new_device"; | 88 fs::path ctorPath = i2cBusPath(params.bus) / "new_device"; |
75 std::ofstream ctor(ctorPath); 76 if (!ctor.good()) 77 { 78 std::cerr << "Failed to open " << ctorPath << "\n"; 79 return -1; 80 } 81 | 89 std::ofstream ctor(ctorPath); 90 if (!ctor.good()) 91 { 92 std::cerr << "Failed to open " << ctorPath << "\n"; 93 return -1; 94 } 95 |
82 ctor << type->name << " " << address << "\n"; | 96 ctor << params.type->name << " " << params.address << "\n"; |
83 ctor.flush(); 84 if (!ctor.good()) 85 { 86 std::cerr << "Failed to write to " << ctorPath << "\n"; 87 return -1; 88 } 89 90 // Check if that created the requisite sysfs directory | 97 ctor.flush(); 98 if (!ctor.good()) 99 { 100 std::cerr << "Failed to write to " << ctorPath << "\n"; 101 return -1; 102 } 103 104 // Check if that created the requisite sysfs directory |
91 if (!present()) | 105 if (!params.devicePresent()) |
92 { 93 destroy(); 94 return -1; 95 } 96 97 return 0; 98} 99 100int I2CDevice::destroy(void) const 101{ | 106 { 107 destroy(); 108 return -1; 109 } 110 111 return 0; 112} 113 114int I2CDevice::destroy(void) const 115{ |
102 // No present() check on this like in create(), since it might be used to 103 // clean up after a device instantiation that was only partially 104 // successful (i.e. when present() would return false but there's still a 105 // dummy i2c client device to remove) | 116 // No params.devicePresent() check on this like in create(), since it 117 // might be used to clean up after a device instantiation that was only 118 // partially successful (i.e. when params.devicePresent() would return 119 // false but there's still a dummy i2c client device to remove) |
106 | 120 |
107 fs::path dtorPath = i2cBusPath(bus) / "delete_device"; | 121 fs::path dtorPath = i2cBusPath(params.bus) / "delete_device"; |
108 std::ofstream dtor(dtorPath); 109 if (!dtor.good()) 110 { 111 std::cerr << "Failed to open " << dtorPath << "\n"; 112 return -1; 113 } 114 | 122 std::ofstream dtor(dtorPath); 123 if (!dtor.good()) 124 { 125 std::cerr << "Failed to open " << dtorPath << "\n"; 126 return -1; 127 } 128 |
115 dtor << address << "\n"; | 129 dtor << params.address << "\n"; |
116 dtor.flush(); 117 if (!dtor.good()) 118 { 119 std::cerr << "Failed to write to " << dtorPath << "\n"; 120 return -1; 121 } 122 123 return 0; 124} | 130 dtor.flush(); 131 if (!dtor.good()) 132 { 133 std::cerr << "Failed to write to " << dtorPath << "\n"; 134 return -1; 135 } 136 137 return 0; 138} |