/*M*
//  PVCS:
//      $Workfile:   ipmicmd.h  $
//      $Revision:   1.0  $
//      $Modtime:   22 Jul 2002 08:51:14  $
//      $Author:   arcress  $  
//
//  10/24/02 arcress - made cmd param ushort to be more unique
//
 *M*/
/*----------------------------------------------------------------------*
The BSD License 

Copyright (c) 2002, Intel Corporation
Copyright (c) 2009 Kontron America, 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:

  a.. Redistributions of source code must retain the above copyright notice, 
      this list of conditions and the following disclaimer. 
  b.. Redistributions 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. 
  c.. Neither the name of Intel Corporation nor the names of its contributors 
      may be used to endorse or promote products derived from this software 
      without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *----------------------------------------------------------------------*/

#define uchar   unsigned char
#define uint32  unsigned int
#define uint64  unsigned long
// #ifdef __USE_MISC
/* Can use compatibility names for C types. (from sys/types.h) */
// typedef unsigned long int  ulong;
// typedef unsigned short int ushort;
// typedef unsigned int       uint;
// #else
#ifndef ushort
#define ushort  unsigned short
#define ulong   unsigned long
#define uint    unsigned int
#endif

// Other IPMI values
#define PUBLIC_BUS      0
#define PRIVATE_BUS  0x03
#define BMC_SA       0x20
#define BMC_LUN         0
#define SMS_LUN         2
#define ME_SA        0x2C
#define ME_BUS       0x06

#define ADDR_SMI     1
#define ADDR_IPMB    2

// IPMI NetFn types, see Table 5-1
#define NETFN_CHAS   0x00  // chassis
#define NETFN_BRIDGE 0x02  // bridge
#define NETFN_SEVT   0x04  // sensor/event
#define NETFN_APP    0x06  // application
#define NETFN_FW     0x08  // firmware
#define NETFN_STOR   0x0a  // storage
#define NETFN_TRANS  0x0c  // transport
#define NETFN_SOL    0x34  // serial-over-lan (in IPMI 2.0, use TRANS)
#define NETFN_PICMG  0x2c  // for ATCA PICMG systems

#define ACCESS_OK    0
#ifndef IMBAPI_H__ 
// special IMB defines, duplicates if imb_api.h
#define MAX_BUFFER_SIZE        80
#define IPMI_RSPBUF_SIZE       80  // was 1024, but MAX_BUFFER_SIZE == 80
#define MAX_SDR_SIZE           128
#define GET_DEVICE_ID           (0x01 | (NETFN_APP << 8))
#define WRITE_READ_I2C          (0x52 | (NETFN_APP << 8)) /*=MASTER_WRITE_READ*/
#endif

// IPMI Commands, see Table 38-8
#define CMDMASK   0xff      /* mask to leave only the command part */
#define WATCHDOG_RESET  	(0x22 | (NETFN_APP << 8))
#define WATCHDOG_SET    	(0x24 | (NETFN_APP << 8))
#define WATCHDOG_GET    	(0x25 | (NETFN_APP << 8))
#define GET_SYSTEM_GUID 	(0x37 | (NETFN_APP << 8))
#define SET_CHANNEL_ACC 	(0x40 | (NETFN_APP << 8))
#define GET_CHANNEL_ACC	        (0x41 | (NETFN_APP << 8))
#define GET_CHANNEL_INFO        (0x42 | (NETFN_APP << 8))
#define SET_USER_ACCESS         (0x43 | (NETFN_APP << 8))
#define GET_USER_ACCESS         (0x44 | (NETFN_APP << 8))
#define SET_USER_NAME           (0x45 | (NETFN_APP << 8))
#define GET_USER_NAME           (0x46 | (NETFN_APP << 8))
#define SET_USER_PASSWORD       (0x47 | (NETFN_APP << 8))
#define MASTER_WRITE_READ       (0x52 | (NETFN_APP << 8))
// #define SET_PEF_ENABLE       0xA1  /* NETFN_APP (old) */
#define CHASSIS_STATUS          0x01  /* NETFN_CHAS (=00) */
#define CHASSIS_CTL             0x02  /* NETFN_CHAS (=00) */
#define CHASSIS_IDENTIFY        0x04  /* NETFN_CHAS (=00) */
#define SET_BOOT_OPTIONS        0x08  /* NETFN_CHAS (=00) */
#define GET_BOOT_OPTIONS        0x09  /* NETFN_CHAS (=00) */
#define GET_POWERON_HOURS       0x0F  /* NETFN_CHAS (=00) */
#define GET_PEF_CONFIG          (0x13 | (NETFN_SEVT << 8))
#define SET_PEF_CONFIG          (0x12 | (NETFN_SEVT << 8))
#define GET_DEVSDR_INFO		(0x20 | (NETFN_SEVT << 8))
#define GET_DEVICE_SDR		(0x21 | (NETFN_SEVT << 8))
#define RESERVE_DEVSDR_REP	(0x22 | (NETFN_SEVT << 8))
#define SET_SEVT_ENABLE		(0x28 | (NETFN_SEVT << 8))
#define GET_SEVT_ENABLE		(0x29 | (NETFN_SEVT << 8))
#define REARM_SENSOR		(0x2A | (NETFN_SEVT << 8))
#define GET_FRU_INV_AREA        (0x10 | (NETFN_STOR << 8))
#define READ_FRU_DATA           (0x11 | (NETFN_STOR << 8))
#define WRITE_FRU_DATA          (0x12 | (NETFN_STOR << 8))

