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"
34 #include "caremotehandler.h"
38 #include "caprotocolmessage.h"
39 #include "xmpp_helper.h"
40 #include "xmpp_utils.h"
42 #include "xmpp_utils.h"
49 * Logging tag for module name.
51 #define RA_ADAPTER_TAG "RA_ADAP_IBB"
54 * Network Packet Received Callback to CA.
56 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
59 * Network Changed Callback to CA.
61 static CANetworkChangeCallback g_networkChangeCallback = NULL;
64 * Holds XMPP data information.
66 #define RA_MAX_HOSTNAME_LENGTH 256
67 #define RA_MAX_PASSWORD_LENGTH 64
72 char hostname[RA_MAX_HOSTNAME_LENGTH];
73 char password[RA_MAX_PASSWORD_LENGTH];
74 char jid[CA_RAJABBERID_SIZE];
75 CANetworkStatus_t connection_status;
78 static ca_mutex g_raadapterMutex = NULL;
80 static CARAXmppData_t g_xmppData = {.xmpp = NULL, .port = 5222, .hostname = {0},
81 .password = {0}, .jid = {0}, .connection_status = CA_INTERFACE_DOWN};
83 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
85 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
87 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
89 g_xmppData.connection_status = status;
91 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
92 CA_ADAPTER_REMOTE_ACCESS,
96 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
99 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
100 if (networkChangeCallback)
102 networkChangeCallback(localEndpoint, status);
106 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
109 CAFreeEndpoint(localEndpoint);
111 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
114 #define MAX_IBB_SESSION_ID_LENGTH 32
116 #define OBSERVE_REGISTER 0
117 #define OBSERVE_DEREGISTER 1
120 static ilist_t * g_observerList = NULL;
122 typedef struct _obs_item_t
124 char sessid[MAX_IBB_SESSION_ID_LENGTH + 1];
128 static bool CARAFindSessID(obs_item_t *item, char *key)
130 if (item == NULL || key == NULL)
134 if (strcmp(item->sessid, key) == 0)
144 static bool CARAPDUIsRequest(uint32_t x)
146 return (x == CA_GET || x == CA_POST || x == CA_PUT || x == CA_DELETE);
149 static void CARAUpdateObsList(int option, char *sid)
151 if (option == OBSERVE_REGISTER)
153 obs_item_t *item = (obs_item_t *) OICMalloc(sizeof(*item));
154 OICStrcpy(item->sessid, sizeof(item->sessid), sid);
155 item->option = OBSERVE_REGISTER;
156 ilist_add(g_observerList, item);
158 else if (option == OBSERVE_DEREGISTER)
160 obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
163 item->option = OBSERVE_DEREGISTER;
168 static int CARAGetReqObsOption(coap_pdu_t *pdu)
170 uint32_t obsopt = -1;
172 CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICMalloc(sizeof(*reqInfo));
173 VERIFY_NON_NULL_RET(reqInfo, RA_ADAPTER_TAG, "Memory alloc of CARequestInfo_t failed!", -1);
175 CAResult_t result = CAGetRequestInfoFromPDU(pdu, reqInfo);
176 if (CA_STATUS_OK != result)
179 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Get Request Info failed!");
182 if (!CARAPDUIsRequest(reqInfo->method))
185 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "It is not a request data.");
189 uint8_t numOpt = reqInfo->info.numOptions;
190 CAHeaderOption_t *options = reqInfo->info.options;
191 for (uint8_t i = 0; i < numOpt; i++)
193 if(options[i].protocolID == CA_COAP_ID &&
194 options[i].optionID == COAP_OPTION_OBSERVE)
196 obsopt = options[i].optionData[0];
204 static int CARAErrorCB(xmpp_ibb_session_t *sess, xmpperror_t *xerr)
206 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): code(%d) tyep'%s' mesg'%s'",
207 __FUNCTION__, xerr->code, xerr->type, xerr->mesg);
211 static int CARAOpenCB(xmpp_ibb_session_t *sess, char *type)
213 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
217 static int CARACloseCB(xmpp_ibb_session_t *sess, char *type)
219 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
220 char *sid = xmpp_ibb_get_sid(sess);
221 obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
224 ilist_remove(g_observerList, item);
230 static char *CARAGetSIDFromPDU(coap_pdu_t *pdu)
232 static char s_sid[MAX_IBB_SESSION_ID_LENGTH + 1] = {0};
234 VERIFY_NON_NULL_RET(pdu, RA_ADAPTER_TAG, "Invalid parameter!", NULL);
236 if (pdu->hdr->token_length * 2 > MAX_IBB_SESSION_ID_LENGTH)
238 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Token length more than expected!");
243 for (int i = 0; i < pdu->hdr->token_length; i++)
245 snprintf(hex, 3, "%02x", pdu->hdr->token[i]);
246 OICStrcat(s_sid, sizeof(s_sid), hex);
252 static int CARARecvCB(xmpp_ibb_session_t *sess, xmppdata_t *xdata)
256 /* xdata == NULL, send ack result */
260 char *msg = xdata->data;
261 char *from = xmpp_ibb_get_remote_jid(sess);
262 if (g_networkPacketCallback)
264 VERIFY_NON_NULL_RET(from, RA_ADAPTER_TAG, "from sender is NULL", -1);
265 VERIFY_NON_NULL_RET(msg, RA_ADAPTER_TAG, "message is NULL", -1);
267 OIC_LOG_V (DEBUG, RA_ADAPTER_TAG, "Message received from %s", from);
269 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
270 CA_ADAPTER_REMOTE_ACCESS, from, 0);
273 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
276 uint32_t code = CA_NOT_FOUND;
277 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(xdata->data, xdata->size, &code);
278 char *sid = CARAGetSIDFromPDU(pdu);
279 int obsopt = CARAGetReqObsOption(pdu);
280 coap_delete_pdu(pdu);
282 if (CARAPDUIsRequest(code))
284 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a request data");
285 if (obsopt == OBSERVE_DEREGISTER || obsopt == OBSERVE_REGISTER)
287 CARAUpdateObsList(obsopt, sid);
292 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a response data");
293 obs_item_t *item = ilist_finditem_func(g_observerList, CARAFindSessID, sid);
296 if (item->option == OBSERVE_DEREGISTER)
298 xmpp_ibb_close(sess);
299 ilist_remove(g_observerList, item);
305 xmpp_ibb_close(sess);
310 xmpp_ibb_userdata_alloc(sess, &buf, xdata->size);
313 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
314 CAFreeEndpoint(endPoint);
317 memcpy(buf, xdata->data, xdata->size);
318 g_networkPacketCallback(endPoint, buf, xdata->size);
320 CAFreeEndpoint (endPoint);
324 OIC_LOG(ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
329 static int CARAConnHandler(xmpp_t *xmpp, xmppconn_info_t *conninfo, void *udata)
331 if (conninfo->connevent != 0)
333 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, " status(%d) error(%d) errorType(%d) errorText '%s'\n",
334 conninfo->connevent, conninfo->error, conninfo->errortype,
335 conninfo->errortext);
336 CARANotifyNetworkChange(g_xmppData.jid, CA_INTERFACE_DOWN);
339 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "\n\n Bound JID: '%s'\n\n\n", xmpphelper_get_bound_jid(xmpp));
340 CARANotifyNetworkChange(xmpphelper_get_bound_jid(xmpp), CA_INTERFACE_UP);
344 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
345 CANetworkPacketReceivedCallback networkPacketCallback,
346 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
348 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
349 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
351 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
352 return CA_STATUS_INVALID_PARAM;
355 g_networkChangeCallback = netCallback;
356 g_networkPacketCallback = networkPacketCallback;
358 CAConnectivityHandler_t raHandler = {
359 .startAdapter = CAStartRA,
360 .startListenServer = CAStartRAListeningServer,
361 .startDiscoveryServer = CAStartRADiscoveryServer,
362 .sendData = CASendRAUnicastData,
363 .sendDataToAll = CASendRAMulticastData,
364 .GetnetInfo = CAGetRAInterfaceInformation,
365 .readData = CAReadRAData,
366 .stopAdapter = CAStopRA,
367 .terminate = CATerminateRA};
368 registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
370 g_xmppData.xmpp = xmpphelper_new(CARAConnHandler, NULL);
371 xmpphelper_force_tls(g_xmppData.xmpp);
372 g_observerList = ilist_new();
377 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
381 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
382 return CA_STATUS_INVALID_PARAM;
384 if (caraInfo->hostname != NULL)
386 OICStrcpy(g_xmppData.hostname, sizeof(g_xmppData.hostname), caraInfo->hostname);
390 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
391 return CA_STATUS_INVALID_PARAM;
393 if (caraInfo->username != NULL && strlen(caraInfo->username) != 0)
395 OICStrcpy(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->username);
399 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
400 return CA_STATUS_INVALID_PARAM;
402 if (caraInfo->xmpp_domain != NULL && strlen(caraInfo->xmpp_domain) != 0)
404 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "@");
405 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->xmpp_domain);
406 if (caraInfo->resource != NULL && strlen(caraInfo->resource) != 0)
408 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "/");
409 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->resource);
412 if (caraInfo->password != NULL)
414 OICStrcpy(g_xmppData.password, sizeof(g_xmppData.password), caraInfo->password);
416 g_xmppData.port = caraInfo->port;
424 ilist_destroy(g_observerList);
425 xmpphelper_join(g_xmppData.xmpp);
426 xmpphelper_release(g_xmppData.xmpp);
427 g_xmppData.xmpp = NULL;
430 CAResult_t CAStartRA()
432 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
434 if (!g_xmppData.xmpp)
436 OIC_LOG (ERROR, RA_ADAPTER_TAG, "CAStartRA(): g_xmppData.xmpp == NULL");
437 return CA_STATUS_FAILED;
440 g_raadapterMutex = ca_mutex_new ();
441 if (!g_raadapterMutex)
443 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
444 return CA_MEMORY_ALLOC_FAILED;
447 ca_mutex_lock (g_raadapterMutex);
449 xmpphelper_connect(g_xmppData.xmpp, g_xmppData.hostname, g_xmppData.port,
450 g_xmppData.jid, g_xmppData.password);
451 xmpp_ibb_reg_funcs_t regfuncs;
452 regfuncs.open_cb = CARAOpenCB;
453 regfuncs.close_cb = CARACloseCB;
454 regfuncs.recv_cb = CARARecvCB;
455 regfuncs.error_cb = CARAErrorCB;
456 xmpp_ibb_register(xmpphelper_get_conn(g_xmppData.xmpp), ®funcs);
458 xmpphelper_run(g_xmppData.xmpp);
460 ca_mutex_unlock (g_raadapterMutex);
462 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
466 CAResult_t CAStopRA()
468 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
470 xmpphelper_stop(g_xmppData.xmpp);
471 xmpp_ibb_unregister(xmpphelper_get_conn(g_xmppData.xmpp));
472 if (!g_raadapterMutex)
474 ca_mutex_free (g_raadapterMutex);
475 g_raadapterMutex = NULL;
477 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
481 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
484 if (!remoteEndpoint || !data)
486 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
492 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
495 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
497 uint32_t code = CA_NOT_FOUND;
498 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(data, dataLength, &code);
499 char *sid = CARAGetSIDFromPDU(pdu);
500 int obsopt = CARAGetReqObsOption(pdu);
501 coap_delete_pdu(pdu);
503 ca_mutex_lock (g_raadapterMutex);
504 if (CA_INTERFACE_UP != g_xmppData.connection_status)
506 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
507 ca_mutex_unlock (g_raadapterMutex);
511 xmpp_ibb_session_t *sess = xmpp_ibb_get_session_by_sid(sid);
514 sess = xmpp_ibb_open(xmpphelper_get_conn(g_xmppData.xmpp), remoteEndpoint->addr, sid);
517 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB session establish failed!");
518 ca_mutex_unlock (g_raadapterMutex);
522 if (CARAPDUIsRequest(code))
524 if (obsopt == OBSERVE_REGISTER || obsopt == OBSERVE_DEREGISTER)
526 CARAUpdateObsList(obsopt, sid);
529 xmppdata_t xdata = {.data = data, .size = dataLength};
530 int rc = xmpp_ibb_send_data(sess, &xdata);
531 ca_mutex_unlock (g_raadapterMutex);
534 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB send data failed!");
538 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
539 dataLength, remoteEndpoint->addr);
544 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
546 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
547 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
551 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
552 const void *data, uint32_t dataLength)
554 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
558 CAResult_t CAStartRAListeningServer()
560 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
561 return CA_NOT_SUPPORTED;
564 CAResult_t CAStartRADiscoveryServer()
566 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
567 return CA_NOT_SUPPORTED;
570 CAResult_t CAReadRAData()
572 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
573 return CA_NOT_SUPPORTED;
576 #else /* #ifdef RA_ADAPTER_IBB */
579 * Logging tag for module name.
581 #define RA_ADAPTER_TAG "RA_ADAP"
584 * Network Packet Received Callback to CA.
586 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
589 * Network Changed Callback to CA.
591 static CANetworkChangeCallback g_networkChangeCallback = NULL;
594 * Holds XMPP data information.
598 xmpp_context_t context;
599 xmpp_handle_t handle;
600 xmpp_connection_callback_t connection_callback;
601 xmpp_connection_handle_t connection_handle;
602 xmpp_message_context_t message_context;
603 xmpp_message_callback_t message_callback;
604 CANetworkStatus_t connection_status;
606 xmpp_identity_t g_identity;
607 char jabberID[CA_RAJABBERID_SIZE];
610 static ca_mutex g_raadapterMutex = NULL;
612 static CARAXmppData_t g_xmppData = {};
614 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
616 static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
617 const char *const bound_jid,
618 xmpp_connection_handle_t connection);
620 static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
621 xmpp_connection_handle_t connection);
623 static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
624 const void *const recipient, const void *const msg, size_t messageOctets);
626 static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
627 const void *const sender, const void *const msg, size_t messageOctets);
629 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
631 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
633 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
634 CA_ADAPTER_REMOTE_ACCESS,
638 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
641 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
642 if (networkChangeCallback)
644 networkChangeCallback(localEndpoint, status);
648 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
651 CAFreeEndpoint(localEndpoint);
653 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
656 void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
657 const char *const bound_jid,
658 xmpp_connection_handle_t connection)
660 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
661 CANetworkStatus_t connection_status;
662 if (XMPP_ERR_OK == result)
664 printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
666 ca_mutex_lock (g_raadapterMutex);
667 OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
669 g_xmppData.connection_status = CA_INTERFACE_UP;
670 connection_status = CA_INTERFACE_UP;
671 g_xmppData.connection_handle = connection;
672 g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
673 g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
674 g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
675 g_xmppData.message_callback);
679 g_xmppData.connection_status = CA_INTERFACE_DOWN;
680 connection_status = CA_INTERFACE_DOWN;
681 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
684 ca_mutex_unlock (g_raadapterMutex);
685 // Notify network change to CA
686 CARANotifyNetworkChange(bound_jid, connection_status);
688 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
691 void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
692 xmpp_connection_handle_t connection)
694 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
695 char jabberID[CA_RAJABBERID_SIZE];
696 ca_mutex_lock (g_raadapterMutex);
698 g_xmppData.connection_status = CA_INTERFACE_DOWN;
699 xmpp_message_context_destroy(g_xmppData.message_context);
700 OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
702 ca_mutex_unlock (g_raadapterMutex);
704 // Notify network change to CA
705 CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
707 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
710 void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
711 const void *const recipient, const void *const msg, size_t messageOctets)
713 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
717 void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
718 const void *const sender, const void *const msg, size_t messageOctets)
720 if (g_networkPacketCallback)
722 VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
723 VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
725 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
726 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
728 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
729 CA_ADAPTER_REMOTE_ACCESS, sender, 0);
732 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
736 void *buf = OICMalloc(messageOctets);
739 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
740 CAFreeEndpoint(endPoint);
743 memcpy(buf, msg, messageOctets);
744 CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
745 if (networkPacketCallback)
747 g_networkPacketCallback(endPoint, buf, messageOctets);
750 CAFreeEndpoint (endPoint);
754 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
758 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
759 CANetworkPacketReceivedCallback networkPacketCallback,
760 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
762 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
763 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
765 return CA_STATUS_INVALID_PARAM;
768 g_networkChangeCallback = netCallback;
769 g_networkPacketCallback = networkPacketCallback;
771 CAConnectivityHandler_t raHandler = {};
772 raHandler.startAdapter = CAStartRA;
773 raHandler.startListenServer = CAStartRAListeningServer;
774 raHandler.startDiscoveryServer = CAStartRADiscoveryServer;
775 raHandler.sendData = CASendRAUnicastData;
776 raHandler.sendDataToAll = CASendRAMulticastData;
777 raHandler.GetnetInfo = CAGetRAInterfaceInformation;
778 raHandler.readData = CAReadRAData;
779 raHandler.stopAdapter = CAStopRA;
780 raHandler.terminate = CATerminateRA;
781 registerCallback(raHandler, CA_ADAPTER_REMOTE_ACCESS);
786 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
790 return CA_STATUS_INVALID_PARAM;
792 xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
793 caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
794 xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
795 caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
804 CAResult_t CAStartRA()
806 if (g_xmppData.handle.abstract_handle)
808 OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
812 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
814 g_raadapterMutex = ca_mutex_new ();
815 if (!g_raadapterMutex)
817 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
818 return CA_MEMORY_ALLOC_FAILED;
821 ca_mutex_lock (g_raadapterMutex);
823 xmpp_context_init(&g_xmppData.context);
824 g_xmppData.handle = xmpp_startup(&g_xmppData.context);
826 // Wire up connection callbacks and call API to connect to XMPP server
827 g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
828 g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
830 xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
831 &g_xmppData.g_identity, g_xmppData.connection_callback);
833 // Destroy host and identity structures as they are only
834 // required to establish initial connection
835 xmpp_identity_destroy(&g_xmppData.g_identity);
836 xmpp_host_destroy(&g_xmppData.g_host);
838 ca_mutex_unlock (g_raadapterMutex);
840 if (XMPP_ERR_OK != ret)
842 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
844 return CA_STATUS_FAILED;
847 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
851 CAResult_t CAStopRA()
853 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
855 xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
856 if (XMPP_ERR_OK != ret)
858 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
860 return CA_STATUS_FAILED;
863 xmpp_shutdown_xmpp(g_xmppData.handle);
864 xmpp_context_destroy(&g_xmppData.context);
865 ca_mutex_free (g_raadapterMutex);
866 g_raadapterMutex = NULL;
868 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
872 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
875 if (!remoteEndpoint || !data)
877 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
883 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
887 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
888 ca_mutex_lock (g_raadapterMutex);
890 if (CA_INTERFACE_UP != g_xmppData.connection_status)
892 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
893 ca_mutex_unlock (g_raadapterMutex);
897 xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
898 remoteEndpoint->addr, data, dataLength,
899 XMPP_MESSAGE_TRANSMIT_DEFAULT);
900 if (XMPP_ERR_OK != res)
902 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
903 ca_mutex_unlock (g_raadapterMutex);
906 ca_mutex_unlock (g_raadapterMutex);
908 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
909 dataLength, remoteEndpoint->addr);
914 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
916 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
917 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
919 ca_mutex_lock (g_raadapterMutex);
921 if (CA_INTERFACE_UP != g_xmppData.connection_status)
923 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
924 ca_mutex_unlock (g_raadapterMutex);
925 return CA_ADAPTER_NOT_ENABLED;
928 ca_mutex_unlock (g_raadapterMutex);
930 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
931 CA_ADAPTER_REMOTE_ACCESS,
932 g_xmppData.jabberID, 0);
935 *info = localEndpoint;
940 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
941 const void *data, uint32_t dataLength)
943 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
947 CAResult_t CAStartRAListeningServer()
949 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
950 return CA_NOT_SUPPORTED;
953 CAResult_t CAStartRADiscoveryServer()
955 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
956 return CA_NOT_SUPPORTED;
959 CAResult_t CAReadRAData()
961 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
962 return CA_NOT_SUPPORTED;