diff --git a/ndn/app/tlv/definitions.go b/ndn/app/tlv/definitions.go index ad125599..9b6ca933 100644 --- a/ndn/app/tlv/definitions.go +++ b/ndn/app/tlv/definitions.go @@ -12,6 +12,12 @@ type Message struct { DSKResponse *DSKResponse `tlv:"0xCC"` //+field:struct:DSKACK DSKACK *DSKACK `tlv:"0xCE"` + //+field:struct:RefreshPing + RefreshPing *RefreshPing `tlv:"0xD0"` + //+field:struct:RefreshAck + RefreshAck *RefreshAck `tlv:"0xD2"` + //+field:struct:RefreshRequest + RefreshRequest *RefreshRequest `tlv:"0xD4"` } type AeadBlock struct { @@ -46,3 +52,36 @@ type DSKACK struct { //+field:binary X25519Peer []byte `tlv:"0x57A"` } + +type RefreshPing struct { + //+field:string + RequestId string `tlv:"0x5A0"` + //+field:string + Requester string `tlv:"0x5A2"` + //+field:string + SentAt string `tlv:"0x5A4"` +} + +type RefreshAck struct { + //+field:string + RequestId string `tlv:"0x5A0"` + //+field:string + Requester string `tlv:"0x5A2"` + //+field:string + Responder string `tlv:"0x5A4"` + //+field:natural + Freshness uint64 `tlv:"0x5A6"` + //+field:string + SentAt string `tlv:"0x5A8"` +} + +type RefreshRequest struct { + //+field:string + RequestId string `tlv:"0x5A0"` + //+field:string + Requester string `tlv:"0x5A2"` + //+field:string + Responder string `tlv:"0x5A4"` + //+field:string + SentAt string `tlv:"0x5A6"` +} diff --git a/ndn/app/tlv/zz_generated.go b/ndn/app/tlv/zz_generated.go index 15711696..898ed509 100644 --- a/ndn/app/tlv/zz_generated.go +++ b/ndn/app/tlv/zz_generated.go @@ -12,19 +12,25 @@ import ( type MessageEncoder struct { Length uint - AeadBlock_encoder AeadBlockEncoder - YjsDelta_encoder YjsDeltaEncoder - DSKRequest_encoder DSKRequestEncoder - DSKResponse_encoder DSKResponseEncoder - DSKACK_encoder DSKACKEncoder + AeadBlock_encoder AeadBlockEncoder + YjsDelta_encoder YjsDeltaEncoder + DSKRequest_encoder DSKRequestEncoder + DSKResponse_encoder DSKResponseEncoder + DSKACK_encoder DSKACKEncoder + RefreshPing_encoder RefreshPingEncoder + RefreshAck_encoder RefreshAckEncoder + RefreshRequest_encoder RefreshRequestEncoder } type MessageParsingContext struct { - AeadBlock_context AeadBlockParsingContext - YjsDelta_context YjsDeltaParsingContext - DSKRequest_context DSKRequestParsingContext - DSKResponse_context DSKResponseParsingContext - DSKACK_context DSKACKParsingContext + AeadBlock_context AeadBlockParsingContext + YjsDelta_context YjsDeltaParsingContext + DSKRequest_context DSKRequestParsingContext + DSKResponse_context DSKResponseParsingContext + DSKACK_context DSKACKParsingContext + RefreshPing_context RefreshPingParsingContext + RefreshAck_context RefreshAckParsingContext + RefreshRequest_context RefreshRequestParsingContext } func (encoder *MessageEncoder) Init(value *Message) { @@ -43,6 +49,15 @@ func (encoder *MessageEncoder) Init(value *Message) { if value.DSKACK != nil { encoder.DSKACK_encoder.Init(value.DSKACK) } + if value.RefreshPing != nil { + encoder.RefreshPing_encoder.Init(value.RefreshPing) + } + if value.RefreshAck != nil { + encoder.RefreshAck_encoder.Init(value.RefreshAck) + } + if value.RefreshRequest != nil { + encoder.RefreshRequest_encoder.Init(value.RefreshRequest) + } l := uint(0) if value.AeadBlock != nil { @@ -70,6 +85,21 @@ func (encoder *MessageEncoder) Init(value *Message) { l += uint(enc.TLNum(encoder.DSKACK_encoder.Length).EncodingLength()) l += encoder.DSKACK_encoder.Length } + if value.RefreshPing != nil { + l += 1 + l += uint(enc.TLNum(encoder.RefreshPing_encoder.Length).EncodingLength()) + l += encoder.RefreshPing_encoder.Length + } + if value.RefreshAck != nil { + l += 1 + l += uint(enc.TLNum(encoder.RefreshAck_encoder.Length).EncodingLength()) + l += encoder.RefreshAck_encoder.Length + } + if value.RefreshRequest != nil { + l += 1 + l += uint(enc.TLNum(encoder.RefreshRequest_encoder.Length).EncodingLength()) + l += encoder.RefreshRequest_encoder.Length + } encoder.Length = l } @@ -80,6 +110,9 @@ func (context *MessageParsingContext) Init() { context.DSKRequest_context.Init() context.DSKResponse_context.Init() context.DSKACK_context.Init() + context.RefreshPing_context.Init() + context.RefreshAck_context.Init() + context.RefreshRequest_context.Init() } func (encoder *MessageEncoder) EncodeInto(value *Message, buf []byte) { @@ -131,6 +164,33 @@ func (encoder *MessageEncoder) EncodeInto(value *Message, buf []byte) { pos += encoder.DSKACK_encoder.Length } } + if value.RefreshPing != nil { + buf[pos] = byte(208) + pos += 1 + pos += uint(enc.TLNum(encoder.RefreshPing_encoder.Length).EncodeInto(buf[pos:])) + if encoder.RefreshPing_encoder.Length > 0 { + encoder.RefreshPing_encoder.EncodeInto(value.RefreshPing, buf[pos:]) + pos += encoder.RefreshPing_encoder.Length + } + } + if value.RefreshAck != nil { + buf[pos] = byte(210) + pos += 1 + pos += uint(enc.TLNum(encoder.RefreshAck_encoder.Length).EncodeInto(buf[pos:])) + if encoder.RefreshAck_encoder.Length > 0 { + encoder.RefreshAck_encoder.EncodeInto(value.RefreshAck, buf[pos:]) + pos += encoder.RefreshAck_encoder.Length + } + } + if value.RefreshRequest != nil { + buf[pos] = byte(212) + pos += 1 + pos += uint(enc.TLNum(encoder.RefreshRequest_encoder.Length).EncodeInto(buf[pos:])) + if encoder.RefreshRequest_encoder.Length > 0 { + encoder.RefreshRequest_encoder.EncodeInto(value.RefreshRequest, buf[pos:]) + pos += encoder.RefreshRequest_encoder.Length + } + } } func (encoder *MessageEncoder) Encode(value *Message) enc.Wire { @@ -150,6 +210,9 @@ func (context *MessageParsingContext) Parse(reader enc.WireView, ignoreCritical var handled_DSKRequest bool = false var handled_DSKResponse bool = false var handled_DSKACK bool = false + var handled_RefreshPing bool = false + var handled_RefreshAck bool = false + var handled_RefreshRequest bool = false progress := -1 _ = progress @@ -206,6 +269,24 @@ func (context *MessageParsingContext) Parse(reader enc.WireView, ignoreCritical handled_DSKACK = true value.DSKACK, err = context.DSKACK_context.Parse(reader.Delegate(int(l)), ignoreCritical) } + case 208: + if true { + handled = true + handled_RefreshPing = true + value.RefreshPing, err = context.RefreshPing_context.Parse(reader.Delegate(int(l)), ignoreCritical) + } + case 210: + if true { + handled = true + handled_RefreshAck = true + value.RefreshAck, err = context.RefreshAck_context.Parse(reader.Delegate(int(l)), ignoreCritical) + } + case 212: + if true { + handled = true + handled_RefreshRequest = true + value.RefreshRequest, err = context.RefreshRequest_context.Parse(reader.Delegate(int(l)), ignoreCritical) + } default: if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { return nil, enc.ErrUnrecognizedField{TypeNum: typ} @@ -239,6 +320,15 @@ func (context *MessageParsingContext) Parse(reader enc.WireView, ignoreCritical if !handled_DSKACK && err == nil { value.DSKACK = nil } + if !handled_RefreshPing && err == nil { + value.RefreshPing = nil + } + if !handled_RefreshAck && err == nil { + value.RefreshAck = nil + } + if !handled_RefreshRequest && err == nil { + value.RefreshRequest = nil + } if err != nil { return nil, err @@ -1004,3 +1094,621 @@ func ParseDSKACK(reader enc.WireView, ignoreCritical bool) (*DSKACK, error) { context.Init() return context.Parse(reader, ignoreCritical) } + +type RefreshPingEncoder struct { + Length uint +} + +type RefreshPingParsingContext struct { +} + +func (encoder *RefreshPingEncoder) Init(value *RefreshPing) { + + l := uint(0) + l += 3 + l += uint(enc.TLNum(len(value.RequestId)).EncodingLength()) + l += uint(len(value.RequestId)) + l += 3 + l += uint(enc.TLNum(len(value.Requester)).EncodingLength()) + l += uint(len(value.Requester)) + l += 3 + l += uint(enc.TLNum(len(value.SentAt)).EncodingLength()) + l += uint(len(value.SentAt)) + encoder.Length = l + +} + +func (context *RefreshPingParsingContext) Init() { + +} + +func (encoder *RefreshPingEncoder) EncodeInto(value *RefreshPing, buf []byte) { + + pos := uint(0) + + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1440)) + pos += 3 + pos += uint(enc.TLNum(len(value.RequestId)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.RequestId) + pos += uint(len(value.RequestId)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1442)) + pos += 3 + pos += uint(enc.TLNum(len(value.Requester)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Requester) + pos += uint(len(value.Requester)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1444)) + pos += 3 + pos += uint(enc.TLNum(len(value.SentAt)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.SentAt) + pos += uint(len(value.SentAt)) +} + +func (encoder *RefreshPingEncoder) Encode(value *RefreshPing) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.Length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *RefreshPingParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*RefreshPing, error) { + + var handled_RequestId bool = false + var handled_Requester bool = false + var handled_SentAt bool = false + + progress := -1 + _ = progress + + value := &RefreshPing{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 1440: + if true { + handled = true + handled_RequestId = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.RequestId = builder.String() + } + } + } + case 1442: + if true { + handled = true + handled_Requester = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.Requester = builder.String() + } + } + } + case 1444: + if true { + handled = true + handled_SentAt = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.SentAt = builder.String() + } + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_RequestId && err == nil { + err = enc.ErrSkipRequired{Name: "RequestId", TypeNum: 1440} + } + if !handled_Requester && err == nil { + err = enc.ErrSkipRequired{Name: "Requester", TypeNum: 1442} + } + if !handled_SentAt && err == nil { + err = enc.ErrSkipRequired{Name: "SentAt", TypeNum: 1444} + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *RefreshPing) Encode() enc.Wire { + encoder := RefreshPingEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *RefreshPing) Bytes() []byte { + return value.Encode().Join() +} + +func ParseRefreshPing(reader enc.WireView, ignoreCritical bool) (*RefreshPing, error) { + context := RefreshPingParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} + +type RefreshAckEncoder struct { + Length uint +} + +type RefreshAckParsingContext struct { +} + +func (encoder *RefreshAckEncoder) Init(value *RefreshAck) { + + l := uint(0) + l += 3 + l += uint(enc.TLNum(len(value.RequestId)).EncodingLength()) + l += uint(len(value.RequestId)) + l += 3 + l += uint(enc.TLNum(len(value.Requester)).EncodingLength()) + l += uint(len(value.Requester)) + l += 3 + l += uint(enc.TLNum(len(value.Responder)).EncodingLength()) + l += uint(len(value.Responder)) + l += 3 + l += uint(1 + enc.Nat(value.Freshness).EncodingLength()) + l += 3 + l += uint(enc.TLNum(len(value.SentAt)).EncodingLength()) + l += uint(len(value.SentAt)) + encoder.Length = l + +} + +func (context *RefreshAckParsingContext) Init() { + +} + +func (encoder *RefreshAckEncoder) EncodeInto(value *RefreshAck, buf []byte) { + + pos := uint(0) + + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1440)) + pos += 3 + pos += uint(enc.TLNum(len(value.RequestId)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.RequestId) + pos += uint(len(value.RequestId)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1442)) + pos += 3 + pos += uint(enc.TLNum(len(value.Requester)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Requester) + pos += uint(len(value.Requester)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1444)) + pos += 3 + pos += uint(enc.TLNum(len(value.Responder)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Responder) + pos += uint(len(value.Responder)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1446)) + pos += 3 + + buf[pos] = byte(enc.Nat(value.Freshness).EncodeInto(buf[pos+1:])) + pos += uint(1 + buf[pos]) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1448)) + pos += 3 + pos += uint(enc.TLNum(len(value.SentAt)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.SentAt) + pos += uint(len(value.SentAt)) +} + +func (encoder *RefreshAckEncoder) Encode(value *RefreshAck) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.Length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *RefreshAckParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*RefreshAck, error) { + + var handled_RequestId bool = false + var handled_Requester bool = false + var handled_Responder bool = false + var handled_Freshness bool = false + var handled_SentAt bool = false + + progress := -1 + _ = progress + + value := &RefreshAck{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 1440: + if true { + handled = true + handled_RequestId = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.RequestId = builder.String() + } + } + } + case 1442: + if true { + handled = true + handled_Requester = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.Requester = builder.String() + } + } + } + case 1444: + if true { + handled = true + handled_Responder = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.Responder = builder.String() + } + } + } + case 1446: + if true { + handled = true + handled_Freshness = true + value.Freshness = uint64(0) + { + for i := 0; i < int(l); i++ { + x := byte(0) + x, err = reader.ReadByte() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + break + } + value.Freshness = uint64(value.Freshness<<8) | uint64(x) + } + } + } + case 1448: + if true { + handled = true + handled_SentAt = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.SentAt = builder.String() + } + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_RequestId && err == nil { + err = enc.ErrSkipRequired{Name: "RequestId", TypeNum: 1440} + } + if !handled_Requester && err == nil { + err = enc.ErrSkipRequired{Name: "Requester", TypeNum: 1442} + } + if !handled_Responder && err == nil { + err = enc.ErrSkipRequired{Name: "Responder", TypeNum: 1444} + } + if !handled_Freshness && err == nil { + err = enc.ErrSkipRequired{Name: "Freshness", TypeNum: 1446} + } + if !handled_SentAt && err == nil { + err = enc.ErrSkipRequired{Name: "SentAt", TypeNum: 1448} + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *RefreshAck) Encode() enc.Wire { + encoder := RefreshAckEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *RefreshAck) Bytes() []byte { + return value.Encode().Join() +} + +func ParseRefreshAck(reader enc.WireView, ignoreCritical bool) (*RefreshAck, error) { + context := RefreshAckParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} + +type RefreshRequestEncoder struct { + Length uint +} + +type RefreshRequestParsingContext struct { +} + +func (encoder *RefreshRequestEncoder) Init(value *RefreshRequest) { + + l := uint(0) + l += 3 + l += uint(enc.TLNum(len(value.RequestId)).EncodingLength()) + l += uint(len(value.RequestId)) + l += 3 + l += uint(enc.TLNum(len(value.Requester)).EncodingLength()) + l += uint(len(value.Requester)) + l += 3 + l += uint(enc.TLNum(len(value.Responder)).EncodingLength()) + l += uint(len(value.Responder)) + l += 3 + l += uint(enc.TLNum(len(value.SentAt)).EncodingLength()) + l += uint(len(value.SentAt)) + encoder.Length = l + +} + +func (context *RefreshRequestParsingContext) Init() { + +} + +func (encoder *RefreshRequestEncoder) EncodeInto(value *RefreshRequest, buf []byte) { + + pos := uint(0) + + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1440)) + pos += 3 + pos += uint(enc.TLNum(len(value.RequestId)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.RequestId) + pos += uint(len(value.RequestId)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1442)) + pos += 3 + pos += uint(enc.TLNum(len(value.Requester)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Requester) + pos += uint(len(value.Requester)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1444)) + pos += 3 + pos += uint(enc.TLNum(len(value.Responder)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.Responder) + pos += uint(len(value.Responder)) + buf[pos] = 253 + binary.BigEndian.PutUint16(buf[pos+1:], uint16(1446)) + pos += 3 + pos += uint(enc.TLNum(len(value.SentAt)).EncodeInto(buf[pos:])) + copy(buf[pos:], value.SentAt) + pos += uint(len(value.SentAt)) +} + +func (encoder *RefreshRequestEncoder) Encode(value *RefreshRequest) enc.Wire { + + wire := make(enc.Wire, 1) + wire[0] = make([]byte, encoder.Length) + buf := wire[0] + encoder.EncodeInto(value, buf) + + return wire +} + +func (context *RefreshRequestParsingContext) Parse(reader enc.WireView, ignoreCritical bool) (*RefreshRequest, error) { + + var handled_RequestId bool = false + var handled_Requester bool = false + var handled_Responder bool = false + var handled_SentAt bool = false + + progress := -1 + _ = progress + + value := &RefreshRequest{} + var err error + var startPos int + for { + startPos = reader.Pos() + if startPos >= reader.Length() { + break + } + typ := enc.TLNum(0) + l := enc.TLNum(0) + typ, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + l, err = reader.ReadTLNum() + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: 0, Err: err} + } + + err = nil + if handled := false; true { + switch typ { + case 1440: + if true { + handled = true + handled_RequestId = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.RequestId = builder.String() + } + } + } + case 1442: + if true { + handled = true + handled_Requester = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.Requester = builder.String() + } + } + } + case 1444: + if true { + handled = true + handled_Responder = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.Responder = builder.String() + } + } + } + case 1446: + if true { + handled = true + handled_SentAt = true + { + var builder strings.Builder + _, err = reader.CopyN(&builder, int(l)) + if err == nil { + value.SentAt = builder.String() + } + } + } + default: + if !ignoreCritical && ((typ <= 31) || ((typ & 1) == 1)) { + return nil, enc.ErrUnrecognizedField{TypeNum: typ} + } + handled = true + err = reader.Skip(int(l)) + } + if err == nil && !handled { + } + if err != nil { + return nil, enc.ErrFailToParse{TypeNum: typ, Err: err} + } + } + } + + startPos = reader.Pos() + err = nil + + if !handled_RequestId && err == nil { + err = enc.ErrSkipRequired{Name: "RequestId", TypeNum: 1440} + } + if !handled_Requester && err == nil { + err = enc.ErrSkipRequired{Name: "Requester", TypeNum: 1442} + } + if !handled_Responder && err == nil { + err = enc.ErrSkipRequired{Name: "Responder", TypeNum: 1444} + } + if !handled_SentAt && err == nil { + err = enc.ErrSkipRequired{Name: "SentAt", TypeNum: 1446} + } + + if err != nil { + return nil, err + } + + return value, nil +} + +func (value *RefreshRequest) Encode() enc.Wire { + encoder := RefreshRequestEncoder{} + encoder.Init(value) + return encoder.Encode(value) +} + +func (value *RefreshRequest) Bytes() []byte { + return value.Encode().Join() +} + +func ParseRefreshRequest(reader enc.WireView, ignoreCritical bool) (*RefreshRequest, error) { + context := RefreshRequestParsingContext{} + context.Init() + return context.Parse(reader, ignoreCritical) +} diff --git a/ndn/app/workspace.go b/ndn/app/workspace.go index 8ab00c62..f172eff1 100644 --- a/ndn/app/workspace.go +++ b/ndn/app/workspace.go @@ -613,6 +613,99 @@ func (a *App) SvsAloJs( return js.ValueOf(name.String()), nil }), + // pub_refresh_ping(requestId: string, requester: string, sentAt: string): Promise; + "pub_refresh_ping": jsutil.AsyncFunc(func(this js.Value, p []js.Value) (any, error) { + requestId := p[0].String() + requester := p[1].String() + sentAt := p[2].String() + + if requestId == "" || requester == "" { + return nil, fmt.Errorf("invalid request parameters") + } + + pub := &tlv.Message{ + RefreshPing: &tlv.RefreshPing{ + RequestId: requestId, + Requester: requester, + SentAt: sentAt, + }, + } + + name, state, err := alo.Publish(pub.Encode()) + if err != nil { + return nil, err + } + + // Persist state + jsutil.Await(persistState.Invoke(jsutil.SliceToJsArray(state.Join()))) + + return js.ValueOf(name.String()), nil + }), + + // pub_refresh_ack(requestId: string, requester: string, responder: string, freshness: number, sentAt: string): Promise; + "pub_refresh_ack": jsutil.AsyncFunc(func(this js.Value, p []js.Value) (any, error) { + requestId := p[0].String() + requester := p[1].String() + responder := p[2].String() + Freshness := uint64(p[3].Int()) + SentAt := p[4].String() + + if requestId == "" || requester == "" || responder == "" { + return nil, fmt.Errorf("invalid request parameters") + } + + pub := &tlv.Message{ + RefreshAck: &tlv.RefreshAck{ + RequestId: requestId, + Requester: requester, + Responder: responder, + Freshness: Freshness, + SentAt: SentAt, + }, + } + + name, state, err := alo.Publish(pub.Encode()) + if err != nil { + return nil, err + } + + // Persist state + jsutil.Await(persistState.Invoke(jsutil.SliceToJsArray(state.Join()))) + + return js.ValueOf(name.String()), nil + }), + + // pub_refresh_req(requestId: string, requester: string, responder: string, sentAt: string): Promise; + "pub_refresh_req": jsutil.AsyncFunc(func(this js.Value, p []js.Value) (any, error) { + requestId := p[0].String() + requester := p[1].String() + responder := p[2].String() + SentAt := p[3].String() + + if requestId == "" || requester == "" || responder == "" { + return nil, fmt.Errorf("invalid request parameters") + } + + pub := &tlv.Message{ + RefreshRequest: &tlv.RefreshRequest{ + RequestId: requestId, + Requester: requester, + Responder: responder, + SentAt: SentAt, + }, + } + + name, state, err := alo.Publish(pub.Encode()) + if err != nil { + return nil, err + } + + // Persist state + jsutil.Await(persistState.Invoke(jsutil.SliceToJsArray(state.Join()))) + + return js.ValueOf(name.String()), nil + }), + // pub_blob_fetch(name: string, encapsulate: Uint8Array | undefined): Promise; "pub_blob_fetch": jsutil.AsyncFunc(func(this js.Value, p []js.Value) (any, error) { // This message is special, in the sense that it is purely intended for repo. @@ -689,11 +782,19 @@ func (a *App) SvsAloJs( return nil, nil }), - // subscribe(name: string, { on_yjs_delta }): Promise; + // subscribe({ + // on_yjs_delta, + // on_refresh_ping, + // on_refresh_ack, + // on_refresh_req, + // }): Promise; "subscribe": jsutil.AsyncFunc(func(this js.Value, p []js.Value) (any, error) { // Send a list of publications to the JS callback sendPub := func(pubs []ndn_sync.SvsPub) { yjsDeltas := js.Global().Get("Array").New() + refreshPings := js.Global().Get("Array").New() + refreshAcks := js.Global().Get("Array").New() + refreshReqs := js.Global().Get("Array").New() for _, pub := range pubs { pmsg, err := tlv.ParseMessage(enc.NewWireView(pub.Content), true) @@ -759,16 +860,62 @@ func (a *App) SvsAloJs( delete(a.dskReqs, peerHex) } + case pmsg.RefreshPing != nil: + refreshPings.Call("push", js.ValueOf(map[string]any{ + "request_id": pmsg.RefreshPing.RequestId, + "requester": pmsg.RefreshPing.Requester, + "sent_at": pmsg.RefreshPing.SentAt, + "publisher": pub.Publisher.String(), + "boot_time": pub.BootTime, + "seq_num": pub.SeqNum, + })) + + case pmsg.RefreshAck != nil: + refreshAcks.Call("push", js.ValueOf(map[string]any{ + "request_id": pmsg.RefreshAck.RequestId, + "requester": pmsg.RefreshAck.Requester, + "responder": pmsg.RefreshAck.Responder, + "freshness": pmsg.RefreshAck.Freshness, + "sent_at": pmsg.RefreshAck.SentAt, + "publisher": pub.Publisher.String(), + "boot_time": pub.BootTime, + "seq_num": pub.SeqNum, + })) + + case pmsg.RefreshRequest != nil: + refreshReqs.Call("push", js.ValueOf(map[string]any{ + "request_id": pmsg.RefreshRequest.RequestId, + "requester": pmsg.RefreshRequest.Requester, + "responder": pmsg.RefreshRequest.Responder, + "sent_at": pmsg.RefreshRequest.SentAt, + "publisher": pub.Publisher.String(), + "boot_time": pub.BootTime, + "seq_num": pub.SeqNum, + })) + default: // This will be logged even for BlobFetch commands, which is fine // (can be fixed but avoid the extra parse that is unused) // log.Warn(a, "Ignoring unknown message", "publisher", pub.Publisher) } } - - if yjsDeltas.Get("length").Int() > 0 { - jsutil.Await(p[0].Get("on_yjs_delta").Invoke(yjsDeltas)) + + invokeBatch := func(name string, arr js.Value) { + if arr.Get("length").Int() == 0 { + return + } + cb := p[0].Get(name) + if cb.Type() != js.TypeFunction { + return + } + jsutil.Await(cb.Invoke(arr)) } + + invokeBatch("on_yjs_delta", yjsDeltas) + invokeBatch("on_refresh_ping", refreshPings) + invokeBatch("on_refresh_ack", refreshAcks) + invokeBatch("on_refresh_req", refreshReqs) + } // Subscribe to the SVS instance diff --git a/public/main.wasm b/public/main.wasm index d60df33f..bb9db7e1 100755 Binary files a/public/main.wasm and b/public/main.wasm differ diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index 50e007ac..1ab1df28 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -132,6 +132,18 @@ +
  • + + + {{ showAdvancedSettings ? 'Hide advanced settings' : 'Advanced settings' }} + +
  • +
  • + + + {{ isRequestingSOS ? 'Broadcasting SOS...' : 'SOS' }} + +
  • @@ -187,6 +199,8 @@ import { faCircleInfo, faRobot, faCircleExclamation, + faArrowsRotate, + faGear, faMoon, faSun, } from '@fortawesome/free-solid-svg-icons'; @@ -222,6 +236,8 @@ const showProjectModal = ref(false); const showInviteModal = ref(false); const showIdentity = ref(false); const showAgentModal = ref(false); +const showAdvancedSettings = ref(false); +const isRequestingSOS = ref(false); // vue-tsc chokes on this type inference const projectTree = useTemplateRef>>('projectTree'); @@ -442,6 +458,27 @@ function setNotification() { else showNotifBubble.value = false; } + +async function sosRequest() { + if (isRequestingSOS.value) return; + + const wksp = globalThis.ActiveWorkspace; + if (!wksp) { + Toast.error('No active workspace'); + return; + } + + isRequestingSOS.value = true; + const progress = Toast.loading('Broadcasting SOS refresh request...'); + try { + const { responder } = await wksp.sosRequest(); + await progress.success(`SOS request sent to ${responder}`); + } catch (err) { + await progress.error(`Failed to send SOS request: ${err}`); + } finally { + isRequestingSOS.value = false; + } +}