[submodule "edge-home-orchestration-go"]
path = edge-home-orchestration-go
url = https://github.com/lf-edge/edge-home-orchestration-go.git
- branch = Baobab
+ branch = master
BINARY_FILE := edge-orchestration
SRC_FILES := \
$(SRC_DIR)/main.c \
- $(SRC_DIR)/orchestration_server.c
+ $(SRC_DIR)/orchestration_dbus_server.c \
+ $(SRC_DIR)/orchestration_service.c \
+ $(SRC_DIR)/orchestration_cipher.c \
+ $(SRC_DIR)/orchestration_key.c
OBJ_FILES := *.o
# Build parameter
-CFLAGS := -g -Wall -Werror -fPIE -pie
+CFLAGS := -g -Wall -Werror -fPIE -pie -Wno-unused-function
all: clean build
* limitations under the License.
*
*******************************************************************************/
+
+#include <stdlib.h>
+
+#ifndef __ORCHESTRATION_H__
+#define __ORCHESTRATION_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
#define MAX_SVC_INFO_NUM 3
typedef struct {
char* ExecutionType;
TargetInfo RemoteTargetInfo;
} ResponseService;
+typedef char* (*identityGetterFunc)();
+typedef char* (*keyGetterFunc)(char* id);
+
+identityGetterFunc iGetter;
+keyGetterFunc kGetter;
+
+static void setPSKHandler(identityGetterFunc ihandle, keyGetterFunc khandle){
+ iGetter = ihandle;
+ kGetter = khandle;
+}
+
+static char* bridge_iGetter(){
+ return iGetter();
+}
+
+static char* bridge_kGetter(char* id){
+ return kGetter(id);
+}
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif // __ORCHESTRATION_H__
+
+
#line 1 "cgo-generated-wrapper"
extern int PrintLog(char* p0);
+extern void SetPSKHandler(identityGetterFunc p0, keyGetterFunc p1);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#ifndef __ORCHESTRATION_CIPHER_H__
+#define __ORCHESTRATION_CIPHER_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int encrypter(char* in, int inLen, char* out);
+int decrypter(char* in, int inLen, char* out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ORCHESTRATION_CIPHER_H__ */
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#ifndef __ORCHESTRATION_SERVER_H__
+#define __ORCHESTRATION_SERVER_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <orchestration_type.h>
+
+void set_default_dbus_interface(void);
+int orchestration_server_initialize(dbus_funcs cb);
+void orchestration_server_finish(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ORCHESTRATION_SERVER_H__ */
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#ifndef __ORCHESTRATION_KEY_H__
+#define __ORCHESTRATION_KEY_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int updateKeyPair(char* id,char* key);
+char* identityGetter();
+char* keyGetter(char* id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ORCHESTRATION_KEY_H__ */
+++ /dev/null
-/*******************************************************************************
- * Copyright 2019 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *******************************************************************************/
-
-#ifndef __ORCHESTRATION_SERVER_H__
-#define __ORCHESTRATION_SERVER_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include <stdbool.h>
-#include <orchestration.h>
-
-#define DEBUG(fmt, ...) printf("[%s:%d] ", __FILE__, __LINE__); printf((fmt), ##__VA_ARGS__);
-
-typedef enum {
- /* Errors of Orchestration*/
- ORCH_ERROR_NOT_READY = -1,
- ORCH_ERROR_WIFI_UNREACHABLE = -2,
-
- /* Errors of DBus*/
- ORCH_ERROR_FAULT = -100,
- ORCH_ERROR_INVALID_PARAMETER = -101,
- ORCH_ERROR_DBUS_FAILURE = -102,
-
- /*Success Error Code*/
- ORCH_ERROR_NONE = 0,
-} _orchestration_state_e;
-
-typedef int (*request_service_cb)(char* app_name, bool self_select, RequestServiceInfo service_info[], int count, int client_pid);
-
-void set_default_dbus_interface(void);
-int orchestration_server_initialize(request_service_cb cb);
-void orchestration_server_finish(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ORCHESTRATION_SERVER_H__ */
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#ifndef __ORCHESTRATION_SERVICE_H__
+#define __ORCHESTRATION_SERVICE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <orchestration.h>
+#include <orchestration_type.h>
+
+_orchestration_state_e orchestration_service_start();
+dbus_funcs getDbusFuncs();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ORCHESTRATION_SERVER_H__ */
--- /dev/null
+/*******************************************************************************
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#ifndef __ORCHESTRATION_TYPE_H__
+#define __ORCHESTRATION_TYPE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <orchestration.h>
+
+typedef enum {
+ /* Errors of Orchestration*/
+ ORCH_ERROR_NOT_READY = -1,
+ ORCH_ERROR_WIFI_UNREACHABLE = -2,
+
+ /* Errors of DBus*/
+ ORCH_ERROR_FAULT = -100,
+ ORCH_ERROR_INVALID_PARAMETER = -101,
+ ORCH_ERROR_DBUS_FAILURE = -102,
+
+ /*Success Error Code*/
+ ORCH_ERROR_NONE = 0,
+} _orchestration_state_e;
+
+typedef RequestServiceInfo requestServiceInfo;
+
+typedef int (*request_service_func)(char* app_name, bool self_select, requestServiceInfo service_info[], int count, char* client_pname);
+typedef int (*update_key_pair_func)(char* id, char* key, char* client_pname);
+
+typedef struct _dbus_funcs{
+ request_service_func request_service_f;
+ update_key_pair_func update_key_pair_f;
+} dbus_funcs;
+
+#define DEBUG(fmt, ...) printf("[%s:%d] ", __FILE__, __LINE__); printf((fmt), ##__VA_ARGS__);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ORCHESTRATION_TYPE_H__ */
*
*******************************************************************************/
-#include <stdio.h>
+
#include <gio/gio.h>
#include <stdarg.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-
-#include <orchestration_server.h>
-int get_process_name_by_pid(char* process_name, int pid) {
- char fname[1024] = {0, };
- char line[1024] = {0, };
- ssize_t fname_len = snprintf(NULL, 0, "/proc/%d/status", pid);
-
- snprintf(fname, fname_len + 1, "/proc/%d/status", pid);
- FILE *fp = fopen(fname, "r");
- if (fp == NULL) {
- DEBUG("%d Process not found!!!\n", pid);
- return -1;
- }
- while (!feof(fp)) {
- fgets(line, 1024, fp);
- if (strstr(line, "Name:") != NULL) {
- int index = 0;
- char *ptr = strchr(line, ':');
- while (1) {
- ptr++;
- if (*ptr == '\n' || *ptr == '\0')
- break;
- if (*ptr != ' ' && *ptr != '\t')
- process_name[index++] = *ptr;
- }
- process_name[index] = '\0';
- printf("process_name = %s\n", process_name);
- fclose(fp);
- return 0;
- }
- }
- printf("%d Process status have no Process name!!\n", pid);
- fclose(fp);
- return -1;
-}
-
-int request_cb(char* app_name, bool self_select, RequestServiceInfo service_info[], int count, int client_pid){
- int ret = ORCH_ERROR_NONE;
- char process_name[128] = {0, };
- const char unknown[] = "Unknown";
- ResponseService result;
-
- if (get_process_name_by_pid(process_name, client_pid) != 0) {
- DEBUG("could not get Process name");
- strncpy(process_name, unknown, strlen(unknown));
- }
-
- DEBUG("[orchestration_server]\n")
- DEBUG("\t app_name : %s\n", app_name);
- DEBUG("\t self_select : %s\n", self_select ? "true" : "false");
- DEBUG("\t count : %d\n", count);
- DEBUG("\t client_pid : %d\n", client_pid);
- DEBUG("\t process_name : %s\n", process_name);
- for (int ix = 0; ix < count; ix++) {
- DEBUG("\t service_info[%d].ExecutionType : %s\n", ix, service_info[ix].ExecutionType);
- DEBUG("\t service_info[%d].ExeCmd : %s\n", ix, service_info[ix].ExeCmd);
- }
-
- result = OrchestrationRequestService(app_name, self_select, process_name, service_info, count);
- DEBUG("result = %s\n", result.Message);
-
- /* TO DO : parsing API response */
- return ret;
-}
-
-void* thread_orchestration() {
- DEBUG("Start OrchestrationInit Thread !!\n");
- OrchestrationInit();
- return NULL;
-}
+#include <orchestration_service.h>
+#include <orchestration_dbus_server.h>
int main(void){
int result;
- pthread_t p_thread;
GMainLoop *loop;
/* DEBUG for log can be used after OrchestrationInit */
- if (pthread_create(&p_thread, NULL, thread_orchestration, NULL) != 0) {
- DEBUG("Fail to start OrchestrationInit Thread !!");
+ result = orchestration_service_start();
+ if (result != ORCH_ERROR_NONE){
+ DEBUG("orchestration_service_initialize failed\n");
return -1;
}
- set_default_dbus_interface();
DEBUG("orchestration_server_initialize call\n");
- result = orchestration_server_initialize(request_cb);
+ set_default_dbus_interface();
+ result = orchestration_server_initialize(getDbusFuncs());
if(result != ORCH_ERROR_NONE){
DEBUG("orchestration_server_initialize failed\n");
orchestration_server_finish();
}
loop = g_main_loop_new(NULL, FALSE);
- if (!loop)
+ if (!loop){
return -1;
+ }
g_main_loop_run (loop);
orchestration_server_finish();
-
return 0;
}
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#include <orchestration_cipher.h>
+
+int encrypter(char* in, int inLen, char* out) {
+ out = in;
+ return inLen;
+}
+int decrypter(char* in, int inLen, char* out) {
+ out = in;
+ return inLen;
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#include "orchestration_dbus_server.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gdbus_interface.h"
+
+static _gdbus_interface _gdbus;
+
+static guint owner_id;
+static GDBusConnection *_gdbus_conn;
+static GDBusNodeInfo *introspection_data = NULL;
+
+request_service_func _request_service_cb = NULL;
+update_key_pair_func _update_key_pair_cb = NULL;
+
+#define _ORCHESTRATION_BUS_NAME "org.tizen.orchestration"
+#define _ORCHESTRATION_OBJECT_PATH "/org/tizen/orchestration"
+
+
+static int _request_service(GVariant *parameters, int origin_client_pid);
+static int _update_key_pair(GVariant *parameters, int origin_client_pid);
+static int get_process_name_by_pid(char* process_name, int pid);
+static int get_pid_with_connection(const gchar* sender);
+static int _get_sync(void);
+static int _set_node_info_new_for_xml(void);
+static int _connection_register_object(void);
+static int _own_name_on_connection(void);
+static int orch_dbus_initialize(void);
+static void _handle_method_call(
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data);
+
+static const GDBusInterfaceVTable _interface_vtable =
+{
+ _handle_method_call,
+ NULL,
+ NULL
+};
+
+/* Introspection data for the service we are exporting */
+static gchar introspection_xml[] =
+ " <node>"
+ " <interface name='org.tizen.orchestration.agent'>"
+ " <method name='request_service'>"
+ " <arg type='s' name='app_name' direction='in'/>"
+ " <arg type='i' name='self_select' direction='in'/>"
+ " <arg type='a(ss)' name='service_info' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='i' name='client_pid' direction='in'/>"
+ " <arg type='i' name='return_value' direction='out'/>"
+ " </method>"
+ " <method name='update_key_pair'>"
+ " <arg type='s' name='id' direction='in'/>"
+ " <arg type='s' name='key' direction='in'/>"
+ " <arg type='i' name='client_pid' direction='in'/>"
+ " <arg type='i' name='return_value' direction='out'/>"
+ " </method>"
+ " </interface>"
+ " </node>";
+/* ---------------------------------------------------------------------------------------------------- */
+
+#define _FREEDESKTOP_BUS_NAME "org.freedesktop.DBus"
+#define _FREEDESKTOP_OBJECT_PATH "/org/freedesktop/DBus"
+#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus"
+#define _FREEDESKTOP_GETPROCESSID_METHOD "GetConnectionUnixProcessID"
+
+void set_default_dbus_interface(void)
+{
+ _gdbus.get_sync = g_bus_get_sync;
+ _gdbus.own_name_on_connection = g_bus_own_name_on_connection;
+ _gdbus.unown_name = g_bus_unown_name;
+ _gdbus.node_info_new_for_xml = g_dbus_node_info_new_for_xml;
+ _gdbus.node_info_unref = g_dbus_node_info_unref;
+ _gdbus.connection_register_object = g_dbus_connection_register_object;
+ _gdbus.error_free = g_error_free;
+ _gdbus.invocation_return_value = g_dbus_method_invocation_return_value;
+ _gdbus.connection_call_sync = g_dbus_connection_call_sync;
+}
+
+int orchestration_server_initialize(dbus_funcs cb)
+{
+ int result = ORCH_ERROR_NONE;
+
+ if (cb.request_service_f == NULL || cb.update_key_pair_f == NULL) {
+ result = ORCH_ERROR_INVALID_PARAMETER;
+ printf("request_service_cb is null\n");
+ goto out;
+ }
+ _request_service_cb = cb.request_service_f;
+ _update_key_pair_cb = cb.update_key_pair_f;
+
+ if (!owner_id) {
+ result = orch_dbus_initialize();
+ if (result != ORCH_ERROR_NONE)
+ {
+ printf("orch_dbus_initialize is failed\n");
+ goto out;
+ }
+ }
+
+out:
+ return result;
+}
+
+void orchestration_server_finish(void)
+{
+ if (owner_id)
+ {
+ _gdbus.unown_name(owner_id);
+ }
+ if (introspection_data)
+ {
+ _gdbus.node_info_unref(introspection_data);
+ }
+ printf("orchestration_server_finish\n");
+}
+
+static int orch_dbus_initialize(void)
+{
+ int result;
+
+ result = _get_sync();
+ if (result != ORCH_ERROR_NONE)
+ {
+ printf("Failed to _dbus_init\n");
+ goto out;
+ }
+
+ result = _set_node_info_new_for_xml();
+ if (result != ORCH_ERROR_NONE)
+ {
+ printf("Failed to _set_node_info_new_for_xml\n");
+ goto out;
+ }
+
+ result = _connection_register_object();
+ if (result != ORCH_ERROR_NONE)
+ {
+ printf("Failed to _connection_register_object\n");
+ goto out;
+ }
+
+ result = _own_name_on_connection();
+ if (result != ORCH_ERROR_NONE)
+ {
+ printf("Failed to _dbus_own_name_onconnection\n");
+ goto out;
+ }
+
+out:
+ return result;
+}
+
+static void _handle_method_call(
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ int ret = ORCH_ERROR_NONE;
+ int origin_client_pid;
+
+ origin_client_pid = get_pid_with_connection(sender);
+ if (origin_client_pid < 0) {
+ DEBUG("get_pid_with_connection error!!\n");
+ }
+
+
+ if (g_strcmp0(method_name, "request_service") == 0)
+ {
+ DEBUG("receive method request_service\n");
+ ret = _request_service(parameters, origin_client_pid);
+ }
+ else if (g_strcmp0(method_name, "update_key_pair") == 0)
+ {
+ DEBUG("receive method update key pair\n");
+ ret = _update_key_pair(parameters, origin_client_pid);
+ }
+
+ if (ret == ORCH_ERROR_NONE)
+ {
+ printf("Orchestration service Success, method name : %s\n", method_name);
+ }
+ else
+ {
+ printf("Orchestration service fail, method name : %s\n", method_name);
+ }
+ _gdbus.invocation_return_value(invocation, g_variant_new("(i)", ret));
+}
+
+static int _get_sync(void)
+{
+ GError *error = NULL;
+ if (_gdbus_conn == NULL)
+ {
+ _gdbus_conn = _gdbus.get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (_gdbus_conn == NULL)
+ {
+ if (error != NULL)
+ {
+ printf("Failed to get dbus [%s]\n", error->message);
+ _gdbus.error_free(error);
+ }
+ return ORCH_ERROR_DBUS_FAILURE;
+ }
+ }
+ return ORCH_ERROR_NONE;
+}
+
+static int _own_name_on_connection(void)
+{
+ int result = ORCH_ERROR_NONE;
+
+ owner_id = _gdbus.own_name_on_connection(_gdbus_conn,
+ _ORCHESTRATION_BUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!owner_id)
+ {
+ printf("Failed to own name on connection\n");
+ result = ORCH_ERROR_DBUS_FAILURE;
+ }
+ return result;
+}
+
+static int _set_node_info_new_for_xml(void)
+{
+ int result = ORCH_ERROR_NONE;
+ GError *error = NULL;
+
+ introspection_data = _gdbus.node_info_new_for_xml(introspection_xml, &error);
+ if (!introspection_data)
+ {
+ printf("g_dbus_node_info_new_for_xml is failed\n");
+ if (error != NULL)
+ {
+ printf("g_dbus_node_info_new_for_xml err [%s]\n", error->message);
+ _gdbus.error_free(error);
+ }
+ result = ORCH_ERROR_DBUS_FAILURE;
+ }
+ return result;
+}
+
+static int _connection_register_object(void)
+{
+ int result = ORCH_ERROR_NONE;
+ guint orch_registration_id;
+
+ orch_registration_id = _gdbus.connection_register_object(_gdbus_conn,
+ _ORCHESTRATION_OBJECT_PATH,
+ introspection_data->interfaces[0],
+ &_interface_vtable,
+ NULL,
+ NULL,
+ NULL);
+
+ if (orch_registration_id == 0)
+ {
+ printf("Failed to g_dbus_connection_register_object\n");
+ result = ORCH_ERROR_DBUS_FAILURE;
+ }
+ return result;
+}
+
+static int _request_service(GVariant *parameters, int origin_client_pid)
+{
+ int result = ORCH_ERROR_NONE;
+
+ char *app_name;
+ int count;
+ bool self_select;
+ int client_pid;
+ GVariantIter *iter;
+ RequestServiceInfo service_info[MAX_SVC_INFO_NUM] = {NULL, };
+
+ if (!parameters)
+ {
+ return ORCH_ERROR_INVALID_PARAMETER;
+ }
+
+ g_variant_get(parameters, "(sia(ss)ii)", &app_name, &self_select, &iter, &count, &client_pid);
+
+ DEBUG("[orchestration dbus_interface] _request_service\n");
+ DEBUG("\t app_name = %s\n", app_name);
+ DEBUG("\t self_select = %s\n", self_select ? "true" : "false");
+ DEBUG("\t count = %d\n", count);
+ DEBUG("\t client_pid = %d\n", client_pid);
+
+ for (int i = 0; i < count; i++) {
+ g_variant_iter_loop (iter, "(ss)", &service_info[i].ExecutionType, &service_info[i].ExeCmd);
+
+ DEBUG("\t service_info[%d].ExecutionType = %s\n", i, service_info[i].ExecutionType);
+ DEBUG("\t service_info[%d].ExeCmd = %s\n", i, service_info[i].ExeCmd);
+ }
+ g_variant_iter_free (iter);
+
+ if (g_strcmp0(app_name, "") == 0)
+ return ORCH_ERROR_INVALID_PARAMETER;
+
+ if (origin_client_pid != client_pid) {
+ DEBUG("not matched clinet_pid from client and dbus, origin_client_pid(%d), client_pid(%d)\n", origin_client_pid, client_pid);
+ }
+
+ char process_name[128] = {0, };
+ const char unknown[] = "Unknown";
+ if (get_process_name_by_pid(process_name, origin_client_pid) != 0) {
+ DEBUG("could not get Process name");
+ strncpy(process_name, unknown, strlen(unknown));
+ }
+
+ result = _request_service_cb(app_name, self_select, service_info, count, process_name);
+
+ return result;
+}
+
+static int _update_key_pair(GVariant *parameters, int origin_client_pid)
+{
+ int result = ORCH_ERROR_NONE;
+
+ char *key;
+ char *id;
+ int client_pid;
+
+ if (!parameters) {
+ return ORCH_ERROR_INVALID_PARAMETER;
+ }
+
+ g_variant_get(parameters, "(ssi)", &id, &key, &client_pid);
+
+ DEBUG("[orchestration dbus_interface] _update_key_pair\n");
+ DEBUG("\t id = %s\n", id);
+ DEBUG("\t key = %s\n", key);
+ DEBUG("\t client_pid = %d\n", client_pid);
+
+ if (g_strcmp0(id, "") == 0 || g_strcmp0(key, "") == 0) {
+ return ORCH_ERROR_INVALID_PARAMETER;
+ }
+
+ if (origin_client_pid != client_pid) {
+ DEBUG("not matched clinet_pid from client and dbus, origin_client_pid(%d), client_pid(%d)\n", origin_client_pid, client_pid);
+ }
+
+ char process_name[128] = {0, };
+ const char unknown[] = "Unknown";
+ if (get_process_name_by_pid(process_name, origin_client_pid) != 0) {
+ DEBUG("could not get Process name");
+ strncpy(process_name, unknown, strlen(unknown));
+ }
+
+ result = _update_key_pair_cb(id, key, process_name);
+
+ return result;
+}
+
+
+static int get_process_name_by_pid(char* process_name, int pid) {
+ char fname[1024] = {0, };
+ char line[1024] = {0, };
+ ssize_t fname_len = snprintf(NULL, 0, "/proc/%d/status", pid);
+
+ snprintf(fname, fname_len + 1, "/proc/%d/status", pid);
+ FILE *fp = fopen(fname, "r");
+ if (fp == NULL) {
+ DEBUG("%d Process not found!!!\n", pid);
+ return -1;
+ }
+ while (!feof(fp)) {
+ fgets(line, 1024, fp);
+ if (strstr(line, "Name:") != NULL) {
+ int index = 0;
+ char *ptr = strchr(line, ':');
+ while (1) {
+ ptr++;
+ if (*ptr == '\n' || *ptr == '\0')
+ break;
+ if (*ptr != ' ' && *ptr != '\t')
+ process_name[index++] = *ptr;
+ }
+ process_name[index] = '\0';
+ printf("process_name = %s\n", process_name);
+ fclose(fp);
+ return 0;
+ }
+ }
+ printf("%d Process status have no Process name!!\n", pid);
+ fclose(fp);
+ return -1;
+}
+
+static int get_pid_with_connection(const gchar* sender) {
+ int origin_client_pid;
+ GError *error = NULL;
+ GVariant * connection;
+
+ connection = g_variant_new ("(s)", sender);
+
+ GVariant *result =
+ _gdbus.connection_call_sync (_gdbus_conn,
+ _FREEDESKTOP_BUS_NAME,
+ _FREEDESKTOP_OBJECT_PATH,
+ _FREEDESKTOP_INTERFACE,
+ _FREEDESKTOP_GETPROCESSID_METHOD,
+ connection,
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_variant_get(result, "(u)", &origin_client_pid);
+ DEBUG("origin_client_pid: %d\n", origin_client_pid);
+
+ if (result)
+ g_variant_unref (result);
+
+ if (error) {
+ DEBUG("Failed to call remote method - %i : %s\n", error->code, error->message);
+ g_error_free (error);
+ error = NULL;
+ g_object_unref (_gdbus_conn);
+ return -1;
+ }
+
+ return origin_client_pid;
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "orchestration_type.h"
+
+#define MAX_KEY_SIZE 256
+
+static char id[MAX_KEY_SIZE];
+static char key[MAX_KEY_SIZE];
+
+int updateKeyPair(char* _id,char* _key) {
+ if (strlen(_id) > MAX_KEY_SIZE) {
+ DEBUG("invalid id size: %u/n", strlen(_id));
+ return -1;
+ }
+ else if (strlen(_key) > MAX_KEY_SIZE) {
+ DEBUG("invalid key size: %u/n", strlen(_key));
+ return -1;
+ }
+ strncpy(id, _id, strlen(_id));
+ strncpy(key, _key, strlen(_key));
+
+ return 0;
+}
+
+char* identityGetter() {
+ return id;
+}
+char* keyGetter(char* id) {
+ return key;
+}
+++ /dev/null
-/*******************************************************************************
- * Copyright 2019 Samsung Electronics All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *******************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "gdbus_interface.h"
-#include "orchestration_server.h"
-
-static _gdbus_interface _gdbus;
-
-static guint owner_id;
-static GDBusConnection *_gdbus_conn;
-static GDBusNodeInfo *introspection_data = NULL;
-
-request_service_cb _request_service_cb = NULL;
-
-#define _ORCHESTRATION_BUS_NAME "org.tizen.orchestration"
-#define _ORCHESTRATION_OBJECT_PATH "/org/tizen/orchestration"
-
-/* Introspection data for the service we are exporting */
-static gchar introspection_xml[] =
- " <node>"
- " <interface name='org.tizen.orchestration.agent'>"
- " <method name='request_service'>"
- " <arg type='s' name='app_name' direction='in'/>"
- " <arg type='i' name='self_select' direction='in'/>"
- " <arg type='a(ss)' name='service_info' direction='in'/>"
- " <arg type='i' name='count' direction='in'/>"
- " <arg type='i' name='client_pid' direction='in'/>"
- " <arg type='i' name='return_value' direction='out'/>"
- " </method>"
- " </interface>"
- " </node>";
-/* ---------------------------------------------------------------------------------------------------- */
-
-#define _FREEDESKTOP_BUS_NAME "org.freedesktop.DBus"
-#define _FREEDESKTOP_OBJECT_PATH "/org/freedesktop/DBus"
-#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus"
-#define _FREEDESKTOP_GETPROCESSID_METHOD "GetConnectionUnixProcessID"
-
-int get_pid_with_connection(const gchar* sender) {
- int origin_client_pid;
- GError *error = NULL;
- GVariant * connection;
-
- connection = g_variant_new ("(s)", sender);
-
- GVariant *result =
- _gdbus.connection_call_sync (_gdbus_conn,
- _FREEDESKTOP_BUS_NAME,
- _FREEDESKTOP_OBJECT_PATH,
- _FREEDESKTOP_INTERFACE,
- _FREEDESKTOP_GETPROCESSID_METHOD,
- connection,
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
-
- g_variant_get(result, "(u)", &origin_client_pid);
- DEBUG("origin_client_pid: %d\n", origin_client_pid);
-
- if (result)
- g_variant_unref (result);
-
- if (error) {
- DEBUG("Failed to call remote method - %i : %s\n", error->code, error->message);
- g_error_free (error);
- error = NULL;
- g_object_unref (_gdbus_conn);
- return -1;
- }
-
- return origin_client_pid;
-}
-
-void set_default_dbus_interface(void)
-{
- _gdbus.get_sync = g_bus_get_sync;
- _gdbus.own_name_on_connection = g_bus_own_name_on_connection;
- _gdbus.unown_name = g_bus_unown_name;
- _gdbus.node_info_new_for_xml = g_dbus_node_info_new_for_xml;
- _gdbus.node_info_unref = g_dbus_node_info_unref;
- _gdbus.connection_register_object = g_dbus_connection_register_object;
- _gdbus.error_free = g_error_free;
- _gdbus.invocation_return_value = g_dbus_method_invocation_return_value;
- _gdbus.connection_call_sync = g_dbus_connection_call_sync;
-}
-
-static int _request_service(GVariant *parameters, int origin_client_pid)
-{
- int result = ORCH_ERROR_NONE;
-
- char *app_name;
- int count;
- bool self_select;
- int client_pid;
- GVariantIter *iter;
- RequestServiceInfo service_info[MAX_SVC_INFO_NUM] = {NULL, };
-
- if (!parameters)
- {
- return ORCH_ERROR_INVALID_PARAMETER;
- }
-
- g_variant_get(parameters, "(sia(ss)ii)", &app_name, &self_select, &iter, &count, &client_pid);
-
- DEBUG("[orchestration dbus_interface] _request_service\n");
- DEBUG("\t app_name = %s\n", app_name);
- DEBUG("\t self_select = %s\n", self_select ? "true" : "false");
- DEBUG("\t count = %d\n", count);
- DEBUG("\t client_pid = %d\n", client_pid);
-
- for (int i = 0; i < count; i++) {
- g_variant_iter_loop (iter, "(ss)", &service_info[i].ExecutionType, &service_info[i].ExeCmd);
-
- DEBUG("\t service_info[%d].ExecutionType = %s\n", i, service_info[i].ExecutionType);
- DEBUG("\t service_info[%d].ExeCmd = %s\n", i, service_info[i].ExeCmd);
- }
- g_variant_iter_free (iter);
-
- if (g_strcmp0(app_name, "") == 0)
- return ORCH_ERROR_INVALID_PARAMETER;
-
- if (origin_client_pid != client_pid) {
- DEBUG("not matched clinet_pid from client and dbus, origin_client_pid(%d), client_pid(%d)\n", origin_client_pid, client_pid);
- }
-
- result = _request_service_cb(app_name, self_select, service_info, count, origin_client_pid);
-
- return result;
-}
-
-static void _handle_method_call(
- GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- int ret = ORCH_ERROR_NONE;
- int origin_client_pid;
-
- origin_client_pid = get_pid_with_connection(sender);
- if (origin_client_pid < 0) {
- DEBUG("get_pid_with_connection error!!\n");
- }
-
- if (g_strcmp0(method_name, "request_service") == 0)
- {
- ret = _request_service(parameters, origin_client_pid);
- }
-
- if (ret == ORCH_ERROR_NONE)
- {
- printf("Orchestration service Success, method name : %s\n", method_name);
- }
- else
- {
- printf("Orchestration service fail, method name : %s\n", method_name);
- }
- _gdbus.invocation_return_value(invocation, g_variant_new("(i)", ret));
-}
-
-static const GDBusInterfaceVTable _interface_vtable =
-{
- _handle_method_call,
- NULL,
- NULL
-};
-
-static int _get_sync(void)
-{
- GError *error = NULL;
- if (_gdbus_conn == NULL)
- {
- _gdbus_conn = _gdbus.get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
- if (_gdbus_conn == NULL)
- {
- if (error != NULL)
- {
- printf("Failed to get dbus [%s]\n", error->message);
- _gdbus.error_free(error);
- }
- return ORCH_ERROR_DBUS_FAILURE;
- }
- }
- return ORCH_ERROR_NONE;
-}
-
-static int _own_name_on_connection(void)
-{
- int result = ORCH_ERROR_NONE;
-
- owner_id = _gdbus.own_name_on_connection(_gdbus_conn,
- _ORCHESTRATION_BUS_NAME,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- NULL,
- NULL,
- NULL,
- NULL);
- if (!owner_id)
- {
- printf("Failed to own name on connection\n");
- result = ORCH_ERROR_DBUS_FAILURE;
- }
- return result;
-}
-
-static int _set_node_info_new_for_xml(void)
-{
- int result = ORCH_ERROR_NONE;
- GError *error = NULL;
-
- introspection_data = _gdbus.node_info_new_for_xml(introspection_xml, &error);
- if (!introspection_data)
- {
- printf("g_dbus_node_info_new_for_xml is failed\n");
- if (error != NULL)
- {
- printf("g_dbus_node_info_new_for_xml err [%s]\n", error->message);
- _gdbus.error_free(error);
- }
- result = ORCH_ERROR_DBUS_FAILURE;
- }
- return result;
-}
-
-static int _connection_register_object(void)
-{
- int result = ORCH_ERROR_NONE;
- guint orch_registration_id;
-
- orch_registration_id = _gdbus.connection_register_object(_gdbus_conn,
- _ORCHESTRATION_OBJECT_PATH,
- introspection_data->interfaces[0],
- &_interface_vtable,
- NULL,
- NULL,
- NULL);
-
- if (orch_registration_id == 0)
- {
- printf("Failed to g_dbus_connection_register_object\n");
- result = ORCH_ERROR_DBUS_FAILURE;
- }
- return result;
-}
-
-static int orch_dbus_initialize(void)
-{
- int result;
-
- result = _get_sync();
- if (result != ORCH_ERROR_NONE)
- {
- printf("Failed to _dbus_init\n");
- goto out;
- }
-
- result = _set_node_info_new_for_xml();
- if (result != ORCH_ERROR_NONE)
- {
- printf("Failed to _set_node_info_new_for_xml\n");
- goto out;
- }
-
- result = _connection_register_object();
- if (result != ORCH_ERROR_NONE)
- {
- printf("Failed to _connection_register_object\n");
- goto out;
- }
-
- result = _own_name_on_connection();
- if (result != ORCH_ERROR_NONE)
- {
- printf("Failed to _dbus_own_name_onconnection\n");
- goto out;
- }
-
-out:
- return result;
-}
-
-int orchestration_server_initialize(request_service_cb cb)
-{
- int result = ORCH_ERROR_NONE;
-
- if (cb == NULL)
- {
- result = ORCH_ERROR_INVALID_PARAMETER;
- printf("request_service_cb is null\n");
- goto out;
- }
- _request_service_cb = cb;
-
- if (!owner_id)
- {
- result = orch_dbus_initialize();
- if (result != ORCH_ERROR_NONE)
- {
- printf("orch_dbus_initialize is failed\n");
- goto out;
- }
- }
-
-out:
- return result;
-}
-
-void orchestration_server_finish(void)
-{
- if (owner_id)
- {
- _gdbus.unown_name(owner_id);
- }
- if (introspection_data)
- {
- _gdbus.node_info_unref(introspection_data);
- }
- printf("orchestration_server_finish\n");
-}
--- /dev/null
+/*******************************************************************************
+ * Copyright 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *******************************************************************************/
+
+#include <orchestration_service.h>
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <gio/gio.h>
+
+#include "orchestration_key.h"
+
+static int request_service(
+ char* app_name,
+ bool self_select,
+ requestServiceInfo service_info[],
+ int count,
+ char* client_pname);
+static int update_key_pair(
+ char* id,
+ char* key,
+ char* client_pname);
+
+void *orchestration_service_thread() {
+ DEBUG("Start OrchestrationInit Thread !!\n");
+ OrchestrationInit();
+ SetPSKHandler(identityGetter, keyGetter);
+
+ return NULL;
+}
+
+_orchestration_state_e orchestration_service_start() {
+ pthread_t p_thread;
+
+ if (pthread_create(&p_thread, NULL, orchestration_service_thread, NULL) != 0) {
+ DEBUG("Fail to start OrchestrationInit Thread !!");
+ return ORCH_ERROR_NOT_READY;
+ }
+
+ return ORCH_ERROR_NONE;
+}
+
+dbus_funcs getDbusFuncs() {
+ dbus_funcs funcs;
+ funcs.request_service_f = request_service;
+ funcs.update_key_pair_f = update_key_pair;
+ return funcs;
+}
+
+static int request_service(char* app_name, bool self_select, requestServiceInfo service_info[], int count, char* client_pname){
+ int ret = ORCH_ERROR_NONE;
+ ResponseService result;
+
+ DEBUG("[orchestration_server]\n")
+ DEBUG("\t app_name : %s\n", app_name);
+ DEBUG("\t self_select : %s\n", self_select ? "true" : "false");
+ DEBUG("\t count : %d\n", count);
+ DEBUG("\t process_name : %s\n", client_pname);
+ for (int ix = 0; ix < count; ix++) {
+ DEBUG("\t service_info[%d].ExecutionType : %s\n", ix, service_info[ix].ExecutionType);
+ DEBUG("\t service_info[%d].ExeCmd : %s\n", ix, service_info[ix].ExeCmd);
+ }
+
+ result = OrchestrationRequestService(app_name, self_select, client_pname, service_info, count);
+ DEBUG("result = %s\n", result.Message);
+
+ /* TO DO : parsing API response */
+ return ret;
+}
+
+#define ALLOWED_KEY_UPDATER "homeedge"
+
+static int update_key_pair(char* id, char* key, char* client_pname) {
+ if (g_strcmp0(client_pname, ALLOWED_KEY_UPDATER) != 0) {
+ DEBUG("process_name : %s -> is not allowed.\n", client_pname);
+ return -1;
+ }
+
+ return updateKeyPair(id, key);
+}
# Build parameter
CC := g++
-CFLAGS := -g -Wall -Werror
+CFLAGS := -g -Wall -Werror -Wno-unused-function
LIBS := -lgtest -lgtest_main -lpthread -fprofile-arcs -ftest-coverage
# BUILDFLAGS := -lgtest -lgtest_main -lpthread -fprofile-arcs -ftest-coverage
extern "C"
{
-#include "orchestration_server.c"
+#include "orchestration_dbus_server.c"
+#include <orchestration_type.h>
#include <gio/gio.h>
}
GDBusInterfaceInfo *valid_GDBusinterface;
gboolean requestCbResult;
-int fake_request_cb(char* app_name, bool self_select, RequestServiceInfo service_info[], int count, int client_pid)
+int fake_request_cb(char* app_name, bool self_select, RequestServiceInfo service_info[], int count, char * client_pname)
{
if (!strcmp(app_name, APP_NAME) &&
count == 1 &&
}
}
+int fake_update_key_pair(char* id, char* key, char* client_pname) {
+ if (id != NULL && key != NULL && client_pname != NULL) {
+ return 1;
+ }
+ return -1;
+}
+
GDBusConnection *fake_get_sync_return_NULL(GBusType bus_type, GCancellable *cancellable, GError **error)
{
*error = NULL;
TEST_F(OrchestrationServerTests, WhenCalledServerInit_WithInvalidcb_ExpectedErrorReturn)
{
- ASSERT_EQ(orchestration_server_initialize(NULL), ORCH_ERROR_INVALID_PARAMETER);
+ dbus_funcs fake_funcs;
+ fake_funcs.request_service_f = NULL;
+ fake_funcs.update_key_pair_f = NULL;
+ ASSERT_EQ(orchestration_server_initialize(fake_funcs), ORCH_ERROR_INVALID_PARAMETER);
}
TEST_F(OrchestrationServerTests, WhenCalledServerInit_OccuredDbusError_ExpectedErrorReturn)
set_default_dbus_interface();
_gdbus.get_sync = fake_get_sync_return_NULL;
- ASSERT_EQ(orchestration_server_initialize(fake_request_cb), ORCH_ERROR_DBUS_FAILURE);
+ dbus_funcs fake_funcs;
+ fake_funcs.request_service_f = fake_request_cb;
+ fake_funcs.update_key_pair_f = fake_update_key_pair;
+
+ ASSERT_EQ(orchestration_server_initialize(fake_funcs), ORCH_ERROR_DBUS_FAILURE);
}
TEST_F(OrchestrationServerTests, WhenCalledOrchDbusInit_GetSyncFailure_ExpectedErrorReturn)
_gdbus.node_info_new_for_xml = fake_node_info_new_for_xml_success;
_gdbus.connection_register_object = fake_connection_register_object_success;
- ASSERT_EQ(orchestration_server_initialize(fake_request_cb), ORCH_ERROR_NONE);
+ dbus_funcs fake_funcs;
+ fake_funcs.request_service_f = fake_request_cb;
+ fake_funcs.update_key_pair_f = fake_update_key_pair;
+
+ ASSERT_EQ(orchestration_server_initialize(fake_funcs), ORCH_ERROR_NONE);
if (valid_GDBusConnection != NULL)
{
#include <stdio.h>
#include <string.h>
#include <dbus_consumer.h>
+#include <gio/gio.h>
/* ---------------------------------------------------------------------------------------------------- */
orchestration_changed_service_status_cb _changed_service_status_cb;
%attr(755,system_fw,system_fw)%{_includedir}/%{name}/orchestration_client.h
# orchestration sample
%attr(755,system_fw,system_fw)%{_bindir}/edge_*
-%attr(755,system_fw,system_fw)/var/%{name}/apps/native_sample/*
\ No newline at end of file
+%attr(755,system_fw,system_fw)/var/%{name}/apps/native_sample/*