-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathAction.hpp
234 lines (210 loc) · 9.31 KB
/
Action.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
/**
* @file Action.hpp
* @brief Action Base class and related definitions for IoT Client
*
* Defines a base class to be used by all Actions that can be run by the
* IoT Client. Also contains definitions for related Action types like
* ActionType, ActionState and ActionData
*/
#pragma once
#include <string>
#include <iostream>
#include <memory>
#include <atomic>
#include "util/Utf8String.hpp"
#include "util/threading/ThreadTask.hpp"
#include "ResponseCode.hpp"
#include "NetworkConnection.hpp"
#define DEFAULT_NETWORK_ACTION_THREAD_SLEEP_DURATION_MS 100
namespace awsiotsdk {
/**
* @brief ActionType Enum Class
*
* Defines a strongly typed enum which specifies different Action Types.
* Actions can be registered in the core client for each of these Types.
*/
enum class ActionType {
RESERVED_ACTION = 0,
CORE_PROCESS_INBOUND = 1,
CORE_PROCESS_OUTBOUND = 2,
CONNECT = 3,
DISCONNECT = 4,
PUBLISH = 5,
PUBACK = 6,
PUBREC = 7,
PUBREL = 8,
PUBCOMP = 9,
SUBSCRIBE = 10,
READ_INCOMING = 11,
KEEP_ALIVE = 12,
PUBLISH_INBOUND = 13,
UNSUBSCRIBE = 14,
RECONNECT = 15,
GREENGRASS_DISCOVER = 16
};
/**
* @brief Action State Class
*
* Defines an Action State class which is retained by each Action for its lifetime
* This is a pure virtual class, cannot be instantiated
*/
class ActionState {
public:
/**
* @brief Get Action ID of the next Action
*
* @return uint16_t Next Action ID
*/
virtual uint16_t GetNextActionId() = 0;
// Rule of 5 stuff
// Keeping defaults, explicitly mentioned to avoid conflicts with future C++ specifications
// Must always be able to copy and move
ActionState() = default; // Default constructor
ActionState(const ActionState &) = delete; // Copy constructor
ActionState(ActionState &&) = delete; // Move constructor
ActionState &operator=(const ActionState &) & = delete; // Copy assignment operator
ActionState &operator=(ActionState &&) & = delete; // Move assignment operator
virtual ~ActionState() = default; // Default destructor
};
/**
* @brief Action Data Class
*
* Defines an Action Data class which contains dynamic information to be used by the action
* Instance of concrete implementation of this class is passed as argument each time Perform Action is called
* This is a pure virtual class, cannot be instantiated
*/
class ActionData {
public:
/**
* Define a type for the Async Ack notification handler
* Clients can provide an instance of this to receive notification on status of Async API calls
*/
typedef std::function<void(uint16_t action_id, ResponseCode rc)> AsyncAckNotificationHandlerPtr;
// Rule of 5 stuff
// Since virtual destructor is present, derived classes will have to explicitly define defaults
// Must always be able to copy and move
ActionData() = default; // Default constructor
ActionData(const ActionData &) = default; // Copy constructor
ActionData(ActionData &&) = default; // Move constructor
ActionData &operator=(const ActionData &) & = default; // Copy assignment operator
ActionData &operator=(ActionData &&) & = default; // Move assignment operator
virtual ~ActionData() = default; // Default destructor
AsyncAckNotificationHandlerPtr p_async_ack_handler_; ///< Handler to call when response is received for this action
/**
* @brief Get ID of the current run of this Action
* @return uint16_t - Action ID
*/
virtual uint16_t GetActionId() = 0;
/**
* @brief Set the Action ID for this run of the Action
*
* @param action_id - new Action ID
*/
virtual void SetActionId(uint16_t action_id) = 0;
};
/**
* @brief Action Class
*
* Defines a base class for SDK Actions. Provides basic template for concrete implementations.
* Also includes code for Thread sync with client core.
* All Actions that can be performed by the Client Core must inherit from this class.
* This is a pure virtual class and cannot be instantiated
*
*/
class Action {
public:
/**
* Define a type for Create Factory method. Takes Action state as argument and returns a unique_ptr to a new
* action instance
*/
typedef std::function<std::unique_ptr<Action>(std::shared_ptr<ActionState> p_action_state)> CreateHandlerPtr;
/**
* @brief Get Type of this Action
* @return ActionType
*/
ActionType GetActionType() {
return action_type_;
}
/**
* @brief Get information/description about the current action
*
* Gets runtime information about the currently running Action if it was set when the action was created
*
* @return String containing Info Text
*/
util::String GetActionInfo() {
return action_info_string_;
}
/**
* @brief Sets the parent thread sync variable
*
* @param p_thread_continue - Pointer to the new sync variable to use
*/
void SetParentThreadSync(std::shared_ptr<std::atomic_bool> p_thread_continue) {
p_thread_continue_ = p_thread_continue;
}
/**
* @brief Virtual base function for Performing Action
*
* This function is called by Client Core and defines how the Action is Performed.
* This is a pure virtual function. Inherited classes MUST implement this.
*
* @param p_network_connection - Network connection to be used to perform the Action
* @param p_action_data - Action data to be used for this run of the action
* @return ResponseCode indicating result of the API call
*/
virtual ResponseCode PerformAction(std::shared_ptr<NetworkConnection> p_network_connection,
std::shared_ptr<ActionData> p_action_data) = 0;
// Rule of 5 stuff
// Disabling default, move and copy constructors
// Actions instances can be run as threads if needed and should not be copied or moved
Action() = delete; // Delete Default constructor
Action(const Action &) = delete; // Copy constructor
Action(Action &&) = delete; // Move constructor
Action &operator=(const Action &) & = delete; // Copy assignment operator
Action &operator=(Action &&) & = delete; // Move assignment operator
virtual ~Action() = default; // Default destructor
/**
* @brief Action Constructor
*
* @param action_type - Type fo the Action being instantiated
* @param action_info_string - Info string describing the action
*/
Action(ActionType action_type, util::String action_info_string);
protected:
ActionType action_type_; ///< Type of the action
util::String action_info_string_; ///< Info string
std::shared_ptr<std::atomic_bool> p_thread_continue_; ///< Shared atomic variable used for sync when action is run in separate thread
/**
* @brief Generic Network Read function for all actions
* @param p_network_connection - Network connection to be used to perform Read
* @param read_buf - Buffer read data should be copied to. Assumed to already have enough memory reserved
* @param bytes_to_read - Number of bytes to read
* @return ResponeCode indicating result of the API call
*/
ResponseCode ReadFromNetworkBuffer(std::shared_ptr<NetworkConnection> p_network_connection,
util::Vector<unsigned char> &read_buf, size_t bytes_to_read);
/**
* @brief Generic Network Write function for all actions
* @param p_network_connection - Network connection to be used to perform Write
* @param read_buf - Buffer containing data to be written to the network instance
* @return ResponeCode indicating result of the API call
*/
ResponseCode WriteToNetworkBuffer(std::shared_ptr<NetworkConnection> p_network_connection,
const util::String &write_buf);
};
}