1 /******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 ******************************************************************/
21 #include "caraadapter.h"
28 #include "caadapterutils.h"
30 #include "uarraylist.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
35 #include "caremotehandler.h"
40 * @brief Logging tag for module name
42 #define RA_ADAPTER_TAG "RA_ADAP"
45 * @var g_networkPacketCallback
46 * @brief Network Packet Received Callback to CA
48 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
51 * @var g_networkChangeCallback
52 * @brief Network Changed Callback to CA
54 static CANetworkChangeCallback g_networkChangeCallback = NULL;
58 * @brief Holds XMPP data information.
62 xmpp_context_t context;
64 xmpp_connection_callback_t connection_callback;
65 xmpp_connection_handle_t connection_handle;
66 xmpp_message_context_t message_context;
67 xmpp_message_callback_t message_callback;
68 CANetworkStatus_t connection_status;
70 xmpp_identity_t g_identity;
71 char jabberID[CA_RAJABBERID_SIZE];
74 static ca_mutex g_raadapterMutex = NULL;
76 static CARAXmppData_t g_xmppData = {};
78 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
80 static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
81 const char *const bound_jid,
82 xmpp_connection_handle_t connection);
84 static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
85 xmpp_connection_handle_t connection);
87 static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
88 const void *const recipient, const void *const msg, size_t messageOctets);
90 static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
91 const void *const sender, const void *const msg, size_t messageOctets);
93 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
95 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
97 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
98 CA_ADAPTER_REMOTE_ACCESS,
102 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
105 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
106 if (networkChangeCallback)
108 networkChangeCallback(localEndpoint, status);
112 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
115 CAFreeEndpoint(localEndpoint);
117 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
120 void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
121 const char *const bound_jid,
122 xmpp_connection_handle_t connection)
124 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
125 CANetworkStatus_t connection_status;
126 if (XMPP_ERR_OK == result)
128 printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
130 ca_mutex_lock (g_raadapterMutex);
131 OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
133 g_xmppData.connection_status = CA_INTERFACE_UP;
134 connection_status = CA_INTERFACE_UP;
135 g_xmppData.connection_handle = connection;
136 g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
137 g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
138 g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
139 g_xmppData.message_callback);
143 g_xmppData.connection_status = CA_INTERFACE_DOWN;
144 connection_status = CA_INTERFACE_DOWN;
145 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
148 ca_mutex_unlock (g_raadapterMutex);
149 // Notify network change to CA
150 CARANotifyNetworkChange(bound_jid, connection_status);
152 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
155 void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
156 xmpp_connection_handle_t connection)
158 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
159 char jabberID[CA_RAJABBERID_SIZE];
160 ca_mutex_lock (g_raadapterMutex);
162 g_xmppData.connection_status = CA_INTERFACE_DOWN;
163 xmpp_message_context_destroy(g_xmppData.message_context);
164 OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
166 ca_mutex_unlock (g_raadapterMutex);
168 // Notify network change to CA
169 CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
171 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
174 void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
175 const void *const recipient, const void *const msg, size_t messageOctets)
177 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
181 void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
182 const void *const sender, const void *const msg, size_t messageOctets)
184 if (g_networkPacketCallback)
186 VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
187 VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
189 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
190 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
192 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
193 CA_ADAPTER_REMOTE_ACCESS, sender, 0);
196 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
200 void *buf = OICMalloc(messageOctets);
203 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
204 CAFreeEndpoint(endPoint);
207 memcpy(buf, msg, messageOctets);
208 CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
209 if (networkPacketCallback)
211 g_networkPacketCallback(endPoint, buf, messageOctets);
214 CAFreeEndpoint (endPoint);
218 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
222 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
223 CANetworkPacketReceivedCallback networkPacketCallback,
224 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
226 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
227 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
229 return CA_STATUS_INVALID_PARAM;
232 g_networkChangeCallback = netCallback;
233 g_networkPacketCallback = networkPacketCallback;
235 CAConnectivityHandler_t raHandler = {};
236 raHandler.startAdapter = CAStartRA;
237 raHandler.startListenServer = CAStartRAListeningServer;
238 raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
239 raHandler.sendData = CASendRAUnicastData;
240 raHandler.sendDataToAll = CASendRAMulticastData;
241 raHandler.GetnetInfo = CAGetRAInterfaceInformation;
242 raHandler.readData = CAReadRAData;
243 raHandler.stopAdapter = CAStopRA;
244 raHandler.terminate = CATerminateRA;
245 registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
250 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
254 return CA_STATUS_INVALID_PARAM;
256 xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
257 caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
258 xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
259 caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
268 CAResult_t CAStartRA()
270 if (g_xmppData.handle.abstract_handle)
272 OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
276 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
278 g_raadapterMutex = ca_mutex_new ();
279 if (!g_raadapterMutex)
281 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
282 return CA_MEMORY_ALLOC_FAILED;
285 ca_mutex_lock (g_raadapterMutex);
287 xmpp_context_init(&g_xmppData.context);
288 g_xmppData.handle = xmpp_startup(&g_xmppData.context);
290 // Wire up connection callbacks and call API to connect to XMPP server
291 g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
292 g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
294 xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
295 &g_xmppData.g_identity, g_xmppData.connection_callback);
297 // Destroy host and identity structures as they are only
298 // required to establish initial connection
299 xmpp_identity_destroy(&g_xmppData.g_identity);
300 xmpp_host_destroy(&g_xmppData.g_host);
302 ca_mutex_unlock (g_raadapterMutex);
304 if (XMPP_ERR_OK != ret)
306 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
308 return CA_STATUS_FAILED;
311 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
315 CAResult_t CAStopRA()
317 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
319 xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
320 if (XMPP_ERR_OK != ret)
322 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
324 return CA_STATUS_FAILED;
327 xmpp_shutdown_xmpp(g_xmppData.handle);
328 xmpp_context_destroy(&g_xmppData.context);
329 ca_mutex_free (g_raadapterMutex);
330 g_raadapterMutex = NULL;
332 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
336 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
339 if (!remoteEndpoint || !data)
341 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
347 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
351 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
352 ca_mutex_lock (g_raadapterMutex);
354 if (CA_INTERFACE_UP != g_xmppData.connection_status)
356 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
357 ca_mutex_unlock (g_raadapterMutex);
361 xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
362 remoteEndpoint->addr, data, dataLength,
363 XMPP_MESSAGE_TRANSMIT_DEFAULT);
364 if (XMPP_ERR_OK != res)
366 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
367 ca_mutex_unlock (g_raadapterMutex);
370 ca_mutex_unlock (g_raadapterMutex);
372 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
373 dataLength, remoteEndpoint->addr);
378 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
380 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
381 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
383 ca_mutex_lock (g_raadapterMutex);
385 if (CA_INTERFACE_UP != g_xmppData.connection_status)
387 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
388 ca_mutex_unlock (g_raadapterMutex);
389 return CA_ADAPTER_NOT_ENABLED;
392 ca_mutex_unlock (g_raadapterMutex);
394 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
395 CA_ADAPTER_REMOTE_ACCESS,
396 g_xmppData.jabberID, 0);
399 *info = localEndpoint;
404 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
405 const void *data, uint32_t dataLength)
407 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
411 CAResult_t CAStartRAListeningServer()
413 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
414 return CA_NOT_SUPPORTED;
417 CAResult_t CAStartRADiscoveryServer()
419 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
420 return CA_NOT_SUPPORTED;
423 CAResult_t CAReadRAData()
425 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
426 return CA_NOT_SUPPORTED;