void *user_data;
} spawn_info_s;
+static spawn_info_s *dhcp_info = NULL;
+
static char* __get_obtained_ip_address(const char *str)
{
char *token = NULL;
static gboolean _child_logger(GIOChannel *source, GIOCondition condition,
gpointer data)
{
- spawn_info_s *info = (spawn_info_s *)data;
gchar *buf = NULL;
gchar *address = NULL;
GError *error = NULL;
GIOStatus status = G_IO_STATUS_NORMAL;
NOTUSED(condition);
+ NOTUSED(data);
- while(G_IO_STATUS_NORMAL == status || G_IO_STATUS_AGAIN == status) {
+ while(G_IO_STATUS_NORMAL == status) {
status = g_io_channel_read_line(source, &buf, NULL, NULL, &error);
if (G_IO_STATUS_ERROR == status) {
MESH_LOGE("Failed to read i/o [%s]", error->message);
g_free(buf);
g_error_free(error);
} else if (G_IO_STATUS_EOF != status) {
+ if (NULL == buf) continue;
MESH_LOGD("[CHILD] %s", buf);
/* Check if IP obtained */
address = g_strdup("0.0.0.0");
MESH_LOGD("[Found] %s", address);
- if (info)
- info->ip_address = address;
+ if (dhcp_info)
+ dhcp_info->ip_address = address;
}
}
}
static void _child_process_watcher(GPid pid, gint status, gpointer user_data)
{
- spawn_info_s *info = (spawn_info_s *)user_data;
+ NOTUSED(user_data);
g_spawn_close_pid(pid);
- if (info) {
- info->callback(info->interface, info->ip_address, info->user_data);
-
- g_source_remove(info->error_source);
- g_source_remove(info->output_source);
- g_source_remove(info->child_source);
- g_free(info->ip_address);
- g_free(info);
+ if (dhcp_info) {
+ dhcp_info->callback(dhcp_info->interface,
+ dhcp_info->ip_address, dhcp_info->user_data);
+
+ g_source_remove(dhcp_info->error_source);
+ g_source_remove(dhcp_info->output_source);
+ g_source_remove(dhcp_info->child_source);
+ g_free(dhcp_info->ip_address);
+
+ g_free(dhcp_info);
+ dhcp_info = NULL;
}
MESH_LOGD("[CHILD] terminated with [%d]", status);
}
-static int _internal_request_dhcp(const char *interface_name, spawn_info_s *info)
+static int _internal_request_dhcp(const char *interface_name)
{
gboolean result = FALSE;
NULL
};
+ if (NULL == dhcp_info) {
+ MESH_LOGE("Unexpected parameter failure");
+ return MESHD_ERROR_OPERATION_FAILED;
+ }
+
result = g_spawn_async_with_pipes(NULL,
request_dhcp,
NULL,
(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD),
NULL,
NULL,
- &(info->child_pid),
+ &(dhcp_info->child_pid),
NULL,
&standard_output,
&standard_error,
&error);
if (result == FALSE) {
MESH_LOGE("Failed to request DHCP! : [%s]", error->message);
- g_free(info);
g_error_free(error);
+ g_free(dhcp_info);
+ dhcp_info = NULL;
+
return MESHD_ERROR_OPERATION_FAILED;
}
output_channel = g_io_channel_unix_new(standard_output);
error_channel = g_io_channel_unix_new(standard_error);
- info->output_source = g_io_add_watch(output_channel,
- (G_IO_IN | G_IO_ERR), _child_logger, info);
- info->error_source = g_io_add_watch(error_channel,
- (G_IO_IN | G_IO_ERR), _child_logger, info);
+ g_io_channel_set_flags(output_channel, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_channel_set_flags(error_channel, G_IO_FLAG_NONBLOCK, NULL);
+ dhcp_info->output_source = g_io_add_watch(output_channel,
+ (G_IO_IN | G_IO_ERR), _child_logger, NULL);
+ dhcp_info->error_source = g_io_add_watch(error_channel,
+ (G_IO_IN | G_IO_ERR), _child_logger, NULL);
g_io_channel_unref(output_channel);
g_io_channel_unref(error_channel);
- info->child_source = g_child_watch_add(info->child_pid,
- _child_process_watcher, info);
+ dhcp_info->child_source = g_child_watch_add(dhcp_info->child_pid,
+ _child_process_watcher, NULL);
MESH_LOGD("DHCP requested");
return MESHD_ERROR_NONE;
dhcp_finished_cb callback, void *user_data)
{
int ret = MESHD_ERROR_NONE;
- spawn_info_s *info = NULL;
- info = g_new0(spawn_info_s, 1);
- if (NULL == info) {
+ if (NULL != dhcp_info) {
+ MESH_LOGE("DHCP is requested already");
+ return MESHD_ERROR_IN_PROGRESS;
+ }
+
+ dhcp_info = g_new0(spawn_info_s, 1);
+ if (NULL == dhcp_info) {
MESH_LOGE("Falied to allocate information");
return MESHD_ERROR_OUT_OF_MEMORY;
}
- info->interface = interface;
- info->callback = callback;
- info->user_data = user_data;
- ret = _internal_request_dhcp(interface, info);
+ dhcp_info->interface = interface;
+ dhcp_info->callback = callback;
+ dhcp_info->user_data = user_data;
+ ret = _internal_request_dhcp(interface);
return ret;
}
+
+int mesh_dhcp_stop_request()
+{
+ gboolean result;
+ GError *error = NULL;
+
+ if (NULL == dhcp_info) {
+ MESH_LOGE("DHCP is not requested or terminated already !");
+ return MESHD_ERROR_NONE;
+ }
+
+ result = g_spawn_command_line_async("/usr/bin/killall dhcp", &error);
+ if (FALSE == result) {
+ MESH_LOGE("Failed to terminate DHCP : [%s]", error->message);
+ g_error_free(error);
+ return MESHD_ERROR_OPERATION_FAILED;
+ }
+
+ g_source_remove(dhcp_info->output_source);
+ g_source_remove(dhcp_info->error_source);
+
+ g_free(dhcp_info);
+ dhcp_info = NULL;
+
+ return MESHD_ERROR_NONE;
+}