[Feature][API-532][connman] add ifconfig for gsw
Change-Id: I7c9a854b2d99abc9dcb3f275217da101f9a89faa
diff --git a/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_ifconfig_cmd.patch b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_ifconfig_cmd.patch
new file mode 100755
index 0000000..86cee4d
--- /dev/null
+++ b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_ifconfig_cmd.patch
@@ -0,0 +1,445 @@
+--- connman-1.41/src/manager.c 2022-01-28 22:48:01.000000000 +0800
++++ connman-1.41/src/manager_new.c 2022-08-20 17:16:50.031688400 +0800
+@@ -29,6 +29,13 @@
+
+ #include <connman/agent.h>
+
++#include <stdio.h>
++#include <unistd.h>
++#include <sys/socket.h>
++#include <net/if.h>
++#include <net/if_arp.h>
++#include <sys/ioctl.h>
++
+ #include "connman.h"
+
+ static bool connman_state_idle;
+@@ -69,12 +76,61 @@
+ return reply;
+ }
+
++struct dev_info {
++ const char * dev_name;
++ char identifier[128];
++ char group[16];
++ int index;
++};
++
++void device_enum_callback (int index, void *user_data) {
++ struct dev_info * dev = (struct dev_info*)user_data;
++ unsigned short type;
++ int sock_mac;
++ struct ifreq ifr_mac;
++
++ DBG("index:%d, ptr %p", index, dev);
++ if (dev == NULL) {
++ return;
++ }
++
++ if (g_strcmp0(dev->dev_name, connman_inet_ifname(index)) == 0) {
++ type = __connman_ipconfig_get_type_from_index(index);
++ DBG("index:%d, type %d", index, type);
++ if ( type == ARPHRD_ETHER || type == ARPHRD_EETHER) {
++ sock_mac = socket( AF_INET, SOCK_STREAM, 0 );
++
++ if( sock_mac == -1) {
++ DBG("bad sock mac");
++ return;
++ }
++ strcpy(ifr_mac.ifr_name, dev->dev_name);
++ if( (ioctl( sock_mac, SIOCGIFHWADDR, &ifr_mac)) >= 0) {
++ sprintf(dev->identifier, "ethernet_%02x%02x%02x%02x%02x%02x_cable",
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[0],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[1],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[2],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[3],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[4],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[5]);
++ strcpy(dev->group, "Wired");
++ dev->index = index;
++ }
++
++ close( sock_mac );
++ }
++ }
++}
++
+ static DBusMessage *set_property(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+ {
+ DBusMessageIter iter, value;
+ const char *name;
+ int type;
++ struct dev_info dev;
++ struct connman_service * service_ptr;
++ int err = 0;
+
+ DBG("conn %p", conn);
+
+@@ -108,14 +164,105 @@
+ if (type != DBUS_TYPE_BOOLEAN)
+ return __connman_error_invalid_arguments(msg);
+
+- dbus_message_iter_get_basic(&value, &sessionmode);
+-
++ dbus_message_iter_get_basic(&value, &sessionmode);
+ } else
+ return __connman_error_invalid_property(msg);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ }
+
++static DBusMessage *set_ipconfig(DBusConnection *conn,
++ DBusMessage *msg, void *data)
++{
++ DBusMessageIter iter, value;
++ const char *name;
++ int type;
++ struct dev_info dev;
++ struct connman_service * service_ptr;
++ int err = 0;
++
++ DBG("conn %p", conn);
++ memset(&dev, 0, sizeof (dev));
++
++ if (!dbus_message_iter_init(msg, &iter))
++ return __connman_error_invalid_arguments(msg);
++
++ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
++ return __connman_error_invalid_arguments(msg);
++
++ dbus_message_iter_get_basic(&iter, &name);
++ dbus_message_iter_next(&iter);
++
++ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
++ return __connman_error_invalid_arguments(msg);
++
++ dbus_message_iter_recurse(&iter, &value);
++
++ type = dbus_message_iter_get_arg_type(&value);
++
++ if (!g_str_equal(name, "")) {
++ dev.dev_name = name;
++ DBG("%s, %s", name, dev.dev_name);
++ __connman_ipconfig_foreach(&device_enum_callback, &dev);
++ if (dev.identifier[0] == '\0') {
++ return __connman_error_invalid_arguments(msg);
++ }
++
++ service_ptr = __connman_service_lookup_from_index(dev.index);
++
++ DBG("servcie+ptr %p", service_ptr);
++ if (service_ptr != NULL) {
++ DBG("return EEXIST");
++ return __connman_error_failed(msg, -EEXIST);
++ }
++ struct connman_ipconfig *ipconfig, *new_ipconfig;
++ enum connman_ipconfig_method old_method, new_method;
++
++ int index;
++ const char *service_identifier = dev.identifier;
++ const char* servcie_name = dev.group;
++
++ old_method = __connman_ipconfig_get_method(ipconfig);
++ index = __connman_ipconfig_get_index(ipconfig);
++
++ new_ipconfig = __connman_ipconfig_create(index,
++ CONNMAN_IPCONFIG_TYPE_IPV4);
++ if (!new_ipconfig)
++ return __connman_error_invalid_arguments(msg);
++
++ if (1) {
++ err = __connman_ipconfig_set_config(new_ipconfig, &value);
++ if (err < 0) {
++ __connman_ipconfig_unref(new_ipconfig);
++ return __connman_error_invalid_arguments(msg);
++ }
++
++ new_method = __connman_ipconfig_get_method(new_ipconfig);
++ }
++
++ GKeyFile *keyfile;
++
++ keyfile = g_key_file_new();
++ if (!keyfile)
++ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
++
++ if (servcie_name)
++ g_key_file_set_string(keyfile, service_identifier,
++ "Name", servcie_name);
++
++ if (new_ipconfig)
++ __connman_ipconfig_save(new_ipconfig, keyfile,
++ service_identifier, "IPv4.");
++
++ __connman_storage_save_service(keyfile, service_identifier);
++
++ g_key_file_free(keyfile);
++ } else
++ return __connman_error_invalid_property(msg);
++
++ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
++}
++
+ static void append_technology_structs(DBusMessageIter *iter, void *user_data)
+ {
+ __connman_technology_list_struct(iter);
+@@ -582,7 +729,10 @@
+ register_peer_service) },
+ { GDBUS_METHOD("UnregisterPeerService",
+ GDBUS_ARGS({ "specification", "a{sv}" }), NULL,
+- unregister_peer_service) },
++ unregister_peer_service) },
++ { GDBUS_METHOD("SetIPConfig",
++ GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
++ NULL, set_ipconfig) },
+ { },
+ };
+
+--- connman-1.41/client/commands.c 2022-01-28 22:48:01.000000000 +0800
++++ connman-1.41/client/commands_new.c 2022-08-20 18:37:54.452762100 +0800
+@@ -45,6 +45,11 @@
+ #include "agent.h"
+ #include "vpnconnections.h"
+
++#include <sys/socket.h>
++#include <net/if.h>
++#include <net/if_arp.h>
++#include <sys/ioctl.h>
++
+ static DBusConnection *connection;
+ static GHashTable *service_hash;
+ static GHashTable *vpnconnection_hash;
+@@ -980,6 +985,12 @@
+ struct connman_option *options;
+ };
+
++struct ipconfig_options {
++ char *service_name;
++ char *ipconfig_cmd;
++ struct config_append append;
++};
++
+ static void config_append_ipv4(DBusMessageIter *iter,
+ void *user_data)
+ {
+@@ -999,6 +1010,59 @@
+ append->values = i;
+ }
+
++static int ipconfig_return(DBusMessageIter *iter, int errnum,
++ const char *error, void *user_data)
++{
++ struct ipconfig_options * config = user_data;
++
++ char * path;
++ int sock_mac;
++ struct ifreq ifr_mac;
++ char identifier[64];
++
++// printf("ipconfig_return %d %s\n", errnum, error);
++ if (errnum == -EEXIST || (error && strstr(error, "-17") != NULL)) {
++// printf("exits service\n");
++ sock_mac = socket( AF_INET, SOCK_STREAM, 0 );
++
++ if( sock_mac == -1) {
++ return -1;
++ }
++
++ strcpy(ifr_mac.ifr_name, config->service_name);
++ if( (ioctl( sock_mac, SIOCGIFHWADDR, &ifr_mac)) >= 0) {
++ sprintf(identifier, "ethernet_%02x%02x%02x%02x%02x%02x_cable",
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[0],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[1],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[2],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[3],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[4],
++ (unsigned char)ifr_mac.ifr_hwaddr.sa_data[5]);
++ }
++
++ close( sock_mac );
++
++ path = g_strdup_printf("/net/connman/service/%s", identifier);
++ //printf("service name %s\n", identifier);
++ __connmanctl_dbus_set_property_dict(connection,
++ path, "net.connman.Service",
++ config_return, g_strdup(identifier),
++ "IPv4.Configuration", DBUS_TYPE_STRING,
++ config_append_ipv4, &config->append);
++ }
++ else if (error)
++ fprintf(stderr, "Error %s: %s\n", config->service_name, error);
++ else if (config->ipconfig_cmd) {
++ system(config->ipconfig_cmd);
++ g_free(config->ipconfig_cmd);
++ }
++
++ g_free(config->service_name);
++ g_free(user_data);
++
++ return 0;
++}
++
+ static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
+ {
+ struct config_append *append = user_data;
+@@ -1327,6 +1391,78 @@
+ return result;
+ }
+
++static int cmd_ipconfig(char *args[], int num, struct connman_option *options)
++{
++ int result = 0, res = 0, index = 2, oldindex = 0;
++ int c;
++ char *service_name, *path;
++ char **opt_start;
++ struct config_append append;
++ struct ipconfig_options *ipconfig_ptr;
++
++ service_name = args[1];
++ if (!service_name)
++ return -EINVAL;
++// printf("ifconfig name %s\n", service_name);
++
++ while (index < num && args[index]) {
++ c = parse_args(args[index], options);
++ opt_start = &args[index + 1];
++ append.opts = opt_start;
++ append.values = 0;
++ ipconfig_ptr = g_new0(struct ipconfig_options, 1);
++ ipconfig_ptr->service_name = g_strdup(service_name);
++ ipconfig_ptr->ipconfig_cmd = NULL;
++ ipconfig_ptr->append.opts = opt_start;
++ ipconfig_ptr->append.values = 0;
++
++ res = 0;
++
++ oldindex = index;
++ path = g_strdup_printf("/");
++
++ switch (c) {
++ case 'i':
++ {
++ if (num > 4 && strcmp(args[2], "--ipv4") == 0 && strcmp(args[3], "manual") == 0) {
++ if (num > 5)
++ ipconfig_ptr->ipconfig_cmd = g_strdup_printf("ifconfig %s %s netmask %s", service_name, args[4], args[5]);
++ else
++ ipconfig_ptr->ipconfig_cmd = g_strdup_printf("ifconfig %s %s", service_name, args[4]);
++ }
++ res = __connmanctl_dbus_method_call_with_name(connection,
++ "net.connman", path, "net.connman.Manager", "SetIPConfig",
++ ipconfig_return, ipconfig_ptr,
++ service_name, DBUS_TYPE_STRING,
++ config_append_ipv4, &append);
++
++// printf("res is %d\n", res);
++ index += append.values;
++ break;
++ }
++
++ default:
++ res = -EINVAL;
++ break;
++ }
++
++ g_free(path);
++
++ if (res < 0) {
++ if (res == -EINPROGRESS)
++ result = -EINPROGRESS;
++ else
++ printf("Error '%s': %s\n", args[oldindex],
++ strerror(-res));
++ } else
++ index += res;
++
++ index++;
++ }
++
++ return result;
++}
++
+ static DBusHandlerResult monitor_changed(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+ {
+@@ -2825,6 +2961,8 @@
+ lookup_service_arg },
+ { "config", "<service>", config_options, cmd_config,
+ "Set service configuration options", lookup_config },
++ { "ifconfig", "<interface>", config_options, cmd_ipconfig,
++ "Set interface configuration options", lookup_config },
+ { "monitor", "[off]", monitor_options, cmd_monitor,
+ "Monitor signals from interfaces", lookup_monitor },
+ { "agent", "on|off", NULL, cmd_agent,
+--- connman-1.41/client/dbus_helpers.h 2022-01-28 22:48:01.000000000 +0800
++++ connman-1.41/client/dbus_helpers_new.h 2022-08-20 17:17:32.301009500 +0800
+@@ -49,6 +49,14 @@
+ void * user_data, connmanctl_dbus_append_func_t append_fn,
+ void *append_data);
+
++int __connmanctl_dbus_method_call_with_name(DBusConnection *connection,
++ const char *service, const char *path,
++ const char *interface, const char *method,
++ connmanctl_dbus_method_return_func_t cb, void * user_data,
++ const char *property, int type,
++ connmanctl_dbus_append_func_t append_fn,
++ void *append_data);
++
+ int __connmanctl_dbus_set_property(DBusConnection *connection,
+ const char *path, const char *interface,
+ connmanctl_dbus_method_return_func_t cb, void * user_data,
+--- connman-1.41/client/dbus_helpers.c 2022-01-28 22:48:01.000000000 +0800
++++ connman-1.41/client/dbus_helpers_new.c 2022-08-20 17:54:29.303478800 +0800
+@@ -289,6 +289,52 @@
+ return send_method_call(connection, message, cb, user_data);
+ }
+
++int __connmanctl_dbus_method_call_with_name(DBusConnection *connection,
++ const char *service, const char *path,
++ const char *interface, const char *method,
++ connmanctl_dbus_method_return_func_t cb, void * user_data,
++ const char *property, int type,
++ connmanctl_dbus_append_func_t append_fn,
++ void *append_data)
++{
++ DBusMessage *message;
++ DBusMessageIter iter, variant, dict;
++
++ message = dbus_message_new_method_call(service, path, interface,
++ method);
++
++ if (!message)
++ return -ENOMEM;
++
++ //printf("set property path:%s,interface:%s\n", path, interface);
++ if (!message)
++ return -ENOMEM;
++
++ dbus_message_iter_init_append(message, &iter);
++ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
++ dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
++ DBUS_TYPE_ARRAY_AS_STRING
++ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
++ DBUS_TYPE_STRING_AS_STRING
++ DBUS_TYPE_VARIANT_AS_STRING
++ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
++ &variant);
++
++ dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
++ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
++ DBUS_TYPE_STRING_AS_STRING
++ DBUS_TYPE_VARIANT_AS_STRING
++ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
++ &dict);
++
++ append_fn(&dict, append_data);
++
++ dbus_message_iter_close_container(&variant, &dict);
++ dbus_message_iter_close_container(&iter, &variant);
++
++ return send_method_call(connection, message, cb, user_data);
++}
++
+ int __connmanctl_dbus_set_property(DBusConnection *connection,
+ const char *path, const char *interface,
+ connmanctl_dbus_method_return_func_t cb, void * user_data,
diff --git a/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman_%.bbappend b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman_%.bbappend
index 10bcc18..48244d8 100755
--- a/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman_%.bbappend
+++ b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman_%.bbappend
@@ -3,5 +3,6 @@
SRC_URI += "\
file://lynq_wifi_ap_sta.patch \
file://lynq_wifi_netmask.patch \
+ file://lynq_ifconfig_cmd.patch \
"