1 #include <avr/pgmspace.h> 
   9 uint8_t ipmb_csum(unsigned char *buf
, int len
) 
  14         for(i 
= 0; i 
< len
; i
++) { 
  21 void ipmb_send(struct ipmb_resp 
*resp
, const unsigned char *data
, uint8_t datalen
) 
  23         unsigned char buf
[24]; 
  30         buf
[1] = ((resp
->netFn
)<<2) | (resp
->rqLUN 
& 0x3); 
  31         buf
[2] = ipmb_csum(buf
, 2); 
  33         buf
[4] = ((resp
->rqSEQ
)<<2) | (resp
->rsLUN 
& 0x3); 
  35         memcpy(buf
+6, data
, datalen
); 
  37         buf
[len
-1] = ipmb_csum(buf
+3, len 
- 4); 
  41         for(i 
= 0; i 
< len
; i
++) { 
  42                 printf("0x%02x ", buf
[i
]); 
  52 void ipmb_dump_req(struct ipmb_req 
*req
) 
  56         printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 
  57         printf("Connection Header:\n"); 
  58         printf("\trs Slave Addr.: 0x%02x\n", req
->rsSA
); 
  59         printf("\tnetFn: 0x%02x, LUN: 0x%02x\n", req
->netFn
, req
->rsLUN
); 
  61         printf("\trq Slave Addr.: 0x%02x\n", req
->rqSA
); 
  62         printf("\trqSeq: 0x%02x, rqLUN: 0x%02x\n", req
->rqSEQ
, req
->rqLUN
); 
  63         printf("\tcmd: 0x%02x\n", req
->cmd
); 
  65         for(i 
= 0; i 
< req
->datalen
; i
++) { 
  66                 printf("0x%02x ", req
->data
[i
]); 
  69         printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); 
  73 void ipmb_invalid(struct ipmb_resp 
*resp
) 
  76         const unsigned char cmd_invalid
[] = {IPMB_CC_INVALID
}; 
  78         ipmb_send(resp
, cmd_invalid
, sizeof(cmd_invalid
)); 
  82 void ipmb_cmd(struct ipmb_req 
*req
) 
  84         struct ipmb_resp resp
; 
  85         const unsigned char get_devid
[] = 
  86                 {IPMB_CC_NORMALLY
, 0x42, 0x42, 0x01, 0x01, 0x51, 0xff /* Add. Dev. Supp */, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
  87         const unsigned char get_wd_timer
[] = 
  88                 {IPMB_CC_NORMALLY
, 0x42, 0x00, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xfe}; 
  89         const unsigned char cc_normal
[] = 
  91         const unsigned char sel_info
[] = 
  92                 {IPMB_CC_NORMALLY
, 0x51, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}; 
  93         const unsigned char sel_alloc_info
[] = 
  94                 {IPMB_CC_NORMALLY
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
  95         const unsigned char sel_entry
[] = 
  97         const unsigned char sel_timestamp
[] = 
  98                 {IPMB_CC_NORMALLY
, 0x00, 0x00, 0x00, 0x00}; 
  99         const unsigned char chassis_status
[] = 
 100                 {IPMB_CC_NORMALLY
, 0x60, 0x10, 0x00, 0x00}; 
 101         const unsigned char reserve_sdr
[] = 
 102                 {IPMB_CC_NORMALLY
, 0x00, 0x00}; 
 103         const unsigned char get_sdr
[] = 
 104                 {IPMB_CC_NORMALLY
, 0xff, 0xff}; 
 106         resp
.rqSA 
= req
->rqSA
; 
 107         resp
.netFn 
= req
->netFn
+1; 
 108         resp
.rqLUN 
= req
->rqLUN
; 
 109         resp
.rsSA 
= req
->rsSA
; 
 110         resp
.rqSEQ 
= req
->rqSEQ
; 
 111         resp
.rsLUN 
= req
->rsLUN
; 
 114         switch (req
->netFn
) { 
 115                 case IPMB_NETFN_CHASSIS
: 
 117                                 case IPMB_CHASSIS_GET_STATUS
: 
 118                                         ipmb_send(&resp
, chassis_status
, sizeof(chassis_status
)); 
 120                                 case IPMB_CHASSIS_CONTROL
: 
 121                                         chassis_control(*(req
->data
)); 
 122                                         ipmb_send(&resp
, cc_normal
, sizeof(cc_normal
)); 
 126                                         printf("Unknown chassis cmd 0x%02x\n", req
->cmd
); 
 134                 case IPMB_NETFN_SENSOR_EVENT
: 
 136                                 case IPMB_SE_PLATFORM_EVENT
: 
 138                                          * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
 140                                          *         rs Slave Addr.: 0x24 
 141                                          *         netFn: 0x04, LUN: 0x00 
 143                                          *         rq Slave Addr.: 0x28 
 144                                          *         rqSeq: 0x03, rqLUN: 0x00 
 146                                          *         Data: 0x03 0xc8 0x00 0x6f 0x61 0x8f 0x03 
 147                                          * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
 148                                          * data[0] - EvMRev:                            0x03 
 149                                          * data[1] - Sensor Type:                       0xc8 
 150                                          * data[2] - Sensor #:                          0x00 
 151                                          * data[3] - Event Dir(1)|Event Type(7):        0x6f: 0x0|0x6f (assert, discrete) 
 152                                          * data[4] - Event Data:                        0x61 
 153                                          * data[5] - Event Data:                        0x8f 
 154                                          * data[6] - Event Data:                        0x03 
 156                                         ipmb_send(&resp
, cc_normal
, sizeof(cc_normal
)); 
 162                                         printf("Unknown sensor cmd 0x%02x\n", req
->cmd
); 
 172                                 case IPMB_APP_GET_DEVICE_ID
: 
 173                                         ipmb_send(&resp
, get_devid
, sizeof(get_devid
)); 
 176                                 case IPMB_APP_GET_WATCHDOG_TIMER
: 
 177                                         ipmb_send(&resp
, get_wd_timer
, sizeof(get_wd_timer
)); 
 182                                         printf("Unknown app cmd 0x%02x\n", req
->cmd
); 
 190                 case IPMB_NETFN_STORAGE
: 
 192                                 case IPMB_STORAGE_RESERVE_SDR
: 
 193                                         ipmb_send(&resp
, reserve_sdr
, sizeof(reserve_sdr
)); 
 195                                 case IPMB_STORAGE_GET_SDR
: 
 196                                         ipmb_send(&resp
, get_sdr
, sizeof(get_sdr
)); 
 198                                 case IPMB_STORAGE_GET_SEL_INFO
: 
 199                                         ipmb_send(&resp
, sel_info
, sizeof(sel_info
)); 
 201                                 case IPMB_STORAGE_GET_SEL_ALLOCATION
: 
 202                                         ipmb_send(&resp
, sel_alloc_info
, sizeof(sel_alloc_info
)); 
 204                                 case IPMB_STORAGE_GET_SEL_ENTRY
: 
 205                                         ipmb_send(&resp
, sel_entry
, sizeof(sel_entry
)); 
 207                                 case IPMB_STORAGE_GET_SEL_TIME
: 
 208                                         ipmb_send(&resp
, sel_timestamp
, sizeof(sel_timestamp
)); 
 212                                         printf("Unknown storage cmd 0x%02x\n", req
->cmd
); 
 222                         printf("Unknown netFn 0x%02x\n", req
->netFn
); 
 230 void decode_ipmb_pkt(unsigned char *buf
, int len
) 
 234         if ((buf
[2] != ipmb_csum(buf
, 2)) || 
 235             (buf
[len
-1] != ipmb_csum(buf
+3, len
-4))) 
 236                 return; /* Checksum wrong */ 
 239         req
.netFn 
= (buf
[1]>>2)&0x3f; 
 240         req
.rsLUN 
= (buf
[1] & 0x03); 
 242         req
.rqSEQ 
= (buf
[4]>>2)&0x3f; 
 243         req
.rqLUN 
= (buf
[4] & 0x03); 
 246         req
.datalen 
= len 
- 6 - 1;