Pebble Foundation Classes
0.2.0
C++ for Pebble
|
Bi-directional communication between phone apps and Pebble watchapps. More...
Macros | |
#define | APP_MESSAGE_INBOX_SIZE_MINIMUM 124 |
#define | APP_MESSAGE_OUTBOX_SIZE_MINIMUM 636 |
Typedefs | |
typedef void(* | AppMessageInboxReceived) (DictionaryIterator *iterator, void *context) |
typedef void(* | AppMessageInboxDropped) (AppMessageResult reason, void *context) |
typedef void(* | AppMessageOutboxSent) (DictionaryIterator *iterator, void *context) |
typedef void(* | AppMessageOutboxFailed) (DictionaryIterator *iterator, AppMessageResult reason, void *context) |
Enumerations | |
enum | AppMessageResult { APP_MSG_OK = 0, APP_MSG_SEND_TIMEOUT = 1 << 1, APP_MSG_SEND_REJECTED = 1 << 2, APP_MSG_NOT_CONNECTED = 1 << 3, APP_MSG_APP_NOT_RUNNING = 1 << 4, APP_MSG_INVALID_ARGS = 1 << 5, APP_MSG_BUSY = 1 << 6, APP_MSG_BUFFER_OVERFLOW = 1 << 7, APP_MSG_ALREADY_RELEASED = 1 << 9, APP_MSG_CALLBACK_ALREADY_REGISTERED = 1 << 10, APP_MSG_CALLBACK_NOT_REGISTERED = 1 << 11, APP_MSG_OUT_OF_MEMORY = 1 << 12, APP_MSG_CLOSED = 1 << 13, APP_MSG_INTERNAL_ERROR = 1 << 14, APP_MSG_INVALID_STATE = 1 << 15 } |
AppMessage result codes. More... | |
Functions | |
AppMessageResult | app_message_open (const uint32_t size_inbound, const uint32_t size_outbound) |
void | app_message_deregister_callbacks (void) |
void * | app_message_get_context (void) |
void * | app_message_set_context (void *context) |
AppMessageInboxReceived | app_message_register_inbox_received (AppMessageInboxReceived received_callback) |
AppMessageInboxDropped | app_message_register_inbox_dropped (AppMessageInboxDropped dropped_callback) |
AppMessageOutboxSent | app_message_register_outbox_sent (AppMessageOutboxSent sent_callback) |
AppMessageOutboxFailed | app_message_register_outbox_failed (AppMessageOutboxFailed failed_callback) |
uint32_t | app_message_inbox_size_maximum (void) |
uint32_t | app_message_outbox_size_maximum (void) |
AppMessageResult | app_message_outbox_begin (DictionaryIterator **iterator) |
AppMessageResult | app_message_outbox_send (void) |
Bi-directional communication between phone apps and Pebble watchapps.
AppMessage is a bi-directional messaging subsystem that enables communication between phone apps and Pebble watchapps. This is accomplished by allowing phone and watchapps to exchange arbitrary sets of key/value pairs. The key/value pairs are stored in the form of a Dictionary, the layout of which is left for the application developer to define.
AppMessage implements a push-oriented messaging protocol, enabling your app to call functions and methods to push messages from Pebble to phone and vice versa. The protocol is symmetric: both Pebble and the phone can send messages. All messages are acknowledged. In this context, there is no client-server model, as such.
During the sending phase, one side initiates the communication by transferring a dictionary over the air. The other side then receives this message and is given an opportunity to perform actions on that data. As soon as possible, the other side is expected to reply to the message with a simple acknowledgment that the message was received successfully.
PebbleKit JavaScript provides you with a set of standard JavaScript APIs that let your app receive messages from the watch, make HTTP requests, and send new messages to the watch. AppMessage APIs are used to send and receive data. A Pebble watchapp can use the resources of the connected phone to fetch information from web services, send information to web APIs, or store login credentials. On the JavaScript side, you communicate with Pebble via a Pebble object exposed in the namespace.
Messages always need to get either ACKnowledged or "NACK'ed," that is, not acknowledged. If not, messages will result in a time-out failure. The AppMessage subsystem takes care of this implicitly. In the phone libraries, this step is a bit more explicit.
The Pebble watch interfaces make a distinction between the Inbox and the Outbox calls. The Inbox receives messages from the phone on the watch; the Outbox sends messages from the watch to the phone. These two buffers can be managed separately.
A critical constraint of AppMessage is that messages are limited in size. An ingoing (outgoing) message larger than the inbox (outbox) will not be transmitted and will generate an error. You can choose your inbox and outbox size when you call app_message_open().
Pebble SDK provides a static minimum guaranteed size (APP_MESSAGE_INBOX_SIZE_MINIMUM and APP_MESSAGE_OUTBOX_SIZE_MINIMUM). Requesting a buffer of the minimum guaranteed size (or smaller) is always guaranteed to succeed on all Pebbles in this SDK version or higher, and with every phone.
In some context, Pebble might be able to provide your application with larger inbox/outbox. You can call app_message_inbox_size_maximum() and app_message_outbox_size_maximum() in your code to get the largest possible value you can use.
To always get the largest buffer available, follow this best practice:
app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum())
AppMessage uses your application heap space. That means that the sizes you pick for the AppMessage inbox and outbox buffers are important in optimizing your app’s performance. The more you use for AppMessage, the less space you’ll have for the rest of your app.
To register callbacks, you should call app_message_register_inbox_received(), app_message_register_inbox_dropped(), app_message_register_outbox_sent(), app_message_register_outbox_failed().
Pebble recommends that you call them before app_message_open() to ensure you do not miss a message arriving between starting AppMessage and registering the callback. You can set a context that will be passed to all the callbacks with app_message_set_context().
In circumstances that may not be ideal, when using AppMessage several types of errors may occur. For example:
Other errors are possible and described by AppMessageResult. A client of the AppMessage interface should use the result codes to be more robust in the face of communication problems either in the field or while debugging.
Refer to the for a conceptual overview and code usage.
For code examples, refer to the SDK Examples that directly use App Message. These include:
#define APP_MESSAGE_INBOX_SIZE_MINIMUM 124 |
As long as the firmware maintains its current major version, inboxes of this size or smaller will be allowed.
#define APP_MESSAGE_OUTBOX_SIZE_MINIMUM 636 |
As long as the firmware maintains its current major version, outboxes of this size or smaller will be allowed.
typedef void(* AppMessageInboxDropped) (AppMessageResult reason, void *context) |
Called after an incoming message is dropped.
[in] | result | The reason why the message was dropped. Some possibilities include APP_MSG_BUSY and APP_MSG_BUFFER_OVERFLOW. |
[in] | context | Pointer to application data as specified when registering the callback. |
Note that you can call app_message_outbox_begin() from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling app_message_outbox_begin().
typedef void(* AppMessageInboxReceived) (DictionaryIterator *iterator, void *context) |
Called after an incoming message is received.
[in] | iterator | The dictionary iterator to the received message. Never NULL. Note that the iterator cannot be modified or saved off. The library may need to re-use the buffered space where this message is supplied. Returning from the callback indicates to the library that the received message contents are no longer needed or have already been externalized outside its buffering space and iterator. |
[in] | context | Pointer to application data as specified when registering the callback. |
typedef void(* AppMessageOutboxFailed) (DictionaryIterator *iterator, AppMessageResult reason, void *context) |
Called after an outbound message has not been sent successfully.
[in] | iterator | The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict_begin() after this callback returns. |
[in] | result | The result of the operation. Some possibilities for the value include APP_MSG_SEND_TIMEOUT, APP_MSG_SEND_REJECTED, APP_MSG_NOT_CONNECTED, APP_MSG_APP_NOT_RUNNING, and the combination (APP_MSG_NOT_CONNECTED | APP_MSG_APP_NOT_RUNNING) . |
context | Pointer to application data as specified when registering the callback. |
Note that you can call app_message_outbox_begin() from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling app_message_outbox_begin().
typedef void(* AppMessageOutboxSent) (DictionaryIterator *iterator, void *context) |
Called after an outbound message has been sent and the reply has been received.
[in] | iterator | The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict_begin() after this callback returns. |
[in] | context | Pointer to application data as specified when registering the callback. |
enum AppMessageResult |
AppMessage result codes.
void app_message_deregister_callbacks | ( | void | ) |
Deregisters all callbacks and their context.
void* app_message_get_context | ( | void | ) |
Gets the context that will be passed to all AppMessage callbacks.
uint32_t app_message_inbox_size_maximum | ( | void | ) |
Programatically determine the inbox size maximum in the current configuration.
AppMessageResult app_message_open | ( | const uint32_t | size_inbound, |
const uint32_t | size_outbound | ||
) |
Open AppMessage to transfers.
Use dict_calc_buffer_size_from_tuplets() or dict_calc_buffer_size() to estimate the size you need.
[in] | size_inbound | The required size for the Inbox buffer |
[in] | size_outbound | The required size for the Outbox buffer |
AppMessageResult app_message_outbox_begin | ( | DictionaryIterator ** | iterator | ) |
Begin writing to the Outbox's Dictionary buffer.
[out] | iterator | Location to write the DictionaryIterator pointer. This will be NULL on failure. |
AppMessageResult app_message_outbox_send | ( | void | ) |
Sends the outbound dictionary.
uint32_t app_message_outbox_size_maximum | ( | void | ) |
Programatically determine the outbox size maximum in the current configuration.
AppMessageInboxDropped app_message_register_inbox_dropped | ( | AppMessageInboxDropped | dropped_callback | ) |
Registers a function that will be called after any Inbox message is received but dropped by the system.
Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore.
[in] | dropped_callback | The callback that will be called going forward; NULL to not have a callback. |
AppMessageInboxReceived app_message_register_inbox_received | ( | AppMessageInboxReceived | received_callback | ) |
Registers a function that will be called after any Inbox message is received successfully.
Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore.
[in] | received_callback | The callback that will be called going forward; NULL to not have a callback. |
AppMessageOutboxFailed app_message_register_outbox_failed | ( | AppMessageOutboxFailed | failed_callback | ) |
Registers a function that will be called after any Outbox message is not sent with a timely ACK reply. The call to app_message_outbox_send() must have succeeded.
Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore.
[in] | failed_callback | The callback that will be called going forward; NULL to not have a callback. |
AppMessageOutboxSent app_message_register_outbox_sent | ( | AppMessageOutboxSent | sent_callback | ) |
Registers a function that will be called after any Outbox message is sent and an ACK reply occurs in a timely fashion.
Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore.
[in] | sent_callback | The callback that will be called going forward; NULL to not have a callback. |
void* app_message_set_context | ( | void * | context | ) |
Sets the context that will be passed to all AppMessage callbacks.
[in] | context | The context that will be passed to all AppMessage callbacks. |