Skip to content

Commit

Permalink
qrg: Update parse gateway qr response
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad Vitan committed Sep 10, 2024
1 parent dcd2455 commit d780ef2
Show file tree
Hide file tree
Showing 15 changed files with 309 additions and 276 deletions.
11 changes: 9 additions & 2 deletions api/ttn/lorawan/v3/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10563,8 +10563,15 @@ The Pba service allows clients to manage peering through Packet Broker.

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `format_id` | [`string`](#string) | | Identifier of the format used to successfully parse the QR code data. |
| `claim_gateway_request` | [`ClaimGatewayRequest`](#ttn.lorawan.v3.ClaimGatewayRequest) | | |
| `format_id` | [`string`](#string) | | Identifier of the format used to parse the QR code data. |
| `gateway_eui` | [`bytes`](#bytes) | | |
| `owner_token` | [`string`](#string) | | |

#### Field Rules

| Field | Validations |
| ----- | ----------- |
| `gateway_eui` | <p>`bytes.len`: `8`</p> |

### <a name="ttn.lorawan.v3.QRCodeFormat">Message `QRCodeFormat`</a>

Expand Down
11 changes: 8 additions & 3 deletions api/ttn/lorawan/v3/api.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -28058,10 +28058,15 @@
"properties": {
"format_id": {
"type": "string",
"description": "Identifier of the format used to successfully parse the QR code data."
"description": "Identifier of the format used to parse the QR code data."
},
"claim_gateway_request": {
"$ref": "#/definitions/v3ClaimGatewayRequest"
"gateway_eui": {
"type": "string",
"format": "string",
"example": "70B3D57ED000ABCD"
},
"owner_token": {
"type": "string"
}
}
},
Expand Down
21 changes: 18 additions & 3 deletions api/ttn/lorawan/v3/qrcodegenerator.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "ttn/lorawan/v3/deviceclaimingserver.proto";
import "thethings/json/annotations.proto";
import "ttn/lorawan/v3/end_device.proto";
import "ttn/lorawan/v3/picture.proto";
import "validate/validate.proto";
Expand Down Expand Up @@ -147,9 +147,24 @@ message ParseGatewayQRCodeRequest {
}

message ParseGatewayQRCodeResponse {
// Identifier of the format used to successfully parse the QR code data.
// Identifier of the format used to parse the QR code data.
string format_id = 1;
ClaimGatewayRequest claim_gateway_request = 2;
bytes gateway_eui = 2 [
(validate.rules).bytes = {
len: 8,
ignore_empty: true
},
(thethings.json.field) = {
marshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.MarshalHEXBytes",
unmarshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.Unmarshal8Bytes"
},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
type: STRING,
format: "string",
example: "\"70B3D57ED000ABCD\""
}
];
string owner_token = 3;
}

// The GatewayQRCodeGenerator service provides functionality to generate and parse QR codes for gateways.
Expand Down
12 changes: 3 additions & 9 deletions pkg/qrcodegenerator/grpc_gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,8 @@ func (s *gatewayQRCodeGeneratorServer) Parse(
}

return &ttnpb.ParseGatewayQRCodeResponse{
FormatId: data.FormatID(),
ClaimGatewayRequest: &ttnpb.ClaimGatewayRequest{
SourceGateway: &ttnpb.ClaimGatewayRequest_AuthenticatedIdentifiers_{
AuthenticatedIdentifiers: &ttnpb.ClaimGatewayRequest_AuthenticatedIdentifiers{
GatewayEui: data.GatewayEUI().Bytes(),
AuthenticationCode: []byte(data.OwnerToken()),
},
},
},
FormatId: data.FormatID(),
GatewayEui: data.GatewayEUI().Bytes(),
OwnerToken: data.OwnerToken(),
}, nil
}
2 changes: 2 additions & 0 deletions pkg/qrcodegenerator/grpc_gateways_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ func TestGatewayQRCodeParsing(t *testing.T) {
return false
}
a.So(resp.FormatId, should.Equal, ttigpro1.ID())
a.So(resp.GatewayEui, should.Resemble, []uint8{0xec, 0x65, 0x6e, 0xff, 0xfe, 0x00, 0x01, 0x28})
a.So(resp.OwnerToken, should.Equal, "abcdef123456")

return true
},
Expand Down
5 changes: 2 additions & 3 deletions pkg/qrcodegenerator/qrcode/gateways/gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package gateways

import (
"context"
"encoding"

"go.thethings.network/lorawan-stack/v3/pkg/errors"
Expand Down Expand Up @@ -56,13 +55,13 @@ type Server struct {
}

// New returns a new Server.
func New(_ context.Context) *Server {
func New() *Server {
s := &Server{
// Newer formats should be added to this slice first to
// preferentially match with those first.
gatewayFormats: []gatewayFormat{
{
id: formatIDTTIGPRO1,
id: ttigpro1FormatID,
format: new(TTIGPRO1Format),
},
},
Expand Down
3 changes: 1 addition & 2 deletions pkg/qrcodegenerator/qrcode/gateways/gateways_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package gateways_test

import (
"context"
"strconv"
"testing"

Expand Down Expand Up @@ -48,7 +47,7 @@ func TestParseGatewaysAuthenticationCodes(t *testing.T) {
t.Parallel()
a := assertions.New(t)

qrCode := gateways.New(context.Background())
qrCode := gateways.New()

d, err := qrCode.Parse(tc.FormatID, tc.Data)
data := test.Must(d, err)
Expand Down
19 changes: 8 additions & 11 deletions pkg/qrcodegenerator/qrcode/gateways/ttigpro1.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,19 @@ import (
)

const (
formatIDTTIGPRO1 = "ttigpro1"

euiLength = 16
ownerTokenLength = 12
ttigpro1FormatID = "ttigpro1"
)

// ttigpro1Regex is the regular expression to match the TTIGPRO1 format.
// The format is as follows: https://ttig.pro/c/{16 lowercase base16 chars}/{12 base62 chars}.
var ttigpro1Regex = regexp.MustCompile(`^https://ttig\.pro/c/([a-f0-9]{16})/([a-z0-9]{12})$`)

// TTIGPRO1 is a format for gateway identification QR codes.
type ttigpro1 struct {
gatewayEUI types.EUI64
ownerToken string
}

// ttigpro1Regex is the regular expression to match the TTIGPRO1 format.
// The format is as follows: https://ttig.pro/c/{16 lowercase base16 chars}/{12 base62 chars}.
var ttigpro1Regex = regexp.MustCompile(`^https://ttig\.pro/c/([a-f0-9]{16})/([a-z0-9]{12})$`)

// UnmarshalText implements the TextUnmarshaler interface.
func (m *ttigpro1) UnmarshalText(text []byte) error {
// Match the URL against the pattern
Expand All @@ -52,7 +49,7 @@ func (m *ttigpro1) UnmarshalText(text []byte) error {

m.ownerToken = matches[2]

if len(m.ownerToken) != ownerTokenLength {
if len(m.ownerToken) != 12 /* owner token length */ {
return errInvalidLength
}

Expand All @@ -61,7 +58,7 @@ func (m *ttigpro1) UnmarshalText(text []byte) error {

// FormatID implements the Data interface.
func (*ttigpro1) FormatID() string {
return formatIDTTIGPRO1
return ttigpro1FormatID
}

func (m *ttigpro1) GatewayEUI() types.EUI64 {
Expand Down Expand Up @@ -89,7 +86,7 @@ func (TTIGPRO1Format) Format() *ttnpb.QRCodeFormat {

// ID is the identifier of the format as a string.
func (TTIGPRO1Format) ID() string {
return formatIDTTIGPRO1
return ttigpro1FormatID
}

// New implements the Format interface.
Expand Down
2 changes: 1 addition & 1 deletion pkg/qrcodegenerator/qrcodegenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func New(c *component.Component, _ *Config, opts ...Option) (*QRCodeGenerator, e
qrg.grpc.gatewayQRCodeGenerator = &gatewayQRCodeGeneratorServer{QRG: qrg}

qrg.endDevices = enddevices.New(ctx)
qrg.gateways = gateways.New(ctx)
qrg.gateways = gateways.New()

c.RegisterGRPC(qrg)

Expand Down
Loading

0 comments on commit d780ef2

Please sign in to comment.