From 5c75177cbd7695d13c59e1e7c6b1f95c4decf50c Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 2 Feb 2016 15:24:32 -0800 Subject: [PATCH 01/42] Create serial_protocol.md Initial copy from google doc --- serial_protocol.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 serial_protocol.md diff --git a/serial_protocol.md b/serial_protocol.md new file mode 100644 index 00000000..2f42e2f3 --- /dev/null +++ b/serial_protocol.md @@ -0,0 +1,42 @@ +#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. +##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 + OK - When connected to new network + FAIL - When unable to connect +###Examples + >> NETWORK home-guest + << OK + >> NETWORK home-private MySecretPassword + << OK + +##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 + 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. +###Usage + GET $Path +###Response + OK +##Set +##Push +##Remove +##Stream From eff608796c3f6702304d5ad49d6a5b312a437c94 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 2 Feb 2016 16:36:07 -0800 Subject: [PATCH 02/42] Update serial_protocol.md --- serial_protocol.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 2f42e2f3..2a47be1b 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -4,7 +4,7 @@ During the first use, or when the chiplet changes environments a “NETWORK” c 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. -##Network +##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 @@ -18,7 +18,7 @@ Only needs to be called when the chiplet is in a new environment and needs to co >> NETWORK home-private MySecretPassword << OK -##Init +##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 @@ -30,12 +30,31 @@ Must be called after creating a Serial connection, it can take either just a hos << OK >> INIT https://samplechat.firebaseio-demo.com nnz...sdf << OK -##Get -Fetches the value at $Path and returns it on the serial line. +##GET +Fetches the value, in json, at $Path and returns it on the serial line. ###Usage - GET $Path + GET $PATH ###Response - OK + $SIZE_OF_DATA $DATA +###Examples + >>GET /user/aturing + <<39 { "first" : "Alan", "last" : "Turing" } + +##GET_VALUE +Fetches the value stored $Path and returns it on the serial line. $PATH must point to a leaf node in the tree as this call returns one value but does so without json wrapper. +###Usage + GET_VALUE $PATH +###Response + $SIZE_OF_DATA_IN_BYTES $DATA + ERROR_NOT_LEAF_NODE +###Examples + >>GET_VALUE /user/aturing/first + <<4 Alan + >>GET_VALUE /user/aturing/last + <<7 Turing + >>GET_VALUE /user/aturing + < Date: Tue, 2 Feb 2016 16:41:46 -0800 Subject: [PATCH 03/42] Update serial_protocol.md --- serial_protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 2a47be1b..015c10d6 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -35,7 +35,7 @@ Fetches the value, in json, at $Path and returns it on the serial line. ###Usage GET $PATH ###Response - $SIZE_OF_DATA $DATA + $DATA_BYTE_COUNT $DATA ###Examples >>GET /user/aturing <<39 { "first" : "Alan", "last" : "Turing" } @@ -45,7 +45,7 @@ Fetches the value stored $Path and returns it on the serial line. $PATH must poi ###Usage GET_VALUE $PATH ###Response - $SIZE_OF_DATA_IN_BYTES $DATA + $DATA_BYTE_COUNT $DATA ERROR_NOT_LEAF_NODE ###Examples >>GET_VALUE /user/aturing/first From 81788aa7a81e76259dab83409ee2ba3f9e3ecd8a Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 3 Feb 2016 15:03:39 -0800 Subject: [PATCH 04/42] Update serial_protocol.md remove GET_VALUE --- serial_protocol.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 015c10d6..2d9099b6 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -31,29 +31,18 @@ Must be called after creating a Serial connection, it can take either just a hos >> INIT https://samplechat.firebaseio-demo.com nnz...sdf << OK ##GET -Fetches the value, in json, at $Path and returns it on the serial line. +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. ###Usage GET $PATH ###Response $DATA_BYTE_COUNT $DATA -###Examples - >>GET /user/aturing - <<39 { "first" : "Alan", "last" : "Turing" } - -##GET_VALUE -Fetches the value stored $Path and returns it on the serial line. $PATH must point to a leaf node in the tree as this call returns one value but does so without json wrapper. -###Usage - GET_VALUE $PATH -###Response - $DATA_BYTE_COUNT $DATA - ERROR_NOT_LEAF_NODE ###Examples >>GET_VALUE /user/aturing/first <<4 Alan >>GET_VALUE /user/aturing/last <<7 Turing >>GET_VALUE /user/aturing - < Date: Wed, 3 Feb 2016 15:57:58 -0800 Subject: [PATCH 05/42] Update serial_protocol.md --- serial_protocol.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 2d9099b6..3a6eda62 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -37,11 +37,11 @@ Fetches the value at $Path and returns it on the serial line. If $PATH points to ###Response $DATA_BYTE_COUNT $DATA ###Examples - >>GET_VALUE /user/aturing/first + >>GET /user/aturing/first <<4 Alan - >>GET_VALUE /user/aturing/last + >>GET /user/aturing/last <<7 Turing - >>GET_VALUE /user/aturing + >>GET /user/aturing <<39 { "first" : "Alan", "last" : "Turing" } ##Set From 85576587cfea65c08adc168552145c03edfc4410 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 3 Feb 2016 16:32:03 -0800 Subject: [PATCH 06/42] Update serial_protocol.md --- serial_protocol.md | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 3a6eda62..88f7a082 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -4,19 +4,30 @@ During the first use, or when the chiplet changes environments a “NETWORK” c 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 + $ If response is ok and a raw value prefixed by count of bytes in response. + & If response is ok and json formatted + ! If response is an error +``` ##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 - OK - When connected to new network - FAIL - When unable to connect + CONNECTED - When connected to new network + UNABLE_TO_CONNECT - When unable to connect ###Examples >> NETWORK home-guest - << OK + << +CONNECTED >> NETWORK home-private MySecretPassword - << OK + << +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. @@ -27,23 +38,35 @@ Must be called after creating a Serial connection, it can take either just a hos OK - Accepted initialization parameters ###Examples >> INIT https://samplechat.firebaseio-demo.com - << OK + << +OK >> INIT https://samplechat.firebaseio-demo.com nnz...sdf - << OK + << +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. ###Usage GET $PATH ###Response - $DATA_BYTE_COUNT $DATA + $DATA_AT_PATH ###Examples >>GET /user/aturing/first - <<4 Alan + <<+Alan >>GET /user/aturing/last - <<7 Turing + <<+Turing >>GET /user/aturing - <<39 { "first" : "Alan", "last" : "Turing" } + <<&{ "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. +###Usage + GET_BULK $PATH +###Response + $DATA_BYTE_COUNT $DATA_AT_PATH +###Examples + >>GET_BULK /user/aturing/first + <<$4 Alan + >>GET /user/aturing + < Date: Wed, 3 Feb 2016 16:44:09 -0800 Subject: [PATCH 07/42] Update serial_protocol.md --- serial_protocol.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 88f7a082..f873c0d9 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -9,8 +9,9 @@ In the following examples we use $ to represent variables. For example $Host rep All responses will be prefixed with one of the following bytes signifying the response type. ``` + If response is ok and a raw value - $ If response is ok and a raw value prefixed by count of bytes in response. + * If response is ok and a raw value prefixed by count of bytes in response. & If response is ok and json formatted + $ If response is ok and json formatted and prefixed by count of bytes in response. ! If response is an error ``` ##NETWORK @@ -64,9 +65,9 @@ Also only returns values at leaf nodes, if called on internal node returns error $DATA_BYTE_COUNT $DATA_AT_PATH ###Examples >>GET_BULK /user/aturing/first - <<$4 Alan + <<*4 Alan >>GET /user/aturing - < Date: Wed, 3 Feb 2016 16:50:16 -0800 Subject: [PATCH 08/42] Update serial_protocol.md --- serial_protocol.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index f873c0d9..a547e231 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -51,8 +51,6 @@ Fetches the value at $Path and returns it on the serial line. If $PATH points to ###Examples >>GET /user/aturing/first <<+Alan - >>GET /user/aturing/last - <<+Turing >>GET /user/aturing <<&{ "first" : "Alan", "last" : "Turing" } @@ -67,7 +65,7 @@ Also only returns values at leaf nodes, if called on internal node returns error >>GET_BULK /user/aturing/first <<*4 Alan >>GET /user/aturing - <<$38 { "first" : "Alan", "last" : "Turing" } + <<$39 { "first" : "Alan", "last" : "Turing" } ##Set ##Push ##Remove From 8a3a56c08ce2996eff3654d7b0fa0cc322376d76 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Thu, 4 Feb 2016 13:44:43 -0800 Subject: [PATCH 09/42] Update serial_protocol.md --- serial_protocol.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index a547e231..5b615ceb 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -8,11 +8,13 @@ In the following examples we use $ to represent variables. For example $Host rep ##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 - * If response is ok and a raw value prefixed by count of bytes in response. - & If response is ok and json formatted - $ If response is ok and json formatted and prefixed by count of bytes in response. - ! If response is an error + + If response is ok and a raw string value. + * If response is ok and a raw string value prefixed by count of bytes in response then new line. + # If response is ok and a integer value. + . If response is ok and a float value. + $ If response is ok and a boolean value. + & If response is ok and json formatted and prefixed by count of bytes in response then new line. + - If response is an error ``` ##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. @@ -28,7 +30,7 @@ Only needs to be called when the chiplet is in a new environment and needs to co >> NETWORK home-private MySecretPassword << +CONNECTED >> NETWORK home-guest - << !UNABLE_TO_CONNECT + << -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. @@ -48,11 +50,13 @@ Fetches the value at $Path and returns it on the serial line. If $PATH points to GET $PATH ###Response $DATA_AT_PATH + $JSON_DATA_BYTE_COUNT \n\r $JSON_DATA ###Examples >>GET /user/aturing/first <<+Alan >>GET /user/aturing - <<&{ "first" : "Alan", "last" : "Turing" } + <<&39 + <<{ "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. @@ -63,9 +67,11 @@ Also only returns values at leaf nodes, if called on internal node returns error $DATA_BYTE_COUNT $DATA_AT_PATH ###Examples >>GET_BULK /user/aturing/first - <<*4 Alan + <<*4 + <>GET /user/aturing - <<$39 { "first" : "Alan", "last" : "Turing" } + <<$39 + <<{ "first" : "Alan", "last" : "Turing" } ##Set ##Push ##Remove From 6150e54c33193defd82662613f0ef25fa3eaa86b Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 10:49:48 -0800 Subject: [PATCH 10/42] Update serial_protocol.md --- serial_protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 5b615ceb..c777257a 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -12,8 +12,8 @@ All responses will be prefixed with one of the following bytes signifying the re * If response is ok and a raw string value prefixed by count of bytes in response then new line. # If response is ok and a integer value. . If response is ok and a float value. - $ If response is ok and a boolean value. - & If response is ok and json formatted and prefixed by count of bytes in response then new line. + ? If response is ok and a boolean value. + $ If response is ok and json formatted and prefixed by count of bytes in response then new line. - If response is an error ``` ##NETWORK From 3d96c9c5c42e8343af54e42902479610ceeb039d Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 10:53:40 -0800 Subject: [PATCH 11/42] Update serial_protocol.md --- serial_protocol.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index c777257a..bfc06776 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -12,8 +12,8 @@ All responses will be prefixed with one of the following bytes signifying the re * If response is ok and a raw string value prefixed by count of bytes in response then new line. # If response is ok and a integer value. . If response is ok and a float value. - ? If response is ok and a boolean value. - $ If response is ok and json formatted and prefixed by count of bytes in response then new line. + $ If response is ok and a boolean value. + & If response is ok and json formatted and prefixed by count of bytes in response then new line. - If response is an error ``` ##NETWORK @@ -58,20 +58,22 @@ Fetches the value at $Path and returns it on the serial line. If $PATH points to <<&39 <<{ "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. +##GET{+,*,#,.,?,$} +Same as GET but will either return the value in the format specified (by the format byte) or return an error. ###Usage - GET_BULK $PATH + GET+ $PATH + GET* $PATH + GET# $PATH + GET. $PATH + GET? $PATH + GET$ $PATH ###Response - $DATA_BYTE_COUNT $DATA_AT_PATH + $FORMATED_RESPONSE ###Examples - >>GET_BULK /user/aturing/first - <<*4 - <>GET /user/aturing - <<$39 - <<{ "first" : "Alan", "last" : "Turing" } + >>GET? /user/aturing/was_human + <>GET? /user/aturing/first + <<-ERROR_INCORRECT_FORMAT ##Set ##Push ##Remove From d554f5d90468cf44cc218b4b744d3e680488300f Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 11:21:06 -0800 Subject: [PATCH 12/42] Update serial_protocol.md --- serial_protocol.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/serial_protocol.md b/serial_protocol.md index bfc06776..26fffc40 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -75,6 +75,29 @@ Same as GET but will either return the value in the format specified (by the for >>GET? /user/aturing/first <<-ERROR_INCORRECT_FORMAT ##Set +Store the data provided at the path provided. This method should be used for simple strings and will assume the first newline is the end of the data. +###Usage + SET $PATH $DATA +###RESPONSE + +OK + -FAIL +###Examples + >>SET /user/aturning/first Alan + <<+OK +##SET_BULK +Similar to SET above but used to write multiline strings or raw data. + +Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. +###Usage + SET_BULK $PATH $DATA_BYTE_COUNT $DATA +###RESPONSE + +OK + -FAIL + -FAIL_TIMEOUT +###Examples + >>SET /user/aturning/address 23 78 High Street, + >>Hampton + <<+OK ##Push ##Remove ##Stream From 246f2e8f896c8adfd3de13cf55cbf9f5a308cd56 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 11:29:14 -0800 Subject: [PATCH 13/42] Update serial_protocol.md --- serial_protocol.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 26fffc40..17fbcbda 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -78,7 +78,7 @@ Same as GET but will either return the value in the format specified (by the for Store the data provided at the path provided. This method should be used for simple strings and will assume the first newline is the end of the data. ###Usage SET $PATH $DATA -###RESPONSE +###Response +OK -FAIL ###Examples @@ -90,7 +90,7 @@ Similar to SET above but used to write multiline strings or raw data. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage SET_BULK $PATH $DATA_BYTE_COUNT $DATA -###RESPONSE +###Response +OK -FAIL -FAIL_TIMEOUT @@ -98,6 +98,17 @@ Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of >>SET /user/aturning/address 23 78 High Street, >>Hampton <<+OK -##Push + ##Remove +Deletes the value located at the path provided. +###Usage + REMOVE $PATH +###Response + +OK + -FAIL +###Examples + >>REMOVE /user/aturning + <<+OK + +##Push ##Stream From d3da4e9ecf84711ebe00b599161df3e62aea3ad2 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:16:14 -0800 Subject: [PATCH 14/42] Update serial_protocol.md --- serial_protocol.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 17fbcbda..e535758f 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -85,7 +85,7 @@ Store the data provided at the path provided. This method should be used for sim >>SET /user/aturning/first Alan <<+OK ##SET_BULK -Similar to SET above but used to write multiline strings or raw data. +Similar to SET above but used to write multiline strings or raw binary data. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage @@ -99,7 +99,7 @@ Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of >>Hampton <<+OK -##Remove +##REMOVE Deletes the value located at the path provided. ###Usage REMOVE $PATH @@ -110,5 +110,25 @@ Deletes the value located at the path provided. >>REMOVE /user/aturning <<+OK -##Push +##PUSH +Adds a value to the list located at the path provided and returns the key at which the new object is located. +###Usage + PUSH $PATH $DATA +###Response + $KEY +###Examples + >>PUSH /user/aturning/login_timestamps 1455052043 + <<+-K94eLnB0rAAvfkh_WC2 +##Push_BULK +Similar to PUSH but used to write multiline strings or raw binary data. + +Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. +###Usage + Push_BULK $PATH $DATA_BYTE_COUNT $DATA +###Response + $KEY +###Examples + >>PUSH /user/aturning/quotes 91 We can only see a short distance ahead, + >>but we can see plenty there that needs to be done. + <<+-K94eLnB0rAAvfkh_WC3 ##Stream From 07c43db8b241399082cf3ca5c04d661887289866 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:42:01 -0800 Subject: [PATCH 15/42] Update serial_protocol.md --- serial_protocol.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index e535758f..56113681 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -119,16 +119,38 @@ Adds a value to the list located at the path provided and returns the key at whi ###Examples >>PUSH /user/aturning/login_timestamps 1455052043 <<+-K94eLnB0rAAvfkh_WC2 -##Push_BULK + +##PUSH_BULK Similar to PUSH but used to write multiline strings or raw binary data. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage - Push_BULK $PATH $DATA_BYTE_COUNT $DATA + PUSH_BULK $PATH $DATA_BYTE_COUNT $DATA ###Response $KEY ###Examples >>PUSH /user/aturning/quotes 91 We can only see a short distance ahead, >>but we can see plenty there that needs to be done. <<+-K94eLnB0rAAvfkh_WC3 -##Stream + +##STREAM +Used to register to receive a stream of events that occur to the object at the provided path. + +After registering you will start receiving events on the response line. They will be formatted as one line with the event type {PUT,PATCH,etc..} and the other line with the data associated with that event type. This data will be formatted similar to GET results and can have multi-line batch strings (*) or json strings (&). + +The event stream will continue until you send CANCEL_STREAM. +###Usage + STREAM $PATH + CANCEL_STREAM +###Response + $EVENT_NAME + $DATA + +OK +###Examples + >>STREAM /user/aturning/last_login + <<+PUT + <<#1455052043 + <<+PUT + <<#1455054063 + >>CANCEL_STREAM + <<+OK From ebb181b018a2c522c2b8a0e340d1abc1fcebca47 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:45:19 -0800 Subject: [PATCH 16/42] Update serial_protocol.md --- serial_protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial_protocol.md b/serial_protocol.md index 56113681..6bbd054e 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -74,7 +74,7 @@ Same as GET but will either return the value in the format specified (by the for <>GET? /user/aturing/first <<-ERROR_INCORRECT_FORMAT -##Set +##SET Store the data provided at the path provided. This method should be used for simple strings and will assume the first newline is the end of the data. ###Usage SET $PATH $DATA From 51921e3cfd64fe670c2f3e32fe0d5eea0488529b Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:48:29 -0800 Subject: [PATCH 17/42] Update serial_protocol.md --- serial_protocol.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 6bbd054e..822aa9ca 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -136,21 +136,21 @@ Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of ##STREAM Used to register to receive a stream of events that occur to the object at the provided path. -After registering you will start receiving events on the response line. They will be formatted as one line with the event type {PUT,PATCH,etc..} and the other line with the data associated with that event type. This data will be formatted similar to GET results and can have multi-line batch strings (*) or json strings (&). +After registering you will start receiving events on the response line. They will be formatted as one line with the event type {PUT,PATCH,etc..} followed by the sub_path that changed and the other line with the data associated with that event type. This data will be formatted similar to GET results and can have multi-line batch strings (*) or json strings (&). The event stream will continue until you send CANCEL_STREAM. ###Usage STREAM $PATH CANCEL_STREAM ###Response - $EVENT_NAME + $EVENT_NAME $SUB_PATH $DATA +OK ###Examples - >>STREAM /user/aturning/last_login - <<+PUT + >>STREAM /user/aturning + <<+PUT /last_login <<#1455052043 - <<+PUT + <<+PUT /last_login <<#1455054063 >>CANCEL_STREAM <<+OK From 1b318b3200537464d5ae691b6c69bdfa84d16f6b Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:50:16 -0800 Subject: [PATCH 18/42] Update serial_protocol.md --- serial_protocol.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 822aa9ca..0c7e5e95 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -95,7 +95,7 @@ Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of -FAIL -FAIL_TIMEOUT ###Examples - >>SET /user/aturning/address 23 78 High Street, + >>SET /user/aturning/address 24 78 High Street, >>Hampton <<+OK @@ -150,7 +150,8 @@ The event stream will continue until you send CANCEL_STREAM. >>STREAM /user/aturning <<+PUT /last_login <<#1455052043 - <<+PUT /last_login - <<#1455054063 + <<+PUT /address + <<*24 78 High Street, + >>Hampton >>CANCEL_STREAM <<+OK From 629766093f4a7b483688e17a64abc3f056de82d0 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:50:39 -0800 Subject: [PATCH 19/42] Update serial_protocol.md --- serial_protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial_protocol.md b/serial_protocol.md index 0c7e5e95..44005045 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -152,6 +152,6 @@ The event stream will continue until you send CANCEL_STREAM. <<#1455052043 <<+PUT /address <<*24 78 High Street, - >>Hampton + <>CANCEL_STREAM <<+OK From ecea516a24a6118bb6f426f53c05ed95d5c6c77f Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:51:27 -0800 Subject: [PATCH 20/42] Update serial_protocol.md --- serial_protocol.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serial_protocol.md b/serial_protocol.md index 44005045..9551f071 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -151,7 +151,8 @@ The event stream will continue until you send CANCEL_STREAM. <<+PUT /last_login <<#1455052043 <<+PUT /address - <<*24 78 High Street, + <<*24 + <<78 High Street, <>CANCEL_STREAM <<+OK From 6f304011f3b3f74f92812dcabba3f8d3846b87a3 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 13:59:27 -0800 Subject: [PATCH 21/42] Update serial_protocol.md --- serial_protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 9551f071..2539729f 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -12,8 +12,8 @@ All responses will be prefixed with one of the following bytes signifying the re * If response is ok and a raw string value prefixed by count of bytes in response then new line. # If response is ok and a integer value. . If response is ok and a float value. - $ If response is ok and a boolean value. - & If response is ok and json formatted and prefixed by count of bytes in response then new line. + ? If response is ok and a boolean value. + $ If response is ok and json formatted and prefixed by count of bytes in response then new line. - If response is an error ``` ##NETWORK From 8dac3f3d8e47f5e2ec4827ccc5aaa139aafa9335 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 15:01:15 -0800 Subject: [PATCH 22/42] Update serial_protocol.md --- serial_protocol.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 2539729f..8848b8d8 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -84,18 +84,20 @@ Store the data provided at the path provided. This method should be used for sim ###Examples >>SET /user/aturning/first Alan <<+OK -##SET_BULK -Similar to SET above but used to write multiline strings or raw binary data. +##SET$ +Similar to SET above but used to write multiline strings or raw binary data. Data format is similar to the batch string ($) return type, we specify the $DATA_BYTE_COUNT on the same line as SET$ then a newline and all data. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage - SET_BULK $PATH $DATA_BYTE_COUNT $DATA + SET$ $PATH $DATA_BYTE_COUNT + $DATA ###Response +OK -FAIL -FAIL_TIMEOUT ###Examples - >>SET /user/aturning/address 24 78 High Street, + >>SET /user/aturning/address 24 + >>78 High Street, >>Hampton <<+OK @@ -120,16 +122,18 @@ Adds a value to the list located at the path provided and returns the key at whi >>PUSH /user/aturning/login_timestamps 1455052043 <<+-K94eLnB0rAAvfkh_WC2 -##PUSH_BULK -Similar to PUSH but used to write multiline strings or raw binary data. +##PUSH$ +Similar to PUSH but used to write multiline strings or raw binary data. Data format is similar to the batch string ($) return type, we specify the $DATA_BYTE_COUNT on the same line as SET$ then a newline and all data. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage - PUSH_BULK $PATH $DATA_BYTE_COUNT $DATA + PUSH_BULK $PATH $DATA_BYTE_COUNT + $DATA ###Response $KEY ###Examples - >>PUSH /user/aturning/quotes 91 We can only see a short distance ahead, + >>PUSH /user/aturning/quotes 91 + >>We can only see a short distance ahead, >>but we can see plenty there that needs to be done. <<+-K94eLnB0rAAvfkh_WC3 From b0d90d2e1a2ffb897f112f47527bf13211f9f961 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 15:31:36 -0800 Subject: [PATCH 23/42] Added Serial client example. --- .../FirebaseSerialClient.ino | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 examples/FirebaseSerialClient/FirebaseSerialClient.ino diff --git a/examples/FirebaseSerialClient/FirebaseSerialClient.ino b/examples/FirebaseSerialClient/FirebaseSerialClient.ino new file mode 100644 index 00000000..10a32ad6 --- /dev/null +++ b/examples/FirebaseSerialClient/FirebaseSerialClient.ino @@ -0,0 +1,142 @@ +// +// Copyright 2015 Google Inc. +// +// 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. +// + +// FirebaseSerialClient is a sample that would sit on the other +// end of a serial connection and communicate with our chiplet. +// When you hold down the send button it will generate a random number +// of flashes and store that in Firebase. Then when you hold down the +// flash button it will read that value from Firebase and flash the +// led the appropriate number of times. If you hold both it will delete +// the stored value. +// This example touches most of the basic calls over the serial interface. + +// Set these parameters. + +const String network_ssid = ""; +const String host = ""; +const String auth = ""; + +bool initialized = false; + +void setup() { + // Connect to pc over usb. + Serial.begin(9600); + + // Connect to chiplet over the Serial1 port (pins 19 and 18). + // If you don't have a Serial1 port than remove all debug output and switch to Serial + Serial1.begin(9600); + + // Note, in production you only need to set NETWORK when your device changes location. + // It will persist through power cycles. + dataPrintLn(String("NETWORK ") + network_ssid); + String response = dataReadLn(); + if (response != "+CONNECTED") { + debugPrintLn("Failed to connect to network: " + response); + return; + } + debugPrintLn("Connected to " + network_ssid); + + dataPrintLn(String("INIT ") + host + " " + auth); + response = dataReadLn(); + if (response != "+OK") { + debugPrintLn("Failed to initalize: " + response); + return; + } + initialized = true; +} + +void loop() { + if (!initialized) { + return; + } + + if (SendButtonDown() && FlashButtonDown()) { + dataPrintLn("REMOVE /led_flashes"); + String response = dataReadLn(); + if (response != "+OK") { + debugPrintLn("Error during REMOVE: " + response); + } + + } else if (SendButtonDown()) { + debugPrintLn("Sending random number."); + int flashes = random(10); + + dataPrintLn(String("SET /led_flashes") + flashes); + String response = dataReadLn(); + if (response != "+OK") { + debugPrintLn("Error during SET: " + response); + } + + // Write to a log as well so we can see the history. + dataPrintLn(String("PUSH /led_flashes_log ") + flashes); + if (dataReadType() == '-') { + debugPrintLn("Error during PUSH: " + dataReadLn()); + } else { + // Drain input, we don't care about the new key. + dataReadLn(); + } + + debugPrintLn("Done sending random number."); + + } else if (FlashButtonDown()) { + debugPrintLn("Flashing LED."); + dataPrintLn(String("GET# /led_flashes")); + if (dataReadType() == '-') { + debugPrintLn("Error during GET: " + dataReadLn()); + } + + int flashes = atoi(dataReadLn().c_str()); + FlashLed(flashes); + + debugPrintLn("Done flashing LED."); + } +} + +bool SendButtonDown() { + //TODO Add detection for button on pin. + return false; +} + +bool FlashButtonDown() { + //TODO Add detection for button on pin. + return false; +} + +void FlashLed(int times) { + //TODO Add logic to flash led at high frequency <500ms between + // flashes so we don't take too long. +} + +void debugPrintLn(const String& message) { + Serial.println(message); +} + +void dataPrintLn(const String& message) { + Serial1.println(message); +} + +char dataReadType() { + return Serial1.read(); +} + +String dataReadLn() { + String line = Serial1.readStringUntil('\r'); + // Dump \r\n + Serial1.read(); + Serial1.read(); + return line; +} + From fc6a0f4d758d0b47d17be21fc98685e480dda4c7 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 15:39:08 -0800 Subject: [PATCH 24/42] Update FirebaseSerialClient.ino --- examples/FirebaseSerialClient/FirebaseSerialClient.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/FirebaseSerialClient/FirebaseSerialClient.ino b/examples/FirebaseSerialClient/FirebaseSerialClient.ino index 10a32ad6..28ed32a1 100644 --- a/examples/FirebaseSerialClient/FirebaseSerialClient.ino +++ b/examples/FirebaseSerialClient/FirebaseSerialClient.ino @@ -32,7 +32,7 @@ const String auth = ""; bool initialized = false; void setup() { - // Connect to pc over usb. + // Connect to pc over usb for debug output. Serial.begin(9600); // Connect to chiplet over the Serial1 port (pins 19 and 18). From 9f146de8878769e28ee0c0afb536e3c792108f24 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 16:40:33 -0800 Subject: [PATCH 25/42] Added buttons and led logic --- .../FirebaseSerialClient.ino | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/examples/FirebaseSerialClient/FirebaseSerialClient.ino b/examples/FirebaseSerialClient/FirebaseSerialClient.ino index 10a32ad6..f7f5dc3e 100644 --- a/examples/FirebaseSerialClient/FirebaseSerialClient.ino +++ b/examples/FirebaseSerialClient/FirebaseSerialClient.ino @@ -23,8 +23,11 @@ // the stored value. // This example touches most of the basic calls over the serial interface. -// Set these parameters. +const int sendButtonPin = 4; +const int flashButtonPin = 5; +const int ledPin = 6; +// Set these parameters. const String network_ssid = ""; const String host = ""; const String auth = ""; @@ -32,6 +35,10 @@ const String auth = ""; bool initialized = false; void setup() { + pinMode(sendButtonPin, INPUT); + pinMode(flashButtonPin, INPUT); + pinMode(ledPin, OUTPUT); + // Connect to pc over usb. Serial.begin(9600); @@ -63,14 +70,14 @@ void loop() { return; } - if (SendButtonDown() && FlashButtonDown()) { + if (digitalRead(sendButtonPin) && digitalRead(flashButtonPin)) { dataPrintLn("REMOVE /led_flashes"); String response = dataReadLn(); if (response != "+OK") { debugPrintLn("Error during REMOVE: " + response); } - } else if (SendButtonDown()) { + } else if (digitalRead(sendButtonPin)) { debugPrintLn("Sending random number."); int flashes = random(10); @@ -91,7 +98,7 @@ void loop() { debugPrintLn("Done sending random number."); - } else if (FlashButtonDown()) { + } else if (digitalRead(flashButtonPin)) { debugPrintLn("Flashing LED."); dataPrintLn(String("GET# /led_flashes")); if (dataReadType() == '-') { @@ -99,25 +106,19 @@ void loop() { } int flashes = atoi(dataReadLn().c_str()); - FlashLed(flashes); + flashLed(flashes); debugPrintLn("Done flashing LED."); } } -bool SendButtonDown() { - //TODO Add detection for button on pin. - return false; -} - -bool FlashButtonDown() { - //TODO Add detection for button on pin. - return false; -} - -void FlashLed(int times) { - //TODO Add logic to flash led at high frequency <500ms between - // flashes so we don't take too long. +void flashLed(int times) { + for (int i=0; i < times; i++) { + digitalWrite(ledPin, HIGH); + delay(200); + digitalWrite(ledPin, LOW); + delay(300); + } } void debugPrintLn(const String& message) { From c39e37167cb71b1801ee2dbbfe33a8fb158990b5 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 17:11:39 -0800 Subject: [PATCH 26/42] Update serial_protocol.md --- serial_protocol.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index 8848b8d8..a02349a2 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -1,7 +1,7 @@ #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. +Every time a serial connection is established we will expect a “BEGIN” 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. @@ -10,8 +10,7 @@ All responses will be prefixed with one of the following bytes signifying the re ``` + If response is ok and a raw string value. * If response is ok and a raw string value prefixed by count of bytes in response then new line. - # If response is ok and a integer value. - . If response is ok and a float value. + : If response is ok and a number, this could be float or int. ? If response is ok and a boolean value. $ If response is ok and json formatted and prefixed by count of bytes in response then new line. - If response is an error @@ -32,17 +31,17 @@ Only needs to be called when the chiplet is in a new environment and needs to co >> NETWORK home-guest << -UNABLE_TO_CONNECT -##INIT +##BEGIN 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 - INIT $Host $Secret + BEGIN $Host + BEGIN $Host $Secret ###Response OK - Accepted initialization parameters ###Examples - >> INIT https://samplechat.firebaseio-demo.com + >> BEGIN https://samplechat.firebaseio-demo.com << +OK - >> INIT https://samplechat.firebaseio-demo.com nnz...sdf + >> BEGIN 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. @@ -63,8 +62,7 @@ Same as GET but will either return the value in the format specified (by the for ###Usage GET+ $PATH GET* $PATH - GET# $PATH - GET. $PATH + GET: $PATH GET? $PATH GET$ $PATH ###Response @@ -153,7 +151,7 @@ The event stream will continue until you send CANCEL_STREAM. ###Examples >>STREAM /user/aturning <<+PUT /last_login - <<#1455052043 + <<:1455052043 <<+PUT /address <<*24 <<78 High Street, From 6ca12bebebf38ad88594557b954573121b741ce6 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 17:13:26 -0800 Subject: [PATCH 27/42] updated example for changes to protocol --- examples/FirebaseSerialClient/FirebaseSerialClient.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/FirebaseSerialClient/FirebaseSerialClient.ino b/examples/FirebaseSerialClient/FirebaseSerialClient.ino index a96e270f..425b14fc 100644 --- a/examples/FirebaseSerialClient/FirebaseSerialClient.ino +++ b/examples/FirebaseSerialClient/FirebaseSerialClient.ino @@ -56,7 +56,7 @@ void setup() { } debugPrintLn("Connected to " + network_ssid); - dataPrintLn(String("INIT ") + host + " " + auth); + dataPrintLn(String("BEGIN ") + host + " " + auth); response = dataReadLn(); if (response != "+OK") { debugPrintLn("Failed to initalize: " + response); @@ -100,7 +100,7 @@ void loop() { } else if (digitalRead(flashButtonPin)) { debugPrintLn("Flashing LED."); - dataPrintLn(String("GET# /led_flashes")); + dataPrintLn(String("GET: /led_flashes")); if (dataReadType() == '-') { debugPrintLn("Error during GET: " + dataReadLn()); } From 6be74cd4cd0959ccaf2e7b1259156bf18b2e673e Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 17:16:07 -0800 Subject: [PATCH 28/42] Update serial_protocol.md --- serial_protocol.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/serial_protocol.md b/serial_protocol.md index a02349a2..46482d61 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -9,10 +9,9 @@ In the following examples we use $ to represent variables. For example $Host rep All responses will be prefixed with one of the following bytes signifying the response type. ``` + If response is ok and a raw string value. - * If response is ok and a raw string value prefixed by count of bytes in response then new line. + $ If response is ok, raw string value will be json formatted and prefixed by the byte count and a new line. : If response is ok and a number, this could be float or int. ? If response is ok and a boolean value. - $ If response is ok and json formatted and prefixed by count of bytes in response then new line. - If response is an error ``` ##NETWORK @@ -54,14 +53,13 @@ Fetches the value at $Path and returns it on the serial line. If $PATH points to >>GET /user/aturing/first <<+Alan >>GET /user/aturing - <<&39 + <<$39 <<{ "first" : "Alan", "last" : "Turing" } ##GET{+,*,#,.,?,$} Same as GET but will either return the value in the format specified (by the format byte) or return an error. ###Usage GET+ $PATH - GET* $PATH GET: $PATH GET? $PATH GET$ $PATH @@ -153,8 +151,7 @@ The event stream will continue until you send CANCEL_STREAM. <<+PUT /last_login <<:1455052043 <<+PUT /address - <<*24 - <<78 High Street, - <>CANCEL_STREAM <<+OK From e8c962309f469b4c9347eba545a04d5de6834b02 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 9 Feb 2016 17:20:07 -0800 Subject: [PATCH 29/42] Update serial_protocol.md --- serial_protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial_protocol.md b/serial_protocol.md index 46482d61..613993e8 100644 --- a/serial_protocol.md +++ b/serial_protocol.md @@ -119,7 +119,7 @@ Adds a value to the list located at the path provided and returns the key at whi <<+-K94eLnB0rAAvfkh_WC2 ##PUSH$ -Similar to PUSH but used to write multiline strings or raw binary data. Data format is similar to the batch string ($) return type, we specify the $DATA_BYTE_COUNT on the same line as SET$ then a newline and all data. +Similar to PUSH but used to write multiline strings or raw binary data. Data format is similar to the batch string ($) return type, we specify the $DATA_BYTE_COUNT on the same line as SET$ then a newline and all data. However you are not required to json escape all of your data, that will be handled for you. Receiver will wait until a timeout for client to send $DATA_BYTE_COUNT worth of data before becoming responsive again. ###Usage From d9bdee645e838ff4aaf207aea83b2557bbd57c31 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 10 Feb 2016 10:48:04 -0800 Subject: [PATCH 30/42] Move serial client to another branch --- .../FirebaseSerialClient.ino | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 examples/FirebaseSerialClient/FirebaseSerialClient.ino diff --git a/examples/FirebaseSerialClient/FirebaseSerialClient.ino b/examples/FirebaseSerialClient/FirebaseSerialClient.ino deleted file mode 100644 index 425b14fc..00000000 --- a/examples/FirebaseSerialClient/FirebaseSerialClient.ino +++ /dev/null @@ -1,143 +0,0 @@ -// -// Copyright 2015 Google Inc. -// -// 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. -// - -// FirebaseSerialClient is a sample that would sit on the other -// end of a serial connection and communicate with our chiplet. -// When you hold down the send button it will generate a random number -// of flashes and store that in Firebase. Then when you hold down the -// flash button it will read that value from Firebase and flash the -// led the appropriate number of times. If you hold both it will delete -// the stored value. -// This example touches most of the basic calls over the serial interface. - -const int sendButtonPin = 4; -const int flashButtonPin = 5; -const int ledPin = 6; - -// Set these parameters. -const String network_ssid = ""; -const String host = ""; -const String auth = ""; - -bool initialized = false; - -void setup() { - pinMode(sendButtonPin, INPUT); - pinMode(flashButtonPin, INPUT); - pinMode(ledPin, OUTPUT); - - // Connect to pc over usb for debug output. - Serial.begin(9600); - - // Connect to chiplet over the Serial1 port (pins 19 and 18). - // If you don't have a Serial1 port than remove all debug output and switch to Serial - Serial1.begin(9600); - - // Note, in production you only need to set NETWORK when your device changes location. - // It will persist through power cycles. - dataPrintLn(String("NETWORK ") + network_ssid); - String response = dataReadLn(); - if (response != "+CONNECTED") { - debugPrintLn("Failed to connect to network: " + response); - return; - } - debugPrintLn("Connected to " + network_ssid); - - dataPrintLn(String("BEGIN ") + host + " " + auth); - response = dataReadLn(); - if (response != "+OK") { - debugPrintLn("Failed to initalize: " + response); - return; - } - initialized = true; -} - -void loop() { - if (!initialized) { - return; - } - - if (digitalRead(sendButtonPin) && digitalRead(flashButtonPin)) { - dataPrintLn("REMOVE /led_flashes"); - String response = dataReadLn(); - if (response != "+OK") { - debugPrintLn("Error during REMOVE: " + response); - } - - } else if (digitalRead(sendButtonPin)) { - debugPrintLn("Sending random number."); - int flashes = random(10); - - dataPrintLn(String("SET /led_flashes") + flashes); - String response = dataReadLn(); - if (response != "+OK") { - debugPrintLn("Error during SET: " + response); - } - - // Write to a log as well so we can see the history. - dataPrintLn(String("PUSH /led_flashes_log ") + flashes); - if (dataReadType() == '-') { - debugPrintLn("Error during PUSH: " + dataReadLn()); - } else { - // Drain input, we don't care about the new key. - dataReadLn(); - } - - debugPrintLn("Done sending random number."); - - } else if (digitalRead(flashButtonPin)) { - debugPrintLn("Flashing LED."); - dataPrintLn(String("GET: /led_flashes")); - if (dataReadType() == '-') { - debugPrintLn("Error during GET: " + dataReadLn()); - } - - int flashes = atoi(dataReadLn().c_str()); - flashLed(flashes); - - debugPrintLn("Done flashing LED."); - } -} - -void flashLed(int times) { - for (int i=0; i < times; i++) { - digitalWrite(ledPin, HIGH); - delay(200); - digitalWrite(ledPin, LOW); - delay(300); - } -} - -void debugPrintLn(const String& message) { - Serial.println(message); -} - -void dataPrintLn(const String& message) { - Serial1.println(message); -} - -char dataReadType() { - return Serial1.read(); -} - -String dataReadLn() { - String line = Serial1.readStringUntil('\r'); - // Dump \r\n - Serial1.read(); - Serial1.read(); - return line; -} - From 75ab6e5cdfbd8c0da090e3328a229bae4be08119 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 10 Feb 2016 13:47:09 -0800 Subject: [PATCH 31/42] Modem design image --- modem/design.png | Bin 0 -> 11771 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 modem/design.png diff --git a/modem/design.png b/modem/design.png new file mode 100644 index 0000000000000000000000000000000000000000..3f525b35df71715c68bb7326bdf0850f26d5d20d GIT binary patch literal 11771 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
>&D8+JXv^eb){_1mjA#!C; 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 Date: Wed, 10 Feb 2016 13:50:58 -0800 Subject: [PATCH 32/42] modified diagram --- modem/design.png | Bin 11771 -> 14888 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modem/design.png b/modem/design.png index 3f525b35df71715c68bb7326bdf0850f26d5d20d..7255bd68e479a3f4f21891fb389d0f19973b31be 100644 GIT binary patch literal 14888 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 literal 11771 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
>&D8+JXv^eb){_1mjA#!C; zO#kXc9Qvb64r}F{jNtm&3)tbxI(VyGIt8(`n61f8Tt6PFM)aK~lsQJX@&oOU_1{X_ zWiZ8Zs@Z`E(wvLU845e2=vRuSTgdu5n#*KDvaXAnlDDOd6}6WxLk`8)8wS^I$>xHE zj$s#7Utjr7xmLNEfvTX~*&Nl*M}%c`V9?C!nMI>)t3s%U@7(aL->_dgMQ@?pCJQ#4 z@LHB~%taoEQ};cOAiph)CKeQ3&hg9FGwa9wKGOYMl!I!OTRrP!n;wcLML5Y6fR2i! zMzx@{8Qx48GTdp+CTj=ascp47Zu(o$oRwzv_3bo8%RieW7woff%cVA1gANbD)aZ}~ zS`D=i-cw?eg)eTnR=b5+uXt5vg*SGDw48d50~4ZB9$7HHbzs&oF{#{cwdB!yORa-b`z< zcx@YRR?-&@!U7Pp-pmrybPC9#D`eljY`Ts{1m&LX^ix&)FdE{kO4~nEdQY%gghY7v zCuk$tBS*7v=5+4`ysitU$v_15mN%;BRhPHq732N>U+bUu&$u}Cdt8pmJ_g+u{9N64 zjG$9e;?$qi?gSdEj$Zcfq>mZAhTC1V6MUPmiGNKM0NytwPd=?jS`RzLd~vNaK0fQ$ zjtn{+T_5zczd;I?6a|JYIIVJ;=@f;9LBA zJgw!$Z~IWH1t@<5g2PjhqlAWUkjPBLH)o+VNgTLB)vv9|DBc(GH~XVH)rf_|F$SlU z0G;w#nF*0+goXww$wJ|lx!rvWK8?}S@Wbw^KCD~qy`t;ZQQ**3i@Y%Q=1nsrD6a82 zZ*dQngRE<5XvA&Yz(iP1>S`w9b^czzFm*M_!}wwPa9Hz+@u%Z72|&-A_UHP}I4>|B zXTf;H*G~Cj7`%wWJ&G2HvLnCDD7s8)AW2<4Q#G|K>jn8teQGHgj~PFUv$@juc*7<} zJDsxnrsLkC?`XbeY*6zgy`Yy4RFi`Ix$_l1;XyU*C#Y)ng01yLd$zK&b3N=tMlT(5 zH@J~22eePWi=8EDKXLI0lJsXeL`AXqc#X0<&)K~G7_W`?C&(SaP8)v`!k?$QluoEXJ4hMDr(+yt5mOp98Vj_mu zru(iC;nj${tyNI@aYdR z%#HkI_i zB)4M@CQ?bR{_>HtQf2BdZUr(-LEt@+Pes&A`gy;-nfY~~*RaPqdVQ5G7Q5!CjQt?X zzVhvlPL{$}5B#3;E(XfLbhGb6u+&o8*{@ic8{;vosSVQ+7}%=b9Qbf>0*bcs3H%%^g>KGEc?3k=@qX7~Q{u4aPo%BG{8%N-GY!|@X3I6tj^0xiDLHAhR*eyr?w38&>yS94 zQld`ygt>|Sy3$oQFdgH1*IJqwk1;tby+Y4Ma`cmV1&+6hSwNbqUe$41=PY;DZ=v_P z$H!TH*XAK~H{`&i+Hy&BNZ!Yj{%3~;=a8%6jV){6BzJU%TGeHD_XfG_U>bI|()(kw z`YCjI$I^loTnD9PrUEa*R;Q`aG?x#}yuuWppy-{u*&8J6fXqkQx-<+!;%4iJtlr2c zi31cAW>K-wS~yWS-i4&$^h_#xnkh>qjRhonme9k;9ORXuM$}>$Gn%k&?(tOSEqs0Z( zTnsWL@}<=@;*~9D;1i}%*nfe}AsD`67!pgykJ8lpJ%w*kf|p#Sm-Levte$|QwBxox z{7&qka1UP>1^<`CAjr@#xz{AS%xs5B=HLs#>Izn5t~H#jPE#RU%l#pFu=^K9MpJK- z1`TP_DI78rn9g{Y7@s^+J$QtSG>z84SRWoRa7j#BFc#iN3Ff~n>;;j&h`@}eG%eSd z{hHRTPLAc+RXM{v_|^U! zjd>rn{mq8YmGUjNbq$@)@-m=<-I00pymi2|T1(Ii}Z;dK+UzauakKU`|xMR?murLUpW`{;0(+`Ry zP~r>dCXLVJ)8M;=0G&ntb5iT+ibJA`{^+3(BbTMynvM-PJPf{F{Ge)(0=})#wpU&w zE(59D$$zfR%P!qX?3R_Jt3q;Fxk$s2WLhvbvJy%%5uU-hK{K2L=;> zp?rahJBC{@(P2}IPg}Z07{t5>H_)<2<3P~RR65@x&BOf3## zt#?KBH0je!2&Dgl@E)d9gL87PeP;%df%q-s{Ab}q{(^c7xcJ{{_|HKc9ZY*qcqu1) z=fvl!9&HGp7aK``yZS7|R2T)0HRdY45FA!q0luk_BW~&hoOjHlggjTH=_ONd=fxK= z-1z;c?Z=@0RO?~4`g;}kqtC(zEKfO`kt*&5A|MBOE(E3{mt=)|HwOcHLq>~K2H)k! zd!%4(oq*oAE%BcM6(}m(8DtLEAmA(Z9Fg;-=hL+m}}_(8QYTa&-GZj|IBtDg8ZQ7sU zS?pzgC5J*Vq89kn=dGV8s*^R9TGVfuQs`dT)kvH-pZIbkF+ZW9t@ZC{@9?Q0j;GQm zR`cM6z2F-Q`M8#GL;?J%n`u9)1x3A=Ezs77+E&2G^BA zoFjei(Dzr4zC)@&bKbj2`sjLv9}wujBdWg@Ji2p Date: Wed, 10 Feb 2016 13:51:16 -0800 Subject: [PATCH 33/42] renamed diagram --- modem/{design.png => diagram.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename modem/{design.png => diagram.png} (100%) diff --git a/modem/design.png b/modem/diagram.png similarity index 100% rename from modem/design.png rename to modem/diagram.png From d9a29155eee514ece2315b08a75cf5983e7fb7bb Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 10 Feb 2016 13:52:21 -0800 Subject: [PATCH 34/42] Create design.md --- modem/design.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 modem/design.md diff --git a/modem/design.md b/modem/design.md new file mode 100644 index 00000000..af827ba7 --- /dev/null +++ b/modem/design.md @@ -0,0 +1,8 @@ +Overview: + +![Design diagram](modem/diagram.png) + +We create a Transceiver object that will manage the serial connection. It will do command detection and hand off to the appropriate Command object to handle the interaction. The Command object will be subclassed for each type of command we will receive and will handle the processing of the command and generating the response. + +The Transceiver object will also own the Firebase object and present it to each command during processing. The Firebase object is our link to the firebase backend. + From 545ce3813e5d7eb0c8e70ac2ccef06d897b2273e Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Wed, 10 Feb 2016 13:53:16 -0800 Subject: [PATCH 35/42] Update design.md --- modem/design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modem/design.md b/modem/design.md index af827ba7..1e94d9ca 100644 --- a/modem/design.md +++ b/modem/design.md @@ -1,6 +1,6 @@ Overview: -![Design diagram](modem/diagram.png) +![Design diagram](diagram.png) We create a Transceiver object that will manage the serial connection. It will do command detection and hand off to the appropriate Command object to handle the interaction. The Command object will be subclassed for each type of command we will receive and will handle the processing of the command and generating the response. From 176035484e717216c936f8966383a0bb417f316d Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 16 Feb 2016 11:06:36 -0800 Subject: [PATCH 36/42] Updated diagram --- modem/diagram.png | Bin 14888 -> 0 bytes modem/diagram.svg | 4 ++++ 2 files changed, 4 insertions(+) delete mode 100644 modem/diagram.png create mode 100644 modem/diagram.svg diff --git a/modem/diagram.png b/modem/diagram.png deleted file mode 100644 index 7255bd68e479a3f4f21891fb389d0f19973b31be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14888 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 diff --git a/modem/diagram.svg b/modem/diagram.svg new file mode 100644 index 00000000..8375539b --- /dev/null +++ b/modem/diagram.svg @@ -0,0 +1,4 @@ + + + + From 71803c7314c5315830d8f7482ee5adb38a857fa8 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 16 Feb 2016 11:08:37 -0800 Subject: [PATCH 37/42] Update design.md --- modem/design.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modem/design.md b/modem/design.md index 1e94d9ca..74f2fb64 100644 --- a/modem/design.md +++ b/modem/design.md @@ -1,8 +1,10 @@ Overview: -![Design diagram](diagram.png) +![Design diagram](diagram.svg) -We create a Transceiver object that will manage the serial connection. It will do command detection and hand off to the appropriate Command object to handle the interaction. The Command object will be subclassed for each type of command we will receive and will handle the processing of the command and generating the response. +We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible handling all input. -The Transceiver object will also own the Firebase object and present it to each command during processing. The Firebase object is our link to the firebase backend. +We will aim to keep the Transceiver/Command interaction generic enough to enable creating additional Protocol Transceivers in the future. + +The Transceiver object will also own the Firebase object and present it to each command during construction. The Firebase object is our link to the firebase backend. From c99734b46318dbd426f0d3e2ed13eb4ac7e1ccb9 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 16 Feb 2016 11:10:50 -0800 Subject: [PATCH 38/42] switched diagram back to png --- modem/diagram.png | Bin 0 -> 15934 bytes modem/diagram.svg | 4 ---- 2 files changed, 4 deletions(-) create mode 100644 modem/diagram.png delete mode 100644 modem/diagram.svg diff --git a/modem/diagram.png b/modem/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5407a95774e25011dd282660e29e25b5d7bd5c GIT binary patch literal 15934 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 F{{Y}f#&`e# literal 0 HcmV?d00001 diff --git a/modem/diagram.svg b/modem/diagram.svg deleted file mode 100644 index 8375539b..00000000 --- a/modem/diagram.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - From 65ef68ed03706fafb458255d0fd21184b9c68bb3 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 16 Feb 2016 11:11:17 -0800 Subject: [PATCH 39/42] Update design.md --- modem/design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modem/design.md b/modem/design.md index 74f2fb64..456dc4b1 100644 --- a/modem/design.md +++ b/modem/design.md @@ -1,6 +1,6 @@ Overview: -![Design diagram](diagram.svg) +![Design diagram](diagram.png) We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible handling all input. From da9d3e6e20231bfc03f50c2376037140e054991e Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Tue, 16 Feb 2016 11:35:31 -0800 Subject: [PATCH 40/42] Update design.md --- modem/design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modem/design.md b/modem/design.md index 456dc4b1..fea7487b 100644 --- a/modem/design.md +++ b/modem/design.md @@ -2,7 +2,7 @@ Overview: ![Design diagram](diagram.png) -We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible handling all input. +We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible for handling all necessary input and leaving the input line in a clean state for the next command. We will aim to keep the Transceiver/Command interaction generic enough to enable creating additional Protocol Transceivers in the future. From fb3526cde5466a270df83bc8545cd2970d0b4413 Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Fri, 25 Mar 2016 14:38:47 -0700 Subject: [PATCH 41/42] Delete design.md Moving to modem-impl branch. --- modem/design.md | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 modem/design.md diff --git a/modem/design.md b/modem/design.md deleted file mode 100644 index fea7487b..00000000 --- a/modem/design.md +++ /dev/null @@ -1,10 +0,0 @@ -Overview: - -![Design diagram](diagram.png) - -We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible for handling all necessary input and leaving the input line in a clean state for the next command. - -We will aim to keep the Transceiver/Command interaction generic enough to enable creating additional Protocol Transceivers in the future. - -The Transceiver object will also own the Firebase object and present it to each command during construction. The Firebase object is our link to the firebase backend. - From de4d3e95e530d41c9966d18c2b5c31082b49247d Mon Sep 17 00:00:00 2001 From: Ed Coyne Date: Fri, 25 Mar 2016 14:39:02 -0700 Subject: [PATCH 42/42] Delete diagram.png Moving to modem-impl branch. --- modem/diagram.png | Bin 15934 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 modem/diagram.png diff --git a/modem/diagram.png b/modem/diagram.png deleted file mode 100644 index ea5407a95774e25011dd282660e29e25b5d7bd5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15934 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 F{{Y}f#&`e#