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"
39 * Logging tag for module name.
41 #define RA_ADAPTER_TAG "RA_ADAP"
44 * Network Packet Received Callback to CA.
46 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
49 * Network Changed Callback to CA.
51 static CANetworkChangeCallback g_networkChangeCallback = NULL;
54 * Holds XMPP data information.
58 xmpp_context_t context;
60 xmpp_connection_callback_t connection_callback;
61 xmpp_connection_handle_t connection_handle;
62 xmpp_message_context_t message_context;
63 xmpp_message_callback_t message_callback;
64 CANetworkStatus_t connection_status;
66 xmpp_identity_t g_identity;
67 char jabberID[CA_RAJABBERID_SIZE];
70 static ca_mutex g_raadapterMutex = NULL;
72 static CARAXmppData_t g_xmppData = {};
74 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
76 static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
77 const char *const bound_jid,
78 xmpp_connection_handle_t connection);
80 static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
81 xmpp_connection_handle_t connection);
83 static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
84 const void *const recipient, const void *const msg, size_t messageOctets);
86 static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
87 const void *const sender, const void *const msg, size_t messageOctets);
89 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
91 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
93 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
94 CA_ADAPTER_REMOTE_ACCESS,
98 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
101 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
102 if (networkChangeCallback)
104 networkChangeCallback(localEndpoint, status);
108 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
111 CAFreeEndpoint(localEndpoint);
113 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
116 void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
117 const char *const bound_jid,
118 xmpp_connection_handle_t connection)
120 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
121 CANetworkStatus_t connection_status;
122 if (XMPP_ERR_OK == result)
124 printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
126 ca_mutex_lock (g_raadapterMutex);
127 OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
129 g_xmppData.connection_status = CA_INTERFACE_UP;
130 connection_status = CA_INTERFACE_UP;
131 g_xmppData.connection_handle = connection;
132 g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
133 g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
134 g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
135 g_xmppData.message_callback);
139 g_xmppData.connection_status = CA_INTERFACE_DOWN;
140 connection_status = CA_INTERFACE_DOWN;
141 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
144 ca_mutex_unlock (g_raadapterMutex);
145 // Notify network change to CA
146 CARANotifyNetworkChange(bound_jid, connection_status);
148 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
151 void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
152 xmpp_connection_handle_t connection)
154 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
155 char jabberID[CA_RAJABBERID_SIZE];
156 ca_mutex_lock (g_raadapterMutex);
158 g_xmppData.connection_status = CA_INTERFACE_DOWN;
159 xmpp_message_context_destroy(g_xmppData.message_context);
160 OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
162 ca_mutex_unlock (g_raadapterMutex);
164 // Notify network change to CA
165 CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
167 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
170 void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
171 const void *const recipient, const void *const msg, size_t messageOctets)
173 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
177 void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
178 const void *const sender, const void *const msg, size_t messageOctets)
180 if (g_networkPacketCallback)
182 VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
183 VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
185 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
186 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
188 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
189 CA_ADAPTER_REMOTE_ACCESS, sender, 0);
192 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
196 void *buf = OICMalloc(messageOctets);
199 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
200 CAFreeEndpoint(endPoint);
203 memcpy(buf, msg, messageOctets);
204 CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
205 if (networkPacketCallback)
207 g_networkPacketCallback(endPoint, buf, messageOctets);
210 CAFreeEndpoint (endPoint);
214 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
218 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
219 CANetworkPacketReceivedCallback networkPacketCallback,
220 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
222 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
223 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
225 return CA_STATUS_INVALID_PARAM;
228 g_networkChangeCallback = netCallback;
229 g_networkPacketCallback = networkPacketCallback;
231 CAConnectivityHandler_t raHandler = {};
232 raHandler.startAdapter = CAStartRA;
233 raHandler.startListenServer = CAStartRAListeningServer;
234 raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
235 raHandler.sendData = CASendRAUnicastData;
236 raHandler.sendDataToAll = CASendRAMulticastData;
237 raHandler.GetnetInfo = CAGetRAInterfaceInformation;
238 raHandler.readData = CAReadRAData;
239 raHandler.stopAdapter = CAStopRA;
240 raHandler.terminate = CATerminateRA;
241 registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
246 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
250 return CA_STATUS_INVALID_PARAM;
252 xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
253 caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
254 xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
255 caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
264 CAResult_t CAStartRA()
266 if (g_xmppData.handle.abstract_handle)
268 OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
272 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
274 g_raadapterMutex = ca_mutex_new ();
275 if (!g_raadapterMutex)
277 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
278 return CA_MEMORY_ALLOC_FAILED;
281 ca_mutex_lock (g_raadapterMutex);
283 xmpp_context_init(&g_xmppData.context);
284 g_xmppData.handle = xmpp_startup(&g_xmppData.context);
286 // Wire up connection callbacks and call API to connect to XMPP server
287 g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
288 g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
290 xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
291 &g_xmppData.g_identity, g_xmppData.connection_callback);
293 // Destroy host and identity structures as they are only
294 // required to establish initial connection
295 xmpp_identity_destroy(&g_xmppData.g_identity);
296 xmpp_host_destroy(&g_xmppData.g_host);
298 ca_mutex_unlock (g_raadapterMutex);
300 if (XMPP_ERR_OK != ret)
302 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
304 return CA_STATUS_FAILED;
307 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
311 CAResult_t CAStopRA()
313 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
315 xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
316 if (XMPP_ERR_OK != ret)
318 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
320 return CA_STATUS_FAILED;
323 xmpp_shutdown_xmpp(g_xmppData.handle);
324 xmpp_context_destroy(&g_xmppData.context);
325 ca_mutex_free (g_raadapterMutex);
326 g_raadapterMutex = NULL;
328 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
332 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
335 if (!remoteEndpoint || !data)
337 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
343 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
347 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
348 ca_mutex_lock (g_raadapterMutex);
350 if (CA_INTERFACE_UP != g_xmppData.connection_status)
352 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
353 ca_mutex_unlock (g_raadapterMutex);
357 xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
358 remoteEndpoint->addr, data, dataLength,
359 XMPP_MESSAGE_TRANSMIT_DEFAULT);
360 if (XMPP_ERR_OK != res)
362 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
363 ca_mutex_unlock (g_raadapterMutex);
366 ca_mutex_unlock (g_raadapterMutex);
368 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
369 dataLength, remoteEndpoint->addr);
374 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
376 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
377 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
379 ca_mutex_lock (g_raadapterMutex);
381 if (CA_INTERFACE_UP != g_xmppData.connection_status)
383 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
384 ca_mutex_unlock (g_raadapterMutex);
385 return CA_ADAPTER_NOT_ENABLED;
388 ca_mutex_unlock (g_raadapterMutex);
390 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
391 CA_ADAPTER_REMOTE_ACCESS,
392 g_xmppData.jabberID, 0);
395 *info = localEndpoint;
400 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
401 const void *data, uint32_t dataLength)
403 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
407 CAResult_t CAStartRAListeningServer()
409 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
410 return CA_NOT_SUPPORTED;
413 CAResult_t CAStartRADiscoveryServer()
415 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
416 return CA_NOT_SUPPORTED;
419 CAResult_t CAReadRAData()
421 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
422 return CA_NOT_SUPPORTED;