Example
Dependencies: FXAS21002 FXOS8700Q
Diff: simple-mbed-cloud-client/mbed-cloud-client/mbed-client/source/include/m2mcallbackstorage.h
- Revision:
- 0:11cc2b7889af
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple-mbed-cloud-client/mbed-cloud-client/mbed-client/source/include/m2mcallbackstorage.h Tue Nov 19 09:49:38 2019 +0000 @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2017 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * 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. + */ +#ifndef __M2M_CALLBACK_STORAGE_H__ +#define __M2M_CALLBACK_STORAGE_H__ + +#include "mbed-client/m2mvector.h" + +class M2MBase; +class M2MCallbackAssociation; +class M2MCallbackStorage; + +typedef m2m::Vector<M2MCallbackAssociation> M2MCallbackAssociationList; + +// XXX: this should not be visible for client code +class M2MCallbackAssociation +{ +public: + + // Types of callbacks stored as "void*" in the _callback variable. + // Note: the FPn<> -types are actually stored as pointers to object instances, + // which needs to be handled externally when fetching and deleting the callbacks. + enum M2MCallbackType { + // typedef FP1<void, const char*> value_updated_callback; + M2MBaseValueUpdatedCallback, + + // typedef void(*value_updated_callback2) (const char* object_name); + M2MBaseValueUpdatedCallback2, + + // typedef FP1<void,void*> execute_callback; + M2MResourceInstanceExecuteCallback, + + //typedef void(*execute_callback_2) (void *arguments); + M2MResourceInstanceExecuteCallback2, + + // typedef FP1<void, M2MBlockMessage *> incoming_block_message_callback; + M2MResourceInstanceIncomingBlockMessageCallback, + + // typedef FP3<void, const String &, uint8_t *&, uint32_t &> outgoing_block_message_callback; + M2MResourceInstanceOutgoingBlockMessageCallback, + + // class M2MResourceCallback + M2MResourceInstanceM2MResourceCallback, + + // typedef FP0<void> notification_sent_callback; + M2MResourceInstanceNotificationSentCallback, + + // typedef void(*notification_sent_callback_2) (void); + M2MResourceInstanceNotificationSentCallback2, + + // typedef FP2<void, const uint16_t, const M2MResourceBase::NotificationStatus> notification_status_callback; + M2MResourceInstanceNotificationStatusCallback, + + // typedef void(*notification_status_callback_2) (const uint16_t msg_id, const M2MResourceBase::NotificationStatus status); + M2MResourceInstanceNotificationStatusCallback2, + + // typedef void(*notification_delivery_status_cb) (const M2MBase& base, + // const M2MBase::NotificationDeliveryStatus status, void *client_args); + M2MBaseNotificationDeliveryStatusCallback, + + //typedef void(*message_delivery_status_cb) (const M2MBase& base, + // const MessageDeliveryStatus status, + // const MessageType type, + // void *client_args); + M2MBaseMessageDeliveryStatusCallback, + + // typedef void(*value_set_callback) (const M2MResourceBase *resource, + // uint8_t *value, const uint32_t value_length); + M2MResourceBaseValueSetCallback, + + // typedef size_t(*read_resource_value_callback) (const M2MResourceBase& resource, + // void *buffer, void *client_args); + M2MResourceBaseValueReadCallback, + + // typedef bool(*write_resource_value_callback) (const M2MResourceBase& resource, + // const uint8_t *buffer, const size_t buffer_size, void *client_args); + M2MResourceBaseValueWriteCallback + +#ifdef ENABLE_ASYNC_REST_RESPONSE + // typedef bool(*handle_async_coap_request_cb) (const M2MBase& base, + // M2MBase::Operation operation, const uint8_t *token, const uint8_t token_len, + // const uint8_t *buffer, size_t buffer_size, void *client_args); + ,M2MBaseAsyncCoapRequestCallback +#endif // ENABLE_ASYNC_REST_RESPONSE + }; + + /** + * Dummy constructor which does not initialize any predictable value to members, + * needed for array instantiation. Please use the parameterized constructor for real work. + */ + M2MCallbackAssociation(); + + M2MCallbackAssociation(const M2MBase *object, void *callback, M2MCallbackType type, void *client_args); + +public: + /** Object, where the callback is associated to. This is used as key on searches, must not be null. */ + const M2MBase *_object; + + /** + * Callback pointer, actual data type of the is dependent of _type. + * + * We could also use eg. a union with specific pointer types to avoid ugly casts, but that would + * then require a type-specific get_callback_<type>() to avoid casts on caller side too - unless + * the get_callback() would return this object and the caller would access the union._callback_<type> + * variable according to the _type. + */ + void *_callback; + + /** Type of the data _callback points to and needed for interpreting the data in it. */ + M2MCallbackType _type; + + void *_client_args; +}; + + +class M2MCallbackStorage +{ +public: + + ~M2MCallbackStorage(); + + // get the shared instance of the storage. + // TODO: tie this' instance to the nsdlinterface or similar class instead, as it would help + // to manage the lifecycle of the object. This would also remove the need for these static methods. + static M2MCallbackStorage *get_instance(); + + // utility for deleting the singleton instance, used on unit test and on application exit + static void delete_instance(); + + static bool add_callback(const M2MBase &object, + void *callback, + M2MCallbackAssociation::M2MCallbackType type, + void *client_args = 0); + + // remove all callbacks attached for given object + static void remove_callbacks(const M2MBase &object); + + // remove callback if one exists, return old value of it + static void* remove_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type); + + // XXX: needed for protecting the vector during iteration, but that would add a dependency on PAL here + // void lock(); + // void release(); + + // XXX: const_iterator would be nicer + //int get_callback(const M2MBase &object, void &*callback, M2MCallbackType type); + + static bool does_callback_exist(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type); + + static void* get_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type); + + static M2MCallbackAssociation* get_association_item(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type); + // XXX: this is actually not needed unless the client has multiple callbacks per object and type. + inline const M2MCallbackAssociationList& get_callbacks() const; + +private: + bool does_callback_exist(const M2MBase &object, void *callback, M2MCallbackAssociation::M2MCallbackType type) const; + void do_remove_callbacks(const M2MBase &object); + void* do_remove_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type); + bool do_add_callback(const M2MBase &object, void *callback, M2MCallbackAssociation::M2MCallbackType type, void *client_args); + void* do_get_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) const; + + M2MCallbackAssociation* do_get_association_item(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) const; + +private: + + /** + * Currently there is only one storage object, which is shared between all the interfaces and + * M2M objects. + */ + static M2MCallbackStorage *_static_instance; + + /** + * Callback objects stored. There combination of <object>+<type> is used on searches and + * the code does not fully support for adding multiple callbacks for <object>+<type> -pair. + * But that should not be too hard if the feature was added to M2M object API too, it just + * requires the M2M objects to iterate through the callbacks associated to it, not just call + * the get_callback(<object>,<type>) and call the first one. + */ + M2MCallbackAssociationList _callbacks; +}; + +inline const M2MCallbackAssociationList& M2MCallbackStorage::get_callbacks() const +{ + return _callbacks; +} + +#endif // !__M2M_CALLBACK_STORAGE_H__