Checkpoint 5
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
| .idea | .idea | ||||||
| godoor | godoor | ||||||
| godoor_server/godoor_server | godoor_server/godoor_server | ||||||
|  | godoor_server/keys.json | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | dev: | ||||||
|  | 	GOOS=linux GOARCH=arm64 go build . | ||||||
|  | 	scp godoor workshopdoor:/tmp/ | ||||||
|  | 	ssh workshopdoor 'mv -f /tmp/godoor ~/ && sudo systemctl restart godoor' | ||||||
							
								
								
									
										3
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								build.sh
									
									
									
									
									
								
							| @@ -1,3 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| GOOS=linux GOARCH=arm64 go build && scp godoor rpi4b: |  | ||||||
							
								
								
									
										83
									
								
								godoor.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								godoor.go
									
									
									
									
									
								
							| @@ -6,7 +6,6 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/joho/godotenv" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"log" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| @@ -15,8 +14,12 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"syscall" | 	"syscall" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"godoor/hash" | ||||||
|  |  | ||||||
|  | 	"github.com/joho/godotenv" | ||||||
| ) | ) | ||||||
| import "time" |  | ||||||
|  |  | ||||||
| const wiegand_a = 17 | const wiegand_a = 17 | ||||||
| const wiegand_b = 18 | const wiegand_b = 18 | ||||||
| @@ -54,12 +57,20 @@ type KeepDoorOpen struct { | |||||||
| 	timer *time.Timer | 	timer *time.Timer | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type OpenedTimestamp struct { | ||||||
|  | 	Opened time.Time | ||||||
|  | 	Closed *time.Time | ||||||
|  | } | ||||||
|  |  | ||||||
| var config Config | var config Config | ||||||
| var globalLock sync.Mutex | var globalLock sync.Mutex | ||||||
| var validUids ValidUids | var validUids ValidUids | ||||||
| var wiegand Wiegand | var wiegand Wiegand | ||||||
| var keepDoorOpen KeepDoorOpen | var keepDoorOpen KeepDoorOpen | ||||||
|  |  | ||||||
|  | var lastSyncedTimestamp *time.Time | ||||||
|  | var openDoorTimestamps []OpenedTimestamp | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
|  |  | ||||||
| 	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) | 	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) | ||||||
| @@ -85,6 +96,7 @@ func main() { | |||||||
|  |  | ||||||
| 	// cleanup | 	// cleanup | ||||||
| } | } | ||||||
|  |  | ||||||
| func setup() { | func setup() { | ||||||
| 	log.Println("Started Setup") | 	log.Println("Started Setup") | ||||||
|  |  | ||||||
| @@ -99,6 +111,8 @@ func setup() { | |||||||
| 	} | 	} | ||||||
| 	log.Println("HW Setup done") | 	log.Println("HW Setup done") | ||||||
|  |  | ||||||
|  | 	http.DefaultClient.Timeout = 120 * time.Second | ||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		for { | 		for { | ||||||
| 			waitEvents() | 			waitEvents() | ||||||
| @@ -107,8 +121,6 @@ func setup() { | |||||||
|  |  | ||||||
| 	log.Println("Initialized longpoll event loop") | 	log.Println("Initialized longpoll event loop") | ||||||
|  |  | ||||||
| 	http.DefaultClient.Timeout = 120 * time.Second |  | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		log.Println("Start initial token population") | 		log.Println("Start initial token population") | ||||||
| 		err := reloadTokens() | 		err := reloadTokens() | ||||||
| @@ -120,6 +132,8 @@ func setup() { | |||||||
| 		time.Sleep(10 * time.Second) | 		time.Sleep(10 * time.Second) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	go runHttpServer() | ||||||
|  |  | ||||||
| 	log.Println("Initial token population success") | 	log.Println("Initial token population success") | ||||||
|  |  | ||||||
| 	go cardRunner(wiegand) | 	go cardRunner(wiegand) | ||||||
| @@ -127,13 +141,36 @@ func setup() { | |||||||
| 	log.Println("Setup completed") | 	log.Println("Setup completed") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func runHttpServer() { | ||||||
|  | 	http.HandleFunc("/lastsync", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		e := json.NewEncoder(w) | ||||||
|  | 		e.Encode(map[string]any{ | ||||||
|  | 			"last_synced": lastSyncedTimestamp, | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 	http.HandleFunc("/opened", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		e := json.NewEncoder(w) | ||||||
|  | 		e.Encode(map[string]any{ | ||||||
|  | 			"open_timestamps": openDoorTimestamps, | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 	http.HandleFunc("/isopen", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		e := json.NewEncoder(w) | ||||||
|  | 		open, _ := wiegand.IsDoorOpen() | ||||||
|  | 		e.Encode(map[string]any{ | ||||||
|  | 			"open": open, | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 	http.ListenAndServe(":3334", nil) | ||||||
|  | } | ||||||
|  |  | ||||||
| func OpenAndCloseDoor(w Wiegand) error { | func OpenAndCloseDoor(w Wiegand) error { | ||||||
| 	err := w.OpenDoor() | 	err := OpenDoor(w) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if keepDoorOpen.until.After(time.Now().Add(5 * time.Second)) { | 	if keepDoorOpen.until.After(time.Now()) { | ||||||
| 		fmt.Println("Door is already open") | 		fmt.Println("Door is already open") | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -142,7 +179,7 @@ func OpenAndCloseDoor(w Wiegand) error { | |||||||
|  |  | ||||||
| 	time.Sleep(5 * time.Second) | 	time.Sleep(5 * time.Second) | ||||||
|  |  | ||||||
| 	err = w.CloseDoor() | 	err = CloseDoor(w) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -151,6 +188,27 @@ func OpenAndCloseDoor(w Wiegand) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func OpenDoor(w Wiegand) error { | ||||||
|  | 	open, _ := w.IsDoorOpen() | ||||||
|  | 	if open { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	w.OpenDoor() | ||||||
|  | 	openDoorTimestamps = append(openDoorTimestamps, OpenedTimestamp{Opened: time.Now(), Closed: nil}) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func CloseDoor(w Wiegand) error { | ||||||
|  | 	open, _ := w.IsDoorOpen() | ||||||
|  | 	if !open { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	w.CloseDoor() | ||||||
|  | 	t := time.Now() | ||||||
|  | 	openDoorTimestamps[len(openDoorTimestamps)-1].Closed = &t | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func cardRunner(w Wiegand) { | func cardRunner(w Wiegand) { | ||||||
| 	for { | 	for { | ||||||
| 		card, err := w.GetCardUid() | 		card, err := w.GetCardUid() | ||||||
| @@ -159,7 +217,7 @@ func cardRunner(w Wiegand) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		printCardId(card) | 		printCardId(card) | ||||||
| 		hashedHex := hashCardUid(card) | 		hashedHex := hash.HashCardUid(card) | ||||||
| 		log.Println(hashedHex) | 		log.Println(hashedHex) | ||||||
|  |  | ||||||
| 		globalLock.Lock() | 		globalLock.Lock() | ||||||
| @@ -287,6 +345,9 @@ func reloadTokens() error { | |||||||
| 		updateKeepOpenDoor(*cl.KeepOpenUntil) | 		updateKeepOpenDoor(*cl.KeepOpenUntil) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	t := time.Now() | ||||||
|  | 	lastSyncedTimestamp = &t | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -300,20 +361,20 @@ func updateKeepOpenDoor(newKeepOpenTime time.Time) { | |||||||
|  |  | ||||||
| 	if newKeepOpenTime.After(time.Now()) { | 	if newKeepOpenTime.After(time.Now()) { | ||||||
| 		log.Printf("Keeping door open until %v", newKeepOpenTime) | 		log.Printf("Keeping door open until %v", newKeepOpenTime) | ||||||
| 		wiegand.OpenDoor() | 		OpenDoor(wiegand) | ||||||
| 		timer := time.AfterFunc(time.Until(newKeepOpenTime), handleKeepDoorOpenCloseCleanup) | 		timer := time.AfterFunc(time.Until(newKeepOpenTime), handleKeepDoorOpenCloseCleanup) | ||||||
| 		keepDoorOpen = KeepDoorOpen{ | 		keepDoorOpen = KeepDoorOpen{ | ||||||
| 			timer: timer, | 			timer: timer, | ||||||
| 			until: newKeepOpenTime, | 			until: newKeepOpenTime, | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		wiegand.CloseDoor() | 		CloseDoor(wiegand) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func handleKeepDoorOpenCloseCleanup() { | func handleKeepDoorOpenCloseCleanup() { | ||||||
| 	fmt.Println("Keep door open time is reached!") | 	fmt.Println("Keep door open time is reached!") | ||||||
| 	wiegand.CloseDoor() | 	CloseDoor(wiegand) | ||||||
| 	keepDoorOpen = KeepDoorOpen{} | 	keepDoorOpen = KeepDoorOpen{} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								godoor_server/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								godoor_server/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | dev: | ||||||
|  | 	GOOS=linux GOARCH=arm64 go build . | ||||||
|  | 	scp godoor_server workshopdoor:/tmp/ | ||||||
|  | 	ssh workshopdoor 'mv -f /tmp/godoor_server ~/' | ||||||
| @@ -1 +0,0 @@ | |||||||
| [{"token":{"uid_hash":"873636abbcf597a4835afc1c9b16a72eb6175b7ab278a8f18ab13c50172c90ea97cc3e258efd9cc1d885d7ea32d87fd006907892793e7cd6c468417bd8b8421a"}},{"token":{"uid_hash":"a08094343b4057777af4935b79df586d7eb999117883a53393e8b46f1ab19577b12039a5d2e0b9d0364bbed5c82d83a507492fea47ace633acf23da2dcf1560e"}},{"token":{"uid_hash":"d78271547cde009726b159dca09e53bee72feebe90b3eb7cb6e394caafc30bdb1f1567efc2f19bbdf3c6922e0bebed910ee4fa4f5b13bd379651da4f620f3559"}},{"token":{"uid_hash":"d72c87d0f077c7766f2985dfab30e8955c373a13a1e93d315203939f542ff86e73ee37c31f4c4b571f4719fa8e3589f12db8dcb57ea9f56764bb7d58f64cf705"}},{"token":{"uid_hash":"873636abbcf597a4835afc1c9b16a72eb6175b7ab278a8f18ab13c50172c90ea97cc3e258efd9cc1d885d7ea32d87fd006907892793e7cd6c468417bd8b8421a"}},{"token":{"uid_hash":"a08094343b4057777af4935b79df586d7eb999117883a53393e8b46f1ab19577b12039a5d2e0b9d0364bbed5c82d83a507492fea47ace633acf23da2dcf1560e"}},{"token":{"uid_hash":"d78271547cde009726b159dca09e53bee72feebe90b3eb7cb6e394caafc30bdb1f1567efc2f19bbdf3c6922e0bebed910ee4fa4f5b13bd379651da4f620f3559"}},{"token":{"uid_hash":"873636abbcf597a4835afc1c9b16a72eb6175b7ab278a8f18ab13c50172c90ea97cc3e258efd9cc1d885d7ea32d87fd006907892793e7cd6c468417bd8b8421a"}},{"token":{"uid_hash":"a08094343b4057777af4935b79df586d7eb999117883a53393e8b46f1ab19577b12039a5d2e0b9d0364bbed5c82d83a507492fea47ace633acf23da2dcf1560e"}},{"token":{"uid_hash":"d78271547cde009726b159dca09e53bee72feebe90b3eb7cb6e394caafc30bdb1f1567efc2f19bbdf3c6922e0bebed910ee4fa4f5b13bd379651da4f620f3559"}}] |  | ||||||
							
								
								
									
										40
									
								
								hash/godoor_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								hash/godoor_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | package hash | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestHash(t *testing.T) { | ||||||
|  | 	hash := HashCardUid(0x000000000F0AD2301) | ||||||
|  | 	if hash != "a6d9ba36ecb5f8e6312f40ee260ad59e9cca3c6ce073bf072df3324c0072886196e6823a7c758ab567fc53e91fbbda297a4efe0072e41316c56446ef126a5180" { | ||||||
|  | 		t.Errorf("WRONG Key generated: %q", hash) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	hash = HashCardUid(0x3CBB5AAD) | ||||||
|  | 	if hash != "1e7bbc1aeeff4bfe58ea8d97df7cd0f97599fa31633d3a1f57d138549b3968c20affb186fe0b85570d34718b273d269bcd28b2be59faf8122451d91a2cdc5f18" { | ||||||
|  | 		t.Errorf("WRONG Key generated: %q", hash) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestBits(t *testing.T) { | ||||||
|  |  | ||||||
|  | 	bits := make([]bool, 64) | ||||||
|  | 	trueBits := []int{0, 1, 2, 3, 8, 10, 12, 13, 15, 18, 22, 23, 31} | ||||||
|  | 	for _, i := range trueBits { | ||||||
|  | 		bits[i] = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var card uint64 = 0 | ||||||
|  | 	for i := 63; i >= 0; i-- { | ||||||
|  | 		if bits[i] == true { | ||||||
|  | 			card |= 1 << (63 - i) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	cardId := fmt.Sprintf("%x", card) | ||||||
|  | 	fmt.Println(cardId) | ||||||
|  | 	if card != 0xF0AD230100000000 { | ||||||
|  | 		panic(fmt.Errorf("WROOONG: %x", card)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								hash/hash.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hash/hash.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | package hash | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/binary" | ||||||
|  | 	"encoding/hex" | ||||||
|  |  | ||||||
|  | 	"golang.org/x/crypto/scrypt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func HashCardUid(card uint64) string { | ||||||
|  | 	b := make([]byte, 8) | ||||||
|  | 	binary.LittleEndian.PutUint64(b, card) | ||||||
|  |  | ||||||
|  | 	hashed, err := scrypt.Key(b, []byte("hkRXwLlQKmCJoy5qaahp"), 16384, 8, 1, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) // can only happen when scrypt params are garbage | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	hashedHex := hex.EncodeToString(hashed) | ||||||
|  | 	return hashedHex | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								wiegand.go
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								wiegand.go
									
									
									
									
									
								
							| @@ -1,15 +1,11 @@ | |||||||
| package main | package main | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/binary" |  | ||||||
| 	"encoding/hex" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"golang.org/x/crypto/scrypt" |  | ||||||
| 	"log" | 	"log" | ||||||
|  | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| ) |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/warthog618/gpiod" | 	"github.com/warthog618/gpiod" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -29,41 +25,45 @@ type WiegandHW struct { | |||||||
| 	bitTimeoutTimer *time.Timer | 	bitTimeoutTimer *time.Timer | ||||||
|  |  | ||||||
| 	solenoidLine *gpiod.Line | 	solenoidLine *gpiod.Line | ||||||
|  | 	lock         sync.RWMutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func (w *WiegandHW) OpenDoor() error { | func (w *WiegandHW) OpenDoor() error { | ||||||
|  | 	w.lock.Lock() | ||||||
|  | 	defer w.lock.Unlock() | ||||||
|  |  | ||||||
|  | 	open, _ := w.isDoorOpen() | ||||||
|  | 	if open { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return w.solenoidLine.SetValue(1) | 	return w.solenoidLine.SetValue(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (w *WiegandHW) CloseDoor() error { | func (w *WiegandHW) CloseDoor() error { | ||||||
|  | 	w.lock.Lock() | ||||||
|  | 	defer w.lock.Unlock() | ||||||
|  |  | ||||||
|  | 	open, _ := w.isDoorOpen() | ||||||
|  | 	if !open { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return w.solenoidLine.SetValue(0) | 	return w.solenoidLine.SetValue(0) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (w *WiegandHW) IsDoorOpen() (bool, error) { | func (w *WiegandHW) IsDoorOpen() (bool, error) { | ||||||
|  | 	w.lock.RLock() | ||||||
|  | 	defer w.lock.RUnlock() | ||||||
|  | 	return w.isDoorOpen() | ||||||
|  | } | ||||||
|  | func (w *WiegandHW) isDoorOpen() (bool, error) { | ||||||
| 	i, err := w.solenoidLine.Value() | 	i, err := w.solenoidLine.Value() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| 	return i == 1, nil | 	return i == 1, nil | ||||||
| } | } | ||||||
| func printCardId(card uint64) { |  | ||||||
| 	for i := 0; i < 7; i++ { |  | ||||||
| 		fmt.Printf("%02x", (card>>(8*i))&0xff) |  | ||||||
| 	} |  | ||||||
| 	fmt.Printf("\n") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func hashCardUid(card uint64) string { |  | ||||||
| 	b := make([]byte, 8) |  | ||||||
| 	binary.LittleEndian.PutUint64(b, card) |  | ||||||
| 	hashed, err := scrypt.Key(b, []byte(config.uidSalt), 16384, 8, 1, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) // can only happen when scrypt params are garbage |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	hashedHex := hex.EncodeToString(hashed) |  | ||||||
| 	return hashedHex |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (w *WiegandHW) GetCardUid() (uint64, error) { | func (w *WiegandHW) GetCardUid() (uint64, error) { | ||||||
| 	// Wait for bit timeout | 	// Wait for bit timeout | ||||||
| @@ -78,7 +78,7 @@ func (w *WiegandHW) GetCardUid() (uint64, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var card uint64 = 0 | 	var card uint64 = 0 | ||||||
| 	for i := 63; i != 0; i-- { | 	for i := 63; i >= 0; i-- { | ||||||
| 		if w.bits[i] == true { | 		if w.bits[i] == true { | ||||||
| 			card |= 1 << (63 - i) | 			card |= 1 << (63 - i) | ||||||
| 		} | 		} | ||||||
| @@ -89,15 +89,15 @@ func (w *WiegandHW) GetCardUid() (uint64, error) { | |||||||
|  |  | ||||||
| func (w *WiegandHW) wiegandAEvent(evt gpiod.LineEvent) { | func (w *WiegandHW) wiegandAEvent(evt gpiod.LineEvent) { | ||||||
| 	w.bitTimeoutTimer.Reset(w.bitTimeout) | 	w.bitTimeoutTimer.Reset(w.bitTimeout) | ||||||
| 	w.bits[w.bitNr] = false | 	w.bits[w.bitNr] = true | ||||||
| 	fmt.Printf("0") | 	fmt.Printf("1") | ||||||
| 	w.bitNr += 1 | 	w.bitNr += 1 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (w *WiegandHW) wiegandBEvent(evt gpiod.LineEvent) { | func (w *WiegandHW) wiegandBEvent(evt gpiod.LineEvent) { | ||||||
| 	w.bitTimeoutTimer.Reset(w.bitTimeout) | 	w.bitTimeoutTimer.Reset(w.bitTimeout) | ||||||
| 	w.bits[w.bitNr] = true | 	w.bits[w.bitNr] = false | ||||||
| 	fmt.Printf("1") | 	fmt.Printf("0") | ||||||
| 	w.bitNr += 1 | 	w.bitNr += 1 | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -139,3 +139,10 @@ func (w *WiegandHW) WiegandClose() { | |||||||
| 	w.bLine.Close() | 	w.bLine.Close() | ||||||
| 	w.solenoidLine.Close() | 	w.solenoidLine.Close() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func printCardId(card uint64) { | ||||||
|  | 	for i := 0; i < 7; i++ { | ||||||
|  | 		fmt.Printf("%02x", (card>>(8*i))&0xff) | ||||||
|  | 	} | ||||||
|  | 	fmt.Printf("\n") | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user