#define GET_SENSOR_READING_FACTORS (0x23 | (NETFN_SEVT << 8))
#define SET_SENSOR_HYSTERESIS	(0x24 | (NETFN_SEVT << 8))
#define GET_SENSOR_HYSTERESIS	(0x25 | (NETFN_SEVT << 8))
#define SET_SENSOR_THRESHOLD	(0x26 | (NETFN_SEVT << 8))
#define GET_SENSOR_THRESHOLD	(0x27 | (NETFN_SEVT << 8))
#define GET_SENSOR_EVT_ENABLE	(0x29 | (NETFN_SEVT << 8))
#define REARM_SENSOR_EVENTS	(0x2A | (NETFN_SEVT << 8))
#define GET_SENSOR_EVT_STATUS	(0x2B | (NETFN_SEVT << 8))
#define GET_SENSOR_READING	(0x2D | (NETFN_SEVT << 8))
#define GET_SENSOR_TYPE 	(0x2F | (NETFN_SEVT << 8))

#define SET_LAN_CONFIG          (0x01 | (NETFN_TRANS << 8))
#define GET_LAN_CONFIG          (0x02 | (NETFN_TRANS << 8))
#define GET_LAN_STATS           (0x04 | (NETFN_TRANS << 8))
#define SET_SER_CONFIG          (0x10 | (NETFN_TRANS << 8))
#define GET_SER_CONFIG          (0x11 | (NETFN_TRANS << 8))
#define SET_SER_MUX             (0x12 | (NETFN_TRANS << 8))
#define GET_SEL_INFO            (0x40 | (NETFN_STOR << 8))
#define GET_SEL_ALLOCATION_INFO (0x41 | (NETFN_STOR << 8))
#define RESERVE_SEL             (0x42 | (NETFN_STOR << 8))
#define GET_SEL_ENTRY           (0x43 | (NETFN_STOR << 8))
#define CLEAR_SEL               (0x47 | (NETFN_STOR << 8))
#define GET_SEL_TIME     	(0x48 | (NETFN_STOR << 8))
#define GET_SDR_REPINFO		(0x20 | (NETFN_STOR << 8))
#define RESERVE_SDR_REP         (0x22 | (NETFN_STOR << 8))
#define GET_SDR			(0x23 | (NETFN_STOR << 8))
#define ACTIVATE_SOL1		(0x01 | (NETFN_SOL << 8))
#define SET_SOL_CONFIG		(0x03 | (NETFN_SOL << 8))
#define GET_SOL_CONFIG		(0x04 | (NETFN_SOL << 8))
#define ACTIVATE_SOL2		(0x20 | (NETFN_TRANS << 8))
#define SET_SOL_CONFIG2		(0x21 | (NETFN_TRANS << 8))
#define GET_SOL_CONFIG2		(0x22 | (NETFN_TRANS << 8))
#define READ_EVENT_MSGBUF	(0x35 | (NETFN_APP << 8))
#define GET_EVENT_RECEIVER	(0x01 | (NETFN_SEVT << 8))
#define SMS_OS_REQUEST 		0x10 /*(0x10 | (NETFN_APP << 8)) */
/*
 Other commands used for IPMI LAN:
    GET_CHAN_AUTH  (0x38 | (NETFN_APP << 8))
    GET_SESS_CHAL  (0x39 | (NETFN_APP << 8))
    ACT_SESSION    (0x3A | (NETFN_APP << 8))
    SET_SESS_PRIV  (0x3B | (NETFN_APP << 8))
    CLOSE_SESSION  (0x3C | (NETFN_APP << 8))
 */
