main.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "USBMicroX.h"
  2. #include <fcntl.h>
  3. #include <sys/stat.h>
  4. #include <sys/time.h>
  5. #define DATA_DIR "plexMonitor/"
  6. #define OUT_FILE_DEFAULT "MOTION"
  7. #define SLEEP_DELAY 250000
  8. #define TIMEOUT 2
  9. #define MAX_STR_LEN 4096
  10. //#define DEBUG
  11. // Typedef
  12. typedef unsigned char u8;
  13. // Prototypes
  14. void timeout(int sig);
  15. USBmX_DeviceRef init();
  16. u8 readDev(USBmX_DeviceRef dev);
  17. char * initPaths(const char *name);
  18. // Globals
  19. USBmX_ContextRef ctx;
  20. int main(int argc, const char * argv[])
  21. {
  22. char *outfile;
  23. const char *serial;
  24. unsigned int motion;
  25. USBmX_DeviceRef device;
  26. // Sanity check
  27. if (argc < 2) {
  28. fprintf(stderr, "Usage: %s SERIAL [NAME]\n", argv[0]);
  29. exit(-1);
  30. }
  31. // Setup the output file
  32. if (argc > 2) {
  33. outfile = initPaths(argv[2]);
  34. } else {
  35. outfile = initPaths(OUT_FILE_DEFAULT);
  36. }
  37. // Monitor for alarms
  38. signal(SIGALRM, timeout);
  39. // Setup the USB devices
  40. device = init(argv[1]);
  41. // Read forever
  42. while (1) {
  43. // Check for motion in any device
  44. motion = 0;
  45. if (readDev(device)) {
  46. motion = 1;
  47. }
  48. // If we detected motion
  49. if (motion > 0) {
  50. #ifdef DEBUG
  51. printf("Motion detected\n");
  52. #endif
  53. if (utimes(outfile, NULL) != 0) {
  54. fprintf(stderr, "Error touching output file (%s): %s\n", strerror(errno), outfile);
  55. exit(2);
  56. }
  57. } else {
  58. #ifdef DEBUG
  59. printf("\n");
  60. #endif
  61. }
  62. // Delay and loop
  63. usleep(SLEEP_DELAY);
  64. }
  65. // Cleanup (we never get here)
  66. USBmX_Destroy(ctx);
  67. return 0;
  68. }
  69. // Catch the timeout
  70. void timeout(int sig) {
  71. signal(sig, SIG_IGN);
  72. fprintf(stderr, "Timeout waiting for USB read\n");
  73. exit(1);
  74. }
  75. // Setup the USBMicro context and build refs to our specified devices
  76. USBmX_DeviceRef init(const char *serial) {
  77. USBmX_DeviceRef device;
  78. // Create a new USBmicroX context as needed
  79. if (!ctx) {
  80. ctx = USBmX_Create();
  81. USBmX_Begin(ctx);
  82. }
  83. // Find the specified device
  84. device = USBmX_DeviceWithSerial(ctx, serial);
  85. if (!device) {
  86. fprintf(stderr, "Device not found: %s\n", serial);
  87. exit(1);
  88. }
  89. // Return device handle
  90. return device;
  91. }
  92. // Read the specified USBMicro device
  93. u8 readDev(USBmX_DeviceRef dev) {
  94. unsigned char data = 0x00;
  95. // Enable the timeout
  96. alarm(TIMEOUT);
  97. // Read from the device
  98. if (USBmX_ReadA(dev, &data) != 0) {
  99. fprintf(stderr, "Device read error\n");
  100. exit(1);
  101. }
  102. // Clear the timeout
  103. alarm(0);
  104. // Return pin A5
  105. return (data & 0x20);
  106. }
  107. // Setup the data directory and output file
  108. char * initPaths(const char *name) {
  109. int fd;
  110. size_t dirLen, fileLen;
  111. char *datadir, *outfile;
  112. struct stat statbuf;
  113. // Construct the data directory and output file paths
  114. dirLen = confstr(_CS_DARWIN_USER_TEMP_DIR, NULL, (size_t) 0);
  115. dirLen += sizeof(DATA_DIR);
  116. fileLen = dirLen + strnlen(name, MAX_STR_LEN);
  117. datadir = malloc(dirLen);
  118. outfile = malloc(fileLen);
  119. if (datadir == NULL || outfile == NULL) {
  120. fprintf(stderr, "Out of memory\n");
  121. exit(1);
  122. }
  123. confstr(_CS_DARWIN_USER_TEMP_DIR, datadir, dirLen);
  124. strlcat(datadir, DATA_DIR, dirLen);
  125. strlcpy(outfile, datadir, fileLen);
  126. strlcat(outfile, name, fileLen);
  127. // Create the datadir as needed
  128. stat(datadir, &statbuf);
  129. if (!S_ISDIR(statbuf.st_mode)) {
  130. fprintf(stderr, "Creating data directory: %s\n", datadir);
  131. if (mkdir(datadir, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
  132. fprintf(stderr, "Error creating data directory (%s): %s\n", strerror(errno), datadir);
  133. exit(1);
  134. }
  135. }
  136. // Create the output file as needed
  137. stat(outfile, &statbuf);
  138. if(!S_ISREG(statbuf.st_mode)) {
  139. fprintf(stderr, "Creating output file: %s\n", outfile);
  140. fd = open(outfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  141. if (fd <= 0 || close(fd) != 0) {
  142. fprintf(stderr, "Error creating output file (%s): %s\n", strerror(errno), outfile);
  143. exit(1);
  144. }
  145. }
  146. // Return the output file path
  147. return outfile;
  148. }