Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/datacake.toit
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import system.services show ServiceResourceProxy
import .internal.api show DatacakeService DatacakeServiceClient

_client_/DatacakeServiceClient? ::= (DatacakeServiceClient).open
--if_absent=: null
--if-absent=: null

connect --tls/bool=true -> Client:
client := _client_
Expand Down
8 changes: 4 additions & 4 deletions src/internal/api.toit
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ interface DatacakeService:
--minor=0

connect tls/bool -> int
static CONNECT_INDEX ::= 0
static CONNECT-INDEX ::= 0

publish handle/int field/string value/string -> none
static PUBLISH_INDEX ::= 1
static PUBLISH-INDEX ::= 1

class DatacakeServiceClient extends services.ServiceClient implements DatacakeService:
static SELECTOR ::= DatacakeService.SELECTOR
Expand All @@ -23,7 +23,7 @@ class DatacakeServiceClient extends services.ServiceClient implements DatacakeSe
super selector

connect tls/bool -> int:
return invoke_ DatacakeService.CONNECT_INDEX tls
return invoke_ DatacakeService.CONNECT-INDEX tls

publish handle/int field/string value/string -> none:
invoke_ DatacakeService.PUBLISH_INDEX [handle, field, value]
invoke_ DatacakeService.PUBLISH-INDEX [handle, field, value]
84 changes: 42 additions & 42 deletions src/service.toit
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import net

import encoding.tison

import certificate_roots
import certificate-roots
import mqtt
import mqtt.packets as mqtt

Expand All @@ -18,53 +18,53 @@ import system.assets
import system.services show ServiceHandler ServiceProvider ServiceResource
import system.base.network show NetworkModule NetworkState NetworkResource

DEFINE_API_TOKEN ::= "datacake.api.token"
DEFINE_DEVICE_ID ::= "datacake.device.id"
DEFINE_PRODUCT_SLUG ::= "datacake.product.slug"
DEFINE-API-TOKEN ::= "datacake.api.token"
DEFINE-DEVICE-ID ::= "datacake.device.id"
DEFINE-PRODUCT-SLUG ::= "datacake.product.slug"

HOST ::= "mqtt.datacake.co"
PORT ::= 8883

main:
logger ::= log.Logger log.DEBUG_LEVEL log.DefaultTarget --name="datacake"
logger ::= log.Logger log.DEBUG-LEVEL log.DefaultTarget --name="datacake"
logger.info "service starting"

defines := assets.decode.get "jag.defines"
--if_present=: tison.decode it
--if_absent=: {:}
--if-present=: tison.decode it
--if-absent=: {:}
if defines is not Map:
logger.error "defines are malformed" --tags={"defines": defines}
exit 1

api_token := defines.get DEFINE_API_TOKEN
if api_token is not string:
logger.error "$DEFINE_API_TOKEN definition is not a string"
api-token := defines.get DEFINE-API-TOKEN
if api-token is not string:
logger.error "$DEFINE-API-TOKEN definition is not a string"
exit 1

device_id := defines.get DEFINE_DEVICE_ID
if device_id is not string:
logger.error "$DEFINE_DEVICE_ID definition is not a string"
device-id := defines.get DEFINE-DEVICE-ID
if device-id is not string:
logger.error "$DEFINE-DEVICE-ID definition is not a string"
exit 1

product_slug := defines.get DEFINE_PRODUCT_SLUG
if product_slug is not string:
logger.error "$DEFINE_PRODUCT_SLUG definition is not a string"
product-slug := defines.get DEFINE-PRODUCT-SLUG
if product-slug is not string:
logger.error "$DEFINE-PRODUCT-SLUG definition is not a string"
exit 1

credentials := DatacakeCredentials
--api_token=api_token
--device_id=device_id
--product_slug=product_slug
--api-token=api-token
--device-id=device-id
--product-slug=product-slug

service := DatacakeServiceProvider logger credentials
service.install
logger.info "service running"