#define IPMB_CLEAR_MSGF           0x30
#define IPMB_GET_MESSAGE          0x33
#define IPMB_SEND_MESSAGE         0x34

#define PICMG_SLAVE_BUS           0x40 
/* commands under NETFN_PICMG */
#define PICMG_GET_PROPERTIES      0x00   
#define PICMG_GET_LED_PROPERTIES  0x05
#define PICMG_SET_LED_STATE       0x07
#define PICMG_GET_LED_STATE       0x08
#define PICMG_ID               0x00
 
#define NCMDS   62  
typedef struct {
 ushort cmdtyp;
 uchar sa;
 uchar bus;
 uchar netfn;
 uchar lun;
 uchar len;  /*length of request data (FYI, but not used here) */
 uchar rslen;  /*length of response data expected (not including ccode) */
} ipmi_cmd_t;

struct valstr {
        ushort val;
        const char * str;
};

/* IPMI driver types for fDriverTyp */
#define NDRIVERS   12
#define DRV_UNKNOWN 0
#define DRV_IMB   1
#define DRV_VA    2
#define DRV_MV    3
#define DRV_GNU   4
#define DRV_LD    5
#define DRV_LAN   6
#define DRV_KCS   7
#define DRV_SMB   8
#define DRV_LAN2  9
#define DRV_MS   10
#define DRV_BMC  11
#define DRV_SM   12  /*SuperMicro LAN mode*/

/* Event severity codes, used in ievents.c and oem*.c */
#define SEV_INFO  0
#define SEV_MIN   1
#define SEV_MAJ   2
#define SEV_CRIT  3

/* Errors returned by ipmi _send_lan_cmd(), etc, see decode_rv() */
#define ERR_BAD_LENGTH     -24 /*length < MIN */
#define ERR_BAD_FORMAT     -23 /*bad format*/
#define ERR_USAGE          -22 /*usage/help requested*/
#define ERR_NOT_FOUND      -21 /*requested item not found*/
#define ERR_FILE_OPEN      -20 /*cannot open file*/
#define LAN_ERR_DROPPED    -19 /*Remote BMC dropped the connection*/
#define ERR_NOT_ALLOWED    -18 /*access not allowed*/
#define ERR_BAD_PARAM      -17 /*invalid parameter*/
#define ERR_NO_DRV         -16 /*cannot open IPMI driver*/
#define LAN_ERR_V2         -15 /*BMC only supports IPMI 2.0*/
#define LAN_ERR_V1         -14 /*BMC only supports IPMI 1.x*/
#define LAN_ERR_OTHER      -13
#define LAN_ERR_PING       -12 /*error with ping*/
#define LAN_ERR_HOSTNAME   -11 /*error resolving hostname*/
#define LAN_ERR_TOO_SHORT  -10 /*recv data too short */
#define LAN_ERR_NOTSUPPORT -9  /*slave address != 0x20, not supported now */
#define LAN_ERR_INVPARAM   -8  /*null pointers, etc. */
#define LAN_ERR_BADLENGTH  -7  /*length > MAX */
#define LAN_ERR_TIMEOUT    -6  /*timeout signal(SIGALRM) recvd */
#define LAN_ERR_ABORT      -5  /*abort signal(SIGINT) recvd */
#define LAN_ERR_CONNECT    -4  /*problem connecting to BMC*/
#define LAN_ERR_RECV_FAIL  -3  /*receive failed, usually no response*/
#define LAN_ERR_SEND_FAIL  -2  /*send failed */
#define ERR_BMC_MSG      -504  /*error getting message from BMC*/
                   /* see ipmidir.h: ERGETTINGIPMIMESSAGE -504 */

