target_os = env.get('TARGET_OS')
transport = env.get('TARGET_TRANSPORT')
build_sample = env.get('BUILD_SAMPLE')
+ with_ra = env.get('WITH_RA')
print "Given Transport is %s" % transport
print "Given OS is %s" % target_os
Exit(1)
if 'ALL' in transport:
+ if with_ra == True:
+ env.AppendUnique(CPPDEFINES = ['RA_ADAPTER'])
if target_os == 'linux':
- env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER'])
+ env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','LE_ADAPTER'])
elif target_os == 'tizen':
env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
elif target_os in['darwin','ios']:
env.AppendUnique(CPPDEFINES = ['NO_EDR_ADAPTER'])
if 'BLE' in transport:
- if target_os == 'linux':
- print "CA Transport BLE is not supported in Linux"
- Exit(1)
- else:
- env.AppendUnique(CPPDEFINES = ['LE_ADAPTER'])
- print "CA Transport is BLE"
+ env.AppendUnique(CPPDEFINES = ['LE_ADAPTER'])
+ print "CA Transport is BLE"
else:
env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER'])
env.AppendUnique(CPPDEFINES = ['NO_IP_ADAPTER'])
env.SConscript('./src/SConscript')
--
+#if build_sample == 'ON':
+# if target_os in ['linux', 'arduino', 'android']:
+# env.SConscript('./samples/' + target_os + '/SConscript')
+ if build_sample == 'ON':
+ if target_os in ['linux', 'arduino', 'darwin']:
+ target_path = target_os
+
+ if target_os == 'darwin':
+ target_path = 'linux'
+ env.SConscript('./samples/' + target_path + '/SConscript')
+
+ elif target_os in ['android']:
+ env.SConscript('./samples/' + target_os + '/SConscript')
+
+ #to build sample apk, uncomment below line after ca libraries are built
+ #while building ca libraries comment the below line, to avoid build errors
+
+ #env.SConscript('./samples/' + target_os + '/casample/SConscript')
#include "secureresourcemanager.h"
#include "cacommon.h"
#include "cainterface.h"
+ #include "ocpayload.h"
+ #include "ocpayloadcbor.h"
#ifdef WITH_ARDUINO
#include "Time.h"
#include "coap_time.h"
#include "utlist.h"
#include "pdu.h"
- #include "cJSON.h"
#ifndef ARDUINO
#include <arpa/inet.h>
#endif
static OCMode myStackMode;
+ #ifdef RA_ADAPTER
+ //TODO: revisit this design
+ static bool gRASetInfo = false;
+ #endif
OCDeviceEntityHandler defaultDeviceHandler;
void* defaultDeviceHandlerCallbackParameter = NULL;
#define MAX_OBSERVE_AGE (0x2FFFFUL)
#define MILLISECONDS_PER_SECOND (1000)
- /**
- * Parse the presence payload and extract various parameters.
- * Note: Caller should invoke OICFree after done with resType pointer.
- *
- * @param payload Presence payload.
- * @param seqNum Sequence number.
- * @param maxAge Time To Live (in seconds).
- * @param resType Resource type.
- */
- void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
- OCPresenceTrigger *presenceTrigger, char** resType);
//-----------------------------------------------------------------------------
// Private internal function prototypes
static OCStackResult verifyUriQueryLength(const char * inputUri,
uint16_t uriLen);
- /**
- * Determine if a request/response must be sent in a block transfer because it is too large to be
- * sent in a single PDU. This function can be used for either a request or a response.
- * Note: Either the request or response parameter should be non-NULL (i.e. only one, not both).
- *
- * @param request NULL or pointer to request.
- * @param response NULL or pointer to response.
- * @param size 0 or size of the request/response. If 0, strlen is used for determining
- * the length of the request/response.
- *
- * @return
- * false - packet transfer NOT required (i.e. normal request/response).
- * true - packet transfer required (i.e. block transfer needed).
- */
- static bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size);
-
/*
* Attempts to initialize every network interface that the CA Layer might have compiled in.
*
out->adapter = (OCTransportAdapter)in->adapter;
out->flags = CAToOCTransportFlags(in->flags);
- strncpy(out->addr, in->addr, MAX_ADDR_STR_SIZE);
- out->addr[MAX_ADDR_STR_SIZE - 1] = '\0';
+ OICStrcpy(out->addr, sizeof(out->addr), in->addr);
out->port = in->port;
+ out->interface = in->interface;
}
void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out)
out->adapter = (CATransportAdapter_t)in->adapter;
out->flags = OCToCATransportFlags(in->flags);
- strncpy(out->addr, in->addr, MAX_ADDR_STR_SIZE);
+ OICStrcpy(out->addr, sizeof(out->addr), in->addr);
out->port = in->port;
- }
-
- static OCStackResult OCCreateEndpoint(OCDevAddr *devAddr, CAEndpoint_t **endpoint)
- {
- VERIFY_NON_NULL(devAddr, FATAL, OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
-
- CAEndpoint_t *ep = (CAEndpoint_t *)OICMalloc(sizeof (CAEndpoint_t));
- if (!ep)
- {
- return OC_STACK_NO_MEMORY;
- }
-
- ep->adapter = (CATransportAdapter_t)devAddr->adapter;
- ep->flags = OCToCATransportFlags(devAddr->flags);
- strncpy(ep->addr, devAddr->addr, MAX_ADDR_STR_SIZE_CA);
- ep->port = devAddr->port;
-
- *endpoint = ep;
-
- return OC_STACK_OK;
- }
-
- static void OCDestroyEndpoint(CAEndpoint_t *endpoint)
- {
- free(endpoint);
+ out->interface = in->interface;
}
void FixUpClientResponse(OCClientResponse *cr)
{
OCStackResult result = OC_STACK_ERROR;
ResourceObserver * observer = NULL;
- OCEntityHandlerRequest ehRequest = {};
+ OCEntityHandlerRequest ehRequest = {0};
switch(status)
{
case OC_OBSERVER_NOT_INTERESTED:
- OC_LOG(DEBUG, TAG, PCF("observer is not interested in our notifications anymore"));
+ OC_LOG(DEBUG, TAG, PCF("observer not interested in our notifications"));
observer = GetObserverUsingToken (token, tokenLength);
if(observer)
{
- result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
- OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
- NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
+ result = FormOCEntityHandlerRequest(&ehRequest,
+ (OCRequestHandle)NULL,
+ OC_REST_NOMETHOD,
+ &observer->devAddr,
+ (OCResourceHandle)NULL,
+ NULL, NULL, 0, 0, NULL,
+ OC_OBSERVE_DEREGISTER,
+ observer->observeId);
if(result != OC_STACK_OK)
{
return result;
observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
observer->resource->entityHandlerCallbackParam);
}
- //observer is not observing anymore
+
result = DeleteObserverUsingToken (token, tokenLength);
if(result == OC_STACK_OK)
{
OC_LOG(DEBUG, TAG, PCF("Observer Removal failed"));
}
break;
+
case OC_OBSERVER_STILL_INTERESTED:
- //observer is still interested
- OC_LOG(DEBUG, TAG, PCF("observer is interested in our \
- notifications, reset the failedCount"));
+ OC_LOG(DEBUG, TAG, PCF("observer still interested, reset the failedCount"));
observer = GetObserverUsingToken (token, tokenLength);
if(observer)
{
result = OC_STACK_OBSERVER_NOT_FOUND;
}
break;
+
case OC_OBSERVER_FAILED_COMM:
- //observer is not reachable
OC_LOG(DEBUG, TAG, PCF("observer is unreachable"));
observer = GetObserverUsingToken (token, tokenLength);
if(observer)
{
if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
{
- result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) NULL,
- OC_REST_NOMETHOD, (OCResourceHandle) NULL, NULL, NULL, 0,
- NULL, OC_OBSERVE_DEREGISTER, observer->observeId);
+ result = FormOCEntityHandlerRequest(&ehRequest,
+ (OCRequestHandle)NULL,
+ OC_REST_NOMETHOD,
+ &observer->devAddr,
+ (OCResourceHandle)NULL,
+ NULL, NULL, 0, 0, NULL,
+ OC_OBSERVE_DEREGISTER,
+ observer->observeId);
if(result != OC_STACK_OK)
{
return OC_STACK_ERROR;
}
observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
observer->resource->entityHandlerCallbackParam);
- //observer is unreachable
+
result = DeleteObserverUsingToken (token, tokenLength);
if(result == OC_STACK_OK)
{
case CA_BAD_REQ:
ret = OC_STACK_INVALID_QUERY;
break;
+ case CA_UNAUTHORIZED_REQ:
+ ret = OC_STACK_UNAUTHORIZED_REQ;
+ break;
case CA_BAD_OPT:
ret = OC_STACK_INVALID_OPTION;
break;
case OC_STACK_COMM_ERROR:
ret = CA_RETRANSMIT_TIMEOUT;
break;
+ case OC_STACK_UNAUTHORIZED_REQ:
+ ret = CA_UNAUTHORIZED_REQ;
+ break;
default:
break;
}
{
CATransportFlags_t caFlags = (CATransportFlags_t)ocFlags;
- // supply default behavior
+ // supply default behavior.
if ((caFlags & (CA_IPV6|CA_IPV4)) == 0)
{
caFlags = (CATransportFlags_t)(caFlags|CA_IPV6|CA_IPV4);
cbNode->presence->TTL = maxAgeSeconds;
- for(int index = 0; index < PresenceTimeOutSize; index++)
+ for (int index = 0; index < PresenceTimeOutSize; index++)
{
// Guard against overflow
if (cbNode->presence->TTL < (UINT32_MAX/(MILLISECONDS_PER_SECOND*PresenceTimeOut[index]))
OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
{
- if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CREATE) == 0)
+ if(!triggerStr)
+ {
+ return OC_PRESENCE_TRIGGER_CREATE;
+ }
+ else if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CREATE) == 0)
{
return OC_PRESENCE_TRIGGER_CREATE;
}
*
* requestUri must be a char array of size CA_MAX_URI_LENGTH
*/
- static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri, char *presenceUri)
+ static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri,
+ char *presenceUri)
{
- VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(endpoint , FATAL, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(resourceUri, FATAL, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(presenceUri, FATAL, OC_STACK_INVALID_PARAM);
- const char *format;
+ CAEndpoint_t *ep = (CAEndpoint_t *)endpoint;
- if (endpoint->flags & CA_IPV6)
- {
- format = "coap://[%s]:%u%s";
- }
- else
- {
- format = "coap://%s:%u%s";
- }
-
- return snprintf(presenceUri, CA_MAX_URI_LENGTH, format, endpoint->addr,
- endpoint->port, OC_PRESENCE_URI);
- }
-
- void parsePresencePayload(char* payload, uint32_t* seqNum, uint32_t* maxAge,
- OCPresenceTrigger *presenceTrigger, char** resType)
- {
- if(!payload || !seqNum || !maxAge || !presenceTrigger || !resType)
+ if (ep->adapter == CA_ADAPTER_IP)
{
- return;
- }
-
- cJSON *repObj = cJSON_Parse(payload);
- cJSON *ocObj = NULL;
- cJSON *presenceObj = NULL;
- cJSON *seqNumObj = NULL;
- cJSON *maxAgeObj = NULL;
- cJSON *triggerObj = NULL;
- cJSON *resObj = NULL;
- if(repObj)
- {
- ocObj = cJSON_GetObjectItem(repObj, OC_RSRVD_OC);
- if(ocObj)
+ if ((ep->flags & CA_IPV6) && !(ep->flags & CA_IPV4))
{
- //Presence payloads should only carry one JSON payload. The first
- // & only array item is retrieved.
- presenceObj = cJSON_GetArrayItem(ocObj, 0);
- if(presenceObj)
+ if ('\0' == ep->addr[0]) // multicast
{
- seqNumObj = cJSON_GetObjectItem(presenceObj, OC_RSRVD_NONCE);
- if(seqNumObj)
- {
- *seqNum = (uint32_t)seqNumObj->valuedouble;
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Nonce (AKA SeqNum) not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- maxAgeObj = cJSON_GetObjectItem(presenceObj, OC_RSRVD_TTL);
- if(maxAgeObj)
- {
- *maxAge = maxAgeObj->valueint;
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("TTL (AKA MaxAge) not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- triggerObj = cJSON_GetObjectItem(presenceObj,
- OC_RSRVD_TRIGGER);
- if(triggerObj)
- {
- char * triggerStr = triggerObj->valuestring;
- *presenceTrigger = convertTriggerStringToEnum(triggerStr);
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Trigger Reason not found in"
- " JSON Presence Payload."));
- goto exit;
- }
- resObj = cJSON_GetObjectItem(presenceObj,
- OC_RSRVD_RESOURCE_TYPE);
- if(resObj)
- {
- *resType = OICStrdup(resObj->valuestring);
- if(!*resType)
- {
- goto exit;
- }
- }
- else
- {
- OC_LOG(ERROR, TAG, PCF("Resource Type not found in"
- " JSON Presence Payload."));
- goto exit;
- }
+ return snprintf(presenceUri, CA_MAX_URI_LENGTH, OC_RSRVD_PRESENCE_URI);
}
else
{
- OC_LOG(ERROR, TAG, PCF("JSON Presence Object not found in"
- " Presence Payload."));
- OICFree(*resType);
- goto exit;
+ return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://[%s]:%u%s",
+ ep->addr, ep->port, OC_RSRVD_PRESENCE_URI);
}
}
else
{
- OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does not contain a"
- " valid \"oic\" JSON representation."));
- OICFree(*resType);
- goto exit;
+ if ('\0' == ep->addr[0]) // multicast
+ {
+ OICStrcpy(ep->addr, sizeof(ep->addr), OC_MULTICAST_IP);
+ ep->port = OC_MULTICAST_PORT;
+ }
+ return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://%s:%u%s",
+ ep->addr, ep->port, OC_RSRVD_PRESENCE_URI);
}
}
- else
- {
- OC_LOG(ERROR, TAG, PCF("JSON Presence Payload does map to a valid JSON"
- " representation."));
- OICFree(*resType);
- goto exit;
- }
- exit:
- cJSON_Delete(repObj);
+ // might work for other adapters (untested, but better than nothing)
+ return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://%s%s", ep->addr,
+ OC_RSRVD_PRESENCE_URI);
}
+
OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
const CAResponseInfo_t *responseInfo)
{
OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
ClientCB * cbNode = NULL;
char *resourceTypeName = NULL;
- OCClientResponse response;
+ OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
OCStackResult result = OC_STACK_ERROR;
uint32_t maxAge = 0;
- OCPresenceTrigger presenceTrigger = OC_PRESENCE_TRIGGER_CHANGE;
int uriLen;
char presenceUri[CA_MAX_URI_LENGTH];
return OC_STACK_ERROR;
}
- uriLen = FormCanonicalPresenceUri(endpoint, OC_PRESENCE_URI, presenceUri);
- if (uriLen < 0 || uriLen >= sizeof (presenceUri))
+ // check for unicast presence
+ uriLen = FormCanonicalPresenceUri(endpoint, OC_RSRVD_PRESENCE_URI, presenceUri);
+ if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri))
{
return OC_STACK_INVALID_URI;
}
}
else
{
- strncpy(presenceUri, responseInfo->info.resourceUri, CA_MAX_URI_LENGTH);
+ // check for multiicast presence
+ CAEndpoint_t ep = { .adapter = endpoint->adapter,
+ .flags = endpoint->flags };
+
+ uriLen = FormCanonicalPresenceUri(&ep, OC_RSRVD_PRESENCE_URI, presenceUri);
+
cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
if (cbNode)
{
if (!presenceSubscribe && !multicastPresenceSubscribe)
{
- OC_LOG(ERROR, TAG, PCF("Received a presence notification, but no callback, ignoring"));
+ OC_LOG(ERROR, TAG, PCF("Received a presence notification, but no callback, ignoring"));
goto exit;
}
- response.resJSONPayload = responseInfo->info.payload;
+ response.payload = NULL;
response.result = OC_STACK_OK;
CopyEndpointToDevAddr(endpoint, &response.devAddr);
if (responseInfo->info.payload)
{
- parsePresencePayload(responseInfo->info.payload,
- &(response.sequenceNumber),
- &maxAge,
- &presenceTrigger,
- &resourceTypeName);
+ result = OCParsePayload(&response.payload, responseInfo->info.payload,
+ responseInfo->info.payloadSize);
+
+ if(result != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("Presence parse failed"));
+ goto exit;
+ }
+ if(!response.payload || response.payload->type != PAYLOAD_TYPE_PRESENCE)
+ {
+ OC_LOG(ERROR, TAG, PCF("Presence payload was wrong type"));
+ result = OC_STACK_ERROR;
+ goto exit;
+ }
+ response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber;
+ resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType;
+ maxAge = ((OCPresencePayload*)response.payload)->maxAge;
}
if (presenceSubscribe)
cbNode->sequenceNumber = response.sequenceNumber;
// Ensure that a filter is actually applied.
- if(resourceTypeName && cbNode->filterResourceType)
+ if( resourceTypeName && cbNode->filterResourceType)
{
if(!findResourceType(cbNode->filterResourceType, resourceTypeName))
{
}
exit:
- OICFree(resourceTypeName);
+ OCPayloadDestroy(response.payload);
return result;
}
{
VERIFY_NON_NULL_NR(endPoint, FATAL);
VERIFY_NON_NULL_NR(responseInfo, FATAL);
- VERIFY_NON_NULL_NR(responseInfo->info.resourceUri, FATAL);
- if(strcmp(responseInfo->info.resourceUri, OC_PRESENCE_URI) == 0)
+ OC_LOG(INFO, TAG, PCF("Enter HandleCAResponses"));
+
+ if(responseInfo->info.resourceUri &&
+ strcmp(responseInfo->info.resourceUri, OC_RSRVD_PRESENCE_URI) == 0)
{
HandlePresenceResponse(endPoint, responseInfo);
return;
ClientCB *cbNode = GetClientCB(responseInfo->info.token,
responseInfo->info.tokenLength, NULL, NULL);
- OC_LOG_V(DEBUG, TAG, "Response has the token %s", responseInfo->info.token);
+
ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token,
responseInfo->info.tokenLength);
OC_LOG(INFO, TAG, PCF("Receiving A Timeout for this token"));
OC_LOG(INFO, TAG, PCF("Calling into application address space"));
- OCClientResponse response = {};
+ OCClientResponse response =
+ {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
CopyEndpointToDevAddr(endPoint, &response.devAddr);
FixUpClientResponse(&response);
response.resourceUri = responseInfo->info.resourceUri;
+ memcpy(response.identity.id, responseInfo->info.identity.id,
+ sizeof (response.identity.id));
+ response.identity.id_length = responseInfo->info.identity.id_length;
response.result = CAToOCStackResult(responseInfo->result);
cbNode->callBack(cbNode->context,
OC_LOG(INFO, TAG, PCF("This is a regular response, A client call back is found"));
OC_LOG(INFO, TAG, PCF("Calling into application address space"));
- OCClientResponse response = {};
+ OCClientResponse response =
+ {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
+ response.sequenceNumber = OC_OBSERVE_NO_OPTION;
CopyEndpointToDevAddr(endPoint, &response.devAddr);
FixUpClientResponse(&response);
response.resourceUri = responseInfo->info.resourceUri;
+ memcpy(response.identity.id, responseInfo->info.identity.id,
+ sizeof (response.identity.id));
+ response.identity.id_length = responseInfo->info.identity.id_length;
response.result = CAToOCStackResult(responseInfo->result);
- response.resJSONPayload = (const char*)responseInfo->info.payload;
+ if(responseInfo->info.payload &&
+ responseInfo->info.payloadSize &&
+ OC_STACK_OK != OCParsePayload(&response.payload, responseInfo->info.payload,
+ responseInfo->info.payloadSize))
+ {
+ OC_LOG(ERROR, TAG, PCF("Error converting payload"));
+ OCPayloadDestroy(response.payload);
+ return;
+ }
+
response.numRcvdVendorSpecificHeaderOptions = 0;
if(responseInfo->info.numOptions > 0)
{
if(response.numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS)
{
OC_LOG(ERROR, TAG, PCF("#header options are more than MAX_HEADER_OPTIONS"));
+ OCPayloadDestroy(response.payload);
return;
}
SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0);
}
+
+ OCPayloadDestroy(response.payload);
}
return;
}
}
else
{
- OC_LOG(INFO, TAG, PCF("Received a response or notification,\
- but I do not have callback. Sending RESET"));
+ OC_LOG(INFO, TAG, PCF("Received a message without callbacks. Sending RESET"));
SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
CA_MSG_RESET, 0, NULL, NULL, 0);
}
responseInfo->info.messageId);
}
}
+
return;
}
- OC_LOG_V(INFO, TAG, PCF("Received payload: %s\n"), (char*)responseInfo->info.payload);
OC_LOG(INFO, TAG, PCF("Exit HandleCAResponses"));
}
const uint8_t numOptions, const CAHeaderOption_t *options,
CAToken_t token, uint8_t tokenLength)
{
- CAResponseInfo_t respInfo = {};
- respInfo.result = responseResult;
+ CAResponseInfo_t respInfo = {
+ .result = responseResult
+ };
respInfo.info.messageId = coapID;
respInfo.info.numOptions = numOptions;
respInfo.info.options = (CAHeaderOption_t*)options;
return;
}
- OCServerProtocolRequest serverRequest = {};
+ OCServerProtocolRequest serverRequest = {0};
- OC_LOG_V(INFO, TAG, PCF("Endpoint URI : %s\n"), requestInfo->info.resourceUri);
+ OC_LOG_V(INFO, TAG, PCF("Endpoint URI : %s"), requestInfo->info.resourceUri);
- char * newUri = NULL;
+ char * uriWithoutQuery = NULL;
char * query = NULL;
- requestResult = getQueryFromUri(requestInfo->info.resourceUri, &query, &newUri);
+ requestResult = getQueryFromUri(requestInfo->info.resourceUri, &query, &uriWithoutQuery);
- if (requestResult != OC_STACK_OK)
+ if (requestResult != OC_STACK_OK || !uriWithoutQuery)
{
OC_LOG_V(ERROR, TAG, "getQueryFromUri() failed with OC error code %d\n", requestResult);
return;
}
- OC_LOG_V(INFO, TAG, PCF("URI without query: %s\n"), newUri);
- OC_LOG_V(INFO, TAG, PCF("Query : %s\n"), query);
+ OC_LOG_V(INFO, TAG, PCF("URI without query: %s"), uriWithoutQuery);
+ OC_LOG_V(INFO, TAG, PCF("Query : %s"), query);
- if(strlen(newUri) < MAX_URI_LENGTH)
+ if(strlen(uriWithoutQuery) < MAX_URI_LENGTH)
{
- //copy URI
- OICStrcpy(serverRequest.resourceUrl, sizeof(serverRequest.resourceUrl),
- newUri);
- OICFree(newUri);
+ OICStrcpy(serverRequest.resourceUrl, sizeof(serverRequest.resourceUrl), uriWithoutQuery);
+ OICFree(uriWithoutQuery);
}
else
{
OC_LOG(ERROR, TAG, PCF("URI length exceeds MAX_URI_LENGTH."));
- OICFree(newUri);
+ OICFree(uriWithoutQuery);
OICFree(query);
return;
}
- //copy query
+
if(query)
{
if(strlen(query) < MAX_QUERY_LENGTH)
return;
}
}
- //copy request payload
- if (requestInfo->info.payload)
+
+ if ((requestInfo->info.payload) && (0 < requestInfo->info.payloadSize))
{
- size_t payloadLen = strlen(requestInfo->info.payload);
- serverRequest.reqTotalSize = payloadLen + 1;
- OICStrcpy(serverRequest.reqJSONPayload, sizeof(serverRequest.reqJSONPayload),
- requestInfo->info.payload);
+ serverRequest.reqTotalSize = requestInfo->info.payloadSize;
+ serverRequest.payload = (uint8_t *) OICMalloc(requestInfo->info.payloadSize);
+ memcpy (serverRequest.payload, requestInfo->info.payload,
+ requestInfo->info.payloadSize);
}
else
{
- serverRequest.reqTotalSize = 1;
- serverRequest.reqJSONPayload[0] = '\0';
+ serverRequest.reqTotalSize = 0;
}
switch (requestInfo->method)
serverRequest.method = OC_REST_DELETE;
break;
default:
- OC_LOG(ERROR, TAG, PCF("Received CA method %d not supported"));
+ OC_LOG_V(ERROR, TAG, "Received CA method %d not supported", requestInfo->method);
SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_REQ,
requestInfo->info.type, requestInfo->info.numOptions,
requestInfo->info.options, requestInfo->info.token,
requestInfo->info.tokenLength);
+ OICFree(serverRequest.payload);
return;
}
- OC_LOG_V(INFO, TAG, "HandleCARequests: CA token length = %d",
- requestInfo->info.tokenLength);
OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)requestInfo->info.token,
requestInfo->info.tokenLength);
serverRequest.requestToken = (CAToken_t)OICMalloc(requestInfo->info.tokenLength);
serverRequest.tokenLength = requestInfo->info.tokenLength;
- // Module Name
+
if (!serverRequest.requestToken)
{
- OC_LOG(FATAL, TAG, "Server Request Token is NULL");
+ OC_LOG(FATAL, TAG, "Allocation for token failed.");
SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_INTERNAL_SERVER_ERROR,
requestInfo->info.type, requestInfo->info.numOptions,
requestInfo->info.options, requestInfo->info.token,
requestInfo->info.tokenLength);
+ OICFree(serverRequest.payload);
return;
}
memcpy(serverRequest.requestToken, requestInfo->info.token, requestInfo->info.tokenLength);
serverRequest.coapID = requestInfo->info.messageId;
- // copy the address
CopyEndpointToDevAddr(endPoint, &serverRequest.devAddr);
// copy vendor specific header options
requestInfo->info.type, requestInfo->info.numOptions,
requestInfo->info.options, requestInfo->info.token,
requestInfo->info.tokenLength);
+ OICFree(serverRequest.payload);
OICFree(serverRequest.requestToken);
return;
}
}
// requestToken is fed to HandleStackRequests, which then goes to AddServerRequest.
// The token is copied in there, and is thus still owned by this function.
+ OICFree(serverRequest.payload);
OICFree(serverRequest.requestToken);
OC_LOG(INFO, TAG, PCF("Exit HandleCARequests"));
}
protocolRequest->method, protocolRequest->numRcvdVendorSpecificHeaderOptions,
protocolRequest->observationOption, protocolRequest->qos,
protocolRequest->query, protocolRequest->rcvdVendorSpecificHeaderOptions,
- protocolRequest->reqJSONPayload, protocolRequest->requestToken,
+ protocolRequest->payload, protocolRequest->requestToken,
protocolRequest->tokenLength,
protocolRequest->resourceUrl, protocolRequest->reqTotalSize,
&protocolRequest->devAddr);
}
else
{
- OC_LOG(INFO, TAG,
- PCF("This is either a repeated or blocked Server Request"));
+ OC_LOG(INFO, TAG, PCF("This is either a repeated or blocked Server Request"));
}
if(request->requestComplete)
//-----------------------------------------------------------------------------
// Public APIs
//-----------------------------------------------------------------------------
+ #ifdef RA_ADAPTER
+ OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo)
+ {
+ if (!raInfo ||
+ !raInfo->username ||
+ !raInfo->hostname ||
+ !raInfo->xmpp_domain)
+ {
+
+ return OC_STACK_INVALID_PARAM;
+ }
+ OCStackResult result = CAResultToOCResult(CASetRAInfo((const CARAInfo_t *) raInfo));
+ gRASetInfo = (result == OC_STACK_OK)? true : false;
+
+ return result;
+ }
+ #endif
OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
{
(void) ipAddr;
(void) port;
-
return OCInit1(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS);
}
return OC_STACK_OK;
}
+ #ifdef RA_ADAPTER
+ if(!gRASetInfo)
+ {
+ OC_LOG(ERROR, TAG, PCF("Need to call OCSetRAInfo before calling OCInit"));
+ return OC_STACK_ERROR;
+ }
+ #endif
+
OCStackResult result = OC_STACK_ERROR;
OC_LOG(INFO, TAG, PCF("Entering OCInit"));
}
myStackMode = mode;
+ if (mode == OC_CLIENT || mode == OC_CLIENT_SERVER)
+ {
+ caglobals.client = true;
+ }
+ if (mode == OC_SERVER || mode == OC_CLIENT_SERVER)
+ {
+ caglobals.server = true;
+ }
+
caglobals.serverFlags = (CATransportFlags_t)serverFlags;
+ if (!(caglobals.serverFlags & CA_IPFAMILY_MASK))
+ {
+ caglobals.serverFlags = (CATransportFlags_t)(caglobals.serverFlags|CA_IPV4|CA_IPV6);
+ }
caglobals.clientFlags = (CATransportFlags_t)clientFlags;
+ if (!(caglobals.clientFlags & CA_IPFAMILY_MASK))
+ {
+ caglobals.clientFlags = (CATransportFlags_t)(caglobals.clientFlags|CA_IPV4|CA_IPV6);
+ }
defaultDeviceHandler = NULL;
defaultDeviceHandlerCallbackParameter = NULL;
VERIFY_SUCCESS(result, OC_STACK_OK);
#ifdef WITH_PRESENCE
- PresenceTimeOutSize = sizeof(PresenceTimeOut)/sizeof(PresenceTimeOut[0]) - 1;
+ PresenceTimeOutSize = sizeof (PresenceTimeOut) / sizeof (PresenceTimeOut[0]) - 1;
#endif // WITH_PRESENCE
//Update Stack state to initialized
// Free memory dynamically allocated for resources
deleteAllResources();
DeleteDeviceInfo();
+ DeletePlatformInfo();
CATerminate();
// Remove all observers
DeleteObserverList();
// TODO after BeachHead delivery: consolidate into single SRMDeInit()
SRMDeInitPolicyEngine();
+
stackState = OC_STACK_UNINITIALIZED;
return OC_STACK_OK;
}
// processs url prefix, if any
size_t urlLen = slash - start;
+ // port
+ uint16_t port = 0;
+ size_t len = 0;
if (urlLen && devAddr)
{ // construct OCDevAddr
if (start[0] == '[')
{
colon = close + 1;
}
+ adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP);
+ flags = (OCTransportFlags)(flags | OC_IP_USE_V6);
}
else
- { // ipv4 address
- end = slash;
- colon = strchr(start, ':');
- end = (colon && colon < slash) ? colon : slash;
+ {
+ char *dot = strchr(start, '.');
+ if (dot && dot < slash)
+ { // ipv4 address
+ colon = strchr(start, ':');
+ end = (colon && colon < slash) ? colon : slash;
+ adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP);
+ flags = (OCTransportFlags)(flags | OC_IP_USE_V4);
+ }
+ else
+ { // MAC address
+ end = slash;
+ }
}
- size_t len = end - start;
- if (len > MAX_ADDR_STR_SIZE)
+ len = end - start;
+ if (len >= sizeof(da->addr))
{
return OC_STACK_INVALID_URI;
}
-
- // port
- uint16_t port = 0; // use standard multicast port
+ // collect port, if any
if (colon && colon < slash)
{
for (colon++; colon < slash; colon++)
}
}
+ da = (OCDevAddr *)OICCalloc(1, sizeof (OCDevAddr));
++
+ len = end - start;
+ if (len >= sizeof(da->addr))
+ {
+ return OC_STACK_INVALID_URI;
+ }
+
+ da = (OCDevAddr *)OICCalloc(sizeof (OCDevAddr), 1);
++
if (!da)
{
return OC_STACK_NO_MEMORY;
}
- strncpy(da->addr, start, len);
+ OICStrcpyPartial(da->addr, sizeof(da->addr), start, len);
da->port = port;
da->adapter = adapter;
da->flags = flags;
size_t tlen = 0; // resource type length
char *type = NULL;
- static const char *strPresence = "/oc/presence?rt=";
- static const size_t lenPresence = 15; // = strlen(presence);
+ static const char strPresence[] = "/oic/ad?rt=";
+ static const size_t lenPresence = sizeof(strPresence) - 1;
if (!strncmp(slash, strPresence, lenPresence))
{
type = slash + lenPresence;
result = OC_STACK_NO_MEMORY;
goto error;
}
- strncpy(*resourceType, type, tlen);
+
+ OICStrcpy(*resourceType, (tlen+1), type);
}
}
FormCanonicalPresenceUri(endpoint, resourceUri, uri);
- *requestUri = (char *)OICMalloc(strlen(uri) + 1);
+ *requestUri = OICStrdup(uri);
if (!*requestUri)
{
return OC_STACK_NO_MEMORY;
}
- strcpy(*requestUri, uri);
return OC_STACK_OK;
}
OCMethod method,
const char *requestUri,
const OCDevAddr *destination,
- const char *request,
+ OCPayload* payload,
OCConnectivityType connectivityType,
OCQualityOfService qos,
OCCallbackData *cbData,
uint8_t tokenLength = CA_MAX_TOKEN_LEN;
ClientCB *clientCB = NULL;
OCDoHandle resHandle = NULL;
- CAEndpoint_t *endpoint = NULL;
+ CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
OCDevAddr tmpDevAddr = { OC_DEFAULT_ADAPTER };
uint32_t ttl = 0;
OCTransportAdapter adapter;
OCTransportFlags flags;
// the request contents are put here
- CARequestInfo_t requestInfo = { CA_GET };
+ CARequestInfo_t requestInfo = {.method = CA_GET};
// requestUri will be parsed into the following three variables
OCDevAddr *devAddr = NULL;
char *resourceUri = NULL;
goto exit;
}
- if ((request) && (strlen(request) > MAX_REQUEST_LENGTH))
- {
- result = OC_STACK_INVALID_PARAM;
- goto exit;
- }
-
/*
* Support original behavior with address on resourceUri argument.
*/
flags = (OCTransportFlags)(connectivityType & CT_MASK_FLAGS);
result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType);
+
if (result != OC_STACK_OK)
{
OC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri);
break;
case OC_REST_DISCOVER:
qos = OC_LOW_QOS;
- if (!destination && !devAddr)
+ if (destination || devAddr)
+ {
+ requestInfo.isMulticast = false;
+ }
+ else
{
+ tmpDevAddr.adapter = adapter;
+ tmpDevAddr.flags = flags;
destination = &tmpDevAddr;
+ requestInfo.isMulticast = true;
}
// CA_DISCOVER will become GET and isMulticast
requestInfo.method = CA_GET;
- requestInfo.isMulticast = true;
break;
#ifdef WITH_PRESENCE
case OC_REST_PRESENCE:
if (caResult != CA_STATUS_OK)
{
OC_LOG(ERROR, TAG, PCF("CAGenerateToken error"));
+ result= OC_STACK_ERROR;
goto exit;
}
requestInfo.info.token = token;
requestInfo.info.tokenLength = tokenLength;
requestInfo.info.resourceUri = resourceUri;
- requestInfo.info.payload = (char *)request;
+
if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL))
{
result = CreateObserveHeaderOption (&(requestInfo.info.options),
requestInfo.info.numOptions = numOptions;
}
- // create remote endpoint
- result = OCCreateEndpoint(devAddr, &endpoint);
+ CopyDevAddrToEndpoint(devAddr, &endpoint);
+
+ if(payload)
+ {
+ if((result =
+ OCConvertPayload(payload, &requestInfo.info.payload, &requestInfo.info.payloadSize))
+ != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("Failed to create CBOR Payload"));
+ goto exit;
+ }
+ }
+ else
+ {
+ requestInfo.info.payload = NULL;
+ requestInfo.info.payloadSize = 0;
+ }
+
if (result != OC_STACK_OK)
{
OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
if (method == OC_REST_PRESENCE)
{
char *presenceUri = NULL;
- result = OCPreparePresence(endpoint, resourceUri, &presenceUri);
+ result = OCPreparePresence(&endpoint, resourceUri, &presenceUri);
if (OC_STACK_OK != result)
{
goto exit;
}
- OICFree(resourceUri);
+
+ // Assign full presence uri as coap://ip:port/oic/ad to add to callback list.
+ // Presence notification will form a canonical uri to
+ // look for callbacks into the application.
resourceUri = presenceUri;
}
#endif
resourceType = NULL; // Client CB list entry now owns it
// send request
- caResult = CASendRequest(endpoint, &requestInfo);
+ caResult = CASendRequest(&endpoint, &requestInfo);
if (caResult != CA_STATUS_OK)
{
OC_LOG(ERROR, TAG, PCF("CASendRequest"));
}
OICFree(resHandle);
}
+
+ // This is the owner of the payload object, so we free it
+ OCPayloadDestroy(payload);
+ OICFree(requestInfo.info.payload);
OICFree(devAddr);
OICFree(resourceUri);
OICFree(resourceType);
- OICFree(endpoint);
if (hdrOptionMemAlloc)
{
OICFree(requestInfo.info.options);
* Remove the callback associated on client side.
*/
OCStackResult ret = OC_STACK_OK;
- CAEndpoint_t* endpoint = NULL;
+ CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
CAResult_t caResult;
- CAInfo_t requestData = {};
- CARequestInfo_t requestInfo = {};
+ CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
+ CARequestInfo_t requestInfo = {.method = CA_GET};
if(!handle)
{
return OC_STACK_INVALID_PARAM;
}
- OC_LOG(INFO, TAG, PCF("Entering OCCancel"));
-
ClientCB *clientCB = GetClientCB(NULL, 0, handle, NULL);
if (!clientCB)
{
{
case OC_REST_OBSERVE:
case OC_REST_OBSERVE_ALL:
- OC_LOG(INFO, TAG, PCF("Canceling observation"));
+ OC_LOG_V(INFO, TAG, "Canceling observation for resource %s",
+ clientCB->requestUri);
if (qos != OC_HIGH_QOS)
{
FindAndDeleteClientCB(clientCB);
break;
}
+ else
+ {
+ OC_LOG(INFO, TAG, PCF("Cancelling observation as CONFIRMABLE"));
+ }
requestData.type = qualityOfServiceToMessageType(qos);
requestData.token = clientCB->token;
return OC_STACK_ERROR;
}
requestData.numOptions = numOptions + 1;
+ requestData.resourceUri = OICStrdup (clientCB->requestUri);
+
requestInfo.method = CA_GET;
requestInfo.info = requestData;
- ret = OCCreateEndpoint(clientCB->devAddr, &endpoint);
- if (ret != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
- goto Error;
- }
+ CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint);
// send request
- caResult = CASendRequest(endpoint, &requestInfo);
+ caResult = CASendRequest(&endpoint, &requestInfo);
if (caResult != CA_STATUS_OK)
{
OC_LOG(ERROR, TAG, PCF("CASendRequest error"));
}
Error:
- OCDestroyEndpoint(endpoint);
if (requestData.numOptions > 0)
{
OICFree(requestData.options);
}
-
+ if (requestData.resourceUri)
+ {
+ OICFree (requestData.resourceUri);
+ }
return ret;
}
cbNode->presence->TTLlevel);
OC_LOG_V(DEBUG, TAG, "current ticks %d", now);
- if(cbNode->presence->TTLlevel >= (PresenceTimeOutSize + 1))
+ if (cbNode->presence->TTLlevel > PresenceTimeOutSize)
{
goto exit;
}
OC_LOG_V(DEBUG, TAG, "timeout ticks %d",
cbNode->presence->timeOut[cbNode->presence->TTLlevel]);
}
-
if (cbNode->presence->TTLlevel >= PresenceTimeOutSize)
{
OC_LOG(DEBUG, TAG, PCF("No more timeout ticks"));
clientResponse.result = OC_STACK_PRESENCE_TIMEOUT;
clientResponse.devAddr = *cbNode->devAddr;
FixUpClientResponse(&clientResponse);
- clientResponse.resJSONPayload = NULL;
+ clientResponse.payload = NULL;
// Increment the TTLLevel (going to a next state), so we don't keep
// sending presence notification to client.
}
CAResult_t caResult = CA_STATUS_OK;
- CAEndpoint_t* endpoint = NULL;
- CAInfo_t requestData ={};
- CARequestInfo_t requestInfo = {};
+ CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
+ CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
+ CARequestInfo_t requestInfo = {.method = CA_GET};
OC_LOG(DEBUG, TAG, PCF("time to test server presence"));
- result = OCCreateEndpoint(cbNode->devAddr, &endpoint);
- if (result != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, PCF("CACreateEndpoint error"));
- goto exit;
- }
+ CopyDevAddrToEndpoint(cbNode->devAddr, &endpoint);
requestData.type = CA_MSG_NONCONFIRM;
requestData.token = cbNode->token;
requestData.tokenLength = cbNode->tokenLength;
+ requestData.resourceUri = OC_RSRVD_PRESENCE_URI;
requestInfo.method = CA_GET;
requestInfo.info = requestData;
- caResult = CASendRequest(endpoint, &requestInfo);
- OCDestroyEndpoint(endpoint);
+ caResult = CASendRequest(&endpoint, &requestInfo);
if (caResult != CA_STATUS_OK)
{
{
OC_LOG(ERROR, TAG, PCF("OCProcessPresence error"));
}
+
return result;
}
#endif // WITH_PRESENCE
presenceState = OC_PRESENCE_INITIALIZED;
OCDevAddr devAddr = { OC_DEFAULT_ADAPTER };
- OICStrcpy(devAddr.addr, sizeof(devAddr.addr), OC_MULTICAST_IP);
- devAddr.port = OC_MULTICAST_PORT;
CAToken_t caToken = NULL;
CAResult_t caResult = CAGenerateToken(&caToken, tokenLength);
return OC_STACK_ERROR;
}
- AddObserver(OC_PRESENCE_URI, NULL, 0, caToken, tokenLength,
+ AddObserver(OC_RSRVD_PRESENCE_URI, NULL, 0, caToken, tokenLength,
(OCResource *)presenceResource.handle, OC_LOW_QOS, &devAddr);
CADestroyToken(caToken);
}
if(presenceResource.handle)
{
((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
- }
// make resource inactive
result = OCChangeResourceProperty(
&(((OCResource *) presenceResource.handle)->resourceProperties),
OC_ACTIVE, 0);
+ }
if(result != OC_STACK_OK)
{
// Validate parameters
if(!uri || uri[0]=='\0' || strlen(uri)>=MAX_URI_LENGTH )
{
- OC_LOG(ERROR, TAG, PCF("URI is invalid"));
+ OC_LOG(ERROR, TAG, PCF("URI is empty or too long"));
return OC_STACK_INVALID_URI;
}
// Is it presented during resource discovery?
- if (!handle || !resourceTypeName)
+ if (!handle || !resourceTypeName || resourceTypeName[0] == '\0' )
{
OC_LOG(ERROR, TAG, PCF("Input parameter is NULL"));
return OC_STACK_INVALID_PARAM;
// Make sure resourceProperties bitmask has allowed properties specified
if (resourceProperties
- > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE))
+ > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE |
+ OC_EXPLICIT_DISCOVERABLE))
{
OC_LOG(ERROR, TAG, PCF("Invalid property"));
return OC_STACK_INVALID_PARAM;
{
if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0)
{
- OC_LOG(ERROR, TAG, PCF("URI already in use"));
+ OC_LOG_V(ERROR, TAG, "Resource %s already exists", uri);
return OC_STACK_INVALID_PARAM;
}
pointer = pointer->next;
char *str = NULL;
OCStackResult result = OC_STACK_ERROR;
- OC_LOG(INFO, TAG, PCF("Entering BindResourceTypeToResource"));
-
- // Validate parameters
VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
- // TODO: Does resource attribute representation really have to be maintained in stack?
- // Is it presented during resource discovery?
- // Create the resourcetype and insert it into the resource list
pointer = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
if (!pointer)
{
goto exit;
}
- // Set the resourceTypeName
str = OICStrdup(resourceTypeName);
if (!str)
{
char *str = NULL;
OCStackResult result = OC_STACK_ERROR;
- OC_LOG(INFO, TAG, PCF("Entering BindResourceInterfaceToResource"));
-
- // Validate parameters
VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
- //TODO ("Make sure that the resourceinterface name doesn't already exist in the resource");
+ OC_LOG_V(INFO, TAG, "Binding %s interface to %s", resourceInterfaceName, resource->uri);
- // Create the resourceinterface and insert it into the resource list
pointer = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
if (!pointer)
{
goto exit;
}
- // Set the resourceinterface name
str = OICStrdup(resourceInterfaceName);
if (!str)
{
OCStackResult result = OC_STACK_ERROR;
OCResource *resource = NULL;
- // Make sure resource exists
resource = findResource((OCResource *) handle);
if (!resource)
{
return OC_STACK_ERROR;
}
- // call internal function
result = BindResourceTypeToResource(resource, resourceTypeName);
#ifdef WITH_PRESENCE
OCStackResult result = OC_STACK_ERROR;
OCResource *resource = NULL;
- // Make sure resource exists
resource = findResource((OCResource *) handle);
if (!resource)
{
return OC_STACK_ERROR;
}
- // call internal function
result = BindResourceInterfaceToResource(resource, resourceInterfaceName);
#ifdef WITH_PRESENCE
{
OCResource *pointer = headResource;
- OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResources"));
VERIFY_NON_NULL(numResources, ERROR, OC_STACK_INVALID_PARAM);
*numResources = 0;
while (pointer)
{
OCResource *pointer = headResource;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandle"));
-
- // Iterate through the list
for( uint8_t i = 0; i < index && pointer; ++i)
{
pointer = pointer->next;
OCStackResult OCDeleteResource(OCResourceHandle handle)
{
- OC_LOG(INFO, TAG, PCF("Entering OCDeleteResource"));
-
if (!handle)
{
- OC_LOG(ERROR, TAG, PCF("Invalid param"));
+ OC_LOG(ERROR, TAG, PCF("Invalid handle for deletion"));
return OC_STACK_INVALID_PARAM;
}
const char *OCGetResourceUri(OCResourceHandle handle)
{
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceUri"));
resource = findResource((OCResource *) handle);
if (resource)
OCResourceProperty OCGetResourceProperties(OCResourceHandle handle)
{
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceProperties"));
resource = findResource((OCResource *) handle);
if (resource)
OCResource *resource = NULL;
OCResourceType *pointer = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceTypes"));
VERIFY_NON_NULL(numResourceTypes, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
{
OCResourceType *resourceType = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceTypeName"));
-
resourceType = findResourceTypeAtIndex(handle, index);
if (resourceType)
{
OCResourceInterface *pointer = NULL;
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceInterfaces"));
-
VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(numResourceInterfaces, ERROR, OC_STACK_INVALID_PARAM);
{
OCResourceInterface *resourceInterface = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceInterfaceName"));
-
resourceInterface = findResourceInterfaceAtIndex(handle, index);
if (resourceInterface)
{
{
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetContainedResource"));
-
if (index >= MAX_CONTAINED_RESOURCES)
{
return NULL;
{
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCBindResourceHandler"));
-
// Validate parameters
VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
{
OCResource *resource = NULL;
- OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandler"));
-
- // Use the handle to find the resource in the resource linked list
resource = findResource((OCResource *)handle);
if (!resource)
{
#endif // WITH_PRESENCE
OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService qos)
{
-
- OC_LOG(INFO, TAG, PCF("Entering OCNotifyAllObservers"));
-
OCResource *resPtr = NULL;
OCStackResult result = OC_STACK_ERROR;
OCMethod method = OC_REST_NOMETHOD;
uint32_t maxAge = 0;
- OC_LOG(INFO, TAG, PCF("Entering OCNotifyAllObservers"));
+ OC_LOG(INFO, TAG, PCF("Notifying all observers"));
#ifdef WITH_PRESENCE
if(handle == presenceResource.handle)
{
OCNotifyListOfObservers (OCResourceHandle handle,
OCObservationId *obsIdList,
uint8_t numberOfIds,
- const char *notificationJSONPayload,
+ const OCRepPayload *payload,
OCQualityOfService qos)
{
OC_LOG(INFO, TAG, PCF("Entering OCNotifyListOfObservers"));
VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
VERIFY_NON_NULL(obsIdList, ERROR, OC_STACK_ERROR);
- VERIFY_NON_NULL(notificationJSONPayload, ERROR, OC_STACK_ERROR);
+ VERIFY_NON_NULL(payload, ERROR, OC_STACK_ERROR);
- // Verify that the resource exists
resPtr = findResource ((OCResource *) handle);
if (NULL == resPtr || myStackMode == OC_CLIENT)
{
incrementSequenceNumber(resPtr);
}
return (SendListObserverNotification(resPtr, obsIdList, numberOfIds,
- notificationJSONPayload, maxAge, qos));
+ payload, maxAge, qos));
}
OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
VERIFY_NON_NULL(ehResponse, ERROR, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(ehResponse->requestHandle, ERROR, OC_STACK_INVALID_PARAM);
- // TODO: Placeholder for creating a response entry when implementing
- // block transfer feature
-
- // If a response payload is present, check if block transfer is required
- if (ehResponse->payload && OCIsPacketTransferRequired(NULL,
- (const char *)ehResponse->payload, ehResponse->payloadSize))
- {
- OC_LOG(INFO, TAG, PCF("Block transfer required"));
-
- // Persistent response buffer is needed for block transfer
- if (!ehResponse->persistentBufferFlag)
- {
- OC_LOG(WARNING, TAG, PCF("Persistent response buffer required"));
- return OC_STACK_PERSISTENT_BUFFER_REQUIRED;
- }
- // TODO: Placeholder for block transfer handling
- // TODO: Placeholder for setting the the response handle in the OCServerResponse struct
- // when implementing the block transfer feature
- }
- else
+ // Normal response
+ // Get pointer to request info
+ serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
+ if(serverRequest)
{
- // Normal response
- // Get pointer to request info
- serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
- if(serverRequest)
- {
- result = serverRequest->ehResponseHandler(ehResponse);
- }
+ // response handler in ocserverrequest.c. Usually HandleSingleResponse.
+ result = serverRequest->ehResponseHandler(ehResponse);
}
+
return result;
}
OCStackResult initResources()
{
OCStackResult result = OC_STACK_OK;
- // Init application resource vars
+
headResource = NULL;
tailResource = NULL;
// Init Virtual Resources
#ifdef WITH_PRESENCE
presenceResource.presenceTTL = OC_DEFAULT_PRESENCE_TTL_SECONDS;
- //presenceResource.token = OCGenerateCoAPToken();
+
result = OCCreateResource(&presenceResource.handle,
OC_RSRVD_RESOURCE_TYPE_PRESENCE,
"core.r",
- OC_PRESENCE_URI,
+ OC_RSRVD_PRESENCE_URI,
NULL,
NULL,
OC_OBSERVABLE);
{
OCResource *prev = NULL;
OCResource *temp = NULL;
+ if(!resource)
+ {
+ OC_LOG_V(DEBUG,TAG,"resource is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OC_LOG_V (INFO, TAG, "Deleting resource %s", resource->uri);
temp = headResource;
while (temp)
return;
}
- // remove URI
OICFree(resource->uri);
-
- // Delete resourcetype linked list
deleteResourceType(resource->rsrcType);
-
- // Delete resourceinterface linked list
deleteResourceInterface(resource->rsrcInterface);
}
while (pointer)
{
- // resource type already exists. Free 2nd arg and return.
if (!strcmp(resourceType->resourcetypename, pointer->resourcetypename))
{
+ OC_LOG_V(INFO, TAG, "Type %s already exists", resourceType->resourcetypename);
OICFree(resourceType->resourcetypename);
OICFree(resourceType);
return;
previous->next = resourceType;
}
resourceType->next = NULL;
+
+ OC_LOG_V(INFO, TAG, "Added type %s to %s", resourceType->resourcetypename, resource->uri);
}
OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle, uint8_t index)
return pointer;
}
- bool OCIsPacketTransferRequired(const char *request, const char *response, size_t size)
- {
- bool result = false;
-
- // Determine if we are checking a request or a response
- if (request)
- {
- // If size is greater than 0, use it for the request size value, otherwise
- // assume request is null terminated and use strlen for size value
- if ((size > MAX_REQUEST_LENGTH) || (strlen(request) > MAX_REQUEST_LENGTH))
- {
- result = true;
- }
- }
- else if (response)
- {
- // If size is greater than 0, use it for the response size value, otherwise
- // assume response is null terminated and use strlen for size value
- if ((size > MAX_RESPONSE_LENGTH) || (strlen(response) > MAX_RESPONSE_LENGTH))
- {
- result = true;
- }
- }
- return result;
- }
-
/*
* This function splits the uri using the '?' delimiter.
* "uriWithoutQuery" is the block of characters between the beginning
char *pointerToDelimiter = strstr(uri, "?");
- uriWithoutQueryLen = pointerToDelimiter == NULL ? uriLen : pointerToDelimiter - uri;
+ uriWithoutQueryLen = pointerToDelimiter == NULL ? uriLen : (size_t)(pointerToDelimiter - uri);
queryLen = pointerToDelimiter == NULL ? 0 : uriLen - uriWithoutQueryLen - 1;
if (uriWithoutQueryLen)
CATransportAdapter_t connTypes[] = {
CA_ADAPTER_IP,
CA_ADAPTER_RFCOMM_BTEDR,
- CA_ADAPTER_GATT_BTLE};
+ CA_ADAPTER_GATT_BTLE
+
+ #ifdef RA_ADAPTER
+ ,CA_ADAPTER_REMOTE_ACCESS
+ #endif
+ };
int numConnTypes = sizeof(connTypes)/sizeof(connTypes[0]);
for(int i = 0; i<numConnTypes; i++)
target_os = env.get('TARGET_OS')
-if target_os not in ['arduino','darwin','ios']:
+#if target_os not in ['arduino','darwin']:
# Build things manager project
- SConscript('things-manager/SConscript')
+ #SConscript('things-manager/SConscript')
# Build soft sensor manager project
- SConscript('soft-sensor-manager/SConscript')
+ #SConscript('soft-sensor-manager/SConscript')
# Build protocol plugin project
# protocol-plugin use 'inotify', this feature isn't support by MAC OSX
- if target_os not in ['darwin', 'ios']:
- SConscript('protocol-plugin/SConscript')
+ #if target_os not in ['darwin', 'ios', 'android']:
+ # SConscript('protocol-plugin/SConscript')
# Build notification manager project
- if target_os not in ['android', 'tizen']:
- SConscript('notification-manager/SConscript')
+ #SConscript('notification-manager/SConscript')
+
+if target_os in ['arduino','android', 'linux']:
+ SConscript('easy-setup/SConscript')
++ #if target_os not in ['android', 'tizen']:
++ #SConscript('notification-manager/SConscript')
+
+ # Build resource-encapsulation project
- SConscript('resource-encapsulation/SConscript')
++ #if target_os not in ['tizen']:
++ #SConscript('resource-encapsulation/SConscript')
+ #else:
+ # SConscript('notification-manager/SampleApp/arduino/SConscript')
+
++#if target_os in ['arduino','android', 'linux']:
++ #SConscript('easy-setup/SConscript')
--- /dev/null
+#******************************************************************
+#
+# Copyright 2014 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# easy-setup project build script
+##
+
+import os
+
+Import('env')
+
+env.AppendUnique(CPPDEFINES = ['EASY_SETUP_CA_INIT'])
+
+easy_setup_env = env.Clone()
+target_os = env.get('TARGET_OS')
+
+lib_env = env.Clone()
+if target_os == 'android':
+ SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
+######################################################################
+# Build flags
+######################################################################
+easy_setup_env.AppendUnique(CPPPATH = ['sdk/inc', 'sdk/src', 'sdk/common'])
+
+if target_os not in ['windows', 'winrt']:
+ easy_setup_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+ if target_os not in ['android', 'arduino']:
+ easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
+
+if target_os in ['android', 'linux']:
+ easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+ easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+ easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+ if target_os not in ['linux', 'arduino']:
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared'])
+ if not env.get('RELEASE'):
+ easy_setup_env.AppendUnique(LIBS = ['log'])
+ else:
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction'])
+
+if target_os == 'arduino':
+ easy_setup_env.AppendUnique(CPPPATH = [
+ '../../resource/oc_logger/include',
+ '../../resource/csdk/logger/include',
+ '../../resource/csdk/stack/include',
+ '../../extlibs/cjson',
+ 'sdk/enrollee/arduino/wifi',
+ 'sdk/enrollee/common/src',
+ 'sdk/enrollee/common/inc'])
+
+if target_os in ['android','linux']:
+ easy_setup_env.PrependUnique(CPPPATH = [
+ env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include',
+ env.get('SRC_DIR') + '/resource/csdk/connectivity/common/inc',
+ env.get('SRC_DIR') + '/resource/csdk/connectivity/api',
+ env.get('SRC_DIR') + '/resource/csdk/stack/include',
+ env.get('SRC_DIR') + '/resource/csdk/logger/include',
+ env.get('SRC_DIR') + '/resource/csdk/security/include',
+ env.get('SRC_DIR') + '/extlibs/cjson',
+ 'sdk/common',
+ 'sdk/mediator/inc'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+
+if target_os == 'arduino':
+ es_sdk_static = easy_setup_env.StaticLibrary('ESSDKLibrary',
+ ['sdk/enrollee/common/src/easysetup.cpp',
+ 'sdk/enrollee/common/src/resourceHandler.cpp',
+ 'sdk/enrollee/arduino/wifi/networkHandler.cpp'])
+ easy_setup_env.InstallTarget(es_sdk_static, 'libESSDK')
+
+
+if target_os == 'android':
+ es_sdk_shared = easy_setup_env.StaticLibrary('libESSDK',
+ ['sdk/mediator/src/easysetupmgr.cpp',
+ 'sdk/mediator/src/camutex_pthreads.c',
+ 'sdk/mediator/src/provisioninghandler.cpp'])
+ easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
+
+if target_os == 'linux':
+ es_sdk_shared = easy_setup_env.SharedLibrary('ESSDKLibrary',
+ ['sdk/mediator/src/easysetupmgr.cpp',
+ 'sdk/mediator/src/camutex_pthreads.c',
+ 'sdk/mediator/src/provisioninghandler.cpp'])
+ easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
+
+#Go to build sample apps
+SConscript('sampleapp/SConscript')
+
+
--- /dev/null
- <iotivity-root>/service/easy-setup/sdk/android
+
+Steps to build and deploy Easysetup Mediator in Android platform
+
+1) Compilation using Scons
+ 0) Prerequisite exports for Android
+ export ANDROID_HOME=<ANDROID_HOME>
+ export ANDROID_NDK=<ANDROID_NDK>
+ a) In the IoTivity root source folder execute
+ scons TARGET_OS=android TARGET_ARCH=armeabi TARGET_TRANSPORT=IP RELEASE=0
+
+ b) If the project is setup correctly, you should see a BUILD SUCCESSFUL message on the terminal
+ You should see the .aar files generated inside of '<iotivity>/android/android_api/base/build/outputs/aar' directory. The .aar files contain jni directory and also a .jar file
+
+ c) Now navigate to the Easysetup NDK folder
++ <iotivity-root>/service/easy-setup/sdk/mediator/android
+
+ d) Execute NDK-Build with the following command to cross compiled Easysetup JNI .so files
+ ~/madan/android-ndk-r10d/ndk-build
+
+ e) Step (d) will generate cross compiled Easysetup JNI .so files in the following folder
+
+2) Compilation using Android Studio
+
+ 0) Prerequisite for running the Android application
+ Install Android Studio and use the Android SDK manager to update the Android API to 21
+
+ a) Import following projects to the Studio using the "File->New->Import Project"
+ - service\easy-setup\sdk\android\EasySetupCore
+ - service\easy-setup\sampleapp\android\EasySetup
+
+ b) EasySetupCore is dependent on the .aar files generated in 1.b
+ 1) To add an .aar file to the 'EasySetupCore' project,
+ a.Right click on EasySetup->New->Module->Import .JAR or .AAR Package
+ b.Select the .aar file(iotivity-armeabi-base-*.aar) from the location in steps 1.b
+ c.Right click on EasySetup->Open Module Settings
+ d.Select each sample app module under 'Modules'->Dependencies->Add->Module Dependency
+
+ c) Build EasySetupCore project using "Android Studio->Build->Make Module "easySetupCore"
+ If the project is setup correctly, you should see a BUILD SUCCESSFUL in the Android Studio Gradle Build terminal
+ You should see the .aar file generated inside of
+ 'iotivity\service\easy-setup\sdk\mediator\android\easySetupCore\build\outputs\aar'
+
+ d) EasySetup application is also dependent on the .so files generated in 1.d step
+ 1) Drag and drop the following .so files in to the EasySetup\app\src\main\jniLibs\armeabi folder
+ - libeasysetup-jni.so [Easy Setup file]
+
+ e) EasySetup is also dependent on the .aar files generated in 1.b and 2.c steps
+ 1) To add an .aar file to the 'EasySetup' project,
+ a.Right click on EasySetup->New->Module->Import .JAR or .AAR Package
+ b.Select the .aar file from the location in steps 1.b and 2.b above
+ c.Right click on EasySetup->Open Module Settings
+ d.Select each sample app module under 'Modules'->Dependencies->Add->Module Dependency
+ e.The .aar files (easySetupCore-*.aar & iotivity-armeabi-base-*.aar) selected in step 2.c.1.b above should be present. Select it.
+
+
+ e) Run "Easy Setup" as an Android application
+
+Folder structure
+iotivity/
+└── service
+ └── easy-setup/
+ │── SConscript
+ │── sdk
+ │ └── inc
+ │ └── src
+ │ └── android
+ │ └── arduino
+ │ └──wifi
+ │ └──inc
+ │ └──src
+ │── sampleapp
+ │ └──android
+ │ └──arduino
+ │ └──linux
+ └── README - You are reading this.
+
+
--- /dev/null
- thinserver_env.PrependUnique(LIBS = ['octbstack', 'connectivity_abstraction','coap', 'ESSDKLibrary'])
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+
+thinserver_env = env.Clone()
+######################################################################
+# Build flags
+######################################################################
+thinserver_env.PrependUnique(CPPPATH = [
+ '../../../../../resource/oc_logger/include',
+ '../../../../../resource/csdk/logger/include',
+ '../../../../../resource/csdk/stack/include',
+ '../../../../../extlibs/cjson',
+ '../../../sdk/common',
+ '../../../sdk/enrollee/arduino/wifi',
+ '../../../sdk/enrollee/common/inc',
+ '../../../sdk/enrollee/common/src'
+ ])
+
+thinserver_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+thinserver_env.AppendUnique(CPPDEFINES = ['TB_LOG', 'ARDUINOWIFI'])
+
++thinserver_env.PrependUnique(LIBS = ['octbstack','ocsrm','connectivity_abstraction','coap', 'ESSDKLibrary'])
+
+thinserver = thinserver_env.Program('thinserver', 'thinserver.cpp')
+env.CreateBin('thinserver')
+
+i_thinserver = thinserver_env.Install(env.get('BUILD_DIR'), thinserver)
+
+Alias('thinserver', i_thinserver)
+env.AppendTarget('thinserver')
+
+if(thinserver_env['UPLOAD'] == True):
+ from sys import platform as _platform
+ if _platform == "linux" or _platform == "linux2":
+ thinserver_env.Upload(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/arduino/thinserver/thinserver.hex')
+ else:
+ print 'Please use appropriate install method for your developing machine. Linux is the only supported platform right now.'
--- /dev/null
- char ssid[] = "hub2.4G";
- char passwd[] = "09877890";
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+#include "easysetup.h"
+
+const char *getResult(OCStackResult result);
+
+PROGMEM const char TAG[] = "ThinServer";
+
- if (OCStartPresence(0) != OC_STACK_OK)
++char ssid[] = "EasySetup123";
++char passwd[] = "EasySetup123";
+
+void EventCallbackInApp(ES_RESULT eventFlag)
+{
+ Serial.println("callback!!! in app");
+}
+
+// On Arduino Atmel boards with Harvard memory architecture, the stack grows
+// downwards from the top and the heap grows upwards. This method will print
+// the distance(in terms of bytes) between those two.
+// See here for more details :
+// http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
+void PrintArduinoMemoryStats()
+{
+#ifdef ARDUINO_AVR_MEGA2560
+ //This var is declared in avr-libc/stdlib/malloc.c
+ //It keeps the largest address not allocated for heap
+ extern char *__brkval;
+ //address of tmp gives us the current stack boundry
+ int tmp;
+ OC_LOG_V(INFO, TAG, "Stack: %u Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
+ OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
+ ((unsigned int)&tmp - (unsigned int)__brkval));
+#endif
+}
+//The setup function is called once at startup of the sketch
+void setup()
+{
+ // Add your initialization code here
+ // Note : This will initialize Serial port on Arduino at 115200 bauds
+ OC_LOG_INIT();
+ OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
+
+ FindNetworkForOnboarding(ES_WIFI, ssid, passwd, EventCallbackInApp);
+
+ // Initialize the OC Stack in Server mode
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("OCStack init error"));
+ return;
+ }
+
+ InitializeProvisioning(EventCallbackInApp);
+
++ /* if (OCStartPresence(0) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("Start Presence init error"));
+ return;
+ }
++ */
+}
+
+// The loop function is called in an endless loop
+void loop()
+{
+ // This artificial delay is kept here to avoid endless spinning
+ // of Arduino microcontroller. Modify it as per specific application needs.
+ delay(2000);
+
+ // This call displays the amount of free SRAM available on Arduino
+ PrintArduinoMemoryStats();
+
+ // Give CPU cycles to OCStack to perform send/recv and other OCStack stuff
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, PCF("OCStack process error"));
+ return;
+ }
+}
--- /dev/null
-
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef ES_COMMON_H_
+#define ES_COMMON_H_
+
+#include "ocstack.h"
+#include "octypes.h"
+
+// Defines
+#define OIC_STRING_MAX_VALUE 100
+#define IPV4_ADDR_SIZE 16
+#define IP_PORT 6298
+#define NET_WIFI_SSID_SIZE 16
+#define NET_WIFI_PWD_SIZE 16
+
+/**
+ * @brief Mac address length for BT port
+ */
+#define NET_MACADDR_SIZE 18
+
+//The following variable determines the interface (wifi, ethernet etc.)
+//to be used for sending unicast messages. Default set to Ethernet.
+static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
+
+static const char * UNICAST_PROVISIONING_QUERY = "coap://%s:%d/oic/res?rt=oic.prov";
+static const char * UNICAST_PROV_STATUS_QUERY = "coap://%s:%d%s";
+
+
+/**
+ * Attributes used to form a proper easysetup conforming JSON message.
+ */
+#define OC_RSRVD_ES_PS "ps"
+#define OC_RSRVD_ES_TNN "tnn"
+#define OC_RSRVD_ES_CD "cd"
++#define OC_RSRVD_ES_TR "tr"
++#define OC_RSRVD_ES_TNT "tnt"
++#define OC_RSRVD_ES_ANT "ant"
++#define OC_RSRVD_ES_URI_PROV "/oic/prov"
++#define OC_RSRVD_ES_URI_NET "/oic/net"
+
+
+
+typedef enum
+{
+ ES_ERROR = -1,
+ ES_OK = 0,
+ ES_NETWORKFOUND = 1,
+ ES_NETWORKCONNECTED,
+ ES_NETWORKNOTCONNECTED,
+ ES_RESOURCECREATED = 11,
+ ES_RECVREQOFPROVRES = 21,
+ ES_RECVREQOFNETRES,
+ ES_RECVUPDATEOFPROVRES,
+ ES_RECVTRIGGEROFPROVRES,
+} ES_RESULT;
+
+
+/**
+ * Provisioning Device Status
+ */
+typedef struct {
+ /// Address of remote server
+ OCDevAddr * addr;
+ /// Indicates adaptor type on which the response was received
+ OCConnectivityType connType;
+} ProvDeviceInfo;
+
+/**
+ * Provosioning Status
+ */
+typedef enum {
+ DEVICE_PROVISIONED = 0, DEVICE_NOT_PROVISIONED
+} ProvStatus;
+
+/**
+ * Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
+ */
+typedef struct {
+ // Provisioning Status
+ ProvStatus provStatus;
+ // Provisioning Device Info
+ ProvDeviceInfo provDeviceInfo;
+} ProvisioningInfo;
+
+/**
+ * @brief Network information of the Enroller
+ */
+typedef union
+{
+ /**
+ * @brief BT Mac Information
+ */
+ struct
+ {
+ char btMacAddress[NET_MACADDR_SIZE]; /**< BT mac address **/
+ } BT;
+
+ /**
+ * @brief LE MAC Information
+ */
+ struct
+ {
+ char leMacAddress[NET_MACADDR_SIZE]; /**< BLE mac address **/
+ } LE;
+
+ /**
+ * @brief IP Information
+ */
+ struct
+ {
+ char ipAddress[IPV4_ADDR_SIZE]; /**< IP Address of the Enroller**/
+ char ssid[NET_WIFI_SSID_SIZE]; /**< ssid of the Enroller**/
+ char pwd[NET_WIFI_PWD_SIZE]; /**< pwd of the Enroller**/
+ } WIFI;
+} EnrolleeInfo_t;
+
+
+/**
+ * @brief Network Information
+ */
+typedef struct
+{
+ EnrolleeInfo_t netAddressInfo; /**< Enroller Network Info**/
+ OCConnectivityType connType; /**< Connectivity Type**/
+ bool isSecured; /**< Secure connection**/
+} EnrolleeNWProvInfo_t;
+
+/**
+ * Client applications implement this callback to consume responses received from Servers.
+ */
+typedef void (*OCProvisioningStatusCB)(ProvisioningInfo *provInfo);
+
+#endif
--- /dev/null
- return ES_ERROR;
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "networkHandler.h"
+
+PROGMEM const char TAG[] = "networkHandler";
+
+int findNetwork(const char *ssid);
+int ConnectToNetwork(const char *ssid, const char *pass);
+void printEncryptionType(int thisType);
+
+// Arduino WiFi Shield
+// Note : Arduino WiFi Shield currently does NOT support multicast and therefore
+// this server will NOT be listening on 224.0.1.187 multicast address.
+
+static const char ARDUINO_WIFI_SHIELD_UDP_FW_VER[] = "1.1.0";
+
+IPAddress myIP;
+
+ES_RESULT ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback cb)
+{
+ char *fwVersion;
+ int status = WL_IDLE_STATUS;
+ int res;
+
+ // check for the presence of the shield:
+ if (WiFi.status() == WL_NO_SHIELD)
+ {
+ OC_LOG(ERROR, TAG, PCF("WiFi shield not present"));
+ return ES_ERROR;
+ }
+
+ // Verify that WiFi Shield is running the firmware with all UDP fixes
+ fwVersion = WiFi.firmwareVersion();
+ OC_LOG_V(INFO, TAG, "WiFi Shield Firmware version %s", fwVersion);
+ if (strncmp(fwVersion, ARDUINO_WIFI_SHIELD_UDP_FW_VER, sizeof(ARDUINO_WIFI_SHIELD_UDP_FW_VER))
+ != 0)
+ {
+ OC_LOG(DEBUG, TAG, PCF("!!!!! Upgrade WiFi Shield Firmware version !!!!!!"));
++ //return ES_ERROR;
+ }
+
+ while (findNetwork(ssid) == 0) // found
+ {
+ delay(1000);
+ }
+
+ if (cb != NULL)
+ {
+ cb(ES_NETWORKFOUND);
+ }
+
+ if (WiFi.status() == WL_CONNECTED)
+ WiFi.disconnect();
+
+ res = ConnectToNetwork(ssid, pass);
+
+ if (res == 0)
+ {
+ return ES_NETWORKCONNECTED;
+ }
+ else
+ {
+ return ES_NETWORKNOTCONNECTED;
+ }
+}
+
+int findNetwork(const char *ssid)
+{
+ int res = 0;
+ // scan for nearby networks:
+ Serial.println("** Scan Networks **");
+ int numSsid = WiFi.scanNetworks();
+ if (numSsid == -1)
+ {
+ Serial.println("Couldn't get a wifi connection");
+
+ return res;
+ }
+
+ // print the list of networks seen:
+ Serial.print("number of available networks:");
+ Serial.println(numSsid);
+
+ // print the network number and name for each network found:
+ for (int thisNet = 0; thisNet < numSsid; thisNet++)
+ {
+ Serial.print(thisNet);
+ Serial.print(") ");
+ Serial.print(WiFi.SSID(thisNet));
+ Serial.print("\tEncryption: ");
+ printEncryptionType(WiFi.encryptionType(thisNet));
+
+ if (strcmp(WiFi.SSID(thisNet), ssid) == 0)
+ {
+ res = 1;
+ }
+ }
+
+ return res;
+}
+
+int ConnectToNetwork(const char *ssid, const char *pass)
+{
+ int status = WL_IDLE_STATUS;
+
+ // attempt to connect to Wifi network:
+ while (status != WL_CONNECTED)
+ {
+ OC_LOG_V(INFO, TAG, "Attempting to connect to SSID: %s", ssid);
+
+ status = WiFi.begin((char *) ssid, (char *) pass);
+
+ // wait 10 seconds for connection:
+ delay(10000);
+ }
+ OC_LOG(DEBUG, TAG, PCF("Connected to wifi"));
+
+ myIP = WiFi.localIP();
+ OC_LOG_V(INFO, TAG, "IP Address: %d.%d.%d.%d", myIP[0], myIP[1], myIP[2], myIP[3]);
+
+ char buf[50];
+ sprintf(buf, "IP Address: %d.%d.%d.%d", myIP[0], myIP[1], myIP[2], myIP[3]);
+ Serial.println(buf);
+
+ return 0;
+}
+
+int getCurrentNetworkInfo(NetworkType targetType, NetworkInfo *info)
+{
+ if (targetType == ES_WIFI && WiFi.status() == WL_CONNECTED)
+ {
+ info->type = ES_WIFI;
+ info->ipaddr = WiFi.localIP();
+ strcpy(info->ssid, WiFi.SSID());
+
+ return 0;
+ }
+
+ return -1;
+}
+
+void printEncryptionType(int thisType)
+{
+ // read the encryption type and print out the name:
+ switch (thisType)
+ {
+ case ENC_TYPE_WEP:
+ Serial.println("WEP");
+ break;
+ case ENC_TYPE_TKIP:
+ Serial.println("WPA");
+ break;
+ case ENC_TYPE_CCMP:
+ Serial.println("WPA2");
+ break;
+ case ENC_TYPE_NONE:
+ Serial.println("None");
+ break;
+ case ENC_TYPE_AUTO:
+ Serial.println("Auto");
+ break;
+ }
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+
+#include "common.h"
+
+#ifndef ES_NETWORK_HANDLER_H_
+#define ES_NETWORK_HANDLER_H_
+
+#define MAXSSIDLEN 33
+#define MAXNETCREDLEN 20
+#define MAXNUMTYPE 5
+#define MAXADDRLEN 15
+
+typedef void (*NetworkEventCallback)(ES_RESULT);
+
+enum NetworkType
+{
+ ES_WIFI = 1, ES_BT = 2, ES_BLE = 3, ES_ZIGBEE = 4, ES_ETH = 5
+};
+
+typedef struct NETWORKINFO
+{
+ NetworkType type;
+
+ // for WiFI
+ IPAddress ipaddr;
+ char ssid[MAXSSIDLEN];
+
+ // for BT, BLE
+ byte mac[6];
+} NetworkInfo;
+
+ES_RESULT ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback);
+int getCurrentNetworkInfo(NetworkType targetType, NetworkInfo *info);
+
+#endif
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#include "common.h"
+#include "networkHandler.h"
+#include "resourceHandler.h"
+
+typedef void (*EventCallback)(ES_RESULT);
+
+OCStackResult Init();
+
+ES_RESULT FindNetworkForOnboarding(NetworkType networkType, EventCallback);
+ES_RESULT FindNetworkForOnboarding(NetworkType networkType, const char *name, const char *pass,
+ EventCallback);
+
+//OCStackResult FindNetworkForOnboarding(NetworkType networkType, char *name);
+//OCStackResult FindNetworkForOnboarding(NetworkType networkType, char *name, char *pass);
+
+ES_RESULT InitializeProvisioning(EventCallback);
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#include "common.h"
+#include "networkHandler.h"
+#include "octypes.h"
+
+#ifndef ES_RESOURCE_HANDLER_H_
+#define ES_RESOURCE_HANDLER_H_
+
+typedef void (*ResourceEventCallback)(ES_RESULT);
+
+/* Structure to represent a Light resource */
+typedef struct PROVRESOURCE
+{
+ OCResourceHandle handle;
+ int ps; // provisiong status, 1 : need to provisioning, 2 : Connected to Internet
+ int tnt; // target network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+ char tnn[MAXSSIDLEN]; // target network name, i.e. SSID for WLAN, MAC address for BT
+ char cd[MAXNETCREDLEN]; // credential information
+} ProvResource;
+
+/* Structure to represent a Light resource */
+typedef struct NETRESOURCE
+{
+ OCResourceHandle handle;
+ int cnt; // current network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+ int ant[MAXNUMTYPE]; // available network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+ char ipaddr[MAXADDRLEN]; // ip address
+ char cnn[MAXSSIDLEN]; // current network name
+} NetResource;
+
+OCStackResult CreateProvisioningResource();
+OCStackResult CreateNetworkResource();
+void GetTargetNetworkInfoFromProvResource(char *, char *);
+void RegisterResourceEventCallBack(ResourceEventCallback);
+
+#endif
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "easysetup.h"
+
+/// WiFi network info and credentials
+char defaultSsid[] = "EasyConnect";
+char defaultPass[] = "EasyConnect";
+
+int g_eventflag = 0;
+int g_cnt = 0;
+char *targetSsid;
+char *targetPass;
+
+EventCallback g_cbForProvisioning = NULL;
+EventCallback g_cbForOnboarding = NULL;
+
+void EventCallbackInOnboarding(ES_RESULT event);
+void EventCallbackInProvisioning(ES_RESULT event);
+void EventCallbackAfterProvisioning(ES_RESULT event);
+
+void EventCallbackInOnboarding(ES_RESULT event)
+{
+ if (event == ES_NETWORKFOUND || event == ES_NETWORKCONNECTED)
+ {
+ if (g_cbForOnboarding != NULL)
+ {
+ g_cbForOnboarding(event);
+ }
+ }
+}
+
+void EventCallbackInProvisioning(ES_RESULT event)
+{
+ ES_RESULT res = ES_OK;
+
+ if (event == ES_RECVTRIGGEROFPROVRES)
+ {
+ targetSsid = (char *) malloc(MAXSSIDLEN);
+ targetPass = (char *) malloc(MAXNETCREDLEN);
+
+ GetTargetNetworkInfoFromProvResource(targetSsid, targetPass);
+
+ res = ConnectToWiFiNetwork(targetSsid, targetPass, EventCallbackAfterProvisioning);
+
+ if (g_cbForProvisioning != NULL)
+ {
+ g_cbForProvisioning(res);
+ }
+ }
+}
+
+void EventCallbackAfterProvisioning(ES_RESULT event)
+{
+ if (event == ES_NETWORKFOUND || event == ES_NETWORKCONNECTED)
+ {
+ if (g_cbForProvisioning != NULL)
+ {
+ g_cbForProvisioning(event);
+ }
+ }
+}
+
+ES_RESULT FindNetworkForOnboarding(NetworkType networkType, EventCallback cb)
+{
+ if (networkType == ES_WIFI)
+ {
+ if (g_cbForOnboarding == NULL)
+ {
+ g_cbForOnboarding = cb;
+ }
+
+ return ConnectToWiFiNetwork(defaultSsid, defaultPass, EventCallbackInOnboarding);
+ }
+}
+
+ES_RESULT FindNetworkForOnboarding(NetworkType networkType, const char *ssid, const char *passwd,
+ EventCallback cb)
+{
+ if (!ssid || !passwd)
+ {
+ return ES_ERROR;
+ }
+
+ if (networkType == ES_WIFI)
+ {
+ if (g_cbForOnboarding == NULL)
+ {
+ g_cbForOnboarding = cb;
+ }
+
+ return ConnectToWiFiNetwork(ssid, passwd, EventCallbackInOnboarding);
+ }
+}
+
+ES_RESULT InitializeProvisioning(EventCallback cb)
+{
+ if (cb == NULL)
+ {
+ return ES_ERROR;
+ }
+ else
+ {
+ g_cbForProvisioning = cb;
+ }
+
+ if (CreateProvisioningResource() != OC_STACK_OK)
+ {
+ return ES_ERROR;
+ }
+
+ if (CreateNetworkResource() != OC_STACK_OK)
+ {
+ return ES_ERROR;
+ }
+
+ RegisterResourceEventCallBack(EventCallbackInProvisioning);
+
+ return ES_RESOURCECREATED;
+}
+
--- /dev/null
- #include "cJSON.h"
+//******************************************************************
+//
+// Copyright 2014 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "resourceHandler.h"
- OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *);
++#include "ocpayload.h"
+
+PROGMEM const char TAG[] = "resourceHandler";
+
+ProvResource g_prov;
+NetResource g_net;
+
- OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize);
- char* constructJsonResponse(OCEntityHandlerRequest *ehRequest);
-
++OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *, void *callback);
+const char *getResult(OCStackResult result);
+
- g_cbForResEvent = cb;
++OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
++OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
+int g_flag = 0;
+
+ResourceEventCallback g_cbForResEvent = NULL;
+
+void RegisterResourceEventCallBack(ResourceEventCallback cb)
+{
- if (name != NULL && pass != NULL)
- {
- sprintf(name, "%s", g_prov.tnn);
- sprintf(pass, "%s", g_prov.cd);
- }
++ g_cbForResEvent = cb;
+}
+
+void GetTargetNetworkInfoFromProvResource(char *name, char *pass)
+{
- g_prov.ps = 1; // need to provisioning
- g_prov.tnt = ES_WIFI;
- sprintf(g_prov.tnn, "Unknown");
- sprintf(g_prov.cd, "Unknown");
++ if (name != NULL && pass != NULL)
++ {
++ sprintf(name, "%s", g_prov.tnn);
++ sprintf(pass, "%s", g_prov.cd);
++ }
+}
+
+OCStackResult CreateProvisioningResource()
+{
- OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
- "/oic/prov", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
++ g_prov.ps = 1; // need to provisioning
++ g_prov.tnt = ES_WIFI;
++ sprintf(g_prov.tnn, "Unknown");
++ sprintf(g_prov.cd, "Unknown");
+
- OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
++ OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
++ OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
+
- return res;
++ OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
+
- NetworkInfo netInfo;
++ return res;
+}
+
+OCStackResult CreateNetworkResource()
+{
- if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
- {
- return OC_STACK_ERROR;
- }
++ NetworkInfo netInfo;
+
- if (netInfo.type != ES_WIFI)
- {
- return OC_STACK_ERROR;
- }
++ if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
++ {
++ return OC_STACK_ERROR;
++ }
+
- g_net.cnt = (int) netInfo.type;
- g_net.ant[0] = (int) ES_WIFI;
- sprintf(g_net.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1], netInfo.ipaddr[2],
- netInfo.ipaddr[3]);
- sprintf(g_net.cnn, "%s", netInfo.ssid);
++ if (netInfo.type != ES_WIFI)
++ {
++ return OC_STACK_ERROR;
++ }
+
- OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
- OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
++ g_net.cnt = (int) netInfo.type;
++ g_net.ant[0] = (int) ES_WIFI;
++ sprintf(g_net.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1], netInfo.ipaddr[2],
++ netInfo.ipaddr[3]);
++ sprintf(g_net.cnn, "%s", netInfo.ssid);
+
- OCStackResult res = OCCreateResource(&g_net.handle, "oic.net", OC_RSRVD_INTERFACE_DEFAULT,
- "/oic/net", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
- OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
++ OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
++ OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
+
- return res;
++ OCStackResult res = OCCreateResource(&g_net.handle, "oic.net", OC_RSRVD_INTERFACE_DEFAULT,
++ OC_RSRVD_ES_URI_NET, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
++ OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
+
- OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++ return res;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
-
- char *getResp = constructJsonResponse(ehRequest);
-
- if (!getResp)
- {
- OC_LOG(ERROR, TAG, "constructJsonResponse failed");
- return OC_EH_ERROR;
- }
-
- if (MAX_RESPONSE_LENGTH > strlen(getResp))
- {
- strncpy(payload, getResp, strlen(getResp));
- ehResult = OC_EH_OK;
- }
- else
- {
- OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
- ehResult = OC_EH_ERROR;
- }
-
- free(getResp);
-
- return ehResult;
++OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
+{
- OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++ OCEntityHandlerResult ehResult = OC_EH_ERROR;
++ OCRepPayload *getResp = constructResponse(ehRequest);
++ if(!getResp)
++ {
++ OC_LOG(ERROR, TAG, "constructResponse failed");
++ return OC_EH_ERROR;
++ }
++
++ *payload = getResp;
++ ehResult = OC_EH_OK;
++
++ return ehResult;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
-
- OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
-
- // Get cJSON pointer to query
- cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
- if (!putJson)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- // Get root of JSON payload, then the 1st resource.
- cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
- carrier = cJSON_GetArrayItem(carrier, 0);
- carrier = cJSON_GetObjectItem(carrier, "rep");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- cJSON* prop = cJSON_GetObjectItem(carrier, "tnn");
- if (prop)
- {
- sprintf(g_prov.tnn, "%s", prop->valuestring);
- }
-
- prop = cJSON_GetObjectItem(carrier, "cd");
- if (prop)
- {
- sprintf(g_prov.cd, "%s", prop->valuestring);
- }
-
- cJSON_Delete(putJson);
-
- // TODO: Now once receiving PUT request, the enrollee start to connect to enroller.
- g_flag = 1;
-
- char *getResp = constructJsonResponse(ehRequest);
-
- if (!getResp)
- {
- OC_LOG(ERROR, TAG, "constructJsonResponse failed");
- return OC_EH_ERROR;
- }
-
- if (MAX_RESPONSE_LENGTH > strlen(getResp))
- {
- strncpy(payload, getResp, strlen(getResp));
- ehResult = OC_EH_OK;
- }
- else
- {
- OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
- ehResult = OC_EH_ERROR;
- }
-
- free(getResp);
- return ehResult;
++OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
++ OCRepPayload** payload)
+{
- OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
- uint16_t maxPayloadSize)
++
++ OCEntityHandlerResult ehResult=OC_EH_ERROR;
++ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++ OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
++ return ehResult;
++ }
++
++ OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
++ if(!input)
++ {
++ OC_LOG_V(ERROR, TAG, "Failed to parse");
++ return ehResult;
++ }
++
++ const char* tnn;
++ if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN, &tnn))
++ {
++ sprintf(g_prov.tnn, "%s", tnn);
++ }
++
++ const char* cd;
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
++ {
++ sprintf(g_prov.cd, "%s", cd);
++ }
++
++ g_flag = 1;
++
++ OCRepPayload *getResp = constructResponse(ehRequest);
++ if(!getResp)
++ {
++ OC_LOG(ERROR, TAG, "constructResponse failed");
++ return OC_EH_ERROR;
++ }
++
++ *payload = getResp;
++ ehResult = OC_EH_OK;
++
++
++
++ return ehResult;
+}
+
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
- OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
-
- // Get cJSON pointer to query
- cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-
- if (!putJson)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- // Get root of JSON payload, then the 1st resource.
- cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
- carrier = cJSON_GetArrayItem(carrier, 0);
- carrier = cJSON_GetObjectItem(carrier, "rep");
- if (!carrier)
- {
- OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
- return ehResult;
- }
-
- cJSON* prop = cJSON_GetObjectItem(carrier, "tr");
- if (prop)
- {
- // Triggering
- ehResult = OC_EH_OK;
- }
-
- cJSON_Delete(putJson);
-
- g_flag = 1;
-
- return ehResult;
++
++OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
+{
- char* constructJsonResponse(OCEntityHandlerRequest *ehRequest)
++ OCEntityHandlerResult ehResult = OC_EH_ERROR;
++ if(!ehRequest)
++ {
++ OC_LOG(ERROR, TAG, PCF("Request is Null"));
++ return ehResult;
++ }
++ if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++ {
++ OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
++ return ehResult;
++ }
++
++ OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
++ if(!input)
++ {
++ OC_LOG_V(ERROR, TAG, "Failed to parse" );
++ return ehResult;
++ }
++ const char* tr;
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_TR, &tr))
++ {
++
++ // Triggering
++ ehResult = OC_EH_OK;
++ }
++
++ g_flag = 1;
++
++ return ehResult;
+}
+
- cJSON *json = cJSON_CreateObject();
- cJSON *format;
- char *jsonResponse;
- char *JsonResp;
- char temp_resp[256];
-
- if (g_prov.handle != NULL && ehRequest->resource == g_prov.handle)
- {
- char *uri = (char *) "/oic/prov";
-
- cJSON_AddStringToObject(json, "href", uri);
- cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
- cJSON_AddNumberToObject(format, "ps", g_prov.ps);
- cJSON_AddNumberToObject(format, "tnt", g_prov.tnt);
- cJSON_AddStringToObject(format, "tnn", g_prov.tnn);
- cJSON_AddStringToObject(format, "cd", g_prov.cd);
-
- jsonResponse = cJSON_Print(json);
- cJSON_Delete(json);
- }
- else if (g_net.handle != NULL && ehRequest->requestHandle == g_net.handle)
- {
- char *uri = (char *) "/oic/net";
-
- cJSON_AddStringToObject(json, "href", uri);
- cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
- cJSON_AddNumberToObject(format, "ant", g_net.ant[0]);
-
- jsonResponse = cJSON_Print(json);
- cJSON_Delete(json);
- }
- else
- {
- return jsonResponse;
- }
-
- OC_LOG_V(INFO, TAG, "Constructed Response: %s", jsonResponse);
-
- return jsonResponse;
++OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
+{
- OCEntityHandlerRequest* entityHandlerRequest)
++
++ OCRepPayload* payload = OCRepPayloadCreate();
++ if(!payload)
++ {
++ OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
++ return NULL;
++ }
++
++ if (g_prov.handle != NULL && ehRequest->resource == g_prov.handle)
++ {
++
++
++ OCRepPayloadSetUri(payload,OC_RSRVD_ES_URI_PROV);
++
++ OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS,g_prov.ps);
++ OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, g_prov.tnt);
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN, g_prov.tnn);
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD, g_prov.cd);
++ }
++ else if (g_net.handle != NULL && ehRequest->requestHandle == g_net.handle)
++ {
++
++ OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
++ OCRepPayloadSetPropInt(payload, "ant", g_net.ant[0]);
++ }
++ return payload;
+}
+
+// This is the entity handler for the registered resource.
+// This is invoked by OCStack whenever it recevies a request for this resource.
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
- OCEntityHandlerResult ehRet = OC_EH_OK;
- OCEntityHandlerResponse response =
- { 0 };
- char payload[MAX_RESPONSE_LENGTH] =
- { 0 };
-
- if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
- {
- if (OC_REST_GET == entityHandlerRequest->method)
- {
- OC_LOG_V(INFO, TAG, "Received GET request");
- ehRet = ProcessGetRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
- }
- else if (OC_REST_PUT == entityHandlerRequest->method)
- {
- OC_LOG_V(INFO, TAG, "Received PUT request");
-
- if (g_prov.handle != NULL && entityHandlerRequest->resource == g_prov.handle)
- {
- ehRet = ProcessPutRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
- }
- else
- {
- ehRet = OC_EH_ERROR;
- }
- }
- else if (OC_REST_POST == entityHandlerRequest->method)
- {
- // TODO: As of now, POST request will be not received.
- OC_LOG(INFO, TAG, "Received OC_REST_POST from client");
- //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
- }
-
- if (ehRet == OC_EH_OK)
- {
- // Format the response. Note this requires some info about the request
- response.requestHandle = entityHandlerRequest->requestHandle;
- response.resourceHandle = entityHandlerRequest->resource;
- response.ehResult = ehRet;
- response.payload = payload;
- response.payloadSize = strlen(payload);
- response.numSendVendorSpecificHeaderOptions = 0;
- memset(response.sendVendorSpecificHeaderOptions, 0,
- sizeof response.sendVendorSpecificHeaderOptions);
- memset(response.resourceUri, 0, sizeof response.resourceUri);
- // Indicate that response is NOT in a persistent buffer
- response.persistentBufferFlag = 0;
-
- // Send the response
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OC_LOG(ERROR, TAG, "Error sending response");
- ehRet = OC_EH_ERROR;
- }
- }
- }
-
- if (g_flag == 1)
- {
- g_cbForResEvent(ES_RECVTRIGGEROFPROVRES);
- g_flag = 0;
- }
-
- return ehRet;
++ OCEntityHandlerRequest* entityHandlerRequest,void *callback)
+{
- switch (result)
- {
- case OC_STACK_OK:
- return "OC_STACK_OK";
- case OC_STACK_INVALID_URI:
- return "OC_STACK_INVALID_URI";
- case OC_STACK_INVALID_QUERY:
- return "OC_STACK_INVALID_QUERY";
- case OC_STACK_INVALID_IP:
- return "OC_STACK_INVALID_IP";
- case OC_STACK_INVALID_PORT:
- return "OC_STACK_INVALID_PORT";
- case OC_STACK_INVALID_CALLBACK:
- return "OC_STACK_INVALID_CALLBACK";
- case OC_STACK_INVALID_METHOD:
- return "OC_STACK_INVALID_METHOD";
- case OC_STACK_NO_MEMORY:
- return "OC_STACK_NO_MEMORY";
- case OC_STACK_COMM_ERROR:
- return "OC_STACK_COMM_ERROR";
- case OC_STACK_INVALID_PARAM:
- return "OC_STACK_INVALID_PARAM";
- case OC_STACK_NOTIMPL:
- return "OC_STACK_NOTIMPL";
- case OC_STACK_NO_RESOURCE:
- return "OC_STACK_NO_RESOURCE";
- case OC_STACK_RESOURCE_ERROR:
- return "OC_STACK_RESOURCE_ERROR";
- case OC_STACK_SLOW_RESOURCE:
- return "OC_STACK_SLOW_RESOURCE";
- case OC_STACK_NO_OBSERVERS:
- return "OC_STACK_NO_OBSERVERS";
- case OC_STACK_ERROR:
- return "OC_STACK_ERROR";
- default:
- return "UNKNOWN";
- }
++ (void)callback;
++ OCEntityHandlerResult ehRet = OC_EH_OK;
++ OCEntityHandlerResponse response =
++ { 0 };
++ OCRepPayload* payload = NULL;
++ if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
++ {
++ if (OC_REST_GET == entityHandlerRequest->method)
++ {
++ OC_LOG_V(INFO, TAG, "Received GET request");
++ ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
++ }
++ else if (OC_REST_PUT == entityHandlerRequest->method)
++ {
++ OC_LOG_V(INFO, TAG, "Received PUT request");
++
++ if (g_prov.handle != NULL && entityHandlerRequest->resource == g_prov.handle)
++ {
++ ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
++ }
++ else
++ {
++ ehRet = OC_EH_ERROR;
++ }
++ }
++ else if (OC_REST_POST == entityHandlerRequest->method)
++ {
++ // TODO: As of now, POST request will be not received.
++ OC_LOG(INFO, TAG, "Received OC_REST_POST from client");
++ //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
++ }
++
++ if (ehRet == OC_EH_OK)
++ {
++ // Format the response. Note this requires some info about the request
++ response.requestHandle = entityHandlerRequest->requestHandle;
++ response.resourceHandle = entityHandlerRequest->resource;
++ response.ehResult = ehRet;
++ response.payload = (OCPayload*)(&payload); //response uses OCPaylod while all get,put methodes use OCRepPayload
++ response.numSendVendorSpecificHeaderOptions = 0;
++ memset(response.sendVendorSpecificHeaderOptions, 0,
++ sizeof response.sendVendorSpecificHeaderOptions);
++ memset(response.resourceUri, 0, sizeof response.resourceUri);
++ // Indicate that response is NOT in a persistent buffer
++ response.persistentBufferFlag = 0;
++
++ // Send the response
++ if (OCDoResponse(&response) != OC_STACK_OK)
++ {
++ OC_LOG(ERROR, TAG, "Error sending response");
++ ehRet = OC_EH_ERROR;
++ }
++ }
++ }
++
++ if (g_flag == 1)
++ {
++ g_cbForResEvent(ES_RECVTRIGGEROFPROVRES);
++ g_flag = 0;
++ }
++
++ return ehRet;
+}
+
+const char *getResult(OCStackResult result)
+{
++ switch (result)
++ {
++ case OC_STACK_OK:
++ return "OC_STACK_OK";
++ case OC_STACK_INVALID_URI:
++ return "OC_STACK_INVALID_URI";
++ case OC_STACK_INVALID_QUERY:
++ return "OC_STACK_INVALID_QUERY";
++ case OC_STACK_INVALID_IP:
++ return "OC_STACK_INVALID_IP";
++ case OC_STACK_INVALID_PORT:
++ return "OC_STACK_INVALID_PORT";
++ case OC_STACK_INVALID_CALLBACK:
++ return "OC_STACK_INVALID_CALLBACK";
++ case OC_STACK_INVALID_METHOD:
++ return "OC_STACK_INVALID_METHOD";
++ case OC_STACK_NO_MEMORY:
++ return "OC_STACK_NO_MEMORY";
++ case OC_STACK_COMM_ERROR:
++ return "OC_STACK_COMM_ERROR";
++ case OC_STACK_INVALID_PARAM:
++ return "OC_STACK_INVALID_PARAM";
++ case OC_STACK_NOTIMPL:
++ return "OC_STACK_NOTIMPL";
++ case OC_STACK_NO_RESOURCE:
++ return "OC_STACK_NO_RESOURCE";
++ case OC_STACK_RESOURCE_ERROR:
++ return "OC_STACK_RESOURCE_ERROR";
++ case OC_STACK_SLOW_RESOURCE:
++ return "OC_STACK_SLOW_RESOURCE";
++ case OC_STACK_NO_OBSERVERS:
++ return "OC_STACK_NO_OBSERVERS";
++ case OC_STACK_ERROR:
++ return "OC_STACK_ERROR";
++ default:
++ return "UNKNOWN";
++ }
+}
+
--- /dev/null
- <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="EasySetupCore" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="android-gradle" name="Android-Gradle">
+ <configuration>
+ <option name="GRADLE_PROJECT_PATH" value=":" />
+ </configuration>
+ </facet>
+ <facet type="android" name="Android">
+ <configuration>
+ <option name="SELECTED_BUILD_VARIANT" value="debug" />
+ <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+ <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+ <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
- <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
+ <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+ <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+ <option name="ALLOW_USER_CONFIGURATION" value="false" />
+ <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+ <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+ <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+ <option name="LIBRARY_PROJECT" value="true" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+ <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java/common" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java/interface" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/EasySetupCore/iotivity-armeabi-base-debug/unspecified/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+ <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+ </content>
+ <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="iotivity-armeabi-base-debug" exported="" />
+ <orderEntry type="library" exported="" name="iotivity-armeabi-base-debug-unspecified" level="project" />
+ </component>
+</module>
--- /dev/null
- OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
++
+#ifndef __PROVISIONING_HANDLER_H_
+#define __PROVISIONING_HANDLER_H_
+
++
++#include "octypes.h"
++
+#include "logger.h"
+#include "ocstack.h"
+#include "common.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "provisioninghandler"
+#define DEFAULT_CONTEXT_VALUE 0x99
+#ifndef MAX_LENGTH_IPv4_ADDR
+#define MAX_LENGTH_IPv4_ADDR 16
+#endif
+
+//-----------------------------------------------------------------------------
+// Typedefs
+//-----------------------------------------------------------------------------
+
+/**
+ * List of methods that can be inititated from the client
+ */
+OCStackResult InitProvisioningHandler();
+
+OCStackResult TerminateProvisioningHandler();
+
+void listeningFunc(void*);
+
+OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri);
+
+OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
+ OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
++ OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload * request,
+ OCHeaderOption * options, uint8_t numOptions);
+
+OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query);
+
+OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
+ OCProvisioningStatusCB provisioningStatusCallback);
+
+
+void StopProvisioningProcess();
+
+OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
+ OCClientResponse* clientResponse);
+
+OCStackResult SubscribeProvPresence(OCQualityOfService qos, const char* requestURI);
+
+OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
+ OCDoHandle handle, OCClientResponse * clientResponse);
+
+void FindProvisioningResource(void *data);
+
+//Invoke Provisioning Status Callback
+ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
+ ProvStatus provStatus);
+
+#endif
+
--- /dev/null
- //******************************************************************
++ //******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sstream>
+
+#include "easysetupmgr.h"
+
+//Use ipv4addr for both InitDiscovery and InitDeviceDiscovery
+char ipv4addr[IPV4_ADDR_SIZE] = { 0 };
+
+static OCProvisioningStatusCB cbData = NULL;
+
+OCStackResult InitEasySetupManager() {
++
++
+ OCStackResult result = OC_STACK_ERROR;
+
+ if (InitProvisioningHandler() == OC_STACK_OK) {
+ result = OC_STACK_OK;
+ OIC_LOG(DEBUG, TAG, "InitProvisioningHandler returned Success");
+ } else {
+ result = OC_STACK_ERROR;
+ OIC_LOG_V(ERROR, TAG, "InitProvisioningHandler returned error = %s",
+ result);
+ }
+
+ return result;
+}
+
+OCStackResult TerminateEasySetupManager() {
+ return TerminateProvisioningHandler();
+}
+
+OCStackResult RegisterProvisioningStausCallback(
+ OCProvisioningStatusCB provisioningStatusCallback) {
+ OCStackResult result = OC_STACK_OK;
+
+ if(provisioningStatusCallback != NULL)
+ {
+ cbData = provisioningStatusCallback;
+ }
+ else
+ {
+ result = OC_STACK_ERROR;
+ OIC_LOG(ERROR, TAG, "provisioningStatusCallback is NULL");
+ }
+
+ return result;
+}
+
+void UnRegisterProvisioningStausCallback() {
+ if (cbData) {
+ cbData = NULL;
+ }
+}
+
+OCStackResult ProvisionEnrollee(const EnrolleeNWProvInfo_t *netInfo)
+{
- return StartProvisioningProcess(netInfo, cbData);
++ return StartProvisioningProcess(netInfo, cbData);
+}
+
+OCStackResult StopEnrolleeProvisioning(OCConnectivityType connectivityType) {
+ OCStackResult result = OC_STACK_OK;
+
+ //TODO: Have to handle the transport specific easy setup termination
+ StopProvisioningProcess();
+
+ return result;
+}
+
--- /dev/null
- //******************************************************************
- //
- // Copyright 2015 Samsung Electronics All Rights Reserved.
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <unistd.h>
-
- #include "provisioninghandler.h"
-
- // External includes
- #include "cJSON.h"
- #include "camutex.h"
- #include "cathreadpool.h"
- #include "logger.h"
- #include "oic_malloc.h"
-
-
- /**
- * @var g_provisioningMutex
- * @brief Mutex to synchronize access to g_caDtlsContext.
- */
- static ca_mutex g_provisioningMutex = NULL;
- static ca_cond g_provisioningCond = NULL;
- bool g_provisioningCondFlag = false;
-
- static EnrolleeNWProvInfo_t* netProvInfo;
-
- /**
- * @var cbData
- * @brief Callback for providing provisioning status callback to application
- */
- static OCProvisioningStatusCB cbData = NULL;
- static ca_thread_pool_t g_threadPoolHandle = NULL;
-
- OCStackResult InitProvisioningHandler() {
- OCStackResult ret = OC_STACK_ERROR;
- /* Initialize OCStack*/
- if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack init error");
- return ret;
- }
-
- g_provisioningMutex = ca_mutex_new();
-
- OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
-
- if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
- OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
- return OC_STACK_ERROR;
- }
-
- g_provisioningCond = ca_cond_new();
- if (NULL == g_provisioningCond) {
- OIC_LOG(DEBUG, TAG, "Failed to create condition");
- ca_mutex_free(g_provisioningMutex);
- ca_thread_pool_free(g_threadPoolHandle);
- return OC_STACK_ERROR;
- }
-
- char *string = "listeningFunc invoked in a thread";
- if (CA_STATUS_OK
- != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
- (void *) string)) {
- OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
- ca_thread_pool_free(g_threadPoolHandle);
- ca_mutex_unlock(g_provisioningMutex);
- ca_mutex_free(g_provisioningMutex);
- ca_cond_free(g_provisioningCond);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
- }
-
- OCStackResult TerminateProvisioningHandler() {
- OCStackResult ret = OC_STACK_ERROR;
- if (OCStop() != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- ca_mutex_lock(g_provisioningMutex);
- g_provisioningCondFlag = true;
- //ca_cond_signal(g_provisioningCond);
- ca_mutex_unlock(g_provisioningMutex);
-
- ca_mutex_free(g_provisioningMutex);
- g_provisioningMutex = NULL;
-
- ca_thread_pool_free(g_threadPoolHandle);
- g_threadPoolHandle = NULL;
-
- ret = OC_STACK_OK;
- return ret;
- }
-
- void listeningFunc(void *data) {
- while (!g_provisioningCondFlag) {
- OCStackResult result;
-
- ca_mutex_lock(g_provisioningMutex);
- result = OCProcess();
- ca_mutex_unlock(g_provisioningMutex);
-
- if (result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- // To minimize CPU utilization we may wish to do this with sleep
- sleep(1);
- }
- }
-
- OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
- OCClientResponse * clientResponse) {
- ProvisioningInfo *provInfo;
-
- if (clientResponse) {
- OIC_LOG_V(INFO, TAG, "Put Response JSON = %s",
- clientResponse->resJSONPayload);
- } else {
- OIC_LOG_V(INFO, TAG,
- "ProvisionEnrolleeResponse received Null clientResponse");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s ",
- clientResponse->resJSONPayload);
-
- if (clientResponse->resJSONPayload) {
- cJSON *observeJson = cJSON_CreateObject();
- observeJson = cJSON_Parse(clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
- cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
- char *ocArray_str = cJSON_PrintUnformatted(representationArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(observeJson);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- int countofrep = cJSON_GetArraySize(representationArray);
-
- for (int i = 0; i < countofrep; ++i) {
- cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
- OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_PS))
- {
- if(arrayJSON->valueint == 1)
- {
- OIC_LOG_V(DEBUG, TAG, "PS is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_TNN))
- {
- if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.ssid))
- {
- OIC_LOG_V(DEBUG, TAG, "SSID is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- if (!strcmp(arrayJSON->string, OC_RSRVD_ES_CD))
- {
- if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.pwd))
- {
- OIC_LOG_V(DEBUG, TAG, "Password is proper");
- continue;
- }
- else{
- OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- }
- }
-
- switch (arrayJSON->type) {
- case cJSON_False:
- case cJSON_True:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's int value : %d", i,
- arrayJSON->valueint);
- break;
- case cJSON_Number:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's double value : %f", i,
- arrayJSON->valuedouble);
- break;
- case cJSON_String:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
- arrayJSON->valuestring);
- break;
- case cJSON_NULL:
- default:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
- break;
- }
- }
-
- cJSON_Delete(observeJson);
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_PROVISIONED);
- cbData(provInfo);
-
- return OC_STACK_KEEP_TRANSACTION;
- } else {
- OIC_LOG(INFO, TAG,
- "ProvisionEnrolleeResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- }
-
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {
- OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
-
- cJSON *jsonFinal = cJSON_CreateObject();
- cJSON *json = cJSON_CreateObject();
- cJSON *jsonArray;
- cJSON *format;
- char* payload = NULL;
-
- cJSON_AddStringToObject(json, OC_RSRVD_HREF, resUri);
- cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, format = cJSON_CreateObject());
- cJSON_AddStringToObject(format, OC_RSRVD_ES_TNN, netProvInfo->netAddressInfo.WIFI.ssid);
- cJSON_AddStringToObject(format, OC_RSRVD_ES_CD, netProvInfo->netAddressInfo.WIFI.pwd);
- cJSON_AddItemToObject(jsonFinal, OC_RSRVD_OC, jsonArray = cJSON_CreateArray());
- cJSON_AddItemToArray(jsonArray, json);
-
- OIC_LOG_V(DEBUG, TAG, "ProvisionEnrollee : %s",
- cJSON_PrintUnformatted(jsonFinal));
- payload = cJSON_Print(jsonFinal);
- OIC_LOG_V(DEBUG, TAG, "Payload : %s", payload);
-
- OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,
- ProvisionEnrolleeResponse, payload, NULL, 0);
-
- cJSON_Delete(json);
- return ret;
- }
-
- OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
- OCDoHandle handle, OCClientResponse * clientResponse) {
- ProvisioningInfo *provInfo;
-
- if (clientResponse == NULL) {
- OIC_LOG(INFO, TAG,
- "getReqCB received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- if (clientResponse->rcvdVendorSpecificHeaderOptions
- && clientResponse->numRcvdVendorSpecificHeaderOptions) {
- OIC_LOG(INFO, TAG, "Received vendor specific options");
- uint8_t i = 0;
- OCHeaderOption * rcvdOptions =
- clientResponse->rcvdVendorSpecificHeaderOptions;
- for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
- i++) {
- if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
- OIC_LOG_V(INFO, TAG,
- "Received option with OC_COAP_ID and ID %u with",
- ((OCHeaderOption) rcvdOptions[i]).optionID);
-
- OIC_LOG_BUFFER(INFO, TAG,
- ((OCHeaderOption) rcvdOptions[i]).optionData,
- MAX_HEADER_OPTION_DATA_LENGTH);
- }
- }
- }
-
- char query[OIC_STRING_MAX_VALUE] = { '\0' };
-
-
- if (clientResponse->resJSONPayload) {
- cJSON *observeJson = cJSON_CreateObject();
- observeJson = cJSON_Parse(clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
- cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
-
- OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
- resUriObj->string, resUriObj->valuestring);
-
- char resURI[MAX_URI_LENGTH]={'\0'};
-
- strncpy(resURI, resUriObj->valuestring, sizeof(resURI));
-
- snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
- clientResponse->addr->addr,
- IP_PORT, resURI);
-
- cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
- char *ocArray_str = cJSON_PrintUnformatted(representationArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(observeJson);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- int countofrep = cJSON_GetArraySize(representationArray);
-
- for (int i = 0; i < countofrep; ++i) {
- cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
- OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
-
- switch (arrayJSON->type) {
- case cJSON_False:
- case cJSON_True:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
- arrayJSON->valueint);
- break;
- case cJSON_Number:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
- arrayJSON->valuedouble);
- break;
- case cJSON_String:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
- arrayJSON->valuestring);
- break;
- case cJSON_NULL:
- default:
- OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
- break;
- }
- }
- cJSON_Delete(observeJson);
-
- if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatusResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
-
- return OC_STACK_DELETE_TRANSACTION;
- }
- } else {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatusResponse received NULL clientResponse. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
- OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
- OCHeaderOption * options, uint8_t numOptions) {
- OCStackResult ret;
- OCCallbackData cbData;
-
- cbData.cb = cb;
- cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
- cbData.cd = NULL;
-
- ret = OCDoResource(NULL, method, query, 0, request, OC_CONNTYPE, qos,
- &cbData, options, numOptions);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
- ret, method);
- }
-
- return ret;
- }
-
- OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
- OCStackResult ret = OC_STACK_ERROR;
- OCHeaderOption options[MAX_HEADER_OPTIONS];
-
- OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
-
- uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
- memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
- options[0].protocolID = OC_COAP_ID;
- options[0].optionID = 2048;
- memcpy(options[0].optionData, option0, sizeof(option0));
- options[0].optionLength = 10;
- options[1].protocolID = OC_COAP_ID;
- options[1].optionID = 3000;
- memcpy(options[1].optionData, option1, sizeof(option1));
- options[1].optionLength = 10;
-
- ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
- GetProvisioningStatusResponse, NULL, options, 2);
- return ret;
- }
-
- OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
- OCProvisioningStatusCB provisioningStatusCallback) {
- OCStackResult result = OC_STACK_ERROR;
-
- if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
- OIC_LOG(ERROR, TAG, "Request URI is NULL");
- return result;
- }
-
- if (provisioningStatusCallback == NULL) {
- OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
- return result;
- }
-
- cbData = provisioningStatusCallback;
-
- //Copy Network Provisioning Information
- netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
-
- if (NULL == netProvInfo)
- {
- OIC_LOG(ERROR, TAG, "Invalid input..");
- return OC_STACK_ERROR;
- }
- memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
-
- OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
- netProvInfo->netAddressInfo.WIFI.ssid);
-
- OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
- netProvInfo->netAddressInfo.WIFI.pwd);
-
-
- if (CA_STATUS_OK
- != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
- (void *) "")) {
- OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");
- ca_thread_pool_free(g_threadPoolHandle);
- ca_mutex_unlock(g_provisioningMutex);
- ca_mutex_free(g_provisioningMutex);
- ca_cond_free(g_provisioningCond);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
- }
-
- void StopProvisioningProcess() {
- cbData = NULL;
- }
-
- // This is a function called back when a device is discovered
- OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
- OCDoHandle handle, OCClientResponse * clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
-
- OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
-
- ProvisioningInfo *provInfo;
-
- if (clientResponse->result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG,
- "OCStack stop error. Calling Provisioing Status Callback");
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
-
- cbData(provInfo);
- return response;
- }
-
- if (clientResponse) {
- cJSON *discoveryJson = cJSON_CreateObject();
- discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
- char *ocArray_str = cJSON_PrintUnformatted(ocArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(discoveryJson);
-
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return response;
- }
-
- cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
- cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
-
- OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
- resUriObj->string, resUriObj->valuestring);
-
-
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
- clientResponse->devAddr.addr, IP_PORT, resUriObj->valuestring);
- OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
-
- if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
- OIC_LOG(INFO, TAG,
- "GetProvisioningStatus returned error. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
-
- cbData(provInfo);
- return OC_STACK_DELETE_TRANSACTION;
- }
- } else {
- // clientResponse is invalid
- OIC_LOG(ERROR, TAG,
- "Invalid response for Provisioning Discovery request. \
- Invoking Provisioing Status Callback");
- provInfo = PrepareProvisioingStatusCB(clientResponse,
- DEVICE_NOT_PROVISIONED);
- cbData(provInfo);
- return response;
- }
- return OC_STACK_KEEP_TRANSACTION;
- }
-
- void FindProvisioningResource(void *data)
- {
- OCStackResult ret = OC_STACK_ERROR;
-
- /* Start a discovery query*/
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
- netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
-
- OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
-
- OCCallbackData ocCBData;
-
- ocCBData.cb = FindProvisioningResourceResponse;
- ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
- ocCBData.cd = NULL;
-
- ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
- OC_LOW_QOS, &ocCBData, NULL, 0);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack resource error");
-
- OIC_LOG(ERROR, TAG,
- "FindProvisioningResource failed. \
- Invoking Provisioing Status Callback");
-
- ProvisioningInfo *provInfo;
- provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
-
- if(provInfo == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return;
- }
-
- OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
-
- if(devAddr == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return;
- }
-
- strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));
- devAddr->port= IP_PORT;
- provInfo->provDeviceInfo.addr = devAddr;
- provInfo->provStatus = DEVICE_NOT_PROVISIONED;
-
-
- cbData(provInfo);
- }
- }
-
- OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
- OCClientResponse* clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
-
- OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
-
- if (clientResponse->result != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- return response;
- }
-
- if (clientResponse) {
- OIC_LOG(INFO, TAG, PCF("Client Response exists"));
-
- cJSON *discoveryJson = cJSON_CreateObject();
- discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
- cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
- char *ocArray_str = cJSON_PrintUnformatted(ocArray);
-
- if (strstr(ocArray_str, "[{}") == ocArray_str) {
- OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
- cJSON_Delete(discoveryJson);
- return response;
- }
-
- char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
- snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
-
- OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
- clientResponse->resJSONPayload, sourceIPAddr);
-
- /* Start a discovery query*/
- char szQueryUri[64] = { 0 };
-
- snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
- sourceIPAddr, IP_PORT);
-
- /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
- return OC_STACK_KEEP_TRANSACTION;
- }*/
- } else {
- // clientResponse is invalid
- OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
- }
- return OC_STACK_KEEP_TRANSACTION;
- }
-
- OCStackResult SubscribeProvPresence(OCQualityOfService qos,
- const char* requestURI) {
- OCStackResult ret = OC_STACK_ERROR;
-
- OCCallbackData cbData;
-
- cbData.cb = &SubscribeProvPresenceCallback;
- cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
- cbData.cd = NULL;
-
- ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
- OC_LOW_QOS, &cbData, NULL, 0);
-
- if (ret != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack resource error");
- }
-
- return ret;
- }
-
- OCStackResult FindNetworkResource() {
- OCStackResult ret = OC_STACK_ERROR;
- if (OCStop() != OC_STACK_OK) {
- OIC_LOG(ERROR, TAG, "OCStack stop error");
- }
-
- return ret;
- }
-
- ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
-
- ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
-
- if(provInfo == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return NULL;
- }
-
- OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
-
- if(devAddr == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
- return NULL;
- }
-
- strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));
- devAddr->port= clientResponse->addr->port;
-
- provInfo->provDeviceInfo.addr = devAddr;
-
- provInfo->provStatus = provStatus;
-
- return provInfo;
- }
-
++//******************************************************************\r
++//\r
++// Copyright 2015 Samsung Electronics All Rights Reserved.\r
++//\r
++//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
++//\r
++// Licensed under the Apache License, Version 2.0 (the "License");\r
++// you may not use this file except in compliance with the License.\r
++// You may obtain a copy of the License at\r
++//\r
++// http://www.apache.org/licenses/LICENSE-2.0\r
++//\r
++// Unless required by applicable law or agreed to in writing, software\r
++// distributed under the License is distributed on an "AS IS" BASIS,\r
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
++// See the License for the specific language governing permissions and\r
++// limitations under the License.\r
++//\r
++//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
++\r
++#include <stdio.h>\r
++#include <stdlib.h>\r
++#include <string.h>\r
++#include <signal.h>\r
++#include <unistd.h>\r
++#include "ocpayload.h"\r
++#include "provisioninghandler.h"\r
++\r
++// External includes\r
++\r
++#include "camutex.h"\r
++#include "cathreadpool.h"\r
++#include "logger.h"\r
++#include "oic_malloc.h"\r
++\r
++\r
++/**\r
++ * @var g_provisioningMutex\r
++ * @brief Mutex to synchronize access to g_caDtlsContext.\r
++ */\r
++static ca_mutex g_provisioningMutex = NULL;\r
++static ca_cond g_provisioningCond = NULL;\r
++bool g_provisioningCondFlag = false;\r
++\r
++static EnrolleeNWProvInfo_t* netProvInfo;\r
++\r
++/**\r
++ * @var cbData\r
++ * @brief Callback for providing provisioning status callback to application\r
++ */\r
++static OCProvisioningStatusCB cbData = NULL;\r
++static ca_thread_pool_t g_threadPoolHandle = NULL;\r
++\r
++OCStackResult InitProvisioningHandler() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ /* Initialize OCStack*/\r
++ if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack init error");\r
++ return ret;\r
++ }\r
++\r
++ g_provisioningMutex = ca_mutex_new();\r
++\r
++ OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");\r
++\r
++ if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_init failed");\r
++ return OC_STACK_ERROR;\r
++ }\r
++\r
++ g_provisioningCond = ca_cond_new();\r
++ if (NULL == g_provisioningCond) {\r
++ OIC_LOG(DEBUG, TAG, "Failed to create condition");\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ return OC_STACK_ERROR;\r
++ }\r
++\r
++ char *string = "listeningFunc invoked in a thread";\r
++ if (CA_STATUS_OK\r
++ != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,\r
++ (void *) string)) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_cond_free(g_provisioningCond);\r
++ return OC_STACK_ERROR;\r
++ }\r
++ return OC_STACK_OK;\r
++}\r
++\r
++OCStackResult TerminateProvisioningHandler() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ if (OCStop() != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ ca_mutex_lock(g_provisioningMutex);\r
++ g_provisioningCondFlag = true;\r
++ //ca_cond_signal(g_provisioningCond);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++\r
++ ca_mutex_free(g_provisioningMutex);\r
++ g_provisioningMutex = NULL;\r
++\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ g_threadPoolHandle = NULL;\r
++\r
++ ret = OC_STACK_OK;\r
++ return ret;\r
++}\r
++\r
++void listeningFunc(void *data) {\r
++ while (!g_provisioningCondFlag) {\r
++ OCStackResult result;\r
++\r
++ ca_mutex_lock(g_provisioningMutex);\r
++ result = OCProcess();\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++\r
++ if (result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ // To minimize CPU utilization we may wish to do this with sleep\r
++ sleep(1);\r
++ }\r
++}\r
++\r
++OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,\r
++ OCClientResponse * clientResponse) {\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse) {\r
++ OIC_LOG_V(INFO, TAG, "Put Response");\r
++ } else {\r
++ OIC_LOG_V(INFO, TAG,\r
++ "ProvisionEnrolleeResponse received Null clientResponse");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ if (clientResponse->payload) {\r
++\r
++ if(clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);\r
++ if(!input)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ while(input){\r
++\r
++ int64_t ps;\r
++ if(OCRepPayloadGetPropInt(input,OC_RSRVD_ES_PS,&ps)) {\r
++ if(ps == 1)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "PS is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ }\r
++ }\r
++\r
++ const char* tnn;\r
++ if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN,&tnn)){\r
++ if(!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "SSID is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ }\r
++ }\r
++ const char* cd;\r
++ if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD,&cd)){\r
++ if(!strcmp(cd,netProvInfo->netAddressInfo.WIFI.pwd))\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Password is proper");\r
++ continue;\r
++ }\r
++ else{\r
++ OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ }\r
++ }\r
++\r
++ OCRepPayloadValue* val = input->values;\r
++\r
++ switch(val->type)\r
++ {\r
++ case OCREP_PROP_NULL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);\r
++ break;\r
++ case OCREP_PROP_INT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);\r
++ break;\r
++ case OCREP_PROP_DOUBLE:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);\r
++ break;\r
++ case OCREP_PROP_BOOL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");\r
++ break;\r
++ case OCREP_PROP_STRING:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);\r
++ break;\r
++ case OCREP_PROP_OBJECT:\r
++ // Note: Only prints the URI (if available), to print further, you'll\r
++ // need to dig into the object better!\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);\r
++ break;\r
++ case OCREP_PROP_ARRAY:\r
++ switch(val->arr.type)\r
++ {\r
++ case OCREP_PROP_INT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_DOUBLE:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_BOOL:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_STRING:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ case OCREP_PROP_OBJECT:\r
++ OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",\r
++ val->name,\r
++ val->arr.dimensions[0], val->arr.dimensions[1],\r
++ val->arr.dimensions[2]);\r
++ break;\r
++ default:\r
++ //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",\r
++ // val->name);\r
++ break;\r
++ }\r
++ break;\r
++ default:\r
++ /*OC_LOG_V(ERROR, TAG\r
++ , "\t\t%s <-- Unknown type!", val->name);*/\r
++ break;\r
++ }\r
++ input=input->next;\r
++ }\r
++\r
++\r
++\r
++\r
++\r
++\r
++\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++ } else {\r
++ OIC_LOG(INFO, TAG,\r
++ "ProvisionEnrolleeResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++}\r
++\r
++\r
++\r
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {\r
++ OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);\r
++\r
++\r
++ OCRepPayload* payload = OCRepPayloadCreate();\r
++\r
++ OCRepPayloadSetUri(payload,resUri);\r
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN,netProvInfo->netAddressInfo.WIFI.ssid);\r
++ OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD,netProvInfo->netAddressInfo.WIFI.pwd);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");\r
++\r
++ OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,\r
++ ProvisionEnrolleeResponse, payload, NULL, 0);\r
++\r
++ return ret;\r
++}\r
++\r
++\r
++OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,\r
++ OCDoHandle handle, OCClientResponse * clientResponse) {\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse == NULL) {\r
++ OIC_LOG(INFO, TAG,\r
++ "getReqCB received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ if (clientResponse->rcvdVendorSpecificHeaderOptions\r
++ && clientResponse->numRcvdVendorSpecificHeaderOptions) {\r
++ OIC_LOG(INFO, TAG, "Received vendor specific options");\r
++ uint8_t i = 0;\r
++ OCHeaderOption * rcvdOptions =\r
++ clientResponse->rcvdVendorSpecificHeaderOptions;\r
++ for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;\r
++ i++) {\r
++ if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {\r
++ OIC_LOG_V(INFO, TAG,\r
++ "Received option with OC_COAP_ID and ID %u with",\r
++ ((OCHeaderOption) rcvdOptions[i]).optionID);\r
++\r
++ OIC_LOG_BUFFER(INFO, TAG,\r
++ ((OCHeaderOption) rcvdOptions[i]).optionData,\r
++ MAX_HEADER_OPTION_DATA_LENGTH);\r
++ }\r
++ }\r
++ }\r
++\r
++ char query[OIC_STRING_MAX_VALUE] = { '\0' };\r
++\r
++\r
++ if (clientResponse->payload) {\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);\r
++ if(!input)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s",input->uri);\r
++\r
++ char resURI[MAX_URI_LENGTH]={'\0'};\r
++\r
++ strncpy(resURI, input->uri, sizeof(resURI));\r
++\r
++ snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,\r
++ clientResponse->addr->addr,\r
++ IP_PORT, resURI);\r
++\r
++ //OCPayloadLogRep(DEBUG,TAG,input);\r
++\r
++ if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatusResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ } else {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatusResponse received NULL clientResponse. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++}\r
++\r
++OCStackResult InvokeOCDoResource(const char* query, OCMethod method,\r
++ OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* request,\r
++ OCHeaderOption * options, uint8_t numOptions) {\r
++ OCStackResult ret;\r
++ OCCallbackData cbData;\r
++\r
++ cbData.cb = cb;\r
++ cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ cbData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, method, query, 0, &request->base, OC_CONNTYPE, qos,\r
++ &cbData, options, numOptions);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",\r
++ ret, method);\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ OCHeaderOption options[MAX_HEADER_OPTIONS];\r
++\r
++ OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);\r
++\r
++ uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r
++ uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };\r
++ memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);\r
++ options[0].protocolID = OC_COAP_ID;\r
++ options[0].optionID = 2048;\r
++ memcpy(options[0].optionData, option0, sizeof(option0));\r
++ options[0].optionLength = 10;\r
++ options[1].protocolID = OC_COAP_ID;\r
++ options[1].optionID = 3000;\r
++ memcpy(options[1].optionData, option1, sizeof(option1));\r
++ options[1].optionLength = 10;\r
++\r
++ ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,\r
++ GetProvisioningStatusResponse, NULL, options, 2);\r
++ return ret;\r
++}\r
++\r
++OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,\r
++ OCProvisioningStatusCB provisioningStatusCallback) {\r
++ OCStackResult result = OC_STACK_ERROR;\r
++\r
++ if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {\r
++ OIC_LOG(ERROR, TAG, "Request URI is NULL");\r
++ return result;\r
++ }\r
++\r
++ if (provisioningStatusCallback == NULL) {\r
++ OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");\r
++ return result;\r
++ }\r
++\r
++ cbData = provisioningStatusCallback;\r
++\r
++ //Copy Network Provisioning Information\r
++ netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));\r
++\r
++ if (NULL == netProvInfo)\r
++ {\r
++ OIC_LOG(ERROR, TAG, "Invalid input..");\r
++ return OC_STACK_ERROR;\r
++ }\r
++ memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",\r
++ netProvInfo->netAddressInfo.WIFI.ssid);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",\r
++ netProvInfo->netAddressInfo.WIFI.pwd);\r
++\r
++\r
++ if (CA_STATUS_OK\r
++ != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,\r
++ (void *) "")) {\r
++ OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");\r
++ ca_thread_pool_free(g_threadPoolHandle);\r
++ ca_mutex_unlock(g_provisioningMutex);\r
++ ca_mutex_free(g_provisioningMutex);\r
++ ca_cond_free(g_provisioningCond);\r
++ return OC_STACK_ERROR;\r
++ }\r
++ return OC_STACK_OK;\r
++}\r
++\r
++void StopProvisioningProcess() {\r
++ cbData = NULL;\r
++}\r
++\r
++\r
++// This is a function called back when a device is discovered\r
++OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,\r
++ OCDoHandle handle, OCClientResponse * clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));\r
++\r
++ OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
++\r
++ ProvisioningInfo *provInfo;\r
++\r
++ if (clientResponse->result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG,\r
++ "OCStack stop error. Calling Provisioing Status Callback");\r
++\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++\r
++ if (clientResponse) {\r
++\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++\r
++ OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);\r
++ if(!discoveryPayload)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++ OIC_LOG_V(DEBUG, TAG, "resUri = %s",discoveryPayload->uri);\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,\r
++ clientResponse->devAddr.addr, IP_PORT, discoveryPayload->uri);\r
++ OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);\r
++\r
++ if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {\r
++ OIC_LOG(INFO, TAG,\r
++ "GetProvisioningStatus returned error. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++\r
++ cbData(provInfo);\r
++ return OC_STACK_DELETE_TRANSACTION;\r
++ }\r
++ } else {\r
++ // clientResponse is invalid\r
++ OIC_LOG(ERROR, TAG,\r
++ "Invalid response for Provisioning Discovery request. \\r
++ Invoking Provisioing Status Callback");\r
++ provInfo = PrepareProvisioingStatusCB(clientResponse,\r
++ DEVICE_NOT_PROVISIONED);\r
++ cbData(provInfo);\r
++ return response;\r
++ }\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++}\r
++\r
++\r
++void FindProvisioningResource(void *data)\r
++{\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++\r
++ /* Start a discovery query*/\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
++ netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);\r
++\r
++ OCCallbackData ocCBData;\r
++\r
++ ocCBData.cb = FindProvisioningResourceResponse;\r
++ ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ ocCBData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,\r
++ OC_LOW_QOS, &ocCBData, NULL, 0);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack resource error");\r
++\r
++ OIC_LOG(ERROR, TAG,\r
++ "FindProvisioningResource failed. \\r
++ Invoking Provisioing Status Callback");\r
++\r
++ ProvisioningInfo *provInfo;\r
++ provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
++\r
++ if(provInfo == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return;\r
++ }\r
++\r
++ OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
++\r
++ if(devAddr == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return;\r
++ }\r
++\r
++ strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));\r
++ devAddr->port= IP_PORT;\r
++ provInfo->provDeviceInfo.addr = devAddr;\r
++ provInfo->provStatus = DEVICE_NOT_PROVISIONED;\r
++\r
++\r
++ cbData(provInfo);\r
++ }\r
++}\r
++\r
++OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,\r
++ OCClientResponse* clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));\r
++\r
++ OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
++\r
++ if (clientResponse->result != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ return response;\r
++ }\r
++\r
++ if (clientResponse) {\r
++ OIC_LOG(INFO, TAG, PCF("Client Response exists"));\r
++\r
++ if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
++ return response;\r
++ }\r
++\r
++ OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);\r
++ if(!discoveryPayload)\r
++ {\r
++ OIC_LOG_V(DEBUG, TAG, "invalid payload");\r
++ return response;\r
++ }\r
++\r
++ char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };\r
++ snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);\r
++\r
++ OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",\r
++ discoveryPayload->uri, sourceIPAddr);\r
++\r
++ /* Start a discovery query*/\r
++ char szQueryUri[64] = { 0 };\r
++\r
++ snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
++ sourceIPAddr, IP_PORT);\r
++\r
++ /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++ }*/\r
++ } else {\r
++ // clientResponse is invalid\r
++ OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));\r
++ }\r
++ return OC_STACK_KEEP_TRANSACTION;\r
++}\r
++\r
++\r
++OCStackResult SubscribeProvPresence(OCQualityOfService qos,\r
++ const char* requestURI) {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++\r
++ OCCallbackData cbData;\r
++\r
++ cbData.cb = &SubscribeProvPresenceCallback;\r
++ cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
++ cbData.cd = NULL;\r
++\r
++ ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,\r
++ OC_LOW_QOS, &cbData, NULL, 0);\r
++\r
++ if (ret != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack resource error");\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++OCStackResult FindNetworkResource() {\r
++ OCStackResult ret = OC_STACK_ERROR;\r
++ if (OCStop() != OC_STACK_OK) {\r
++ OIC_LOG(ERROR, TAG, "OCStack stop error");\r
++ }\r
++\r
++ return ret;\r
++}\r
++\r
++ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {\r
++\r
++ ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
++\r
++ if(provInfo == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return NULL;\r
++ }\r
++\r
++ OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
++\r
++ if(devAddr == NULL)\r
++ {\r
++ OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
++ return NULL;\r
++ }\r
++\r
++ strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));\r
++ devAddr->port= clientResponse->addr->port;\r
++\r
++ provInfo->provDeviceInfo.addr = devAddr;\r
++\r
++ provInfo->provStatus = provStatus;\r
++\r
++ return provInfo;\r
++}\r
++\r
++\r
++\r
++\r