summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt3
-rw-r--r--inc/controller_util.h1
-rwxr-xr-xinc/resource.h1
-rw-r--r--inc/resource/resource_camera.h30
-rw-r--r--inc/webutil.h2
-rw-r--r--packaging/org.tizen.position-finder-server.spec1
-rw-r--r--res/pi.conf3
-rw-r--r--src/connection_manager.c20
-rw-r--r--src/controller.c53
-rw-r--r--src/controller_util.c24
-rw-r--r--src/resource/resource_camera.c233
-rw-r--r--src/webutil.c124
-rw-r--r--tizen-manifest.xml.in3
13 files changed, 474 insertions, 24 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d2914d..49fd759 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,6 +22,8 @@ pkg_check_modules(APP_PKGS REQUIRED
glib-2.0
json-glib-1.0
capi-system-info
+ capi-network-connection
+ capi-media-camera
)
ADD_DEFINITIONS(-DCBOR_FILE_IN_RES="${INSTALL_RESDIR}/${CBOR_FILE}")
@@ -60,6 +62,7 @@ ADD_EXECUTABLE(${PROJECT_NAME}
${PROJECT_ROOT_DIR}/src/resource/resource_gas_detection_sensor.c
${PROJECT_ROOT_DIR}/src/resource/resource_sound_level_sensor.c
${PROJECT_ROOT_DIR}/src/resource/resource_adc_mcp3008.c
+ ${PROJECT_ROOT_DIR}/src/resource/resource_camera.c
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -lm)
diff --git a/inc/controller_util.h b/inc/controller_util.h
index 29b5e46..f36973a 100644
--- a/inc/controller_util.h
+++ b/inc/controller_util.h
@@ -24,6 +24,7 @@
int controller_util_get_path(const char **path);
int controller_util_get_address(const char **address);
+int controller_util_get_image_address(const char **image_upload);
void controller_util_free(void);
#endif /* __POSITION_FINDER_CONTROLLER_UTIL_H__ */
diff --git a/inc/resource.h b/inc/resource.h
index 783fd8f..f3ffe3c 100755
--- a/inc/resource.h
+++ b/inc/resource.h
@@ -38,5 +38,6 @@
#include "resource/resource_tilt_sensor.h"
#include "resource/resource_gas_detection_sensor.h"
#include "resource/resource_sound_level_sensor.h"
+#include "resource/resource_camera.h"
#endif /* __POSITION_FINDER_RESOURCE_H__ */
diff --git a/inc/resource/resource_camera.h b/inc/resource/resource_camera.h
new file mode 100644
index 0000000..545e9b9
--- /dev/null
+++ b/inc/resource/resource_camera.h
@@ -0,0 +1,30 @@
+/*
+ * 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 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://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,
+ * 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 <camera.h>
+
+#define MAX_IMAGE_FILE_LEN 256
+#define DEFAULT_FILE_PATH "/home/owner/media"
+
+typedef void (*capture_completed_cb)(const void *image, unsigned int size, void *user_data);
+
+int resource_capture_camera(capture_completed_cb capture_completed_cb, void *data);
+void resource_close_camera(void);
diff --git a/inc/webutil.h b/inc/webutil.h
index 8947bc2..a229e07 100644
--- a/inc/webutil.h
+++ b/inc/webutil.h
@@ -68,6 +68,8 @@ struct _web_util_sensor_data_s {
int web_util_noti_init(void);
void web_util_noti_fini(void);
int web_util_noti_post(const char *resource, const char *json_data);
+int web_util_noti_post_image_data(const char *url, const char *device_id,
+ const void *image_data, unsigned int image_size);
int web_util_noti_get(const char *resource, char **res);
int web_util_json_init(void);
diff --git a/packaging/org.tizen.position-finder-server.spec b/packaging/org.tizen.position-finder-server.spec
index dd4e98a..8f50c9b 100644
--- a/packaging/org.tizen.position-finder-server.spec
+++ b/packaging/org.tizen.position-finder-server.spec
@@ -28,6 +28,7 @@ BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(json-glib-1.0)
BuildRequires: pkgconfig(capi-system-info)
BuildRequires: pkgconfig(capi-network-connection)
+BuildRequires: pkgconfig(capi-media-camera)
%description
Server for Position Finder
diff --git a/res/pi.conf b/res/pi.conf
index b55530e..b7e63e9 100644
--- a/res/pi.conf
+++ b/res/pi.conf
@@ -1,3 +1,4 @@
[default]
-path=/door/1
+path=sensor-pi-1
address=http://showiot.xyz/api/tt/data
+image_address=http://test.showiot.xyz/api/image/
diff --git a/src/connection_manager.c b/src/connection_manager.c
index ef5fd7e..443cd1f 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -1,23 +1,3 @@
-/*
- * 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 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://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,
- * 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.
- */
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
diff --git a/src/controller.c b/src/controller.c
index a442f82..7b35e9f 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -34,16 +34,69 @@
#define CONNECTIVITY_KEY "opened"
#define SENSORING_TIME_INTERVAL 5.0f
+#define CAMERA_TIME_INTERVAL 2
+#define TEST_CAMERA_SAVE 0
+#define CAMERA_ENABLED 0
typedef struct app_data_s {
Ecore_Timer *getter_timer;
connectivity_resource_s *resource_info;
} app_data;
+static void __resource_camera_capture_completed_cb(const void *image, unsigned int size, void *user_data)
+{
+ /* TODO */
+ const char *path = NULL;
+ const char *url = NULL;
+
+ controller_util_get_path(&path);
+
+ controller_util_get_image_address(&url);
+
+ web_util_noti_post_image_data(url, path, image, size);
+
+#if TEST_CAMERA_SAVE
+ FILE *fp = NULL;
+ char *data_path = NULL;
+ char file[256];
+
+ data_path = app_get_data_path();
+
+ snprintf(file, sizeof(file), "%sjjoggoba.jpg", data_path);
+ free(data_path);
+ _D("File : %s", file);
+
+ fp = fopen(file, "w");
+ if (!fp) {
+ _E("Failed to open file: %s", file);
+ return;
+ }
+
+ if (fwrite(image, size, 1, fp) != 1) {
+ _E("Failed to write image to file");
+ return;
+ }
+
+ fclose(fp);
+#endif
+}
+
static Eina_Bool control_sensors_cb(void *data)
{
app_data *ad = data;
int value = 1;
+ int ret = 0;
+#if CAMERA_ENABLED
+ static unsigned int count = 0;
+
+ if (count % CAMERA_TIME_INTERVAL == 0) {
+ ret = resource_capture_camera(__resource_camera_capture_completed_cb, NULL);
+ if (ret < 0)
+ _E("Failed to capture camera");
+ }
+
+ count++;
+#endif
/* This is example, get value from sensors first */
if (connectivity_notify_int(ad->resource_info, "Motion", value) == -1)
diff --git a/src/controller_util.c b/src/controller_util.c
index 3bba0d5..5bb65dc 100644
--- a/src/controller_util.c
+++ b/src/controller_util.c
@@ -28,11 +28,13 @@
#define CONF_GROUP_DEFAULT_NAME "default"
#define CONF_KEY_PATH_NAME "path"
#define CONF_KEY_ADDRESS_NAME "address"
+#define CONF_KEY_IMAGE_UPLOAD_NAME "image_address"
#define CONF_FILE_NAME "pi.conf"
struct controller_util_s {
char *path;
char *address;
+ char *image_upload;
};
struct controller_util_s controller_util = { 0, };
@@ -71,6 +73,13 @@ static int _read_conf_file(void)
if (!controller_util.address)
_E("could not get the key string");
+ controller_util.image_upload = g_key_file_get_string(gkf,
+ CONF_GROUP_DEFAULT_NAME,
+ CONF_KEY_IMAGE_UPLOAD_NAME,
+ NULL);
+ if (!controller_util.image_upload)
+ _E("could not get the key string");
+
g_key_file_free(gkf);
return 0;
@@ -106,6 +115,21 @@ int controller_util_get_address(const char **address)
return 0;
}
+int controller_util_get_image_address(const char **image_upload)
+{
+ retv_if(!image_upload, -1);
+
+ if (!controller_util.image_upload) {
+ int ret = -1;
+ ret = _read_conf_file();
+ retv_if(-1 == ret, -1);
+ }
+
+ *image_upload = controller_util.image_upload;
+
+ return 0;
+}
+
void controller_util_free(void)
{
if (controller_util.path) {
diff --git a/src/resource/resource_camera.c b/src/resource/resource_camera.c
new file mode 100644
index 0000000..64ae611
--- /dev/null
+++ b/src/resource/resource_camera.c
@@ -0,0 +1,233 @@
+/*
+ * 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 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://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,
+ * 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 <camera.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tizen.h>
+
+#include "log.h"
+#include "resource/resource_camera.h"
+
+#define RESOLUTION_W 320
+#define RESOLUTION_H 240
+
+static int __init(void);
+static void __completed_cb(void *user_data);
+static bool __resolution_list_cb(int width, int height, void *user_data);
+static void __capturing_cb(camera_image_data_s *image, camera_image_data_s *postview,
+ camera_image_data_s *thumbnail, void *user_data);
+
+struct __camera_data {
+ camera_h cam_handle;
+ int resolution_w;
+ int resolution_h;
+ void *captured_file;
+ unsigned int image_size;
+ capture_completed_cb completed_cb;
+ void *completed_cb_data;
+};
+
+static struct __camera_data *camera_data = NULL;
+
+int resource_capture_camera(capture_completed_cb capture_completed, void *user_data)
+{
+ camera_state_e state;
+ int ret = CAMERA_ERROR_NONE;
+
+ if (camera_data == NULL) {
+ _I("Camera is not initialized");
+ ret = __init();
+ if (ret < 0) {
+ _E("Failed to initialize camera");
+ return -1;
+ }
+ }
+
+ ret = camera_get_state(camera_data->cam_handle, &state);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to get camera state");
+ return -1;
+ }
+
+ if (state >= CAMERA_STATE_CAPTURING) {
+ _D("Camera is now capturing");
+ return 0;
+ }
+
+ if (state != CAMERA_STATE_PREVIEW) {
+ _I("Preview is not started");
+ ret = camera_start_preview(camera_data->cam_handle);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to start preview");
+ return -1;
+ }
+ }
+
+ ret = camera_start_capture(camera_data->cam_handle, __capturing_cb, __completed_cb, camera_data);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to start capturing");
+ return -1;
+ }
+
+ camera_data->completed_cb = capture_completed;
+ camera_data->completed_cb_data = user_data;
+
+ return 0;
+}
+
+void resource_close_camera(void)
+{
+ if (camera_data == NULL)
+ return;
+
+ camera_stop_preview(camera_data->cam_handle);
+
+ camera_destroy(camera_data->cam_handle);
+ camera_data->cam_handle = NULL;
+
+ free(camera_data);
+ camera_data = NULL;
+}
+
+static void __capturing_cb(camera_image_data_s *image, camera_image_data_s *postview,
+ camera_image_data_s *thumbnail, void *user_data)
+{
+ struct __camera_data *camera_data = user_data;
+ if (image == NULL) {
+ _E("Image is NULL");
+ return;
+ }
+
+ camera_data->captured_file = malloc(image->size);
+ if (camera_data->captured_file == NULL)
+ return;
+
+ _D("Now is on Capturing: Image size[%d x %d]", image->width, image->height);
+
+ memcpy(camera_data->captured_file, image->data, image->size);
+ camera_data->image_size = image->size;
+
+ return;
+}
+
+static void __completed_cb(void *user_data)
+{
+ struct __camera_data *camera_data = user_data;
+ int ret = CAMERA_ERROR_NONE;
+
+ if (camera_data->completed_cb)
+ camera_data->completed_cb(camera_data->captured_file, camera_data->image_size, camera_data->completed_cb_data);
+
+ free(camera_data->captured_file);
+ camera_data->captured_file = NULL;
+
+ if (!camera_data->cam_handle) {
+ _E("Camera is NULL");
+ return;
+ }
+ _D("Capture is completed");
+
+ ret = camera_start_preview(camera_data->cam_handle);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to start preview");
+ return;
+ }
+
+ ret = camera_stop_preview(camera_data->cam_handle);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to stop preview");
+ return;
+ }
+
+ return;
+}
+
+static bool __resolution_list_cb(int width, int height, void *user_data)
+{
+ _D("Supported resolution - Width[%d], Height[%d]", width, height);
+
+ if (width > camera_data->resolution_w && width <= RESOLUTION_W &&
+ height > camera_data->resolution_h && height <= RESOLUTION_H) {
+ camera_data->resolution_w = width;
+ camera_data->resolution_h = height;
+ }
+ _D("Fixed Resolution is Width[%d], Height[%d]", camera_data->resolution_w, camera_data->resolution_h);
+
+ return true;
+}
+
+static int __init(void)
+{
+ int ret = CAMERA_ERROR_NONE;
+
+ camera_data = malloc(sizeof(struct __camera_data));
+ if (camera_data == NULL) {
+ _E("Failed to allocate Camera data");
+ return -1;
+ }
+ memset(camera_data, 0, sizeof(struct __camera_data));
+
+ ret = camera_create(CAMERA_DEVICE_CAMERA0, &(camera_data->cam_handle));
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to create camera");
+ goto ERROR;
+ }
+
+ ret = camera_foreach_supported_capture_resolution(camera_data->cam_handle, __resolution_list_cb, NULL);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to foreach supported capture resolution");
+ goto ERROR;
+ }
+
+ ret = camera_set_preview_resolution(camera_data->cam_handle, camera_data->resolution_w, camera_data->resolution_h);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to set preview resolution");
+ goto ERROR;
+ }
+
+ ret = camera_set_capture_resolution(camera_data->cam_handle, camera_data->resolution_w, camera_data->resolution_h);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to set capture resolution");
+ goto ERROR;
+ }
+
+ ret = camera_set_capture_format(camera_data->cam_handle, CAMERA_PIXEL_FORMAT_JPEG);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to set capture resolution");
+ goto ERROR;
+ }
+
+ ret = camera_start_preview(camera_data->cam_handle);
+ if (ret != CAMERA_ERROR_NONE) {
+ _E("Failed to start preview[%d]", ret);
+ goto ERROR;
+ }
+
+ return 0;
+
+ERROR:
+ camera_destroy(camera_data->cam_handle);
+ free(camera_data);
+ return -1;
+}
+
diff --git a/src/webutil.c b/src/webutil.c
index 27f8a37..7afde87 100644
--- a/src/webutil.c
+++ b/src/webutil.c
@@ -22,7 +22,7 @@
#include <stdbool.h>
#include <curl/curl.h>
-#include <glib-object.h>
+#include <glib.h>
#include <json-glib/json-glib.h>
#include "log.h"
#include "webutil.h"
@@ -67,6 +67,62 @@ static size_t _get_response_write_callback(void *ptr, size_t size, size_t nmemb,
return res_size;
}
+static int __curl_debug(CURL *handle, curl_infotype type,
+ char *data, size_t size, void *userptr)
+{
+ const char *prefix = NULL;
+ char *message = NULL;
+
+ switch (type) {
+ case CURLINFO_END:
+ return 0;
+ case CURLINFO_TEXT:
+ _D("== text Info: %s", data);
+ return 0;
+ case CURLINFO_HEADER_OUT:
+ prefix = "=> Send header:";
+ break;
+ case CURLINFO_DATA_OUT:
+ prefix = "=> Send data:";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ prefix = "=> Send SSL data:";
+ break;
+ case CURLINFO_HEADER_IN:
+ prefix = "<= Recv header:";
+ break;
+ case CURLINFO_DATA_IN:
+ prefix = "<= Recv data:";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ prefix = "<= Recv SSL data:";
+ break;
+ }
+ message = g_strndup(data, size);
+ _D("%s %s", prefix, message);
+ g_free(message);
+ return 0;
+}
+
+static const char *_get_time_str(void)
+{
+ struct timeval val;
+ struct tm *ptm;
+ static char res_time[40] = {0, };
+
+ gettimeofday(&val, NULL);
+ ptm = localtime(&val.tv_sec);
+
+ // format : YY-MM-DD_hh:mm:ss:uuuuuu
+ snprintf(res_time, sizeof(res_time), "%04d-%02d-%02d_%02d:%02d:%02d:%06ld"
+ , ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday
+ , ptm->tm_hour, ptm->tm_min, ptm->tm_sec
+ , val.tv_usec);
+
+ return (const char *)res_time;
+}
+
+
int web_util_noti_init(void)
{
int ret = 0;
@@ -86,6 +142,71 @@ void web_util_noti_fini(void)
return;
}
+int web_util_noti_post_image_data(const char *url, const char *device_id,
+ const void *image_data, unsigned int image_size)
+{
+ int ret = 0;
+ CURL *curl = NULL;
+ CURLcode response = CURLE_OK;
+ struct curl_httppost *formpost = NULL;
+ struct curl_httppost *lastptr = NULL;
+ char *filename = NULL;
+ char *post_url = NULL;
+
+ retv_if(url == NULL, -1);
+ retv_if(device_id == NULL, -1);
+ retv_if(image_data == NULL, -1);
+ retv_if(image_size == 0, -1);
+
+ curl = curl_easy_init();
+
+ if (!curl) {
+ _E("fail to init curl");
+ return -1;
+ }
+
+ filename = g_strdup_printf("%s_%s.jpg", device_id, _get_time_str());
+ post_url = g_strdup_printf("%s?id=%s", url, device_id);
+ _D("FileName: [%s], PostUrl: [%s]", filename, post_url);
+
+ curl_formadd(&formpost, &lastptr,
+ CURLFORM_COPYNAME, "content-type:",
+ CURLFORM_COPYCONTENTS, "multipart/form-data",
+ CURLFORM_END);
+
+ curl_formadd(&formpost, &lastptr,
+ CURLFORM_COPYNAME, "imageFile",
+ CURLFORM_BUFFER, filename,
+ CURLFORM_BUFFERPTR, image_data,
+ CURLFORM_BUFFERLENGTH, image_size,
+ CURLFORM_END);
+
+ curl_easy_setopt(curl, CURLOPT_URL, post_url);
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+
+ /* if CURLOPT_VERBOSE is enabled, __curl_debug() function will be called */
+ // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, __curl_debug);
+
+ // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
+ // curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQ_TIMEOUT);
+
+ response = curl_easy_perform(curl);
+
+ if (response != CURLE_OK) {
+ _E("curl_easy_perform() failed: %s",
+ curl_easy_strerror(response));
+ ret = -1;
+ }
+
+ curl_easy_cleanup(curl);
+ curl_formfree(formpost);
+ g_free(post_url);
+ g_free(filename);
+
+ return ret;
+}
+
int web_util_noti_post(const char *resource, const char *json_data)
{
int ret = 0;
@@ -399,7 +520,6 @@ int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_
}
*/
-
json_builder_begin_object(Json_h.builder);
json_builder_set_member_name(Json_h.builder, n_id);
diff --git a/tizen-manifest.xml.in b/tizen-manifest.xml.in
index 2ea5ef4..e014ce2 100644
--- a/tizen-manifest.xml.in
+++ b/tizen-manifest.xml.in
@@ -5,7 +5,7 @@
<author email="gs86.lee@samsung.com" href="www.samsung.com">Geunsun Lee</author>
<author email="ey928.lee@samsung.com" href="www.samsung.com">Eunyoung Lee</author>
<author email="junkyu.han@samsung.com" href="www.samsung.com">Junkyu Han</author>
- <service-application appid="@ORG_PREFIX@.@PROJECT_NAME@" auto-restart="true" exec="@PROJECT_NAME@" multiple="false" nodisplay="true" on-boot="true" taskmanage="false" type="capp">
+ <service-application appid="@ORG_PREFIX@.@PROJECT_NAME@" auto-restart="false" exec="@PROJECT_NAME@" multiple="false" nodisplay="true" on-boot="false" taskmanage="false" type="capp">
<label>@APP_LABEL@</label>
<icon>@PROJECT_NAME@.png</icon>
</service-application>
@@ -13,5 +13,6 @@
<privilege>http://tizen.org/privilege/network.get</privilege>
<privilege>http://tizen.org/privilege/internet</privilege>
<privilege>http://tizen.org/privilege/peripheralio</privilege>
+ <privilege>http://tizen.org/privilege/camera</privilege>
</privileges>
</manifest>