-
Notifications
You must be signed in to change notification settings - Fork 492
Add serial protocol #59
Changes from 8 commits
5c75177
eff6087
7bddea6
81788aa
04bdf6e
8557658
67f51e6
e323a1c
8a3a56c
6150e54
3d96c9c
d554f5d
246f2e8
d3da4e9
07c43db
ebb181b
51921e3
1b318b3
6297660
ecea516
6f30401
8dac3f3
b0d90d2
724fde5
1c422b9
fc6a0f4
9f146de
76c746c
c39e371
6ca12be
c485ef7
6be74cd
e8c9623
d9bdee6
6530949
f004ae5
bba8045
8ced4fb
e5570d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#Protocol: | ||
During the first use, or when the chiplet changes environments a “NETWORK” call is expected to initialize the wifi parameters. | ||
|
||
Every time a serial connection is established we will expect a “INIT” call after which any subsequent calls can be made, until the connection is closed. | ||
|
||
In the following examples we use $ to represent variables. For example $Host represents your firebase host. | ||
|
||
##Response Format Byte | ||
All responses will be prefixed with one of the following bytes signifying the response type. | ||
``` | ||
+ If response is ok and a raw value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also have something for raw number and booleans ( maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
* If response is ok and a raw value prefixed by count of bytes in response. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need size prefix for leaf raw value like number and simple strings they are unlikely to grow that big. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is actually where I saw the most use for it. Say you wanted to store a bunch of text to scroll on a display with line breaks. Or say you wanted to push a large binary blob, like a OTA update, to your client. This is where it is nice to know the size of the package so you can prepare memory and storage for it before you start reading it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, since the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking about that as well. The only use case that doesn't support is multiline strings, we cannot know if the value is a multiline string without reading the whole value. But I would like to keep the protocol able to work without the chiplet having to read the whole value into memory. It would be more flexible if it were able to stream data directly from the http connection to the serial connection. It is very possible that the chiplet will have far less ram than the client's MCU. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually as I think about handling multiline strings will be a pain anyway. I think we should just pass them back to the client and allow them to un-escape the newlines. Alright I am sold, lets just determine a threshold to autopromote a string to a bulk string. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can also use the content-length as an hint to promote to bulk string. The trick is that for some "growing" value the client code might have to adapt to get predictable output. Maybe we should have typed GET command where the client can express more intent: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I think as long as we are always prefixing the response than the user has the tools they need to resolve a "growing" value. When the prefix changes they can adapt. That said I don't see any harm in providing typed get commands that will just return an error if the type is not matched. |
||
& If response is ok and json formatted | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like we could always use $ and size prefix for json value (sorry if I went back and forth on this) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am ok with that, not a problem to change your mind. It is easy to do at this stage, better than when we have actually implemented things. |
||
$ If response is ok and json formatted and prefixed by count of bytes in response. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a \r\n after the size to match Redis spec for bulk strings There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
! If response is an error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
``` | ||
##NETWORK | ||
Only needs to be called when the chiplet is in a new environment and needs to connect to a new network. This setting will be stored by the chiplet and persisted through power cycles. | ||
###Usage | ||
NETWORK $SSID | ||
NETWORK $SSID $PASSWORD | ||
###Response | ||
CONNECTED - When connected to new network | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be +CONNECTED :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on nvm, this is then correct in the example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
UNABLE_TO_CONNECT - When unable to connect | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -UNABLE_TO_CONNECT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
###Examples | ||
>> NETWORK home-guest | ||
<< +CONNECTED | ||
>> NETWORK home-private MySecretPassword | ||
<< +CONNECTED | ||
>> NETWORK home-guest | ||
<< !UNABLE_TO_CONNECT | ||
|
||
##INIT | ||
Must be called after creating a Serial connection, it can take either just a host for accessing public variables or you may also provide a secret for accessing protected variables in the database. | ||
###Usage | ||
INIT $Host | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we could have that be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm not sure about that one, INIT implies that it needs to be called everytime to initialize the connection. Maybe CONNECT $HOST $SECRET? Just It seems these should all be commands to the system and phrased as such where FIREBASE isn't really a command. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking that if the CHIPLET was programmed with multiple APIs, it might expose similar commands derived from REST verbs over different APIs (hence the explicit 'FIREBASE'). But that may be a premature discussion, what about 'BEGIN' to make it Arduinoish? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah got ya. Hadn't considered the other APIs. BEGIN works too, we can do BEGIN_FIREBASE if we want to leave the option open for other APIs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's do only begin for now ;) I agree we should worry about multiple API when we have more than 1 binding ;) sorry for the disgression. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then what about:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not really sold on adding an extra call. I think the fewer calls you need to make to get the env setup to start communicating the better. I guess for versions I would just change the begin call. i.e. create a BEGIN_FIREBASE2 if we ever need to implement a breaking change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I liked about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright I am on board with something like that. We can have a concept of "default api" that will load at startup. So for now we can just leave this out all together and address it later on when we introduce other APIs or versions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, so for now I think it's fine to just have |
||
INIT $Host $Secret | ||
###Response | ||
OK - Accepted initialization parameters | ||
###Examples | ||
>> INIT https://samplechat.firebaseio-demo.com | ||
<< +OK | ||
>> INIT https://samplechat.firebaseio-demo.com nnz...sdf | ||
<< +OK | ||
##GET | ||
Fetches the value at $Path and returns it on the serial line. If $PATH points to a leaf node you will get the raw value back, if it points to an internal node you will get a JSON string with all children. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/Path/PATH` to match the "Usage"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
###Usage | ||
GET $PATH | ||
###Response | ||
$DATA_AT_PATH | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the confusing part of using "$" for bulk strings. I am using it in all of the documentation to represent a variable (ala bash). So this should stay variable "DATA_AT_PATH" because we cannot say what type it will be. |
||
###Examples | ||
>>GET /user/aturing/first | ||
<<+Alan | ||
>>GET /user/aturing | ||
<<&{ "first" : "Alan", "last" : "Turing" } | ||
|
||
##GET_BULK | ||
Same as GET but returns value with size prefix. useful when value is expected to be large so you can know the size before accepting value. | ||
Also only returns values at leaf nodes, if called on internal node returns error. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking that the bulk MODE would return the data always as it is coming from fbase (json escaped), otherwise it's a strict subset of GET behavior. Maybe we need separate flag/mode for json/size/type and keep the default very simple and readable (leaf value, un escaped, no prefix), wdyt? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am ok with just dropping the bulk mode for now. We can add it back if we see a need for it in practice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd love if we added all of those as optional stateful flags you could turn on and off so that we can experiment with the wire protocol and see how it feels without adding all the different combination as separate commands. Then we can debate which one is the default, but everything you listed sounds nice to have:
|
||
###Usage | ||
GET_BULK $PATH | ||
###Response | ||
$DATA_BYTE_COUNT $DATA_AT_PATH | ||
###Examples | ||
>>GET_BULK /user/aturing/first | ||
<<*4 Alan | ||
>>GET /user/aturing | ||
<<$39 { "first" : "Alan", "last" : "Turing" } | ||
##Set | ||
##Push | ||
##Remove | ||
##Stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: since
$
is already used in the protocol, maybe we should using a different delimeter for placeholder like%VALUE%
,[VALUE]
or<VALUE>