Add subgroup imeplementation
authorJihoon Jung <jh8801.jung@samsung.com>
Tue, 23 Jan 2018 12:18:36 +0000 (21:18 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:47 +0000 (19:38 +0900)
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
13 files changed:
capi/demo/comp-manager.c
capi/include/companion.h
capi/src/companion.c
capi/src/companion_gdbus.xml
src/companion-manager/include/comp_context.h
src/companion-manager/include/comp_gdbus_group.h
src/companion-manager/include/comp_group.h
src/companion-manager/include/comp_iot.h
src/companion-manager/src/comp_gdbus.c
src/companion-manager/src/comp_gdbus_group.c
src/companion-manager/src/comp_group.c [changed mode: 0644->0755]
src/companion-manager/src/comp_iot.c
src/companion-manager/src/companion_gdbus.xml

index 49554b89e73062dfb7a07f362aa41b1402e07288..4273776594f37d70c8332c075a5383fe7bd1e95c 100644 (file)
@@ -30,6 +30,7 @@
 GList *found_group_list;
 GList *found_device_list;
 GList *my_devices_list;
+GList *found_subgroup_list;
 
 static char groupid[MENU_DATA_SIZE + 1] = "mygroup";
 static char timeout[MENU_DATA_SIZE + 1] = "5";
@@ -39,6 +40,8 @@ static char group_idx_b[MENU_DATA_SIZE + 1] = "2";
 static char device_idx[MENU_DATA_SIZE + 1] = "1";
 static char pin[MENU_DATA_SIZE + 1] = "12341234";
 static char message[MENU_DATA_SIZE + 1] = "Hello World!!";
+static char subgroupid[MENU_DATA_SIZE + 1] = "subgroup";
+static char subgroup_idx[MENU_DATA_SIZE + 1] = "1";
 
 int run_get_my_id(MManager *mm, struct menu_data *menu)
 {
@@ -590,6 +593,37 @@ static int run_group_show(MManager *mm, struct menu_data *menu)
        return RET_SUCCESS;
 }
 
+static int run_subgroup_show(MManager *mm, struct menu_data *menu)
+{
+       char *name;
+       companion_group_h subgroup;
+
+       int i;
+       GList *iter = NULL;
+
+       /* Get a first item */
+       i = 0;
+       iter = g_list_first(found_subgroup_list);
+       while (NULL != iter) {
+               subgroup = iter->data;
+               if (!subgroup) {
+                       msgr("subgroup is null");
+                       break;
+               }
+               companion_group_information_get_name(subgroup, &name);
+               msgb("[%d] subgroup name: %s", i+1, name);
+               if (name) {
+                       free(name);
+                       name = NULL;
+               }
+               /* Next item */
+               iter = g_list_next(iter);
+               i++;
+       }
+
+       return RET_SUCCESS;
+}
+
 static void _group_join_finish_cb(int result, void *user_data)
 {
        msgp("join operation finished");
@@ -849,6 +883,132 @@ int run_device_show_mowned_device(MManager *mm, struct menu_data *menu)
 
        return RET_SUCCESS;
 }
+static int run_create_subgroup(MManager *mm, struct menu_data *menu)
+{
+       int ret = 0;
+       int grp_count = 0;
+       int dev_count = 0;
+       companion_device_h device = NULL;
+       companion_group_h group = NULL;
+
+       dev_count = g_list_length(found_device_list);
+       grp_count = g_list_length(found_group_list);
+
+       if (0 >= dev_count || 0 >= grp_count) {
+               msgr("No Device");
+               return RET_SUCCESS;
+       }
+
+       group = (companion_group_h)(found_group_list[atoi(group_idx) - 1].data);
+       device = (companion_device_h)(found_device_list[atoi(device_idx) - 1].data);
+
+       ret = companion_create_subgroup(group, device, subgroupid);
+       if (COMP_ERROR_NONE != ret) {
+               msgr("Failed to Create Subgroup: [%s(0x%X)]", comp_error_to_string(ret), ret);
+               return RET_FAILURE;
+       }
+
+       msg(" - companion_create_subgroup() ret: [0x%X] [%s]", ret, comp_error_to_string(ret));
+
+       return RET_SUCCESS;
+}
+
+static int run_get_subgroup(MManager *mm, struct menu_data *menu)
+{
+       int ret;
+       int count;
+       companion_group_h group = NULL;
+       companion_group_h *subgroups;
+
+       msg("Get Subgroups");
+
+       count = g_list_length(found_group_list);
+
+       if (0 >= count) {
+               msgr("No Device");
+               return RET_SUCCESS;
+       }
+
+       group = (companion_group_h)(found_group_list[atoi(group_idx - 1)].data);
+
+       ret = companion_get_subgroups(group, &subgroups, &count);
+       if (COMP_ERROR_NONE != ret) {
+               msgr("Failed to Get Found Groups: [%s(0x%X)]", comp_error_to_string(ret), ret);
+               return RET_FAILURE;
+       }
+       msg(" - companion_get_subgroups() ret: [0x%X] [%s]", ret, comp_error_to_string(ret));
+
+       for (int i = 0; i < count; i++) {
+               char *name;
+               companion_group_information_get_name(subgroups[i], &name);
+               msgb("%d. name : %s", i+1, name);
+               found_subgroup_list = g_list_prepend(found_subgroup_list, subgroups[i]);
+       }
+
+       return RET_SUCCESS;
+}
+
+static int run_add_device_to_subgroup(MManager *mm, struct menu_data *menu)
+{
+       int ret = 0;
+       int subgrp_count = 0;
+       int dev_count = 0;
+       companion_device_h device = NULL;
+       companion_group_h subgroup = NULL;
+
+       dev_count = g_list_length(found_device_list);
+       subgrp_count = g_list_length(found_subgroup_list);
+
+       if (0 >= dev_count || 0 >= subgrp_count) {
+               msgr("No Device");
+               return RET_SUCCESS;
+       }
+
+       subgroup = (companion_group_h)(found_subgroup_list[atoi(subgroup_idx) - 1].data);
+       device = (companion_device_h)(found_device_list[atoi(device_idx) - 1].data);
+
+       ret = companion_add_device_to_subgroup(subgroup, device);
+       if (COMP_ERROR_NONE != ret) {
+               msgr("Failed to Create Subgroup: [%s(0x%X)]", comp_error_to_string(ret), ret);
+               return RET_FAILURE;
+       }
+
+       msg(" - companion_create_subgroup() ret: [0x%X] [%s]", ret, comp_error_to_string(ret));
+
+       return RET_SUCCESS;
+}
+
+static int run_delete_subgroup(MManager *mm, struct menu_data *menu)
+{
+       int ret = 0;
+       int grp_count = 0;
+       int dev_count = 0;
+       companion_device_h device = NULL;
+       companion_group_h group = NULL;
+
+       dev_count = g_list_length(found_device_list);
+       grp_count = g_list_length(found_group_list);
+
+       if (0 >= dev_count || 0 >= grp_count) {
+               msgr("No Device");
+               return RET_SUCCESS;
+       }
+
+       group = (companion_group_h)(found_group_list[atoi(group_idx - 1)].data);
+       device = (companion_device_h)(found_device_list[atoi(device_idx - 1)].data);
+
+       msgr("Device selected");
+
+       ret = companion_create_subgroup(group, device, subgroupid);
+       if (COMP_ERROR_NONE != ret) {
+               msgr("Failed to Create Subgroup: [%s(0x%X)]", comp_error_to_string(ret), ret);
+               return RET_FAILURE;
+       }
+
+       msg(" - companion_create_subgroup() ret: [0x%X] [%s]", ret, comp_error_to_string(ret));
+
+       return RET_SUCCESS;
+}
 
 
 static struct menu_data menu_group_create[] = {
@@ -936,6 +1096,41 @@ static struct menu_data menu_devices_find_mownd_device[] = {
        { NULL, NULL, },
 };
 
+static struct menu_data menu_create_subgroup[] = {
+       { "0", "Show Found Group(s)", NULL, run_group_show, NULL },
+       { "1", "Show Found Device(s)", NULL, run_devices_show, NULL },
+       { "2", "Group Index", NULL, NULL, group_idx },
+       { "3", "Device Index", NULL, NULL, device_idx },
+       { "4", "Subgroup Name", NULL, NULL, subgroupid },
+       { "5", "Run", NULL, run_create_subgroup, NULL },
+       { NULL, NULL, },
+};
+
+static struct menu_data menu_get_subgroups[] = {
+       { "0", "Show Found Group(s)", NULL, run_group_show, NULL },
+       { "1", "Group Index", NULL, NULL, group_idx },
+       { "2", "Run", NULL, run_get_subgroup, NULL },
+       { NULL, NULL, },
+};
+
+static struct menu_data menu_add_device_to_subgroup[] = {
+       { "0", "Show Subgroup(s)", NULL, run_subgroup_show, NULL },
+       { "1", "Show Found Device(s)", NULL, run_devices_show, NULL },
+       { "2", "Subgroup Index", NULL, NULL, subgroup_idx },
+       { "3", "Device Index", NULL, NULL, device_idx },
+       { "4", "Run", NULL, run_add_device_to_subgroup, NULL },
+       { NULL, NULL, },
+};
+
+static struct menu_data menu_delete_subgroup[] = {
+       { "0", "Show Found Group(s)", NULL, run_group_show, NULL },
+       { "1", "Show Found Device(s)", NULL, run_devices_show, NULL },
+       { "2", "Group Index", NULL, NULL, group_idx },
+       { "3", "Device Index", NULL, NULL, device_idx },
+       { "4", "Subgroup Name", NULL, NULL, subgroupid },
+       { "5", "Run", NULL, run_delete_subgroup, NULL },
+       { NULL, NULL, },
+};
 struct menu_data menu_comp_manager[] = {
        { "0", "Get My Device ID", NULL, run_get_my_id, NULL },
        { "1", "Group Create", menu_group_create, NULL, NULL },
@@ -954,5 +1149,9 @@ struct menu_data menu_comp_manager[] = {
        { "14", "Find My Onwed Device(s)", menu_devices_find_mownd_device, NULL, NULL },
        { "15", "Show My Onwed Device(s)", NULL, run_device_show_mowned_device, NULL},
        { "16", "Send Message", menu_send_data, NULL, NULL },
+       { "17", "Create Subgroup", menu_create_subgroup, NULL, NULL },
+       { "18", "Get Subgroups", menu_get_subgroups, NULL, NULL },
+       { "19", "Add device to Subgroup", menu_add_device_to_subgroup, NULL, NULL },
+       { "20", "Delete Subgroup", menu_delete_subgroup, NULL, NULL },
        { NULL, NULL, },
 };
index 8ebc447f5d8fd1340ee9c8e8c6748dc32af6400c..e27ad5ae3b7b83aa72d191f7048ca98573158b0f 100644 (file)
@@ -109,6 +109,12 @@ int companion_device_information_get_device_type(companion_device_h device, char
 
 int companion_send_data(companion_device_h device, char *data, companion_send_data_finish_cb finish_cb, void *user_data);
 
+int companion_create_subgroup(companion_group_h group, companion_device_h device, char *subgroup_name);
+int companion_get_subgroups(companion_group_h group, companion_group_h **subgroups, int *count);
+int companion_add_device_to_subgroup(companion_group_h subgroup, companion_device_h device);
+int companion_delete_subgroup(companion_group_h subgroup);
+
+
 #ifdef __cplusplus
 }
 #endif
index 943defda92210dad3c842910cd3876e3d848788c..e40513939b90aba79ed80917d86ca4ff93445d02 100644 (file)
@@ -657,6 +657,7 @@ int companion_device_invite(companion_group_h group,
        int ret = 0;
        GError *error = NULL;
        companion_device_t *dev = (companion_device_t *)device;
+       companion_group_t *grp = (companion_group_t *)group;
 
        device_invite_result_cb.result_cb = result_cb;
        device_invite_result_cb.user_data = user_data;
@@ -665,7 +666,7 @@ int companion_device_invite(companion_group_h group,
 #if 0
        group_call_device_invite_sync(group_proxy, dev->device_id, PIN, &ret, NULL, &error);
 #else
-       group_call_invite_sync(group_proxy, dev->device_id, PIN, &ret, NULL, &error);
+       group_call_invite_sync(group_proxy, grp->group_name, dev->device_id, PIN, &ret, NULL, &error);
 #endif
 
        return ret;
@@ -784,6 +785,13 @@ int companion_group_information_get_uri_path(companion_group_h group, char **uri
        return 0;
 }
 
+int companion_group_information_get_name(companion_group_h group, char **name)
+{
+       *name = g_strdup(((companion_group_t *)group)->group_name);
+
+       return 0;
+}
+
 int companion_device_information_create(companion_device_h* device)
 {
        companion_device_h _device = g_malloc0(sizeof(companion_device_t));
@@ -864,3 +872,98 @@ int companion_device_information_get_device_type(companion_device_h device, char
 
        return 0;
 }
+
+int companion_create_subgroup(companion_group_h group, companion_device_h device, char *subgroup_name)
+{
+       int ret;
+       GError *error = NULL;
+       companion_device_t *dev = (companion_device_t *)device;
+       companion_group_t *grp = (companion_group_t *)group;
+       _ERR("%s", dev->device_id);
+
+       group_call_create_subgroup_sync(group_proxy, grp->group_name, dev->device_id, subgroup_name, &ret, NULL, &error);
+
+       return ret;
+}
+
+int companion_get_subgroups(companion_group_h group, companion_group_h **subgroups, int *count)
+{
+       int ret = 0;
+       GVariant *va = NULL;
+       GError *error = NULL;
+       companion_group_t *grp = (companion_group_t *)group;
+
+       _ERR("%s", grp->group_name);
+
+       /* get groups from daemon using gdbus */
+       group_call_get_subgroups_sync(group_proxy, grp->group_name, &va, &ret, NULL, &error);
+       *count = g_variant_n_children(va);
+
+       _ERR("get subgroups : %d", *count);
+
+       if (*count > 0) {
+               GVariantIter *iter = NULL, *iter_row = NULL;
+               GVariant *key_value;
+               const gchar *key;
+               guint i = 0;
+
+               *subgroups = g_new0(companion_group_h, *count);
+
+               g_variant_get(va, "aa{sv}", &iter);
+               while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+                       companion_group_t *subgroup = NULL;
+                       companion_group_type_e type;
+                       char *uri_path;
+                       char *device_id;
+                       char *group_name;
+                       char *host_addr;
+                       char *resource_type;
+
+                       while (g_variant_iter_loop(iter_row, "{sv}", &key, &key_value)) {
+                               if (g_strcmp0(key, "URI") == 0) {
+                                       uri_path = (char *)g_variant_get_string(key_value, NULL);
+                               } else if (g_strcmp0(key, "DeviceID") == 0) {
+                                       device_id = (char *)g_variant_get_string(key_value, NULL);
+                               } else if (g_strcmp0(key, "GroupName") == 0) {
+                                       group_name = (char *)g_variant_get_string(key_value, NULL);
+                               } else if (g_strcmp0(key, "HostAddress") == 0) {
+                                       host_addr = (char *)g_variant_get_string(key_value, NULL);
+                               } else if (g_strcmp0(key, "GroupDeviceType") == 0) {
+                                       resource_type = (char *)g_variant_get_string(key_value, NULL);
+                               } else if (g_strcmp0(key, "GroupType") == 0) {
+                                       type = g_variant_get_int32(key_value);
+                               }
+                       }
+                       g_variant_iter_free(iter_row);
+
+                       subgroup = _create_group_handle(uri_path,
+                               device_id, group_name, host_addr, resource_type, type);
+
+                       (*subgroups)[i++] = (companion_group_h)subgroup;
+               }
+               g_variant_iter_free(iter);
+       }
+       g_variant_unref(va);
+
+       return ret;
+}
+
+int companion_add_device_to_subgroup(companion_group_h subgroup, companion_device_h device)
+{
+       int ret = 0;
+       GError *error = NULL;
+       companion_group_t *subgrp = (companion_group_t *)subgroup;
+       companion_device_t *dev = (companion_device_t *)device;
+
+       _ERR("%s", subgrp->group_name);
+
+       group_call_add_device_to_subgroup(group_proxy, subgrp->group_name, dev->device_id, &ret, NULL, &error);
+
+       return ret;
+}
+
+int companion_delete_subgroup(companion_group_h subgroup)
+{
+
+}
+
index 0b01eff386f1e7bd3ce51cbcfd4b21d045aebdca..e643210525a2be078c6e51ee74c791a9961eb168 100644 (file)
@@ -40,6 +40,7 @@
                        <arg type="i" name="result" direction="out" />
                </method>
                <method name="Invite">
+                       <arg type="s" name="group_name" direction="in"/>
                        <arg type="s" name="uuid" direction="in"/>
                        <arg type="s" name="pin" direction="in" />
                        <arg type="i" name="result" direction="out"/>
                <method name="GetMyUuid">
                        <arg type="s" name="uuid" direction="out" />
                </method>
+               <method name="CreateSubgroup">
+                       <arg type="s" name="group_name" direction="in" />
+                       <arg type="s" name="uuid" direction="in" />
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="GetSubgroups">
+                       <arg type="s" name="group_name" direction="in" />
+                       <arg type="aa{sv}" name="groups" direction="out" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="AddDeviceToSubgroup">
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="s" name="uuid" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="DeleteSubgroup">
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
                <!-- Signal (D-Bus) definitions -->
                <signal name="GroupFound">
                        <arg type="a{sv}" name="group_info" direction="out" />
index 1f1bbc4ebfe908d33f2b33ac47b84599804995e8..ec108875de399fb92ceca7761f0b2ce428c33b2a 100644 (file)
@@ -17,7 +17,8 @@ typedef struct {
 
        char *device_uuid;
        bool mot_me; /**< Indicator whether mot local comp-manager */
-       int operation_resource_count;
+       GList *grp_list;
+       GList *pairwise_list;
 } comp_context_t;
 
 int comp_context_create();
index 70d2e19adbd5e3057516450248643a6ad63de580..7a5f2f6d5ac9f21238bd3fa850e329e163734310 100644 (file)
@@ -34,7 +34,7 @@ gboolean group_device_invite(Group *group, GDBusMethodInvocation *invocation,
 gboolean group_device_eject(Group *group, GDBusMethodInvocation *invocation,
        gchar *uuid_dev1, gchar *uuid_dev2, gpointer user_data);
 
-gboolean group_invite(Group *group, GDBusMethodInvocation *invocation,
+gboolean group_invite(Group *group, GDBusMethodInvocation *invocation, gchar *group_name,
        gchar *uuid, gchar *pin, gpointer user_data);
 
 gboolean group_eject(Group *group, GDBusMethodInvocation *invocation,
@@ -67,6 +67,18 @@ gboolean group_get_my_mowned_device(Group *group,
 gboolean group_get_my_uuid(Group *group,
        GDBusMethodInvocation *invocation, gpointer user_data);
 
+gboolean group_create_subgroup(Group *group, GDBusMethodInvocation *invocation,
+ gchar *group_name, gchar *uuid, gchar *subgroup_name, gpointer user_data);
+
+gboolean group_get_subgroups(Group *group, GDBusMethodInvocation *invocation,
+ gchar *group_name, gpointer user_data);
+
+gboolean group_add_device_to_subgroup(Group *group, GDBusMethodInvocation *invocation,
+ gchar *subgroup_name, gchar *uuid, gpointer user_data);
+
+gboolean group_delete_subgroup(Group *group, GDBusMethodInvocation *invocation,
+       gchar *subgroup_name, gpointer user_data);
+
 void notify_group_found(GVariant *group_data);
 void notify_group_find_finish(int ret);
 void notify_device_found(int device_count, GVariant *device_data);
index f929ac8c120cfec5834eb980f11c4d3dbe0ecbd1..ae8409ecc5809653b6eca4629e4be35ed782229b 100755 (executable)
@@ -66,10 +66,7 @@ int comp_group_find_mot_enabled_devices();
 char *comp_group_invite_get_uuid();
 char *comp_group_invite_get_pin();
 //Join to device in group (async)
-int comp_group_invite(gchar *uuid_dev1, gchar *uuid_dev2, gchar *pin,
-                                       gchar *uri_1, gchar *rt_1, gchar *interface_1,
-                                       int permission_1, gchar *uri_2, gchar *rt_2,
-                                       gchar *interface_2, int permission_2);
+int comp_group_invite(char *group_name, char *uuid, char *pin);
 comp_group_invite_info_t *comp_group_get_invite_info();
 void comp_group_free_invite_info();
 void comp_group_notify_group_invite(int result);
@@ -110,5 +107,12 @@ int comp_group_get_group_device_id(comp_group_t *handle);
 
 /* notify */
 int comp_group_event_handler(/*callback*/); // event hadnler
+int comp_group_add_device_in_group(char *group_name, char *uuid);
+int comp_group_add_subgroup_in_group(char *group_name, char *uuid, char *subgroup_name);
+
+int comp_group_create_subgroup(char *group_name, char *uuid, char *subgroup_name);
+GVariant *comp_group_get_subgroups(char *group_name);
+int comp_group_add_device_to_subgroup(char *subgroup_name, char *uuid);
+int comp_group_delete_subgroup(char *subgroup_name);
 
 #endif
index 4f814799f9eec80452bf480de7514e28caf443f2..8ebb3674c1eca76a1f61f066c620e90c2695e4d5 100755 (executable)
@@ -10,6 +10,15 @@ typedef struct _iot_discovery_t {
        gchar *data;
 } iot_discovery_t;
 
+typedef struct _comp_command_t {
+       gchar *command;
+       gchar *uuid;
+       gchar *arg1;
+       gchar *arg2;
+       gchar *arg3;
+       gchar *arg4;
+} comp_command_t;
+
 int comp_iot_initialize();
 int comp_iot_add_resource(comp_resource_type_e resource_type, char *uri);
 int comp_iot_delete_resource(comp_resource_type_e resource_type);
index 4d8e6996178611395d17b3b6167cbb89c2f5f4f3..c81c9b9894d4c648a9ab14b254e080d7f863f673 100644 (file)
@@ -114,6 +114,26 @@ static bool __group_init(GDBusConnection *connection)
                G_CALLBACK(group_get_my_uuid),
                NULL);
 
+       g_signal_connect(group_skeleton,
+               "handle-create-subgroup",
+               G_CALLBACK(group_create_subgroup),
+               NULL);
+
+       g_signal_connect(group_skeleton,
+               "handle-get-subgroups",
+               G_CALLBACK(group_get_subgroups),
+               NULL);
+
+       g_signal_connect(group_skeleton,
+               "handle-add-device-to-subgroup",
+               G_CALLBACK(group_add_device_to_subgroup),
+               NULL);
+
+       g_signal_connect(group_skeleton,
+               "handle-delete-subgroup",
+               G_CALLBACK(group_delete_subgroup),
+               NULL);
+
        group = g_dbus_object_manager_server_new(COMP_DBUS_GROUP_PATH);
 
        // Set connection to 'manager'
index c703e5350e4bdfaa66a3c1ab9a92bcbd29c1a2ce..ab976318388dca04b8040316a6cfa8ada763064d 100644 (file)
@@ -94,11 +94,11 @@ gboolean group_device_invite(Group *group, GDBusMethodInvocation *invocation,
        gint result = 0;
 
        LOG_DEBUG("group device invite called using dbus successful");
-
+/*
        result = comp_group_invite(uuid_dev1, uuid_dev2, pin, uri_1, rt_1,
                                        interface_1, permission_1, uri_2, rt_2, interface_2,
                                        permission_2);
-
+*/
        group_complete_device_invite(group, invocation, result);
 
        return TRUE;
@@ -118,24 +118,14 @@ gboolean group_device_eject(Group *group, GDBusMethodInvocation *invocation,
        return TRUE;
 }
 
-#include "comp_context.h"
-
-#define FULL_PERMISSION 31
-
-gboolean group_invite(Group *group, GDBusMethodInvocation *invocation,
+gboolean group_invite(Group *group, GDBusMethodInvocation *invocation, gchar *group_name,
        gchar *uuid, gchar *pin, gpointer user_data)
 {
        gint result = 0;
 
-       comp_context_t *comp_ctx = comp_context_get_context();
-       if (!comp_ctx) {
-               LOG_ERR("ctx is null");
-               return FALSE;
-       }
+       LOG_DEBUG("group invite called using dbus successful");
 
-       result = comp_group_invite(comp_ctx->device_uuid, uuid, pin,
-               "/comp/data/1", "core.comp.data", "oic.if.baseline", FULL_PERMISSION,
-               "/comp/data/1", "core.comp.data", "oic.if.baseline", FULL_PERMISSION);
+       result = comp_group_invite(group_name, uuid, pin);
 
        /* Now, for the sake of convenience, we change 'group_complete_invite' to 'group_complete_device_invite'. */
 #if 0
@@ -289,6 +279,63 @@ gboolean group_get_my_uuid(Group *group,
        return TRUE;
 }
 
+gboolean group_create_subgroup(Group *group, GDBusMethodInvocation *invocation,
+ gchar *group_name, gchar *uuid, gchar *subgroup_name, gpointer user_data)
+{
+       int ret = 0;
+
+       LOG_DEBUG("create subgroup called using dbus successful");
+
+       ret = comp_group_create_subgroup(group_name, uuid, subgroup_name);
+
+       group_complete_create_subgroup(group, invocation, ret);
+
+       return TRUE;
+}
+
+gboolean group_get_subgroups(Group *group, GDBusMethodInvocation *invocation,
+ gchar *group_name, gpointer user_data)
+{
+       int ret = 0;
+       GVariant *group_data;
+
+       LOG_DEBUG("get subgroups called using dbus successful : %s", group_name);
+
+       group_data = comp_group_get_subgroups(group_name);
+
+       group_complete_get_subgroups(group, invocation, group_data, ret);
+
+       return TRUE;
+}
+
+gboolean group_add_device_to_subgroup(Group *group, GDBusMethodInvocation *invocation,
+ gchar *subgroup_name, gchar *uuid, gpointer user_data)
+{
+       int ret = 0;
+
+       LOG_DEBUG("Add device to subgroup called using dbus successful");
+
+       ret = comp_group_add_device_to_subgroup(subgroup_name, uuid);
+
+       group_complete_add_device_to_subgroup(group, invocation, ret);
+
+       return TRUE;
+}
+
+gboolean group_delete_subgroup(Group *group, GDBusMethodInvocation *invocation,
+       gchar *subgroup_name, gpointer user_data)
+{
+       int ret = 0;
+
+       LOG_DEBUG("Delete subgroup called using dbus successful");
+
+       ret = comp_group_delete_subgroup(subgroup_name);
+
+       group_complete_delete_subgroup(group, invocation, ret);
+
+       return TRUE;
+}
+
 void notify_group_found(GVariant *group_data)
 {
        group_emit_group_found(group_dbus_get_object(), group_data);
old mode 100644 (file)
new mode 100755 (executable)
index 9a14ad9..6721de9
@@ -16,6 +16,48 @@ int comp_group_initialize()
        return COMP_ERROR_NONE;
 }
 
+typedef struct {
+       char *uuid; //remote device uuid
+       char *name; //subgroup name
+} comp_subgrp_t;
+
+typedef struct {
+       char *name; //group name
+       GList *device_list; //remote device UUIDs. char* type
+       GList *subgroup_list; //comp sub group t type
+} comp_grp_t;
+
+void __print_foreach_subgroup(gpointer data, gpointer user_data)
+{
+       comp_subgrp_t *sub_grp = (comp_subgrp_t *)data;
+       LOG_DEBUG("        - Group name : %s, uuid : %s", sub_grp->name, sub_grp->uuid);
+}
+
+void __print_foreach_device(gpointer data, gpointer user_data)
+{
+       char *uuid = (char *)data;
+       LOG_DEBUG("        - %s", uuid);
+}
+
+void __print_foreach_grp(gpointer data, gpointer user_data)
+{
+       comp_grp_t *grp = (comp_grp_t *)data;
+       LOG_DEBUG("Group name : %s", grp->name);
+       LOG_DEBUG("    <Device>");
+       g_list_foreach(grp->device_list, __print_foreach_device, NULL);
+       LOG_DEBUG("    <Sub Group>");
+       g_list_foreach(grp->subgroup_list, __print_foreach_subgroup, NULL);
+       LOG_DEBUG("");
+}
+
+void __print_groups_information()
+{
+       comp_context_t *comp_ctx = comp_context_get_context();
+       LOG_DEBUG("-------------------------------------------");
+       g_list_foreach(comp_ctx->grp_list, __print_foreach_grp, NULL);
+       LOG_DEBUG("-------------------------------------------");
+}
+
 /* create group and destroy */
 int comp_group_create(char* name)
 {
@@ -29,18 +71,26 @@ int comp_group_create(char* name)
                LOG_ERR("Add resource is failed : %s", comp_log_get_error_string(ret));
        }
 
+       comp_context_t *comp_ctx = comp_context_get_context();
+       GList *list = comp_ctx->grp_list;
 
-       /* A own group device is included in the created group by default. */
-       /* I would like to use multiple group device resource for this created group resources.
-               If there is a better way, please change it.
+       GList *l;
+       for (l = list; l != NULL; l = l->next) {
+               comp_grp_t *grp = (comp_grp_t *)l->data;
+
+               if (strcmp(grp->name, name) == 0) {
+                       LOG_ERR("already exists name in structure");
+                       return COMP_ERROR_UNKNOWN;
+               }
+       }
 
-               Group/Jihoon (Group (In this daemon))
-                       - Group/Device123123 (Group Device (In this daemon))
-                       - Group/Device3321 (Group Device (remote))
-                       - Group/Device1101 (Group Device (remote))
-       */
+       comp_grp_t *grp = g_new0(comp_grp_t, 1);
+       grp->name = strdup(name);
+
+       comp_ctx->grp_list = g_list_prepend(comp_ctx->grp_list, grp);
 
        comp_resource_print_list();
+       __print_groups_information();
 
        LOG_END();
 
@@ -327,15 +377,113 @@ void comp_group_notify_group_invite(int ret)
        notify_group_device_invite_result(ret);
 }
 
+
+#define FULL_PERMISSION 31
+
+int _is_pairwise_uuid(char *uuid)
+{
+       comp_context_t *comp_ctx = comp_context_get_context();
+
+       GList *iter = NULL;
+
+       iter = comp_ctx->pairwise_list;
+       while (iter != NULL) {
+               char *pairwise_uuid = (char *)iter->data;
+
+               if (strcmp(pairwise_uuid, uuid) == 0)
+                       return 0;
+
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+int comp_group_add_device_in_group(char *group_name, char *uuid)
+{
+       comp_context_t *comp_ctx = comp_context_get_context();
+
+       GList *iter = NULL;
+
+       iter = comp_ctx->grp_list;
+       while (iter != NULL) {
+               comp_grp_t *group = (comp_grp_t *)iter->data;
+
+               if (strcmp(group_name, group->name) == 0) {
+                       GList *device_iter = group->device_list;
+                       GList *subgroup_iter = group->subgroup_list;
+                       while (device_iter != NULL) {
+                               char *device_uuid = (char *)device_iter->data;
+                               if (strcmp(device_uuid, uuid) == 0)
+                                       return -1;
+
+                               device_iter = g_list_next(device_iter);
+                       }
+
+                       while (subgroup_iter != NULL) {
+                               comp_subgrp_t *subgroup = (comp_subgrp_t *)subgroup_iter->data;
+                               if (strcmp(subgroup->uuid, uuid) == 0)
+                                       return -1;
+
+                               subgroup_iter = g_list_next(subgroup_iter);
+                       }
+
+                       group->device_list = g_list_prepend(group->device_list, strdup(uuid));
+                       __print_groups_information();
+                       return 0;
+               }
+
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
+int comp_group_add_subgroup_in_group(char *group_name, char *uuid, char *subgroup_name)
+{
+       comp_context_t *comp_ctx = comp_context_get_context();
+
+       GList *iter = NULL;
+
+       iter = comp_ctx->grp_list;
+       while (iter != NULL) {
+               comp_grp_t *group = (comp_grp_t *)iter->data;
+
+               if (strcmp(group_name, group->name) == 0) {
+                       GList *subgroup_iter = group->subgroup_list;
+
+                       while (subgroup_iter != NULL) {
+                               comp_subgrp_t *subgroup = (comp_subgrp_t *)subgroup_iter->data;
+                               if (strcmp(subgroup->uuid, uuid) == 0)
+                                       return -1;
+
+                               subgroup_iter = g_list_next(subgroup_iter);
+                       }
+
+                       comp_subgrp_t *subgroup;
+                       subgroup = g_try_malloc0(sizeof(comp_subgrp_t));
+                       subgroup->name = g_strdup(subgroup_name);
+                       subgroup->uuid = g_strdup(uuid);
+
+                       group->subgroup_list = g_list_prepend(group->subgroup_list, subgroup);
+                       __print_groups_information();
+                       return 0;
+               }
+
+               iter = g_list_next(iter);
+       }
+
+       return -1;
+}
+
 //Join to device in group (async)
-int comp_group_invite(gchar *uuid_dev1, gchar *uuid_dev2, gchar *pin,
-                                       gchar *uri_1, gchar *rt_1, gchar *interface_1,
-                                       int permission_1, gchar *uri_2, gchar *rt_2,
-                                       gchar *interface_2, int permission_2)
+int comp_group_invite(char *group_name, char *uuid, char *pin)
 {
        int ret = COMP_ERROR_NONE;
 
        LOG_BEGIN();
+       comp_context_t *comp_ctx = comp_context_get_context();
+
 
 #ifdef INVITE_EJECT_DEVICE_BY_MULTI_RUN
        /*
@@ -343,28 +491,38 @@ int comp_group_invite(gchar *uuid_dev1, gchar *uuid_dev2, gchar *pin,
         * 2. Discover Mowned devices
         * 3. Pairwise
         */
-
-       ret = agent_mot(uuid_dev2, pin);
-
-       if (ret == COMP_ERROR_NONE) {
-               group_invite_info = g_try_malloc0(sizeof(comp_group_invite_info_t));
-               group_invite_info->uuid_dev1 = g_strdup(uuid_dev1);
-               group_invite_info->uuid_dev2 = g_strdup(uuid_dev2);
-               group_invite_info->pin = g_strdup(pin);
-               group_invite_info->uri_1 = g_strdup(uri_1);
-               group_invite_info->rt_1 = g_strdup(rt_1);
-               group_invite_info->interface_1 = g_strdup(interface_1);
-               group_invite_info->permission_1 = permission_1;
-               group_invite_info->uri_2 = g_strdup(uri_2);
-               group_invite_info->rt_2 = g_strdup(rt_2);
-               group_invite_info->interface_2 = g_strdup(interface_2);
-               group_invite_info->permission_2 = permission_2;
-
-               LOG_DEBUG("Group Invite Information created %p", group_invite_info);
+       LOG_DEBUG("group name : %s, uuid : %s", group_name, uuid);
+
+       if (_is_pairwise_uuid(uuid) < 0) {
+               /*
+               * 1. Perform MOT
+               * 2. Discover Mowned devices
+               * 3. Pairwise
+               */
+               ret = agent_mot(uuid, pin);
+
+               if (ret == COMP_ERROR_NONE) {
+                       group_invite_info = g_try_malloc0(sizeof(comp_group_invite_info_t));
+                       group_invite_info->uuid_dev1 = g_strdup(comp_ctx->device_uuid);
+                       group_invite_info->uuid_dev2 = g_strdup(uuid);
+                       group_invite_info->pin = g_strdup(pin);
+                       group_invite_info->uri_1 = g_strdup("/comp/data/1");
+                       group_invite_info->rt_1 = g_strdup("core.comp.data");
+                       group_invite_info->interface_1 = g_strdup("oic.if.baseline");
+                       group_invite_info->permission_1 = FULL_PERMISSION;
+                       group_invite_info->uri_2 = g_strdup("/comp/data/1");
+                       group_invite_info->rt_2 = g_strdup("core.comp.data");
+                       group_invite_info->interface_2 = g_strdup("oic.if.baseline");
+                       group_invite_info->permission_2 = FULL_PERMISSION;
+               }
        }
+
+       if (comp_group_add_device_in_group(group_name, uuid) < 0)
+               return COMP_ERROR_UNKNOWN;
+
 #else
-       ret = agent_pair(pin, uuid_dev1, uuid_dev2, uri_1, rt_1, interface_1, permission_1,
-               uuid_dev2, uuid_dev1, uri_2, rt_2, interface_2, permission_2);
+       ret = agent_pair(pin, comp_ctx->device_uuid, uuid, "/comp/data/1", "core.comp.data",
+               "oic.if.baseline", FULL_PERMISSION, uuid, comp_ctx->device_uuid, "/comp/data/1", "core.comp.data", "oic.if.baseline", FULL_PERMISSION);
 #endif
        LOG_END();
 
@@ -657,3 +815,127 @@ int comp_group_get_group_device_id(comp_group_t *handle)
        return ret;
 }
 
+int comp_group_create_subgroup(char *group_name, char *uuid, char *subgroup_name)
+{
+       int ret = COMP_ERROR_NONE;
+
+       comp_command_t *cmd = g_new0(comp_command_t, 1);
+       cmd->command = g_strdup("create_subgroup");
+       cmd->uuid = g_strdup(uuid);
+       cmd->arg1 = g_strdup(group_name);
+       cmd->arg2 = g_strdup(subgroup_name);
+
+       comp_group_add_subgroup_in_group(group_name, uuid, subgroup_name);
+
+       ret = comp_iot_discovery_resource(COMP_RESOURCE_TYPE_DATA, 5, cmd);
+       if (ret != COMP_ERROR_NONE) {
+               LOG_ERR("Failed to discover resource : %s",
+                                comp_log_get_error_string(ret));
+       }
+
+       return ret;
+}
+
+GVariant *comp_group_get_subgroups(char *group_name)
+{
+       GVariantBuilder builder;
+
+       GVariant *group_data;
+       GList *iter = NULL;
+
+       comp_context_t *comp_ctx = comp_context_get_context();
+
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
+
+       iter = comp_ctx->grp_list;
+       while(iter != NULL) {
+               comp_grp_t *group = (comp_grp_t *)iter->data;
+
+               LOG_ERR("group->name : %s, group_name : %s", group->name, group_name);
+
+               if (strcmp(group->name, group_name) == 0) {
+                       GList *sub_iter = group->subgroup_list;
+                       LOG_ERR("sub iter");
+
+                       while(sub_iter != NULL) {
+                               LOG_ERR("sub iter");
+                               comp_subgrp_t *subgroup = (comp_subgrp_t *)sub_iter->data;
+                               g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
+                               g_variant_builder_add(&builder, "{sv}", "DeviceID",
+                                                                         g_variant_new_string(subgroup->uuid));
+                               g_variant_builder_add(&builder, "{sv}", "GroupName",
+                                                                         g_variant_new_string(subgroup->name));
+                               g_variant_builder_close(&builder);
+                               sub_iter = g_list_next(sub_iter);
+                       }
+               }
+
+               iter = g_list_next(iter);
+
+       }
+
+       group_data = g_variant_builder_end(&builder);
+
+       return group_data;
+}
+char *__get_uuid_by_subgroup(char *subgroup_name)
+{
+       comp_context_t *comp_ctx = comp_context_get_context();
+
+       GList *iter = NULL;
+
+       iter = comp_ctx->grp_list;
+       while (iter != NULL) {
+               comp_grp_t *group = (comp_grp_t *)iter->data;
+               GList *subgroup_iter = group->subgroup_list;
+
+               while (subgroup_iter != NULL) {
+                       comp_subgrp_t *subgroup = (comp_subgrp_t *)subgroup_iter->data;
+                       if (strcmp(subgroup->name, subgroup_name) == 0) {
+                               return subgroup->uuid;
+                       }
+
+                       subgroup_iter = g_list_next(subgroup_iter);
+               }
+
+               iter = g_list_next(iter);
+       }
+
+       return NULL;
+}
+int comp_group_add_device_to_subgroup(char *subgroup_name, char *uuid)
+{
+       //get uuid from subgroup_name.
+       //create CMD : add_device_to_subgroup
+       //arg1 : target UUID by subgroupname.
+       //arg2 : uuid
+       int ret = COMP_ERROR_NONE;
+       char *subgroup_uuid;
+       comp_command_t *cmd = NULL;
+
+       subgroup_uuid = __get_uuid_by_subgroup(subgroup_name);
+       LOG_ERR("send remote data : %s, %s, %s", subgroup_name, subgroup_uuid, uuid);
+       if (subgroup_uuid != NULL) {
+               cmd = g_new0(comp_command_t, 1);
+               cmd->command = g_strdup("add_device_to_subgroup");
+               cmd->uuid = g_strdup(subgroup_uuid);
+               cmd->arg1 = g_strdup(subgroup_name);
+               cmd->arg2 = g_strdup(uuid);
+       } else {
+               LOG_ERR("the uuid is NULL");
+       }
+
+       ret = comp_iot_discovery_resource(COMP_RESOURCE_TYPE_DATA, 5, cmd);
+       if (ret != COMP_ERROR_NONE) {
+               LOG_ERR("Failed to discover resource : %s",
+                                comp_log_get_error_string(ret));
+       }
+}
+
+
+int comp_group_delete_subgroup(char *subgroup_name)
+{
+
+}
+
+
index b857d32a04c8a6e688866880367d4258b19ce47f..d45c9802a1f1f1b67422525281b8884fbb413eff 100755 (executable)
@@ -90,6 +90,18 @@ int comp_iot_initialize()
        return COMP_ERROR_NONE;
 }
 
+static bool _query_foreach(const char *key, const char *value, void *user_data)
+{
+       char *group_name = (char *)user_data;
+
+       if (strncmp(key, "UUID", 4) == 0) {
+               LOG_DEBUG("Insert in %s, UUID : %s", group_name, value);
+               comp_group_add_device_in_group(group_name, value);
+       }
+
+       return IOTCON_FUNC_CONTINUE;
+}
+
 static void _request_handler(iotcon_resource_h resource, iotcon_request_h request,
        void *user_data)
 {
@@ -110,6 +122,35 @@ static void _request_handler(iotcon_resource_h resource, iotcon_request_h reques
 
        if (IOTCON_REQUEST_GET == type) {
                iotcon_response_h response = NULL;
+               iotcon_query_h query = NULL;
+
+               ret = iotcon_request_get_query(request, &query);
+               if (IOTCON_ERROR_NONE != ret)
+                        return;
+
+               if (IOTCON_ERROR_NONE == ret && query) {
+                       char *command;
+                       iotcon_query_lookup(query, "CMD", &command);
+
+                       if (strcmp(command, "create_subgroup") == 0) {
+                               LOG_DEBUG("Another device request create sub group");
+                               char *group_name;
+                               iotcon_query_lookup(query, "group_name", &group_name);
+
+                               comp_group_create(group_name);
+                       } else if (strcmp(command, "add_device_to_subgroup") == 0) {
+                               LOG_DEBUG("Another device request add device to sub group");
+                               char *group_name;
+                               char *uuid;
+
+                               iotcon_query_lookup(query, "group_name", &group_name);
+                               iotcon_query_lookup(query, "device_id", &uuid);
+
+                               LOG_DEBUG("group_name : %s, UUID : %s", group_name, uuid);
+
+                               comp_group_invite(group_name, uuid, "12341234");
+                       }
+               }
 
                ret = iotcon_response_create(request, &response);
                if (IOTCON_ERROR_NONE != ret)
@@ -221,11 +262,10 @@ static bool _found_resource(iotcon_remote_resource_h resource,
        char *resource_uri_path = NULL;
        iotcon_resource_types_h resource_types;
        char *resource_device_id;
-       char *resource_device_name;
        char *resource_host;
        char *resource_type;
        comp_group_type_e group_type;
-       iot_discovery_t *iot = (iot_discovery_t *)user_data;
+
        /* Callback: When no more resource available.
           As timeout is configured by IOTCON Library*/
        if (resource == NULL) {
@@ -250,27 +290,6 @@ static bool _found_resource(iotcon_remote_resource_h resource,
                return IOTCON_FUNC_CONTINUE;
        }
        LOG_DEBUG("resource device id : %s", resource_device_id);
-       if (iot != NULL && strcmp(iot->uuid, resource_device_id) == 0) {
-               LOG_DEBUG("Send data is ready.");
-               iotcon_remote_resource_h resource_clone = NULL;
-               ret = iotcon_remote_resource_clone(resource, &resource_clone);
-       if (IOTCON_ERROR_NONE != ret)
-       return IOTCON_FUNC_CONTINUE;
-               ret = iotcon_remote_resource_get(resource_clone, NULL, _on_get, NULL);
-               if (IOTCON_ERROR_NONE != ret) {
-                        iotcon_remote_resource_destroy(resource_clone);
-                        return IOTCON_FUNC_CONTINUE;
-               }
-       }
-
-       /* get the resource device name */
-       ret = iotcon_remote_resource_get_device_name(resource,
-                                                                &resource_device_name);
-       if (IOTCON_ERROR_NONE != ret) {
-               LOG_ERR("Failed to get resource device name");
-               return IOTCON_FUNC_CONTINUE;
-       }
-       LOG_DEBUG("resource device name : %s", resource_device_name);
 
        /* get the resource host address */
        ret = iotcon_remote_resource_get_host_address(resource, &resource_host);
@@ -300,13 +319,54 @@ static bool _found_resource(iotcon_remote_resource_h resource,
                else
                        group_type = COMP_GROUP_REMOTE_DEVICE;
 
+               char *temp = strdup(resource_uri_path);
+               char *ptr = strtok(temp, "/");
+               ptr = strtok(NULL, "/");
+               ptr = strtok(NULL, "/");
+
+               LOG_DEBUG("group name is %s", ptr);
                comp_group_add_new(resource_uri_path, resource_device_id,
-                                                resource_device_name, resource_host, resource_type, group_type);
+                                                ptr, resource_host, resource_type, group_type);
                found_device_count++;
 
                g_free(resource_type);
 
                return IOTCON_FUNC_CONTINUE;
+       } else if (strcmp(resource_type, "core.comp.data") == 0) {
+               comp_command_t *cmd = (comp_command_t *)user_data;
+
+               if (cmd != NULL && strcmp(cmd->uuid, resource_device_id) == 0) {
+                       LOG_DEBUG("Send data is ready. Create Subgroup Start");
+
+                       iotcon_remote_resource_h resource_clone = NULL;
+                       iotcon_query_h query = NULL;
+
+                       ret = iotcon_remote_resource_clone(resource, &resource_clone);
+               if (IOTCON_ERROR_NONE != ret)
+                               return IOTCON_FUNC_CONTINUE;
+
+                       ret = iotcon_query_create(&query);
+                       if (IOTCON_ERROR_NONE != ret)
+                               return IOTCON_FUNC_CONTINUE;
+
+                       if (strcmp(cmd->command, "create_subgroup") == 0) {
+                               LOG_DEBUG("CMD : %s, group_name : %s", cmd->command, cmd->arg2);
+                               iotcon_query_add(query, "CMD", cmd->command);
+                               iotcon_query_add(query, "group_name", cmd->arg2);
+                       } else if (strcmp(cmd->command, "add_device_to_subgroup") == 0) {
+                               LOG_DEBUG("CMD : %s, group_name : %s, UUID : %s", cmd->command, cmd->arg1, cmd->arg2);
+                               iotcon_query_add(query, "CMD", cmd->command);
+                               iotcon_query_add(query, "group_name", cmd->arg1);
+                               iotcon_query_add(query, "device_id", cmd->arg2);
+                       }
+
+                       ret = iotcon_remote_resource_get(resource_clone, query, _on_get, NULL);
+                       if (IOTCON_ERROR_NONE != ret) {
+                                iotcon_remote_resource_destroy(resource_clone);
+                                return IOTCON_FUNC_CONTINUE;
+                       }
+               }
+
        }
 }
 
index 0b01eff386f1e7bd3ce51cbcfd4b21d045aebdca..e643210525a2be078c6e51ee74c791a9961eb168 100644 (file)
@@ -40,6 +40,7 @@
                        <arg type="i" name="result" direction="out" />
                </method>
                <method name="Invite">
+                       <arg type="s" name="group_name" direction="in"/>
                        <arg type="s" name="uuid" direction="in"/>
                        <arg type="s" name="pin" direction="in" />
                        <arg type="i" name="result" direction="out"/>
                <method name="GetMyUuid">
                        <arg type="s" name="uuid" direction="out" />
                </method>
+               <method name="CreateSubgroup">
+                       <arg type="s" name="group_name" direction="in" />
+                       <arg type="s" name="uuid" direction="in" />
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="GetSubgroups">
+                       <arg type="s" name="group_name" direction="in" />
+                       <arg type="aa{sv}" name="groups" direction="out" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="AddDeviceToSubgroup">
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="s" name="uuid" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
+               <method name="DeleteSubgroup">
+                       <arg type="s" name="subgroup_name" direction="in" />
+                       <arg type="i" name="result" direction="out" />
+               </method>
                <!-- Signal (D-Bus) definitions -->
                <signal name="GroupFound">
                        <arg type="a{sv}" name="group_info" direction="out" />