summaryrefslogtreecommitdiffstats
path: root/command/payload_cmds.cpp
blob: 02c854acbb9ddbcc6a3e4c989831242b28847210 (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
#include <host-ipmid/ipmid-api.h>
#include <phosphor-logging/log.hpp>
#include "main.hpp"
#include "payload_cmds.hpp"
#include "sol/sol_manager.hpp"
#include "sol_cmds.hpp"

namespace sol
{

namespace command
{

using namespace phosphor::logging;

std::vector<uint8_t> activatePayload(std::vector<uint8_t>& inPayload,
                                     const message::Handler& handler)
{
    std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
    auto request = reinterpret_cast<ActivatePayloadRequest*>(inPayload.data());
    auto response = reinterpret_cast<ActivatePayloadResponse*>
                    (outPayload.data());

    response->completionCode = IPMI_CC_OK;

    // SOL is the payload currently supported for activation.
    if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    // Only one instance of SOL is currently supported.
    if (request->payloadInstance != 1)
    {
        response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
        return outPayload;
    }

    auto session = (std::get<session::Manager&>(singletonPool).getSession(
                       handler.sessionID)).lock();

    if (!request->encryption && session->isCryptAlgoEnabled())
    {
        response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
        return outPayload;
    }

    auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive(
            request->payloadInstance);
    if (status)
    {
        response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
        return outPayload;
    }

    // Set the current command's socket channel to the session
    handler.setChannelInSession();

    // Start the SOL payload
    try
    {
        std::get<sol::Manager&>(singletonPool).startPayloadInstance(
                request->payloadInstance,
                handler.sessionID);
    }
    catch (std::exception& e)
    {
        log<level::ERR>(e.what());
        response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
        return outPayload;
    }

    response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
    response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
    response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);

    // VLAN addressing is not used
    response->vlanNum = 0xFFFF;

    return outPayload;
}

} // namespace command

} // namespace sol
OpenPOWER on IntegriCloud