ip_connection.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2012-2014 Matthias Bolte <matthias@tinkerforge.com>
00003  * Copyright (C) 2011 Olaf Lüke <olaf@tinkerforge.com>
00004  *
00005  * Redistribution and use in source and binary forms of this file,
00006  * with or without modification, are permitted. See the Creative
00007  * Commons Zero (CC0 1.0) License for more details.
00008  */
00009 
00010 #ifndef IP_CONNECTION_H
00011 #define IP_CONNECTION_H
00012 
00017 #ifndef __STDC_LIMIT_MACROS
00018         #define __STDC_LIMIT_MACROS
00019 #endif
00020 #include <stdint.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023 
00024 #if !defined __cplusplus && defined __GNUC__
00025         #include <stdbool.h>
00026 #endif
00027 
00028 #ifdef _WIN32
00029         #ifndef WIN32_LEAN_AND_MEAN
00030                 #define WIN32_LEAN_AND_MEAN
00031         #endif
00032         #include <windows.h>
00033 #else
00034         #include <pthread.h>
00035         #include <semaphore.h>
00036 #endif
00037 
00038 #ifdef __cplusplus
00039 extern "C" {
00040 #endif
00041 
00042 enum {
00043         E_OK = 0,
00044         E_TIMEOUT = -1,
00045         E_NO_STREAM_SOCKET = -2,
00046         E_HOSTNAME_INVALID = -3,
00047         E_NO_CONNECT = -4,
00048         E_NO_THREAD = -5,
00049         E_NOT_ADDED = -6, // unused since v2.0
00050         E_ALREADY_CONNECTED = -7,
00051         E_NOT_CONNECTED = -8,
00052         E_INVALID_PARAMETER = -9, // error response from device
00053         E_NOT_SUPPORTED = -10, // error response from device
00054         E_UNKNOWN_ERROR_CODE = -11 // error response from device
00055 };
00056 
00057 #ifdef IPCON_EXPOSE_INTERNALS
00058 
00059 typedef struct _Socket Socket;
00060 
00061 typedef struct {
00062 #ifdef _WIN32
00063         CRITICAL_SECTION handle;
00064 #else
00065         pthread_mutex_t handle;
00066 #endif
00067 } Mutex;
00068 
00069 void mutex_create(Mutex *mutex);
00070 
00071 void mutex_destroy(Mutex *mutex);
00072 
00073 void mutex_lock(Mutex *mutex);
00074 
00075 void mutex_unlock(Mutex *mutex);
00076 
00077 typedef struct {
00078 #ifdef _WIN32
00079         HANDLE handle;
00080 #else
00081         pthread_cond_t condition;
00082         pthread_mutex_t mutex;
00083         bool flag;
00084 #endif
00085 } Event;
00086 
00087 typedef struct {
00088 #ifdef _WIN32
00089         HANDLE handle;
00090 #else
00091         sem_t object;
00092         sem_t *pointer;
00093 #endif
00094 } Semaphore;
00095 
00096 typedef void (*ThreadFunction)(void *opaque);
00097 
00098 typedef struct {
00099 #ifdef _WIN32
00100         HANDLE handle;
00101         DWORD id;
00102 #else
00103         pthread_t handle;
00104 #endif
00105         ThreadFunction function;
00106         void *opaque;
00107 } Thread;
00108 
00109 typedef struct {
00110         Mutex mutex;
00111         int used;
00112         int allocated;
00113         uint32_t *keys;
00114         void **values;
00115 } Table;
00116 
00117 typedef struct _QueueItem {
00118         struct _QueueItem *next;
00119         int kind;
00120         void *data;
00121 } QueueItem;
00122 
00123 typedef struct {
00124         Mutex mutex;
00125         Semaphore semaphore;
00126         QueueItem *head;
00127         QueueItem *tail;
00128 } Queue;
00129 
00130 #if defined _MSC_VER || defined __BORLANDC__
00131         #pragma pack(push)
00132         #pragma pack(1)
00133         #define ATTRIBUTE_PACKED
00134 #elif defined __GNUC__
00135         #ifdef _WIN32
00136                 // workaround struct packing bug in GCC 4.7 on Windows
00137                 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
00138                 #define ATTRIBUTE_PACKED __attribute__((gcc_struct, packed))
00139         #else
00140                 #define ATTRIBUTE_PACKED __attribute__((packed))
00141         #endif
00142 #else
00143         #error unknown compiler, do not know how to enable struct packing
00144 #endif
00145 
00146 typedef struct {
00147         uint32_t uid;
00148         uint8_t length;
00149         uint8_t function_id;
00150         uint8_t sequence_number_and_options;
00151         uint8_t error_code_and_future_use;
00152 } ATTRIBUTE_PACKED PacketHeader;
00153 
00154 typedef struct {
00155         PacketHeader header;
00156         uint8_t payload[64];
00157         uint8_t optional_data[8];
00158 } ATTRIBUTE_PACKED Packet;
00159 
00160 #if defined _MSC_VER || defined __BORLANDC__
00161         #pragma pack(pop)
00162 #endif
00163 #undef ATTRIBUTE_PACKED
00164 
00165 #endif // IPCON_EXPOSE_INTERNALS
00166 
00167 typedef struct _IPConnection IPConnection;
00168 typedef struct _IPConnectionPrivate IPConnectionPrivate;
00169 typedef struct _Device Device;
00170 typedef struct _DevicePrivate DevicePrivate;
00171 
00172 #ifdef IPCON_EXPOSE_INTERNALS
00173 
00174 typedef struct _CallbackContext CallbackContext;
00175 
00176 #endif
00177 
00178 typedef void (*EnumerateCallbackFunction)(const char *uid,
00179                                           const char *connected_uid,
00180                                           char position,
00181                                           uint8_t hardware_version[3],
00182                                           uint8_t firmware_version[3],
00183                                           uint16_t device_identifier,
00184                                           uint8_t enumeration_type,
00185                                           void *user_data);
00186 typedef void (*ConnectedCallbackFunction)(uint8_t connect_reason,
00187                                           void *user_data);
00188 typedef void (*DisconnectedCallbackFunction)(uint8_t disconnect_reason,
00189                                              void *user_data);
00190 
00191 #ifdef IPCON_EXPOSE_INTERNALS
00192 
00193 typedef void (*CallbackWrapperFunction)(DevicePrivate *device_p, Packet *packet);
00194 
00195 #endif
00196 
00200 struct _Device {
00201         DevicePrivate *p;
00202 };
00203 
00204 #ifdef IPCON_EXPOSE_INTERNALS
00205 
00206 #define DEVICE_NUM_FUNCTION_IDS 256
00207 
00211 struct _DevicePrivate {
00212         int ref_count;
00213 
00214         uint32_t uid;
00215 
00216         IPConnectionPrivate *ipcon_p;
00217 
00218         uint8_t api_version[3];
00219 
00220         Mutex request_mutex;
00221 
00222         uint8_t expected_response_function_id; // protected by request_mutex
00223         uint8_t expected_response_sequence_number; // protected by request_mutex
00224         Mutex response_mutex;
00225         Packet response_packet; // protected by response_mutex
00226         Event response_event;
00227         int response_expected[DEVICE_NUM_FUNCTION_IDS];
00228 
00229         void *registered_callbacks[DEVICE_NUM_FUNCTION_IDS];
00230         void *registered_callback_user_data[DEVICE_NUM_FUNCTION_IDS];
00231         CallbackWrapperFunction callback_wrappers[DEVICE_NUM_FUNCTION_IDS];
00232 };
00233 
00237 enum {
00238         DEVICE_RESPONSE_EXPECTED_INVALID_FUNCTION_ID = 0,
00239         DEVICE_RESPONSE_EXPECTED_ALWAYS_TRUE, // getter
00240         DEVICE_RESPONSE_EXPECTED_ALWAYS_FALSE, // callback
00241         DEVICE_RESPONSE_EXPECTED_TRUE, // setter
00242         DEVICE_RESPONSE_EXPECTED_FALSE // setter, default
00243 };
00244 
00248 void device_create(Device *device, const char *uid,
00249                    IPConnectionPrivate *ipcon_p, uint8_t api_version_major,
00250                    uint8_t api_version_minor, uint8_t api_version_release);
00251 
00255 void device_release(DevicePrivate *device_p);
00256 
00260 int device_get_response_expected(DevicePrivate *device_p, uint8_t function_id,
00261                                  bool *ret_response_expected);
00262 
00266 int device_set_response_expected(DevicePrivate *device_p, uint8_t function_id,
00267                                  bool response_expected);
00268 
00272 int device_set_response_expected_all(DevicePrivate *device_p, bool response_expected);
00273 
00277 void device_register_callback(DevicePrivate *device_p, uint8_t id, void *callback,
00278                               void *user_data);
00279 
00283 int device_get_api_version(DevicePrivate *device_p, uint8_t ret_api_version[3]);
00284 
00288 int device_send_request(DevicePrivate *device_p, Packet *request, Packet *response);
00289 
00290 #endif // IPCON_EXPOSE_INTERNALS
00291 
00297 enum {
00298         IPCON_CALLBACK_ENUMERATE = 253,
00299         IPCON_CALLBACK_CONNECTED = 0,
00300         IPCON_CALLBACK_DISCONNECTED = 1
00301 };
00302 
00308 enum {
00309         IPCON_ENUMERATION_TYPE_AVAILABLE = 0,
00310         IPCON_ENUMERATION_TYPE_CONNECTED = 1,
00311         IPCON_ENUMERATION_TYPE_DISCONNECTED = 2
00312 };
00313 
00319 enum {
00320         IPCON_CONNECT_REASON_REQUEST = 0,
00321         IPCON_CONNECT_REASON_AUTO_RECONNECT = 1
00322 };
00323 
00329 enum {
00330         IPCON_DISCONNECT_REASON_REQUEST = 0,
00331         IPCON_DISCONNECT_REASON_ERROR = 1,
00332         IPCON_DISCONNECT_REASON_SHUTDOWN = 2
00333 };
00334 
00340 enum {
00341         IPCON_CONNECTION_STATE_DISCONNECTED = 0,
00342         IPCON_CONNECTION_STATE_CONNECTED = 1,
00343         IPCON_CONNECTION_STATE_PENDING = 2 // auto-reconnect in progress
00344 };
00345 
00349 struct _IPConnection {
00350         IPConnectionPrivate *p;
00351 };
00352 
00353 #ifdef IPCON_EXPOSE_INTERNALS
00354 
00355 #define IPCON_NUM_CALLBACK_IDS 256
00356 #define IPCON_MAX_SECRET_LENGTH 64
00357 
00361 typedef Device BrickDaemon;
00362 
00366 struct _IPConnectionPrivate {
00367 #ifdef _WIN32
00368         bool wsa_startup_done; // protected by socket_mutex
00369 #endif
00370 
00371         char *host;
00372         uint16_t port;
00373 
00374         uint32_t timeout; // in msec
00375 
00376         bool auto_reconnect;
00377         bool auto_reconnect_allowed;
00378         bool auto_reconnect_pending;
00379 
00380         Mutex sequence_number_mutex;
00381         uint8_t next_sequence_number; // protected by sequence_number_mutex
00382 
00383         Mutex authentication_mutex; // protects authentication handshake
00384         uint32_t next_authentication_nonce; // protected by authentication_mutex
00385 
00386         Mutex devices_ref_mutex; // protects DevicePrivate.ref_count
00387         Table devices;
00388 
00389         void *registered_callbacks[IPCON_NUM_CALLBACK_IDS];
00390         void *registered_callback_user_data[IPCON_NUM_CALLBACK_IDS];
00391 
00392         Mutex socket_mutex;
00393         Socket *socket; // protected by socket_mutex
00394         uint64_t socket_id; // protected by socket_mutex
00395 
00396         bool receive_flag;
00397         Thread receive_thread; // protected by socket_mutex
00398 
00399         CallbackContext *callback;
00400 
00401         bool disconnect_probe_flag;
00402         Thread disconnect_probe_thread; // protected by socket_mutex
00403         Event disconnect_probe_event;
00404 
00405         Semaphore wait;
00406 
00407         BrickDaemon brickd;
00408 };
00409 
00410 #endif // IPCON_EXPOSE_INTERNALS
00411 
00418 void ipcon_create(IPConnection *ipcon);
00419 
00427 void ipcon_destroy(IPConnection *ipcon);
00428 
00442 int ipcon_connect(IPConnection *ipcon, const char *host, uint16_t port);
00443 
00450 int ipcon_disconnect(IPConnection *ipcon);
00451 
00465 int ipcon_authenticate(IPConnection *ipcon, const char secret[64]);
00466 
00478 int ipcon_get_connection_state(IPConnection *ipcon);
00479 
00489 void ipcon_set_auto_reconnect(IPConnection *ipcon, bool auto_reconnect);
00490 
00496 bool ipcon_get_auto_reconnect(IPConnection *ipcon);
00497 
00506 void ipcon_set_timeout(IPConnection *ipcon, uint32_t timeout);
00507 
00513 uint32_t ipcon_get_timeout(IPConnection *ipcon);
00514 
00521 int ipcon_enumerate(IPConnection *ipcon);
00522 
00535 void ipcon_wait(IPConnection *ipcon);
00536 
00545 void ipcon_unwait(IPConnection *ipcon);
00546 
00552 void ipcon_register_callback(IPConnection *ipcon, uint8_t id,
00553                              void *callback, void *user_data);
00554 
00555 #ifdef IPCON_EXPOSE_INTERNALS
00556 
00560 int packet_header_create(PacketHeader *header, uint8_t length,
00561                          uint8_t function_id, IPConnectionPrivate *ipcon_p,
00562                          DevicePrivate *device_p);
00563 
00567 uint8_t packet_header_get_sequence_number(PacketHeader *header);
00568 
00572 void packet_header_set_sequence_number(PacketHeader *header,
00573                                        uint8_t sequence_number);
00574 
00578 uint8_t packet_header_get_response_expected(PacketHeader *header);
00579 
00583 void packet_header_set_response_expected(PacketHeader *header,
00584                                          uint8_t response_expected);
00585 
00589 uint8_t packet_header_get_error_code(PacketHeader *header);
00590 
00594 int16_t leconvert_int16_to(int16_t native);
00595 
00599 uint16_t leconvert_uint16_to(uint16_t native);
00600 
00604 int32_t leconvert_int32_to(int32_t native);
00605 
00609 uint32_t leconvert_uint32_to(uint32_t native);
00610 
00614 int64_t leconvert_int64_to(int64_t native);
00615 
00619 uint64_t leconvert_uint64_to(uint64_t native);
00620 
00624 float leconvert_float_to(float native);
00625 
00629 int16_t leconvert_int16_from(int16_t little);
00630 
00634 uint16_t leconvert_uint16_from(uint16_t little);
00635 
00639 int32_t leconvert_int32_from(int32_t little);
00640 
00644 uint32_t leconvert_uint32_from(uint32_t little);
00645 
00649 int64_t leconvert_int64_from(int64_t little);
00650 
00654 uint64_t leconvert_uint64_from(uint64_t little);
00655 
00659 float leconvert_float_from(float little);
00660 
00661 #endif // IPCON_EXPOSE_INTERNALS
00662 
00663 #ifdef __cplusplus
00664 }
00665 #endif
00666 
00667 #endif


tinkerforge_laser_transform
Author(s): M.Fischer
autogenerated on Thu Jun 6 2019 20:39:25