Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 3 additions & 35 deletions openscreen-application/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
//!
//! Reference: ref/w3c_ref/messages_appendix.cddl

use bytes::Buf;
use heapless::Vec;
use minicbor::{Decoder, Encoder};
use openscreen_common::quinn_varint::{Codec, VarInt};
use openscreen_common::{MessageError, MAX_STRING_LENGTH, MAX_URLS};
use openscreen_common::{
decode_type_key, encode_type_key, MessageError, MAX_STRING_LENGTH, MAX_URLS,
};

/// A wrapper around heapless::Vec that implements minicbor's Write trait
struct VecWriter<'a, const N: usize> {
Expand All @@ -48,38 +48,6 @@ impl<'a, const N: usize> minicbor::encode::Write for VecWriter<'a, N> {
}
}

/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec
fn encode_type_key<const N: usize>(
type_key: u16,
buf: &mut Vec<u8, N>,
) -> Result<(), MessageError> {
let varint = VarInt::from(type_key);
let size = varint.size();

// Ensure we have space
if buf.len() + size > N {
return Err(MessageError::BufferFull);
}

// Encode varint to a small stack buffer, then copy
let mut temp = [0u8; 8];
let mut slice = &mut temp[..];
varint.encode(&mut slice);
buf.extend_from_slice(&temp[..size])
.map_err(|_| MessageError::BufferFull)
}

/// Decode a type key as RFC 9000 variable-length integer from a byte slice.
/// Returns the type key and the number of bytes consumed.
fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> {
let mut cursor = data;
let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?;
let consumed = data.len() - cursor.remaining();
let value = varint.into_inner();
let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?;
Ok((type_key, consumed))
}

/// Maximum size for a single CBOR message
pub const MAX_MESSAGE_SIZE: usize = 1024;

Expand Down
2 changes: 2 additions & 0 deletions openscreen-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

mod error;
pub mod quinn_varint;
mod type_key;
mod types;

pub use error::*;
pub use type_key::*;
pub use types::*;
53 changes: 53 additions & 0 deletions openscreen-common/src/type_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Type key encoding/decoding using RFC 9000 variable-length integers.

use bytes::Buf;
use heapless::Vec;

use crate::error::MessageError;
use crate::quinn_varint::{Codec, VarInt};

/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec
pub fn encode_type_key<const N: usize>(
type_key: u16,
buf: &mut Vec<u8, N>,
) -> Result<(), MessageError> {
let varint = VarInt::from(type_key);
let size = varint.size();

// Ensure we have space
if buf.len() + size > N {
return Err(MessageError::BufferFull);
}

// Encode varint to a small stack buffer, then copy
let mut temp = [0u8; 4];
let mut slice = &mut temp[..];
varint.encode(&mut slice);
buf.extend_from_slice(&temp[..size])
.map_err(|_| MessageError::BufferFull)
}

/// Decode a type key as RFC 9000 variable-length integer from a byte slice.
/// Returns the type key and the number of bytes consumed.
pub fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> {
let mut cursor = data;
let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?;
let consumed = data.len() - cursor.remaining();
let value = varint.into_inner();
let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?;
Ok((type_key, consumed))
}
36 changes: 1 addition & 35 deletions openscreen-network/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@
//!
//! Reference: ref/w3c_ref/messages_appendix.cddl

use bytes::Buf;
use heapless::Vec;
use minicbor::{Decoder, Encoder};
use openscreen_common::quinn_varint::{Codec, VarInt};
use openscreen_common::MessageError;
use openscreen_common::{decode_type_key, encode_type_key, MessageError};

/// A wrapper around heapless::Vec that implements minicbor's Write trait
/// This allows us to encode directly into the Vec without stack allocations
Expand All @@ -51,38 +49,6 @@ impl<'a, const N: usize> minicbor::encode::Write for VecWriter<'a, N> {
}
}

/// Encode a type key as RFC 9000 variable-length integer into a heapless::Vec
fn encode_type_key<const N: usize>(
type_key: u16,
buf: &mut Vec<u8, N>,
) -> Result<(), MessageError> {
let varint = VarInt::from(type_key);
let size = varint.size();

// Ensure we have space
if buf.len() + size > N {
return Err(MessageError::BufferFull);
}

// Encode varint to a small stack buffer, then copy
let mut temp = [0u8; 8];
let mut slice = &mut temp[..];
varint.encode(&mut slice);
buf.extend_from_slice(&temp[..size])
.map_err(|_| MessageError::BufferFull)
}

/// Decode a type key as RFC 9000 variable-length integer from a byte slice.
/// Returns the type key and the number of bytes consumed.
fn decode_type_key(data: &[u8]) -> Result<(u16, usize), MessageError> {
let mut cursor = data;
let varint = VarInt::decode(&mut cursor).map_err(|_| MessageError::DecodeFailed)?;
let consumed = data.len() - cursor.remaining();
let value = varint.into_inner();
let type_key = u16::try_from(value).map_err(|_| MessageError::InvalidMessageType)?;
Ok((type_key, consumed))
}

/// Maximum size for a single CBOR message
pub const MAX_MESSAGE_SIZE: usize = 1024;

Expand Down
Loading