3 * UCC (University [of WA] Computer Club) Electronic Accounting System
5 * handler_door.c - Door Relay code
7 * This file is licenced under the 3-clause BSD Licence. See the file
8 * COPYING for full details.
22 #include <semaphore.h>
26 #define DOOR_UNLOCKED_DELAY 10 // Time in seconds before the door re-locks
31 void* Door_Lock(void* Unused);
32 int Door_InitHandler();
33 int Door_CanDispense(int User, int Item);
34 int Door_DoDispense(int User, int Item);
37 tHandler gDoor_Handler = {
43 char *gsDoor_SerialPort; // Set from config in main.c
44 sem_t gDoor_UnlockSemaphore;
45 pthread_t gDoor_LockThread;
46 bool gbDoor_LockThreadStarted;
49 void* Door_Lock(void* Unused __attribute__((unused)))
51 gbDoor_LockThreadStarted = true;
54 sem_wait(&gDoor_UnlockSemaphore);
56 int door_serial_handle = InitSerial(gsDoor_SerialPort, 9600);
57 if(door_serial_handle < 0)
59 fprintf(stderr, "Unable to open door serial '%s'\n", gsDoor_SerialPort);
60 perror("Opening door port");
66 tcgetattr(door_serial_handle, &info);
67 info.c_cflag &= ~CLOCAL;
68 tcsetattr(door_serial_handle, TCSANOW, &info);
71 if(write(door_serial_handle, "\xff\x01\x01", 3) != 3) // Relay ON
73 fprintf(stderr, "Failed to write Relay ON (unlock) command, errstr: %s", strerror(errno));
76 sleep(DOOR_UNLOCKED_DELAY);
78 if(write(door_serial_handle, "\xff\x01\x00", 3) != 3) // Relay OFF
80 fprintf(stderr, "Failed to write Relay OFF (lock) command, errstr: %s", strerror(errno));
83 close(door_serial_handle);
87 int Door_InitHandler(void)
89 // Thread started later
96 int Door_CanDispense(int User, int Item)
99 printf("Door_CanDispense: (User=%i,Item=%i)\n", User, Item);
102 if( Item != 0 ) return -1;
104 if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
107 printf("Door_CanDispense: User %i not in door\n", User);
113 printf("Door_CanDispense: User %i can open the door\n", User);
120 * \brief Actually do a dispense from the coke machine
122 int Door_DoDispense(int User, int Item)
125 printf("Door_DoDispense: (User=%i,Item=%i)\n", User, Item);
129 if( Item != 0 ) return -1;
131 // Check if user is in door
132 if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
135 printf("Door_CanDispense: User %i not in door\n", User);
140 // Door thread spun up here because program is forked after thread created
141 if( !gbDoor_LockThreadStarted )
143 // Initialize semaphore, triggers door lock release if semaphore is greater than 0
144 sem_init(&gDoor_UnlockSemaphore, 0, 0);
146 pthread_create(&gDoor_LockThread, NULL, &Door_Lock, NULL);
149 if(sem_post(&gDoor_UnlockSemaphore))
151 perror("Failed to post \"Unlock Door\" semaphore, sem_post returned");
156 printf("Door_DoDispense: User %i opened door\n", User);