// GetForAppEUI returns the last Announcement that contains metadata for the given AppEUI func (s *RedisAnnouncementStore) GetForAppEUI(appEUI types.AppEUI) (*Announcement, error) { key, err := s.byAppEUI.Get(appEUI.String()) if err != nil { return nil, err } service := strings.Split(key, ":") return s.Get(service[0], service[1]) }
// SetApp stores the app ID and app EUI preferences func SetApp(ctx log.Interface, appID string, appEUI types.AppEUI) { config := readData(appFilename) config[idKey] = appID config[euiKey] = appEUI.String() err := writeData(appFilename, config) if err != nil { ctx.WithError(err).Fatal("Could not save app preference") } }
// AppEUIs that are handled by this component func (a *Announcement) AppEUIs() (euis []types.AppEUI) { for _, meta := range a.Metadata { if euiBytes := meta.GetAppEui(); euiBytes != nil { eui := new(types.AppEUI) if err := eui.Unmarshal(euiBytes); err != nil { continue } euis = append(euis, *eui) } } return }
func doTestHandleActivation(h *handler, appEUI types.AppEUI, devEUI types.DevEUI, devNonce [2]byte, appKey types.AppKey) (*pb.DeviceActivationResponse, error) { devAddr := types.DevAddr{1, 2, 3, 4} requestPHY := lorawan.PHYPayload{ MHDR: lorawan.MHDR{ MType: lorawan.JoinRequest, Major: lorawan.LoRaWANR1, }, MACPayload: &lorawan.JoinRequestPayload{ AppEUI: lorawan.EUI64(appEUI), DevEUI: lorawan.EUI64(devEUI), DevNonce: devNonce, }, } requestPHY.SetMIC(lorawan.AES128Key(appKey)) requestBytes, _ := requestPHY.MarshalBinary() responsePHY := lorawan.PHYPayload{ MHDR: lorawan.MHDR{ MType: lorawan.JoinAccept, Major: lorawan.LoRaWANR1, }, MACPayload: &lorawan.JoinAcceptPayload{}, } templateBytes, _ := responsePHY.MarshalBinary() return h.HandleActivation(&pb_broker.DeduplicatedDeviceActivationRequest{ Payload: requestBytes, AppEui: &appEUI, AppId: appEUI.String(), DevEui: &devEUI, DevId: devEUI.String(), ActivationMetadata: &pb_protocol.ActivationMetadata{Protocol: &pb_protocol.ActivationMetadata_Lorawan{ Lorawan: &pb_lorawan.ActivationMetadata{ DevAddr: &devAddr, }, }}, ResponseTemplate: &pb_broker.DeviceActivationResponse{ Payload: templateBytes, }, }) }
// SetApp stores the app EUI preference func SetAppEUI(ctx log.Interface, appEUI types.AppEUI) { err := setData(appFilename, euiKey, appEUI.String()) if err != nil { ctx.WithError(err).Fatal("Could not save app EUI") } }
func TestHandleActivation(t *testing.T) { a := New(t) h := &handler{ Component: &component.Component{Ctx: GetLogger(t, "TestHandleActivation")}, applications: application.NewRedisApplicationStore(GetRedisClient(), "handler-test-activation"), devices: device.NewRedisDeviceStore(GetRedisClient(), "handler-test-activation"), } h.InitStatus() h.mqttEvent = make(chan *types.DeviceEvent, 10) var wg WaitGroup appEUI := types.AppEUI{1, 2, 3, 4, 5, 6, 7, 8} appID := appEUI.String() devEUI := types.DevEUI{1, 2, 3, 4, 5, 6, 7, 8} devID := devEUI.String() unknownDevEUI := types.DevEUI{8, 7, 6, 5, 4, 3, 2, 1} appKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} h.applications.Set(&application.Application{ AppID: appID, }) defer func() { h.applications.Delete(appID) }() h.devices.Set(&device.Device{ AppID: appID, DevID: devID, AppEUI: appEUI, DevEUI: devEUI, AppKey: appKey, }) defer func() { h.devices.Delete(appID, devID) }() // Unknown res, err := doTestHandleActivation(h, appEUI, unknownDevEUI, [2]byte{1, 2}, appKey, ) a.So(err, ShouldNotBeNil) a.So(res, ShouldBeNil) // Wrong AppKey res, err = doTestHandleActivation(h, appEUI, devEUI, [2]byte{1, 2}, [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, ) a.So(err, ShouldNotBeNil) a.So(res, ShouldBeNil) wg.Add(1) go func() { <-h.mqttEvent wg.Done() }() // Known res, err = doTestHandleActivation(h, appEUI, devEUI, [2]byte{1, 2}, appKey, ) a.So(err, ShouldBeNil) a.So(res, ShouldNotBeNil) wg.WaitFor(50 * time.Millisecond) // Same DevNonce used twice res, err = doTestHandleActivation(h, appEUI, devEUI, [2]byte{1, 2}, appKey, ) a.So(err, ShouldNotBeNil) a.So(res, ShouldBeNil) wg.Add(1) go func() { <-h.mqttEvent wg.Done() }() // Other DevNonce res, err = doTestHandleActivation(h, appEUI, devEUI, [2]byte{2, 1}, appKey, ) a.So(err, ShouldBeNil) a.So(res, ShouldNotBeNil) wg.WaitFor(50 * time.Millisecond) // TODO: Validate response // TODO: Check DB }