summaryrefslogtreecommitdiffstats
path: root/presence/main.cpp
blob: 16866d4d5d2e4bc7c13724d1de8c7b66c337ce9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "argument.hpp"
#include "gpio_presence.hpp"

#include <systemd/sd-event.h>

#include <iostream>
#include <phosphor-logging/log.hpp>

using namespace phosphor::logging;
using namespace phosphor::gpio;
using namespace phosphor::gpio::presence;

/**
 * Pulls out the path,device pairs from the string
 * passed in
 *
 * @param[in] driverString - space separated path,device pairs
 * @param[out] drivers - vector of device,path tuples filled in
 *                       from driverString
 *
 * @return int - 0 if successful, < 0 else
 */
static int getDrivers(const std::string& driverString,
                      std::vector<Driver>& drivers)
{
    std::istringstream stream{driverString};

    while (true)
    {
        std::string entry;

        // Extract each path,device pair
        stream >> entry;

        if (entry.empty())
        {
            break;
        }

        // Extract the path and device and save them
        auto pos = entry.rfind(',');
        if (pos != std::string::npos)
        {
            auto path = entry.substr(0, pos);
            auto device = entry.substr(pos + 1);

            drivers.emplace_back(device, path);
        }
        else
        {
            std::cerr << "Invalid path,device combination: " << entry << "\n";
            return -1;
        }
    }

    return 0;
}

int main(int argc, char* argv[])
{
    auto options = ArgumentParser(argc, argv);

    auto inventory = options["inventory"];
    auto key = options["key"];
    auto path = options["path"];
    auto drivers = options["drivers"];
    if (argc < 4)
    {
        std::cerr << "Too few arguments\n";
        options.usage(argv);
    }

    if (inventory == ArgumentParser::emptyString)
    {
        std::cerr << "Inventory argument required\n";
        options.usage(argv);
    }

    if (key == ArgumentParser::emptyString)
    {
        std::cerr << "GPIO key argument required\n";
        options.usage(argv);
    }

    if (path == ArgumentParser::emptyString)
    {
        std::cerr << "Device path argument required\n";
        options.usage(argv);
    }

    std::vector<Driver> driverList;

    // Driver list is optional
    if (drivers != ArgumentParser::emptyString)
    {
        if (getDrivers(drivers, driverList) < 0)
        {
            options.usage(argv);
        }
    }

    auto bus = sdbusplus::bus::new_default();
    auto rc = 0;
    sd_event* event = nullptr;
    rc = sd_event_default(&event);
    if (rc < 0)
    {
        log<level::ERR>("Error creating a default sd_event handler");
        return rc;
    }
    EventPtr eventP{event};
    event = nullptr;

    auto name = options["name"];
    Presence presence(bus, inventory, path, std::stoul(key), name, eventP,
                      driverList);

    while (true)
    {
        // -1 denotes wait forever
        rc = sd_event_run(eventP.get(), (uint64_t)-1);
        if (rc < 0)
        {
            log<level::ERR>("Failure in processing request",
                            entry("ERROR=%s", strerror(-rc)));
            break;
        }
    }
    return rc;
}
OpenPOWER on IntegriCloud