Manual NanoService C Client 1.11-RC2 import

Dependents:   Trenton_Doormat_FRDM-KL25Z_ETH

Files at this revision

API Documentation at this revision

Comitter:
zdshelby
Date:
Tue Feb 18 01:10:07 2014 +0000
Parent:
0:aafd54b05111
Commit message:
- Added libnsdl import

Changed in this revision

sn_grs.c Show annotated file Show diff for this revision Revisions of this file
sn_grs.h Show annotated file Show diff for this revision Revisions of this file
sn_nsdl.c Show annotated file Show diff for this revision Revisions of this file
sn_nsdl_lib.h Show annotated file Show diff for this revision Revisions of this file
diff -r aafd54b05111 -r 14a9b0f4b9d6 sn_grs.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sn_grs.c	Tue Feb 18 01:10:07 2014 +0000
@@ -0,0 +1,1468 @@
+/**
+ *
+ * \file sn_grs.c
+ * \brief General resource server for Sensinode NanoService platforms
+ *
+ *
+ *
+ */
+#include "nsdl_types.h"
+#include "sn_linked_list.h"
+#include "sn_nsdl.h"
+
+#if(SN_NSDL_HAVE_HTTPS_CAPABILITY&&SN_NSDL_HAVE_HTTP_CAPABILITY)
+#include "sn_http.h"
+#endif
+
+#if(SN_NSDL_HAVE_COAP_CAPABILITY)
+#include "sn_coap_header.h"
+#include "sn_coap_protocol.h"
+#endif
+
+#include "sn_nsdl_lib.h"
+#include "sn_grs.h"
+
+#include <stdlib.h>
+#include <string.h>			// for memcomp
+
+/* Defines */
+#define WELLKNOWN_PATH_LEN				16
+#define WELLKNOWN_PATH					(".well-known/core")
+
+/* Local static function prototypes */
+static sn_nsdl_resource_info_s *	sn_grs_search_resource				(uint16_t pathlen, uint8_t *path, uint8_t search_method);
+static int8_t 						sn_grs_resource_info_free			(sn_nsdl_resource_info_s *resource_ptr);
+static uint8_t *					sn_grs_convert_uri					(uint16_t *uri_len, uint8_t *uri_ptr);
+static int8_t 						sn_grs_add_resource_to_list			(sn_linked_list_t *list_ptr, sn_nsdl_resource_info_s *resource_ptr);
+#ifdef CC8051_PLAT
+void 								copy_code_nsdl						(uint8_t * ptr, prog_uint8_t * code_ptr, uint16_t len);
+#endif
+static uint8_t 						sn_grs_compare_code					(uint8_t * ptr, prog_uint8_t * code_ptr, uint8_t len);
+
+/* Extern function prototypes */
+extern int8_t 						sn_nsdl_build_registration_body		(sn_coap_hdr_s *message_ptr, uint8_t updating_registeration);
+
+
+/* Local global variables */
+ static sn_linked_list_t *resource_root_list = NULL;
+
+
+/* Local global function pointers */
+static void 	*(*sn_grs_alloc)(uint16_t);
+static void 	(*sn_grs_free)(void*);
+static uint8_t (*sn_grs_tx_callback)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *);
+static int8_t (*sn_grs_rx_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *);
+
+/**
+ * \fn int8_t sn_grs_destroy(void)
+ * \brief This function may be used to flush GRS related stuff when a program exits.
+ * @return always 0.
+ */
+ extern int8_t sn_grs_destroy(void)
+{
+	if(resource_root_list)
+	{
+		uint16_t size =  sn_linked_list_count_nodes(resource_root_list);
+		uint16_t i = 0;
+		sn_nsdl_resource_info_s*tmp;
+
+		for(i=0;i<size;i++)
+		{
+			tmp = sn_linked_list_get_first_node(resource_root_list);
+
+			if(tmp)
+			{
+				if(tmp->resource_parameters_ptr->resource_type_ptr)
+				{
+					sn_grs_free(tmp->resource_parameters_ptr->resource_type_ptr);
+					tmp->resource_parameters_ptr->resource_type_ptr = 0;
+				}
+
+				if(tmp->resource_parameters_ptr->interface_description_ptr)
+				{
+					sn_grs_free(tmp->resource_parameters_ptr->interface_description_ptr);
+					tmp->resource_parameters_ptr->interface_description_ptr = 0;
+				}
+
+				if(tmp->resource_parameters_ptr)
+				{
+					sn_grs_free(tmp->resource_parameters_ptr);
+					tmp->resource_parameters_ptr = 0;
+				}
+				if(tmp->path)
+				{
+					sn_grs_free(tmp->path);
+					tmp->path = 0;
+				}
+				if(tmp->resource)
+				{
+					sn_grs_free(tmp->resource);
+					tmp->resource = 0;
+				}
+				sn_linked_list_remove_current_node(resource_root_list);
+				sn_grs_free(tmp);
+				tmp = 0;
+			}
+		}
+
+		if(!sn_linked_list_count_nodes(resource_root_list))
+		{
+			sn_linked_list_free(resource_root_list);
+		}
+
+	}
+	return 0;
+}
+
+
+/**
+ * \fn int8_t sn_grs_init	(uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
+ *		sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *), sn_nsdl_mem_s *sn_memory)
+ *
+ * \brief GRS library initialize function.
+ *
+ * This function initializes GRS and CoAP libraries.
+ *
+ * \param 	sn_grs_tx_callback 		A function pointer to a transmit callback function.
+ * \param  *sn_grs_rx_callback_ptr A function pointer to a receiving callback function. If received packet is not for GRS, it will be passed to
+ *									upper level (NSDL) to be proceed.
+ * \param 	sn_memory 				A pointer to a structure containing the platform specific functions for memory allocation and free.
+ *
+ * \return success = 0, failure = -1
+ *
+*/
+
+extern int8_t sn_grs_init	(uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
+		sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *), sn_nsdl_mem_s *sn_memory)
+{
+	/* If application tries to init GRS more than once.. */
+	if(!resource_root_list)
+	{
+		/* if sn_memory struct is NULL or , return failure */
+		if(!sn_memory)
+			return SN_NSDL_FAILURE;
+
+		if (sn_memory->sn_nsdl_alloc == NULL ||
+			sn_memory->sn_nsdl_free == NULL ||
+			sn_grs_tx_callback_ptr == NULL)
+		{
+			/* There was a null pointer as a parameter */
+			return SN_NSDL_FAILURE;
+		}
+
+		/* Alloc and free - function pointers  */
+		sn_grs_alloc = sn_memory->sn_nsdl_alloc;
+		sn_grs_free = sn_memory->sn_nsdl_free;
+
+		/* TX callback function pointer */
+		sn_grs_tx_callback = sn_grs_tx_callback_ptr;
+		sn_grs_rx_callback = sn_grs_rx_callback_ptr;
+
+		/* Initialize linked list */
+		sn_linked_list_init(sn_memory->sn_nsdl_alloc, sn_memory->sn_nsdl_free);
+
+		/* Initialize HTTP protocol library, if implemented to library*/
+#if	(SN_NSDL_HAVE_HTTP_CAPABILITY || SN_NSDL_HAVE_HTTPS_CAPABILITY)
+		sn_http_init(sn_memory->sn_nsdl_alloc, sn_memory->sn_grs_free);
+#endif
+
+		/* Initialize CoAP protocol library, if implemented to library */
+
+		/* Initialize list for resources */
+		resource_root_list = sn_linked_list_create();
+		if (!resource_root_list)
+		{
+			return SN_NSDL_FAILURE;
+		}
+
+#if	SN_NSDL_HAVE_COAP_CAPABILITY
+		sn_coap_builder_and_parser_init(sn_memory->sn_nsdl_alloc, sn_memory->sn_nsdl_free);
+
+		if(sn_coap_protocol_init(sn_memory->sn_nsdl_alloc, sn_memory->sn_nsdl_free, sn_grs_tx_callback))
+		{
+			sn_linked_list_free(resource_root_list);
+			return SN_NSDL_FAILURE;
+		}
+#endif
+
+		return SN_NSDL_SUCCESS;
+	}
+
+	return SN_NSDL_FAILURE;
+}
+
+/**
+ * \fn extern int8_t sn_grs_exec(uint32_t time)
+ *
+ * \brief CoAP retransmission function.
+ *
+ *	Used to give execution time for the GRS (CoAP) library for retransmissions. The GRS library
+ *	will call the exec functions of all enabled protocol modules.
+ *
+ *	\param 	time	Time in seconds.
+ *
+ *	\return  0 = success, -1 = failure
+ *
+*/
+
+extern int8_t sn_grs_exec(uint32_t time)
+{
+#if(SN_NSDL_HAVE_COAP_CAPABILITY)
+	/* Call CoAP execution function */
+	return sn_coap_protocol_exec(time);
+#endif
+	return SN_NSDL_SUCCESS;
+}
+
+/**
+ * \fn extern sn_grs_resource_list_s *sn_grs_list_resource(uint16_t pathlen, uint8_t *path)
+ *
+ * \brief Resource list function
+ *
+ * \param pathlen	Contains the length of the target path (excluding possible trailing '\0').
+ *					The length value is not examined if the path itself is a NULL pointer.
+ *
+ * \param *path		A pointer to an array containing the path or a NULL pointer.
+ *
+ * \return !NULL 	A pointer to a sn_grs_resource_list structure containing the resource listing.\n
+ *          NULL 	failure with an unspecified error
+ */
+
+extern sn_grs_resource_list_s *sn_grs_list_resource(uint16_t pathlen, uint8_t *path)
+{
+	/* Local variables */
+	uint8_t i = 0;
+	sn_grs_resource_list_s 	*grs_resource_list_ptr 	= NULL;
+	sn_nsdl_resource_info_s 	*grs_resource_ptr 		= NULL;
+
+	/* Allocate memory for the resource list to be filled */
+	grs_resource_list_ptr = (sn_grs_resource_list_s *)sn_grs_alloc(sizeof(sn_grs_resource_list_s));
+	if(!grs_resource_list_ptr)
+	{
+		return (sn_grs_resource_list_s *)NULL;
+	}
+
+	/* Count resources to the resource list struct */
+	grs_resource_list_ptr->res_count = sn_linked_list_count_nodes(resource_root_list);
+
+	/**************************************/
+	/* Fill resource structs to the table */
+	/**************************************/
+
+	/* If resources in list */
+	if(grs_resource_list_ptr->res_count)
+	{
+		/* Allocate memory for resources */
+		grs_resource_list_ptr->res = sn_grs_alloc(grs_resource_list_ptr->res_count*(sizeof(sn_grs_resource_s)));
+		if(!grs_resource_list_ptr->res)
+		{
+			sn_grs_free(grs_resource_list_ptr);
+			return (sn_grs_resource_list_s *)NULL;
+		}
+
+		/* Get first resource */
+		grs_resource_ptr = sn_linked_list_get_first_node(resource_root_list);
+
+		for(i = 0; i < grs_resource_list_ptr->res_count; i++)
+		{
+			/* Copy pathlen to resource list */
+			grs_resource_list_ptr->res[i].pathlen = grs_resource_ptr->pathlen;
+
+			/* Allocate memory for path string */
+			grs_resource_list_ptr->res[i].path = sn_grs_alloc(grs_resource_list_ptr->res[i].pathlen);
+			if(!grs_resource_list_ptr->res[i].path)
+				//todo: free struct
+				return (sn_grs_resource_list_s *)NULL;
+
+			/* Move pathstring to resource list */
+			memmove(grs_resource_list_ptr->res[i].path,grs_resource_ptr->path, grs_resource_ptr->pathlen);
+
+			/* move to next node */
+			grs_resource_ptr = sn_linked_list_get_next_node(resource_root_list);
+		}
+	}
+	return grs_resource_list_ptr;
+}
+
+
+extern sn_nsdl_resource_info_s *sn_grs_get_first_resource(void)
+{
+
+	return sn_linked_list_get_first_node(resource_root_list);
+
+}
+
+
+extern sn_nsdl_resource_info_s *sn_grs_get_next_resource(void)
+{
+
+	return sn_linked_list_get_next_node(resource_root_list);
+
+}
+
+/**
+ * \fn extern sn_grs_resource_info_s *sn_grs_get_resource(uint16_t pathlen, uint8_t *path)
+ *
+ * \brief Resource get function.
+ *
+ *	Used to get a resource.
+ *
+ *	\param pathlen	Contains the length of the path that is to be returned (excluding possible trailing '\\0').
+ *
+ *	\param *path	A pointer to an array containing the path.
+ *
+ *	\return 		!NULL success, pointer to a sn_grs_resource_info_t that contains the resource information\n
+ *					NULL failure
+*/
+
+extern sn_nsdl_resource_info_s *sn_grs_get_resource(uint16_t pathlen, uint8_t *path)
+{
+
+	/* Search for resource */
+	return sn_grs_search_resource(pathlen, path, SN_GRS_SEARCH_METHOD);
+
+}
+
+
+
+/**
+ * \fn 	extern int8_t sn_grs_delete_resource(uint16_t pathlen, uint8_t *path_ptr)
+ *
+ * \brief Resource delete function.
+ *
+ *	Used to delete a resource. If resource has a subresources, these all must also be removed.
+ *
+ *	\param 	pathlen		Contains the length of the path that is to be deleted (excluding possible trailing �\0�).
+ *
+ *	\param 	*path_ptr	A pointer to an array containing the path.
+ *
+ *	\return 		0 = success, -1 = failure (No such resource)
+*/
+
+
+extern int8_t sn_grs_delete_resource(uint16_t pathlen, uint8_t *path_ptr)
+{
+	/* Local variables */
+	sn_nsdl_resource_info_s 	*resource_temp 	= NULL;
+
+	/* Search if resource found */
+	resource_temp = sn_grs_search_resource(pathlen, path_ptr, SN_GRS_SEARCH_METHOD);
+
+	/* If not found */
+	if(resource_temp == (sn_nsdl_resource_info_s *)NULL)
+		return SN_NSDL_FAILURE;
+
+	/* If found, delete it and delete also subresources, if there is any */
+	while (resource_temp != (sn_nsdl_resource_info_s *)NULL)
+	{
+		/* Remove from list */
+		resource_temp = (sn_nsdl_resource_info_s *)sn_linked_list_remove_current_node(resource_root_list);
+
+		/* Free */
+		sn_grs_resource_info_free(resource_temp);
+
+		/* Search for subresources */
+		resource_temp = sn_grs_search_resource(pathlen, path_ptr, SN_GRS_DELETE_METHOD);
+	}
+	return SN_NSDL_SUCCESS;
+}
+
+
+
+/**
+ * \fn 	extern int8_t sn_grs_update_resource(sn_grs_resource_info_s *res)
+ *
+ * \brief Resource updating function.
+ *
+ *	Used to update the direct value of a static resource, the callback function pointer of a dynamic resource
+ *	and access rights of the recource.
+ *
+ *	\param 	*res	Pointer to a structure of type sn_grs_resource_info_t that contains the information
+ *					about the resource. Only the pathlen and path elements are evaluated along with
+ *					either resourcelen and resource or the function pointer.
+ *
+ *	\return			0 = success, -1 = failure
+*/
+
+extern int8_t sn_grs_update_resource(sn_nsdl_resource_info_s *res)
+{
+	/* Local variables */
+	sn_nsdl_resource_info_s 	*resource_temp 	= NULL;
+
+	/* Search resource */
+	resource_temp = sn_grs_search_resource(res->pathlen, res->path, SN_GRS_SEARCH_METHOD);
+	if(!resource_temp)
+		return SN_NSDL_FAILURE;
+
+	/* If there is payload on resource, free it */
+	if(resource_temp->resource != NULL)
+	{
+		sn_grs_free(resource_temp->resource);
+		resource_temp->resource = 0;
+	}
+	/* Update resource len */
+	resource_temp->resourcelen = res->resourcelen;
+
+	/* If resource len >0, allocate memory and copy payload */
+	if(res->resourcelen)
+	{
+		resource_temp->resource = sn_grs_alloc(res->resourcelen);
+		if(resource_temp->resource == NULL)
+		{
+
+			resource_temp->resourcelen = 0;
+			return SN_NSDL_FAILURE;
+
+		}
+
+		memcpy(resource_temp->resource, res->resource, resource_temp->resourcelen);
+	}
+
+	/* Update access rights and callback address */
+	resource_temp->access = res->access;
+	resource_temp->sn_grs_dyn_res_callback = res->sn_grs_dyn_res_callback;
+
+	/* TODO: resource_parameters_ptr not copied */
+
+	return SN_NSDL_SUCCESS;
+}
+
+
+
+/**
+ * \fn 	extern int8_t sn_grs_create_resource(sn_grs_resource_info_t *res)
+ *
+ * \brief Resource creating function.
+ *
+ *	Used to create a static or dynamic HTTP(S) or CoAP resource.
+ *
+ *	\param 	*res	Pointer to a structure of type sn_grs_resource_info_t that contains the information
+ *					about the resource.
+ *
+ *	\return 		 0 success
+ *					-1 Failure
+ *					-2 Resource already exists
+ *					-3 Invalid path
+ *					-4 List adding failure
+*/
+
+extern int8_t sn_grs_create_resource(sn_nsdl_resource_info_s *res)
+{
+
+	if(!res)
+		return SN_NSDL_FAILURE;
+
+	/* Check path validity */
+	if(!res->pathlen || !res->path)
+		return SN_GRS_INVALID_PATH;
+
+	/* Check if resource already exists */
+	if(sn_grs_search_resource(res->pathlen, res->path, SN_GRS_SEARCH_METHOD) != (sn_nsdl_resource_info_s *)NULL)
+	{
+		return SN_GRS_RESOURCE_ALREADY_EXISTS;
+	}
+
+	if(res->resource_parameters_ptr)
+	{
+		res->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_NOT_REGISTERED;
+	}
+
+	/* Create resource */
+	if(sn_grs_add_resource_to_list(resource_root_list, res) == SN_NSDL_SUCCESS)
+	{
+		return SN_NSDL_SUCCESS;
+	}
+	return SN_GRS_LIST_ADDING_FAILURE;
+}
+
+
+
+/**
+ * \fn 	extern int8_t sn_grs_process_http(uint8_t *packet, uint16_t *packet_len, sn_grs_addr_t *src)
+ *
+ * \brief To push HTTP packet to GRS library
+ *
+ *	Used to push an HTTP or unencrypted HTTPS packet to GRS library for processing.
+ *
+ *	\param 	*packet		Pointer to a uint8_t array containing the packet (including the HTTP headers).
+ *						After SN_NSDL_SUCCESSful execution this array may contain the response packet.
+ *
+ *	\param 	*packet_len	Pointer to length of the packet. After successful execution this array may
+ *						contain the length of the response packet.
+ *
+ *	\param 	*src		Pointer to packet source address information. After SN_NSDL_SUCCESSful execution
+ *						this array may contain the destination address of the response packet.
+ *
+ *	\return				1 success, response packet to be sent.
+ *						0 success, no response to be sent
+ *						-1 failure
+*/
+
+extern int8_t sn_grs_process_http(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src)
+{
+#if(SN_NSDL_HAVE_HTTP_CAPABILITY && SN_NSDL_HAVE_HTTPS_CAPABILITY)
+	/* Local variables */
+	sn_http_hdr_t 	*http_packet_ptr 	= NULL;
+	int8_t 			status 				= 0;
+
+	/******************************************/
+	/* Parse HTTP packet and check if succeed */
+	/******************************************/
+	http_packet_ptr = sn_http_parse(*packet_len, packet);
+	if(!http_packet_ptr)
+		return SN_NSDL_FAILURE;
+
+	if(http_packet_ptr->status != SN_HTTP_STATUS_OK)
+		return SN_NSDL_FAILURE;			// Todo: other SN_NSDL_FAILUREs from HTTP
+
+	switch (http_packet_ptr->method)
+	{
+	case (SN_GRS_POST):
+		return status;
+
+	case (SN_GRS_PUT):
+		return status;
+
+	case (SN_GRS_GET):
+		return status;
+
+	case (SN_GRS_DELETE):
+		return status;
+
+	default:
+		return SN_NSDL_FAILURE;
+	}
+#endif
+	return SN_NSDL_FAILURE;
+}
+
+
+
+/**
+ * \fn 	extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src)
+ *
+ * \brief To push CoAP packet to GRS library
+ *
+ *	Used to push an CoAP packet to GRS library for processing.
+ *
+ *	\param 	*packet		Pointer to a uint8_t array containing the packet (including the CoAP headers).
+ *						After successful execution this array may contain the response packet.
+ *
+ *	\param 	*packet_len	Pointer to length of the packet. After successful execution this array may contain the length
+ *						of the response packet.
+ *
+ *	\param 	*src		Pointer to packet source address information. After successful execution this array may contain
+ *						the destination address of the response packet.
+ *
+ *	\return				0 = success, -1 = failure
+*/
+
+extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src_addr_ptr)
+{
+	sn_coap_hdr_s 			*coap_packet_ptr 	= NULL;
+	sn_nsdl_resource_info_s	*resource_temp_ptr	= NULL;
+	sn_coap_msg_code_e 		status 				= COAP_MSG_CODE_EMPTY;
+	sn_coap_hdr_s 			*response_message_hdr_ptr = NULL;
+
+
+	/* Parse CoAP packet */
+	coap_packet_ptr = sn_coap_protocol_parse(src_addr_ptr, packet_len, packet);
+
+	/* Check if parsing was successfull */
+	if(coap_packet_ptr == (sn_coap_hdr_s *)NULL)
+		return SN_NSDL_FAILURE;
+
+	/* Check, if coap itself sends response, or block receiving is ongoing... */
+	if(coap_packet_ptr->coap_status != COAP_STATUS_OK && coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED)
+	{
+		sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+		return SN_NSDL_SUCCESS;
+	}
+
+	/* If proxy options added, return not supported */
+	if (coap_packet_ptr->options_list_ptr)
+	{
+		if(coap_packet_ptr->options_list_ptr->proxy_uri_len)
+		{
+			status = COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED;
+		}
+
+	}
+
+	/* * * * * * * * * * * * * * * * * * * * * * * * * * */
+	/* If message is response message, call RX callback  */
+	/* * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+	if((coap_packet_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE && status == COAP_MSG_CODE_EMPTY) ||
+			(coap_packet_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT && status == COAP_MSG_CODE_EMPTY))
+	{
+		int8_t retval = sn_grs_rx_callback(coap_packet_ptr, src_addr_ptr);
+		if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+		{
+			sn_grs_free(coap_packet_ptr->payload_ptr);
+			coap_packet_ptr->payload_ptr = 0;
+		}
+		sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+		return retval;
+	}
+
+	/* * * * * * * * * * * * * * * */
+	/* Other messages are for GRS  */
+	/* * * * * * * * * * * * * * * */
+
+	else if(coap_packet_ptr->msg_code <= COAP_MSG_CODE_REQUEST_DELETE && status == COAP_MSG_CODE_EMPTY)
+	{
+		/* Check if .well-known/core */
+		if(coap_packet_ptr->uri_path_len == WELLKNOWN_PATH_LEN && sn_grs_compare_code(coap_packet_ptr->uri_path_ptr, (const uint8_t*)WELLKNOWN_PATH, WELLKNOWN_PATH_LEN) == 0)
+		{
+
+			sn_coap_content_format_e wellknown_content_format = COAP_CT_LINK_FORMAT;
+
+			/* Allocate resopnse message  */
+			response_message_hdr_ptr = sn_grs_alloc(sizeof(sn_coap_hdr_s));
+			if(!response_message_hdr_ptr)
+			{
+				if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+				{
+					sn_grs_free(coap_packet_ptr->payload_ptr);
+					coap_packet_ptr->payload_ptr = 0;
+				}
+				sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+				return SN_NSDL_FAILURE;
+			}
+			memset(response_message_hdr_ptr, 0, sizeof(sn_coap_hdr_s));
+
+			/* Build response */
+			response_message_hdr_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
+			response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
+			response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id;
+			response_message_hdr_ptr->content_type_len = 1;
+			response_message_hdr_ptr->content_type_ptr = malloc(1);
+			if(!response_message_hdr_ptr)
+			{
+				if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+				{
+					sn_grs_free(coap_packet_ptr->payload_ptr);
+					coap_packet_ptr->payload_ptr = 0;
+				}
+				sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+				sn_grs_free(response_message_hdr_ptr);
+				return SN_NSDL_FAILURE;
+			}
+
+			*response_message_hdr_ptr->content_type_ptr = wellknown_content_format;
+
+
+			sn_nsdl_build_registration_body(response_message_hdr_ptr, 0);
+
+			/* Send and free */
+			sn_grs_send_coap_message(src_addr_ptr, response_message_hdr_ptr);
+
+			if(response_message_hdr_ptr->payload_ptr)
+			{
+				sn_grs_free(response_message_hdr_ptr->payload_ptr);
+				response_message_hdr_ptr->payload_ptr = 0;
+			}
+			sn_coap_parser_release_allocated_coap_msg_mem(response_message_hdr_ptr);
+
+			/* Free parsed CoAP message */
+			if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+			{
+				sn_grs_free(coap_packet_ptr->payload_ptr);
+				coap_packet_ptr->payload_ptr = 0;
+			}
+			sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+
+			return SN_NSDL_SUCCESS;
+		}
+
+		/* Get resource */
+		resource_temp_ptr = sn_grs_get_resource(coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr);
+
+		/* * * * * * * * * * * */
+		/* If resource exists  */
+		/* * * * * * * * * * * */
+		if(resource_temp_ptr)
+		{
+			/* If dynamic resource, go to callback */
+			if(resource_temp_ptr->mode == SN_GRS_DYNAMIC)
+			{
+				/* Check accesses */
+				if(((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) && !(resource_temp_ptr->access & SN_GRS_GET_ALLOWED)) 			||
+						((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) && !(resource_temp_ptr->access & SN_GRS_POST_ALLOWED)) 	||
+						((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) && !(resource_temp_ptr->access & SN_GRS_PUT_ALLOWED))   	||
+						((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) && !(resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED)))
+				{
+
+					status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
+				}
+				else
+				{
+					resource_temp_ptr->sn_grs_dyn_res_callback(coap_packet_ptr, src_addr_ptr,0);
+					if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+					{
+						sn_grs_free(coap_packet_ptr->payload_ptr);
+						coap_packet_ptr->payload_ptr = 0;
+					}
+					sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+					return SN_NSDL_SUCCESS;
+				}
+			}
+			else
+			{
+				/* Static resource handling */
+				switch (coap_packet_ptr->msg_code )
+				{
+				case (COAP_MSG_CODE_REQUEST_GET):
+					if(resource_temp_ptr->access & SN_GRS_GET_ALLOWED)
+					{
+						status = COAP_MSG_CODE_RESPONSE_CONTENT;
+					}
+					else
+						status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
+					break;
+				case (COAP_MSG_CODE_REQUEST_POST):
+					if(resource_temp_ptr->access & SN_GRS_POST_ALLOWED)
+					{
+						resource_temp_ptr->resourcelen = coap_packet_ptr->payload_len;
+						sn_grs_free(resource_temp_ptr->resource);
+						resource_temp_ptr->resource = 0;
+						if(resource_temp_ptr->resourcelen)
+						{
+							resource_temp_ptr->resource = sn_grs_alloc(resource_temp_ptr->resourcelen);
+							if(!resource_temp_ptr->resource)
+							{
+								status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+								break;
+							}
+							memcpy(resource_temp_ptr->resource, coap_packet_ptr->payload_ptr, resource_temp_ptr->resourcelen);
+						}
+						if(coap_packet_ptr->content_type_ptr)
+						{
+							if(resource_temp_ptr->resource_parameters_ptr)
+							{
+								resource_temp_ptr->resource_parameters_ptr->coap_content_type = *coap_packet_ptr->content_type_ptr;
+							}
+						}
+						status = COAP_MSG_CODE_RESPONSE_CHANGED;
+					}
+					else
+						status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
+					break;
+				case (COAP_MSG_CODE_REQUEST_PUT):
+					if(resource_temp_ptr->access & SN_GRS_PUT_ALLOWED)
+					{
+						resource_temp_ptr->resourcelen = coap_packet_ptr->payload_len;
+						sn_grs_free(resource_temp_ptr->resource);
+						resource_temp_ptr->resource = 0;
+						if(resource_temp_ptr->resourcelen)
+						{
+							resource_temp_ptr->resource = sn_grs_alloc(resource_temp_ptr->resourcelen);
+							if(!resource_temp_ptr->resource)
+							{
+								status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+								break;
+							}
+							memcpy(resource_temp_ptr->resource, coap_packet_ptr->payload_ptr, resource_temp_ptr->resourcelen);
+						}
+						if(coap_packet_ptr->content_type_ptr)
+						{
+							if(resource_temp_ptr->resource_parameters_ptr)
+							{
+								resource_temp_ptr->resource_parameters_ptr->coap_content_type = *coap_packet_ptr->content_type_ptr;
+							}
+						}
+						status = COAP_MSG_CODE_RESPONSE_CHANGED;
+					}
+					else
+						status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
+					break;
+
+				case (COAP_MSG_CODE_REQUEST_DELETE):
+					if(resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED)
+					{
+						if(sn_grs_delete_resource(coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr) == SN_NSDL_SUCCESS)
+							status = COAP_MSG_CODE_RESPONSE_DELETED;
+						else
+							status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+					}
+					else
+						status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
+					break;
+
+				default:
+					status = COAP_MSG_CODE_RESPONSE_FORBIDDEN;
+					break;
+				}
+			}
+		}
+
+		/* * * * * * * * * * * * * * */
+		/* If resource was not found */
+		/* * * * * * * * * * * * * * */
+
+		else
+		{
+			if(coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST ||
+					coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT)
+			{
+				resource_temp_ptr = sn_grs_alloc(sizeof(sn_nsdl_resource_info_s));
+				if(!resource_temp_ptr)
+				{
+					status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+				}
+				else
+				{
+					memset(resource_temp_ptr, 0, sizeof(sn_nsdl_resource_info_s));
+
+					resource_temp_ptr->access = (sn_grs_resource_acl_e)SN_GRS_DEFAULT_ACCESS;
+					resource_temp_ptr->mode = SN_GRS_STATIC;
+
+					resource_temp_ptr->pathlen = coap_packet_ptr->uri_path_len;
+					resource_temp_ptr->path = sn_grs_alloc(resource_temp_ptr->pathlen);
+					if(!resource_temp_ptr->path)
+					{
+						sn_grs_free(resource_temp_ptr);
+						resource_temp_ptr =  0;
+						status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+					}
+					else
+					{
+						memcpy(resource_temp_ptr->path, coap_packet_ptr->uri_path_ptr, resource_temp_ptr->pathlen);
+
+						resource_temp_ptr->resourcelen = coap_packet_ptr->payload_len;
+						resource_temp_ptr->resource = sn_grs_alloc(resource_temp_ptr->resourcelen);
+						if(!resource_temp_ptr->resource)
+						{
+							sn_grs_free(resource_temp_ptr->path);
+							resource_temp_ptr->path = 0;
+							sn_grs_free(resource_temp_ptr);
+							resource_temp_ptr = 0;
+							status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+						}
+						else
+						{
+
+							memcpy(resource_temp_ptr->resource, coap_packet_ptr->payload_ptr, resource_temp_ptr->resourcelen);
+
+							status = sn_linked_list_add_node(resource_root_list, resource_temp_ptr);
+							if(status == SN_LINKED_LIST_ERROR_NO_ERROR)
+							{
+								if(coap_packet_ptr->content_type_ptr)
+								{
+									if(resource_temp_ptr->resource_parameters_ptr)
+									{
+										resource_temp_ptr->resource_parameters_ptr->coap_content_type = *coap_packet_ptr->content_type_ptr;
+									}
+								}
+								status = COAP_MSG_CODE_RESPONSE_CREATED;
+							}
+							else
+							{
+								sn_grs_free(resource_temp_ptr->path);
+								resource_temp_ptr->path = 0;
+
+								sn_grs_free(resource_temp_ptr->resource);
+								resource_temp_ptr->resource = 0;
+
+								sn_grs_free(resource_temp_ptr);
+								resource_temp_ptr = 0;
+
+								status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+							}
+
+						}
+
+					}
+
+				}
+
+			}
+			else
+				status = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
+		}
+
+	}
+
+
+	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+	/* If received packed was other than reset, create response  */
+	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+	if(coap_packet_ptr->msg_type != COAP_MSG_TYPE_RESET && coap_packet_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT)
+	{
+
+		/* Allocate resopnse message  */
+		response_message_hdr_ptr = sn_grs_alloc(sizeof(sn_coap_hdr_s));
+		if(!response_message_hdr_ptr)
+		{
+			if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+			{
+				sn_grs_free(coap_packet_ptr->payload_ptr);
+				coap_packet_ptr->payload_ptr = 0;
+			}
+			sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+			return SN_NSDL_FAILURE;
+		}
+		memset(response_message_hdr_ptr, 0, sizeof(sn_coap_hdr_s));
+
+		/* If status has not been defined, response internal server error */
+		if(status == COAP_MSG_CODE_EMPTY)
+			status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
+
+		/* Fill header */
+		response_message_hdr_ptr->msg_code = status;
+
+		if(coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE)
+			response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
+		else
+			response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
+
+		response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id;
+
+		if(coap_packet_ptr->token_ptr)
+		{
+			response_message_hdr_ptr->token_len = coap_packet_ptr->token_len;
+			response_message_hdr_ptr->token_ptr = sn_grs_alloc(response_message_hdr_ptr->token_len);
+			if(!response_message_hdr_ptr->token_ptr)
+			{
+				if(response_message_hdr_ptr->payload_ptr)
+				{
+					sn_grs_free(response_message_hdr_ptr->payload_ptr);
+					response_message_hdr_ptr->payload_ptr = 0;
+				}
+				sn_coap_parser_release_allocated_coap_msg_mem(response_message_hdr_ptr);
+
+				if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+				{
+					sn_grs_free(coap_packet_ptr->payload_ptr);
+					coap_packet_ptr->payload_ptr = 0;
+				}
+
+				sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+				return SN_NSDL_FAILURE;
+			}
+			memcpy(response_message_hdr_ptr->token_ptr, coap_packet_ptr->token_ptr, response_message_hdr_ptr->token_len);
+		}
+
+		if(status == COAP_MSG_CODE_RESPONSE_CONTENT)
+		{
+			/* Add content type if other than default */
+			if(resource_temp_ptr->resource_parameters_ptr)
+			{
+				if(resource_temp_ptr->resource_parameters_ptr->coap_content_type != 0)
+				{
+					response_message_hdr_ptr->content_type_len = 1;
+					response_message_hdr_ptr->content_type_ptr = sn_grs_alloc(response_message_hdr_ptr->content_type_len);
+					if(!response_message_hdr_ptr->content_type_ptr)
+					{
+						sn_coap_parser_release_allocated_coap_msg_mem(response_message_hdr_ptr);
+
+						if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+						{
+							sn_grs_free(coap_packet_ptr->payload_ptr);
+							coap_packet_ptr->payload_ptr = 0;
+						}
+
+						sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+						return SN_NSDL_FAILURE;
+					}
+					memcpy(response_message_hdr_ptr->content_type_ptr, &resource_temp_ptr->resource_parameters_ptr->coap_content_type, response_message_hdr_ptr->content_type_len);
+				}
+			}
+
+			/* Add payload */
+			response_message_hdr_ptr->payload_len = resource_temp_ptr->resourcelen;
+			response_message_hdr_ptr->payload_ptr = sn_grs_alloc(response_message_hdr_ptr->payload_len);
+
+			if(!response_message_hdr_ptr->payload_ptr)
+			{
+				sn_coap_parser_release_allocated_coap_msg_mem(response_message_hdr_ptr);
+
+				if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+				{
+					sn_grs_free(coap_packet_ptr->payload_ptr);
+					coap_packet_ptr->payload_ptr = 0;
+				}
+
+				sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+				return SN_NSDL_FAILURE;
+			}
+
+			memcpy(response_message_hdr_ptr->payload_ptr, resource_temp_ptr->resource, response_message_hdr_ptr->payload_len);
+		}
+
+		sn_grs_send_coap_message(src_addr_ptr, response_message_hdr_ptr);
+
+		if(response_message_hdr_ptr->payload_ptr)
+		{
+			sn_grs_free(response_message_hdr_ptr->payload_ptr);
+			response_message_hdr_ptr->payload_ptr = 0;
+		}
+		sn_coap_parser_release_allocated_coap_msg_mem(response_message_hdr_ptr);
+	}
+
+	/* Free parsed CoAP message */
+	if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr)
+	{
+		sn_grs_free(coap_packet_ptr->payload_ptr);
+		coap_packet_ptr->payload_ptr = 0;
+	}
+	sn_coap_parser_release_allocated_coap_msg_mem(coap_packet_ptr);
+
+
+	return SN_NSDL_SUCCESS;
+}
+
+
+
+
+/**
+ * \fn 	extern int16_t sn_grs_get_capability(void)
+ *
+ * \brief Capability query function.
+ *
+ *	Used to retrieve the list of supported protocols from the GRS module.
+ *
+ *	\return				>0 success, supported capabilities reported using bitmask with definitions from sn_grs_capab_t\n
+ *						0 success, no supported capabilities\n
+*/
+
+extern int16_t sn_grs_get_capability(void)
+{
+	int16_t capabilities = 0;
+	if(SN_NSDL_HAVE_HTTP_CAPABILITY)
+		capabilities |= 0x01;
+
+	if(SN_NSDL_HAVE_HTTPS_CAPABILITY)
+		capabilities |= 0x02;
+
+	if(SN_NSDL_HAVE_COAP_CAPABILITY)
+		capabilities |= 0x04;
+
+	return capabilities;
+}
+
+
+/**
+ * \fn 	extern uint32_t sn_grs_get_version(void)
+ *
+ * \brief Version query function.
+ *
+ *	Used to retrieve the version information structure from the GRS library.
+ *
+ *	\return 		!0 MSB 2 bytes major version, LSB 2 bytes minor version.
+ *					0 failure
+*/
+
+extern uint32_t sn_grs_get_version(void)
+{
+	return SN_GRS_VERSION;
+}
+
+/**
+ * \fn 	extern int8_t sn_grs_send_coap_message(sn_nsdl_addr_s * address_ptr, sn_coap_hdr_s *coap_hdr_ptr)
+ *
+ * \brief Sends CoAP message
+ *
+ *	Sends CoAP message
+ *
+ *	\param  *coap_hdr_ptr	Pointer to CoAP message to be sent
+ *
+ *	\param 	*address_ptr	Pointer to source address struct
+ *
+ *	\return	0 = success, -1 = failed
+ *
+*/
+extern int8_t sn_grs_send_coap_message(sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr)
+{
+	uint8_t 	*message_ptr = NULL;
+	uint16_t 	message_len	= 0;
+	uint8_t		ret_val = 0;
+
+	/* Calculate message length */
+	message_len = sn_coap_builder_calc_needed_packet_data_size(coap_hdr_ptr);
+
+	/* Allocate memory for message and check was allocating successfully */
+	message_ptr = sn_grs_alloc(message_len);
+	if(message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	/* Build CoAP message */
+	if(sn_coap_protocol_build(address_ptr, message_ptr, coap_hdr_ptr) < 0)
+	{
+		sn_grs_free(message_ptr);
+		message_ptr = 0;
+		return SN_NSDL_FAILURE;
+	}
+
+	/* Call tx callback function to send message */
+	ret_val = sn_grs_tx_callback(SN_NSDL_PROTOCOL_COAP, message_ptr, message_len, address_ptr);
+
+	/* Free allocated memory */
+	sn_grs_free(message_ptr);
+	message_ptr = 0;
+
+	if(ret_val == 0)
+		return SN_NSDL_FAILURE;
+	else
+		return SN_NSDL_SUCCESS;
+}
+
+/**
+ * \fn 	static sn_grs_resource_info_s *sn_grs_search_resource(uint16_t pathlen, uint8_t *path, uint8_t search_method)
+ *
+ * \brief Searches given resource from linked list
+ *
+ *	Search either precise path, or subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc...
+ *
+ *	\param  pathlen			Length of the path to be search
+ *
+ *	\param 	*path			Pointer to the path string to be search
+ *
+ *	\param 	search_method	Search method, SEARCH or DELETE
+ *
+ *	\return					Pointer to the resource. If resource not found, return value is NULL
+ *
+*/
+
+static sn_nsdl_resource_info_s *sn_grs_search_resource(uint16_t pathlen, uint8_t *path, uint8_t search_method)
+{
+	/* Local variables */
+	sn_nsdl_resource_info_s 	*resource_search_temp 	= NULL;
+	uint8_t 					i	 					= 0;
+	uint8_t 					*path_temp_ptr 			= NULL;
+
+	/* Check parameters */
+	if(!pathlen || !path)
+	{
+		return (sn_nsdl_resource_info_s *)NULL;;
+	}
+
+	/* Remove '/' - marks from the end and beginning */
+	path_temp_ptr = sn_grs_convert_uri(&pathlen, path);
+
+	resource_search_temp = sn_linked_list_get_first_node(resource_root_list);
+
+	/* Searchs exact path */
+	if(search_method == SN_GRS_SEARCH_METHOD)
+	{
+		/* Scan all nodes on list */
+		while(resource_search_temp)
+		{
+			/* If length equals.. */
+			if(resource_search_temp->pathlen == pathlen)
+			{
+				/* Compare paths */
+				i = memcmp(resource_search_temp->path, path_temp_ptr, pathlen);
+
+				/* If same, return node pointer */
+				if(!i)
+					return resource_search_temp;
+			}
+			/* If that was not what we needed, get next node.. */
+			resource_search_temp = sn_linked_list_get_next_node(resource_root_list);
+		}
+	}
+
+	/* Search also subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... */
+	else if(search_method == SN_GRS_DELETE_METHOD)
+	{
+		/* Scan all nodes on list */
+		while(resource_search_temp)
+		{
+			uint8_t *temp_ptr = resource_search_temp->path;
+
+			i = memcmp(resource_search_temp->path, path_temp_ptr, pathlen);
+
+			/* If found, return pointer */
+			if((*(temp_ptr+(uint8_t)pathlen) == '/') && !i)
+				return resource_search_temp;
+
+			/* else get next node */
+			resource_search_temp = sn_linked_list_get_next_node(resource_root_list);
+		}
+	}
+
+	/* If there was not nodes we wanted, return NULL */
+	return (sn_nsdl_resource_info_s *)NULL;
+}
+
+
+/**
+ * \fn 	static int8_t sn_grs_add_resource_to_list(sn_linked_list_t *list_ptr, sn_grs_resource_info_s *resource_ptr)
+ *
+ * \brief Adds given resource to resource list
+ *
+ *	\param  *list_ptr			Length of the path to be search
+ *
+ *	\param 	*resource_ptr			Pointer to the path string to be search
+ *
+ *	\return	0 = SN_NSDL_SUCCESS, -1 = SN_NSDL_FAILURE
+ *
+*/
+
+static int8_t sn_grs_add_resource_to_list(sn_linked_list_t *list_ptr, sn_nsdl_resource_info_s *resource_ptr)
+{
+	/* Local variables */
+	int8_t status = 0;
+	uint8_t *path_start_ptr = NULL;
+	uint16_t path_len = 0;
+	sn_nsdl_resource_info_s *resource_copy_ptr = NULL;
+
+		/* Allocate memory for the resource info copy */
+	if(!resource_ptr->pathlen)
+	{
+		return SN_NSDL_FAILURE;
+	}
+	resource_copy_ptr = sn_grs_alloc(sizeof(sn_nsdl_resource_info_s));
+	if(resource_copy_ptr == (sn_nsdl_resource_info_s*)NULL)
+	{
+		return SN_NSDL_FAILURE;
+	}
+
+	/* Set everything to zero  */
+	memset(resource_copy_ptr, 0, sizeof(sn_nsdl_resource_info_s));
+
+	resource_copy_ptr->mode = resource_ptr->mode;
+	resource_copy_ptr->resourcelen = resource_ptr->resourcelen;
+	resource_copy_ptr->sn_grs_dyn_res_callback = resource_ptr->sn_grs_dyn_res_callback;
+	resource_copy_ptr->access = resource_ptr->access;
+
+	/* Remove '/' - chars from the beginning and from the end */
+
+	path_len = resource_ptr->pathlen;
+	path_start_ptr = sn_grs_convert_uri(&path_len, resource_ptr->path);
+
+	/* Allocate memory for the path */
+	resource_copy_ptr->path = sn_grs_alloc(path_len);
+	if(!resource_copy_ptr->path)
+	{
+		sn_grs_resource_info_free(resource_copy_ptr);
+		return SN_NSDL_FAILURE;
+	}
+
+	/* Update pathlen */
+	resource_copy_ptr->pathlen = path_len;
+
+	/* Copy path string to the copy */
+#ifdef CC8051_PLAT
+        copy_code_nsdl(resource_copy_ptr->path, (prog_uint8_t*)path_start_ptr, resource_copy_ptr->pathlen);
+#else
+	memcpy(resource_copy_ptr->path, path_start_ptr, resource_copy_ptr->pathlen);
+#endif
+	/* Allocate memory for the resource, and copy it to copy */
+	if(resource_ptr->resource)
+	{
+		resource_copy_ptr->resource = sn_grs_alloc(resource_ptr->resourcelen);
+		if(!resource_copy_ptr->resource)
+		{
+			sn_grs_resource_info_free(resource_copy_ptr);
+			return SN_NSDL_FAILURE;
+		}
+		memcpy(resource_copy_ptr->resource, resource_ptr->resource, resource_ptr->resourcelen);
+	}
+
+
+
+	/* If resource parameters exists, copy them */
+	if(resource_ptr->resource_parameters_ptr)
+	{
+		resource_copy_ptr->resource_parameters_ptr = sn_grs_alloc(sizeof(sn_nsdl_resource_parameters_s));
+		if(!resource_copy_ptr->resource_parameters_ptr)
+		{
+			sn_grs_resource_info_free(resource_copy_ptr);
+			return SN_NSDL_FAILURE;
+		}
+
+		memset(resource_copy_ptr->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s));
+
+
+		resource_copy_ptr->resource_parameters_ptr->resource_type_len = resource_ptr->resource_parameters_ptr->resource_type_len;
+
+		resource_copy_ptr->resource_parameters_ptr->interface_description_len = resource_ptr->resource_parameters_ptr->interface_description_len;
+
+		resource_copy_ptr->resource_parameters_ptr->mime_content_type = resource_ptr->resource_parameters_ptr->mime_content_type;
+
+		resource_copy_ptr->resource_parameters_ptr->observable = resource_ptr->resource_parameters_ptr->observable;
+
+		if(resource_ptr->resource_parameters_ptr->resource_type_ptr)
+		{
+			resource_copy_ptr->resource_parameters_ptr->resource_type_ptr = sn_grs_alloc(resource_ptr->resource_parameters_ptr->resource_type_len);
+			if(!resource_copy_ptr->resource_parameters_ptr->resource_type_ptr)
+			{
+				sn_grs_resource_info_free(resource_copy_ptr);
+				return SN_NSDL_FAILURE;
+			}
+#ifdef CC8051_PLAT
+                        copy_code_nsdl(resource_copy_ptr->resource_parameters_ptr->resource_type_ptr,(prog_uint8_t*) resource_ptr->resource_parameters_ptr->resource_type_ptr, resource_ptr->resource_parameters_ptr->resource_type_len);
+#else
+			memcpy(resource_copy_ptr->resource_parameters_ptr->resource_type_ptr, resource_ptr->resource_parameters_ptr->resource_type_ptr, resource_ptr->resource_parameters_ptr->resource_type_len);
+#endif
+                }
+
+		if(resource_ptr->resource_parameters_ptr->interface_description_ptr)
+		{
+			resource_copy_ptr->resource_parameters_ptr->interface_description_ptr = sn_grs_alloc(resource_ptr->resource_parameters_ptr->interface_description_len);
+			if(!resource_copy_ptr->resource_parameters_ptr->interface_description_ptr)
+			{
+				sn_grs_resource_info_free(resource_copy_ptr);
+				return SN_NSDL_FAILURE;
+			}
+			memcpy(resource_copy_ptr->resource_parameters_ptr->interface_description_ptr, resource_ptr->resource_parameters_ptr->interface_description_ptr, resource_ptr->resource_parameters_ptr->interface_description_len);
+		}
+
+		/* Copy auto observation parameter */
+		/* todo: aobs not supported ATM - needs fixing */
+/*		if(resource_ptr->resource_parameters_ptr->auto_obs_ptr && resource_ptr->resource_parameters_ptr->auto_obs_len)
+		{
+			resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr = sn_grs_alloc(resource_ptr->resource_parameters_ptr->auto_obs_len);
+			if(!resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr)
+			{
+				sn_grs_resource_info_free(resource_copy_ptr);
+				return SN_NSDL_FAILURE;
+			}
+			memcpy(resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr, resource_ptr->resource_parameters_ptr->auto_obs_ptr, resource_ptr->resource_parameters_ptr->auto_obs_len);
+			resource_copy_ptr->resource_parameters_ptr->auto_obs_len = resource_ptr->resource_parameters_ptr->auto_obs_len;
+		}
+
+		resource_copy_ptr->resource_parameters_ptr->coap_content_type = resource_ptr->resource_parameters_ptr->coap_content_type;
+		*/
+	}
+
+	/* Add copied resource to the linked list */
+	status = sn_linked_list_add_node(list_ptr, resource_copy_ptr);
+
+	/* Was adding ok? */
+	if(status == SN_LINKED_LIST_ERROR_NO_ERROR)
+	{
+		return SN_NSDL_SUCCESS;
+	}
+	else
+	{
+		sn_grs_resource_info_free(resource_copy_ptr);
+		return SN_NSDL_FAILURE;//DONE?: Free memory
+	}
+}
+
+
+/**
+ * \fn 	static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr)
+ *
+ * \brief Removes '/' from the beginning and from the end of uri string
+ *
+ *	\param  *uri_len			Pointer to the length of the path string
+ *
+ *	\param 	*uri_ptr			Pointer to the path string
+ *
+ *	\return	start pointer of the uri
+ *
+*/
+
+static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr)
+{
+	/* Local variables */
+	uint8_t *uri_start_ptr = uri_ptr;
+
+	/* If '/' in the beginning, update uri start pointer and uri len */
+	if(*uri_ptr == '/')
+	{
+		uri_start_ptr = uri_ptr+1;
+		*uri_len = *uri_len-1;
+	}
+
+	/* If '/' at the end, update uri len */
+	if(*(uri_start_ptr+*uri_len-1) == '/')
+	{
+		*uri_len = *uri_len-1;
+	}
+
+	/* Return start pointer */
+	return uri_start_ptr;
+}
+
+/**
+ * \fn 	static int8_t sn_grs_resource_info_free(sn_grs_resource_info_s *resource_ptr)
+ *
+ * \brief Frees resource info structure
+ *
+ *	\param *resource_ptr	Pointer to the resource
+ *
+ *	\return	0 if success, -1 if failed
+ *
+*/
+
+static int8_t sn_grs_resource_info_free(sn_nsdl_resource_info_s *resource_ptr)
+{
+	if(resource_ptr)
+	{
+		if(resource_ptr->resource_parameters_ptr)
+		{
+			if(resource_ptr->resource_parameters_ptr->interface_description_ptr)
+			{
+				sn_grs_free(resource_ptr->resource_parameters_ptr->interface_description_ptr);
+				resource_ptr->resource_parameters_ptr->interface_description_ptr = 0;
+			}
+
+			if(resource_ptr->resource_parameters_ptr->resource_type_ptr)
+			{
+				sn_grs_free(resource_ptr->resource_parameters_ptr->resource_type_ptr);
+				resource_ptr->resource_parameters_ptr->resource_type_ptr = 0;
+			}
+
+			/* Todo: aobs not supported ATM - needs fixing */
+			/*
+			if(resource_ptr->resource_parameters_ptr->auto_obs_ptr)
+			{
+				sn_grs_free(resource_ptr->resource_parameters_ptr->auto_obs_ptr);
+				resource_ptr->resource_parameters_ptr->auto_obs_ptr = 0;
+			}
+			*/
+
+			sn_grs_free(resource_ptr->resource_parameters_ptr);
+			resource_ptr->resource_parameters_ptr = 0;
+		}
+
+		if(resource_ptr->path)
+		{
+			sn_grs_free(resource_ptr->path);
+			resource_ptr->path = 0;
+		}
+		if(resource_ptr->resource)
+		{
+			sn_grs_free(resource_ptr->resource);
+			resource_ptr->resource = 0;
+		}
+		sn_grs_free(resource_ptr);
+		resource_ptr = 0;
+		return SN_NSDL_SUCCESS;
+	}
+	return SN_NSDL_FAILURE;
+}
+
+#ifdef CC8051_PLAT
+void copy_code_nsdl(uint8_t * ptr, prog_uint8_t * code_ptr, uint16_t len)
+{
+	uint16_t i;
+	for(i=0; i<len; i++)
+	{
+		ptr[i] = code_ptr[i];
+	}
+}
+#endif
+
+static uint8_t sn_grs_compare_code(uint8_t * ptr, prog_uint8_t * code_ptr, uint8_t len)
+{
+	uint8_t i=0;
+	while(len)
+	{
+		if(ptr[i] != code_ptr[i])
+		{
+			break;
+		}
+		len--;
+		i++;
+	}
+	return len;
+}
+
+
diff -r aafd54b05111 -r 14a9b0f4b9d6 sn_grs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sn_grs.h	Tue Feb 18 01:10:07 2014 +0000
@@ -0,0 +1,117 @@
+/*
+ * GRS.h
+ *
+ *  Created on: 2.8.2011
+ *      Author: Tero
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GRS_H_
+#define GRS_H_
+
+
+#endif /* GRS_H_ */
+
+#define SN_GRS_VERSION	                	0x0101
+
+#ifndef SN_NSDL_HAVE_HTTP_CAPABILITY
+#define SN_NSDL_HAVE_HTTP_CAPABILITY		0
+#endif
+
+#ifndef SN_NSDL_HAVE_HTTPS_CAPABILITY
+#define SN_NSDL_HAVE_HTTPS_CAPABILITY		0
+#endif
+
+#ifndef SN_NSDL_HAVE_COAP_CAPABILITY
+#define SN_NSDL_HAVE_COAP_CAPABILITY		1
+#endif
+
+#define SN_GRS_RESOURCE_ALREADY_EXISTS	-2
+#define SN_GRS_INVALID_PATH 			-3
+#define SN_GRS_LIST_ADDING_FAILURE		-4
+#define SN_GRS_RESOURCE_UPDATED		-5
+
+#define ACCESS_DENIED			-6
+
+#define SN_GRS_DELETE_METHOD	0
+#define SN_GRS_SEARCH_METHOD	1
+
+#define SN_GRS_DEFAULT_ACCESS	0x0F
+
+#define SN_NDSL_RESOURCE_NOT_REGISTERED	0
+#define SN_NDSL_RESOURCE_REGISTERING	1
+#define SN_NDSL_RESOURCE_REGISTERED		2
+
+/***** Structs *****/
+
+typedef struct sn_grs_version_
+{
+	uint8_t major_version;
+	uint8_t minor_version;
+	uint8_t build;
+}sn_grs_version_s;
+
+
+
+/***** Function prototypes *****/
+/**
+ *	\fn extern int8_t sn_grs_init	(uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
+ *									sn_nsdl_addr_s *), uint8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
+ *									sn_grs_mem_s *sn_memory)
+ *
+ *  \brief GRS library initialize function.
+ *
+ *	This function initializes GRS, CoAP and HTTP libraries.
+ *
+ *	\param 	sn_grs_tx_callback 		A function pointer to a transmit callback function. Should return 1 when succeed, 0 when failed
+ *	\param  *sn_grs_rx_callback_ptr A function pointer to a receiving callback function. If received packet is not for GRS, it will be passed to
+ *									upper level (NSDL) to be proceed.
+ *	\param 	sn_memory 				A pointer to a structure containing the platform specific functions for memory allocation and free.
+ *
+ *	\return success = 0, failure = -1
+ *
+*/
+extern int8_t sn_grs_init	(uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
+		sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *), sn_nsdl_mem_s *sn_memory);
+extern int8_t sn_grs_exec(uint32_t time);
+extern sn_grs_resource_list_s *sn_grs_list_resource(uint16_t pathlen, uint8_t *path);
+extern sn_nsdl_resource_info_s *sn_grs_get_first_resource(void);
+extern sn_nsdl_resource_info_s *sn_grs_get_next_resource(void);
+extern sn_nsdl_resource_info_s *sn_grs_get_resource(uint16_t pathlen, uint8_t *path);
+extern int8_t sn_grs_delete_resource(uint16_t pathlen, uint8_t *path);
+extern int8_t sn_grs_update_resource(sn_nsdl_resource_info_s *res);
+/**
+ * \fn 	extern int8_t sn_grs_create_resource(sn_grs_resource_info_t *res)
+ *
+ * \brief Resource creating function.
+ *
+ *	Used to create a static or dynamic HTTP(S) or CoAP resource.
+ *
+ *	\param 	*res	Pointer to a structure of type sn_grs_resource_info_t that contains the information
+ *					about the resource.
+ *
+ *	\return 		 0 success
+ *					-1 Resource already exists
+ *					-2 Invalid path
+ *					-3 List adding failure
+*/
+extern int8_t sn_grs_create_resource(sn_nsdl_resource_info_s *res);
+extern int8_t sn_grs_process_http(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src);
+extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src);
+extern int16_t sn_grs_get_capability(void);
+extern uint32_t sn_grs_get_version(void);
+extern int8_t sn_grs_send_coap_message(sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
+
+extern int8_t sn_grs_destroy(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
diff -r aafd54b05111 -r 14a9b0f4b9d6 sn_nsdl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sn_nsdl.c	Tue Feb 18 01:10:07 2014 +0000
@@ -0,0 +1,1555 @@
+/**
+ * \file sn_nsdl.c
+ *
+ * \brief Nano service device library
+ *
+ *	Application interface to CoAP, GRS and NSP handling.
+ *
+ */
+
+#include <string.h>
+
+#include "nsdl_types.h"
+#include "sn_nsdl.h"
+#include "sn_coap_header.h"
+#include "sn_coap_protocol.h"
+#include "sn_nsdl_lib.h"
+#include "sn_grs.h"
+#include "sn_linked_list.h"
+
+/* Defines */
+#define RESOURCE_DIR_LEN				2
+#define RESOURCE_DIR_PATH				{'r','d'}
+
+#define EP_NAME_PARAMETERS_LEN			2
+#define EP_NAME_PARAMETERS				{'h','='}
+
+#define RT_PARAMETER_LEN				3
+#define RT_PARAMETER					{'r','t','='}
+
+#define IF_PARAMETER_LEN				3
+#define IF_PARAMETER					{'i','f','='}
+
+#define CON_PARAMETER_LEN				4
+#define CON_PARAMETER					{'c','o','n','='}
+
+#define LT_PARAMETER_LEN				3
+#define LT_PARAMETER					{'l','t','='}
+
+#define OBS_PARAMETER_LEN				3
+#define OBS_PARAMETER					{'o','b','s'}
+
+#define AOBS_PARAMETER_LEN				8
+#define AOBS_PARAMETER					{'a','o','b','s',';','i','d','='}
+
+#define COAP_CON_PARAMETER_LEN			3
+#define COAP_CON_PARAMETER				{'c','t','='}
+
+#define EVENT_PATH_LEN					6
+#define EVENT_PATH						{'e','v','e','n','t','/'}
+
+#define SN_NSDL_EP_REGISTER_MESSAGE		1
+#define SN_NSDL_EP_UPDATE_MESSAGE		2
+
+#define	SN_NSDL_MSG_NO_TYPE				0
+#define	SN_NSDL_MSG_REGISTER			1
+#define SN_NSDL_MSG_UNREGISTER			2
+#define SN_NSDL_MSG_UPDATE				3
+#define SN_NSDL_MSG_EVENT				4
+
+#define	SN_NSDL_MAX_MESSAGE_COUNT		1
+
+/* Constants */
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t 	ep_name_parameter_string[] 	= EP_NAME_PARAMETERS;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t		resource_path_ptr[]			= RESOURCE_DIR_PATH;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t		resource_type_parameter[]	= RT_PARAMETER;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t		obs_parameter[]				= OBS_PARAMETER;
+
+//SN_NSDL_CONST_MEMORY_ATTRIBUTE
+//static uint8_t		aobs_parameter[]			= AOBS_PARAMETER;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t		if_description_parameter[]	= IF_PARAMETER;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t		ep_lifetime_parameter[]		= LT_PARAMETER;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t 	coap_con_type_parameter[]	= COAP_CON_PARAMETER;
+
+SN_NSDL_CONST_MEMORY_ATTRIBUTE
+static uint8_t 	event_path_parameter[]		= EVENT_PATH;
+
+/* Global function pointers */
+static void 	*(*sn_nsdl_alloc)(uint16_t)  = 0;
+static void 	(*sn_nsdl_free)(void*) = 0;
+static uint8_t (*sn_nsdl_tx_callback)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *) = 0;
+static uint8_t (*sn_nsdl_rx_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *) = 0;
+
+/* Global variables */
+static sn_nsdl_ep_parameters_s		*ep_information_ptr  = 0; 	// Endpoint parameters, Name, Domain etc..
+static sn_nsdl_addr_s 				*nsp_address_ptr = 0;		// NSP server address information
+static sn_linked_list_t				*message_list_ptr = 0;		//
+static uint8_t 						sn_nsdl_endpoint_registered = 0;
+
+/* Function prototypes */
+static int8_t 			sn_nsdl_internal_coap_send					(sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr, uint8_t message_description);
+static void				sn_nsdl_resolve_nsp_address					(void);
+int8_t 					sn_nsdl_build_registration_body				(sn_coap_hdr_s *message_ptr, uint8_t updating_registeration);
+static uint16_t 		sn_nsdl_calculate_registration_body_size	(uint8_t updating_registeration);
+static uint8_t 			sn_nsdl_calculate_uri_query_option_len		(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type);
+static int8_t 			sn_nsdl_fill_uri_query_options				(sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type);
+static int8_t			sn_nsdl_local_rx_function					(sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr);
+static int8_t 			sn_nsdl_resolve_ep_information				(sn_coap_hdr_s *coap_packet_ptr);
+static void 			sn_nsdl_mark_resources_as_registered		(void);
+static uint8_t 			sn_nsdl_itoa_len							(uint8_t value);
+static uint8_t 			*sn_nsdl_itoa								(uint8_t *ptr, uint8_t value);
+
+
+int8_t sn_nsdl_destroy(void)
+{
+	if(message_list_ptr)
+	{
+		uint16_t size =  sn_linked_list_count_nodes(message_list_ptr);
+		uint16_t i = 0;
+		sn_nsdl_sent_messages_s*tmp;
+
+
+		for(i=0;i<size;i++)
+		{
+			tmp = sn_linked_list_get_first_node(message_list_ptr);
+
+			if(tmp)
+			{
+				sn_linked_list_remove_current_node(message_list_ptr);
+				sn_nsdl_free(tmp);
+				tmp = 0;
+			}
+		}
+
+		if(!sn_linked_list_count_nodes(message_list_ptr))
+		{
+			sn_linked_list_free(message_list_ptr);
+			message_list_ptr = 0;
+		}
+	}
+
+	if(ep_information_ptr)
+	{
+		if(ep_information_ptr->endpoint_name_ptr)
+		{
+			sn_nsdl_free(ep_information_ptr->endpoint_name_ptr);
+			ep_information_ptr->endpoint_name_ptr = 0;
+		}
+		if(ep_information_ptr->domain_name_ptr)
+		{
+			sn_nsdl_free(ep_information_ptr->domain_name_ptr);
+			ep_information_ptr->domain_name_ptr = 0;
+			ep_information_ptr->domain_name_len = 0;
+		}
+		if(ep_information_ptr->type_ptr)
+		{
+			sn_nsdl_free(ep_information_ptr->type_ptr);
+			ep_information_ptr->type_ptr = 0;
+		}
+
+		if(ep_information_ptr->lifetime_ptr)
+
+		{
+			sn_nsdl_free(ep_information_ptr->lifetime_ptr);
+			ep_information_ptr->lifetime_ptr = 0;
+		}
+
+		sn_nsdl_free(ep_information_ptr);
+		ep_information_ptr = 0;
+	}
+
+	if(nsp_address_ptr)
+	{
+		if(nsp_address_ptr->socket_information)
+		{
+			sn_nsdl_free(nsp_address_ptr->socket_information);
+			nsp_address_ptr->socket_information= 0;
+		}
+
+		if(nsp_address_ptr->addr_ptr)
+		{
+			sn_nsdl_free(nsp_address_ptr->addr_ptr);
+			nsp_address_ptr->addr_ptr = 0;
+		}
+		sn_nsdl_free(nsp_address_ptr);
+		nsp_address_ptr = 0;
+	}
+
+	/* Destroy also libCoap and grs part of libNsdl */
+	sn_grs_destroy();
+	sn_coap_protocol_destroy();
+
+	return 0;
+}
+
+int8_t sn_nsdl_init	(uint8_t (*sn_nsdl_tx_cb)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
+							uint8_t (*sn_nsdl_rx_cb)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
+							sn_nsdl_mem_s *sn_memory)
+{
+	/* Check pointers and define function pointers */
+	if(!sn_memory || !sn_memory->sn_nsdl_alloc || !sn_memory->sn_nsdl_free || !sn_nsdl_tx_cb || !sn_nsdl_rx_cb)
+		return SN_NSDL_FAILURE;
+
+	/* Define function pointers */
+	sn_nsdl_alloc = sn_memory->sn_nsdl_alloc;
+	sn_nsdl_free = sn_memory->sn_nsdl_free;
+
+	sn_nsdl_tx_callback = sn_nsdl_tx_cb;
+	sn_nsdl_rx_callback = sn_nsdl_rx_cb;
+
+	sn_linked_list_init(sn_nsdl_alloc, sn_nsdl_free);
+
+	message_list_ptr = sn_linked_list_create();
+	if(!message_list_ptr)
+		return SN_NSDL_FAILURE;
+
+	/* Initialize ep parameters struct */
+	if(!ep_information_ptr)
+	{
+		ep_information_ptr = sn_nsdl_alloc(sizeof(sn_nsdl_ep_parameters_s));
+		if(!ep_information_ptr)
+		{
+			sn_linked_list_free(message_list_ptr);
+			return SN_NSDL_FAILURE;
+		}
+		memset(ep_information_ptr, 0, sizeof(sn_nsdl_ep_parameters_s));
+	}
+
+	/* Initialize GRS */
+	if(sn_grs_init(sn_nsdl_tx_cb,&sn_nsdl_local_rx_function, sn_memory))
+	{
+
+		sn_nsdl_free(ep_information_ptr);
+		ep_information_ptr = 0;
+		sn_linked_list_free(message_list_ptr);
+		return SN_NSDL_FAILURE;
+
+	}
+
+	// todo: Resolve NS server address -> v0.5 = hardcoded address
+	sn_nsdl_resolve_nsp_address();
+
+	sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED;
+
+	return SN_NSDL_SUCCESS;
+}
+
+int8_t sn_nsdl_GET_with_QUERY(char * uri, uint16_t urilen, uint8_t*destination, uint16_t port, char *query, uint8_t query_len)
+{
+	sn_coap_hdr_s 	*message_ptr;
+	sn_nsdl_addr_s *dst = 0;
+
+	message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	memset(message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	/* Fill message fields -> confirmable post to specified NSP path */
+	message_ptr->msg_type 	= 	COAP_MSG_TYPE_CONFIRMABLE;
+	message_ptr->msg_code 	= 	COAP_MSG_CODE_REQUEST_GET;
+	/* Allocate memory for the extended options list */
+	message_ptr->options_list_ptr = sn_nsdl_alloc(sizeof(sn_coap_options_list_s));
+	if(message_ptr->options_list_ptr == NULL)
+	{
+		sn_nsdl_free(message_ptr);
+		message_ptr = 0;
+		return SN_NSDL_FAILURE;
+	}
+
+
+	memset(message_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
+	message_ptr->options_list_ptr->uri_query_len =query_len;
+	message_ptr->options_list_ptr->uri_query_ptr = (uint8_t *)query;
+	message_ptr->uri_path_len = urilen;
+	message_ptr->uri_path_ptr = (uint8_t *)uri;
+
+	/* Build and send coap message to NSP */
+	/* Local variables */
+	if(!dst)
+	{
+		//allocate only if previously not allocated
+		dst = sn_nsdl_alloc(sizeof(sn_nsdl_addr_s));
+	}
+
+	if(dst)
+	{
+		/* This is only for version 0.5 */
+		dst->type = SN_NSDL_ADDRESS_TYPE_IPV6;
+		dst->port = port;
+		dst->addr_len = 16;
+		if(!dst->addr_ptr)
+		{
+			dst->addr_ptr = sn_nsdl_alloc(dst->addr_len);
+			memcpy(dst->addr_ptr, destination, 16);
+		}
+	}
+
+	sn_grs_send_coap_message(dst, message_ptr);
+
+	if(dst->addr_ptr)
+		sn_nsdl_free(dst->addr_ptr);
+
+	if(dst)
+		sn_nsdl_free(dst);
+	message_ptr->uri_path_ptr = NULL;
+	message_ptr->options_list_ptr->uri_host_ptr = NULL;
+	message_ptr->options_list_ptr->uri_query_ptr = NULL;
+
+	sn_coap_parser_release_allocated_coap_msg_mem(message_ptr);
+	return SN_NSDL_SUCCESS;
+}
+
+int8_t sn_nsdl_GET(char * uri, uint16_t urilen, uint8_t*destination, uint16_t port)
+{
+	sn_coap_hdr_s 	*message_ptr;
+	sn_nsdl_addr_s *dst = 0;
+
+
+	message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	memset(message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	/* Fill message fields -> confirmable post to specified NSP path */
+	message_ptr->msg_type 	= 	COAP_MSG_TYPE_CONFIRMABLE;
+	message_ptr->msg_code 	= 	COAP_MSG_CODE_REQUEST_GET;
+	/* Allocate memory for the extended options list */
+	message_ptr->options_list_ptr = sn_nsdl_alloc(sizeof(sn_coap_options_list_s));
+	if(message_ptr->options_list_ptr == NULL)
+	{
+		sn_nsdl_free(message_ptr);
+		message_ptr = 0;
+		return SN_NSDL_FAILURE;
+	}
+
+
+	memset(message_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
+
+	message_ptr->uri_path_len = urilen;
+	message_ptr->uri_path_ptr = (uint8_t *)uri;
+
+	/* Build and send coap message to NSP */
+	/* Local variables */
+	if(!dst)
+	{
+		//allocate only if previously not allocated
+		dst = sn_nsdl_alloc(sizeof(sn_nsdl_addr_s));
+		memset(dst, 0, sizeof(sn_nsdl_addr_s));
+	}
+
+	if(dst)
+	{
+		/* This is only for version 0.5 */
+		dst->type = SN_NSDL_ADDRESS_TYPE_IPV6;
+		dst->port = port;
+		dst->addr_len = 16;
+		if(!dst->addr_ptr)
+		{
+			dst->addr_ptr = sn_nsdl_alloc(dst->addr_len);
+			memcpy(dst->addr_ptr, destination, 16);
+		}
+	}
+	sn_grs_send_coap_message(dst, message_ptr);
+
+	if(dst->addr_ptr)
+		sn_nsdl_free(dst->addr_ptr);
+	if(dst)
+		sn_nsdl_free(dst);
+	message_ptr->uri_path_ptr = NULL;
+	message_ptr->options_list_ptr->uri_host_ptr = NULL;
+
+	sn_coap_parser_release_allocated_coap_msg_mem(message_ptr);
+	return SN_NSDL_SUCCESS;
+}
+
+
+
+int8_t sn_nsdl_register_endpoint(sn_nsdl_ep_parameters_s *endpoint_info_ptr)
+{
+	/* Local variables */
+	sn_coap_hdr_s 	*register_message_ptr;
+	int8_t			status 					= 0;
+
+	if(!endpoint_info_ptr)
+		return SN_NSDL_FAILURE;
+
+	/*** Build endpoint register message ***/
+
+	/* Allocate memory for header struct */
+	register_message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(register_message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	memset(register_message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	/* Fill message fields -> confirmable post to specified NSP path */
+	register_message_ptr->msg_type 	= 	COAP_MSG_TYPE_CONFIRMABLE;
+	register_message_ptr->msg_code 	= 	COAP_MSG_CODE_REQUEST_POST;
+
+	/* Allocate memory for the extended options list */
+	register_message_ptr->options_list_ptr = sn_nsdl_alloc(sizeof(sn_coap_options_list_s));
+	if(register_message_ptr->options_list_ptr == NULL)
+	{
+		sn_nsdl_free(register_message_ptr);
+		register_message_ptr = 0;
+		return SN_NSDL_FAILURE;
+	}
+
+	memset(register_message_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
+
+	register_message_ptr->uri_path_len = sizeof(resource_path_ptr);
+	register_message_ptr->uri_path_ptr = resource_path_ptr;
+
+	/* If domain name is configured, fill needed fields */
+	if(endpoint_info_ptr->domain_name_len)
+	{
+		register_message_ptr->options_list_ptr->uri_host_len = endpoint_info_ptr->domain_name_len;
+		register_message_ptr->options_list_ptr->uri_host_ptr = endpoint_info_ptr->domain_name_ptr;
+	}
+
+	/* Fill Uri-query options */
+	sn_nsdl_fill_uri_query_options(endpoint_info_ptr, register_message_ptr, SN_NSDL_EP_REGISTER_MESSAGE);
+#ifndef REG_TEMPLATE
+	/* Built body for message */
+	status = sn_nsdl_build_registration_body(register_message_ptr, 0);
+	if(status == SN_NSDL_FAILURE)
+	{ 
+		register_message_ptr->uri_path_ptr = NULL;
+		register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
+		sn_coap_parser_release_allocated_coap_msg_mem(register_message_ptr);
+		return SN_NSDL_FAILURE;
+	}
+#endif
+	/* Build and send coap message to NSP */
+	status = sn_nsdl_internal_coap_send(register_message_ptr, nsp_address_ptr, SN_NSDL_MSG_REGISTER);
+
+	if(register_message_ptr->payload_ptr)
+	{
+		sn_nsdl_free(register_message_ptr->payload_ptr);
+		register_message_ptr->payload_ptr = NULL;
+	}
+
+	register_message_ptr->uri_path_ptr = NULL;
+	register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
+
+	sn_coap_parser_release_allocated_coap_msg_mem(register_message_ptr);
+
+	if(ep_information_ptr)
+	{
+		if(ep_information_ptr->domain_name_ptr)
+		{
+			sn_nsdl_free(ep_information_ptr->domain_name_ptr);
+			ep_information_ptr->domain_name_ptr = 0;
+			ep_information_ptr->domain_name_len = 0;
+		}
+
+		if(ep_information_ptr->endpoint_name_ptr)
+		{
+			sn_nsdl_free(ep_information_ptr->endpoint_name_ptr);
+			ep_information_ptr->endpoint_name_ptr = 0;
+			ep_information_ptr->endpoint_name_len = 0;
+		}
+
+		if(endpoint_info_ptr->domain_name_ptr)
+		{
+
+			if(!ep_information_ptr->domain_name_ptr)
+			{
+				ep_information_ptr->domain_name_ptr = sn_nsdl_alloc(endpoint_info_ptr->domain_name_len);
+			}
+			if(!ep_information_ptr->domain_name_ptr)
+			{
+				return SN_NSDL_FAILURE;
+			}
+
+			memcpy(ep_information_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_len);
+			ep_information_ptr->domain_name_len = endpoint_info_ptr->domain_name_len;
+
+		}
+
+		if(endpoint_info_ptr->endpoint_name_ptr)
+		{
+
+			if(!ep_information_ptr->endpoint_name_ptr)
+			{
+				ep_information_ptr->endpoint_name_ptr = sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len);
+			}
+			if(!ep_information_ptr->endpoint_name_ptr)
+			{
+				if(ep_information_ptr->domain_name_ptr)
+				{
+					sn_nsdl_free(ep_information_ptr->domain_name_ptr);
+					ep_information_ptr->domain_name_ptr  = 0;
+					ep_information_ptr->domain_name_len = 0;
+				}
+				return SN_NSDL_FAILURE;
+			}
+
+			memcpy(ep_information_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len);
+			ep_information_ptr->endpoint_name_len = endpoint_info_ptr->endpoint_name_len;
+
+		}
+	}
+
+	return status;
+}
+
+int8_t sn_nsdl_unregister_endpoint(void)
+{
+	/* Local variables */
+	sn_coap_hdr_s  	*unregister_message_ptr;
+	uint8_t			*temp_ptr = 0;
+
+	/* Check that EP have been registered */
+	if(sn_nsdl_is_ep_registered())
+	{
+
+		/* Memory allocation for unregister message */
+		unregister_message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+		if(!unregister_message_ptr)
+			return SN_NSDL_FAILURE;
+
+		memset(unregister_message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+		/* Fill unregister message */
+		unregister_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
+		unregister_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_DELETE;
+
+		unregister_message_ptr->uri_path_len = (RESOURCE_DIR_LEN + 1 + ep_information_ptr->domain_name_len + 1 + ep_information_ptr->endpoint_name_len);
+		unregister_message_ptr->uri_path_ptr = sn_nsdl_alloc(unregister_message_ptr->uri_path_len);
+		if (!unregister_message_ptr->uri_path_ptr)
+		{
+			sn_coap_parser_release_allocated_coap_msg_mem(unregister_message_ptr);
+			return SN_NSDL_FAILURE;
+		}
+
+		temp_ptr = unregister_message_ptr->uri_path_ptr;
+
+		memcpy(temp_ptr,resource_path_ptr, RESOURCE_DIR_LEN);
+		temp_ptr += RESOURCE_DIR_LEN;
+
+		*temp_ptr++ = '/';
+
+		memcpy(temp_ptr ,ep_information_ptr->domain_name_ptr, ep_information_ptr->domain_name_len);
+		temp_ptr += ep_information_ptr->domain_name_len;
+
+		*temp_ptr++ = '/';
+
+		memcpy(temp_ptr ,ep_information_ptr->endpoint_name_ptr, ep_information_ptr->endpoint_name_len);
+
+		/* Send message */
+		sn_nsdl_internal_coap_send(unregister_message_ptr, nsp_address_ptr, SN_NSDL_MSG_UNREGISTER);
+
+		/* Free memory */
+		sn_coap_parser_release_allocated_coap_msg_mem(unregister_message_ptr);
+
+	}
+
+	return SN_NSDL_SUCCESS;
+}
+
+int8_t sn_nsdl_update_registration (sn_nsdl_ep_parameters_s *endpoint_info_ptr)
+{
+	/* Local variables */
+	sn_coap_hdr_s 	*register_message_ptr;
+	uint8_t			*temp_ptr;
+
+	/*** Build endpoint register update message ***/
+
+	/* Allocate memory for header struct */
+	register_message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(register_message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	memset(register_message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	/* Fill message fields -> confirmable post to specified NSP path */
+	register_message_ptr->msg_type 	= 	COAP_MSG_TYPE_CONFIRMABLE;
+	register_message_ptr->msg_code 	= 	COAP_MSG_CODE_REQUEST_PUT;
+
+	register_message_ptr->uri_path_len 	= 	sizeof(resource_path_ptr) + ep_information_ptr->domain_name_len + ep_information_ptr->endpoint_name_len + 2; 	// = rd/domain/endpoint
+
+	register_message_ptr->uri_path_ptr 	= 	sn_nsdl_alloc(register_message_ptr->uri_path_len);
+	if(!register_message_ptr->uri_path_ptr)
+	{
+		sn_coap_parser_release_allocated_coap_msg_mem(register_message_ptr);
+		return SN_NSDL_FAILURE;
+	}
+
+	temp_ptr = register_message_ptr->uri_path_ptr;
+
+	/* rd/ */
+	memcpy(temp_ptr, resource_path_ptr, sizeof(resource_path_ptr));
+	temp_ptr += sizeof(resource_path_ptr);
+	*temp_ptr++ = '/';
+
+	/* rd/DOMAIN/ */
+	memcpy(temp_ptr, ep_information_ptr->domain_name_ptr, ep_information_ptr->domain_name_len);
+	temp_ptr += ep_information_ptr->domain_name_len;
+	*temp_ptr++ = '/';
+
+	/* rd/domain/ENDPOINT */
+	memcpy(temp_ptr, ep_information_ptr->endpoint_name_ptr, ep_information_ptr->endpoint_name_len);
+
+
+	/* Allocate memory for the extended options list */
+	register_message_ptr->options_list_ptr = sn_nsdl_alloc(sizeof(sn_coap_options_list_s));
+	if(register_message_ptr->options_list_ptr == NULL)
+	{
+		sn_coap_parser_release_allocated_coap_msg_mem(register_message_ptr);
+		return SN_NSDL_FAILURE;
+	}
+
+	memset(register_message_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
+
+	/* Fill Uri-query options */
+	sn_nsdl_fill_uri_query_options(endpoint_info_ptr, register_message_ptr, SN_NSDL_EP_UPDATE_MESSAGE);
+
+	/* Build and send coap message to NSP */
+	sn_nsdl_internal_coap_send(register_message_ptr, nsp_address_ptr, SN_NSDL_MSG_UPDATE);
+
+	if(register_message_ptr->payload_ptr)
+		sn_nsdl_free(register_message_ptr->payload_ptr);
+	sn_coap_parser_release_allocated_coap_msg_mem(register_message_ptr);
+
+	return SN_NSDL_SUCCESS;
+}
+
+int8_t sn_nsdl_send_eventing_message (uint8_t *event_name_ptr, uint16_t event_name_len, uint8_t *message_body_ptr, uint16_t message_body_len)
+{
+	sn_coap_hdr_s 	*eventing_message_ptr;
+	int8_t			status = 0;
+
+	/* Allocate and initialize memory for header struct */
+	eventing_message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(eventing_message_ptr == NULL)
+		return SN_NSDL_FAILURE;
+
+	memset(eventing_message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	/* Fill header */
+	eventing_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
+	eventing_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;
+
+	/* Fill uri path option */
+	eventing_message_ptr->uri_path_len = sizeof(event_path_parameter) + event_name_len;
+	eventing_message_ptr->uri_path_ptr = sn_nsdl_alloc(eventing_message_ptr->uri_path_len);
+
+	if(!eventing_message_ptr->uri_path_ptr)
+	{
+		sn_coap_parser_release_allocated_coap_msg_mem(eventing_message_ptr);
+		return SN_NSDL_FAILURE;
+	}
+
+	memcpy(eventing_message_ptr->uri_path_ptr, event_path_parameter, sizeof(event_path_parameter));
+	memcpy(eventing_message_ptr->uri_path_ptr + sizeof(event_path_parameter), event_name_ptr, event_name_len);
+
+	/* Fill payload */
+	eventing_message_ptr->payload_len = message_body_len;
+	eventing_message_ptr->payload_ptr = message_body_ptr;
+
+	/* Send coap message */
+	status = sn_nsdl_internal_coap_send(eventing_message_ptr, nsp_address_ptr, SN_NSDL_MSG_EVENT);
+
+	eventing_message_ptr->payload_ptr = NULL;
+
+	sn_coap_parser_release_allocated_coap_msg_mem(eventing_message_ptr);
+
+	return status;
+}
+
+void sn_nsdl_nsp_lost(void)
+{
+	sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED;
+	return;
+}
+
+int8_t sn_nsdl_is_ep_registered(void)
+{
+
+	return sn_nsdl_endpoint_registered;
+}
+
+uint16_t sn_nsdl_send_observation_notification(uint8_t *token_ptr, uint8_t token_len,
+													uint8_t *payload_ptr, uint16_t payload_len,
+													uint8_t *observe_ptr, uint8_t observe_len,
+													sn_coap_msg_type_e message_type, uint8_t content_type)
+{
+	sn_coap_hdr_s 	*notification_message_ptr;
+	uint16_t		return_msg_id = 0;
+
+	/* Allocate and initialize memory for header struct */
+	notification_message_ptr = sn_nsdl_alloc(sizeof(sn_coap_hdr_s));
+	if(notification_message_ptr == NULL)
+		return 0;
+
+	memset(notification_message_ptr, 0, sizeof(sn_coap_hdr_s));
+
+	notification_message_ptr->options_list_ptr = sn_nsdl_alloc(sizeof(sn_coap_options_list_s));
+	if(notification_message_ptr->options_list_ptr  == NULL)
+	{
+		sn_nsdl_free(notification_message_ptr);
+		return 0;
+	}
+
+	memset(notification_message_ptr->options_list_ptr , 0, sizeof(sn_coap_options_list_s));
+
+	/* Fill header */
+	notification_message_ptr->msg_type = message_type;
+	notification_message_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
+
+	/* Fill token */
+	notification_message_ptr->token_len = token_len;
+	notification_message_ptr->token_ptr = token_ptr;
+
+	/* Fill payload */
+	notification_message_ptr->payload_len = payload_len;
+	notification_message_ptr->payload_ptr = payload_ptr;
+
+	/* Fill observe */
+	notification_message_ptr->options_list_ptr->observe_len = observe_len;
+	notification_message_ptr->options_list_ptr->observe_ptr = observe_ptr;
+
+	/* Fill content type */
+	if(content_type)
+	{
+		notification_message_ptr->content_type_len = 1;
+		notification_message_ptr->content_type_ptr = &content_type;
+	}
+
+	/* Send message */
+	if(sn_grs_send_coap_message(nsp_address_ptr,notification_message_ptr) == SN_NSDL_FAILURE)
+		return_msg_id = 0;
+	else
+		return_msg_id = notification_message_ptr->msg_id;
+
+	/* Free memory */
+
+	notification_message_ptr->payload_ptr = NULL;
+	notification_message_ptr->options_list_ptr->observe_ptr = NULL;
+	notification_message_ptr->token_ptr = NULL;
+	notification_message_ptr->content_type_ptr = NULL;
+
+	sn_coap_parser_release_allocated_coap_msg_mem(notification_message_ptr);
+
+	return return_msg_id;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * */
+/* 			GRS Wrapper					   */
+/* These are documented in sn_grs.c - file */
+/* * * * * * * * * * * * * * * * * * * * * */
+
+int16_t sn_nsdl_get_capability(void)
+{
+	return sn_grs_get_capability();
+}
+
+
+uint32_t sn_nsdl_get_version(void)
+{
+	return sn_grs_get_version();
+}
+
+
+int8_t sn_nsdl_process_http(uint8_t *packet_ptr, uint16_t *packet_len_ptr, sn_nsdl_addr_s *src_ptr)
+{
+	return sn_grs_process_http(packet_ptr, packet_len_ptr, src_ptr);
+}
+
+
+int8_t sn_nsdl_process_coap(uint8_t *packet_ptr, uint16_t packet_len_ptr, sn_nsdl_addr_s *src_ptr)
+{
+	return sn_grs_process_coap(packet_ptr, packet_len_ptr, src_ptr);
+}
+
+int8_t sn_nsdl_exec(uint32_t time)
+{
+	return sn_grs_exec(time);
+}
+
+int8_t sn_nsdl_create_resource(sn_nsdl_resource_info_s *res_ptr)
+{
+	return sn_grs_create_resource(res_ptr);
+}
+
+int8_t sn_nsdl_update_resource(sn_nsdl_resource_info_s *res_ptr)
+{
+	return sn_grs_update_resource(res_ptr);
+}
+
+int8_t sn_nsdl_delete_resource(uint8_t pathlen, uint8_t *path_ptr)
+{
+	return sn_grs_delete_resource(pathlen, path_ptr);
+}
+
+sn_nsdl_resource_info_s *sn_nsdl_get_resource(uint16_t pathlen, uint8_t *path_ptr)
+{
+	return sn_grs_get_resource(pathlen, path_ptr);
+}
+
+sn_grs_resource_list_s *sn_nsdl_list_resource(uint16_t pathlen, uint8_t *path_ptr)
+{
+	return sn_grs_list_resource(pathlen, path_ptr);
+}
+
+int8_t sn_nsdl_send_coap_message(sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr)
+{
+	return sn_grs_send_coap_message(address_ptr, coap_hdr_ptr);
+}
+
+/********************/
+/* Static functions */
+/********************/
+
+
+/**
+ * \fn static int8_t sn_nsdl_send_coap_message(sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr, uint8_t message_description)
+ *
+ *
+ * \brief To send NSDL messages. Stores message id?s and message description to catch response from NSP server
+ *
+ * \param	*coap_header_ptr	Pointer to the CoAP message header to be sent
+ * \param	*dst_addr_ptr		Pointer to the address structure that contains destination address information
+ * \param	message_description Message description to be stored to list for waiting response
+ *
+ * \return		SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+static int8_t sn_nsdl_internal_coap_send(sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr, uint8_t message_description)
+{
+	uint8_t 					*coap_message_ptr 	= NULL;
+	uint16_t 					coap_message_len 	= 0;
+	int16_t 						status 				= 0;
+
+	coap_message_len = sn_coap_builder_calc_needed_packet_data_size(coap_header_ptr);
+
+	if(coap_message_len == 0)
+		return SN_NSDL_FAILURE;
+
+	coap_message_ptr = sn_nsdl_alloc(coap_message_len);
+	if(!coap_message_ptr)
+		return SN_NSDL_FAILURE;
+
+	/* Build message */
+	status = sn_coap_protocol_build(dst_addr_ptr,coap_message_ptr, coap_header_ptr);
+
+	/* If message building failed */
+	if(status < 0)
+	{
+		sn_nsdl_free(coap_message_ptr);
+		return SN_NSDL_FAILURE;
+	}
+
+	/* If mesage type is confirmable, save it to list to wait for reply */
+	if(coap_header_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE)
+	{
+		sn_nsdl_sent_messages_s *message_ptr = sn_nsdl_alloc(sizeof(sn_nsdl_sent_messages_s));
+		if(message_ptr)
+		{
+			if(sn_linked_list_count_nodes(message_list_ptr) >= SN_NSDL_MAX_MESSAGE_COUNT)
+			{
+				sn_nsdl_sent_messages_s *message_temp_ptr = sn_linked_list_get_last_node(message_list_ptr);
+				if(message_temp_ptr)
+					sn_nsdl_free(message_temp_ptr);
+				sn_linked_list_remove_current_node(message_list_ptr);
+			}
+
+			message_ptr->message_type = message_description;
+			message_ptr->msg_id_number = coap_header_ptr->msg_id;
+			sn_linked_list_add_node(message_list_ptr, (void*)message_ptr);
+
+			status = SN_NSDL_SUCCESS;
+		}
+		else
+		{
+			status = SN_NSDL_FAILURE;
+		}
+
+	}
+
+	sn_nsdl_tx_callback(SN_NSDL_PROTOCOL_COAP, coap_message_ptr, coap_message_len, dst_addr_ptr);
+	sn_nsdl_free(coap_message_ptr);
+
+	return status;
+}
+
+/**
+ * \fn static void sn_nsdl_resolve_nsp_address(void)
+ *
+ * \brief Resolves NSP server address.
+ *
+ * \note Application must set NSP address with set_nsp_address
+ */
+static void sn_nsdl_resolve_nsp_address(void)
+{
+	/* Local variables */
+	if(!nsp_address_ptr)
+	{
+		//allocate only if previously not allocated
+		nsp_address_ptr = sn_nsdl_alloc(sizeof(sn_nsdl_addr_s));
+	}
+
+	if(nsp_address_ptr)
+	{
+		memset(nsp_address_ptr, 0, sizeof(sn_nsdl_addr_s));
+		/* This is only for version 0.5 */
+		nsp_address_ptr->type = SN_NSDL_ADDRESS_TYPE_NONE;
+	}
+
+	/* Todo: get NSP address */
+}
+
+/**
+ * \fn static int8_t sn_nsdl_build_registration_body(sn_coap_hdr_s *message_ptr)
+ *
+ * \brief 	To build GRS resources to registration message payload
+ *
+ * \param	*message_ptr Pointer to CoAP message header
+ *
+ * \return	SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+int8_t sn_nsdl_build_registration_body(sn_coap_hdr_s *message_ptr, uint8_t updating_registeration)
+{
+	/* Local variables */
+	uint8_t					*temp_ptr;
+	sn_nsdl_resource_info_s 	*resource_temp_ptr;
+
+
+	/* Get list of resources */
+
+
+	/* Calculate needed memory and allocate */
+	message_ptr->payload_len = sn_nsdl_calculate_registration_body_size(updating_registeration);
+
+	/* If no resources to be registered, return SN_NSDL_SUCCESS */
+	if(!message_ptr->payload_len)
+	{
+		return SN_NSDL_SUCCESS;
+	}
+
+	message_ptr->payload_ptr = sn_nsdl_alloc(message_ptr->payload_len);
+	if(!message_ptr->payload_ptr)
+	{
+		return SN_NSDL_FAILURE;
+	}
+
+	/* Build message */
+	temp_ptr = message_ptr->payload_ptr;
+
+	resource_temp_ptr = sn_grs_get_first_resource();
+
+	/* Loop trough all resources */
+	while(resource_temp_ptr)
+	{
+
+		/* if resource needs to be registered */
+		if(resource_temp_ptr->resource_parameters_ptr)
+		{
+
+			if(updating_registeration && resource_temp_ptr->resource_parameters_ptr->registered == SN_NDSL_RESOURCE_REGISTERED)
+			{
+				resource_temp_ptr = sn_grs_get_next_resource();
+				continue;
+			}
+			else
+			{
+				resource_temp_ptr->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_REGISTERING;
+			}
+
+			/* If not first resource, add '.' to separator */
+			if(temp_ptr != message_ptr->payload_ptr)
+				*temp_ptr++ = ',';
+
+			*temp_ptr++ = '<';
+			*temp_ptr++ = '/';
+			memcpy(temp_ptr, resource_temp_ptr->path, resource_temp_ptr->pathlen);
+			temp_ptr += resource_temp_ptr->pathlen;
+			*temp_ptr++ = '>';
+
+			/* Resource attributes */
+			if(resource_temp_ptr->resource_parameters_ptr->resource_type_len)
+			{
+				*temp_ptr++ = ';';
+				memcpy(temp_ptr, resource_type_parameter, RT_PARAMETER_LEN);
+				temp_ptr += RT_PARAMETER_LEN;
+				*temp_ptr++ = '"';
+				memcpy(temp_ptr, resource_temp_ptr->resource_parameters_ptr->resource_type_ptr, resource_temp_ptr->resource_parameters_ptr->resource_type_len);
+				temp_ptr += resource_temp_ptr->resource_parameters_ptr->resource_type_len;
+				*temp_ptr++ = '"';
+			}
+
+			if(resource_temp_ptr->resource_parameters_ptr->interface_description_len)
+			{
+				*temp_ptr++ = ';';
+				memcpy(temp_ptr, if_description_parameter, IF_PARAMETER_LEN);
+				temp_ptr += IF_PARAMETER_LEN;
+				*temp_ptr++ = '"';
+				memcpy(temp_ptr, resource_temp_ptr->resource_parameters_ptr->interface_description_ptr, resource_temp_ptr->resource_parameters_ptr->interface_description_len);
+				temp_ptr += resource_temp_ptr->resource_parameters_ptr->interface_description_len;
+				*temp_ptr++ = '"';
+			}
+
+			if(resource_temp_ptr->resource_parameters_ptr->coap_content_type != 0)
+			{
+				*temp_ptr++ = ';';
+				memcpy(temp_ptr, coap_con_type_parameter, COAP_CON_PARAMETER_LEN);
+				temp_ptr += COAP_CON_PARAMETER_LEN;
+				*temp_ptr++ = '"';
+				temp_ptr = sn_nsdl_itoa(temp_ptr, resource_temp_ptr->resource_parameters_ptr->coap_content_type);
+				*temp_ptr++ = '"';
+			}
+
+			/* ;obs */
+			if(resource_temp_ptr->resource_parameters_ptr->observable)
+			{
+				*temp_ptr++ = ';';
+				memcpy(temp_ptr, obs_parameter, OBS_PARAMETER_LEN);
+				temp_ptr += OBS_PARAMETER_LEN;
+			}
+
+			/* ;aobs;id= */
+			/* todo: aosb not supported ATM - needs fixing */
+			/*
+			if((resource_temp_ptr->resource_parameters_ptr->auto_obs_len > 0 && resource_temp_ptr->resource_parameters_ptr->auto_obs_len <= 8) &&
+					resource_temp_ptr->resource_parameters_ptr->auto_obs_ptr)
+			{
+				uint8_t i = 0;
+
+				*temp_ptr++ = ';';
+				memcpy(temp_ptr, aobs_parameter, AOBS_PARAMETER_LEN);
+				temp_ptr += AOBS_PARAMETER_LEN;
+
+				while(i < resource_temp_ptr->resource_parameters_ptr->auto_obs_len)
+				{
+					temp_ptr = sn_nsdl_itoa(temp_ptr, *(resource_temp_ptr->resource_parameters_ptr->auto_obs_ptr + i));
+					i++;
+				}
+			}
+			*/
+
+		}
+
+		resource_temp_ptr = sn_grs_get_next_resource();
+
+	}
+
+	return SN_NSDL_SUCCESS;
+}
+
+/**
+ * \fn static uint16_t sn_nsdl_calculate_registration_body_size(sn_grs_resource_list_s *grs_resources_list_ptr)
+ *
+ *
+ * \brief	Calculates registration message payload size
+ *
+ * \param	*grs_resources_list_ptr Pointer to list of GRS resources
+ *
+ * \return	Needed payload size
+ */
+static uint16_t sn_nsdl_calculate_registration_body_size(uint8_t updating_registeration)
+{
+	/* Local variables */
+	uint16_t return_value = 0;
+	sn_nsdl_resource_info_s *resource_temp_ptr;
+
+	/* check pointer */
+
+	resource_temp_ptr = sn_grs_get_first_resource();
+
+	while(resource_temp_ptr)
+	{
+
+		if(resource_temp_ptr->resource_parameters_ptr)
+		{
+
+			if(updating_registeration && resource_temp_ptr->resource_parameters_ptr->registered == SN_NDSL_RESOURCE_REGISTERED)
+			{
+				resource_temp_ptr = sn_grs_get_next_resource();
+				continue;
+			}
+
+			/* If not first resource, then '.' will be added */
+			if(return_value)
+				return_value++;
+
+			/* Count length for the resource path </path> */
+			return_value +=	(3 + resource_temp_ptr->pathlen);
+
+			/* Count lengths of the attributes */
+
+			/* Resource type parameter */
+			if(resource_temp_ptr->resource_parameters_ptr->resource_type_len)
+			{
+				/* ;rt="restype" */
+				return_value += (6 + resource_temp_ptr->resource_parameters_ptr->resource_type_len);
+			}
+
+			/* Interface description parameter */
+			if(resource_temp_ptr->resource_parameters_ptr->interface_description_len)
+			{
+				/* ;if="iftype" */
+				return_value += (6 + resource_temp_ptr->resource_parameters_ptr->interface_description_len);
+			}
+
+			if(resource_temp_ptr->resource_parameters_ptr->coap_content_type != 0)
+			{
+				/* ;if="content" */
+				return_value += 6; // all but not content
+				return_value += sn_nsdl_itoa_len(resource_temp_ptr->resource_parameters_ptr->coap_content_type);
+			}
+
+			if(resource_temp_ptr->resource_parameters_ptr->observable)
+			{
+				/* ;obs */
+				return_value += 4;
+			}
+			/*todo: aobs not supported ATM - needs fixing*/
+			/*
+			if((resource_temp_ptr->resource_parameters_ptr->auto_obs_len > 0 && resource_temp_ptr->resource_parameters_ptr->auto_obs_len <= 8) &&
+					resource_temp_ptr->resource_parameters_ptr->auto_obs_ptr)
+			{
+				uint8_t i = resource_temp_ptr->resource_parameters_ptr->auto_obs_len;
+				// ;aobs;id=
+				return_value += 9;
+				while(i--)
+				{
+					return_value += sn_nsdl_itoa_len(*(resource_temp_ptr->resource_parameters_ptr->auto_obs_ptr + i));
+				}
+			}
+			*/
+
+		}
+
+		resource_temp_ptr = sn_grs_get_next_resource();
+
+	}
+
+	return return_value;
+
+}
+
+/**
+ * \fn static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type)
+ *
+ *
+ * \brief Calculates needed uri query option length
+ *
+ * \param *endpoint_info_ptr 	Pointer to endpoint info structure
+ * \param msg_type				Message type
+ *
+ * \return	SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type)
+{
+	uint8_t return_value = 0;
+	uint8_t number_of_parameters = 0;
+
+
+	if((endpoint_info_ptr->endpoint_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && endpoint_info_ptr->endpoint_name_ptr != 0)
+	{
+		return_value += endpoint_info_ptr->endpoint_name_len;
+		return_value += 2;		//h=
+		number_of_parameters++;
+	}
+
+	if((endpoint_info_ptr->type_len != 0) && (endpoint_info_ptr->type_ptr != 0))
+	{
+		return_value+=endpoint_info_ptr->type_len;
+		return_value += 3;
+		number_of_parameters++;
+	}
+
+	if((endpoint_info_ptr->lifetime_len != 0) && (endpoint_info_ptr->lifetime_ptr != 0))
+	{
+		return_value+=endpoint_info_ptr->lifetime_len;
+		return_value += 3;
+		number_of_parameters++;
+	}
+
+	if(number_of_parameters != 0)
+		return_value += (number_of_parameters - 1);
+
+	return return_value;
+}
+
+/**
+ * \fn static int8_t sn_nsdl_fill_uri_query_options(sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type)
+ *
+ *
+ * \brief Fills uri-query options to message header struct
+ *
+ * \param *parameter_ptr 	Pointer to endpoint parameters struct
+ * \param *source_msg_ptr	Pointer to CoAP header struct
+ * \param msg_type			Message type
+ *
+ * \return	SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+static int8_t sn_nsdl_fill_uri_query_options(sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type)
+{
+	uint8_t *temp_ptr = NULL;
+	source_msg_ptr->options_list_ptr->uri_query_len  = sn_nsdl_calculate_uri_query_option_len(parameter_ptr, msg_type);
+
+	if(source_msg_ptr->options_list_ptr->uri_query_len == 0)
+		return 0;
+
+	source_msg_ptr->options_list_ptr->uri_query_ptr 	= 	sn_nsdl_alloc(source_msg_ptr->options_list_ptr->uri_query_len);
+
+	if (source_msg_ptr->options_list_ptr->uri_query_ptr == NULL)
+			return SN_NSDL_FAILURE;
+
+	temp_ptr = source_msg_ptr->options_list_ptr->uri_query_ptr;
+
+	/******************************************************/
+	/* If endpoint name is configured, fill needed fields */
+	/******************************************************/
+
+	if((parameter_ptr->endpoint_name_len != 0) && (parameter_ptr->endpoint_name_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE))
+	{
+		/* fill endpoint name, first ?h=, then endpoint name */
+		memcpy(temp_ptr, ep_name_parameter_string, sizeof(ep_name_parameter_string));
+		temp_ptr += EP_NAME_PARAMETERS_LEN;
+		memcpy(temp_ptr, parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len);
+		temp_ptr += parameter_ptr->endpoint_name_len;
+	}
+
+	/******************************************************/
+	/* If endpoint type is configured, fill needed fields */
+	/******************************************************/
+
+	if((parameter_ptr->type_len != 0) && (parameter_ptr->type_ptr != 0))
+	{
+		if(temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr)
+			*temp_ptr++ = '&';
+
+		memcpy(temp_ptr, resource_type_parameter, sizeof(resource_type_parameter));
+		temp_ptr += RT_PARAMETER_LEN;
+		memcpy(temp_ptr, parameter_ptr->type_ptr, parameter_ptr->type_len);
+		temp_ptr += parameter_ptr->type_len;
+	}
+
+
+	/******************************************************/
+	/* If lifetime is configured, fill needed fields */
+	/******************************************************/
+
+	if((parameter_ptr->lifetime_len != 0) && (parameter_ptr->lifetime_ptr != 0))
+	{
+		if(temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr)
+			*temp_ptr++ = '&';
+
+		memcpy(temp_ptr, ep_lifetime_parameter, sizeof(ep_lifetime_parameter));
+		temp_ptr += LT_PARAMETER_LEN;
+		memcpy(temp_ptr, parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len);
+		temp_ptr += parameter_ptr->lifetime_len;
+	}
+
+	return SN_NSDL_SUCCESS;
+}
+
+/**
+ * \fn static uint8_t sn_nsdl_local_rx_function(sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr)
+ *
+ * \brief If received message is reply for the message that NSDL has been sent, it is processed here. Else, packet will be sent to application.
+ *
+ * \param *coap_packet_ptr	Pointer to received CoAP packet
+ * \param *address_ptr		Pointer to source address struct
+ *
+ * \return		SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+static int8_t sn_nsdl_local_rx_function(sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr)
+{
+	int8_t 						status = 0;
+	uint16_t					number_of_messages;
+	sn_nsdl_sent_messages_s 	*sent_message_temp_ptr;
+
+	if((coap_packet_ptr == 0) || (address_ptr == 0))
+		return -1;
+
+	/* If we wait for a response to some message.. */
+	number_of_messages = sn_linked_list_count_nodes(message_list_ptr);
+
+	if(number_of_messages)
+	{
+		while(number_of_messages--)
+		{
+			sent_message_temp_ptr = sn_linked_list_get_last_node(message_list_ptr);
+
+			if(sent_message_temp_ptr)
+			{
+				if(sent_message_temp_ptr->msg_id_number == coap_packet_ptr->msg_id)
+				{
+					switch(sent_message_temp_ptr->message_type)
+					{
+					case SN_NSDL_MSG_REGISTER:
+						if(coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CREATED)
+						{
+							sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_IS_REGISTERED;
+							sn_nsdl_mark_resources_as_registered();
+							status = sn_nsdl_resolve_ep_information(coap_packet_ptr);
+							if(status != SN_NSDL_SUCCESS)
+							{
+								/* Node can be removed */
+								sn_nsdl_free(sent_message_temp_ptr);
+								sn_linked_list_remove_current_node(message_list_ptr);
+								return status;
+							}
+						}
+						break;
+					case SN_NSDL_MSG_UNREGISTER:
+						if(coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_DELETED)
+						{
+							if(ep_information_ptr->endpoint_name_ptr)
+								{
+									sn_nsdl_free(ep_information_ptr->endpoint_name_ptr);
+									ep_information_ptr->endpoint_name_ptr = 0;
+									ep_information_ptr->endpoint_name_len = 0;
+								}
+
+							if(ep_information_ptr->domain_name_ptr)
+								{
+									sn_nsdl_free(ep_information_ptr->domain_name_ptr);
+									ep_information_ptr->domain_name_ptr = 0;
+									ep_information_ptr->domain_name_len = 0;
+								}
+
+						}
+						break;
+					case SN_NSDL_MSG_EVENT:
+					case SN_NSDL_MSG_UPDATE:
+						break;
+					}
+					/* Node can be removed */
+					sn_nsdl_free(sent_message_temp_ptr);
+					sn_linked_list_remove_current_node(message_list_ptr);
+
+					sn_nsdl_rx_callback(coap_packet_ptr, address_ptr);
+					return SN_NSDL_SUCCESS;
+				}
+			}
+			sent_message_temp_ptr = sn_linked_list_get_previous_node(message_list_ptr);
+		}
+	}
+
+	/* No messages to wait for, or message was not response to our request */
+	status = sn_nsdl_rx_callback(coap_packet_ptr, address_ptr);
+
+	return status;
+}
+
+void sn_nsdl_mark_resources_as_registered(void)
+{
+
+	sn_nsdl_resource_info_s *temp_resource;
+
+	temp_resource = sn_grs_get_first_resource();
+
+	while(temp_resource)
+	{
+
+		if(temp_resource->resource_parameters_ptr->registered == SN_NDSL_RESOURCE_REGISTERING)
+		{
+
+			temp_resource->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_REGISTERED;
+
+		}
+
+		temp_resource = sn_grs_get_next_resource();
+
+	}
+
+
+}
+
+/**
+ * \fn static int8_t sn_nsdl_resolve_ep_information(sn_coap_hdr_s *coap_packet_ptr)
+ *
+ *
+ * \brief Resolves endpoint information from received CoAP message
+ *
+ * \param *coap_packet_ptr Pointer to received CoAP message
+ *
+ * \return	SN_NSDL_SUCCESS = 0, Failed = -1
+ */
+static int8_t sn_nsdl_resolve_ep_information(sn_coap_hdr_s *coap_packet_ptr)
+{
+	uint8_t		*temp_ptr;
+	uint8_t		parameter_count 	= 0;
+	uint16_t	parameter_len 		= 0;
+
+	if(!coap_packet_ptr)
+		return SN_NSDL_FAILURE;
+	if(!coap_packet_ptr->options_list_ptr)
+		return SN_NSDL_FAILURE;
+	if(!coap_packet_ptr->options_list_ptr->location_path_ptr)
+		return SN_NSDL_FAILURE;
+
+	temp_ptr = coap_packet_ptr->options_list_ptr->location_path_ptr;
+
+	while(temp_ptr <= (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len))
+	{
+
+		if((temp_ptr == (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) || (*temp_ptr == '/'))
+		{
+
+			parameter_count++;
+			if(parameter_count == 2)
+			{
+				if(!ep_information_ptr->domain_name_ptr)
+				{
+					ep_information_ptr->domain_name_len = parameter_len - 1;
+					ep_information_ptr->domain_name_ptr = sn_nsdl_alloc(ep_information_ptr->domain_name_len);
+					if(!ep_information_ptr->domain_name_ptr)
+						return SN_NSDL_FAILURE;
+					memcpy(ep_information_ptr->domain_name_ptr, temp_ptr - ep_information_ptr->domain_name_len, ep_information_ptr->domain_name_len);
+				}
+
+			}
+			if(parameter_count == 3)
+			{
+				if(!ep_information_ptr->endpoint_name_ptr)
+				{
+					ep_information_ptr->endpoint_name_len = parameter_len - 1;
+					ep_information_ptr->endpoint_name_ptr = sn_nsdl_alloc(ep_information_ptr->endpoint_name_len);
+					if(!ep_information_ptr->endpoint_name_ptr)
+					{
+						if(ep_information_ptr->domain_name_ptr)
+						{
+							sn_nsdl_free(ep_information_ptr->domain_name_ptr);
+							ep_information_ptr->domain_name_ptr = NULL;
+							ep_information_ptr->domain_name_len = 0;
+						}
+
+						return SN_NSDL_FAILURE;
+
+					}
+					memcpy(ep_information_ptr->endpoint_name_ptr, temp_ptr - ep_information_ptr->endpoint_name_len, ep_information_ptr->endpoint_name_len);
+				}
+			}
+			parameter_len = 0;
+		}
+		parameter_len++;
+		temp_ptr++;
+	}
+
+
+	return SN_NSDL_SUCCESS;
+}
+
+/**
+ * \fn int8_t set_NSP_address(uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type)
+ * \brief This function is used to set the NSP address given by an application.
+ * \param uint8_t *NSP_address Pointer to NSP address Note! IPv6 address must always be 16 bytes long and IPv4 address must always be 4 bytes long!
+ * \param uint16_t port NSP port
+ * \param sn_nsdl_addr_type_e address_type NSP address type (SN_NSDL_ADDRESS_TYPE_IPV6 or SN_NSDL_ADDRESS_TYPE_IPV4)
+ * \return 0 on success, -1 on false to indicate that NSDL internal address pointer is not allocated (call nsdl_init() first).
+ *
+ */
+int8_t set_NSP_address(uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type)
+{
+
+	/* Check parameters and source pointers */
+	if(!nsp_address_ptr || !NSP_address)
+	{
+		return -1;
+	}
+
+	nsp_address_ptr->type = address_type;
+
+	if(address_type == SN_NSDL_ADDRESS_TYPE_IPV4)
+	{
+		if(nsp_address_ptr->addr_ptr)
+		{
+			sn_nsdl_free(nsp_address_ptr->addr_ptr);
+		}
+
+		nsp_address_ptr->addr_len = 4;
+
+		nsp_address_ptr->addr_ptr = sn_nsdl_alloc(nsp_address_ptr->addr_len);
+		if(!nsp_address_ptr->addr_ptr)
+			return -1;
+
+		memcpy(nsp_address_ptr->addr_ptr, NSP_address, nsp_address_ptr->addr_len);
+		nsp_address_ptr->port = port;
+	}
+
+	else if(address_type == SN_NSDL_ADDRESS_TYPE_IPV6)
+	{
+		if(nsp_address_ptr->addr_ptr)
+		{
+			sn_nsdl_free(nsp_address_ptr->addr_ptr);
+		}
+
+		nsp_address_ptr->addr_len = 16;
+
+		nsp_address_ptr->addr_ptr = sn_nsdl_alloc(nsp_address_ptr->addr_len);
+		if(!nsp_address_ptr->addr_ptr)
+			return -1;
+
+		memcpy(nsp_address_ptr->addr_ptr, NSP_address, nsp_address_ptr->addr_len);
+		nsp_address_ptr->port = port;
+	}
+	return 0;
+}
+
+
+static uint8_t sn_nsdl_itoa_len(uint8_t value)
+{
+	uint8_t i = 0;
+
+	do
+	{
+		i++;
+	}while((value /= 10) > 0);
+
+	return i;
+}
+
+static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint8_t value)
+{
+
+	uint8_t start = 0;
+	uint8_t end = 0;
+	uint8_t i;
+
+	i = 0;
+
+	/* ITOA */
+	do
+	{
+		ptr[i++] = (value % 10) + '0';
+	}while((value /= 10) > 0);
+
+	end = i - 1;
+
+	/* reverse (part of ITOA) */
+	while(start < end)
+	{
+		uint8_t chr;
+
+		chr = ptr[start];
+		ptr[start] = ptr[end];
+		ptr[end] = chr;
+
+		start++;
+		end--;
+
+	}
+	return (ptr + i);
+}
+
diff -r aafd54b05111 -r 14a9b0f4b9d6 sn_nsdl_lib.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sn_nsdl_lib.h	Tue Feb 18 01:10:07 2014 +0000
@@ -0,0 +1,431 @@
+/**
+ * \file sn_nsdl_lib.h
+ *
+ * \brief NanoService Devices Library header file
+ *
+ *  Created on: Aug 23, 2011
+ *      Author: tero
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SN_NSDL_CONST_MEMORY_ATTRIBUTE
+
+#define SN_NSDL_ENDPOINT_NOT_REGISTERED  0
+#define SN_NSDL_ENDPOINT_IS_REGISTERED   1
+
+/**
+ * \brief Endpoint registration parameters
+ */
+typedef struct sn_nsdl_ep_parameters_
+{
+	uint8_t 	*endpoint_name_ptr;		/**< Endpoint name */
+	uint8_t  	endpoint_name_len;
+
+	uint8_t		*domain_name_ptr;		/**< Domain to register. If null, NSP uses default domain */
+	uint8_t		domain_name_len;
+
+	uint8_t 	*type_ptr;				/**< Endpoint type */
+	uint8_t 	type_len;
+
+	uint8_t		*lifetime_ptr;			/**< Endpoint lifetime in seconds. eg. "1200" = 1200 seconds */
+	uint8_t		lifetime_len;
+
+} sn_nsdl_ep_parameters_s;
+
+/**
+ * \brief For internal use
+ */
+typedef struct sn_nsdl_sent_messages_
+{
+	uint16_t	msg_id_number;
+	uint8_t		message_type;
+} sn_nsdl_sent_messages_s;
+
+/**
+ * \brief Function pointers used for memory allocation and freeing
+ */
+typedef struct sn_nsdl_mem_
+{
+	void *(*sn_nsdl_alloc)(uint16_t);
+	void (*sn_nsdl_free)(void *);
+} sn_nsdl_mem_s;
+
+/**
+ * \brief Includes resource path
+ */
+typedef struct sn_grs_resource_
+{
+	uint8_t pathlen;
+	uint8_t *path;
+} sn_grs_resource_s;
+
+/**
+ * \brief Table of created resources
+ */
+typedef struct sn_grs_resource_list_
+{
+	uint8_t res_count;					/**< Number of resources */
+	sn_grs_resource_s *res;
+} sn_grs_resource_list_s;
+
+/**
+ * \brief Resource access rights
+ */
+typedef enum sn_grs_resource_acl_
+{
+	SN_GRS_GET_ALLOWED 	= 0x01 ,
+	SN_GRS_PUT_ALLOWED 	= 0x02,
+	SN_GRS_POST_ALLOWED	= 0x04,
+	SN_GRS_DELETE_ALLOWED 	= 0x08
+} sn_grs_resource_acl_e;
+
+/**
+ * \brief Used protocol
+ */
+typedef struct sn_proto_info_
+{
+	sn_nsdl_capab_e proto;				/**< Only COAP is supported */
+} sn_proto_info_s;
+
+/**
+ * \brief Defines the resource mode
+ */
+typedef enum sn_nsdl_resource_mode_
+{
+	SN_GRS_STATIC,						/**< Static resources have some value that doesn't change */
+	SN_GRS_DYNAMIC,						/**< Dynamic resources are handled in application. Therefore one must give function callback pointer to them */
+	SN_GRS_DIRECTORY					/**< Directory resources are unused and unsupported */
+} sn_nsdl_resource_mode_e;
+
+/**
+ * \brief Resource registration parameters
+ */
+typedef struct sn_nsdl_resource_parameters_
+{
+	uint8_t		*resource_type_ptr;
+	uint16_t	resource_type_len;
+
+	uint8_t		*interface_description_ptr;
+	uint16_t	interface_description_len;
+
+	uint8_t		coap_content_type;
+
+	uint8_t		mime_content_type;
+
+	uint8_t		observable;
+
+	uint8_t		registered;
+
+}sn_nsdl_resource_parameters_s;
+
+/**
+ * \brief Defines parameters for the resource.
+ */
+typedef struct sn_nsdl_resource_info_
+{
+	sn_nsdl_resource_parameters_s 	*resource_parameters_ptr;
+
+	sn_nsdl_resource_mode_e			mode;						/**< STATIC etc.. */
+
+	uint16_t 						pathlen;					/**< Address */
+	uint8_t 						*path;
+
+	uint16_t 						resourcelen;				/**< 0 if dynamic resource, resource information in static resource */
+	uint8_t 						*resource;					/**< NULL if dynamic resource */
+
+	sn_grs_resource_acl_e 			access;
+
+	uint8_t (*sn_grs_dyn_res_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *, sn_proto_info_s *);
+
+} sn_nsdl_resource_info_s;
+
+/**
+ * \fn extern int8_t sn_nsdl_init	(uint8_t (*sn_nsdl_tx_cb)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
+ *							uint8_t (*sn_nsdl_rx_cb)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
+ *							sn_nsdl_mem_s *sn_memory)
+ *
+ * \brief Initialization function for NSDL library. Initializes NSDL, GRS, HTTP and CoAP.
+ *
+ * \param *sn_nsdl_tx_callback 	A callback function for sending messages.
+ *
+ * \param *sn_nsdl_rx_callback 	A callback function for parsed messages. If received message is not CoAP protocol message (eg. ACK), message for GRS (GET, PUT, POST, DELETE) or
+ * 								reply for some NSDL message (register message etc.), rx callback will be called.
+ *
+ * \param *sn_memory			Memory structure which includes function pointers to the allocation and free functions.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_init(uint8_t (*sn_nsdl_tx_cb)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *),
+							uint8_t (*sn_nsdl_rx_cb)(sn_coap_hdr_s *, sn_nsdl_addr_s *),
+							sn_nsdl_mem_s *sn_memory);
+
+/**
+ * \fn extern uint8_t sn_nsdl_register_endpoint(sn_nsdl_ep_parameters_s *endpoint_info_ptr)
+ *
+ * \brief Registers endpoint to NSP server.
+ *
+ * \param *endpoint_info_ptr	Contains endpoint information.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_register_endpoint(sn_nsdl_ep_parameters_s *endpoint_info_ptr);
+
+/**
+ * \fn extern int8_t sn_nsdl_unregister_endpoint(void)
+ *
+ * \brief Sends unregister-message to NSP server.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_unregister_endpoint(void);
+
+/**
+ * \fn extern int8_t sn_nsdl_update_registration(sn_nsdl_ep_parameters_s *endpoint_parameters_ptr);
+ *
+ * \brief Update the registration with NSP.
+ *
+ * \param *endpoint_info_ptr	Contains endpoint information.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_update_registration(sn_nsdl_ep_parameters_s *endpoint_parameters_ptr);
+
+/**
+ * \fn extern int8_t sn_nsdl_is_ep_registered(void)
+ *
+ * \brief Checks if endpoint is registered.
+ *
+ * \return 1 Endpoint registration is done successfully
+ * \return 0 Endpoint is not registered
+ */
+extern int8_t sn_nsdl_is_ep_registered(void);
+
+/**
+ * \fn extern void sn_nsdl_nsp_lost(void);
+ *
+ * \brief A function to inform NSDL-C library if application detects a fault in NSP registration.
+ *
+ * After calling this function sn_nsdl_is_ep_registered() will return "not registered".
+ */
+extern void sn_nsdl_nsp_lost(void);
+
+/**
+ * \fn extern uint16_t sn_nsdl_send_observation_notification(uint8_t *token_ptr, uint8_t token_len,
+ *													uint8_t *payload_ptr, uint16_t payload_len,
+ *													uint8_t *observe_ptr, uint8_t observe_len,
+ *													sn_coap_msg_type_e message_type, uint8_t content_type)
+ *
+ *
+ * \brief Sends observation message to NSP server
+ *
+ * \param	*token_ptr		Pointer to token to be used
+ * \param	token_len		Token length
+ * \param	*payload_ptr	Pointer to payload to be sent
+ * \param	payload_len		Payload length
+ * \param	*observe_ptr	Pointer to observe number to be sent
+ * \param	observe_len		Observe number len
+ * \param	message_type	Observation message type (confirmable or non-confirmable)
+ * \param	contetnt_type	Observation message payload contetnt type
+ *
+ * \return	!0	Success, observation messages message ID
+ * \return	0	Failure
+ */
+extern uint16_t sn_nsdl_send_observation_notification(uint8_t *token_ptr, uint8_t token_len,
+													uint8_t *payload_ptr, uint16_t payload_len,
+													uint8_t *observe_ptr, uint8_t observe_len,
+													sn_coap_msg_type_e message_type, uint8_t content_type);
+
+/**
+ * \fn extern int16_t sn_nsdl_get_capability(void)
+ *
+ * \brief Capability query function.
+ *
+ * Used to retrieve the list of supported protocols from the NSDL module.
+ *
+ * \return	>0	Success, supported capabilities reported using bitmask with definitions from sn_nsdl_capab_t
+ * \return	0	Success, no supported capabilities
+ */
+extern int16_t sn_nsdl_get_capability(void);
+
+/**
+ * \fn extern uint32_t sn_nsdl_get_version(void)
+ *
+ * \brief Version query function.
+ *
+ * Used to retrieve the version information structure from the NSDL library.
+ *
+ * \return	!0	MSB 2 bytes major version, LSB 2 bytes minor version.
+ * \return	0	Failure
+*/
+extern uint32_t sn_nsdl_get_version(void);
+
+/**
+ * \fn extern int8_t sn_nsdl_process_http(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src)
+ *
+ * \brief Currently HTTP is not supported
+ *
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_process_http(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src);
+
+/**
+ * \fn extern int8_t sn_nsdl_process_coap(uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src)
+ *
+ * \brief To push CoAP packet to NSDL library
+ *
+ * Used to push an CoAP packet to NSDL library for processing.
+ *
+ * \param	*packet  Pointer to a uint8_t array containing the packet (including the CoAP headers).
+ *      After successful execution this array may contain the response packet.
+ *
+ * \param	*packet_len	Pointer to length of the packet. After successful execution this array may contain the length
+ *      of the response packet.
+ *
+ * \param	*src	Pointer to packet source address information. After successful execution this array may contain
+ *      the destination address of the response packet.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_process_coap(uint8_t *packet, uint16_t packet_len, sn_nsdl_addr_s *src);
+
+/**
+ * \fn extern int8_t sn_nsdl_exec(uint32_t time);
+ *
+ * \brief CoAP retransmission function.
+ *
+ * Used to give execution time for the NSDL (CoAP) library for retransmissions. The NSDL library
+ * will call the exec functions of all enabled protocol modules.
+ *
+ * \param  time Time in seconds.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_exec(uint32_t time);
+
+/**
+ * \fn  extern int8_t sn_nsdl_create_resource(sn_nsdl_resource_info_s *res)
+ *
+ * \brief Resource creating function.
+ *
+ * Used to create a static or dynamic HTTP(S) or CoAP resource.
+ *
+ * \param	*res	Pointer to a structure of type sn_nsdl_resource_info_t that contains the information
+ *     about the resource.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ * \return	-2	Resource already exists
+ * \return	-3	Invalid path
+ * \return	-4	List adding failure
+ */
+extern int8_t sn_nsdl_create_resource(sn_nsdl_resource_info_s *res);
+
+/**
+ * \fn extern int8_t sn_nsdl_update_resource(sn_nsdl_resource_info_s *res)
+ *
+ * \brief Resource updating function.
+ *
+ * Used to update the direct value of a static resource, the callback function pointer of a dynamic resource
+ * and access rights of the recource.
+ *
+ * \param	*res	Pointer to a structure of type sn_nsdl_resource_info_t that contains the information
+ *     about the resource. Only the pathlen and path elements are evaluated along with
+ *     either resourcelen and resource or the function pointer.
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_update_resource(sn_nsdl_resource_info_s *res);
+
+/**
+ * \fn extern int8_t sn_nsdl_delete_resource(uint8_t pathlen, uint8_t *path)
+ *
+ * \brief Resource delete function.
+ *
+ * Used to delete a resource. If resource has a subresources, these all must also be removed.
+ *
+ * \param	pathlen		Contains the length of the path that is to be deleted (excluding possible trailing "\0").
+ *
+ * \param	*path_ptr	A pointer to an array containing the path.
+ *
+ * \return	0	Success
+ * \return	-1	Failure (No such resource)
+ */
+extern int8_t sn_nsdl_delete_resource(uint8_t pathlen, uint8_t *path);
+
+/**
+ * \fn extern sn_nsdl_resource_info_s *sn_nsdl_get_resource(uint16_t pathlen, uint8_t *path)
+ *
+ * \brief Resource get function.
+ *
+ * Used to get a resource.
+ *
+ * \param	pathlen	Contains the length of the path that is to be returned (excluding possible trailing '\0').
+ *
+ * \param	*path	A pointer to an array containing the path.
+ *
+ * \return	!NULL	Success, pointer to a sn_nsdl_resource_info_s that contains the resource information\n
+ * \return	NULL	Failure
+ */
+extern sn_nsdl_resource_info_s *sn_nsdl_get_resource(uint16_t pathlen, uint8_t *path);
+
+/**
+ * \fn extern sn_grs_resource_list_s *sn_nsdl_list_resource(uint16_t pathlen, uint8_t *path)
+ *
+ * \brief Resource list function.
+ *
+ * \param	pathlen	Contains the length of the target path (excluding possible trailing '\0').
+ *     The length value is not examined if the path itself is a NULL pointer.
+ *
+ * \param	*path	A pointer to an array containing the path or a NULL pointer.
+ *
+ * \return	!NULL	A pointer to a sn_grs_resource_list_s structure containing the resource listing.
+ * \return	NULL	Failure with an unspecified error
+ */
+extern sn_grs_resource_list_s *sn_nsdl_list_resource(uint16_t pathlen, uint8_t *path);
+
+/**
+ * \fn extern int8_t sn_nsdl_send_coap_message(sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
+ *
+ * \brief Send an outgoing CoAP request.
+ *
+ * \param	*address_ptr	Pointer to source address struct
+ *
+ * \param	*coap_hdr_ptr	Pointer to CoAP message to be sent
+ *
+ * \return	0	Success
+ * \return	-1	Failure
+ */
+extern int8_t sn_nsdl_send_coap_message(sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr);
+
+/**
+ * \fn extern int8_t set_NSP_address(uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type);
+ *
+ * \brief This function is used to set the NSP address given by an application.
+ *
+ * \return	0	Success
+ * \return	-1	Failed to indicate that NSDL internal address pointer is not allocated (call nsdl_init() first).
+ */
+extern int8_t set_NSP_address(uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type);
+
+/**
+ * \fn extern int8_t sn_nsdl_destroy(void);
+ *
+ * \brief This function releases all allocated memory in nsdl and grs modules.
+ */
+extern int8_t sn_nsdl_destroy(void);
+
+#ifdef __cplusplus
+}
+#endif
+