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 CANetworkChangeCallback 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 ca_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 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
95 CA_ADAPTER_REMOTE_ACCESS,
99 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
102 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
103 if (networkChangeCallback)
105 networkChangeCallback(localEndpoint, status);
109 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
112 CAFreeEndpoint(localEndpoint);
114 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
117 #define MAX_IBB_SESSION_ID_LENGTH 32
119 #define OBSERVE_REGISTER 0
120 #define OBSERVE_DEREGISTER 1
123 static ilist_t * g_observerList = NULL;
125 typedef struct _obs_item_t
127 char sessid[MAX_IBB_SESSION_ID_LENGTH + 1];
131 static bool CARAFindSessID(obs_item_t *item, char *key)
133 if (item == NULL || key == NULL)
137 if (strcmp(item->sessid, key) == 0)
147 static bool CARAPDUIsRequest(uint32_t x)
149 return (x == CA_GET || x == CA_POST || x == CA_PUT || x == CA_DELETE);
152 static void CARAUpdateObsList(int option, char *sid)
154 if (option == OBSERVE_REGISTER)
156 obs_item_t *item = (obs_item_t *) OICMalloc(sizeof(*item));
157 OICStrcpy(item->sessid, sizeof(item->sessid), sid);
158 item->option = OBSERVE_REGISTER;
159 ilist_add(g_observerList, item);
161 else if (option == OBSERVE_DEREGISTER)
163 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
166 item->option = OBSERVE_DEREGISTER;
171 static int CARAGetReqObsOption(coap_pdu_t *pdu, const CAEndpoint_t *endPoint)
173 uint32_t obsopt = -1;
175 CARequestInfo_t *reqInfo = (CARequestInfo_t *) OICMalloc(sizeof(*reqInfo));
176 VERIFY_NON_NULL_RET(reqInfo, RA_ADAPTER_TAG, "Memory alloc of CARequestInfo_t failed!", -1);
178 CAResult_t result = CAGetRequestInfoFromPDU(pdu, endPoint, reqInfo);
179 if (CA_STATUS_OK != result)
182 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Get Request Info failed!");
185 if (!CARAPDUIsRequest(reqInfo->method))
188 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "It is not a request data.");
192 uint8_t numOpt = reqInfo->info.numOptions;
193 CAHeaderOption_t *options = reqInfo->info.options;
194 for (uint8_t i = 0; i < numOpt; i++)
196 if(options[i].protocolID == CA_COAP_ID &&
197 options[i].optionID == COAP_OPTION_OBSERVE)
199 obsopt = options[i].optionData[0];
207 static int CARAErrorCB(xmpp_ibb_session_t *sess, xmpperror_t *xerr)
209 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "%s(): code(%d) tyep'%s' mesg'%s'",
210 __FUNCTION__, xerr->code, xerr->type, xerr->mesg);
211 SET_BUT_NOT_USED(sess);
212 SET_BUT_NOT_USED(xerr);
216 static int CARAOpenCB(xmpp_ibb_session_t *sess, char *type)
218 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
219 SET_BUT_NOT_USED(sess);
220 SET_BUT_NOT_USED(type);
224 static int CARACloseCB(xmpp_ibb_session_t *sess, char *type)
226 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "%s(): set type '%s'", __FUNCTION__, type);
227 char *sid = xmpp_ibb_get_sid(sess);
228 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
231 ilist_remove(g_observerList, item);
234 SET_BUT_NOT_USED(type);
238 static char *CARAGetSIDFromPDU(coap_pdu_t *pdu)
240 static char s_sid[MAX_IBB_SESSION_ID_LENGTH + 1] = {0};
242 VERIFY_NON_NULL_RET(pdu, RA_ADAPTER_TAG, "Invalid parameter!", NULL);
244 if (pdu->hdr->coap_hdr_udp_t.token_length * 2 > MAX_IBB_SESSION_ID_LENGTH)
246 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Token length more than expected!");
251 for (int i = 0; i < pdu->hdr->coap_hdr_udp_t.token_length; i++)
253 snprintf(hex, 3, "%02x", pdu->hdr->coap_hdr_udp_t.token[i]);
254 OICStrcat(s_sid, sizeof(s_sid), hex);
260 static int CARARecvCB(xmpp_ibb_session_t *sess, xmppdata_t *xdata)
264 /* xdata == NULL, send ack result */
268 char *msg = xdata->data;
269 char *from = xmpp_ibb_get_remote_jid(sess);
270 if (g_networkPacketCallback)
272 VERIFY_NON_NULL_RET(from, RA_ADAPTER_TAG, "from sender is NULL", -1);
273 VERIFY_NON_NULL_RET(msg, RA_ADAPTER_TAG, "message is NULL", -1);
275 OIC_LOG_V (DEBUG, RA_ADAPTER_TAG, "Message received from %s", from);
277 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
278 CA_ADAPTER_REMOTE_ACCESS, from, 0);
281 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
284 uint32_t code = CA_NOT_FOUND;
285 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(xdata->data, xdata->size, &code,
287 char *sid = CARAGetSIDFromPDU(pdu);
288 int obsopt = CARAGetReqObsOption(pdu, endPoint);
289 coap_delete_pdu(pdu);
291 if (CARAPDUIsRequest(code))
293 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a request data");
294 if (obsopt == OBSERVE_DEREGISTER || obsopt == OBSERVE_REGISTER)
296 CARAUpdateObsList(obsopt, sid);
301 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "this is a response data");
302 obs_item_t *item = ilist_finditem_func(g_observerList, (find_fp) CARAFindSessID, sid);
305 if (item->option == OBSERVE_DEREGISTER)
307 xmpp_ibb_close(sess);
308 ilist_remove(g_observerList, item);
314 xmpp_ibb_close(sess);
319 xmpp_ibb_userdata_alloc(sess, &buf, xdata->size);
322 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
323 CAFreeEndpoint(endPoint);
326 memcpy(buf, xdata->data, xdata->size);
327 CASecureEndpoint_t sep =
328 {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = CA_DEFAULT_FLAGS}};
329 memcpy(&sep.endpoint, endPoint, sizeof(sep.endpoint));
330 g_networkPacketCallback(&sep, buf, xdata->size);
332 CAFreeEndpoint (endPoint);
336 OIC_LOG(ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
341 static int CARAConnHandler(xmpp_t *xmpp, xmppconn_info_t *conninfo, void *udata)
343 if (conninfo->connevent != 0)
345 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, " status(%d) error(%d) errorType(%d) errorText '%s'\n",
346 conninfo->connevent, conninfo->error, conninfo->errortype,
347 conninfo->errortext);
348 CARANotifyNetworkChange(g_xmppData.jid, CA_INTERFACE_DOWN);
351 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Bound JID: '%s'", xmpphelper_get_bound_jid(xmpp));
352 if (g_xmppData.jidBoundCallback != NULL)
354 g_xmppData.jidBoundCallback((char *) xmpphelper_get_bound_jid(xmpp));
356 CARANotifyNetworkChange(xmpphelper_get_bound_jid(xmpp), CA_INTERFACE_UP);
357 VERIFY_NON_NULL_RET(udata, RA_ADAPTER_TAG, "Invalid parameter!", 0);
361 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
362 CANetworkPacketReceivedCallback networkPacketCallback,
363 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
365 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
366 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
368 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
369 return CA_STATUS_INVALID_PARAM;
372 g_networkChangeCallback = netCallback;
373 g_networkPacketCallback = networkPacketCallback;
375 CAConnectivityHandler_t raHandler = {
376 .startAdapter = CAStartRA,
377 .stopAdapter = CAStopRA,
378 .startListenServer = CAStartRAListeningServer,
379 .startDiscoveryServer = CAStartRADiscoveryServer,
380 .sendData = CASendRAUnicastData,
381 .sendDataToAll = CASendRAMulticastData,
382 .GetnetInfo = CAGetRAInterfaceInformation,
383 .readData = CAReadRAData,
384 .terminate = CATerminateRA,
385 .cType = CA_ADAPTER_REMOTE_ACCESS};
387 registerCallback(raHandler);
389 xmpp_log_t *log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
391 xmpp_log_t *log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
393 g_xmppData.xmpp = xmpphelper_new(CARAConnHandler, NULL, log, NULL);
394 xmpphelper_force_tls(g_xmppData.xmpp);
395 g_observerList = ilist_new();
400 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
404 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
405 return CA_STATUS_INVALID_PARAM;
407 if (caraInfo->hostName != NULL)
409 OICStrcpy(g_xmppData.hostName, sizeof(g_xmppData.hostName), caraInfo->hostName);
413 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
414 return CA_STATUS_INVALID_PARAM;
416 if (caraInfo->userName != NULL && strlen(caraInfo->userName) != 0)
418 OICStrcpy(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->userName);
422 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
423 return CA_STATUS_INVALID_PARAM;
425 if (caraInfo->xmppDomain != NULL && strlen(caraInfo->xmppDomain) != 0)
427 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "@");
428 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->xmppDomain);
429 if (caraInfo->resource != NULL && strlen(caraInfo->resource) != 0)
431 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), "/");
432 OICStrcat(g_xmppData.jid, sizeof(g_xmppData.jid), caraInfo->resource);
435 if (caraInfo->password != NULL)
437 OICStrcpy(g_xmppData.password, sizeof(g_xmppData.password), caraInfo->password);
439 g_xmppData.port = caraInfo->port;
440 g_xmppData.jidBoundCallback = caraInfo->jidBoundCallback;
448 ilist_destroy(g_observerList);
449 xmpphelper_join(g_xmppData.xmpp);
450 xmpphelper_release(g_xmppData.xmpp);
451 g_xmppData.xmpp = NULL;
454 CAResult_t CAStartRA()
456 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
458 if (!g_xmppData.xmpp)
460 OIC_LOG (ERROR, RA_ADAPTER_TAG, "CAStartRA(): g_xmppData.xmpp == NULL");
461 return CA_STATUS_FAILED;
464 g_raadapterMutex = ca_mutex_new ();
465 if (!g_raadapterMutex)
467 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
468 return CA_MEMORY_ALLOC_FAILED;
471 ca_mutex_lock (g_raadapterMutex);
473 xmpphelper_connect(g_xmppData.xmpp, g_xmppData.hostName, g_xmppData.port,
474 g_xmppData.jid, g_xmppData.password);
475 xmpp_ibb_reg_funcs_t regfuncs;
476 regfuncs.open_cb = CARAOpenCB;
477 regfuncs.close_cb = CARACloseCB;
478 regfuncs.recv_cb = CARARecvCB;
479 regfuncs.error_cb = CARAErrorCB;
480 xmpp_ibb_register(xmpphelper_get_conn(g_xmppData.xmpp), ®funcs);
482 xmpphelper_run(g_xmppData.xmpp);
484 ca_mutex_unlock (g_raadapterMutex);
486 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
490 CAResult_t CAStopRA()
492 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
494 xmpphelper_stop(g_xmppData.xmpp);
495 xmpp_ibb_unregister(xmpphelper_get_conn(g_xmppData.xmpp));
496 if (!g_raadapterMutex)
498 ca_mutex_free (g_raadapterMutex);
499 g_raadapterMutex = NULL;
501 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
505 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
508 if (!remoteEndpoint || !data)
510 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
516 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
519 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
521 uint32_t code = CA_NOT_FOUND;
522 coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU(data, dataLength, &code, remoteEndpoint);
523 char *sid = CARAGetSIDFromPDU(pdu);
524 int obsopt = CARAGetReqObsOption(pdu, remoteEndpoint);
525 coap_delete_pdu(pdu);
527 ca_mutex_lock (g_raadapterMutex);
528 if (CA_INTERFACE_UP != g_xmppData.connectionStatus)
530 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
531 ca_mutex_unlock (g_raadapterMutex);
535 xmpp_ibb_session_t *sess = xmpp_ibb_get_session_by_sid(sid);
538 sess = xmpp_ibb_open(xmpphelper_get_conn(g_xmppData.xmpp), (char * const) remoteEndpoint->addr, sid);
541 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB session establish failed!");
542 ca_mutex_unlock (g_raadapterMutex);
546 if (CARAPDUIsRequest(code))
548 if (obsopt == OBSERVE_REGISTER || obsopt == OBSERVE_DEREGISTER)
550 CARAUpdateObsList(obsopt, sid);
553 xmppdata_t xdata = {.data = (char *) data, .size = dataLength};
554 int rc = xmpp_ibb_send_data(sess, &xdata);
555 ca_mutex_unlock (g_raadapterMutex);
558 OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB send data failed!");
562 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
563 dataLength, remoteEndpoint->addr);
568 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
570 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
571 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
575 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
576 const void *data, uint32_t dataLength)
578 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
579 SET_BUT_NOT_USED(endpoint);
580 SET_BUT_NOT_USED(data);
581 SET_BUT_NOT_USED(dataLength);
585 CAResult_t CAStartRAListeningServer()
587 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
588 return CA_NOT_SUPPORTED;
591 CAResult_t CAStartRADiscoveryServer()
593 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
594 return CA_NOT_SUPPORTED;
597 CAResult_t CAReadRAData()
599 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
600 return CA_NOT_SUPPORTED;
603 #else /* #ifdef RA_ADAPTER_IBB */
606 * Logging tag for module name.
608 #define RA_ADAPTER_TAG "RA_ADAP"
611 * Network Packet Received Callback to CA.
613 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
616 * Network Changed Callback to CA.
618 static CANetworkChangeCallback g_networkChangeCallback = NULL;
621 * Holds XMPP data information.
625 xmpp_context_t context;
626 xmpp_handle_t handle;
627 xmpp_connection_callback_t connection_callback;
628 xmpp_connection_handle_t connection_handle;
629 xmpp_message_context_t message_context;
630 xmpp_message_callback_t message_callback;
631 CANetworkStatus_t connection_status;
633 xmpp_identity_t g_identity;
634 char jabberID[CA_RAJABBERID_SIZE];
637 static ca_mutex g_raadapterMutex = NULL;
639 static CARAXmppData_t g_xmppData = {};
641 static void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status);
643 static void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
644 const char *const bound_jid,
645 xmpp_connection_handle_t connection);
647 static void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
648 xmpp_connection_handle_t connection);
650 static void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
651 const void *const recipient, const void *const msg, size_t messageOctets);
653 static void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
654 const void *const sender, const void *const msg, size_t messageOctets);
656 void CARANotifyNetworkChange(const char *address, CANetworkStatus_t status)
658 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange IN");
660 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
661 CA_ADAPTER_REMOTE_ACCESS,
665 OIC_LOG(ERROR, RA_ADAPTER_TAG, "localEndpoint creation failed!");
668 CANetworkChangeCallback networkChangeCallback = g_networkChangeCallback;
669 if (networkChangeCallback)
671 networkChangeCallback(localEndpoint, status);
675 OIC_LOG(ERROR, RA_ADAPTER_TAG, "g_networkChangeCallback is NULL");
678 CAFreeEndpoint(localEndpoint);
680 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARANotifyNetworkChange OUT");
683 void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
684 const char *const bound_jid,
685 xmpp_connection_handle_t connection)
687 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB IN");
688 CANetworkStatus_t connection_status;
689 if (XMPP_ERR_OK == result)
691 printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
693 ca_mutex_lock (g_raadapterMutex);
694 OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
696 g_xmppData.connection_status = CA_INTERFACE_UP;
697 connection_status = CA_INTERFACE_UP;
698 g_xmppData.connection_handle = connection;
699 g_xmppData.message_callback.on_received = CARAXmppMessageReceivedCB;
700 g_xmppData.message_callback.on_sent = CARAXmppMessageSentCB;
701 g_xmppData.message_context = xmpp_message_context_create(g_xmppData.connection_handle,
702 g_xmppData.message_callback);
706 g_xmppData.connection_status = CA_INTERFACE_DOWN;
707 connection_status = CA_INTERFACE_DOWN;
708 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
711 ca_mutex_unlock (g_raadapterMutex);
712 // Notify network change to CA
713 CARANotifyNetworkChange(bound_jid, connection_status);
715 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppConnectedCB OUT");
718 void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
719 xmpp_connection_handle_t connection)
721 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
722 char jabberID[CA_RAJABBERID_SIZE];
723 ca_mutex_lock (g_raadapterMutex);
725 g_xmppData.connection_status = CA_INTERFACE_DOWN;
726 xmpp_message_context_destroy(g_xmppData.message_context);
727 OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
729 ca_mutex_unlock (g_raadapterMutex);
731 // Notify network change to CA
732 CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
734 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB OUT");
737 void CARAXmppMessageSentCB(void * const param, xmpp_error_code_t result,
738 const void *const recipient, const void *const msg, size_t messageOctets)
740 OIC_LOG_V(DEBUG, RA_ADAPTER_TAG, "Sending message to %s has result %d",
744 void CARAXmppMessageReceivedCB(void * const param, xmpp_error_code_t result,
745 const void *const sender, const void *const msg, size_t messageOctets)
747 if (g_networkPacketCallback)
749 VERIFY_NON_NULL_VOID(sender, RA_ADAPTER_TAG, "sender is NULL");
750 VERIFY_NON_NULL_VOID(msg, RA_ADAPTER_TAG, "message is NULL");
752 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message received from %s", sender);
753 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "Message reception result %d", result);
755 CAEndpoint_t *endPoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
756 CA_ADAPTER_REMOTE_ACCESS, sender, 0);
759 OIC_LOG(ERROR, RA_ADAPTER_TAG, "EndPoint creation failed!");
763 void *buf = OICMalloc(messageOctets);
766 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Memory alloc of message failed!");
767 CAFreeEndpoint(endPoint);
770 memcpy(buf, msg, messageOctets);
771 CANetworkPacketReceivedCallback networkPacketCallback = g_networkPacketCallback;
772 if (networkPacketCallback)
774 g_networkPacketCallback(endPoint, buf, messageOctets);
777 CAFreeEndpoint (endPoint);
781 OIC_LOG_V (ERROR, RA_ADAPTER_TAG, "No callback for RA received message found");
785 CAResult_t CAInitializeRA(CARegisterConnectivityCallback registerCallback,
786 CANetworkPacketReceivedCallback networkPacketCallback,
787 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
789 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CAInitializeRA IN");
790 if (!registerCallback || !networkPacketCallback || !netCallback || !handle)
792 return CA_STATUS_INVALID_PARAM;
795 g_networkChangeCallback = netCallback;
796 g_networkPacketCallback = networkPacketCallback;
798 CAConnectivityHandler_t raHandler = {
799 .startAdapter = CAStartRA,
800 .stopAdapter = CAStopRA,
801 .startListenServer = CAStartRAListeningServer,
802 .stopListenServer = CAStopRAListeningServer,
803 .startDiscoveryServer = CAStartRADiscoveryServer,
804 .sendData = CASendRAUnicastData,
805 .sendDataToAll = CASendRAMulticastData,
806 .GetnetInfo = CAGetRAInterfaceInformation,
807 .readData = CAReadRAData,
808 .terminate = CATerminateRA,
809 .cType = CA_ADAPTER_REMOTE_ACCESS};
810 registerCallback(raHandler);
815 CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo)
819 return CA_STATUS_INVALID_PARAM;
821 xmpp_identity_init(&g_xmppData.g_identity, caraInfo->username, caraInfo->password,
822 caraInfo->user_jid, XMPP_TRY_IN_BAND_REGISTER);
823 xmpp_host_init(&g_xmppData.g_host, caraInfo->hostname, caraInfo->port,
824 caraInfo->xmpp_domain, XMPP_PROTOCOL_XMPP);
833 CAResult_t CAStartRA()
835 if (g_xmppData.handle.abstract_handle)
837 OIC_LOG(WARNING, RA_ADAPTER_TAG, "RA adapter already started");
841 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
843 g_raadapterMutex = ca_mutex_new ();
844 if (!g_raadapterMutex)
846 OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
847 return CA_MEMORY_ALLOC_FAILED;
850 ca_mutex_lock (g_raadapterMutex);
852 xmpp_context_init(&g_xmppData.context);
853 g_xmppData.handle = xmpp_startup(&g_xmppData.context);
855 // Wire up connection callbacks and call API to connect to XMPP server
856 g_xmppData.connection_callback.on_connected = CARAXmppConnectedCB;
857 g_xmppData.connection_callback.on_disconnected = CARAXmppDisonnectedCB;
859 xmpp_error_code_t ret = xmpp_connect(g_xmppData.handle, &g_xmppData.g_host,
860 &g_xmppData.g_identity, g_xmppData.connection_callback);
862 // Destroy host and identity structures as they are only
863 // required to establish initial connection
864 xmpp_identity_destroy(&g_xmppData.g_identity);
865 xmpp_host_destroy(&g_xmppData.g_host);
867 ca_mutex_unlock (g_raadapterMutex);
869 if (XMPP_ERR_OK != ret)
871 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to init XMPP connection status: %d",
873 return CA_STATUS_FAILED;
876 OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
880 CAResult_t CAStopRA()
882 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopping RA adapter"));
884 xmpp_error_code_t ret = xmpp_close(g_xmppData.connection_handle);
885 if (XMPP_ERR_OK != ret)
887 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Failed to close XMPP connection, status: %d",
889 return CA_STATUS_FAILED;
892 xmpp_shutdown_xmpp(g_xmppData.handle);
893 xmpp_context_destroy(&g_xmppData.context);
894 ca_mutex_free (g_raadapterMutex);
895 g_raadapterMutex = NULL;
897 OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
901 int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data,
904 if (!remoteEndpoint || !data)
906 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Invalid parameter!");
912 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Data length is 0!");
916 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
917 ca_mutex_lock (g_raadapterMutex);
919 if (CA_INTERFACE_UP != g_xmppData.connection_status)
921 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
922 ca_mutex_unlock (g_raadapterMutex);
926 xmpp_error_code_t res = xmpp_send_message(g_xmppData.message_context,
927 remoteEndpoint->addr, data, dataLength,
928 XMPP_MESSAGE_TRANSMIT_DEFAULT);
929 if (XMPP_ERR_OK != res)
931 OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
932 ca_mutex_unlock (g_raadapterMutex);
935 ca_mutex_unlock (g_raadapterMutex);
937 OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
938 dataLength, remoteEndpoint->addr);
943 CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
945 VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
946 VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
948 ca_mutex_lock (g_raadapterMutex);
950 if (CA_INTERFACE_UP != g_xmppData.connection_status)
952 OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
953 ca_mutex_unlock (g_raadapterMutex);
954 return CA_ADAPTER_NOT_ENABLED;
957 ca_mutex_unlock (g_raadapterMutex);
959 CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
960 CA_ADAPTER_REMOTE_ACCESS,
961 g_xmppData.jabberID, 0);
964 *info = localEndpoint;
969 int32_t CASendRAMulticastData(const CAEndpoint_t *endpoint,
970 const void *data, uint32_t dataLength)
972 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support sending multicast data");
976 CAResult_t CAStartRAListeningServer()
978 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
979 return CA_NOT_SUPPORTED;
982 CAResult_t CAStopRAListeningServer()
984 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support listening for multicast data");
985 return CA_NOT_SUPPORTED;
988 CAResult_t CAStartRADiscoveryServer()
990 OIC_LOG(INFO, RA_ADAPTER_TAG, "RA adapter does not support discovery of multicast servers");
991 return CA_NOT_SUPPORTED;
994 CAResult_t CAReadRAData()
996 OIC_LOG(INFO, RA_ADAPTER_TAG, "Read data is not implemented for the RA adapter");
997 return CA_NOT_SUPPORTED;