Friendly LWM2M client
WppClient.cpp
Go to the documentation of this file.
1 /*
2  * WppManager.cpp
3  *
4  * Created on: 20 Jul 2023
5  * Author: valentin
6  */
7 
8 #include "WppClient.h"
9 #include "WppRegistry.h"
10 #include "WppConnection.h"
11 #include "WppLogs.h"
12 #include "WppTaskQueue.h"
13 
14 namespace wpp {
15 
16 WppGuard WppClient::_clientGuard;
17 WppClient *WppClient::_client = NULL;
18 
19 WppClient::WppClient(WppConnection &connection, WppErrHandler errHandler): _connection(connection), _errHandler(errHandler) {
20  lwm2mContextOpen();
21  _registry = new WppRegistry(getContext());
22 }
23 
25  WPP_LOGI(TAG_WPP_CLIENT, "Destroying WppClient");
26  WPP_LOGI(TAG_WPP_CLIENT, "Destroying WppRegistry");
27  delete _registry;
28  _registry = NULL;
29  WPP_LOGI(TAG_WPP_CLIENT, "Clearing wpp tasks");
31  WPP_LOGI(TAG_WPP_CLIENT, "Clearing packet queue");
33  WPP_LOGI(TAG_WPP_CLIENT, "Closing lwm2m context");
34  lwm2mContextClose();
35  _client = NULL;
36 }
37 
38 /* ------------- WppClient management ------------- */
39 bool WppClient::create(const ClientInfo &info, WppConnection &connection, WppErrHandler errHandler) {
40  if (isCreated()) return true;
41 
42  WPP_LOGD(TAG_WPP_CLIENT, "Creating WppClient instance with info: endpoint->%s, msisdn->%s, altPath->%s", info.endpointName.c_str(), info.msisdn.c_str(), info.altPath.c_str());
43  _client = new WppClient(connection, errHandler);
44  bool result = _client->lwm2mConfigure(info.endpointName, info.msisdn, info.altPath);
45  if (!result) {
46  WPP_LOGE(TAG_WPP_CLIENT, "Error during client configuration");
47  delete _client;
48  _client = NULL;
49  }
50 
51  return result;
52 }
53 
55  if (!isCreated()) return;
56  WPP_LOGD(TAG_WPP_CLIENT, "Removing WppClient instance");
57  _client->giveOwnership();
58  delete _client;
59  _client = NULL;
60 }
61 
63  return _client != NULL;
64 }
65 
67  // WPP_LOGD(TAG_WPP_CLIENT, "Taking ownership of client instance");
68  if (!isCreated() || !_clientGuard.try_lock()) return NULL;
69  // WPP_LOGD(TAG_WPP_CLIENT, "Lock acquired, transferring ownership");
70  return _client;
71 }
72 
74  if (!isCreated()) return NULL;
75  // WPP_LOGD(TAG_WPP_CLIENT, "Taking ownership of client instance");
76  _clientGuard.lock();
77  // WPP_LOGD(TAG_WPP_CLIENT, "Lock acquired, transferring ownership");
78  return _client;
79 }
80 
82  // WPP_LOGD(TAG_WPP_CLIENT, "Giving ownership of client instance");
83  _clientGuard.try_lock();
84  _clientGuard.unlock();
85 }
86 
87 
88 /* ------------- WppClient components ------------- */
90  return _connection;
91 }
92 
94  return *_registry;
95 }
96 
97 /* ------------- Wakaama core state processing ------------- */
98 lwm2m_client_state_t WppClient::getState() {
99  return _lwm2m_context->state;
100 }
101 
102 lwm2m_context_t & WppClient::getContext() {
103  return *_lwm2m_context;
104 }
105 
106 time_t WppClient::loop() {
107  // Max sleep time
108  time_t sleepTimeSec = WPP_CLIENT_MAX_SLEEP_TIME_S;
109 
110  WPP_LOGD(TAG_WPP_CLIENT, "Handling server packets if they exists");
111  // Handles packets retreived from server
112  if (connection().getPacketQueueSize()) {
114  // Handle observe step after handling packets for avoid missing notifications
115  lwm2m_observe_step(_lwm2m_context);
116  }
117 
118  WPP_LOGD(TAG_WPP_CLIENT, "Handling wpp tasks if they exists");
119  // Handles Wpp tasks in the WppClient context and return next call interval
120  if (WppTaskQueue::getTaskCnt()) {
121  time_t nextTaskCallIntervalSec = WppTaskQueue::handleEachTask(*this);
122  if (nextTaskCallIntervalSec < sleepTimeSec) sleepTimeSec = nextTaskCallIntervalSec;
123  }
124 
125  // Handles wakaama core state
126  int result = lwm2m_step(_lwm2m_context, &sleepTimeSec);
127  WPP_LOGD(TAG_WPP_CLIENT, "Handling lwm2m internal state: result -> %d, state -> %d", result, getState());
128  if (result) {
129  WPP_LOGW(TAG_WPP_CLIENT, "LWM2M core step failed, error code: %d", result);
130  if (_errHandler) _errHandler(*this, result);
131  _lwm2m_context->state = STATE_INITIAL;
132  sleepTimeSec = 0;
133  }
134 
135  return sleepTimeSec;
136 }
137 
138 /* ------------- WppClient server operations ------------- */
140  WPP_LOGI(TAG_WPP_CLIENT, "Unregister with each server");
141  lwm2m_deregister(_lwm2m_context);
142 }
143 
144 #if defined(LWM2M_SUPPORT_SENML_JSON) && RES_1_23
145 bool WppClient::send(const DataLink &link) {
146  WPP_LOGD(TAG_WPP_CLIENT, "Send data to servers: object ID -> %d, instance ID -> %d, resource ID -> %d, resource instance ID -> %d",
148  lwm2m_uri_t uri = {link.instance.objId, link.instance.objInstId, link.resource.resId, link.resource.resInstId};
149  return !lwm2m_send_operation(_lwm2m_context, &uri);
150 }
151 #endif
152 
153 /* ------------- Wakaama client initialisation ------------- */
154 bool WppClient::lwm2mContextOpen() {
155  _lwm2m_context = lwm2m_init(this);
156  return _lwm2m_context != NULL;
157 }
158 
159 void WppClient::lwm2mContextClose() {
160  lwm2m_close(_lwm2m_context);
161  _lwm2m_context = NULL;
162 }
163 
164 bool WppClient::lwm2mConfigure(const std::string &endpointName, const std::string &msisdn, const std::string &altPath) {
165  lwm2m_object_t *lwm2m_major_objects[] = {&Lwm2mSecurity::object(*this).getLwm2mObject(),
167  &Device::object(*this).getLwm2mObject()};
168  uint16_t objectsCnt = sizeof(lwm2m_major_objects) / sizeof(lwm2m_object_t *);
169  const char *msisdn_c = msisdn.empty()? NULL : msisdn.c_str();
170  const char *altPath_c = altPath.empty()? NULL : altPath.c_str();
171  return !lwm2m_configure(_lwm2m_context, endpointName.c_str(), msisdn_c, altPath_c, objectsCnt, lwm2m_major_objects);
172 }
173 
174 } /* namespace wpp */
#define WPP_CLIENT_MAX_SLEEP_TIME_S
Definition: WppClient.h:20
#define TAG_WPP_CLIENT
Definition: WppLogs.h:8
#define WPP_LOGE(TAG, FMT,...)
Definition: WppLogs.h:49
#define WPP_LOGW(TAG, FMT,...)
Definition: WppLogs.h:43
#define WPP_LOGD(TAG, FMT,...)
Definition: WppLogs.h:31
#define WPP_LOGI(TAG, FMT,...)
Definition: WppLogs.h:37
static Object & object(WppClient &ctx)
Gets the Object reference.
Definition: Device.cpp:49
static Object & object(WppClient &ctx)
Gets the Object reference.
static Object & object(WppClient &ctx)
Gets the Object reference.
Definition: Lwm2mServer.cpp:48
lwm2m_object_t & getLwm2mObject()
Gets the lwm2m_object_t object.
Definition: Object.cpp:41
Represents a client interface for Wpp library.
Definition: WppClient.h:37
static WppClient * takeOwnership()
Takes ownership of the WppClient.
Definition: WppClient.cpp:66
lwm2m_context_t & getContext()
Gets the LwM2M context associated with the WppClient.
Definition: WppClient.cpp:102
void giveOwnership()
Gives up ownership of the WppClient.
Definition: WppClient.cpp:81
static void remove()
Removes the WppClient.
Definition: WppClient.cpp:54
time_t loop()
Processes the state of the Wakaama core. This function performs the necessary work by the Wakaama cor...
Definition: WppClient.cpp:106
WppConnection & connection()
Gets the WppConnection associated with the WppClient.
Definition: WppClient.cpp:89
lwm2m_client_state_t getState()
Gets the state of the Wakaama client.
Definition: WppClient.cpp:98
static bool isCreated()
Checks if the WppClient is created.
Definition: WppClient.cpp:62
static WppClient * takeOwnershipBlocking()
Takes ownership of the WppClient, blocking until it becomes available.
Definition: WppClient.cpp:73
static bool create(const ClientInfo &info, WppConnection &connection, WppErrHandler errHandler=NULL)
Creates a WppClient with the specified client information, connection, and maximum sleep time.
Definition: WppClient.cpp:39
std::function< void(WppClient &client, int errCode)> WppErrHandler
Definition: WppClient.h:49
void deregister()
Deregisters the client from the servers.
Definition: WppClient.cpp:139
WppRegistry & registry()
Gets the WppRegistry associated with the WppClient.
Definition: WppClient.cpp:93
void clearPacketQueue()
Clears the packet queue.
void handlePacketsInQueue(WppClient &client)
Processes the packets in the packet queue.
The WppGuard class provides a linker callback class that must be implemented by the user.
Definition: WppGuard.h:14
bool try_lock()
Tries to lock the guard object.
void unlock()
Unlocks the guard object.
void lock()
Locks the guard object.
The WppRegistry class represents a registry for managing LWM2M objects.
Definition: WppRegistry.h:53
static time_t handleEachTask(WppClient &client)
Execute each task in the queue and delete it from queue if task returns false or task state is SHOULD...
static size_t getTaskCnt()
Returns count of tasks in the queue. Tasks count does not immediately updated after request to remove...
static void hardReset()
Blocks task handling, calls of other methods, and deletes all tasks from the queue,...
The WppConnection class represents a connection interface for the Wpp library.
Definition: WppClient.cpp:14
Represents the information required to create a WppClient.
Definition: WppClient.h:43
std::string endpointName
Definition: WppClient.h:44