Checkpoint 3
This commit is contained in:
150
godoor.go
150
godoor.go
@@ -2,11 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/joho/godotenv"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@@ -31,17 +33,14 @@ type cardList struct {
|
||||
} `json:"allowed_uids"`
|
||||
}
|
||||
|
||||
type simpleUids struct {
|
||||
tokens []string
|
||||
}
|
||||
|
||||
type ValidUids map[string]bool // bool has no meaning
|
||||
|
||||
type Config struct {
|
||||
door string
|
||||
uid_salt string
|
||||
mock string
|
||||
api struct {
|
||||
door string
|
||||
uidSalt string
|
||||
doorOpenTime string
|
||||
mock bool
|
||||
api struct {
|
||||
allowed string
|
||||
longpoll string
|
||||
swipe string
|
||||
@@ -66,26 +65,29 @@ func main() {
|
||||
config.api.longpoll = os.Getenv("KDOORPI_API_LONGPOLL")
|
||||
config.api.swipe = os.Getenv("KDOORPI_API_SWIPE")
|
||||
config.api.key = os.Getenv("KDOORPI_API_KEY")
|
||||
config.uid_salt = os.Getenv("KDOORPI_UID_SALT")
|
||||
config.mock = os.Getenv("KDOORPI_MOCK_HW")
|
||||
config.uidSalt = os.Getenv("KDOORPI_UID_SALT")
|
||||
config.doorOpenTime = os.Getenv("KDOORPI_OPEN_TIME")
|
||||
_, config.mock = os.LookupEnv("KDOORPI_MOCK_HW")
|
||||
|
||||
if config.mock == "true" {
|
||||
go func() {
|
||||
setup()
|
||||
}()
|
||||
|
||||
<-ctx.Done()
|
||||
log.Printf("Cleanup\n")
|
||||
|
||||
// cleanup
|
||||
}
|
||||
func setup() {
|
||||
log.Println("Started Setup")
|
||||
|
||||
if config.mock {
|
||||
log.Println("MOCK mode enabled")
|
||||
wiegand = &WiegandMock{}
|
||||
} else {
|
||||
wiegand = WiegandSetup(wiegand_a, wiegand_b, wiegand_bit_timeout, solenoid)
|
||||
}
|
||||
|
||||
http.DefaultClient.Timeout = 120 * time.Second
|
||||
|
||||
for {
|
||||
err := reloadTokens()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
go cardRunner(wiegand)
|
||||
log.Println("HW Setup done")
|
||||
|
||||
go func() {
|
||||
for {
|
||||
@@ -93,12 +95,44 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Printf("Sleeping\n")
|
||||
log.Println("Initialized longpoll event loop")
|
||||
|
||||
<-ctx.Done()
|
||||
fmt.Printf("Cleanup\n")
|
||||
http.DefaultClient.Timeout = 120 * time.Second
|
||||
|
||||
// cleanup
|
||||
for {
|
||||
log.Println("Start initial token population")
|
||||
err := reloadTokens()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
log.Printf("Initial token population failed. err: %v", err)
|
||||
log.Println("Retrying in 10 seconds...")
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
log.Println("Initial token population success")
|
||||
|
||||
go cardRunner(wiegand)
|
||||
|
||||
log.Println("Setup completed")
|
||||
}
|
||||
|
||||
func OpenAndCloseDoor(w Wiegand) error {
|
||||
err := w.OpenDoor()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Door is now open")
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
err = w.CloseDoor()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Door is now closed")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cardRunner(w Wiegand) {
|
||||
@@ -110,16 +144,26 @@ func cardRunner(w Wiegand) {
|
||||
|
||||
printCardId(card)
|
||||
hashedHex := hashCardUid(card)
|
||||
fmt.Println(hashedHex)
|
||||
log.Println(hashedHex)
|
||||
|
||||
go func() {
|
||||
err := sendSwipeEvent(hashedHex)
|
||||
if err != nil {
|
||||
log.Println("Failed to send swipe event: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
globalLock.Lock()
|
||||
ok := validUids[hashedHex]
|
||||
globalLock.Unlock()
|
||||
if ok {
|
||||
fmt.Println("Opening door")
|
||||
w.OpenDoor()
|
||||
log.Println("Opening door")
|
||||
err := OpenAndCloseDoor(w)
|
||||
if err != nil {
|
||||
log.Println("There was an error opening and closing the Door")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Unknown card")
|
||||
log.Println("Unknown card")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -159,7 +203,7 @@ func waitEvents() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%v\n", resp)
|
||||
log.Printf("%v\n", resp)
|
||||
|
||||
reader := bufio.NewReader(resp.Body)
|
||||
for {
|
||||
@@ -173,9 +217,12 @@ func waitEvents() error {
|
||||
if !found_data {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("got server data: %q\n", data)
|
||||
log.Printf("got server data: %q\n", data)
|
||||
if strings.TrimSpace(data) == config.door {
|
||||
wiegand.OpenDoor()
|
||||
err := OpenAndCloseDoor(wiegand)
|
||||
if err != nil {
|
||||
log.Println("There was an error opening and closing the Door")
|
||||
}
|
||||
}
|
||||
|
||||
go reloadTokens()
|
||||
@@ -183,7 +230,7 @@ func waitEvents() error {
|
||||
|
||||
}
|
||||
|
||||
fmt.Printf("%v\n", resp)
|
||||
log.Printf("%v\n", resp)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -197,7 +244,7 @@ func reloadTokens() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%v\n", resp)
|
||||
log.Printf("%v\n", resp)
|
||||
|
||||
var cl cardList
|
||||
|
||||
@@ -215,9 +262,38 @@ func reloadTokens() error {
|
||||
defer globalLock.Unlock()
|
||||
validUids = make(ValidUids)
|
||||
for i, val := range cl.AllowedUids {
|
||||
fmt.Printf("%d: %+v\n", i, val.Token.UidHash)
|
||||
log.Printf("%d: %+v\n", i, val.Token.UidHash)
|
||||
validUids[val.Token.UidHash] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sendSwipeEvent(cardUidHash string) error {
|
||||
swipeEvent := map[string]string{
|
||||
"uid_hash": cardUidHash,
|
||||
"door": config.door,
|
||||
"timestamp": time.Now().Format(time.DateTime),
|
||||
}
|
||||
|
||||
data, err := json.Marshal(swipeEvent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, config.api.swipe, bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Add("KEY", config.api.key)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
|
||||
return fmt.Errorf("Server responded with %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user