Satori RTM Core SDK
rtm.h
Go to the documentation of this file.
1 
28 #ifndef CORE_RTM_H__INCLUDED
29 #define CORE_RTM_H__INCLUDED
30 #include <stddef.h>
31 #include <time.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 #include <rtm_config.h>
38 
39 #ifdef _WIN32
40  #if !defined(__WINDOWS__)
41  #define __WINDOWS__
42  #endif
43  #include <Winsock2.h>
44  #include <BaseTsd.h>
45  typedef SSIZE_T ssize_t;
46 #endif
47 
48 #if defined(RTM_USE_GNUTLS)
49 
50 #include <gnutls/gnutls.h>
51 
52 #elif defined(RTM_USE_OPENSSL)
53 
54 #include <openssl/conf.h>
55 #include <openssl/err.h>
56 #include <openssl/ssl.h>
57 
58 #elif defined(RTM_USE_APPLE_SSL)
59 
60 #include <Security/Security.h>
61 #include <Security/SecureTransport.h>
62 
63 #endif
64 
65 
66 #if defined(rtm_core_sdk_EXPORTS) && defined(_WIN32)
67 #define RTM_API __declspec(dllexport)
68 #elif defined(_WIN32) && !defined(RTM_BUILD_STATIC)
69 #define RTM_API __declspec(dllimport)
70 #else
71 #define RTM_API
72 #endif
73 
74 #if RTM_TEST_ENV
75 #define RTM_TEST_API RTM_API
76 #else
77 #define RTM_TEST_API
78 #endif
79 
80 #define _RTM_SCRATCH_BUFFER_SIZE (256)
81 #define _RTM_WS_PRE_BUFFER 16
82 
86 #define RTM_MAX_CHANNEL_SIZE (256)
87 
91 #define RTM_MAX_MESSAGE_SIZE (65536)
92 
96 #define RTM_PATH ("/v2")
97 
98 
102 #define RTM_MAX_ENDPOINT_SIZE (256)
103 
107 #define RTM_MAX_APPKEY_SIZE (32)
108 
112 #define RTM_MAX_ROLE_NAME_SIZE (512)
113 
117 #define RTM_AUTHENTICATION_HASH_SIZE (24)
118 
123  RTM_ACTION_UNKNOWN = 0,
124  RTM_ACTION_AUTHENTICATE_ERROR,
125  RTM_ACTION_AUTHENTICATE_OK,
126  RTM_ACTION_DELETE_ERROR,
127  RTM_ACTION_DELETE_OK,
128  RTM_ACTION_GENERAL_ERROR,
129  RTM_ACTION_HANDSHAKE_ERROR,
130  RTM_ACTION_HANDSHAKE_OK,
131  RTM_ACTION_PUBLISH_ERROR,
132  RTM_ACTION_PUBLISH_OK,
133  RTM_ACTION_READ_ERROR,
134  RTM_ACTION_READ_OK,
135  RTM_ACTION_SUBSCRIBE_ERROR,
136  RTM_ACTION_SUBSCRIBE_OK,
137  RTM_ACTION_SUBSCRIPTION_DATA,
138  RTM_ACTION_SUBSCRIPTION_ERROR,
139  RTM_ACTION_SUBSCRIPTION_INFO,
140  RTM_ACTION_UNSUBSCRIBE_ERROR,
141  RTM_ACTION_UNSUBSCRIBE_OK,
142  RTM_ACTION_WRITE_ERROR,
143  RTM_ACTION_WRITE_OK,
144  RTM_ACTION_SENTINEL
145 };
146 
155 typedef struct {
156  char *position;
158 
162 RTM_API char *rtm_iterate(rtm_list_iterator_t const *iterator);
163 
193 typedef struct _rtm_pdu {
194  unsigned request_id;
195  enum rtm_action_t action;
196  union {
197  struct {
198  union {
199  char const *error;
200  char const *info;
201  };
202  char const *reason;
203  };
204  struct {
205  char const *position;
206  char const *subscription_id;
207  union {
208  char const *message;
209  rtm_list_iterator_t message_iterator;
210  };
211  };
212  char const *body;
213  char const *nonce;
214  };
215 } rtm_pdu_t;
216 
220 typedef struct rtm_client rtm_client_t;
221 
242 typedef void(rtm_message_handler_t)(rtm_client_t *rtm, const char *subscription_id,
243  const char *message);
244 
265 typedef void(rtm_pdu_handler_t)(rtm_client_t *rtm, const rtm_pdu_t *pdu);
266 typedef void(rtm_raw_pdu_handler_t)(rtm_client_t *rtm, char const *raw_pdu);
267 
271 typedef void(rtm_error_logger_t)(const char *message);
272 
279 typedef enum {
280  RTM_OK = 0,
283  RTM_ERR_OOM = -100,
290  RTM_ERR_READ = -94,
294  RTM_ERR_TLS = -91,
296 } rtm_status;
297 
301 RTM_API extern const size_t rtm_client_size;
302 
307 RTM_API void rtm_set_error_logger(rtm_client_t *rtm, rtm_error_logger_t *error_logger);
308 
309 
322 typedef void *(rtm_malloc_fn_t)(rtm_client_t *rtm, size_t size);
323 
334 typedef void (rtm_free_fn_t)(rtm_client_t *rtm, void *ptr);
335 
339 RTM_API void *rtm_system_malloc(rtm_client_t *rtm, size_t size);
340 
344 RTM_API void rtm_system_free(rtm_client_t *rtm, void *mem);
345 
352 RTM_API void *rtm_null_malloc(rtm_client_t *rtm, size_t size);
353 
357 RTM_API void rtm_null_free(rtm_client_t *rtm, void *mem);
358 
382 RTM_API void rtm_set_allocator(rtm_client_t *rtm, rtm_malloc_fn_t *malloc_ptr, rtm_free_fn_t *free_ptr);
383 
391 RTM_API void rtm_default_error_logger(const char *message);
392 
400 RTM_API void rtm_default_message_handler(rtm_client_t *rtm, const char *channel,
401  const char *message);
402 
409 RTM_API void rtm_default_pdu_handler(rtm_client_t *rtm, const rtm_pdu_t *pdu);
410 
418 RTM_API time_t rtm_get_ws_ping_interval(rtm_client_t *rtm);
419 
427 RTM_API void rtm_set_connection_timeout(rtm_client_t *rtm, unsigned timeout_in_seconds);
428 
437 RTM_API void rtm_set_ws_ping_interval(rtm_client_t *rtm, time_t ws_ping_interval);
438 
458 RTM_API rtm_client_t *rtm_init(
459  void *memory,
460  rtm_pdu_handler_t *pdu_handler,
461  void *user_context);
462 
469 #define RTM_CLIENT_SIZE_WITH_BUFFERS(buffer_size) (sizeof(struct _rtm_client_priv) + _RTM_WS_PRE_BUFFER + 2*buffer_size)
470 
474 #define RTM_CLIENT_SIZE (RTM_CLIENT_SIZE_WITH_BUFFERS(RTM_MAX_MESSAGE_SIZE))
475 
495 RTM_API rtm_client_t *rtm_init_ex(
496  void *memory,
497  size_t memory_size,
498  rtm_pdu_handler_t *pdu_handler,
499  void *user_context);
500 
519 RTM_API rtm_status rtm_connect(rtm_client_t *rtm,
520  const char *endpoint,
521  const char *appkey);
522 
543  rtm_client_t *rtm,
544  char const *endpoint,
545  char const *appkey,
546  char const *proxy_endpoint);
547 
561 RTM_API void rtm_set_raw_pdu_handler(rtm_client_t *rtm, rtm_raw_pdu_handler_t *handler);
562 
568 RTM_API void rtm_enable_verbose_logging(rtm_client_t *rtm);
569 
575 RTM_API void rtm_disable_verbose_logging(rtm_client_t *rtm);
576 
590 RTM_API void rtm_close(rtm_client_t *rtm);
591 
611  const char *role, unsigned *ack_id);
612 
631 RTM_API rtm_status rtm_authenticate(rtm_client_t *rtm, const char *role_secret, const char *nonce, unsigned *ack_id);
632 
633 
634 
652 RTM_API rtm_status rtm_publish_json(rtm_client_t *rtm, const char *channel,
653  const char *json, unsigned *ack_id);
654 
674 RTM_API rtm_status rtm_publish_string(rtm_client_t *rtm, const char *channel,
675  const char *string, unsigned *ack_id);
676 
693 RTM_API rtm_status rtm_subscribe(rtm_client_t *rtm, const char *channel,
694  unsigned *ack_id);
711 RTM_API rtm_status rtm_subscribe_with_body(rtm_client_t *rtm, const char *body,
712  unsigned *ack_id);
713 
730 RTM_API rtm_status rtm_unsubscribe(rtm_client_t *rtm, const char *channel,
731  unsigned *ack_id);
732 
742 RTM_API rtm_status rtm_parse_pdu(char *message, rtm_pdu_t *pdu);
743 
759 RTM_API rtm_status rtm_read(rtm_client_t *rtm, const char *channel, unsigned *ack_id);
760 
777 RTM_API rtm_status rtm_read_with_body(rtm_client_t *rtm, const char *body, unsigned *ack_id);
778 
789 
808 RTM_API rtm_status rtm_write_string(rtm_client_t *rtm, const char *key, const char *string,
809  unsigned *ack_id);
810 
829 RTM_API rtm_status rtm_write_json(rtm_client_t *rtm, const char *key, const char *json,
830  unsigned *ack_id);
831 
850 RTM_API rtm_status rtm_delete(rtm_client_t *rtm, const char *key, unsigned *ack_id);
851 
864 RTM_API rtm_status rtm_send_pdu(rtm_client_t *rtm, const char *json);
865 
881 RTM_API rtm_status rtm_wait(rtm_client_t *rtm);
882 
895 RTM_API rtm_status rtm_wait_timeout(rtm_client_t *rtm, int timeout_in_seconds);
896 
914 RTM_API rtm_status rtm_poll(rtm_client_t *rtm);
915 
924 RTM_API int rtm_get_fd(rtm_client_t *rtm);
925 
933 RTM_API void *rtm_get_user_context(rtm_client_t *rtm);
934 
942 RTM_API const char *rtm_error_string(rtm_status status);
943 
951 
952  void *user;
953  int fd;
960  size_t fragmented_message_length;
961 
966  size_t input_length;
967 
973  size_t skip_next_n_input_bytes;
974 
975  unsigned is_closed: 1;
976  unsigned is_used: 1;
977  unsigned is_verbose: 1;
987  unsigned skip_current_fragmented_message: 1;
988 
989  unsigned last_request_id;
990  unsigned last_ping_ts;
991  time_t ws_ping_interval;
993  unsigned is_secure: 1;
994  #if defined(RTM_USE_GNUTLS)
995  gnutls_session_t session;
996  #elif defined(RTM_USE_OPENSSL)
997  SSL_CTX *ssl_context;
998  SSL *ssl_connection;
999  #elif defined(RTM_USE_APPLE_SSL)
1000  SSLContextRef sslContext;
1001  #endif
1002 
1003  unsigned connect_timeout;
1004  rtm_pdu_handler_t *handle_pdu;
1005  rtm_raw_pdu_handler_t *handle_raw_pdu;
1007  rtm_error_logger_t *error_logger;
1008  rtm_malloc_fn_t *malloc_fn;
1009  rtm_free_fn_t *free_fn;
1014  char scratch_buffer[_RTM_SCRATCH_BUFFER_SIZE];
1015 
1016  // The buffers are padded so we are always guaranteed to have
1017  // enough bytes to pre pad any buffer with websocket framing
1018 
1044  char *input_buffer;
1045  size_t input_buffer_size;
1060  size_t output_buffer_size;
1061  char *output_buffer;
1062 
1063  size_t dynamic_input_buffer_size;
1064  char *dynamic_input_buffer;
1065 };
1066 
1067 struct rtm_client {
1068  struct _rtm_client_priv priv;
1069 };
1070 
1071 
1072 #ifdef __cplusplus
1073 }
1074 #endif
1075 
1076 #endif // CORE_RTM_H__INCLUDED
Structure containing information about the received PDU.
Definition: rtm.h:193
RTM_API rtm_client_t * rtm_init_ex(void *memory, size_t memory_size, rtm_pdu_handler_t *pdu_handler, void *user_context)
Initialize an instance of rtm_client_t with a custom buffer size.
Definition: rtm.c:75
RTM_API rtm_status rtm_send_pdu(rtm_client_t *rtm, const char *json)
Send a raw PDU as well-formed JSON string.
Definition: rtm.c:624
rtm_action_t
The set of all possible actions that PDUs incoming from RTM can have.
Definition: rtm.h:122
RTM_API rtm_status rtm_subscribe(rtm_client_t *rtm, const char *channel, unsigned *ack_id)
Subscribe to a specific channel.
Definition: rtm.c:554
RTM_API rtm_status rtm_write_json(rtm_client_t *rtm, const char *key, const char *json, unsigned *ack_id)
Write the well-formed JSON value to a specific channel.
Definition: rtm.c:616
RTM_API void rtm_default_message_handler(rtm_client_t *rtm, const char *channel, const char *message)
Default message handler prints all messages to stdout.
RTM_API rtm_status rtm_read_with_body(rtm_client_t *rtm, const char *body, unsigned *ack_id)
Read the latest published message with specifying a full body of read PDU request.
Definition: rtm.c:607
RTM_API void rtm_set_raw_pdu_handler(rtm_client_t *rtm, rtm_raw_pdu_handler_t *handler)
Set the handler for not yet parsed PDUs.
Definition: rtm.c:1455
RTM_API rtm_status rtm_wait(rtm_client_t *rtm)
Wait for any PDUs and execute the user&#39;s callbacks.
Definition: rtm.c:656
RTM_API rtm_status rtm_delete(rtm_client_t *rtm, const char *key, unsigned *ack_id)
Delete the value of a specific channel.
Definition: rtm.c:620
RTM_API rtm_status rtm_subscribe_with_body(rtm_client_t *rtm, const char *body, unsigned *ack_id)
Subscribe with specifying a full body of subscribe PDU request.
Definition: rtm.c:558
void( rtm_message_handler_t)(rtm_client_t *rtm, const char *subscription_id, const char *message)
Type of callback function invoked when client receives messages from RTM.
Definition: rtm.h:242
RTM_API void * rtm_system_malloc(rtm_client_t *rtm, size_t size)
malloc() implementation using the system&#39;s malloc()
Definition: rtm.c:730
RTM_API void rtm_set_error_logger(rtm_client_t *rtm, rtm_error_logger_t *error_logger)
Set the error logger used by the RTM structure. The default value is rtm_default_error_logger.
Definition: rtm.c:1451
Definition: rtm.h:288
RTM_API void rtm_set_ws_ping_interval(rtm_client_t *rtm, time_t ws_ping_interval)
Sets new WS ping interval. A ws ping frame will be perodically sent to server to avoid connection ref...
Definition: rtm.c:598
Definition: rtm.h:293
SDK uses this type to return collections of strings, for example messages in subscription_data PDUs...
Definition: rtm.h:155
struct _rtm_pdu rtm_pdu_t
Structure containing information about the received PDU.
RTM_API char * rtm_iterate(rtm_list_iterator_t const *iterator)
get next element in iterator or NULL if there are none
Definition: rtm.c:1390
RTM_API const char * rtm_error_string(rtm_status status)
Returns a human-readable string representing the status of operation.
Definition: rtm.c:779
RTM_API void * rtm_get_user_context(rtm_client_t *rtm)
Retrieve the user specific pointer from the client.
Definition: rtm.c:651
void( rtm_error_logger_t)(const char *message)
Error logging function.
Definition: rtm.h:271
RTM_API rtm_status rtm_read(rtm_client_t *rtm, const char *channel, unsigned *ack_id)
Read the latest published message.
Definition: rtm.c:603
RTM_API void rtm_enable_verbose_logging(rtm_client_t *rtm)
Enable logging of incoming and outcoming PDUs.
Definition: rtm.c:1514
RTM_API void rtm_set_allocator(rtm_client_t *rtm, rtm_malloc_fn_t *malloc_ptr, rtm_free_fn_t *free_ptr)
Set the allocator used by the RTM structure.
Definition: rtm.c:1446
RTM_API void rtm_system_free(rtm_client_t *rtm, void *mem)
free() implementation using the system&#39;s free()
Definition: rtm.c:735
RTM_API rtm_client_t * rtm_init(void *memory, rtm_pdu_handler_t *pdu_handler, void *user_context)
Initialize an instance of rtm_client_t.
Definition: rtm.c:67
RTM_API rtm_status rtm_handshake(rtm_client_t *rtm, const char *role, unsigned *ack_id)
Send the handshake request to obtain nonce from the server.
Definition: rtm.c:308
RTM_API rtm_status rtm_parse_pdu(char *message, rtm_pdu_t *pdu)
Parse string as top-level PDU object.
Definition: rtm.c:1166
void( rtm_free_fn_t)(rtm_client_t *rtm, void *ptr)
free() like function for use with RTM.
Definition: rtm.h:334
Definition: rtm.h:283
RTM_API rtm_status rtm_unsubscribe(rtm_client_t *rtm, const char *channel, unsigned *ack_id)
Unsubscribe from a channel.
Definition: rtm.c:562
RTM_API rtm_status rtm_publish_string(rtm_client_t *rtm, const char *channel, const char *string, unsigned *ack_id)
Publish the string to RTM.
Definition: rtm.c:546
RTM_API rtm_status rtm_send_ws_ping(rtm_client_t *rtm)
Send a websocket ping frame.
Definition: rtm.c:639
void( rtm_pdu_handler_t)(rtm_client_t *rtm, const rtm_pdu_t *pdu)
Type of callback function invoked when client receives PDU from RTM.
Definition: rtm.h:265
RTM_API void rtm_set_connection_timeout(rtm_client_t *rtm, unsigned timeout_in_seconds)
Sets the given connection timeout in seconds. Default is 5 seconds.
Definition: rtm.c:593
RTM_API void * rtm_null_malloc(rtm_client_t *rtm, size_t size)
malloc() implementation that always fails gracefully
Definition: rtm.c:740
RTM_API void rtm_default_error_logger(const char *message)
Default error handler.
Definition: rtm.h:287
void *( rtm_malloc_fn_t)(rtm_client_t *rtm, size_t size)
malloc() like function for use with RTM.
Definition: rtm.h:322
RTM_API rtm_status rtm_authenticate(rtm_client_t *rtm, const char *role_secret, const char *nonce, unsigned *ack_id)
Send the authenticate request to establish the identity of the client.
Definition: rtm.c:329
RTM_API rtm_status rtm_connect_via_https_proxy(rtm_client_t *rtm, char const *endpoint, char const *appkey, char const *proxy_endpoint)
Connects to RTM via an https proxy.
Definition: rtm.c:282
RTM_API rtm_status rtm_wait_timeout(rtm_client_t *rtm, int timeout_in_seconds)
Wait with timeout for any PDUs and execute the user&#39;s callbacks.
Definition: rtm.c:670
RTM_API void rtm_null_free(rtm_client_t *rtm, void *mem)
free() implementation that does nothing
Definition: rtm.c:746
RTM_API void rtm_close(rtm_client_t *rtm)
Close an RTM connection.
Definition: rtm.c:296
Definition: rtm.h:294
RTM_API time_t rtm_get_ws_ping_interval(rtm_client_t *rtm)
Returns current WS ping interval (sec)
Definition: rtm.c:588
Definition: rtm.h:295
Definition: rtm.h:286
Definition: rtm.h:292
Definition: rtm.h:289
RTM_API rtm_status rtm_write_string(rtm_client_t *rtm, const char *key, const char *string, unsigned *ack_id)
Write the string value to a specific channel.
Definition: rtm.c:612
Definition: rtm.h:290
Definition: rtm.h:284
Definition: rtm.h:281
Definition: rtm.h:280
Definition: rtm.h:1067
RTM_API void rtm_disable_verbose_logging(rtm_client_t *rtm)
Disable logging of incoming and outcoming PDUs.
Definition: rtm.c:1518
Definition: rtm.h:949
RTM_API rtm_status rtm_publish_json(rtm_client_t *rtm, const char *channel, const char *json, unsigned *ack_id)
Publish the well-formed JSON string to RTM.
Definition: rtm.c:550
RTM_API const size_t rtm_client_size
Default size of rtm_client_t in bytes.
Definition: rtm.c:12
RTM_API int rtm_get_fd(rtm_client_t *rtm)
Retrieve the underlying file descriptor so that it can be incorporated into a message loop...
Definition: rtm.c:583
RTM_API rtm_status rtm_poll(rtm_client_t *rtm)
Poll the underlying socket for any PDUs and execute the user&#39;s callbacks.
Definition: rtm.c:1539
rtm_status
Type used internally to report errors.
Definition: rtm.h:279
RTM_API void rtm_default_pdu_handler(rtm_client_t *rtm, const rtm_pdu_t *pdu)
Default PDU handler prints all PDUs to stdout.
Definition: rtm.c:752
RTM_API rtm_status rtm_connect(rtm_client_t *rtm, const char *endpoint, const char *appkey)
Connects to RTM.
Definition: rtm.c:291