Skip to content

Commit

Permalink
Merge pull request #51 from kajiLabTeam/feature-privacy-beacon
Browse files Browse the repository at this point in the history
feat: 滞在ウォッチビーコンに対応
  • Loading branch information
togawa427 authored Nov 26, 2024
2 parents c2f32d1 + 7d0c382 commit 7fabe60
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 107 deletions.
125 changes: 95 additions & 30 deletions go/app/controller/beacon.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"encoding/hex"
"fmt"
"net/http"
"strconv"
Expand All @@ -10,9 +11,15 @@ import (
"Stay_watch/service"
"Stay_watch/util"

"github.com/dchest/siphash"
"github.com/gin-gonic/gin"
)

const (
BEACON_ID_STAYWATCHBEACON = 4
LENGTH_PRIVATE_KEY = 32
)

func getEndUUIDByManufacturer(manufacturer string) string {
slicedManufacturers := []int{}

Expand All @@ -39,29 +46,97 @@ func getEndUUIDByManufacturer(manufacturer string) string {
return resultManufacturer
}

func convertBeacons(inputBeacons []*model.BeaconSignal) []model.BeaconSignal {
func getUserIdBySipHash(randomValue string, hashValue string) (int64, error) {
UserService := service.UserService{}
users, err := UserService.GetUsersByBeaconId(BEACON_ID_STAYWATCHBEACON)
if err != nil {
fmt.Println("failed to get users by db: ", err)
return 0, err
}

for _, user := range users {
if len(user.PrivateKey) == LENGTH_PRIVATE_KEY {
// 例:01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00
// privateKey := "0102030405060708090a0b0c0d0e0f00"
privateKey := user.PrivateKey

//BeaconService := service.BeaconService{}
// 文字列をバイトスライスに変換
bytes, err := hex.DecodeString(privateKey)
if err != nil {
fmt.Println("failed to decode hex string: ", err)
return 0, err
}

outBeacons := []model.BeaconSignal{}
for _, inputBeacon := range inputBeacons {
// バイトスライスをuint64に変換(8バイトずつ分割して変換)
var key1 uint64
var key2 uint64
for i := 0; i < 8; i++ {
key1 |= uint64(bytes[i]) << (8 * i)
key2 |= uint64(bytes[8+i]) << (8 * i)
}

uuid := inputBeacon.Uuid
// ハッシュ化したいデータ
msg := []byte(randomValue) // ランダム値

// SipHashを計算
hash := siphash.Hash(key1, key2, msg) // ここで第1, 第2引数にカスタム値を指定可能

// 結果を出力
// 結果が一緒になればそのユーザの秘密キーがビーコン固有の秘密キー
if(hashValue == strconv.FormatUint(hash, 16)){
return int64(user.ID), nil
}
}
}

// 見つからなかった場合エラーを返す
return 0, err
}

func convertBeaconsStayers(inputBeacons []*model.BeaconSignal) []model.Stayer {
UserService := service.UserService{}

outStayers := []model.Stayer{}
for _, inputBeacon := range inputBeacons {

userId := int64(0)
// iPhoneビーコンの場合UUIDを取得する処理が必要(例:"4c000180000021000021000021000021000021" -> "8ebc21144abd00000000ff0100000021")
if len(inputBeacon.Uuid) == 38 {
tmpUUID := getEndUUIDByManufacturer(inputBeacon.Uuid)
uuid = "8ebc21144abd00000000ff01000" + tmpUUID
uuid := "8ebc21144abd00000000ff01000" + tmpUUID
tmpUserId, err := UserService.GetUserIDByUUID(uuid)
if err != nil {
fmt.Println("Cannot get userid by uuid:", err)
continue
}
userId = tmpUserId
} else {
tmpUserId, err := UserService.GetUserIDByUUID(inputBeacon.Uuid)
userId = tmpUserId
if err != nil {
// もし見つからなかった場合基本的に滞在ウォッチビーコンである
randomValue := inputBeacon.Uuid[:16]
hashValue := inputBeacon.Uuid[16:]
tmpUserId, err := getUserIdBySipHash(randomValue, hashValue)
if err != nil {
fmt.Println("Error:", err)
continue
}
userId = tmpUserId
}
}

tmpBeacon := model.BeaconSignal{
Uuid: uuid,
Rssi: inputBeacon.Rssi,

// 0でない(ユーザが見つかった場合)のみ追加
if userId != 0 {
tmpStayer := model.Stayer {
UserID: userId,
Rssi: inputBeacon.Rssi,
}
outStayers = append(outStayers, tmpStayer)
}
outBeacons = append(outBeacons, tmpBeacon)
}

return outBeacons
return outStayers
}

// ビーコン情報を受け取る
Expand All @@ -75,7 +150,8 @@ func Beacon(c *gin.Context) {
return
}

requestBeacons := convertBeacons(beaconRoom.Beacons)
// requestBeacons := convertBeacons(beaconRoom.Beacons)
requestStayers := convertBeaconsStayers(beaconRoom.Beacons)
requestRoomId := beaconRoom.RoomID

RoomService := service.RoomService{}
Expand All @@ -98,14 +174,9 @@ func Beacon(c *gin.Context) {
targetUserRssi := -200

// リクエストからの滞在者リスト(beaconRoom.Beacons)とStayerテーブルの滞在者リストを比較
for _, currentStayer := range requestBeacons {
pastUUID, err := UserService.GetUserUUIDByUserID(pastStayer.UserID)
if err != nil {
fmt.Printf("Cannnot get user uuid %v", err)
continue
}
// 1つ前のstayerテーブルにもいた場合
if pastUUID == currentStayer.Uuid {
for _, currentStayer := range requestStayers {
// 現在いる部屋に以前からいた場合
if pastStayer.UserID == currentStayer.UserID {
targetUserRssi = int(currentStayer.Rssi)
isExist = true
}
Expand Down Expand Up @@ -179,7 +250,7 @@ func Beacon(c *gin.Context) {
// }
// }

// 以前いた部屋のデータに存在しない場合 {Beacons:[] ,RoomID:1}
// 以前いた部屋のデータに現在はいない場合退室処理
if !isExist && pastStayer.RoomID == requestRoomId {
fmt.Println("以前いた部屋のデータに存在しない場合")

Expand Down Expand Up @@ -217,15 +288,9 @@ func Beacon(c *gin.Context) {

}

for _, currentStayer := range requestBeacons {

// APIのリクエストのUUIDからuserIdを取得する
currentUserID, err := UserService.GetUserIDByUUID(currentStayer.Uuid)
if err != nil {
fmt.Println("failed: Cannnot get user id(UUID : " + currentStayer.Uuid + ")")
continue
}
for _, currentStayer := range requestStayers {

currentUserID := currentStayer.UserID
currentTime := time.Now()
// もし火曜日だったら
if currentTime.Weekday() == time.Tuesday {
Expand Down
Loading

0 comments on commit 7fabe60

Please sign in to comment.