// Handy dany program to send a reset command to the AardRemote and
// wait for the ACK. Should be able to invoke avrdude to upload new
// microcode following this command (with maybe a few nanosecond
// usleep if it doesn't work with no delay).

#include <stdio.h>
#include "LibAard.h"
#include "Commands.h"
#include "AardRemoteMessage.h"
#include "RawIR.h"

bool
Validate(AardRemoteMessage * msg,
         unsigned char msg_kind,
         unsigned char msg_code,
         unsigned short msg_len) {
   if (msg == NULL) {
      printf("No message seen\n");
      return false;
   } else if (! ((msg->MessageKind() == msg_kind) &&
                 (msg->FunctionCode() == msg_code) &&
                 (msg->MessageLength() == msg_len))) {
      printf("Unexpected message: ");
      msg->DebugDump();
      return false;
   }
   return true;
}

int
main(int argc, char ** argv) {
   AardRemoteMessage * msg;

   if (argc != 2) {
      printf("usage: aardreset devicename\n");
      return 2;
   }
   LibAard l;
   if (l.OpenAardRemote(argv[1]) < 0) {
      fprintf(stderr, "open of %s failed\n", argv[1]);
      return 2;
   }

   // Get synced up and make sure the aardremote is talking.

   l.WaitForStartup();
   if (l.HasError()) {
      printf("HasError returned true following WaitForStartup()\n");
      return 2;
   }

   // Now query everything that can be queried.

   l.SendCommand(MKCR_QVERSION);
   msg = l.WaitMessage(100);
   if (Validate(msg, MK_REPLY, MKCR_QVERSION, 2)) {
      unsigned short vers = msg->MessageBody()[1];
      if (vers < 7) {
         printf("AardRemote microcode version (%u) has no reset support.\n",
                vers);
         return 2;
      }
      printf("AardRemote microcode version is %u\n", vers);
   }
   delete msg;

   l.SendCommand(MKCR_RESET);
   msg = l.WaitMessage(100);
   if (Validate(msg, MK_REPLY, MKCR_RESET, 1)) {
      printf("AardRemote has been reset, "
             "you may upload microcode in about 2 seconds.\n");
   } else {
      printf("Reset didn't work - don't know why.\n");
      return 2;
   }
   delete msg;
   return 0;
}