/* values used to request AUTHTYPE */
#define IPMI_SESSION_AUTHTYPE_NONE      0x00
#define IPMI_SESSION_AUTHTYPE_MD2       0x01
#define IPMI_SESSION_AUTHTYPE_MD5       0x02
#define IPMI_SESSION_AUTHTYPE_PASSWORD  0x04
#define IPMI_SESSION_AUTHTYPE_OEM       0x05
#define AUTHTYPE_INIT      0xFF     /*initial value, not set*/
/* mask values used for AUTHTYPE support */
#define IPMI_MASK_AUTHTYPE_NONE      0x01
#define IPMI_MASK_AUTHTYPE_MD2       0x02
#define IPMI_MASK_AUTHTYPE_MD5       0x04
#define IPMI_MASK_AUTHTYPE_PASSWORD  0x10
#define IPMI_MASK_AUTHTYPE_OEM       0x20

#define IPMI_PRIV_LEVEL_OEM      0x05
#define IPMI_PRIV_LEVEL_ADMIN    0x04
#define IPMI_PRIV_LEVEL_OPERATOR 0x03
#define IPMI_PRIV_LEVEL_USER     0x02
#define IPMI_PRIV_LEVEL_CALLBACK 0x01

#define VENDOR_INTEL    0x000157
#define VENDOR_KONTRON  0x003A98   /*=15000*/
#define VENDOR_NSC      0x000322
#define VENDOR_LMC      0x000878
#define VENDOR_TYAN     0x0019FD
#define VENDOR_NEC      0x000077
#define VENDOR_SUPERMICRO 0x002A7C
#define VENDOR_PEPPERCON 0x0028C5  /*used in SuperMicro AOC-SIMSO*/
#define VENDOR_FUJITSU   0x002880  /*Fujitsu-Siemens*/
#define VENDOR_MICROSOFT 0x000137  /* 311. */
#define VENDOR_SUN       0x00002A
#define VENDOR_DELL      0x0002A2 

#define BDELIM  '|'   /*delimeter for canonical output*/

#ifndef LOG_ERR
#define LOG_EMERG       0     //  system is unusable
#define LOG_ALERT       1     //  action must be taken immediately
#define LOG_CRIT        2     //  critical conditions
#define LOG_ERR         3     //  error conditions
#define LOG_WARN        4     //  warning conditions
#define LOG_NOTICE      5     //  normal but significant condition
#define LOG_INFO        6     //  informational
#define LOG_DEBUG       7     //  debug-level messages
#endif

#ifndef _IPMI_RQ_
#define _IPMI_RQ_  1
struct ipmi_rq {
        struct {
                uchar netfn:6;
                uchar lun:2;
                uchar cmd;
                uchar target_cmd;
                ushort data_len;
                uchar *data;
        } msg;
};
#endif

/*
 * ipmi_cmd
 * ushort cmd    (input): (netfn << 8) + command
 * uchar *pdata  (input): pointer to ipmi data
 * uchar sdata   (input): size of ipmi data
 * uchar *presp (output): pointer to response data buffer
 * int *sresp   (input/output): on input, size of response buffer,
 *                              on output, length of response data
 * uchar *cc    (output): completion code
 * char fdebugcmd(input): flag =1 if debug output desired
 */
int ipmi_cmd(ushort cmd, uchar *pdata, uchar sdata, uchar *presp,
		int *sresp, uchar *pcc, char fdebugcmd);   
/*
 * ipmi_cmdraw
 * uchar cmd     (input): IPMI Command
 * uchar netfn   (input): IPMI NetFunction
 * uchar sa      (input): IPMI Slave Address of the MC
 * uchar bus     (input): BUS  of the MC
 * uchar lun     (input): IPMI LUN
 * uchar *pdata  (input): pointer to ipmi data
 * uchar sdata   (input): size of ipmi data
 * uchar *presp (output): pointer to response data buffer
 * int *sresp   (input/output): on input, size of response buffer,
 *                              on output, length of response data
 * uchar *cc    (output): completion code
 * char fdebugcmd(input): flag =1 if debug output desired
 */
