0273cbf4788d366d8b1453e04a6cb1e9ad749e2d
[tpg/opendispense2.git] / src / server / handler_door.c
1 /*
2  * OpenDispense 2 
3  * UCC (University [of WA] Computer Club) Electronic Accounting System
4  *
5  * handler_door.c - Door Relay code
6  *
7  * This file is licenced under the 3-clause BSD Licence. See the file
8  * COPYING for full details.
9  */
10 #define DEBUG   1
11 #define USE_POPEN       0
12
13 #include "common.h"
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <unistd.h>
21 #include <pty.h>
22 #include <pthread.h>
23 #include <semaphore.h>
24 #include <errno.h>
25
26 #define DOOR_UNLOCKED_DELAY     10      // Time in seconds before the door re-locks
27
28 // === IMPORTS ===
29
30 // === PROTOTYPES ===
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);
35
36 // === GLOBALS ===
37 tHandler        gDoor_Handler = {
38         "door",
39         Door_InitHandler,
40         Door_CanDispense,
41         Door_DoDispense
42 };
43 char    *gsDoor_SerialPort;     // Set from config in main.c
44 sem_t   gDoor_UnlockSemaphore;
45 pthread_t       gDoor_LockThread;
46
47 // === CODE ===
48 void* Door_Lock(void* Unused __attribute__((unused)))
49 {
50         while(1)
51         {
52                 sem_wait(&gDoor_UnlockSemaphore);
53
54                 int door_serial_handle = InitSerial(gsDoor_SerialPort, 9600);
55                 if(door_serial_handle < 0)
56                 {
57                         fprintf(stderr, "Unable to open door serial '%s'\n", gsDoor_SerialPort);
58                         perror("Opening door port");
59                 }
60
61                 // Disable local echo
62                 {
63                         struct termios  info;
64                         tcgetattr(door_serial_handle, &info);
65                         info.c_cflag &= ~CLOCAL;
66                         tcsetattr(door_serial_handle, TCSANOW, &info);
67                 }
68
69                 if(write(door_serial_handle, "\xff\x01\x01", 3) != 3)   // Relay ON
70                 {
71                         fprintf(stderr, "Failed to write Relay ON (unlock) command, errstr: %s", strerror(errno));
72                 }
73
74                 sleep(DOOR_UNLOCKED_DELAY);
75
76                 if(write(door_serial_handle, "\xff\x01\x00", 3) != 3)   // Relay OFF
77                 {
78                         fprintf(stderr, "Failed to write Relay OFF (lock) command, errstr: %s", strerror(errno));
79                 }
80
81                 close(door_serial_handle);
82         }
83 }
84
85 int Door_InitHandler(void)
86 {
87         // Initialize semaphore, triggers door lock release if semaphore is greater than 0
88         sem_init(&gDoor_UnlockSemaphore, 0, 0); 
89         
90         pthread_create(&gDoor_LockThread, NULL, &Door_Lock, NULL);
91
92         return 0;
93 }
94
95 /**
96  */
97 int Door_CanDispense(int User, int Item)
98 {
99         #if DEBUG
100         printf("Door_CanDispense: (User=%i,Item=%i)\n", User, Item);
101         #endif
102         // Sanity please
103         if( Item != 0 ) return -1;
104         
105         if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
106         {
107                 #if DEBUG
108                 printf("Door_CanDispense: User %i not in door\n", User);
109                 #endif
110                 return 1;
111         }
112         
113         #if DEBUG
114         printf("Door_CanDispense: User %i can open the door\n", User);
115         #endif
116         
117         return 0;
118 }
119
120 /**
121  * \brief Actually do a dispense from the coke machine
122  */
123 int Door_DoDispense(int User, int Item)
124 {       
125         #if DEBUG
126         printf("Door_DoDispense: (User=%i,Item=%i)\n", User, Item);
127         #endif
128         
129         // Sanity please
130         if( Item != 0 ) return -1;
131         
132         // Check if user is in door
133         if( !(Bank_GetFlags(User) & USER_FLAG_DOORGROUP) )
134         {
135                 #if DEBUG
136                 printf("Door_CanDispense: User %i not in door\n", User);
137                 #endif
138                 return 1;
139         }
140         
141
142         if(sem_post(&gDoor_UnlockSemaphore))
143         {
144                 perror("Failed to post \"Unlock Door\" semaphore, sem_post returned");
145                 return -1;
146         }
147
148         #if DEBUG
149         printf("Door_DoDispense: User %i opened door\n", User);
150         #endif
151
152         return 0;
153 }

UCC git Repository :: git.ucc.asn.au