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"
48 #define SET_BUT_NOT_USED(x) (void) x
50 * Logging tag for module name.
52 #define RA_ADAPTER_TAG "OIC_RA_ADAP_IBB"
55 * Network Packet Received Callback to CA.
57 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
60 * Network Changed Callback to CA.
62 static CAAdapterChangeCallback g_networkChangeCallback = NULL;
65 * Holds XMPP data information.
67 #define RA_MAX_HOSTNAME_LENGTH 256
68 #define RA_MAX_PASSWORD_LENGTH 64
73 char hostName[RA_MAX_HOSTNAME_LENGTH];
74 char password[RA_MAX_PASSWORD_LENGTH];
75 char jid[CA_RAJABBERID_SIZE];
76 CANetworkStatus_t connectionStatus;
77 CAJidBoundCallback jidBoundCallback;
80 static oc_mutex g_raadapterMutex = NULL;
82 static CARAXmppData_t g_xmppData = {.xmpp = NULL, .port = 5222, .hostName = {0},
83 .password = {0}, .jid = {0}, .connectionStatus = CA_INTERFACE_DOWN,
84 .jidBoundCallback = NULL};
86 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
88 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
90 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
92 g_xmppData.connectionStatus = status;
94 CAAdapterChangeCallback networkChangeCallback = g_networkChangeCallback;
95 if (networkChangeCallback)
97 networkChangeCallback(CA_ADAPTER_REMOTE_ACCESS, status);
101 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
104 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
107 #define MAX_IBB_SESSION_ID_LENGTH 32
109 #define OBSERVE_REGISTER 0
110 #define OBSERVE_DEREGISTER 1
113 static ilist_t * g_observerList = NULL;
115 typedef struct _obs_item_t
117 char sessid[MAX_IBB_SESSION_ID_LENGTH + 1];
121 static bool CARAFindSessID(obs_item_t *item, char *key)
123 if (item == NULL || key == NULL)
127 if (strcmp(item->sessid, key) == 0)
137 static bool CARAPDUIsRequest(uint32_t x)
139 return (x == CA_GET || x == CA_POST || x == CA_PUT || x == CA_DELETE);
142 static void CARAUpdateObsList(int option, char *sid)
144 if (option == OBSERVE_REGISTER)
146 obs_item_t *item = (obs_item_t *) OICMalloc(sizeof(*item));
147 OICStrcpy(item->sessid, sizeof(item->sessid), sid);
148 item->option = OBSERVE_REGISTER;
149 ilist_add(g_observerList, item);
151 else if (option == OBSERVE_DEREGISTER)
153 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
156 item->option = OBSERVE_DEREGISTER;
161 static int CARAGetReqObsOption(coap_pdu_t *pdu, const CAEndpoint_t *endPoint)
163 uint32_t obsopt = -1;
165 CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICMalloc(sizeof(*reqInfo));
166 VERIFY_NON_NULL_RET(reqInfo, RA_ADAPTER_TAG, "Memory alloc of CARequestInfo_t failed!", -1);
168 CAResult_t result = CAGetRequestInfoFromPDU(pdu, endPoint, reqInfo);
169 if (CA_STATUS_OK != result)
172 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Get Request Info failed!");
175 if (!CARAPDUIsRequest(reqInfo->method))
178 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "It is not a request data.");
182 uint8_t numOpt = reqInfo->info.numOptions;
183 CAHeaderOption_t *options = reqInfo->info.options;
184 for (uint8_t i = 0; i < numOpt; i++)
186 if(options[i].protocolID == CA_COAP_ID &&
187 options[i].optionID == COAP_OPTION_OBSERVE)
189 obsopt = options[i].optionData[0];
197 static int CARAErrorCB(xmpp_ibb_session_t *sess, xmpperror_t *xerr)
199 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "%s(): code(%d) tyep'%s' mesg'%s'",
200 __FUNCTION__, xerr->code, xerr->type, xerr->mesg);
201 SET_BUT_NOT_USED(sess);
202 SET_BUT_NOT_USED(xerr);
206 static int CARAOpenCB(xmpp_ibb_session_t *sess, char *type)
208 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
209 SET_BUT_NOT_USED(sess);
210 SET_BUT_NOT_USED(type);
214 static int CARACloseCB(xmpp_ibb_session_t *sess, char *type)
216 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
217 char *sid = xmpp_ibb_get_sid(sess);
218 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
221 ilist_remove(g_observerList, item);
224 SET_BUT_NOT_USED(type);
228 static char *CARAGetSIDFromPDU(coap_pdu_t *pdu)
230 static char s_sid[MAX_IBB_SESSION_ID_LENGTH + 1] = {0};
232 VERIFY_NON_NULL_RET(pdu, RA_ADAPTER_TAG, "Invalid parameter!", NULL);
234 if (pdu->hdr->token_length * 2 > MAX_IBB_SESSION_ID_LENGTH)
236 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Token length more than expected!");
241 for (int i = 0; i < pdu->hdr->token_length; i++)
243 snprintf(hex, 3, "%02x", pdu->hdr->token[i]);
244 OICStrcat(s_sid, sizeof(s_sid), hex);
250 static int CARARecvCB(xmpp_ibb_session_t *sess, xmppdata_t *xdata)
254 /* xdata == NULL, send ack result */
258 char *msg = xdata->data;
259 char *from = xmpp_ibb_get_remote_jid(sess);
260 if (g_networkPacketCallback)
262 VERIFY_NON_NULL_RET(from, RA_ADAPTER_TAG, "from sender is NULL", -1);
263 VERIFY_NON_NULL_RET(msg, RA_ADAPTER_TAG, "message is NULL", -1);
265 OIC_LOG_V (DEBUG, RA_ADAPTER_TAG, "Message received from %s", from);
267 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
268 CA_ADAPTER_REMOTE_ACCESS, from, 0);
271 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
274 uint32_t code = CA_NOT_FOUND;
275 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(xdata->data, xdata->size, &code,
277 char *sid = CARAGetSIDFromPDU(pdu);
278 int obsopt = CARAGetReqObsOption(pdu, endPoint);
279 coap_delete_pdu(pdu);
281 if (CARAPDUIsRequest(code))
283 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a request data");
284 if (obsopt == OBSERVE_DEREGISTER || obsopt == OBSERVE_REGISTER)
286 CARAUpdateObsList(obsopt, sid);
291 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a response data");
292 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
295 if (item->option == OBSERVE_DEREGISTER)
297 xmpp_ibb_close(sess);
298 ilist_remove(g_observerList, item);
304 xmpp_ibb_close(sess);
309 xmpp_ibb_userdata_alloc(sess, &buf, xdata->size);
312 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
313 CAFreeEndpoint(endPoint);
316 memcpy(buf, xdata->data, xdata->size);
317 CASecureEndpoint_t sep =
318 {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = CA_DEFAULT_FLAGS}};
319 memcpy(&sep.endpoint, endPoint, sizeof(sep.endpoint));
320 g_networkPacketCallback(&sep, buf, xdata->size);
322 CAFreeEndpoint (endPoint);
326 OIC_LOG(ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
331 static int CARAConnHandler(xmpp_t *xmpp, xmppconn_info_t *conninfo, void *udata)
333 if (conninfo->connevent != 0)
335 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, " status(%d) error(%d) errorType(%d) errorText '%s'\n",
336 conninfo->connevent, conninfo->error, conninfo->errortype,
337 conninfo->errortext);
338 CARANotifyNetworkChange(g_xmppData.jid, CA_INTERFACE_DOWN);
341 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Bound JID: '%s'", xmpphelper_get_bound_jid(xmpp));
342 if (g_xmppData.jidBoundCallback != NULL)
344 g_xmppData.jidBoundCallback((char *) xmpphelper_get_bound_jid(xmpp));
346 CARANotifyNetworkChange(xmpphelper_get_bound_jid(xmpp), CA_INTERFACE_UP);
347 VERIFY_NON_NULL_RET(udata, RA_ADAPTER_TAG, "Invalid parameter!", 0);
351 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
352 CANetworkPacketReceivedCallback networkPacketCallback,
353 CAAdapterChangeCallback netCallback, ca_thread_pool_t handle)
355 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
356 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
358 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
359 return CA_STATUS_INVALID_PARAM;
362 g_networkChangeCallback = netCallback;
363 g_networkPacketCallback = networkPacketCallback;
365 CAConnectivityHandler_t raHandler = {
366 .startAdapter = CAStartRA,
367 .stopAdapter = CAStopRA,
368 .startListenServer = CAStartRAListeningServer,
369 .startDiscoveryServer = CAStartRADiscoveryServer,
370 .sendData = CASendRAUnicastData,
371 .sendDataToAll = CASendRAMulticastData,
372 .GetnetInfo = CAGetRAInterfaceInformation,
373 .readData = CAReadRAData,
374 .terminate = CATerminateRA,
375 .cType = CA_ADAPTER_REMOTE_ACCESS};
377 registerCallback(raHandler);
379 xmpp_log_t *log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
381 xmpp_log_t *log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
383 g_xmppData.xmpp = xmpphelper_new(CARAConnHandler, NULL, log, NULL);
384 xmpphelper_force_tls(g_xmppData.xmpp);
385 g_observerList = ilist_new();
390 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
394 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
395 return CA_STATUS_INVALID_PARAM;
397 if (caraInfo->hostName != NULL)
399 OICStrcpy(g_xmppData.hostName, sizeof(g_xmppData.hostName), caraInfo->hostName);
403 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
404 return CA_STATUS_INVALID_PARAM;
406 if (caraInfo->userName != NULL && strlen(caraInfo->userName) != 0)
408 OICStrcpy(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->userName);
412 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
413 return CA_STATUS_INVALID_PARAM;
415 if (caraInfo->xmppDomain != NULL && strlen(caraInfo->xmppDomain) != 0)
417 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "@");
418 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->xmppDomain);
419 if (caraInfo->resource != NULL && strlen(caraInfo->resource) != 0)
421 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "/");
422 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->resource);
425 if (caraInfo->password != NULL)
427 OICStrcpy(g_xmppData.password, sizeof(g_xmppData.password), caraInfo->password);
429 g_xmppData.port = caraInfo->port;
430 g_xmppData.jidBoundCallback = caraInfo->jidBoundCallback;
438 ilist_destroy(g_observerList);
439 xmpphelper_join(g_xmppData.xmpp);
440 xmpphelper_release(g_xmppData.xmpp);
441 g_xmppData.xmpp = NULL;
444 CAResult_t CAStartRA()
446 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
448 if (!g_xmppData.xmpp)
450 OIC_LOG (ERROR, RA_ADAPTER_TAG, "CAStartRA(): g_xmppData.xmpp == NULL");
451 return CA_STATUS_FAILED;
454 g_raadapterMutex = oc_mutex_new ();
455 if (!g_raadapterMutex)
457 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
458 return CA_MEMORY_ALLOC_FAILED;
461 oc_mutex_lock (g_raadapterMutex);
463 xmpphelper_connect(g_xmppData.xmpp, g_xmppData.hostName, g_xmppData.port,
464 g_xmppData.jid, g_xmppData.password);
465 xmpp_ibb_reg_funcs_t regfuncs;
466 regfuncs.open_cb = CARAOpenCB;
467 regfuncs.close_cb = CARACloseCB;
468 regfuncs.recv_cb = CARARecvCB;
469 regfuncs.error_cb = CARAErrorCB;
470 xmpp_ibb_register(xmpphelper_get_conn(g_xmppData.xmpp), ®funcs);
472 xmpphelper_run(g_xmppData.xmpp);
474 oc_mutex_unlock (g_raadapterMutex);
476 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
480 CAResult_t CAStopRA()
482 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
484 xmpphelper_stop(g_xmppData.xmpp);
485 xmpp_ibb_unregister(xmpphelper_get_conn(g_xmppData.xmpp));
486 if (!g_raadapterMutex)
488 oc_mutex_free (g_raadapterMutex);
489 g_raadapterMutex = NULL;
491 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
495 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
496 uint32_t dataLength, CADataType_t dataType)
498 SET_BUT_NOT_USED(dataType);
500 if (!remoteEndpoint || !data)
502 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
508 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
511 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
513 uint32_t code = CA_NOT_FOUND;
514 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(data, dataLength, &code, remoteEndpoint);
515 char *sid = CARAGetSIDFromPDU(pdu);
516 int obsopt = CARAGetReqObsOption(pdu, remoteEndpoint);
517 coap_delete_pdu(pdu);
519 oc_mutex_lock (g_raadapterMutex);
520 if (CA_INTERFACE_UP != g_xmppData.connectionStatus)
522 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
523 oc_mutex_unlock (g_raadapterMutex);
527 xmpp_ibb_session_t *sess = xmpp_ibb_get_session_by_sid(sid);
530 sess = xmpp_ibb_open(xmpphelper_get_conn(g_xmppData.xmpp), (char * const) remoteEndpoint->addr, sid);
533 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB session establish failed!");
534 oc_mutex_unlock (g_raadapterMutex);
538 if (CARAPDUIsRequest(code))
540 if (obsopt == OBSERVE_REGISTER || obsopt == OBSERVE_DEREGISTER)
542 CARAUpdateObsList(obsopt, sid);
545 xmppdata_t xdata = {.data = (char *) data, .size = dataLength};
546 int rc = xmpp_ibb_send_data(sess, &xdata);
547 oc_mutex_unlock (g_raadapterMutex);
550 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB send data failed!");
554 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
555 dataLength, remoteEndpoint->addr);
560 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
562 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
563 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
567 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
568 const void *data, uint32_t dataLength,
569 CADataType_t dataType)
571 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
572 SET_BUT_NOT_USED(endpoint);
573 SET_BUT_NOT_USED(data);
574 SET_BUT_NOT_USED(dataLength);
575 SET_BUT_NOT_USED(dataType);
579 CAResult_t CAStartRAListeningServer()
581 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
582 return CA_NOT_SUPPORTED;
585 CAResult_t CAStartRADiscoveryServer()
587 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
588 return CA_NOT_SUPPORTED;
591 CAResult_t CAReadRAData()
593 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
594 return CA_NOT_SUPPORTED;
597 #else /* #ifdef RA_ADAPTER_IBB */
600 * Logging tag for module name.
602 #define RA_ADAPTER_TAG "RA_ADAP"
605 * Network Packet Received Callback to CA.
607 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
610 * Network Changed Callback to CA.
612 static CAAdapterChangeCallback g_networkChangeCallback = NULL;
615 * Holds XMPP data information.
619 xmpp_context_t context;
620 xmpp_handle_t handle;
621 xmpp_connection_callback_t connection_callback;
622 xmpp_connection_handle_t connection_handle;
623 xmpp_message_context_t message_context;
624 xmpp_message_callback_t message_callback;
625 CANetworkStatus_t connection_status;
627 xmpp_identity_t g_identity;
628 char jabberID[CA_RAJABBERID_SIZE];
631 static oc_mutex g_raadapterMutex = NULL;
633 static CARAXmppData_t g_xmppData = {};
635 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
637 static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
638 const char *const bound_jid,
639 xmpp_connection_handle_t connection);
641 static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
642 xmpp_connection_handle_t connection);
644 static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
645 const void *const recipient, const void *const msg, size_t messageOctets);
647 static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
648 const void *const sender, const void *const msg, size_t messageOctets);
650 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
652 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
654 CAAdapterChangeCallback networkChangeCallback = g_networkChangeCallback;
655 if (networkChangeCallback)
657 networkChangeCallback(CA_ADAPTER_REMOTE_ACCESS, status);
661 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
664 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
667 void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
668 const char *const bound_jid,
669 xmpp_connection_handle_t connection)
671 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
672 CANetworkStatus_t connection_status;
673 if (XMPP_ERR_OK == result)
675 printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
677 oc_mutex_lock (g_raadapterMutex);
678 OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
680 g_xmppData.connection_status = CA_INTERFACE_UP;
681 connection_status = CA_INTERFACE_UP;
682 g_xmppData.connection_handle = connection;
683 g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
684 g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
685 g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
686 g_xmppData.message_callback);
690 g_xmppData.connection_status = CA_INTERFACE_DOWN;
691 connection_status = CA_INTERFACE_DOWN;
692 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
695 oc_mutex_unlock (g_raadapterMutex);
696 // Notify network change to CA
697 CARANotifyNetworkChange(bound_jid, connection_status);
699 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
702 void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
703 xmpp_connection_handle_t connection)
705 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
706 char jabberID[CA_RAJABBERID_SIZE];
707 oc_mutex_lock (g_raadapterMutex);
709 g_xmppData.connection_status = CA_INTERFACE_DOWN;
710 xmpp_message_context_destroy(g_xmppData.message_context);
711 OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
713 oc_mutex_unlock (g_raadapterMutex);
715 // Notify network change to CA
716 CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
718 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
721 void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
722 const void *const recipient, const void *const msg, size_t messageOctets)
724 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
728 void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
729 const void *const sender, const void *const msg, size_t messageOctets)
731 if (g_networkPacketCallback)
733 VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
734 VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
736 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
737 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
739 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
740 CA_ADAPTER_REMOTE_ACCESS, sender, 0);
743 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
747 void *buf = OICMalloc(messageOctets);
750 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
751 CAFreeEndpoint(endPoint);
754 memcpy(buf, msg, messageOctets);
755 CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
756 if (networkPacketCallback)
758 g_networkPacketCallback(endPoint, buf, messageOctets);
761 CAFreeEndpoint (endPoint);
765 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
769 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
770 CANetworkPacketReceivedCallback networkPacketCallback,
771 CAAdapterChangeCallback netCallback, ca_thread_pool_t handle)
773 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
774 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
776 return CA_STATUS_INVALID_PARAM;
779 g_networkChangeCallback = netCallback;
780 g_networkPacketCallback = networkPacketCallback;
782 CAConnectivityHandler_t raHandler = {
783 .startAdapter = CAStartRA,
784 .stopAdapter = CAStopRA,
785 .startListenServer = CAStartRAListeningServer,
786 .stopListenServer = CAStopRAListeningServer,
787 .startDiscoveryServer = CAStartRADiscoveryServer,
788 .sendData = CASendRAUnicastData,
789 .sendDataToAll = CASendRAMulticastData,
790 .GetnetInfo = CAGetRAInterfaceInformation,
791 .readData = CAReadRAData,
792 .terminate = CATerminateRA,
793 .cType = CA_ADAPTER_REMOTE_ACCESS};
794 registerCallback(raHandler);
799 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
803 return CA_STATUS_INVALID_PARAM;
805 xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
806 caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
807 xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
808 caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
817 CAResult_t CAStartRA()
819 if (g_xmppData.handle.abstract_handle)
821 OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
825 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
827 g_raadapterMutex = oc_mutex_new ();
828 if (!g_raadapterMutex)
830 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
831 return CA_MEMORY_ALLOC_FAILED;
834 oc_mutex_lock (g_raadapterMutex);
836 xmpp_context_init(&g_xmppData.context);
837 g_xmppData.handle = xmpp_startup(&g_xmppData.context);
839 // Wire up connection callbacks and call API to connect to XMPP server
840 g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
841 g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
843 xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
844 &g_xmppData.g_identity, g_xmppData.connection_callback);
846 // Destroy host and identity structures as they are only
847 // required to establish initial connection
848 xmpp_identity_destroy(&g_xmppData.g_identity);
849 xmpp_host_destroy(&g_xmppData.g_host);
851 oc_mutex_unlock (g_raadapterMutex);
853 if (XMPP_ERR_OK != ret)
855 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
857 return CA_STATUS_FAILED;
860 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
864 CAResult_t CAStopRA()
866 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
868 xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
869 if (XMPP_ERR_OK != ret)
871 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
873 return CA_STATUS_FAILED;
876 xmpp_shutdown_xmpp(g_xmppData.handle);
877 xmpp_context_destroy(&g_xmppData.context);
878 oc_mutex_free (g_raadapterMutex);
879 g_raadapterMutex = NULL;
881 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
885 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
886 uint32_t dataLength, CADataType_t dataType)
889 if (!remoteEndpoint || !data)
891 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
897 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
901 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
902 oc_mutex_lock (g_raadapterMutex);
904 if (CA_INTERFACE_UP != g_xmppData.connection_status)
906 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
907 oc_mutex_unlock (g_raadapterMutex);
911 xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
912 remoteEndpoint->addr, data, dataLength,
913 XMPP_MESSAGE_TRANSMIT_DEFAULT);
914 if (XMPP_ERR_OK != res)
916 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
917 oc_mutex_unlock (g_raadapterMutex);
920 oc_mutex_unlock (g_raadapterMutex);
922 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
923 dataLength, remoteEndpoint->addr);
928 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
930 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
931 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
933 oc_mutex_lock (g_raadapterMutex);
935 if (CA_INTERFACE_UP != g_xmppData.connection_status)
937 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
938 oc_mutex_unlock (g_raadapterMutex);
939 return CA_ADAPTER_NOT_ENABLED;
942 oc_mutex_unlock (g_raadapterMutex);
944 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
945 CA_ADAPTER_REMOTE_ACCESS,
946 g_xmppData.jabberID, 0);
949 *info = localEndpoint;
954 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
955 const void *data, uint32_t dataLength,
956 CADataType_t dataType)
958 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
962 CAResult_t CAStartRAListeningServer()
964 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
965 return CA_NOT_SUPPORTED;
968 CAResult_t CAStopRAListeningServer()
970 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
971 return CA_NOT_SUPPORTED;
974 CAResult_t CAStartRADiscoveryServer()
976 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
977 return CA_NOT_SUPPORTED;
980 CAResult_t CAReadRAData()
982 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
983 return CA_NOT_SUPPORTED;