Gitlab CI - Debugging
[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
12 #include "common.h"
13 #include <stdio.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <signal.h>
19 #include <unistd.h>
20 #include <pty.h>
21 #include <pthread.h>
22 #include <semaphore.h>
23 #include <errno.h>
24 #include <stdbool.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 bool    gbDoor_LockThreadStarted;
47
48 // === CODE ===
49 void* Door_Lock(void* Unused __attribute__((unused)))
50 {
51         gbDoor_LockThreadStarted = true;
52         while(1)
53         {
54                 sem_wait(&gDoor_UnlockSemaphore);
55
56                 int door_serial_handle = InitSerial(gsDoor_SerialPort, 9600);
57                 if(door_serial_handle < 0)
58                 {
59                         fprintf(stderr, "Unable to open door serial '%s'\n", gsDoor_SerialPort);
60                         perror("Opening door port");
61                 }
62
63                 // Disable local echo
64                 {
65                         struct termios  info;
66                         tcgetattr(door_serial_handle, &info);
67                         info.c_cflag &= ~CLOCAL;
68                         tcsetattr(door_serial_handle, TCSANOW, &info);
69                 }
70
71                 if(write(door_serial_handle, "\xff\x01\x01", 3) != 3)   // Relay ON
72                 {
73                         fprintf(stderr, "Failed to write Relay ON (unlock) command, errstr: %s", strerror(errno));
74                 }
75
76                 sleep(DOOR_UNLOCKED_DELAY);
77
78                 if(write(door_serial_handle, "\xff\x01\x00", 3) != 3)   // Relay OFF
79                 {
80                         fprintf(stderr, "Failed to write Relay OFF (lock) command, errstr: %s", strerror(errno));
81                 }
82
83                 close(door_serial_handle);
84         }
85 }
86
87 int Door_InitHandler(void)
88 {
89         // Thread started later
90
91         return 0;
92 }
93
94 /**
95  */
96 int Door_CanDispense(int User, int Item)
97 {
98         #if DEBUG
99         printf("Door_CanDispense: (User=%i,Item=%i)\n", User, Item);
100         #endif
101         // Sanity please
102         if( Item != 0 ) return -1;
103         
104         if( !(Bank_GetFlags(User) & (USER_FLAG_DOORGROUP|USER_FLAG_ADMIN)) )
105         {
106                 #if DEBUG
107                 printf("Door_CanDispense: User %i not in door\n", User);
108                 #endif
109                 return 1;
110         }
111         
112         #if DEBUG
113         printf("Door_CanDispense: User %i can open the door\n", User);
114         #endif
115         
116         return 0;
117 }
118
119 /**
120  * \brief Actually do a dispense from the coke machine
121  */
122 int Door_DoDispense(int User, int Item)
123 {       
124         #if DEBUG
125         printf("Door_DoDispense: (User=%i,Item=%i)\n", User, Item);
126         #endif
127
128         // Sanity please
129         if( Item != 0 ) return -1;
130         
131         // Check if user is in door
132         if( !(Bank_GetFlags(User) & (USER_FLAG_DOORGROUP|USER_FLAG_ADMIN)) )
133         {
134                 #if DEBUG
135                 printf("Door_CanDispense: User %i not in door\n", User);
136                 #endif
137                 return 1;
138         }
139         
140         // Door thread spun up here because program is forked after thread created
141         if( !gbDoor_LockThreadStarted )
142         {
143                 // Initialize semaphore, triggers door lock release if semaphore is greater than 0
144                 sem_init(&gDoor_UnlockSemaphore, 0, 0); 
145
146                 pthread_create(&gDoor_LockThread, NULL, &Door_Lock, NULL);
147         }
148
149         if(sem_post(&gDoor_UnlockSemaphore))
150         {
151                 perror("Failed to post \"Unlock Door\" semaphore, sem_post returned");
152                 return -1;
153         }
154
155         #if DEBUG
156         printf("Door_DoDispense: User %i opened door\n", User);
157         #endif
158
159         return 0;
160 }

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