Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson 2024-12-12 16:43:03 -08:00 committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

View file

@ -0,0 +1,22 @@
# Test the 'msgid' feature for identifying encoded messages
Import('env')
env.NanopbProto('msgid_example')
enc = env.Program(['encode_msgid.c',
'msgid_example.pb.c',
'$COMMON/pb_encode.o',
'$COMMON/pb_common.o'])
dec = env.Program(['decode_msgid.c',
'msgid_example.pb.c',
'$COMMON/pb_decode.o',
'$COMMON/pb_common.o'])
env.RunTest("message1.pb", enc, ARGS = ['1'])
env.RunTest("message1.txt", [dec, 'message1.pb'])
env.RunTest("message2.pb", enc, ARGS = ['2'])
env.RunTest("message2.txt", [dec, 'message2.pb'])
env.RunTest("message3.pb", enc, ARGS = ['3'])
env.RunTest("message3.txt", [dec, 'message3.pb'])

View file

@ -0,0 +1,105 @@
/* Decode a message using msgid prefix to identify message type */
#include <stdio.h>
#include <stdlib.h>
#include <pb_decode.h>
#include "msgid_example.pb.h"
#include "test_helpers.h"
/* This function reads the prefix written by sending side. */
bool read_prefix(pb_istream_t *stream, int *msgid)
{
uint8_t prefix = 0;
if (!pb_read(stream, &prefix, 1))
return false;
*msgid = prefix;
return true;
}
/* Main function will call one of these functions based on the prefix */
bool handle_MyMessage1(pb_istream_t *stream)
{
MyMessage1 msg = MyMessage1_init_default;
if (!pb_decode(stream, MyMessage1_fields, &msg))
return false;
printf("Got MyMessage1: intvalue = %d\n", (int)msg.intvalue);
return true;
}
bool handle_MyMessage2(pb_istream_t *stream)
{
MyMessage2 msg = MyMessage2_init_default;
if (!pb_decode(stream, MyMessage2_fields, &msg))
return false;
printf("Got MyMessage2: intvalue = %d, strvalue = %s\n",
(int)msg.intvalue, msg.strvalue);
return true;
}
bool handle_MyMessage3(pb_istream_t *stream)
{
MyMessage3 msg = MyMessage3_init_default;
if (!pb_decode(stream, MyMessage3_fields, &msg))
return false;
printf("Got MyMessage3: boolvalue = %d\n", (int)msg.boolvalue);
return true;
}
int main(int argc, char **argv)
{
uint8_t buffer[128];
pb_istream_t stream;
size_t count;
bool status = false;
int prefix;
/* Read the data into buffer */
SET_BINARY_MODE(stdin);
count = fread(buffer, 1, sizeof(buffer), stdin);
if (!feof(stdin))
{
printf("Message does not fit in buffer\n");
return 1;
}
stream = pb_istream_from_buffer(buffer, count);
if (!read_prefix(&stream, &prefix))
{
printf("Failed to read prefix: %s\n", PB_GET_ERROR(&stream));
return 1;
}
/* Call message handler based on prefix.
* We could write the switch cases manually, comparing against
* the MyMessageX_msgid defines. However, this uses the automatically
* generated X-macro construct to make the switch case.
*/
switch (prefix)
{
#define PB_MSG(id,len,name) case id: status = handle_ ## name(&stream); break;
MSGID_EXAMPLE_MESSAGES
#undef PB_MSG
default: printf("Unknown prefix: %d\n", prefix); return 1;
}
if (!status)
{
printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
return 1;
} else {
return 0;
}
}

View file

@ -0,0 +1,90 @@
/* Encode a message using msgid field as prefix */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pb_encode.h>
#include "msgid_example.pb.h"
#include "test_helpers.h"
/* This function writes the message id as a prefix to the message, allowing
* the receiving side to identify message type. Here we use uint8_t to store
* it, but e.g. varint or some custom header struct would work just as well.
*/
bool write_prefix(pb_ostream_t *stream, int msgid)
{
uint8_t prefix = msgid;
return pb_write(stream, &prefix, 1);
}
/* The main logic will call one of these functions.
* Normally which function you call would be selected based on what message
* you want to send, here it is decided based on command line parameter.
*/
bool encode_MyMessage1(pb_ostream_t *stream)
{
MyMessage1 msg = MyMessage1_init_default;
msg.intvalue = 1234;
return write_prefix(stream, MyMessage1_msgid)
&& pb_encode(stream, MyMessage1_fields, &msg);
}
bool encode_MyMessage2(pb_ostream_t *stream)
{
MyMessage2 msg = MyMessage2_init_default;
msg.intvalue = 9999;
strcpy(msg.strvalue, "Msg2");
return write_prefix(stream, MyMessage2_msgid)
&& pb_encode(stream, MyMessage2_fields, &msg);
}
bool encode_MyMessage3(pb_ostream_t *stream)
{
MyMessage3 msg = MyMessage3_init_default;
msg.boolvalue = true;
return write_prefix(stream, MyMessage3_msgid)
&& pb_encode(stream, MyMessage3_fields, &msg);
}
int main(int argc, char **argv)
{
uint8_t buffer[128];
pb_ostream_t stream;
bool status = false;
int option;
if (argc != 2)
{
fprintf(stderr, "Usage: encode_msgid [number]\n");
return 1;
}
option = atoi(argv[1]);
stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
if (option == 1)
{
status = encode_MyMessage1(&stream);
}
else if (option == 2)
{
status = encode_MyMessage2(&stream);
}
else if (option == 3)
{
status = encode_MyMessage3(&stream);
}
if (status)
{
SET_BINARY_MODE(stdout);
fwrite(buffer, 1, stream.bytes_written, stdout);
return 0;
}
else
{
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
return 1;
}
}

View file

@ -0,0 +1,25 @@
syntax = "proto3";
import "nanopb.proto";
message MyMessage1
{
option (nanopb_msgopt).msgid = 1;
int32 intvalue = 1;
}
message MyMessage2
{
option (nanopb_msgopt).msgid = 2;
int32 intvalue = 1;
string strvalue = 2 [(nanopb).max_size = 16];
}
message MyMessage3
{
option (nanopb_msgopt).msgid = 3;
bool boolvalue = 1;
}