⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 con_001.c

📁 HIP 硬件设备管理标准接口
💻 C
字号:
/* * Check if async events work. * * Copyright (c) 2004 by FORCE Computers * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  This * file and program are licensed under a BSD style license.  See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Authors: *     Thomas Kanngieser <thomas.kanngieser@fci.com> * * This test requires: *  -  IPMI hardware *  -  human assistance to generate an event *     e.g. eject switch handle * * So it is not enabled by default. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <unistd.h>#define dIpmiMaxMsgLength 80// This is an overlay for all the address types, so it's easy to// determine the actual address type.  This is kind of like addresses// work for sockets.#define IPMI_MAX_ADDR_SIZE 32struct ipmi_addr{  // Try to take these from the "Channel Medium Type" table  // in section 6.5 of the IPMI 1.5 manual.  int   addr_type;  short channel;  char  data[IPMI_MAX_ADDR_SIZE];};// When the address is not used, the type will be set to this value.// The channel is the BMC's channel number for the channel (usually// 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE	0x0cstruct ipmi_system_interface_addr{  int           addr_type;  short         channel;  unsigned char lun;};// An IPMB Address.#define IPMI_IPMB_ADDR_TYPE		0x01// Used for broadcast get device id as described in section 17.9 of the// IPMI 1.5 manual.#define IPMI_IPMB_BROADCAST_ADDR_TYPE	0x41struct ipmi_ipmb_addr{  int           addr_type;  short         channel;  unsigned char slave_addr;  unsigned char lun;};// Channel for talking directly with the BMC.  When using this// channel, This is for the system interface address type only.  FIXME// - is this right, or should we use -1?#define IPMI_BMC_CHANNEL  0xf#define IPMI_NUM_CHANNELS 0x10// A raw IPMI message without any addressing.  This covers both// commands and responses.  The completion code is always the first// byte of data in the response (as the spec shows the messages laid// out).struct ipmi_msg{  unsigned char  netfn;  unsigned char  cmd;  unsigned short data_len;  unsigned char  *data;};// Messages sent to the interface are this format.struct ipmi_req{  unsigned char *addr; // Address to send the message to.  unsigned int  addr_len;  long    msgid; // The sequence number for the message.  This                 // exact value will be reported back in the                 // response to this request if it is a command.                 // If it is a response, this will be used as                 // the sequence value for the response.  struct ipmi_msg msg;};// Receive types for messages coming from the receive interface.  This// is used for the receive in-kernel interface and in the receive// IOCTL.#define IPMI_RESPONSE_RECV_TYPE		1 // A response to a command#define IPMI_ASYNC_EVENT_RECV_TYPE	2 // Something from the event queue#define IPMI_CMD_RECV_TYPE		3 // A command from somewhere else// Note that async events and received commands do not have a completion// code as the first byte of the incoming data, unlike a response.// Messages received from the interface are this format.struct ipmi_recv{  int     recv_type; // Is this a command, response or an                     // asyncronous event.  unsigned char *addr;    // Address the message was from is put                          // here.  The caller must supply the                          // memory.  unsigned int  addr_len; // The size of the address buffer.                          // The caller supplies the full buffer                          // length, this value is updated to                          // the actual message length when the                          // message is received.  long    msgid; // The sequence number specified in the request                 // if this is a response.  If this is a command,                 // this will be the sequence number from the                 // command.  struct ipmi_msg msg; // The data field must point to a buffer.                       // The data_size field must be set to the                       // size of the message buffer.  The                       // caller supplies the full buffer                       // length, this value is updated to the                       // actual message length when the message                       // is received.};// Get/set the default timing values for an interface.  You shouldn't// generally mess with these.struct ipmi_timing_parms{	int          retries;	unsigned int retry_time_ms;};// The magic IOCTL value for this interface.#define IPMI_IOC_MAGIC 'i'// Send a message to the interfaces.  error values are://   - EFAULT - an address supplied was invalid.//   - EINVAL - The address supplied was not valid, or the command//              was not allowed.//   - EMSGSIZE - The message to was too large.//   - ENOMEM - Buffers could not be allocated for the command.#define IPMICTL_SEND_COMMAND		_IOR(IPMI_IOC_MAGIC, 13,	\					     struct ipmi_req)// Like RECEIVE_MSG, but if the message won't fit in the buffer, it// will truncate the contents instead of leaving the data in the// buffer.#define IPMICTL_RECEIVE_MSG_TRUNC	_IOWR(IPMI_IOC_MAGIC, 11,	\					      struct ipmi_recv)// Set whether this interface receives events.  Note that the first// user registered for events will get all pending events for the// interface.  error values://  - EFAULT - an address supplied was invalid.#define IPMICTL_SET_GETS_EVENTS_CMD	_IOR(IPMI_IOC_MAGIC, 16, int)#define IPMICTL_SET_TIMING_PARMS_CMD	_IOR(IPMI_IOC_MAGIC, 22, \					     struct ipmi_timing_parms)static intOpenSmiFd( int if_num ){  int fd;  char devname[30];  sprintf( devname, "/dev/ipmidev/%d", if_num );  fd = open( devname, O_RDWR );  if ( fd >= 0 )       return fd;  sprintf( devname, "/dev/ipmi/%d", if_num );  fd = open( devname, O_RDWR );  if ( fd >= 0 )       return fd;  sprintf( devname, "/dev/ipmi%d", if_num );  fd = open( devname, O_RDWR );  return fd;}int main( int argc, char *argv[] ){  // set timing and retries  struct ipmi_timing_parms parms;  int                      rv;  int val;  struct pollfd ufds[1];  // open ipmi device  int fd = OpenSmiFd( 0 );  if ( fd < 0 )     {       fprintf( stderr, "cannot open ipmi device !\n" );       return fd;     }  // set timing and retries  parms.retries       = 0;  parms.retry_time_ms = 1000;  rv = ioctl( fd, IPMICTL_SET_TIMING_PARMS_CMD, &parms );  if ( rv == -1 )       fprintf( stderr, "warning: could not set timing parms !\n" );  // we want async events  val = 1;  rv = ioctl( fd, IPMICTL_SET_GETS_EVENTS_CMD, &val );  if ( rv == -1 )       fprintf( stderr, "warning: could not set gets events !\n" );  ufds[0].fd     = fd;  ufds[0].events = POLLIN;  while( 1 )     {       unsigned char data[dIpmiMaxMsgLength];       struct ipmi_addr     addr;       struct ipmi_recv     recv;       rv = poll( ufds, 1, -1 );       if ( rv != 1 )          {            fprintf( stderr, "poll: %d, %s !\n",                     errno, strerror( errno ) );                        usleep( 100000 );            continue;          }       recv.msg.data     = data;       recv.msg.data_len = dIpmiMaxMsgLength;       recv.addr         = (unsigned char *)&addr;       recv.addr_len     = sizeof( struct ipmi_addr );       rv = ioctl( fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv );       if ( rv == -1 )          {            if ( errno == EMSGSIZE )                 // The message was truncated, handle it as such.                 data[0] = 0xC8;            else                 continue;          }       switch( recv.recv_type )          {            case IPMI_RESPONSE_RECV_TYPE:                 printf( "read response: %02x %02x !\n", recv.msg.netfn, recv.msg.cmd );                 break;            case IPMI_ASYNC_EVENT_RECV_TYPE:                 // if we can read an event this test is passed                 printf( "read event: %02x, %02x\n", recv.msg.netfn, recv.msg.cmd );                 break;            case IPMI_CMD_RECV_TYPE:                 printf( "read incomming message: %02x, %02x\n", recv.msg.netfn, recv.msg.cmd );                 break;            default:                 break;          }          }  return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -