Challenge : Create server requried in Question#3
[apps/native/position-finder-server.git] / src / connectivity.c
index 7522fb7..09b9c30 100644 (file)
@@ -1,38 +1,40 @@
 /*
- * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Contact: Jin Yoon <jinny.yoon@samsung.com>
  *          Geunsun Lee <gs86.lee@samsung.com>
  *          Eunyoung Lee <ey928.lee@samsung.com>
  *          Junkyu Han <junkyu.han@samsung.com>
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Flora License, Version 1.1 (the License);
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://floralicense.org/license/
  *
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
+ * distributed under the License is distributed on an AS IS BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
+#include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <glib.h>
 #include <Eina.h>
-
-#include <iotcon.h>
+#include <app_common.h>
 
 #include "log.h"
 #include "connectivity.h"
 
-#define ULTRASONIC_RESOURCE_1_URI "/door/1"
-#define ULTRASONIC_RESOURCE_2_URI "/door/2"
-#define ULTRASONIC_RESOURCE_TYPE "org.tizen.door"
+#define DEVICE_NAME "Dr.Evil's device"
+#define BUFSIZE 1024
+#define URI_PATH_LEN 64
+#define URI_PATH "/door/1"
+#define PATH "path"
 
-static bool _resource_created;
 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
 
 static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result)
@@ -67,14 +69,14 @@ static void _destroy_representation(iotcon_representation_h representation)
        iotcon_representation_destroy(representation);
 }
 
-static iotcon_representation_h _create_representation_with_attribute(iotcon_resource_h res, bool value)
+static iotcon_representation_h _create_representation_with_bool(connectivity_resource_s *resource_info, const char *key, bool value)
 {
        iotcon_attributes_h attributes = NULL;
        iotcon_representation_h representation = NULL;
        char *uri_path = NULL;
        int ret = -1;
 
-       ret = iotcon_resource_get_uri_path(res, &uri_path);
+       ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
        retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
        ret = iotcon_representation_create(&representation);
@@ -86,7 +88,10 @@ static iotcon_representation_h _create_representation_with_attribute(iotcon_reso
        ret = iotcon_representation_set_uri_path(representation, uri_path);
        goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       ret = iotcon_attributes_add_bool(attributes, "opened", value);
+       ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_attributes_add_bool(attributes, key, value);
        goto_if(IOTCON_ERROR_NONE != ret, error);
 
        ret = iotcon_representation_set_attributes(representation, attributes);
@@ -103,84 +108,142 @@ error:
        return NULL;
 }
 
-static int _handle_get_request(iotcon_resource_h res, iotcon_request_h request)
+static iotcon_representation_h _create_representation_with_int(connectivity_resource_s *resource_info, const char *key, int value)
 {
-       iotcon_representation_h representation;
+       iotcon_attributes_h attributes = NULL;
+       iotcon_representation_h representation = NULL;
+       char *uri_path = NULL;
        int ret = -1;
-       int value = 1;
 
-       /* FIXME : We need to check the value of sensors */
-       representation = _create_representation_with_attribute(res, (bool)value);
-       retv_if(!representation, -1);
+       ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       ret = _send_response(request, representation, IOTCON_RESPONSE_OK);
-       goto_if(0 != ret, error);
+       ret = iotcon_representation_create(&representation);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       _destroy_representation(representation);
+       ret = iotcon_attributes_create(&attributes);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       return 0;
+       ret = iotcon_representation_set_uri_path(representation, uri_path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_attributes_add_int(attributes, key, value);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_representation_set_attributes(representation, attributes);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       iotcon_attributes_destroy(attributes);
+
+       return representation;
 
 error:
-       _destroy_representation(representation);
-       return -1;
+       if (attributes) iotcon_attributes_destroy(attributes);
+       if (representation) iotcon_representation_destroy(representation);
+
+       return NULL;
 }
 
-static int _get_value_from_representation(iotcon_representation_h representation, bool *value)
+static iotcon_representation_h _create_representation_with_double(connectivity_resource_s *resource_info, const char *key, double value)
 {
-       iotcon_attributes_h attributes;
+       iotcon_attributes_h attributes = NULL;
+       iotcon_representation_h representation = NULL;
+       char *uri_path = NULL;
        int ret = -1;
 
-       ret = iotcon_representation_get_attributes(representation, &attributes);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       ret = iotcon_attributes_get_bool(attributes, "opened", value);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       ret = iotcon_representation_create(&representation);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       return 0;
-}
+       ret = iotcon_attributes_create(&attributes);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-static int _set_value_into_thing(iotcon_representation_h representation, bool value)
-{
-       /* FIXME : We need to set the value into the thing */
-       return 0;
+       ret = iotcon_representation_set_uri_path(representation, uri_path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_attributes_add_double(attributes, key, value);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       ret = iotcon_representation_set_attributes(representation, attributes);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
+
+       iotcon_attributes_destroy(attributes);
+
+       return representation;
+
+error:
+       if (attributes) iotcon_attributes_destroy(attributes);
+       if (representation) iotcon_representation_destroy(representation);
+
+       return NULL;
 }
 
-static int _handle_put_request(connectivity_resource_s *resource_info, iotcon_request_h request)
+static iotcon_representation_h _create_representation_with_str(connectivity_resource_s *resource_info, const char *key, char *value)
 {
-       iotcon_representation_h req_repr, resp_repr;
+       iotcon_attributes_h attributes = NULL;
+       iotcon_representation_h representation = NULL;
+       char *uri_path = NULL;
        int ret = -1;
-       bool value = false;
 
-       _D("PUT request");
+       ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       ret = iotcon_request_get_representation(request, &req_repr);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       ret = iotcon_representation_create(&representation);
+       retv_if(IOTCON_ERROR_NONE != ret, NULL);
 
-       ret = _get_value_from_representation(req_repr, &value);
-       retv_if(0 != ret, -1);
+       ret = iotcon_attributes_create(&attributes);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       ret = _set_value_into_thing(req_repr, value);
-       retv_if(0 != ret, -1);
+       ret = iotcon_representation_set_uri_path(representation, uri_path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       resp_repr = _create_representation_with_attribute(resource_info->res, (bool)value);
-       retv_if(NULL == resp_repr, -1);
+       ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       ret = _send_response(request, resp_repr, IOTCON_RESPONSE_OK);
-       goto_if(0 != ret, error);
+       ret = iotcon_attributes_add_str(attributes, key, value);
+       goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       ret = iotcon_resource_notify(resource_info->res, resp_repr, resource_info->observers, IOTCON_QOS_HIGH);
+       ret = iotcon_representation_set_attributes(representation, attributes);
        goto_if(IOTCON_ERROR_NONE != ret, error);
 
-       _destroy_representation(resp_repr);
+       iotcon_attributes_destroy(attributes);
 
-       return 0;
+       return representation;
 
 error:
-       _destroy_representation(resp_repr);
-       return -1;
+       if (attributes) iotcon_attributes_destroy(attributes);
+       if (representation) iotcon_representation_destroy(representation);
+
+       return NULL;
 }
 
-int connectivity_notify(connectivity_resource_s *resource_info, int value)
+static void _print_iotcon_error(int err_no)
+{
+       switch (err_no) {
+       case IOTCON_ERROR_NOT_SUPPORTED:
+               _E("IOTCON_ERROR_NOT_SUPPORTED");
+               break;
+       case IOTCON_ERROR_PERMISSION_DENIED:
+               _E("IOTCON_ERROR_PERMISSION_DENIED");
+               break;
+       case IOTCON_ERROR_INVALID_PARAMETER:
+               _E("IOTCON_ERROR_INVALID_PARAMETER");
+               break;
+       default:
+               _E("Error : [%d]", err_no);
+               break;
+       }
+}
+
+int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
 {
        iotcon_representation_h representation;
        int ret = -1;
@@ -190,77 +253,92 @@ int connectivity_notify(connectivity_resource_s *resource_info, int value)
 
        _D("Notify the value[%d]", value);
 
-       representation = _create_representation_with_attribute(resource_info->res, (bool)value);
+       representation = _create_representation_with_bool(resource_info, key, value);
        retv_if(!representation, -1);
 
-       ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_HIGH);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
+       if (IOTCON_ERROR_NONE != ret) {
+               _I("There are some troubles for notifying value[%d]", ret);
+               _print_iotcon_error(ret);
+               return -1;
+       }
 
        _destroy_representation(representation);
 
        return 0;
 }
 
-static int _handle_post_request(connectivity_resource_s *resource_info, iotcon_request_h request)
+int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
 {
-       iotcon_attributes_h resp_attributes = NULL;
-       iotcon_representation_h resp_repr = NULL;
-       connectivity_resource_s *new_resource_info = NULL;
+       iotcon_representation_h representation;
        int ret = -1;
 
-       _D("POST request");
+       retv_if(!resource_info, -1);
+       retv_if(!resource_info->observers, -1);
 
-       if (_resource_created) {
-               _E("Resource(%s) is already created", ULTRASONIC_RESOURCE_2_URI);
-               return -1;
-       }
+       _D("Notify the value[%d]", value);
 
-       new_resource_info = calloc(1, sizeof(connectivity_resource_s));
-       retv_if(!new_resource_info, -1);
+       representation = _create_representation_with_int(resource_info, key, value);
+       retv_if(!representation, -1);
 
-       ret = connectivity_set_resource(ULTRASONIC_RESOURCE_2_URI, ULTRASONIC_RESOURCE_TYPE, &new_resource_info);
-       retv_if(0 != ret, -1);
+       ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
+       if (IOTCON_ERROR_NONE != ret) {
+               _I("There are some troubles for notifying value[%d]", ret);
+               _print_iotcon_error(ret);
+               return -1;
+       }
 
-       _resource_created = true;
+       _destroy_representation(representation);
 
-       ret = iotcon_representation_create(&resp_repr);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       return 0;
+}
 
-       ret = iotcon_attributes_create(&resp_attributes);
-       goto_if(IOTCON_ERROR_NONE != ret, error);
+int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
+{
+       iotcon_representation_h representation;
+       int ret = -1;
 
-       ret = iotcon_attributes_add_str(resp_attributes, "createduripath", ULTRASONIC_RESOURCE_2_URI);
-       goto_if(IOTCON_ERROR_NONE != ret, error);
+       retv_if(!resource_info, -1);
+       retv_if(!resource_info->observers, -1);
 
-       ret = iotcon_representation_set_attributes(resp_repr, resp_attributes);
-       goto_if(IOTCON_ERROR_NONE != ret, error);
+       _D("Notify the value[%f]", value);
 
-       iotcon_attributes_destroy(resp_attributes);
+       representation = _create_representation_with_double(resource_info, key, value);
+       retv_if(!representation, -1);
 
-       ret = _send_response(request, resp_repr, IOTCON_RESPONSE_RESOURCE_CREATED);
-       goto_if(0 != ret, error);
+       ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
+       if (IOTCON_ERROR_NONE != ret) {
+               _I("There are some troubles for notifying value[%d]", ret);
+               _print_iotcon_error(ret);
+               return -1;
+       }
 
-       iotcon_representation_destroy(resp_repr);
+       _destroy_representation(representation);
 
        return 0;
-
-error:
-       if (resp_attributes) iotcon_attributes_destroy(resp_attributes);
-       iotcon_representation_destroy(resp_repr);
-       return -1;
 }
 
-static int _handle_delete_request(iotcon_resource_h resource, iotcon_request_h request)
+int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, char *value)
 {
+       iotcon_representation_h representation;
        int ret = -1;
 
-       _D("DELETE request");
+       retv_if(!resource_info, -1);
+       retv_if(!resource_info->observers, -1);
 
-       ret = iotcon_resource_destroy(resource);
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       _D("Notify all members [%s]", value);
 
-       ret = _send_response(request, NULL, IOTCON_RESPONSE_RESOURCE_DELETED);
-       retv_if(0 != ret, -1);
+       representation = _create_representation_with_str(resource_info, key, value);
+       retv_if(!representation, -1);
+
+       ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
+       if (IOTCON_ERROR_NONE != ret) {
+               //_I("There are some troubles for notifying value[%d]", ret);
+               _print_iotcon_error(ret);
+               return -1;
+       }
+
+       _destroy_representation(representation);
 
        return 0;
 }
@@ -295,16 +373,16 @@ static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_r
 
        switch (type) {
        case IOTCON_REQUEST_GET:
-               ret = _handle_get_request(resource_info->res, request);
+               _I("Do not support 'get' query");
                break;
        case IOTCON_REQUEST_PUT:
-               ret = _handle_put_request(resource_info, request);
+               _I("Do not support 'put' query");
                break;
        case IOTCON_REQUEST_POST:
-               ret = _handle_post_request(resource_info, request);
+               _I("Do not support 'post' query");
                break;
        case IOTCON_REQUEST_DELETE:
-               ret = _handle_delete_request(resource_info->res, request);
+               _I("Do not support 'delete' query");
                break;
        default:
                _E("Cannot reach here");
@@ -329,12 +407,16 @@ static int _handle_observer(iotcon_request_h request, iotcon_observers_h observe
                ret = iotcon_request_get_observe_id(request, &observe_id);
                retv_if(IOTCON_ERROR_NONE != ret, -1);
 
+               _I("Add an observer : %d", observe_id);
+
                ret = iotcon_observers_add(observers, observe_id);
                retv_if(IOTCON_ERROR_NONE != ret, -1);
        } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
                ret = iotcon_request_get_observe_id(request, &observe_id);
                retv_if(IOTCON_ERROR_NONE != ret, -1);
 
+               _I("Remove an observer : %d", observe_id);
+
                ret = iotcon_observers_remove(observers, observe_id);
                retv_if(IOTCON_ERROR_NONE != ret, -1);
        }
@@ -370,18 +452,49 @@ error:
        _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
 }
 
-/* device_name : "iotcon-test-basic-server" */
-int connectivity_init(const char *device_name)
+static void _copy_file(const char *in_filename, const char *out_filename)
+{
+       char buf[BUFSIZE] = { 0, };
+       size_t nread = 0;
+       FILE *in = NULL;
+       FILE *out = NULL;
+
+       ret_if(!in_filename);
+       ret_if(!out_filename);
+
+       in = fopen(in_filename, "r");
+       ret_if(!in);
+
+       out = fopen(out_filename, "w");
+       goto_if(!out, error);
+
+       rewind(in);
+       while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
+               if (fwrite(buf, 1, nread, out) < nread) {
+                       _E("critical error to copy a file");
+                       break;
+               }
+       }
+
+       fclose(in);
+       fclose(out);
+
+       return;
+
+error:
+       fclose(out);
+}
+
+int connectivity_init(void)
 {
        int ret = -1;
 
-       ret = iotcon_initialize("/home/owner/apps_rw/org.tizen.position-finder-server/data/iotcon-test-svr-db-server.dat");
-       retv_if(IOTCON_ERROR_NONE != ret, -1);
+       _copy_file(CBOR_FILE_IN_RES, CBOR_FILE_IN_DATA);
 
-       ret = iotcon_set_device_name(device_name);
-       goto_if(IOTCON_ERROR_NONE != ret, error);
+       ret = iotcon_initialize(CBOR_FILE_IN_DATA);
+       retv_if(IOTCON_ERROR_NONE != ret, -1);
 
-       ret = iotcon_start_presence(10);
+       ret = iotcon_set_device_name(DEVICE_NAME);
        goto_if(IOTCON_ERROR_NONE != ret, error);
 
        return 0;
@@ -402,10 +515,11 @@ void connectivity_unset_resource(connectivity_resource_s *resource_info)
        ret_if(!resource_info);
        if (resource_info->observers) iotcon_observers_destroy(resource_info->observers);
        if (resource_info->res) iotcon_resource_destroy(resource_info->res);
+       if (resource_info->path) free(resource_info->path);
        free(resource_info);
 }
 
-int connectivity_set_resource(const char *uri_path, const char *type, connectivity_resource_s **out_resource_info)
+int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
 {
        iotcon_resource_types_h resource_types = NULL;
        iotcon_resource_interfaces_h ifaces = NULL;
@@ -413,9 +527,17 @@ int connectivity_set_resource(const char *uri_path, const char *type, connectivi
        uint8_t policies;
        int ret = -1;
 
+       retv_if(!path, -1);
+       retv_if(!type, -1);
+       retv_if(!out_resource_info, -1);
+
        resource_info = calloc(1, sizeof(connectivity_resource_s));
        retv_if(!resource_info, -1);
-       *out_resource_info = resource_info;
+
+       resource_info->path = strdup(path);
+       goto_if(!resource_info->path, error);
+
+       _D("Path : [%s]", resource_info->path);
 
        ret = iotcon_resource_types_create(&resource_types);
        goto_if(IOTCON_ERROR_NONE != ret, error);
@@ -437,7 +559,7 @@ int connectivity_set_resource(const char *uri_path, const char *type, connectivi
                IOTCON_RESOURCE_OBSERVABLE |
                IOTCON_RESOURCE_SECURE;
 
-       ret = iotcon_resource_create(uri_path,
+       ret = iotcon_resource_create(URI_PATH,
                        resource_types,
                        ifaces,
                        policies,
@@ -451,6 +573,7 @@ int connectivity_set_resource(const char *uri_path, const char *type, connectivi
 
        iotcon_resource_types_destroy(resource_types);
        iotcon_resource_interfaces_destroy(ifaces);
+       *out_resource_info = resource_info;
 
        return 0;
 
@@ -458,6 +581,7 @@ error:
        if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
        if (resource_types) iotcon_resource_types_destroy(resource_types);
        if (resource_info->res) iotcon_resource_destroy(resource_info->res);
+       if (resource_info->path) free(resource_info->path);
        if (resource_info) free(resource_info);
 
        return -1;