class DatacakeCredentials:
api_token/string
device_id/string
product_slug/string
constructor --.api_token --.device_id --.product_slug:
api-token/string
device-id/string
product-slug/string
constructor --.api-token --.device-id --.product-slug:

class DatacakeServiceProvider extends ServiceProvider implements ServiceHandler:
logger_/log.Logger
Expand All @@ -76,9 +76,9 @@ class DatacakeServiceProvider extends ServiceProvider implements ServiceHandler:
provides DatacakeService.SELECTOR --handler=this

handle index/int arguments/any --gid/int --client/int -> any:
if index == DatacakeService.CONNECT_INDEX:
if index == DatacakeService.CONNECT-INDEX:
return connect arguments client
if index == DatacakeService.PUBLISH_INDEX:
if index == DatacakeService.PUBLISH-INDEX:
resource := (resource client arguments[0]) as DatacakeClient
return resource.module.publish arguments[1] arguments[2]
unreachable
Expand All @@ -98,7 +98,7 @@ class DatacakeMqttModule implements NetworkModule:
done_/monitor.Latch? := null

constructor logger/log.Logger .credentials_:
logger_ = logger.with_name "mqtt"
logger_ = logger.with-name "mqtt"

connect -> none:
connected := monitor.Latch
Expand All @@ -109,10 +109,10 @@ class DatacakeMqttModule implements NetworkModule:
connect_ connected
finally:
client_ = task_ = done_ = null
critical_do: done.set true
critical-do: done.set true
// Wait until the MQTT task has connected and is running.
client_ = connected.get
client_.when_running: null
client_.when-running: null

disconnect -> none:
if not task_: return
Expand All @@ -122,43 +122,43 @@ class DatacakeMqttModule implements NetworkModule:

connect_ connected/monitor.Latch -> none:
network := net.open
nonce := (random 0x1fff_ffff) ^ (Time.monotonic_us & 0x1fff_ffff)
client_id ::= "$credentials_.device_id[0..8]-$(%x nonce)"
nonce := (random 0x1fff_ffff) ^ (Time.monotonic-us & 0x1fff_ffff)
client-id ::= "$credentials_.device-id[0..8]-$(%x nonce)"
transport/mqtt.TcpTransport? := null
client/mqtt.FullClient? := null
try:
transport = mqtt.TcpTransport.tls network
--host=HOST
--port=PORT
--root_certificates=[ certificate_roots.ISRG_ROOT_X1 ]
--root-certificates=[ certificate-roots.ISRG-ROOT-X1 ]
client = mqtt.FullClient --transport=transport
options := mqtt.SessionOptions
--client_id=client_id
--username=credentials_.api_token
--password=credentials_.api_token
--client-id=client-id
--username=credentials_.api-token
--password=credentials_.api-token
client.connect --options=options
logger_.info "connected" --tags={"host": HOST, "port": PORT, "client": client_id}
logger_.info "connected" --tags={"host": HOST, "port": PORT, "client": client-id}
connected.set client
client.handle: | packet/mqtt.Packet |
logger_.warn "packet received (ignored)" --tags={"type": packet.type}
finally: | is_exception exception |
finally: | is-exception exception |
if client: client.close
else if transport: transport.close
network.close
// We need to call monitor operations to send exceptions
// to the task that initiated the connection attempt, so
// we have to do this in a critical section if we're being
// canceled as part of a disconnect.
critical_do:
if connected.has_value:
logger_.info "disconnected" --tags={"host": HOST, "port": PORT, "client": client_id}
if is_exception:
critical-do:
if connected.has-value:
logger_.info "disconnected" --tags={"host": HOST, "port": PORT, "client": client-id}
if is-exception:
connected.set --exception exception
return

publish field/string value/string -> none:
topic := "dtck-pub/$credentials_.product_slug/$credentials_.device_id/$field"
client_.publish topic value.to_byte_array
topic := "dtck-pub/$credentials_.product-slug/$credentials_.device-id/$field"
client_.publish topic value.to-byte-array
logger_.info "packet published" --tags={"field": field, "value": value}

class DatacakeClient extends NetworkResource:
Expand Down