int ipmi_cmdraw(uchar cmd, uchar netfn, uchar sa, uchar bus, uchar lun,
		uchar *pdata, uchar sdata, uchar *presp,
		int *sresp, uchar *pcc, char fdebugcmd);
int ipmi_getdeviceid(uchar *presp, int sresp, char fdebugcmd);
int ipmi_close_(void);
/* int ipmi_open(void);  * embedded in ipmi_cmd() */
int ipmi_getpicmg(uchar *presp, int sresp, char fdebug);
char *show_driver_type(int idx);
int   set_driver_type(char *tag);  
int   get_driver_type(void);
int nodeislocal(char *nodename);
int ipmi_cmd_mc(ushort icmd, uchar *pdata, uchar sdata, uchar *presp,
                int *sresp, uchar *pcc, char fdebugcmd);
int ipmi_cmdraw_mc(uchar cmd, uchar netfn, 
		uchar *pdata, uchar sdata, uchar *presp,
		int *sresp, uchar *pcc, char fdebugcmd);
void ipmi_set_mc(uchar bus, uchar sa, uchar lun, uchar type);
void ipmi_get_mc(uchar *bus, uchar *sa, uchar *lun, uchar *type);
void ipmi_restore_mc(void);
void ipmi_set_mymc(uchar bus, uchar sa, uchar lun, uchar type);
void ipmi_get_mymc(uchar *bus, uchar *sa, uchar *lun, uchar *type);
int ipmi_sendrecv(struct ipmi_rq * req, uchar *rsp, int *rsp_len);

/* other common subroutines */
int str_icmp(char *s1, char *s2);
char * strdup_(const char *instr);
uchar htoi(uchar *inhex);
char * decode_cc(ushort icmd, uchar cc);
void dump_buf(char *tag,uchar *pbuf,int sz, char fshowascii);
void parse_lan_options(char c, char *optarg, char fdebugcmd);
void print_lan_opt_usage(void);
void show_outcome(char *prog, int ret);
FILE *open_log(char *mname);
void close_log(void);
void flush_log(void);
void print_log( char *pattn, ... );
void dump_log(FILE *fp,char *tag,uchar *pbuf,int sz, char fshowascii);
void logmsg( char *pname, char *pattn, ... );
int get_lan_channel(uchar *chan);
const char *val2str(ushort val, const struct valstr *vs); /*ipmilanplus.c*/
#ifdef WIN32
int strncasecmp(char *s1, char *s2, int n);
#endif
#ifdef LINUX
extern int set_max_kcs_loops(int ms);  /*see ipmidir.c*/
#endif

// extern char *log_name;   /*used by open_log()*/
// extern uchar my_devid[];  /*defined in ipmicmd.c*/
void  set_mfgid(uchar *devid, int len);
void  get_mfgid(int *pvend, int *pprod);
int   get_errno(void);
char *get_node(void);
int   is_remote(void);
int   set_lan_options(char *node, char *user, char *pswd, int auth, int priv,
                int cipher);
void show_devid(uchar b1, uchar b2, uchar i1, uchar i2);
void set_debug(void);
#define LOG_MSG_LENGTH          1024 

/* These common globals are defined in ipmilan.c */
#define SZGNODE  80
extern void os_usleep(int s, int u);
char *decode_rv(int rv);

//extern int  fipmi_lan;
//extern char *gnode;
//extern char *guser;
//extern char *gpswd;
//extern int  gauth_type;
//extern int  gpriv_level;

/* These externals are conditionally compiled in ipmicmd.c */
/*-----------------------------------------------------------------*
   int ipmi_cmdraw_ia(      uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_mv(      uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_va(      uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_ld(      uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_direct(  uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_gnu(char *node, uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_lan(char *node, uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
   int ipmi_cmdraw_lan2(char *node, uchar cmd, uchar netfn, uchar lun, uchar sa,
                uchar bus, uchar *pdata, uchar sdata, uchar *presp, int *sresp,
                uchar *pcc, char fdebugcmd);
 *-----------------------------------------------------------------*/

/* end ipmicmd.h */
