#include <libintl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "adm.h"
#include "librsc.h"
#include "smq.h"
extern smq_t ADM_bpMsgQueue;
extern smq_msg_t ADM_bpMsgBuffer[ADM_BP_BUFF_SIZE];
static void usage();
void
ADM_Process_download(int argc, char *argv[])
{
int BootRetry;
uint8_t DownloadLocation;
static bp_msg_t Message;
static struct timespec Timeout;
char *Filename;
FILE *FilePtr;
timestruc_t Delay;
int i, err;
int retry;
int bootOpt;
if ((argc != 3) && (argc != 4)) {
usage();
exit(-1);
}
if (argc == 4) {
if (strcasecmp(argv[2], "boot") != 0) {
usage();
exit(-1);
}
Filename = argv[3];
DownloadLocation = BP_DAT2_FLASH_BOOT;
bootOpt = 1;
} else {
Filename = argv[2];
DownloadLocation = BP_DAT2_FLASH_MAIN;
bootOpt = 0;
}
if ((FilePtr = fopen(Filename, "r")) == NULL) {
(void) fprintf(stderr, "\n%s - \"%s\"\n\n",
gettext("scadm: file could not be opened"), Filename);
exit(-1);
}
if (ADM_Valid_srecord(FilePtr) != 0) {
(void) fprintf(stderr, "\n%s - \"%s\"\n\n",
gettext("scadm: file not a valid s-record"), Filename);
exit(-1);
}
if (smq_init(&ADM_bpMsgQueue, ADM_bpMsgBuffer,
ADM_BP_BUFF_SIZE) != 0) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: ERROR, unable to setup message queue"));
exit(-1);
}
if (rscp_register_bpmsg_cb(ADM_Callback) != 0) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: ERROR, callback init failed"));
exit(-1);
}
BootRetry = ADM_BOOT_RETRY;
while (BootRetry > 0) {
Message.cmd = BP_OBP_BOOTINIT;
Message.dat1 = 0;
Message.dat2 = DownloadLocation;
rscp_send_bpmsg(&Message);
Timeout.tv_nsec = 0;
Timeout.tv_sec = ADM_BOOT_INIT_TIMEOUT;
if (ADM_Boot_recv(&Message, &Timeout) != 0) {
BootRetry = BootRetry - 1;
continue;
} else {
if ((Message.cmd != BP_RSC_BOOTACK) ||
(Message.dat1 != BP_DAT1_BOOTINIT_ACK)) {
ADM_Display_download_error(Message.cmd,
Message.dat1);
exit(-1);
}
break;
}
}
if (BootRetry <= 0) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: SC did not respond during boot "
"initialization"));
exit(-1);
}
if (ADM_Send_file(FilePtr) != 0) {
(void) fprintf(stderr, "\n%s - \"%s\"\n\n",
gettext("scadm: Error downloading file"), Filename);
exit(-1);
}
Delay.tv_nsec = 0;
Delay.tv_sec = 1;
(void) nanosleep(&Delay, NULL);
Message.cmd = BP_OBP_RESET;
Message.dat1 = 0;
Message.dat2 = 0;
rscp_send_bpmsg(&Message);
rscp_unregister_bpmsg_cb(ADM_Callback);
(void) smq_destroy(&ADM_bpMsgQueue);
(void) fclose(FilePtr);
(void) printf("%s\n\n", gettext("Download completed successfully"));
(void) printf("%s\n\n", gettext("Please wait for verification"));
retry = 0;
do {
if (retry == 1) {
if (rsc_nmi() != 0) {
(void) fprintf(stderr, "\n%s\n\n",
gettext(
"scadm: Unable to reset SC hardware"));
exit(-1);
}
Delay.tv_nsec = 0;
Delay.tv_sec = ADM_BOOT_LOAD_TIMEOUT;
(void) nanosleep(&Delay, NULL);
}
for (i = 0; i < 60; i++) {
rscp_msg_t msg;
msg.type = DP_RSC_STATUS;
msg.len = 0;
msg.data = NULL;
(void) printf("%s", gettext("."));
(void) fflush(stdout);
err = rscp_send(&msg);
if (err == 0)
break;
}
if (err == 0)
break;
retry++;
} while (bootOpt && (retry < 2));
if (err == 0)
(void) printf("\n%s\n\n", gettext("Complete"));
else
(void) printf("\n%s\n\n", gettext("Error during verification"));
}
static void
usage()
{
(void) fprintf(stderr, "\n%s\n\n",
gettext("USAGE: scadm download [boot] <file>"));
}