/*
Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

Redistribution of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistribution in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

Neither the name of Sun Microsystems, Inc. or the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

This software is provided "AS IS," without a warranty of any kind.
ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 */
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_mc.h>
#include <ipmitool/log.h>

/* Duplicate this into our memory space.  Nothing in our code path calls this
 * in a critical path.
 */
static IPMI_OEM sel_iana = IPMI_OEM_UNKNOWN;

const struct valstr completion_code_vals[] = {
    {0x00, "Command completed normally"},
    {0xc0, "Node busy"},
    {0xc1, "Invalid command"},
    {0xc2, "Invalid command on LUN"},
    {0xc3, "Timeout"},
    {0xc4, "Out of space"},
    {0xc5, "Reservation cancelled or invalid"},
    {0xc6, "Request data truncated"},
    {0xc7, "Request data length invalid"},
    {0xc8, "Request data field length limit exceeded"},
    {0xc9, "Parameter out of range"},
    {0xca, "Cannot return number of requested data bytes"},
    {0xcb, "Requested sensor, data, or record not found"},
    {0xcc, "Invalid data field in request"},
    {0xcd, "Command illegal for specified sensor or record type"},
    {0xce, "Command response could not be provided"},
    {0xcf, "Cannot execute duplicated request"},
    {0xd0, "SDR Repository in update mode"},
    {0xd1, "Device firmeware in update mode"},
    {0xd2, "BMC initialization in progress"},
    {0xd3, "Destination unavailable"},
    {0xd4, "Insufficient privilege level"},
    {0xd5, "Command not supported in present state"},
    {0xd6, "Cannot execute command, command disabled"},
    {0xff, "Unspecified error"},
    {0x00, NULL}};

const char* val2str(uint16_t val, const struct valstr* vs)
{
    static char un_str[32];
    int i;

    for (i = 0; vs[i].str != NULL; i++)
    {
        if (vs[i].val == val)
            return vs[i].str;
    }

    memset(un_str, 0, 32);
    snprintf(un_str, 32, "Unknown (0x%02X)", val);

    return un_str;
}

void ipmi_intf_session_set_timeout(struct ipmi_intf* intf, uint32_t timeout)
{
    intf->ssn_params.timeout = timeout;
}

void ipmi_intf_session_set_retry(struct ipmi_intf* intf, int retry)
{
    intf->ssn_params.retry = retry;
}

/* Nullify the methods we don't care about. */
void lprintf(int level, const char* format, ...)
{
    return;
}
void lperror(int level, const char* format, ...)
{
    return;
}

int verbose = 0;

const char* buf2str_extended(const uint8_t* buf, int len, const char* sep)
{
    static char str[BUF2STR_MAXIMUM_OUTPUT_SIZE];
    char* cur;
    int i;
    int sz;
    int left;
    int sep_len;

    if (buf == NULL)
    {
        snprintf(str, sizeof(str), "<NULL>");
        return (const char*)str;
    }
    cur = str;
    left = sizeof(str);
    if (sep)
    {
        sep_len = strlen(sep);
    }
    else
    {
        sep_len = 0;
    }
    for (i = 0; i < len; i++)
    {
        /* may return more than 2, depending on locale */
        sz = snprintf(cur, left, "%2.2x", buf[i]);
        if (sz >= left)
        {
            /* buffer overflow, truncate */
            break;
        }
        cur += sz;
        left -= sz;
        /* do not write separator after last byte */
        if (sep && i != (len - 1))
        {
            if (sep_len >= left)
            {
                break;
            }
            strncpy(cur, sep, left - sz);
            cur += sep_len;
            left -= sep_len;
        }
    }
    *cur = '\0';

    return (const char*)str;
}

const char* buf2str(const uint8_t* buf, int len)
{
    return buf2str_extended(buf, len, NULL);
}

uint8_t ipmi_csum(uint8_t* d, int s)
{
    uint8_t c = 0;
    for (; s > 0; s--, d++)
        c += *d;
    return -c;
}

void printbuf(const uint8_t* buf, int len, const char* desc)
{
    int i;

    if (len <= 0)
        return;

    if (verbose < 1)
        return;

    fprintf(stderr, "%s (%d bytes)\n", desc, len);
    for (i = 0; i < len; i++)
    {
        if (((i % 16) == 0) && (i != 0))
            fprintf(stderr, "\n");
        fprintf(stderr, " %2.2x", buf[i]);
    }
    fprintf(stderr, "\n");
}

IPMI_OEM
ipmi_get_oem(struct ipmi_intf* intf)
{
    /* Execute a Get Device ID command to determine the OEM */
    struct ipmi_rs* rsp;
    struct ipmi_rq req;
    struct ipm_devid_rsp* devid;

    if (intf->fd == 0)
    {
        if (sel_iana != IPMI_OEM_UNKNOWN)
        {
            return sel_iana;
        }
        return IPMI_OEM_UNKNOWN;
    }

    /*
     * Return the cached manufacturer id if the device is open and
     * we got an identified OEM owner.   Otherwise just attempt to read
     * it.
     */
    if (intf->opened && intf->manufacturer_id != IPMI_OEM_UNKNOWN)
    {
        return intf->manufacturer_id;
    }

    memset(&req, 0, sizeof(req));
    req.msg.netfn = IPMI_NETFN_APP;
    req.msg.cmd = BMC_GET_DEVICE_ID;
    req.msg.data_len = 0;

    rsp = intf->sendrecv(intf, &req);
    if (rsp == NULL)
    {
        lprintf(LOG_ERR, "Get Device ID command failed");
        return IPMI_OEM_UNKNOWN;
    }
    if (rsp->ccode > 0)
    {
        lprintf(LOG_ERR, "Get Device ID command failed: %#x %s", rsp->ccode,
                val2str(rsp->ccode, completion_code_vals));
        return IPMI_OEM_UNKNOWN;
    }

    devid = (struct ipm_devid_rsp*)rsp->data;

    lprintf(LOG_DEBUG, "Iana: %u",
            IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));

    return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
}
