help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
help_vars.Add(BoolVariable('WITH_TCP', 'Build with TCP adapter', False))
-help_vars.Add(BoolVariable('WITH_PROXY', 'Build with CoAP-HTTP Proxy', False))
help_vars.Add(ListVariable('WITH_MQ', 'Build with MQ publisher/broker', 'OFF', ['OFF', 'SUB', 'PUB', 'BROKER']))
help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including AccountManager class and Cloud Client sample', False))
help_vars.Add(ListVariable('RD_MODE', 'Resource Directory build mode', 'CLIENT', ['CLIENT', 'SERVER']))
char *OICStrdup(const char *str);
/**
- * Convert source string to lower case characters.
- *
- * @param str Original valid string which needs to be converted.
- *
- */
-void OICStringToLower(char* str);
-
-/**
* Copies a C string into destination buffer. Ensures that the destination
* is null terminated.
*
return dup;
}
-void OICStringToLower(char* str)
-{
- for (int ch = 0; str[ch] != '\0'; ch++)
- {
- if (str[ch] >= 'A' && str[ch] <= 'Z')
- {
- str[ch] += 32;
- }
- }
-}
-
char* OICStrcpy(char* dest, size_t destSize, const char* source)
{
return OICStrcpyPartial(dest, destSize, source, destSize == 0 ? 0 : destSize - 1);
elif liboctbstack_env.get('ROUTING') == 'EP':
liboctbstack_env.AppendUnique(CPPDEFINES = ['ROUTING_EP'])
-if liboctbstack_env.get('WITH_PROXY'):
- liboctbstack_env.AppendUnique(CPPDEFINES = ['WITH_CHPROXY'])
-
if target_os not in ['windows']:
liboctbstack_env.AppendUnique(CFLAGS = ['-Wall'])
/**
* Max header options data length.
*/
-#define CA_MAX_HEADER_OPTION_DATA_LENGTH 1024
+#define CA_MAX_HEADER_OPTION_DATA_LENGTH 20
/**
* Max token length.
CA_REQUEST_ENTITY_INCOMPLETE = 408, /**< Request Entity Incomplete */
CA_REQUEST_ENTITY_TOO_LARGE = 413, /**< Request Entity Too Large */
CA_INTERNAL_SERVER_ERROR = 500, /**< Internal Server Error */
- CA_BAD_GATEWAY = 502,
- CA_RETRANSMIT_TIMEOUT = 504, /**< Retransmit timeout */
- CA_PROXY_NOT_SUPPORTED = 505 /**< Proxy not enabled to service a request */
+ CA_RETRANSMIT_TIMEOUT = 504 /**< Retransmit timeout */
/* Response status code - END HERE */
} CAResponseResult_t;
CAResult_t CASetRAInfo(const CARAInfo_t *caraInfo);
#endif
-#ifdef WITH_CHPROXY
-/**
- * This function sets uri being used for proxy.
- *
- * @param uri NULL terminated resource uri for CoAP-HTTP Proxy.
- *
- * @return ::CA_STATUS_OK or ::CA_STATUS_INVALID_PARAM
- */
-CAResult_t CASetProxyUri(const char *uri);
-#endif
+
#ifdef __cplusplus
} /* extern "C" */
elif env.get('ROUTING') == 'EP':
env.AppendUnique(CPPDEFINES = ['ROUTING_EP'])
-if env.get('WITH_PROXY'):
- env.AppendUnique(CPPDEFINES = ['WITH_CHPROXY'])
-
if ca_os == 'arduino':
env.AppendUnique(CPPDEFINES = ['SINGLE_THREAD'])
env.AppendUnique(CPPDEFINES = ['WITH_ARDUINO'])
static const char COAP_URI_HEADER[] = "coap://[::]/";
-#ifdef WITH_CHPROXY
-static char g_chproxyUri[CA_MAX_URI_LENGTH];
-
-CAResult_t CASetProxyUri(const char *uri)
-{
- VERIFY_NON_NULL(uri, TAG, "uri");
- OICStrcpy(g_chproxyUri, sizeof (g_chproxyUri), uri);
- return CA_STATUS_OK;
-}
-#endif
-
CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
CARequestInfo_t *outReqInfo)
{
&& COAP_OPTION_ACCEPT != opt_iter.type
&& COAP_OPTION_URI_HOST != opt_iter.type && COAP_OPTION_URI_PORT != opt_iter.type
&& COAP_OPTION_ETAG != opt_iter.type && COAP_OPTION_MAXAGE != opt_iter.type
- && COAP_OPTION_PROXY_SCHEME != opt_iter.type)
+ && COAP_OPTION_PROXY_URI != opt_iter.type && COAP_OPTION_PROXY_SCHEME != opt_iter.type)
{
count++;
}
uint32_t optionLength = 0;
bool isfirstsetflag = false;
bool isQueryBeingProcessed = false;
-#ifdef WITH_CHPROXY
- bool isProxyRequest = false;
-#endif
while ((option = coap_option_next(&opt_iter)))
{
COAP_OPTION_URI_HOST == opt_iter.type ||
COAP_OPTION_ETAG == opt_iter.type ||
COAP_OPTION_MAXAGE == opt_iter.type ||
+ COAP_OPTION_PROXY_URI == opt_iter.type ||
COAP_OPTION_PROXY_SCHEME== opt_iter.type)
{
OIC_LOG_V(INFO, TAG, "option[%d] has an unsupported format [%d]",
}
else
{
-#ifdef WITH_CHPROXY
- if (COAP_OPTION_PROXY_URI == opt_iter.type)
- {
- isProxyRequest = true;
- }
-#endif
if (idx < count)
{
if (bufLength <= sizeof(outInfo->options[0].optionData))
return CA_MEMORY_ALLOC_FAILED;
}
}
-#ifdef WITH_CHPROXY
- else if(isProxyRequest && g_chproxyUri[0] != '\0')
- {
- /*
- * A request for CoAP-HTTP Proxy will not have any uri element as per CoAP specs
- * and only COAP_OPTION_PROXY_URI will be present. Use preset proxy uri
- * for such requests.
- */
- outInfo->resourceUri = OICStrdup(g_chproxyUri);
- if (!outInfo->resourceUri)
- {
- OIC_LOG(ERROR, TAG, "Out of memory");
- OICFree(outInfo->options);
- OICFree(outInfo->token);
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-#endif
+
return CA_STATUS_OK;
exit:
{
#endif
-/**
-* Helper for unused warning.
-*/
-#define UNUSED(x) (void)(x)
-
// Use the PCF macro to wrap strings stored in FLASH on the Arduino
// Example: OIC_LOG(INFO, TAG, PCF("Entering function"));
#ifdef ARDUINO
OCStackResult OCDoDirectPairing(void *ctx, OCDPDev_t* peer, OCPrm_t pmSel, char *pinNumber,
OCDirectPairingCB resultCallback);
-#ifdef WITH_CHPROXY
-/**
- * This function sets uri being used for proxy.
- *
- * @param uri NULL terminated resource uri for CoAP-HTTP Proxy.
- */
-OCStackResult OCSetProxyURI(const char *uri);
-#endif
-
#if defined(RD_CLIENT) || defined(RD_SERVER)
/**
* This function binds an resource unique id to the resource.
/**
* Maximum Length of the vendor specific header option
*/
-#define MAX_HEADER_OPTION_DATA_LENGTH (1024)
+#define MAX_HEADER_OPTION_DATA_LENGTH (20)
/**
* Sets the time to live (TTL) for response callback(s).
/** RD Discovery bias factor type. */
#define OC_RSRVD_RD_DISCOVERY_SEL "sel"
-/** Resource URI used to discover Proxy */
-#define OC_RSRVD_PROXY_URI "/oic/chp"
-
-/** Resource URI used to discover Proxy */
-#define OC_RSRVD_PROXY_OPTION_ID 35
-
/** Base URI. */
#define OC_RSRVD_BASE_URI "baseURI"
typedef enum
{
OC_FORMAT_CBOR,
- OC_FORMAT_JSON,
OC_FORMAT_UNDEFINED,
OC_FORMAT_UNSUPPORTED,
} OCPayloadFormat;
{
OC_EH_OK = 0,
OC_EH_ERROR,
- OC_EH_SLOW,
- OC_EH_RESOURCE_CREATED = 201,
- OC_EH_RESOURCE_DELETED = 202,
- OC_EH_VALID = 203,
- OC_EH_CHANGED = 204,
- OC_EH_CONTENT = 205,
- OC_EH_BAD_REQ = 400,
- OC_EH_UNAUTHORIZED_REQ = 401,
- OC_EH_BAD_OPT = 402,
- OC_EH_FORBIDDEN = 403,
- OC_EH_RESOURCE_NOT_FOUND = 404,
- OC_EH_METHOD_NOT_ALLOWED = 405,
- OC_EH_NOT_ACCEPTABLE = 406,
- OC_EH_TOO_LARGE = 413,
- OC_EH_UNSUPPORTED_MEDIA_TYPE = 415,
- OC_EH_INTERNAL_SERVER_ERROR = 500,
- OC_EH_BAD_GATEWAY = 502,
- OC_EH_SERVICE_UNAVAILABLE = 503,
- OC_EH_RETRANSMIT_TIMEOUT = 504
+ OC_EH_RESOURCE_CREATED, // 2.01
+ OC_EH_RESOURCE_DELETED, // 2.02
+ OC_EH_SLOW, // 2.05
+ OC_EH_FORBIDDEN, // 4.03
+ OC_EH_RESOURCE_NOT_FOUND, // 4.04
+ OC_EH_VALID, // 2.03
+ OC_EH_CHANGED, // 2.04
+ OC_EH_CONTENT, // 2.05
+ OC_EH_BAD_REQ, // 4.00
+ OC_EH_UNAUTHORIZED_REQ, // 4.01
+ OC_EH_BAD_OPT, // 4.02
+ OC_EH_METHOD_NOT_ALLOWED, // 4.05
+ OC_EH_NOT_ACCEPTABLE, // 4.06
+ OC_EH_INTERNAL_SERVER_ERROR, // 5.00
+ OC_EH_RETRANSMIT_TIMEOUT // 5.04
} OCEntityHandlerResult;
/**
/** The payload is an OCPresencePayload */
PAYLOAD_TYPE_PRESENCE,
/** The payload is an OCRDPayload */
- PAYLOAD_TYPE_RD,
+ PAYLOAD_TYPE_RD
} OCPayloadType;
/**
while(rep)
{
OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
- if(rep->uri)
- {
- OIC_LOG_V(level, PL_TAG, "\tURI:%s", rep->uri);
- }
-
+ OIC_LOG_V(level, PL_TAG, "\tURI:%s", rep->uri);
+ OIC_LOG(level, PL_TAG, "\tResource Types:");
OCStringLL* strll = rep->types;
- if(strll)
+ while(strll)
{
- OIC_LOG(level, PL_TAG, "\tResource Types:");
- while(strll)
- {
- OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
- strll = strll->next;
- }
+ OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
+ strll = strll->next;
}
-
+ OIC_LOG(level, PL_TAG, "\tInterfaces:");
strll = rep->interfaces;
- if(strll)
+ while(strll)
{
- OIC_LOG(level, PL_TAG, "\tInterfaces:");
- while(strll)
- {
- OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
- strll = strll->next;
- }
+ OIC_LOG_V(level, PL_TAG, "\t\t%s", strll->value);
+ strll = strll->next;
}
// TODO Finish Logging: Values
OCRepPayloadValue* val = rep->values;
+
OIC_LOG(level, PL_TAG, "\tValues:");
+
while(val)
{
switch(val->type)
OIC_LOG_BUFFER(level, PL_TAG, val->ocByteStr.bytes, val->ocByteStr.len);
break;
case OCREP_PROP_OBJECT:
+ // Note: Only prints the URI (if available), to print further, you'll
+ // need to dig into the object better!
OIC_LOG_V(level, PL_TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
- OCPayloadLogRep(level, val->obj);
break;
case OCREP_PROP_ARRAY:
switch(val->arr.type)
val->arr.dimensions[2]);
break;
case OCREP_PROP_OBJECT:
- {
OIC_LOG_V(level, PL_TAG, "\t\t%s(OCRep array):%zu x %zu x %zu",
val->name,
val->arr.dimensions[0], val->arr.dimensions[1],
val->arr.dimensions[2]);
-
- size_t i = 0;
- if (val->arr.dimensions[0] > 0)
- {
- for (i = 0 ; i < val->arr.dimensions[0] ; i++)
- {
- OCPayloadLogRep(level, val->arr.objArray[i]);
- }
- }
break;
- }
default:
OIC_LOG_V(ERROR, PL_TAG, "\t\t%s <-- Unknown/unsupported array type!",
val->name);
{
// Add a zero-character string terminator.
char *securityData = (char *)OICMalloc(payloadSize + 1);
-
+
if (securityData)
{
memcpy(securityData, payload->securityData, payloadSize);
static char discoveryAddr[100];
static std::string coapServerResource = "/a/light";
-// Following resource is used to verify coap-http proxy
-static std::string coapProxyResource = OC_RSRVD_PROXY_URI;
-static std::string httpResource; // Will be taken as user input
-
#ifdef WITH_PRESENCE
// The handle for observe registration
OCDoHandle gPresenceHandle;
static void PrintUsage()
{
- OIC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1..21> -c <0|1>");
+ OIC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1..17> -c <0|1>");
OIC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
OIC_LOG(INFO, TAG, "-c 0 : Use Default connectivity(IP)");
OIC_LOG(INFO, TAG, "-c 1 : IP Connectivity Type");
"add vendor specific header options");
OIC_LOG(INFO, TAG, "-t 19 : Discover Platform");
OIC_LOG(INFO, TAG, "-t 20 : Discover Devices");
- OIC_LOG(INFO, TAG, "-t 21 -p \"http_uri\": Discover Proxy and Initiate Nonconfirmable Get Request");
}
OCStackResult InvokeOCDoResource(std::ostringstream &query,
cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
cbData.cd = NULL;
- const char *uri = query.str().length() ? query.str().c_str() : NULL;
- ret = OCDoResource(&handle, method, uri, remoteAddr,
+ ret = OCDoResource(&handle, method, query.str().c_str(), remoteAddr,
(method == OC_REST_PUT) ? putPayload() : NULL,
(ConnType), qos, &cbData, options, numOptions);
OCResourcePayload *resource = (OCResourcePayload*) payload->resources;
int found = 0;
-
- std::string resourceToFind = (TestCase == TEST_PROXY_GET_REQ_NON) ?
- coapProxyResource : coapServerResource;
while (resource)
{
- if(resource->uri && strcmp(resource->uri, resourceToFind.c_str()) == 0)
+ if(resource->uri && strcmp(resource->uri, coapServerResource.c_str()) == 0)
{
found = 1;
break;
if(!found)
{
- OIC_LOG_V (INFO, TAG, "No %s in payload", resourceToFind.c_str());
+ OIC_LOG_V (INFO, TAG, "No /a/light in payload");
return OC_STACK_KEEP_TRANSACTION;
}
case TEST_OBS_REQ_CON:
InitObserveRequest(OC_HIGH_QOS);
break;
- case TEST_PROXY_GET_REQ_NON:
- InitProxyGetRequest(OC_LOW_QOS);
- break;
#ifdef WITH_PRESENCE
case TEST_OBS_PRESENCE:
case TEST_OBS_PRESENCE_WITH_FILTER:
return result;
}
-int InitProxyGetRequest(OCQualityOfService qos)
-{
- OIC_LOG(INFO, TAG, "InitProxyGetRequest");
- OCHeaderOption option;
- memset(&option, 0, sizeof(option));
-
- option.protocolID = OC_COAP_ID;
- option.optionID = OC_RSRVD_PROXY_OPTION_ID;
- memcpy(option.optionData, (uint8_t *)httpResource.c_str(), httpResource.length());
- option.optionLength = httpResource.length();
-
- std::ostringstream query;
- // A request with proxy uri shall not have resource uri
- // query << coapProxyResource;
-
- return (InvokeOCDoResource(query, &serverAddr, OC_REST_GET,
- (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS, getReqCB, &option, 1));
-}
-
-int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions,
- bool getWithQuery)
+int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions, bool getWithQuery)
{
OCHeaderOption options[MAX_HEADER_OPTIONS];
{
int opt;
- while ((opt = getopt(argc, argv, "u:t:c:p:")) != -1)
+ while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
{
switch(opt)
{
case 'c':
Connectivity = atoi(optarg);
break;
- case 'p':
- if(optarg)
- {
- httpResource = optarg;
- }
- break;
default:
PrintUsage();
return -1;
if ((UnicastDiscovery != 0 && UnicastDiscovery != 1) ||
(TestCase < TEST_DISCOVER_REQ || TestCase >= MAX_TESTS) ||
- (Connectivity < CT_ADAPTER_DEFAULT || Connectivity >= MAX_CT) ||
- (TestCase == TEST_PROXY_GET_REQ_NON && httpResource.length() == 0) )
+ (Connectivity < CT_ADAPTER_DEFAULT || Connectivity >= MAX_CT))
{
PrintUsage();
return -1;
TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
TEST_DISCOVER_PLATFORM_REQ,
TEST_DISCOVER_DEV_REQ,
- TEST_PROXY_GET_REQ_NON,
MAX_TESTS
} CLIENT_TEST;
/* Get the port number the server is listening on */
std::string getPortTBServer(OCClientResponse * clientResponse);
+/* Returns the query string for GET and PUT operations */
+std::string getQueryStrForGetPut(OCClientResponse * clientResponse);
+
/* Following are initialization functions for GET, Observe, PUT
* POST, Delete & Discovery operations
*/
int InitDeviceDiscovery(OCQualityOfService qos);
int InitPlatformDiscovery(OCQualityOfService qos);
int InitDiscovery(OCQualityOfService qos);
-int InitProxyGetRequest(OCQualityOfService qos);
+
+/* Function to retrieve ip address, port no. of the server
+ * and query for the operations to be performed.
+ */
+void parseClientResponse(OCClientResponse * clientResponse);
/* Call delete operation on already deleted resource */
void* RequestDeleteDeathResourceTask(void* myqos);
help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os]))
help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1')))
help_vars.Add(EnumVariable('ROUTING', 'Enable routing', 'EP', allowed_values=('GW', 'EP')))
-help_vars.Add(BoolVariable('WITH_PROXY', 'CoAP-HTTP Proxy', False)) # set to 'no', 'false' or 0 for debug
######################################################################
# Platform(build target) specific options: SDK/NDK & toolchain
elif env.get('ROUTING') == 'EP':
env.AppendUnique(CPPDEFINES = ['ROUTING_EP'])
env.AppendUnique(CPPDEFINES = ['__TIZEN__'])
-if env.get('WITH_PROXY'):
- env.AppendUnique(CPPDEFINES = ['WITH_CHPROXY'])
Export('env')
%build
scons TARGET_OS=tizen -c
-scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} ROUTING=%{ROUTING} WITH_TCP=%{WITH_TCP} WITH_PROXY=%{WITH_PROXY}
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} ROUTING=%{ROUTING} WITH_TCP=%{WITH_TCP}
%install
elif routing == 'EP':
env.AppendUnique(CPPDEFINES = ['ROUTING_EP'])
-if env.get('WITH_PROXY'):
- env.AppendUnique(CPPDEFINES = ['WITH_CHPROXY'])
-
env.Append(LIBS=[
'm', 'pthread', 'rt', 'dl', 'stdc++', 'gobject-2.0', 'gio-2.0', 'glib-2.0', 'capi-network-wifi', 'dlog', 'capi-network-bluetooth', 'connectivity_abstraction', 'coap', 'octbstack', 'ocsrm', 'c_common'
])
secured = env.get('SECURED')
logging = env.get('LOGGING')
routing = env.get('ROUTING')
-with_proxy = env.get('WITH_PROXY')
with_tcp = env.get('WITH_TCP')
env.PrependUnique(CPPPATH = [
env.AppendUnique(CPPDEFINES = ['ROUTING_EP'])
env.AppendUnique(CPPDEFINES = ['__TIZEN__'])
-if env.get('WITH_PROXY'):
- env.AppendUnique(CPPDEFINES = ['WITH_CHPROXY'])
-
print "Given Transport is %s" % transport
print "Given OS is %s" % target_os
if target_os == 'tizen':
- command = "sh resource/csdk/stack/samples/tizen/build/gbsbuild.sh %s %s %s %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging, routing, with_tcp, with_proxy)
+ command = "sh resource/csdk/stack/samples/tizen/build/gbsbuild.sh %s %s %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging, routing, with_tcp)
print "Created Command is %s" % command
gbs_script = env.Command('gbs_build', None, command)
AlwaysBuild ('gbs_script')
\ No newline at end of file
echo $7
export WITH_TCP=$7
-echo $8
-export WITH_PROXY=$8
-
echo $TARGET_TRANSPORT
echo $BUILD_SAMPLE
fi
echo "Calling core gbs build command"
-gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8'"
+gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7'"
echo $gbscommand
if eval $gbscommand; then
echo "Core build is successful"
git commit -m "Initial commit"
fi
echo "Calling sample gbs build command"
- gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7' --define 'WITH_PROXY $8'"
+ gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-RI-OIC --include-all --repository ./ --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --define 'ROUTING $6' --define 'WITH_TCP $7'"
echo $gbscommand
if eval $gbscommand; then
echo "Sample build is successful"
echo %{ROOTDIR}
scons TARGET_OS=tizen -c
-scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} LOGGING=%{LOGGING} ROUTING=%{ROUTING} WITH_TCP=%{WITH_TCP} WITH_PROXY=%{WITH_PROXY}
+scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} LOGGING=%{LOGGING} ROUTING=%{ROUTING} WITH_TCP=%{WITH_TCP}
%install
mkdir -p %{DEST_INC_DIR}
OCDevAddr *devAddr, char * requestUri,
char * resourceTypeName, uint32_t ttl)
{
- if (!clientCB || !cbData || !handle || tokenLength > CA_MAX_TOKEN_LEN)
+ if (!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
{
return OC_STACK_INVALID_PARAM;
}
CADestroyToken (cbNode->token);
OICFree(cbNode->devAddr);
OICFree(cbNode->handle);
- if (cbNode->requestUri)
- {
- OIC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
- OICFree(cbNode->requestUri);
- }
+ OIC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
+ OICFree(cbNode->requestUri);
if (cbNode->deleteCallback)
{
cbNode->deleteCallback(cbNode->context);
// Internal functions
//-----------------------------------------------------------------------------
-bool checkProxyUri(OCHeaderOption *options, uint8_t numOptions)
-{
- if (!options || 0 == numOptions)
- {
- OIC_LOG (INFO, TAG, "No options present");
- return false;
- }
-
- for (uint8_t i = 0; i < numOptions; i++)
- {
- if (options[i].protocolID == OC_COAP_ID && options[i].optionID == OC_RSRVD_PROXY_OPTION_ID)
- {
- OIC_LOG(DEBUG, TAG, "Proxy URI is present");
- return true;
- }
- }
- return false;
-}
-
uint32_t GetTicks(uint32_t afterMilliSeconds)
{
coap_tick_t now;
cbNode->method == OC_REST_OBSERVE_ALL ||
cbNode->method == OC_REST_DELETE)
{
- if (cbNode->requestUri)
+ char targetUri[MAX_URI_LENGTH];
+ snprintf(targetUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
+ OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+ if (strcmp(targetUri, cbNode->requestUri) == 0)
{
- char targetUri[MAX_URI_LENGTH];
- snprintf(targetUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
- OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
- if (strcmp(targetUri, cbNode->requestUri) == 0)
- {
- type = PAYLOAD_TYPE_RD;
- }
- else if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0)
- {
- type = PAYLOAD_TYPE_PLATFORM;
- }
- else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0)
- {
- type = PAYLOAD_TYPE_DEVICE;
- }
- if (type == PAYLOAD_TYPE_INVALID)
- {
- OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
- cbNode->method, cbNode->requestUri);
- type = PAYLOAD_TYPE_REPRESENTATION;
- }
+ type = PAYLOAD_TYPE_RD;
}
- else
+ else if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0)
+ {
+ type = PAYLOAD_TYPE_PLATFORM;
+ }
+ else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0)
+ {
+ type = PAYLOAD_TYPE_DEVICE;
+ }
+ if (type == PAYLOAD_TYPE_INVALID)
{
- OIC_LOG(INFO, TAG, "No Request URI, PROXY URI");
+ OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
+ cbNode->method, cbNode->requestUri);
type = PAYLOAD_TYPE_REPRESENTATION;
}
}
// Validate input parameters
VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+ VERIFY_NON_NULL(requestUri , FATAL, OC_STACK_INVALID_URI);
OCStackResult result = OC_STACK_ERROR;
CAResult_t caResult;
adapter = (OCTransportAdapter)(connectivityType >> CT_ADAPTER_SHIFT);
flags = (OCTransportFlags)(connectivityType & CT_MASK_FLAGS);
- if (requestUri)
- {
- result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType);
- if (result != OC_STACK_OK)
- {
- OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri);
- goto exit;
- }
- }
- else if (!checkProxyUri(options, numOptions))
+ result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType);
+ if (result != OC_STACK_OK)
{
- OIC_LOG(ERROR, TAG, "Request doesn't contain RequestURI/Proxy URI");
+ OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri);
goto exit;
}
}
}
-#ifdef WITH_CHPROXY
-OCStackResult OCSetProxyURI(const char *uri)
-{
- return CAResultToOCResult(CASetProxyUri(uri));
-}
-#endif
-
#if defined(RD_CLIENT) || defined(RD_SERVER)
OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins)
{
#if env.get('WITH_RD') == '1':
#SConscript('resource-directory/SConscript')
- # Build coap-http-proxy project
- if target_os in ['linux'] and env.get('WITH_PROXY', False):
- SConscript('coap-http-proxy/SConscript')
-
# Build EasySetup module
if target_os in ['arduino', 'android', 'linux','tizen']:
SConscript('easy-setup/SConscript')
+++ /dev/null
-#******************************************************************
-#
-# Copyright 2016 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.
-#
-#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-##
-# CoAP-HTTP Proxy build script
-##
-Import('env')
-import os
-local_env = env.Clone()
-
-if local_env.get('LOGGING'):
- local_env.AppendUnique(CPPDEFINES = ['-DTB_LOG'])
-
-if env.get('RELEASE'):
- env.AppendUnique(CCFLAGS = ['-Os'])
- env.AppendUnique(CPPDEFINES = ['NDEBUG'])
-else:
- env.AppendUnique(CCFLAGS = ['-g'])
-
-target_os = env.get('TARGET_OS')
-src_dir = env.get('SRC_DIR')
-
-######################################################################
-# Build flags
-######################################################################
-local_env.AppendUnique(CPPPATH = ['include',
- os.path.join(src_dir, 'resource/csdk/stack/include'),
- os.path.join(src_dir, 'resource/csdk/connectivity/common/inc/'),
- os.path.join(src_dir, 'resource/csdk/connectivity/lib/libcoap-4.1.1'),
- os.path.join(src_dir, 'extlibs/cjson'),
- ])
-local_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap'])
-if target_os not in ['windows']:
- local_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra'])
-
-if target_os in ['linux']:
- local_env.AppendUnique(LIBS = ['pthread', 'curl'])
-
-if target_os == 'android':
- local_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
- local_env.AppendUnique(LIBS = ['gnustl_static'])
-
- if not env.get('RELEASE'):
- rd_env.AppendUnique(LIBS = ['log'])
-######################################################################
-# Source files and Targets
-######################################################################
-
-proxy_src = [
- './src/CoapHttpHandler.c',
- './src/CoapHttpMap.c',
- './src/CoapHttpParser.c',
-]
-
-if target_os in ['tizen'] :
- proxysdk = local_env.SharedLibrary('coap_http_proxy', proxy_src)
-else :
- proxysdk = local_env.StaticLibrary('coap_http_proxy', proxy_src)
-
-local_env.InstallTarget(proxysdk, 'coap_http_proxy')
-local_env.UserInstallTargetLib(proxysdk, 'coap_http_proxy')
-local_env.UserInstallTargetHeader('include/CoapHttpHandler.h', 'service/coap-http-proxy', 'CoapHttpHandler.h')
-
-
-######################################################################
-# Samples for the proxy
-######################################################################
-if target_os in ['linux']:
- SConscript('samples/SConscript')
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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.
- *
- ******************************************************************/
-
-/**
- * @file
- * This file contains the functions to initiate request or response handling by CHP
- */
-
-#ifndef COAP_HTTP_HANDLER_H_
-#define COAP_HTTP_HANDLER_H_
-
-#include "ocstack.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * Initialize the CoAP HTTP Proxy.
- * @return ::OC_STACK_OK or Appropriate error code.
- */
-OCStackResult CHPInitialize();
-
-/**
- * Terminate the CoAP HTTP Proxy.
- * @return ::OC_STACK_OK or Appropriate error code.
- */
-OCStackResult CHPTerminate();
-
-/**
- * API to check if CoAP-HTTP Proxy is initialized.
- * @return true if initialized else false.
- */
-bool CHPIsInitialized();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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.
- *
- ******************************************************************/
-
-/**
- * @file
- * This file contains CoAP to HTTP mapping
- */
-
-#ifndef COAP_HTTP_MAP_H_
-#define COAP_HTTP_MAP_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include "CoapHttpParser.h"
-#include "cJSON.h"
-
-/**
- * Function to get CoAP code for an HTTP code.
- * @param[in] httpCode HTTP Code.
- * @param[in] method Request Method type
- * @param[out] ocfCode Corresponding OCF code.
- * @return ::OC_STACK_OK or appropriate error code.
- */
-OCStackResult CHPGetOCCode(const HttpResponseResult_t httpCode, const OCMethod method,
- OCEntityHandlerResult *ocfCode);
-
-/**
- * Function to get CoAP option for an HTTP option.
- * @param[in] httpOption HTTP Option.
- * @param[out] ret Corresponding CoAP option.
- * @return ::OC_STACK_OK or appropriate error code.
- */
-OCStackResult CHPGetOCOption(const HttpHeaderOption_t *httpOption, OCHeaderOption *ret);
-
-/**
- * Function to get CoAP payload format for HTTP payload format.
- * @param[in] httpContentType HTTP payload format.
- * @return CoAP payload format.
- */
-OCPayloadFormat CHPGetOCContentType(const char *httpContentType);
-
-/**
- * Function to get HTTP method for OCF method.
- * @param[in] method OCF method.
- * @param[out] httpMethod Corresponding HTTP method.
- * @return ::OC_STACK_OK or appropriate error code.
- */
-OCStackResult CHPGetHttpMethod(const OCMethod method, HttpMethod_t *httpMethod);
-
-/**
- * Function to get HTTP option for OCF option.
- * @param[in] option OCF option.
- * @param[out] ret Corresponding HTTP option.
- * @return ::OC_STACK_OK or appropriate error code.
- */
-OCStackResult CHPGetHttpOption(const OCHeaderOption* option, HttpHeaderOption_t **ret);
-
-/**
- * Function to convert Json payload to CBOR representational payload.
- * @param[in] rootJSon Json payload.
- * @param[out] payload CBor representational payload.
- */
-void CHPJsonToRepPayload(cJSON* rootJSon, OCRepPayload* payload);
-
-/**
- * Function to convert CBOR representational payload to Json payload.
- * @param[in] repData Cbor representational payload.
- * @return CJson payload.
- */
-cJSON* CHPRepPayloadToJson(OCRepPayload* repData);
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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.
- *
- ******************************************************************/
-
-/**
- * @file
- * This file contains HTTP parsing functions
- */
-
-#ifndef COAP_HTTP_PARSER_H_
-#define COAP_HTTP_PARSER_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include <unistd.h>
-#include "uarraylist.h"
-#include "octypes.h"
-
-#define CHP_MAX_HF_DATA_LENGTH 1024
-#define CHP_MAX_HF_NAME_LENGTH 255
-#define JSON_CONTENT_TYPE "application/json"
-#define CBOR_CONTENT_TYPE "application/cbor"
-#define ACCEPT_MEDIA_TYPE (CBOR_CONTENT_TYPE "; q=1.0, " JSON_CONTENT_TYPE "; q=0.5")
-
-// HTTP Option types
-#define HTTP_OPTION_CACHE_CONTROL "cache-control"
-#define HTTP_OPTION_ACCEPT "accept"
-#define HTTP_OPTION_IF_MATCH "if-match"
-#define HTTP_OPTION_IF_NONE_MATCH "if-none-match"
-#define HTTP_OPTION_ETAG "etag"
-#define HTTP_OPTION_CONTENT_TYPE "content-type"
-#define HTTP_OPTION_CONTENT_LENGTH "content-length"
-#define HTTP_OPTION_EXPIRES "expires"
-
-/**
- * @enum HttpResponseResult_t
- * Enums for HTTP Response values
- */
-typedef enum
-{
- /* Response status code - START HERE */
- CHP_EMPTY = 0, /**< Empty */
- CHP_SUCCESS = 200, /**< Success */
- CHP_CREATED = 201, /**< Created */
- CHP_ACCEPTED = 202, /**< Accepted */
- CHP_NO_CONTENT = 204, /**< No Content */
- CHP_RESET_CONTENT = 205, /**< Reset content */
- CHP_NOT_MODIFIED = 304, /**< Not Modified */
- CHP_BAD_REQ = 400, /**< Bad Request */
- CHP_UNAUTHORIZED_REQ = 401, /**< Unauthorized Request */
- CHP_FORBIDDEN_REQ = 403, /**< Forbidden Request */
- CHP_NOT_FOUND = 404, /**< Not found */
- CHP_NOT_ACCEPTABLE = 406, /**< Not Acceptable */
- CHP_REQUEST_ENTITY_TOO_LARGE = 413, /**< Request Entity Too Large */
- CHP_REQUEST_URI_TOO_LARGE = 414, /**< Request URI Too Large */
- CHP_UNSUPPORTED_MEDIA_TYPE = 415, /**< Unsupported Media type */
- CHP_INTERNAL_SERVER_ERROR = 500, /**< Internal server Error */
- CHP_NOT_IMPLEMENTED = 501, /**< Not Implemented */
- CHP_BAD_GATEWAY = 502, /**< Bad Gateway */
- CHP_SERVICE_UNAVAILABLE = 503, /**< Service Unavailable */
- CHP_GATEWAY_TIMEOUT = 504, /**< Gateway Timeout */
- CHP_VERSION_NOT_SUPPORTED = 505 /**< Version not supported */
- /* Response status code - END HERE */
-} HttpResponseResult_t;
-
-/**
- * Header fields structure to be filled
- *
- * This structure is used to hold header information.
- */
-typedef struct
-{
- uint16_t optionLength; /**< Option length. **/
- char optionName[CHP_MAX_HF_NAME_LENGTH]; /**< Option name. **/
- char optionData[CHP_MAX_HF_DATA_LENGTH]; /**< Option data values. **/
-} HttpHeaderOption_t;
-
-typedef enum
-{
- CHP_GET = 1, /**< GET */
- CHP_POST, /**< POST */
- CHP_PUT, /**< PUT */
- CHP_DELETE, /**< DELETE */
- CHP_INVALID
-}HttpMethod_t;
-
-typedef struct HttpRequest_t
-{
- unsigned short httpMajor;
- unsigned short httpMinor;
- HttpMethod_t method;
- u_arraylist_t *headerOptions;
- char resourceUri[CHP_MAX_HF_DATA_LENGTH];
- void *payload;
- size_t payloadLength;
- bool payloadCached;
- char payloadFormat[CHP_MAX_HF_DATA_LENGTH];
- char acceptFormat[CHP_MAX_HF_DATA_LENGTH];
-}HttpRequest_t;
-
-typedef struct HttpResponse_t
-{
- unsigned short httpMajor;
- unsigned short httpMinor;
- HttpResponseResult_t status;
- u_arraylist_t *headerOptions;
- char dataFormat[CHP_MAX_HF_DATA_LENGTH];
- void *payload;
- size_t payloadLength;
-}HttpResponse_t;
-
-typedef void (*CHPResponseCallback)(const HttpResponse_t *response, void *context);
-
-/**
- * Function to initialize Parser and HTTP stack.
- */
-OCStackResult CHPParserInitialize();
-
-/**
- * Function to terminate parser and HTTP stack.
- */
-OCStackResult CHPParserTerminate();
-
-/**
- * Function to initiate TCP session and post HTTP request. If the method returns
- * success, payload might be cached by the parser (req->payloadCached) and caller shall not free the
- * payload if the flag is set.
- * @param[in] req Object containing HTTP request information.
- * @param[in] httpcb Callback for http response.
- * @param[in] context Any app specific context for request
- */
-OCStackResult CHPPostHttpRequest(HttpRequest_t *req, CHPResponseCallback httpcb,
- void *context);
-
-/**
- * Macro to verify the validity of input argument.
- *
- * @param arg log level
- * @param log_tag log tag
- * @param log_message log message
- * @param ret return value
- */
-#define VERIFY_NON_NULL_RET(arg, log_tag, log_message, ret) \
- if (NULL == (arg)) \
- { \
- OIC_LOG_V(ERROR, (log_tag), "Invalid input:%s", (log_message)); \
- return (ret); \
- } \
-
-/**
- * Macro to verify the validity of input argument.
- *
- * @param arg log level
- * @param log_tag log tag
- * @param log_message log message
- */
-#define VERIFY_NON_NULL(arg, log_tag, log_message) \
- VERIFY_NON_NULL_RET((arg), (log_tag), (log_message), CA_STATUS_INVALID_PARAM)
-
-/**
- * Macro to verify the validity of input argument.
- *
- * @param arg log level
- * @param log_tag log tag
- * @param log_message log message
- */
-#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \
- if (NULL == (arg)) { \
- OIC_LOG_V(ERROR, (log_tag), "Invalid input:%s", (log_message)); \
- return; \
- } \
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-#******************************************************************
-#
-# Copyright 2016 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.
-#
-#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-##
-# CoAP-HTTP-Proxy Sample Apps build script
-##
-
-Import('env')
-
-lib_env = env.Clone()
-SConscript('#service/third_party_libs.scons', 'lib_env')
-
-proxy_sample_app_env = lib_env.Clone()
-
-target_os = env.get('TARGET_OS')
-######################################################################
-# Build flags
-######################################################################
-proxy_sample_app_env.AppendUnique(CPPPATH = ['../include'])
-
-if target_os not in ['windows']:
- proxy_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
-proxy_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
-proxy_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
-proxy_sample_app_env.PrependUnique(LIBS = ['coap_http_proxy', 'oc', 'octbstack', 'curl', 'connectivity_abstraction'])
-
-if env.get('SECURED') == '1':
- proxy_sample_app_env.AppendUnique(LIBS = ['tinydtls'])
-
-####################################################################
-# Source files and Targets
-######################################################################
-proxy_server = proxy_sample_app_env.Program('proxy_main', 'proxy_main.c')
-
-Alias("coap_http_proxy", [proxy_server])
-
-env.AppendTarget('coap_http_proxy')
+++ /dev/null
-//******************************************************************
-//
-// Copyright 2016 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 "CoapHttpHandler.h"
-
-#include <signal.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-int g_quitFlag = 0;
-
-void handleSigInt(int signum);
-
-/*
-* This method is an entry point of CoAP-HTTP Proxy.
-*/
-
-int main()
-{
- printf("CoAP-HTTP proxy is starting..\n");
- OCStackResult result = OCInit(NULL, 0, OC_SERVER);
- if (result != OC_STACK_OK)
- {
- printf("Failed starting proxy\n");
- return 0;
- }
-
- if (CHPInitialize() != OC_STACK_OK)
- {
- printf("Failed to start proxy.\n");
- OCStop();
- return 0;
- }
-
- printf("Proxy started successfully.\n");
-
- signal(SIGINT, handleSigInt);
- while (!g_quitFlag)
- {
- if (OCProcess() != OC_STACK_OK)
- {
- CHPTerminate();
- OCStop();
- printf("OCStack process error\n");
- return 0;
- }
- }
-
- if (CHPTerminate() != OC_STACK_OK)
- {
- printf("CHPTerminate failed.\n");
- }
- else
- {
- printf("CHPTerminate success.\n");
- }
-
- OCStop();
- printf("Exiting proxy main loop...\n");
- return 0;
-
-}
-
-/*
-* This is a signal handling function for SIGINT(CTRL+C).
-* A Resource Directory handle the SIGINT signal for safe exit.
-*
-* @param[in] signal
-* signal number of caught signal.
-*/
-void handleSigInt(int signum)
-{
- if (signum == SIGINT)
- {
- g_quitFlag = 1;
- }
-}
-
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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 "CoapHttpHandler.h"
-#include "oic_malloc.h"
-#include "oic_string.h"
-#include "logger.h"
-#include "pdu.h"
-#include "ocpayload.h"
-#include "uarraylist.h"
-#include "CoapHttpParser.h"
-#include "CoapHttpMap.h"
-#include "cJSON.h"
-
-#define TAG "CHPHandler"
-
-#define CHP_RESOURCE_TYPE_NAME "core.chp"
-#define CHP_RESOURCE_INTF_NAME "oc.mi.def"
-
-/**
- * CoAP request tracking.
- * This structure is used to hold CoAP request information
- */
-typedef struct
-{
- OCMethod method;
- OCRequestHandle requestHandle;
-} CHPRequest_t;
-
-/**
- * Pointer to handle of the newly created proxy resource.
- */
-static OCResourceHandle g_proxyHandle = NULL;
-static int g_isCHProxyInitialized = false;
-
-/**
- * Function to hand over CoAP request handling to Proxy.
- */
-OCStackResult CHPHandleOCFRequest(const OCEntityHandlerRequest* requestInfo,
- const char* proxyUri);
-
-/**
- * Entity handler to receive requests from csdk.
- */
-OCEntityHandlerResult CHPEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest* entityHandlerRequest,
- void* callbackParam);
-bool CHPIsInitialized()
-{
- return g_isCHProxyInitialized;
-}
-
-OCStackResult CHPInitialize()
-{
- OIC_LOG(DEBUG, TAG, "CHPInitialize IN");
- if (g_isCHProxyInitialized)
- {
- OIC_LOG(DEBUG, TAG, "CH Proxy already initialized");
- return OC_STACK_OK;
- }
-
- OCStackResult result = CHPParserInitialize();
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "Parser initialization failed[%d]", result);
- return result;
- }
-
- result = OCSetProxyURI(OC_RSRVD_PROXY_URI);
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "Setting proxy uri failed[%d]", result);
- CHPParserTerminate();
- return result;
- }
-
- result = OCCreateResource(&g_proxyHandle,
- CHP_RESOURCE_TYPE_NAME,
- CHP_RESOURCE_INTF_NAME,
- OC_RSRVD_PROXY_URI,
- CHPEntityHandler,
- NULL,
- OC_ACTIVE | OC_DISCOVERABLE | OC_SLOW);
-
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "Create resource for proxy failed[%d]", result);
- CHPParserTerminate();
- return result;
- }
-
- g_isCHProxyInitialized = true;
- OIC_LOG(DEBUG, TAG, "CHPInitialize OUT");
- return OC_STACK_OK;
-}
-
-OCStackResult CHPTerminate()
-{
- OIC_LOG(DEBUG, TAG, "CHPTerminate IN");
- OCStackResult result = CHPParserTerminate();
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "Parser termination failed[%d]", result);
- }
-
- result = OCDeleteResource(g_proxyHandle);
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "Delete resource for proxy failed[%d]", result);
- }
-
- g_proxyHandle = NULL;
- g_isCHProxyInitialized = false;
- return result;
- OIC_LOG(DEBUG, TAG, "CHPTerminate OUT");
-}
-
-static void CHPGetProxyURI(OCHeaderOption* options, uint8_t *numOptions, char* uri,
- size_t uriLength)
-{
- OIC_LOG(DEBUG, TAG, "CHPGetProxyURI IN");
- if(!uri || uriLength <= 0)
- {
- OIC_LOG (INFO, TAG, "Invalid uri buffer");
- return;
- }
-
- if (!options || !numOptions || 0 == *numOptions)
- {
- OIC_LOG (INFO, TAG, "No options present");
- return;
- }
-
- for (int count = 0; count < *numOptions; count++)
- {
- if (options[count].protocolID == OC_COAP_ID &&
- options[count].optionID == COAP_OPTION_PROXY_URI)
- {
- OIC_LOG(DEBUG, TAG, "Proxy URI is present");
- // Extract proxy-uri and delete it from headeroptions.
- OICStrcpy(uri, uriLength, (char *)options[count].optionData);
- for (int fwd = count; fwd < *numOptions-1; fwd++)
- {
- options[count] = options[count+1];
- }
- *numOptions -= 1;
- return;
- }
- }
-
- OIC_LOG(DEBUG, TAG, "CHPGetProxyURI OUT");
- return;
-}
-
-// TODO: Will be moved to OCProxyPayload
-static OCRepPayload* CHPGetDiscoveryPayload()
-{
- OCRepPayload* payload = OCRepPayloadCreate();
- if(!payload)
- {
- OIC_LOG(ERROR, TAG, PCF("Failed to create Payload"));
- return NULL;
- }
-
- OCRepPayloadSetUri(payload, OC_RSRVD_PROXY_URI);
- OCRepPayloadSetPropString(payload, OC_RSRVD_DEVICE_ID, OCGetServerInstanceIDString());
- return payload;
-}
-
-OCEntityHandlerResult CHPEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest* entityHandlerRequest,
- void* callbackParam)
-{
- OIC_LOG_V(INFO, TAG, "Proxy request received");
- UNUSED(callbackParam);
-
- if(!g_isCHProxyInitialized)
- {
- OIC_LOG (ERROR, TAG, "Proxy not initialized");
- return OC_EH_INTERNAL_SERVER_ERROR;
- }
-
- if (!entityHandlerRequest)
- {
- OIC_LOG (ERROR, TAG, "Invalid request pointer");
- return OC_EH_ERROR;
- }
-
- if(flag & OC_OBSERVE_FLAG)
- {
- OIC_LOG_V (ERROR, TAG, "Proxy is not observable");
- return OC_EH_BAD_REQ;
- }
- else if (flag & OC_REQUEST_FLAG)
- {
- /*
- * A proxy can handle two type of requests:
- * 1. Discovery request in which case proxy-uri option will not be present.
- * 2. Request for HTTP resource with proxy-uri option.
- */
- char proxyUri[MAX_HEADER_OPTION_DATA_LENGTH] = {'\0'};
- CHPGetProxyURI(entityHandlerRequest->rcvdVendorSpecificHeaderOptions,
- &(entityHandlerRequest->numRcvdVendorSpecificHeaderOptions),
- proxyUri, sizeof(proxyUri));
-
- if(proxyUri[0] != '\0')
- {
- // A request for HTTP resource. Response will be sent asynchronously
- if(OC_STACK_OK == CHPHandleOCFRequest(entityHandlerRequest,
- proxyUri) )
- {
- return OC_EH_SLOW;
- }
- }
- else
- {
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
- switch (entityHandlerRequest->method)
- {
- case OC_REST_GET:
- case OC_REST_DISCOVER:
- {
- // Generate discovery payload
- OIC_LOG (INFO, TAG, "Discovery request from client");
- ehResult = OC_EH_OK;
- OCEntityHandlerResponse response =
- { .requestHandle = entityHandlerRequest->requestHandle,
- .resourceHandle = entityHandlerRequest->resource,
- .ehResult = ehResult};
-
- response.payload = (OCPayload *)CHPGetDiscoveryPayload();
- // Indicate that response is NOT in a persistent buffer
- response.persistentBufferFlag = 0;
-
- // Send the response
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- ehResult = OC_EH_ERROR;
- }
-
- OCPayloadDestroy(response.payload);
- break;
- }
- default:
- // Other methods are not supported
- OIC_LOG (INFO, TAG, "Invalid method from client");
- ehResult = OC_EH_METHOD_NOT_ALLOWED;
- break;
- }
- return ehResult;
- }
- }
-
- return OC_EH_ERROR;
-}
-
-void CHPHandleHttpResponse(const HttpResponse_t *httpResponse, void *context)
-{
- OIC_LOG(DEBUG, TAG, "CHPHandleHttpResponse IN");
- if (!httpResponse || !context)
- {
- OIC_LOG(ERROR, TAG, "Invalid arguements");
- return;
- }
-
- CHPRequest_t *ctxt = (CHPRequest_t *)context;
- OCEntityHandlerResponse response = { .requestHandle = ctxt->requestHandle,
- .resourceHandle = g_proxyHandle};
- response.persistentBufferFlag = 0;
-
- OCStackResult result = CHPGetOCCode(httpResponse->status, ctxt->method,
- &response.ehResult);
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "%s failed[%d]", __func__, result);
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
- OICFree(ctxt);
- return;
- }
-
- // ctxt not required now.
- OICFree(ctxt);
-
- OCPayloadFormat format = CHPGetOCContentType(httpResponse->dataFormat);
- switch (format)
- {
- case OC_FORMAT_CBOR:
- OIC_LOG(DEBUG, TAG, "Payload format is CBOR");
- result = OCParsePayload(&response.payload, PAYLOAD_TYPE_REPRESENTATION,
- httpResponse->payload, httpResponse->payloadLength);
- if(result != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error parsing payload");
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
- return;
- }
- break;
- case OC_FORMAT_JSON:
- OIC_LOG(DEBUG, TAG, "Payload format is JSON");
- cJSON *payloadJson = cJSON_Parse((char *)httpResponse->payload);
- OCRepPayload* payloadCbor = OCRepPayloadCreate();
- if(!payloadCbor)
- {
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
- cJSON_Delete(payloadJson);
- return;
- }
-
- CHPJsonToRepPayload(payloadJson, payloadCbor);
- response.payload = (OCPayload *)payloadCbor;
- cJSON_Delete(payloadJson);
- break;
- default:
- OIC_LOG(ERROR, TAG, "Payload format is not supported");
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
- return;
- }
-
- // Header Options parsing
- response.numSendVendorSpecificHeaderOptions = 0;
- OCHeaderOption *optionsPointer = response.sendVendorSpecificHeaderOptions;
-
- uint8_t tempOptionNumber = u_arraylist_length(httpResponse->headerOptions);
- for (int numOptions = 0; numOptions < tempOptionNumber &&
- response.numSendVendorSpecificHeaderOptions < MAX_HEADER_OPTIONS;
- numOptions++)
- {
- HttpHeaderOption_t *httpOption = u_arraylist_get(httpResponse->headerOptions, numOptions);
- result = CHPGetOCOption(httpOption, optionsPointer);
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "CHPGetCoAPOption failed[%d][%d]", result,
- response.numSendVendorSpecificHeaderOptions);
- continue;
- }
-
- response.numSendVendorSpecificHeaderOptions++;
- optionsPointer += 1;
- }
-
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
-
- //OICFree(coapResponseInfo.info.payload);
- OIC_LOG(DEBUG, TAG, "CHPHandleHttpResponse OUT");
-}
-
-OCStackResult CHPHandleOCFRequest(const OCEntityHandlerRequest* requestInfo,
- const char* proxyUri)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
-
- HttpRequest_t httpRequest = { .httpMajor = 1,
- .httpMinor = 1};
-
- OCEntityHandlerResponse response = { .requestHandle = requestInfo->requestHandle,
- .resourceHandle = requestInfo->resource};
- OCStackResult result = CHPGetHttpMethod(requestInfo->method, &httpRequest.method);
- if (OC_STACK_OK != result)
- {
- OIC_LOG(ERROR, TAG, "Method not found in HTTP");
- response.ehResult = OC_EH_BAD_REQ;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
-
- return OC_STACK_ERROR;
- }
-
- uint8_t vendorOptions = requestInfo->numRcvdVendorSpecificHeaderOptions;
- if (vendorOptions)
- {
- httpRequest.headerOptions = u_arraylist_create();
- for (int option = 0; option < vendorOptions; option++)
- {
- HttpHeaderOption_t *httpOption = NULL;
- result = CHPGetHttpOption(requestInfo->rcvdVendorSpecificHeaderOptions + option,
- &httpOption);
- if (OC_STACK_OK != result || NULL == httpOption )
- {
- OIC_LOG_V(ERROR, TAG, "CHPGetHttpOption failed [%d]", result);
- continue;
- }
- u_arraylist_add(httpRequest.headerOptions, (void *)httpOption);
- }
- }
-
- OICStrcpy(httpRequest.resourceUri, sizeof(httpRequest.resourceUri), proxyUri);
-
- if (requestInfo->payload && requestInfo->payload->type == PAYLOAD_TYPE_REPRESENTATION)
- {
- // Conversion from cbor to json.
- cJSON *payloadJson = CHPRepPayloadToJson((OCRepPayload *)requestInfo->payload);
- if(!payloadJson)
- {
- response.ehResult = OC_EH_BAD_REQ;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
-
- return OC_STACK_ERROR;
-
- }
- httpRequest.payload = (void *)cJSON_Print(payloadJson);
- httpRequest.payloadLength = strlen(httpRequest.payload);
- OICStrcpy(httpRequest.payloadFormat, sizeof(httpRequest.payloadFormat),
- CBOR_CONTENT_TYPE);
- cJSON_Delete(payloadJson);
- }
-
- OICStrcpy(httpRequest.acceptFormat, sizeof(httpRequest.acceptFormat),
- ACCEPT_MEDIA_TYPE);
- CHPRequest_t *chpRequest = (CHPRequest_t *)OICCalloc(1, sizeof(CHPRequest_t));
- if (!chpRequest)
- {
- OIC_LOG(ERROR, TAG, "Calloc failed");
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
-
- OICFree(httpRequest.payload);
- u_arraylist_destroy(httpRequest.headerOptions);
- return OC_STACK_NO_MEMORY;
- }
-
- chpRequest->requestHandle = requestInfo->requestHandle;
- chpRequest->method = requestInfo->method;
-
- result = CHPPostHttpRequest(&httpRequest, CHPHandleHttpResponse,
- (void *)chpRequest);
- if (OC_STACK_OK != result)
- {
- OIC_LOG_V(ERROR, TAG, "CHPPostHttpRequest failed[%d]", result);
- switch (result)
- {
- case OC_STACK_INVALID_URI:
- response.ehResult = OC_EH_BAD_REQ;
- break;
- default:
- response.ehResult = OC_EH_INTERNAL_SERVER_ERROR;
- }
-
- if (OCDoResponse(&response) != OC_STACK_OK)
- {
- OIC_LOG(ERROR, TAG, "Error sending response");
- }
-
- OICFree(httpRequest.payload);
- OICFree(chpRequest);
- u_arraylist_destroy(httpRequest.headerOptions);
- return OC_STACK_ERROR;
- }
-
- if(!httpRequest.payloadCached)
- {
- // Free only if parser has not cached it.
- OICFree(httpRequest.payload);
- }
- u_arraylist_destroy(httpRequest.headerOptions);
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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 "CoapHttpMap.h"
-#include <string.h>
-#include "oic_malloc.h"
-#include "oic_string.h"
-#include "logger.h"
-#include "ocstack.h"
-#include "pdu.h"
-#include "ocpayload.h"
-
-#define TAG "CHPMap"
-
-int CHPGetOptionID(const char *httpOptionName)
-{
- if (!httpOptionName)
- {
- OIC_LOG(ERROR, TAG, "HTTP option name is NULL");
- return 0;
- }
-
- OICStringToLower((char *)httpOptionName);
- if (0 == strcmp(httpOptionName, HTTP_OPTION_CACHE_CONTROL) ||
- 0 == strcmp(httpOptionName, HTTP_OPTION_EXPIRES))
- {
- return COAP_OPTION_MAXAGE;
- }
- else if (0 == strcmp(httpOptionName, HTTP_OPTION_IF_MATCH))
- {
- return COAP_OPTION_IF_MATCH;
- }
- else if (0 == strcmp(httpOptionName, HTTP_OPTION_IF_NONE_MATCH))
- {
- return COAP_OPTION_IF_NONE_MATCH;
- }
- else if (0 == strcmp(httpOptionName, HTTP_OPTION_ETAG))
- {
- return COAP_OPTION_ETAG;
- }
- else
- {
- OIC_LOG_V(ERROR, TAG, "No Mapping found for %s", httpOptionName);
- }
-
- return 0;
-}
-
-OCStackResult CHPGetOCCode(const HttpResponseResult_t httpCode, const OCMethod method,
- OCEntityHandlerResult *ocfCode)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- OIC_LOG_V(DEBUG, TAG, "Http Code is %d", httpCode);
-
- switch (httpCode)
- {
- case CHP_SUCCESS:
- if (OC_REST_GET == method)
- {
- *ocfCode = OC_EH_CONTENT;
- }
- else if (OC_REST_DELETE == method)
- {
- *ocfCode = OC_EH_RESOURCE_DELETED;
- }
- else
- {
- *ocfCode = OC_EH_CHANGED;
- }
- break;
- case CHP_NO_CONTENT:
- if (OC_REST_DELETE == method)
- {
- *ocfCode = OC_EH_RESOURCE_DELETED;
- }
- else
- {
- *ocfCode = OC_EH_CHANGED;
- }
- break;
- case CHP_CREATED:
- *ocfCode = OC_EH_RESOURCE_CREATED;
- break;
- case CHP_NOT_MODIFIED:
- *ocfCode = OC_EH_VALID;
- break;
- case CHP_BAD_REQ:
- case CHP_REQUEST_URI_TOO_LARGE:
- *ocfCode = OC_EH_BAD_REQ;
- break;
- case CHP_BAD_GATEWAY:
- case CHP_VERSION_NOT_SUPPORTED:
- *ocfCode = OC_EH_BAD_GATEWAY;
- break;
- case CHP_UNAUTHORIZED_REQ:
- case CHP_FORBIDDEN_REQ:
- case CHP_NOT_FOUND:
- case CHP_NOT_ACCEPTABLE:
- case CHP_REQUEST_ENTITY_TOO_LARGE:
- case CHP_UNSUPPORTED_MEDIA_TYPE:
- case CHP_INTERNAL_SERVER_ERROR:
- case CHP_NOT_IMPLEMENTED:
- case CHP_SERVICE_UNAVAILABLE:
- case CHP_GATEWAY_TIMEOUT:
- *ocfCode = httpCode;
- break;
- default:
- OIC_LOG_V(ERROR, TAG, "HTTP Response code[%d] is not matching the OCF Response code",
- httpCode);
- return OC_STACK_ERROR;
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-OCStackResult CHPGetOCOption(const HttpHeaderOption_t *httpOption, OCHeaderOption *ocfOption)
-{
- OIC_LOG(DEBUG, TAG, "CHPGetCoAPOption IN");
- if (!httpOption)
- {
- OIC_LOG(ERROR, TAG, "HTTP option is Null");
- return OC_STACK_INVALID_PARAM;
- }
-
- ocfOption->optionID = CHPGetOptionID(httpOption->optionName);
- if (!ocfOption->optionID)
- {
- OIC_LOG(INFO, TAG, "No match for HTTP option found");
- return OC_STACK_INVALID_OPTION;
- }
-
- ocfOption->protocolID = OC_COAP_ID;
- ocfOption->optionLength = httpOption->optionLength < sizeof(ocfOption->optionData) ?
- httpOption->optionLength : sizeof(ocfOption->optionData);
- memcpy(ocfOption->optionData, httpOption->optionData, ocfOption->optionLength);
-
- OIC_LOG(DEBUG, TAG, "CHPGetCoAPOption OUT");
- return OC_STACK_OK;
-}
-
-OCPayloadFormat CHPGetOCContentType(const char *httpContentType)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
-
- OICStringToLower((char *)httpContentType);
- if (strstr(httpContentType, CBOR_CONTENT_TYPE))
- {
- return OC_FORMAT_CBOR;
- }
- else if (strstr(httpContentType, JSON_CONTENT_TYPE))
- {
- return OC_FORMAT_JSON;
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_FORMAT_UNSUPPORTED;
-}
-
-OCStackResult CHPGetHttpMethod(const OCMethod method, HttpMethod_t *httpMethod)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
-
- switch (method)
- {
- case OC_REST_GET:
- *httpMethod = CHP_GET;
- break;
- case OC_REST_PUT:
- *httpMethod = CHP_PUT;
- break;
- case OC_REST_POST:
- *httpMethod = CHP_POST;
- break;
- case OC_REST_DELETE:
- *httpMethod = CHP_DELETE;
- break;
- default:
- *httpMethod = CHP_INVALID;
- OIC_LOG_V(ERROR, TAG, "Unknown method type %d", method);
- return OC_STACK_INVALID_METHOD;
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-OCStackResult CHPGetHttpOption(const OCHeaderOption* option, HttpHeaderOption_t** httpOption)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- if (!option)
- {
- OIC_LOG(ERROR, TAG, "option is NULL");
- return OC_STACK_INVALID_PARAM;
- }
-
- *httpOption = (HttpHeaderOption_t *)OICCalloc(1, sizeof(HttpHeaderOption_t));
- if (NULL == *httpOption)
- {
- OIC_LOG(ERROR, TAG, "Memory allocation failed");
- return OC_STACK_NO_MEMORY;
- }
-
- switch (option->optionID)
- {
- case COAP_OPTION_ACCEPT:
- OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
- HTTP_OPTION_ACCEPT);
- break;
- case COAP_OPTION_IF_MATCH:
- OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
- HTTP_OPTION_IF_MATCH);
- break;
- case COAP_OPTION_IF_NONE_MATCH:
- OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
- HTTP_OPTION_IF_NONE_MATCH);
- break;
- case COAP_OPTION_ETAG:
- OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
- HTTP_OPTION_ETAG);
- break;
- case COAP_OPTION_CONTENT_TYPE:
- OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
- HTTP_OPTION_CONTENT_TYPE);
- break;
- default:
- OIC_LOG_V(INFO, TAG, "No Matching found for the ID %d", option->optionID);
- }
-
- if ('\0' == (*httpOption)->optionName[0])
- {
- OIC_LOG(ERROR, TAG, "No matching is found");
- OICFree(*httpOption);
- return OC_STACK_INVALID_OPTION;
- }
-
- (*httpOption)->optionLength = option->optionLength < sizeof((*httpOption)->optionData) ?
- option->optionLength : sizeof((*httpOption)->optionData);
- memcpy((*httpOption)->optionData, option->optionData, (*httpOption)->optionLength);
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-void CHPJsonToRepPayload(cJSON* rootJSon, OCRepPayload* payload)
-{
- cJSON* dataJson = rootJSon->child;
- while (dataJson)
- {
- switch (dataJson->type)
- {
- case cJSON_String:
- OCRepPayloadSetPropString(payload, dataJson->string, dataJson->valuestring);
- break;
- case cJSON_Number:
- if (dataJson->valueint == dataJson->valuedouble)
- {
- OCRepPayloadSetPropInt(payload, dataJson->string, dataJson->valueint);
- }
- else
- {
- OCRepPayloadSetPropDouble(payload, dataJson->string, dataJson->valuedouble);
- }
- break;
- case cJSON_False:
- OCRepPayloadSetPropBool(payload, dataJson->string, false);
- break;
- case cJSON_True:
- OCRepPayloadSetPropBool(payload, dataJson->string, true);
- break;
- case cJSON_Object:
- {
- OCRepPayload* childPayload = OCRepPayloadCreate();
- CHPJsonToRepPayload(dataJson,childPayload);
- OCRepPayloadSetPropObject(payload, dataJson->string,childPayload );
- break;
- }
- case cJSON_Array:
- {
- int size = cJSON_GetArraySize(dataJson);
- size_t dimensions[MAX_REP_ARRAY_DEPTH];
- dimensions[0] = size;
- dimensions[1] = dimensions[2] = 0;
-
- int i = 0;
- int type = cJSON_IsReference;
- int numType = 0; // int:1, double:2
- const int intType = 1;
- const int doubleType = 2;
-
- int64_t intArray[size];
- double doubleArray[size];
- char* strArray[size];
- OCRepPayload* objPayloadArray[size];
-
- for (; i < size ; ++i)
- {
- cJSON* subitem = cJSON_GetArrayItem(dataJson, i);
- if (subitem == NULL)
- {
- continue;
- }
-
- if ((type != cJSON_IsReference) && (type != subitem->type))
- {
- continue;
- }
- else
- {
- type = subitem->type;
- switch (type)
- {
- case cJSON_Number:
- if (subitem->valueint == subitem->valuedouble)
- {
- numType = intType;
- intArray[i] = (int64_t) subitem->valueint;
- }
- else
- {
- numType = doubleType;
- doubleArray[i] = subitem->valuedouble;
- }
- break;
- case cJSON_String:
- strArray[i] = subitem->valuestring;
- break;
- case cJSON_Object:
- objPayloadArray[i] = OCRepPayloadCreate();
- CHPJsonToRepPayload(subitem,objPayloadArray[i]);
- break;
- default:
- OIC_LOG(ERROR, TAG, "wrong ArrayType in JsonToRepPayload()");
- break;
- }
- }
- }
-
- switch (type)
- {
- case cJSON_Number:
- if (numType == intType)
- {
- OCRepPayloadSetIntArray(payload, dataJson->string,(const int64_t*)intArray,
- dimensions);
- }
- else if (numType == doubleType)
- {
- OCRepPayloadSetDoubleArray(payload, dataJson->string,
- (const double*)doubleArray,
- dimensions);
- }
- break;
- case cJSON_String:
- OCRepPayloadSetStringArray(payload, dataJson->string,
- (const char**)strArray,
- dimensions);
- break;
- case cJSON_Object:
- OCRepPayloadSetPropObjectArray(payload, dataJson->string,
- (const OCRepPayload**)objPayloadArray,
- dimensions);
- break;
- default:
- OIC_LOG(ERROR, TAG, "wrong ArrayType in JsonToRepPayload()");
- break;
- }
- break;
- }
- }
- dataJson = dataJson->next;
- }
-}
-
-cJSON* CHPRepPayloadToJson(OCRepPayload* repData)
-{
- cJSON *outJson = cJSON_CreateObject();
- if (outJson == NULL)
- {
- return NULL;
- }
-
- OCRepPayloadValue* val = repData->values;
- while (val)
- {
- switch (val->type)
- {
- case OCREP_PROP_NULL:
- break;
- case OCREP_PROP_INT:
- OIC_LOG_V(DEBUG, TAG, "%s(int):%d", val->name, (int)val->i);
- cJSON_AddNumberToObject(outJson,val->name,(int)val->i);
- break;
- case OCREP_PROP_DOUBLE:
- OIC_LOG_V(DEBUG, TAG, "%s(double):%f", val->name, val->d);
- cJSON_AddNumberToObject(outJson,val->name,val->d);
- break;
- case OCREP_PROP_BOOL:
- OIC_LOG_V(DEBUG, TAG, "%s(bool):%s", val->name, val->b ? "true" : "false");
- cJSON_AddBoolToObject(outJson,val->name,val->b);
- break;
- case OCREP_PROP_STRING:
- OIC_LOG_V(DEBUG, TAG, "%s(string):%s", val->name, val->str);
- cJSON_AddStringToObject(outJson,val->name,val->str);
- break;
- case OCREP_PROP_OBJECT:
- {
- cJSON *objJson = CHPRepPayloadToJson(val->obj);
- if (objJson != NULL)
- {
- cJSON_AddItemToObject(outJson,val->name,objJson);
- }
- break;
- }
- case OCREP_PROP_ARRAY:
- {
- unsigned int i = 0;
- int arraySize = (int)val->arr.dimensions[0];
- switch (val->arr.type)
- {
- case OCREP_PROP_INT:
- OIC_LOG_V(DEBUG, TAG, "%s(int array)", val->name);
- if (arraySize > 0)
- {
- int castVal[val->arr.dimensions[0]];
- for (i = 0 ; i < (unsigned int)arraySize ; i++)
- {
- castVal[i] = (int)val->arr.iArray[i];
- }
- cJSON *array = cJSON_CreateIntArray(castVal,arraySize);
- if (array != NULL)
- {
- cJSON_AddItemToObject(outJson,val->name,array);
- }
- }
- break;
- case OCREP_PROP_DOUBLE:
- OIC_LOG_V(DEBUG, TAG, "%s(double array)", val->name);
- if (arraySize > 0)
- {
- cJSON *array = cJSON_CreateDoubleArray(val->arr.dArray,arraySize);
- if (array != NULL)
- {
- cJSON_AddItemToObject(outJson,val->name,array);
- }
- }
- break;
- case OCREP_PROP_STRING:
- OIC_LOG_V(DEBUG, TAG, "%s(string array)", val->name);
- if (arraySize > 0)
- {
- cJSON *array = cJSON_CreateStringArray((const char**)val->arr.strArray,
- arraySize);
- if (array != NULL)
- {
- cJSON_AddItemToObject(outJson,val->name,array);
- }
- }
- break;
- case OCREP_PROP_OBJECT:
- if (arraySize > 0)
- {
- cJSON *arrayJson = cJSON_CreateArray();
- for (i = 0 ; i < (unsigned int)arraySize ; i++)
- {
- cJSON *objJson = CHPRepPayloadToJson(val->arr.objArray[i]);
- if (objJson != NULL && arrayJson != NULL)
- {
- cJSON_AddItemToArray(arrayJson, objJson);
- }
- }
- if (arrayJson != NULL)
- {
- cJSON_AddItemToObject(outJson,val->name,arrayJson);
- }
- }
- break;
- case OCREP_PROP_BOOL:
- //TODO : Not support - cJSON_CreateBoolArray
- break;
- default:
- OIC_LOG_V(ERROR, TAG, "Unknown/unsupported array type: %s", val->name);
- break;
- }
- break;
- }
- default:
- OIC_LOG_V(ERROR, TAG, "Unknown type: %s", val->name);
- break;
- }
- val = val->next;
- }
-
- if( repData->values != NULL)
- {
- return outJson;
- }
- else
- {
- cJSON_Delete(outJson);
- return NULL;
- }
-}
+++ /dev/null
-/* ****************************************************************
- *
- * Copyright 2016 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 <stdint.h>
-
-#include "CoapHttpParser.h"
-#include "oic_malloc.h"
-#include "oic_string.h"
-#include "uarraylist.h"
-#include "logger.h"
-
-#include <string.h>
-#include <curl/curl.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#if !defined(_MSC_VER)
-#include <unistd.h>
-#endif //!defined(_MSC_VER)
-#include <sys/types.h>
-#include <fcntl.h>
-#if !defined(_WIN32)
-#include <sys/select.h>
-#endif //!defined(_WIN32)
-#include <errno.h>
-
-#define TAG "CHP_PARSER"
-
-#define DEFAULT_USER_AGENT "IoTivity"
-#define MAX_PAYLOAD_SIZE (1048576U) // 1 MB
-
-typedef struct
-{
- void* context;
- CHPResponseCallback cb;
- HttpResponse_t resp;
- /* libcurl will not cache request payload when creating a easy handle hence we need to cache */
- void* payload;
- size_t payloadLength;
- /* To track multiple read_callbacks from curl */
- size_t readOffset;
- /* To track multiple write_callbacks from curl */
- size_t writeOffset;
- /* libcurl related */
- CURL* easyHandle;
- /* libcurl does not copy header options passed to a request */
- struct curl_slist *list;
-} CHPContext_t;
-
-/* A curl mutihandle is not threadsafe so we require mutexes to add new easy
- * handles to multihandle.
- */
-static CURLM *g_multiHandle;
-static int g_activeConnections;
-
-/* Mutex code is taken from CA.
- * General utility functions shall be placed in common location
- * so that all modules can use them.
- */
-static pthread_mutex_t g_multiHandleMutex;
-
-/* Fds used to signal threads to stop */
-static int g_shutdownFds[2];
-
-static bool g_terminateParser;
-
-/*
- * Fds used to signal fdset to be refreshed.
- * When a new easy_handle is added to multi_handle,
- * existing fd_set has to be updated.
- */
-static int g_refreshFds[2];
-
-/*
- * Thread handle for curl multi_handle processing.
- */
-static pthread_t g_multiHandleThread;
-
-static void CHPParserLockMutex();
-static void CHPParserUnlockMutex();
-
-static void CHPParserResetHeaderOptions(u_arraylist_t** headerOptions)
-{
- VERIFY_NON_NULL_VOID(headerOptions, TAG, "headerOptions is NULL");
-
- HttpHeaderOption_t *option = NULL;
- while (NULL != (option = u_arraylist_remove(*headerOptions, 0)))
- {
- OICFree(option);
- }
- u_arraylist_free(headerOptions);
-}
-
-static void CHPFreeContext(CHPContext_t *ctxt)
-{
- VERIFY_NON_NULL_VOID(ctxt, TAG, "ctxt is NULL");
- if(ctxt->list)
- {
- curl_slist_free_all(ctxt->list);
- }
-
- if(ctxt->easyHandle)
- {
- curl_easy_cleanup(ctxt->easyHandle);
- }
-
- CHPParserResetHeaderOptions(&(ctxt->resp.headerOptions));
- OICFree(ctxt->resp.payload);
- OICFree(ctxt->payload);
- OICFree(ctxt);
-}
-
-static void *CHPParserExecuteMultiHandle(void* data)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- UNUSED(data);
- /*
- * These fd sets will be fetched from curl multi handle and monitored to execute
- * curl_multi_perform()
- */
- fd_set fdread;
- fd_set fdwrite;
- fd_set fdexcep;
- int maxfd;
- struct timeval timeout;
- struct timeval *tv;
- int activeCon;
- int activeEasyHandle;
- bool goForSelect;
- int retValue;
-
- /* When active connections exist, curl_multi_perform() shall be called within
- * curlMultiTimeout seconds regardless of whether select returned successfull or not.
- */
- long curlMultiTimeout;
- while (!g_terminateParser)
- {
- // Required everytime before calling curl_multi_fdset()
- FD_ZERO(&fdread);
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcep);
- maxfd = -1;
- goForSelect = true;
-
- // Get currently active transfer fds from curl
- CHPParserLockMutex();
- curl_multi_fdset(g_multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
- curl_multi_timeout(g_multiHandle, &curlMultiTimeout);
- activeCon = g_activeConnections;
- CHPParserUnlockMutex();
-
- // A 0 represent curl_multi_perform() shall be called.
- if(curlMultiTimeout < 0)
- {
- curlMultiTimeout = 1000;
- }
-
- if(maxfd == -1)
- {
- /* Nothing to monitor from libcurl.
- * This mean that no active sockets exist either because
- * there are no transfer taking place or sockets are not in a
- * state that could be monitored (connecting, retry etc.)
- */
- if(!activeCon)
- {
- // wait until something received on shutdown or refresh fd
- // with no timeout.
- curlMultiTimeout = -1;
- }
- else
- {
- // libcurl recommend doing this.
- usleep(100000);
- // dont select() and directly call curl_multi_perform()
- goForSelect = false;
- }
- }
-
- if(goForSelect)
- {
- FD_SET(g_shutdownFds[0], &fdread);
- if (maxfd < g_shutdownFds[0])
- {
- maxfd = g_shutdownFds[0];
- }
-
- FD_SET(g_refreshFds[0], &fdread);
- if (maxfd < g_refreshFds[0])
- {
- maxfd = g_refreshFds[0];
- }
-
- if(curlMultiTimeout == -1)
- {
- tv = NULL;
- }
- else
- {
- timeout.tv_sec = curlMultiTimeout / 1000;
- timeout.tv_usec = 0;
- tv = &timeout;
- }
-
- // Select here
- retValue = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, tv);
- if(retValue == -1)
- {
- OIC_LOG_V(ERROR, TAG, "Error in select. %s", strerror(errno));
- continue;
- }
-
- // Some sockets are available for operations, check if shutdown or refresh fds are
- // among them. In any case, go ahead and call curl_multi_perform()
- if(retValue)
- {
- if (FD_ISSET(g_shutdownFds[0], &fdread))
- {
- OIC_LOG(ERROR, TAG, "Shutdown requested. multi_handle returning");
- break;
- }
- else if(FD_ISSET(g_refreshFds[0], &fdread))
- {
- char buf[20] = {0};
- ssize_t len = read(g_refreshFds[0], buf, sizeof(buf));
- UNUSED(len);
- // new easy handles added, call multi_perform and refresh fds.
- OIC_LOG(ERROR, TAG, "New easy handle added");
- }
- }
- }
-
- CURLMcode ret;
- CHPParserLockMutex();
- do
- {
- ret = curl_multi_perform(g_multiHandle, &activeEasyHandle);
- struct CURLMsg *cmsg;
- int cmsgq;
- do
- {
- cmsgq = 0;
- cmsg = curl_multi_info_read(g_multiHandle, &cmsgq);
- if(cmsg && (cmsg->msg == CURLMSG_DONE))
- {
- CURL *easyHandle = cmsg->easy_handle;
- g_activeConnections--;
- curl_multi_remove_handle(g_multiHandle, easyHandle);
-
- CHPContext_t *ptr;
- char *uri = NULL;
- char *contentType = NULL;
- long responseCode;
-
- curl_easy_getinfo(easyHandle, CURLINFO_PRIVATE, &ptr);
- curl_easy_getinfo(easyHandle, CURLINFO_EFFECTIVE_URL, &uri);
- curl_easy_getinfo(easyHandle, CURLINFO_RESPONSE_CODE, &responseCode);
- curl_easy_getinfo(easyHandle, CURLINFO_CONTENT_TYPE, &contentType);
-
- ptr->resp.status = responseCode;
- OICStrcpy(ptr->resp.dataFormat, sizeof(ptr->resp.dataFormat), contentType);
- OIC_LOG_V(DEBUG, TAG, "Transfer completed %d uri: %s, %s", g_activeConnections,
- uri, contentType);
- ptr->cb(&(ptr->resp), ptr->context);
- CHPFreeContext(ptr);
- }
- } while(cmsg && !g_terminateParser);
- }while (ret == CURLM_CALL_MULTI_PERFORM && !g_terminateParser);
- CHPParserUnlockMutex();
- }
-
- if (g_terminateParser)
- {
- OIC_LOG_V(DEBUG, TAG, "Shutdown request received.");
- // g_shutdownFds[1] will be already closed.
- close(g_shutdownFds[0]);
- close(g_refreshFds[0]);
- close(g_refreshFds[1]);
- g_shutdownFds[0] = -1;
- g_shutdownFds[1] = -1;
- g_refreshFds[0] = -1;
- g_refreshFds[1] = -1;
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- return NULL;
-}
-
-OCStackResult CHPParserInitializePipe(int fds[2])
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- int ret = -1;
- fds[0] = -1;
- fds[1] = -1;
-#if defined(HAVE_PIPE2)
- ret = pipe2(fds, O_CLOEXEC);
-#else
- ret = pipe(fds);
- if (-1 != ret)
- {
- ret = fcntl(fds[0], F_GETFD);
- if (-1 != ret)
- {
- ret = fcntl(fds[0], F_SETFD, ret|FD_CLOEXEC);
- }
- if (-1 != ret)
- {
- ret = fcntl(fds[1], F_GETFD);
- }
- if (-1 != ret)
- {
- ret = fcntl(fds[1], F_SETFD, ret|FD_CLOEXEC);
- }
- if (-1 == ret)
- {
- close(fds[1]);
- close(fds[0]);
- fds[0] = -1;
- fds[1] = -1;
- }
- }
-#endif
- if (-1 == ret)
- {
- OIC_LOG_V(ERROR, TAG, "FD initialization failed: %s", strerror(errno));
- return OC_STACK_ERROR;
- }
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-static OCStackResult CHPParserInitializeMutex()
-{
- // create the mutex with the attributes set
- int ret = pthread_mutex_init(&g_multiHandleMutex, PTHREAD_MUTEX_DEFAULT);
- if (0 != ret)
- {
- OIC_LOG_V(ERROR, TAG, "%s Failed to initialize mutex !", __func__);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
-}
-
-static OCStackResult CHPParserTerminateMutex()
-{
- int ret = pthread_mutex_destroy(&g_multiHandleMutex);
- if (0 != ret)
- {
- OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__);
- return OC_STACK_ERROR;
- }
- return OC_STACK_OK;
-}
-
-static void CHPParserLockMutex()
-{
- int ret = pthread_mutex_lock(&g_multiHandleMutex);
- if(ret != 0)
- {
- OIC_LOG_V(ERROR, TAG, "Pthread Mutex lock failed: %d", ret);
- }
-}
-
-static void CHPParserUnlockMutex()
-{
- int ret = pthread_mutex_unlock(&g_multiHandleMutex);
- if(ret != 0)
- {
- OIC_LOG_V(ERROR, TAG, "Pthread Mutex unlock failed: %d", ret);
- }
-}
-
-static OCStackResult CHPParserInitializeMultiHandle()
-{
- CHPParserLockMutex();
- if(g_multiHandle)
- {
- OIC_LOG(ERROR, TAG, "Multi handle already initialized.");
- CHPParserUnlockMutex();
- return OC_STACK_OK;
- }
-
- g_multiHandle = curl_multi_init();
- if(!g_multiHandle)
- {
- OIC_LOG(ERROR, TAG, "Failed to create multi handle.");
- CHPParserUnlockMutex();
- return OC_STACK_ERROR;
- }
-
- CHPParserUnlockMutex();
- return OC_STACK_OK;
-}
-
-static OCStackResult CHPParserTerminateMultiHandle()
-{
- CHPParserLockMutex();
- if(!g_multiHandle)
- {
- OIC_LOG(ERROR, TAG, "Multi handle not initialized.");
- CHPParserUnlockMutex();
- return OC_STACK_OK;
- }
-
- curl_multi_cleanup(g_multiHandle);
- g_multiHandle = NULL;
- CHPParserUnlockMutex();
- return OC_STACK_OK;
-}
-
-OCStackResult CHPParserInitialize()
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
-
- OCStackResult ret = CHPParserInitializeMutex();
- if(ret != OC_STACK_OK)
- {
- return ret;
- }
-
- ret = CHPParserInitializeMultiHandle();
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to intialize multi handle: %d", ret);
- CHPParserTerminate();
- return ret;
- }
-
- ret = CHPParserInitializePipe(g_shutdownFds);
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to intialize shutdown fds: %d", ret);
- CHPParserTerminate();
- return ret;
- }
-
- ret = CHPParserInitializePipe(g_refreshFds);
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to intialize refresh fds: %d", ret);
- CHPParserTerminate();
- return ret;
- }
-
- // Launch multi_handle processor thread
- int result = pthread_create(&g_multiHandleThread, NULL, CHPParserExecuteMultiHandle, NULL);
- if(result != 0)
- {
- OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", result);
- CHPParserTerminate();
- return OC_STACK_ERROR;
- }
-
- g_terminateParser = false;
- CHPParserLockMutex();
- g_activeConnections = 0;
- CHPParserUnlockMutex();
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-OCStackResult CHPParserTerminate()
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- g_terminateParser = true;
- if (g_shutdownFds[1] != -1)
- {
- // Signal multi_handle thread to come out
- close(g_shutdownFds[1]);
- }
- pthread_join(g_multiHandleThread, NULL);
-
- OCStackResult ret = CHPParserTerminateMultiHandle();
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "Multi handle termination failed: %d", ret);
- }
-
- CHPParserLockMutex();
- g_activeConnections = 0;
- CHPParserUnlockMutex();
-
- ret = CHPParserTerminateMutex();
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "mutex termination failed: %d", ret);
- }
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-static size_t CHPEasyHandleWriteCb(char *buffer, size_t size, size_t num, void *context)
-{
- size_t dataToWrite = size * num;
- if(!dataToWrite)
- {
- // Empty payload received. Ignore.
- return 0;
- }
-
- if(!context || !buffer || g_terminateParser)
- {
- OIC_LOG_V(ERROR, TAG, "%s invalid arguments or terminating", __func__);
- return 0;
- }
-
- CHPContext_t* ctx = context;
- HttpResponse_t *resp = &(ctx->resp);
-
- if(ctx->writeOffset + dataToWrite > MAX_PAYLOAD_SIZE)
- {
- OIC_LOG_V(ERROR, TAG, "%s Payload limit exceeded", __func__);
- resp->payloadLength = 0;
- ctx->writeOffset = 0;
- OICFree(resp->payload);
- resp->payload = NULL;
- return 0;
- }
-
- if (!resp->payload)
- {
- resp->payload = OICMalloc(dataToWrite);
- if (!resp->payload)
- {
- OIC_LOG_V(ERROR, TAG, "%s Out of memory!", __func__);
- return 0;
- }
- }
- else
- {
- // Realloc buffer
- void *newPayload = OICRealloc(resp->payload, ctx->writeOffset + dataToWrite);
- if (!newPayload)
- {
- OIC_LOG_V(ERROR, TAG, "Realloc failed! Current: %u Extra: %u", ctx->writeOffset,
- dataToWrite);
- resp->payloadLength = 0;
- ctx->writeOffset = 0;
- OICFree(resp->payload);
- resp->payload = NULL;
- return 0;
- }
- resp->payload = newPayload;
- }
-
- memcpy(resp->payload + ctx->writeOffset, buffer, dataToWrite);
- ctx->writeOffset += dataToWrite;
- resp->payloadLength = ctx->writeOffset;
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT %u : %u", __func__, resp->payloadLength, dataToWrite);
- return dataToWrite;
-}
-
-static size_t CHPEasyHandleReadCb(char *buffer, size_t size, size_t num, void *context)
-{
- if(!context || !buffer || g_terminateParser)
- {
- OIC_LOG_V(ERROR, TAG, "%s invalid arguments or terminating", __func__);
- return CURL_READFUNC_ABORT;
- }
-
- CHPContext_t *ctx = context;
- size_t remainingLen = ctx->payloadLength - ctx->readOffset;
- size_t toTransfer = size * num > remainingLen ? remainingLen : size * num;
- memcpy(buffer, ctx->payload + ctx->readOffset, toTransfer);
- ctx->readOffset += toTransfer;
- return toTransfer;
-}
-
-static size_t CHPEasyHandleHeaderCb(char *buffer, size_t size, size_t num, void *context)
-{
- size_t dataToWrite = size * num;
- if(!buffer || !dataToWrite || !context || g_terminateParser)
- {
- OIC_LOG_V(ERROR, TAG, "%s invalid arguments or terminating", __func__);
- return 0;
- }
-
- /* curl will call this function for each line in response header including status line
- * and for each http response that it might have received from http server for ex: redirect,
- * proxy handshakes etc. All these intermediary responses are not useful for us but there
- * isn't any mechanism to track which one is going to be final.
- * Hence here we process each response and assume that the relevant one will be the final
- * response.
- */
-
- /* Start of a response is tracked by presence of status line starting with "HTTP/"
- * This also acts as a reset for everything else (payload, header options) as we are processing
- * a new response.
- */
-
- CHPContext_t *ctx = context;
- HttpResponse_t *resp = &(ctx->resp);
- if (dataToWrite > 5)
- {
- if (strncmp("HTTP/", buffer, 5) == 0)
- {
- OIC_LOG(ERROR, TAG, "New header received");
- resp->payloadLength = 0;
- ctx->writeOffset = 0;
- OICFree(resp->payload);
- resp->payload = NULL;
- CHPParserResetHeaderOptions(&(resp->headerOptions));
- // This is a status line. We are only interested in header options.
- return dataToWrite;
- }
- }
-
-
- // A header line can have CR LF NULL and spaces at end. Make endOfHeader point to last
- // character in header value
- char* endOfHeader = buffer + dataToWrite;
- while ((endOfHeader > buffer) && (*endOfHeader == '\r' || *endOfHeader == '\n'
- || *endOfHeader == ' ' || *endOfHeader == '\0'))
- {
- endOfHeader--;
- }
-
- /* curl might not send the buffer NULL terminated and copying each header is too much overhead
- * hence use mem family of function to search */
- char* ptr = (char*) memchr(buffer, ':', dataToWrite);
- // There is a colon and its not the first character
- if(ptr && ptr != buffer && ptr <= endOfHeader)
- {
- size_t headerFieldLen = ptr - buffer;
- size_t headerValueLen;
- char* headerValuePtr;
-
- /* Skip any white spaces */
- ptr++;
- while(ptr <= endOfHeader && *ptr == ' ')
- {
- ptr++;
- }
-
- if(ptr > endOfHeader)
- {
- headerValueLen = 0;
- headerValuePtr = NULL;
- }
- else
- {
- // endOfHeader is pointing to last header value character hence +1
- headerValueLen = endOfHeader - ptr + 1;
- headerValuePtr = ptr;
- }
-
- if (!(resp->headerOptions))
- {
- // First header callback, assign storage for header options
- resp->headerOptions = u_arraylist_create();
- if (!(resp->headerOptions))
- {
- OIC_LOG(ERROR, TAG, "Memory failed!");
- return 0;
- }
- }
-
- HttpHeaderOption_t *option = OICCalloc(1, sizeof(HttpHeaderOption_t));
- if (!option)
- {
- OIC_LOG(ERROR, TAG, "Memory failed!");
- return 0;
- }
-
- headerFieldLen = headerFieldLen > (sizeof(option->optionName) - 1) ?
- (sizeof(option->optionName) - 1): headerFieldLen;
- memcpy(option->optionName, buffer, headerFieldLen);
- option->optionName[headerFieldLen] = '\0';
-
- if(headerValueLen)
- {
- headerValueLen = headerValueLen > (sizeof(option->optionData) - 1) ?
- (sizeof(option->optionData) - 1): headerValueLen;
- memcpy(option->optionData, headerValuePtr, headerValueLen);
- option->optionData[headerValueLen] = '\0';
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s:: %s: %s", __func__, option->optionName, option->optionData);
- // Add to header option list
- if(!u_arraylist_add(resp->headerOptions, option))
- {
- OIC_LOG(ERROR, TAG, "u_arraylist_add failed!");
- OICFree(option);
- return 0;
- }
- }
-
- // ignore else as this might be CRLF header lines.
- return dataToWrite;
-}
-
-static OCStackResult CHPInitializeEasyHandle(CURL** easyHandle, HttpRequest_t *req,
- CHPContext_t* handleContext)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- VERIFY_NON_NULL_RET(req, TAG, "req", OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL_RET(easyHandle, TAG, "easyHandle", OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL_RET(handleContext, TAG, "handleContext", OC_STACK_INVALID_PARAM);
-
- CURL *e = curl_easy_init();
- if(!e)
- {
- OIC_LOG(ERROR, TAG, "easy init failed!");
- return OC_STACK_ERROR;
- }
-
- /* Set http resource uri */
- curl_easy_setopt(e, CURLOPT_URL, req->resourceUri);
- /* Default protocol when scheme is not available in uri */
- // curl version 7.22 don't support this option.
- //curl_easy_setopt(e, CURLOPT_DEFAULT_PROTOCOL, "http");
- /* Set handle context */
- curl_easy_setopt(e, CURLOPT_PRIVATE, handleContext);
- curl_easy_setopt(e, CURLOPT_WRITEFUNCTION, CHPEasyHandleWriteCb);
- curl_easy_setopt(e, CURLOPT_WRITEDATA, handleContext);
- curl_easy_setopt(e, CURLOPT_READFUNCTION, CHPEasyHandleReadCb);
- curl_easy_setopt(e, CURLOPT_READDATA, handleContext);
- curl_easy_setopt(e, CURLOPT_HEADERFUNCTION, CHPEasyHandleHeaderCb);
- curl_easy_setopt(e, CURLOPT_HEADERDATA, handleContext);
-
- /* Allow access to only http server's */
- curl_easy_setopt(e, CURLOPT_PROTOCOLS,
- CURLPROTO_HTTP | CURLPROTO_HTTPS);
- /* complete connection within 15 seconds */
- curl_easy_setopt(e, CURLOPT_CONNECTTIMEOUT, 15L);
- /* Abort transaction if getting less than 1kbps for 60 seconds */
- curl_easy_setopt(e, CURLOPT_LOW_SPEED_LIMIT, 1024L);
- curl_easy_setopt(e, CURLOPT_LOW_SPEED_TIME, 60L);
- curl_easy_setopt(e, CURLOPT_USERAGENT, DEFAULT_USER_AGENT);
- /* Close connection once done with transaction */
- curl_easy_setopt(e, CURLOPT_FORBID_REUSE, 1L);
- /* Allow redirect */
- curl_easy_setopt(e, CURLOPT_FOLLOWLOCATION, 1L);
- /* Only redirect to http servers */
- curl_easy_setopt(e, CURLOPT_REDIR_PROTOCOLS,
- CURLPROTO_HTTP | CURLPROTO_HTTPS);
- /* Limit maximum redirects */
- curl_easy_setopt(e, CURLOPT_MAXREDIRS, 10L);
-
- handleContext->writeOffset = 0;
- handleContext->readOffset = 0;
- switch(req->method)
- {
- case CHP_GET:
- OIC_LOG(DEBUG, TAG, "Sending GET request");
- curl_easy_setopt(e, CURLOPT_HTTPGET, 1);
- break;
- case CHP_POST:
- OIC_LOG(DEBUG, TAG, "Sending POST request");
- curl_easy_setopt(e, CURLOPT_POST, 1);
- curl_easy_setopt(e, CURLOPT_POSTFIELDS, NULL);
- curl_easy_setopt(e, CURLOPT_POSTFIELDSIZE, req->payloadLength);
- handleContext->payloadLength = req->payloadLength;
- handleContext->payload = req->payload;
- req->payloadCached = true;
- break;
- case CHP_PUT:
- OIC_LOG(DEBUG, TAG, "Sending PUT request");
- curl_easy_setopt(e, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(e, CURLOPT_INFILESIZE, req->payloadLength);
- handleContext->payloadLength = req->payloadLength;
- handleContext->payload = req->payload;
- req->payloadCached = true;
- break;;
- case CHP_DELETE:
- OIC_LOG(DEBUG, TAG, "Sending DELETE request");
- /* libcurl don't have direct option for sending DELETE */
- curl_easy_setopt(e, CURLOPT_CUSTOMREQUEST, "DELETE");
- break;
- default:
- return OC_STACK_INVALID_METHOD;
- }
-
- // Add header options from request
- struct curl_slist *list = NULL;
- char buffer[CHP_MAX_HF_NAME_LENGTH + CHP_MAX_HF_DATA_LENGTH + 2]; // extra 2 bytes for ": "
-
- if (req->headerOptions)
- {
- HttpHeaderOption_t *option = NULL;
- int headerCount = u_arraylist_length(req->headerOptions);
- for(int i = 0; i < headerCount; i++)
- {
- option = u_arraylist_get(req->headerOptions, i);
- if(option)
- {
- OIC_LOG_V(DEBUG, TAG, "Adding header option: %s", buffer);
- snprintf(buffer, sizeof(buffer), "%s: %s", option->optionName, option->optionData);
- list = curl_slist_append(list, buffer);
- }
- }
- }
-
- /* Add content-type and accept header */
- snprintf(buffer, sizeof(buffer), "Accept: %s", req->acceptFormat);
- list = curl_slist_append(list, buffer);
- snprintf(buffer, sizeof(buffer), "Content-Type: %s", req->payloadFormat);
- curl_easy_setopt(e, CURLOPT_HTTPHEADER, list);
-
- *easyHandle = e;
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
-OCStackResult CHPPostHttpRequest(HttpRequest_t *req, CHPResponseCallback httpcb,
- void *context)
-{
- OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
- VERIFY_NON_NULL_RET(req, TAG, "req", OC_STACK_INVALID_PARAM);
- VERIFY_NON_NULL_RET(httpcb, TAG, "httpcb", OC_STACK_INVALID_PARAM);
-
- CHPContext_t *ctxt = OICCalloc(1, sizeof(CHPContext_t));
- if (!ctxt)
- {
- OIC_LOG(ERROR, TAG, "Memory failed!");
- return OC_STACK_NO_MEMORY;
- }
-
- ctxt->cb = httpcb;
- ctxt->context = context;
- OCStackResult ret = CHPInitializeEasyHandle(&ctxt->easyHandle, req, ctxt);
- if(ret != OC_STACK_OK)
- {
- OIC_LOG_V(ERROR, TAG, "Failed to initialize easy handle [%d]", ret);
- OICFree(ctxt);
- return ret;
- }
-
- // Add easy_handle to multi_handle
- CHPParserLockMutex();
- curl_multi_add_handle(g_multiHandle, ctxt->easyHandle);
- g_activeConnections++;
- CHPParserUnlockMutex();
- // Notify refreshfd
- ssize_t len = 0;
- do
- {
- len = write(g_refreshFds[1], "w", 1);
- } while ((len == -1) && (errno == EINTR));
-
- if ((len == -1) && (errno != EINTR) && (errno != EPIPE))
- {
- OIC_LOG_V(DEBUG, TAG, "refresh failed: %s", strerror(errno));
- }
-
- OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
- return OC_STACK_OK;
-}
-
%{!?LOGGING: %define LOGGING True}
%{!?ROUTING: %define ROUTING EP}
%{!?WITH_TCP: %define WITH_TCP true}
-%{!?WITH_PROXY: %define WITH_PROXY False}
%{!?ES_TARGET_ENROLLEE: %define ES_TARGET_ENROLLEE tizen}
%{!?VERBOSE: %define VERBOSE 1}
VERBOSE=%{VERBOSE} \
TARGET_OS=tizen TARGET_ARCH=%{RPM_ARCH} TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
RELEASE=%{RELEASE} SECURED=%{SECURED} WITH_TCP=%{WITH_TCP} WITH_CLOUD=%{WITH_CLOUD} LOGGING=%{LOGGING} ROUTING=%{ROUTING} \
- ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} LIB_INSTALL_DIR=%{_libdir} WITH_PROXY=%{WITH_PROXY}
+ ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} LIB_INSTALL_DIR=%{_libdir}
scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
TARGET_OS=tizen TARGET_ARCH=%{RPM_ARCH} TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
RELEASE=%{RELEASE} SECURED=%{SECURED} WITH_TCP=%{WITH_TCP} WITH_CLOUD=%{WITH_CLOUD} LOGGING=%{LOGGING} ROUTING=%{ROUTING} \
- ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} LIB_INSTALL_DIR=%{_libdir} WITH_PROXY=%{WITH_PROXY}
+ ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} LIB_INSTALL_DIR=%{_libdir}