static int do_command(const unsigned char *command, char *reply, int cmd_len) { int ret; ret = ser_send_buf(upsfd, command, cmd_len); if (ret < 0) { upsdebug_with_errno(2, "send"); return -1; } else if (ret < cmd_len) { upsdebug_hex(2, "send: truncated", command, ret); return -1; } upsdebug_hex(2, "send", command, ret); ret = ser_get_buf_len(upsfd, reply, 8, 1, 0); /* it needs that this driver works with USB to Serial cable */ if (ret < 0) { upsdebug_with_errno(2, "read"); return -1; } else if (ret < 6) { upsdebug_hex(2, "read: truncated", reply, ret); return -1; } else if (reply[7] != cksum(reply, 7)) { upsdebug_hex(2, "read: checksum error", reply, ret); return -1; } upsdebug_hex(2, "read", reply, ret); return ret; }
int get_ups_statuscode() { uint8_t length; riello_init_serial(); length = riello_prepare_rc(&bufOut[0], gpser_error_control); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Communication error while writing to port"); return -1; } riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Get statuscode Ko: bad CRC or Checksum"); return -1; } /* optional */ if (!wait_packet && foundnak) { upsdebugx (3, "Get statuscode Ko: command not supported"); return 0; } upsdebugx (3, "Get statuscode Ok: received byte %u", buf_ptr_length); riello_parse_rc(&bufIn[0], &DevData); return 0; }
static void send_command(unsigned char *command, int command_length) { int retry = 0, sent; unsigned char sbuf[128]; /* Prepare the send buffer */ sbuf[0] = PW_COMMAND_START_BYTE; sbuf[1] = (unsigned char)(command_length); memcpy(sbuf+2, command, command_length); command_length += 2; /* Add checksum */ sbuf[command_length] = calc_checksum(sbuf); command_length += 1; upsdebug_hex (3, "send_command", sbuf, command_length); while (retry++ < PW_MAX_TRY) { if (retry == PW_MAX_TRY) { ser_send_char(upsfd, 0x1d); /* last retry is preceded by a ESC.*/ usleep(250000); } sent = ser_send_buf(upsfd, sbuf, command_length); if (sent == command_length) { return; } } }
void send_zeros(void) { /* send 100 times the value 0x00.....it seems to be used for resetting */ unsigned char buf[100]; /* the ups serial port */ memset(buf, '\0', sizeof(buf)); ser_send_buf(upsfd, buf, sizeof(buf)); return; }
/* send a write command to the UPS, the write command and the value to be written are passed with a char* buffer it retries 5 times before give up */ void send_write_command(unsigned char *command, int command_length) { int i, retry, sent, checksum; unsigned char raw_buf[255]; /* prepares the raw data */ raw_buf[0] = 0x02; /* STX byte */ raw_buf[1] = (unsigned char)(command_length + 1); /* data length + checksum */ memcpy(raw_buf+2, command, command_length); command_length += 2; /* calculate checksum */ checksum = 0; for (i = 1; i < command_length; i++) checksum += raw_buf[i]; checksum = checksum % 256; raw_buf[command_length] = (unsigned char)checksum; command_length +=1; retry = 0; sent = 0; while ((sent != (command_length)) && (retry < 5)) { if (retry == 4) send_zeros(); /* last retry is preceded by a serial reset... */ sent = ser_send_buf(upsfd, raw_buf, (command_length)); if (sent != (command_length)) printf("Error sending command %d\n", raw_buf[2]); retry += 1; } }
int start_ups_comm() { uint8_t length; upsdebugx (2, "entering start_ups_comm()\n"); riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) { length = riello_prepare_gi(&bufOut[0]); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Communication error while writing to port"); return -1; } riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); } else { bufOut[0] = 192; length = 1; if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Communication error while writing to port"); return -1; } riello_serialcomm(&bufIn[0], DEV_RIELLOSENTRY); } if (!wait_packet && foundbadcrc) { upsdebugx (3, "Get identif Ko: bad CRC or Checksum"); return 1; } if (!wait_packet && foundnak) { upsdebugx (3, "Get identif Ko: command not supported"); return 1; } upsdebugx (3, "Get identif Ok: received byte %u", buf_ptr_length); return 0; }
/* send a read command to the UPS, it retries 5 times before give up it's a 4 byte request (STX, LENGTH, COMMAND and CHECKSUM) */ void send_read_command(char command) { int retry, sent; unsigned char buf[4]; retry = 0; sent = 0; while ((sent != 4) && (retry < 5)) { buf[0]=0x02; /* STX Start of Transmission */ buf[1]=0x02; /* data length(data + checksum byte) */ buf[2]=command; /* command to send */ buf[3]=buf[1] + buf[2]; /* checksum (sum modulus 256 of data bytes + length) */ if (retry == 4) send_zeros(); /* last retry is preceded by a serial reset...*/ sent = ser_send_buf(upsfd, buf, 4); retry += 1; } }
int get_ups_sentr() { uint8_t length; riello_init_serial(); bufOut[0] = requestSENTR; if (requestSENTR == SENTR_EXT176) { bufOut[1] = 103; bufOut[2] = 1; bufOut[3] = 0; bufOut[4] = 24; length = 5; } else length = 1; if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Communication error while writing to port"); return -1; } riello_serialcomm(&bufIn[0], DEV_RIELLOSENTRY); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Get sentry Ko: bad CRC or Checksum"); return -1; } /* mandatory */ if (!wait_packet && foundnak) { upsdebugx (3, "Get sentry Ko: command not supported"); return -1; } upsdebugx (3, "Get sentry Ok: received byte %u", buf_ptr_length); riello_parse_sentr(&bufIn[0], &DevData); return 0; }
void SendCmdToSerial(unsigned char *Buff, int Len) { int i; unsigned char Tmp[20], Xor ; Tmp[0] = STX_CHAR ; Xor = Tmp[1] = (unsigned char) (Len & 0x1f) ; for (i=0 ; i < Tmp[1] ; i++) { Tmp[i+2] = Buff[i] ; Xor ^= Buff[i] ; } Tmp[Len+2] = Xor ; upsdebug_hex(4, "->UPS", Tmp, Len+3) ; /* flush serial port */ ser_flush_in(upsfd, "", 0) ; /* empty input buffer */ ser_send_buf(upsfd, Tmp, Len+3) ; /* send data to the UPS */ }
int get_ups_status() { uint8_t numread, length; riello_init_serial(); length = riello_prepare_rs(&bufOut[0], gpser_error_control); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Communication error while writing to port"); return -1; } if (input_monophase) numread = LENGTH_RS_MM; else if (output_monophase) numread = LENGTH_RS_TM; else numread = LENGTH_RS_TT; riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Get status Ko: bad CRC or Checksum"); return -1; } /* mandatory */ if (!wait_packet && foundnak) { upsdebugx (3, "Get status Ko: command not supported"); return -1; } upsdebugx (3, "Get status Ok: received byte %u", buf_ptr_length); riello_parse_rs(&bufIn[0], &DevData, numread); return 0; }
int riello_instcmd(const char *cmdname, const char *extra) { uint8_t length; uint16_t delay; const char *delay_char; if (!riello_test_bit(&DevData.StatusCode[0], 1)) { if (!strcasecmp(cmdname, "load.off")) { delay = 0; riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cs(bufOut, gpser_error_control, delay); else length = riello_prepare_shutsentr(bufOut, delay); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.off communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.off Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.off Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command load.off Ok"); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "load.off.delay")) { delay_char = dstate_getinfo("ups.delay.shutdown"); delay = atoi(delay_char); riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cs(bufOut, gpser_error_control, delay); else length = riello_prepare_shutsentr(bufOut, delay); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.off delay communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.off.delay Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.off.delay Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command load.off delay Ok"); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "load.on")) { delay = 0; riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cr(bufOut, gpser_error_control, delay); else { length = riello_prepare_setrebsentr(bufOut, delay); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.on communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.on Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.on Ko: command not supported"); return STAT_INSTCMD_FAILED; } length = riello_prepare_rebsentr(bufOut, delay); } if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.on communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.on Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.on Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command load.on Ok"); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "load.on.delay")) { delay_char = dstate_getinfo("ups.delay.reboot"); delay = atoi(delay_char); riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cr(bufOut, gpser_error_control, delay); else { length = riello_prepare_setrebsentr(bufOut, delay); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.on delay communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.on delay Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.on delay Ko: command not supported"); return STAT_INSTCMD_FAILED; } length = riello_prepare_rebsentr(bufOut, delay); } if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command load.on delay communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command load.on.delay Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command load.on.delay Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command load.on delay Ok"); return STAT_INSTCMD_HANDLED; } } else { if (!strcasecmp(cmdname, "shutdown.return")) { delay_char = dstate_getinfo("ups.delay.shutdown"); delay = atoi(delay_char); riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cs(bufOut, gpser_error_control, delay); else length = riello_prepare_shutsentr(bufOut, delay); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command shutdown.return communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command shutdown.return Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command shutdown.return Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command shutdown.return Ok"); return STAT_INSTCMD_HANDLED; } } if (!strcasecmp(cmdname, "shutdown.stop")) { riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_cd(bufOut, gpser_error_control); else length = riello_prepare_cancelsentr(bufOut); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command shutdown.stop communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command shutdown.stop Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command shutdown.stop Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command shutdown.stop Ok"); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "test.panel.start")) { riello_init_serial(); length = riello_prepare_tp(bufOut, gpser_error_control); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command test.panel.start communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command test.panel.start Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command test.panel.start Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command test.panel.start Ok"); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "test.battery.start")) { riello_init_serial(); if (typeRielloProtocol == DEV_RIELLOGPSER) length = riello_prepare_tb(bufOut, gpser_error_control); else length = riello_prepare_tbsentr(bufOut); if (ser_send_buf(upsfd, bufOut, length) == 0) { upsdebugx (3, "Command test.battery.start communication error"); return STAT_INSTCMD_FAILED; } riello_serialcomm(&bufIn[0], typeRielloProtocol); if (!wait_packet && foundbadcrc) { upsdebugx (3, "Command battery.start Ko: bad CRC or Checksum"); return STAT_INSTCMD_FAILED; } if (!wait_packet && foundnak) { upsdebugx (3, "Command battery.start Ko: command not supported"); return STAT_INSTCMD_FAILED; } upsdebugx (3, "Command test.battery.start Ok"); return STAT_INSTCMD_HANDLED; } upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname); return STAT_INSTCMD_UNKNOWN; }
void riello_comm_setup(const char *port) { uint8_t length; upsdebugx(2, "set baudrate 9600"); ser_set_speed(upsfd, device_path, B9600); upsdebugx(2, "try to detect SENTR"); riello_init_serial(); bufOut[0] = 192; ser_send_buf(upsfd, bufOut, 1); riello_serialcomm(&bufIn[0], DEV_RIELLOSENTRY); if (buf_ptr_length == 103) { typeRielloProtocol = DEV_RIELLOSENTRY; upslogx(LOG_INFO, "Connected to UPS SENTR on %s with baudrate %d", port, 9600); return; } upsdebugx(2, "try to detect GPSER"); riello_init_serial(); length = riello_prepare_gi(&bufOut[0]); ser_send_buf(upsfd, bufOut, length); riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); if (!wait_packet && !foundbadcrc && !foundnak) { typeRielloProtocol = DEV_RIELLOGPSER; upslogx(LOG_INFO, "Connected to UPS GPSER on %s with baudrate %d", port, 9600); return; } upsdebugx(2, "set baudrate 1200"); ser_set_speed(upsfd, device_path, B1200); upsdebugx(2, "try to detect SENTR"); riello_init_serial(); bufOut[0] = 192; ser_send_buf(upsfd, bufOut, 1); riello_serialcomm(&bufIn[0], DEV_RIELLOSENTRY); if (buf_ptr_length == 103) { typeRielloProtocol = DEV_RIELLOSENTRY; upslogx(LOG_INFO, "Connected to UPS SENTR on %s with baudrate %d", port, 1200); return; } upsdebugx(2, "try to detect GPSER"); riello_init_serial(); length = riello_prepare_gi(&bufOut[0]); ser_send_buf(upsfd, bufOut, length); riello_serialcomm(&bufIn[0], DEV_RIELLOGPSER); if (!wait_packet && !foundbadcrc && !foundnak) { typeRielloProtocol = DEV_RIELLOGPSER; upslogx(LOG_INFO, "Connected to UPS GPSER on %s with baudrate %d", port, 1200); return; } fatalx(EXIT_FAILURE, "Can't connect to the UPS on port %s!\n", port); }