t_model_car_connection_update_cb controller_update_cb;
GSocket *socket;
- GSocketAddress *car;
+ GSocketAddress *car_address;
gint port;
guint io_watch_id;
Ecore_Timer *connection_wait_timer;
+
+ bool ready_to_drive;
+
+ float direction;
+ float throttle;
} s_model_car_connection;
s_model_car_connection s_info = { 0, };
gboolean _read_socket_cb(GIOChannel *source, GIOCondition condition, gpointer data)
{
+ GIOChannel *channel = data;
+ GString *buffer = g_string_new(NULL);
+ GIOStatus state = G_IO_STATUS_NORMAL;
+ GError *error = NULL;
- return true;
+ while (state == G_IO_STATUS_NORMAL)
+ {
+ gsize delim = 0;
+
+ state = g_io_channel_read_line_string(channel, buffer, &delim, &error);
+
+ if (error) {
+ g_warning("%s\n", error->message);
+ }
+
+ switch(state)
+ {
+ case G_IO_STATUS_NORMAL:
+ if (strlen(buffer->str) > 0)
+ {
+ _D("Got: %s\n", buffer->str);
+ if (!strncmp(buffer->str, "PING!", strlen("PING!")))
+ {
+ _D("Received reply\n");
+ }
+ else if (!strncmp(buffer->str, "Welcome to the echo service!", strlen("Welcome to the echo service!")))
+ {
+ _D("Service online\n");
+ }
+
+ /* reset the buffer for the next call */
+ g_string_set_size(buffer, 0);
+ delim = 0;
+ }
+ break;
+ case G_IO_STATUS_AGAIN:
+ /* no data right now... try again later */
+ break;
+ case G_IO_STATUS_ERROR:
+ case G_IO_STATUS_EOF:
+ _W("Error reading: %s\n", error->message);
+
+ /* drop last reference on connection */
+ g_io_channel_shutdown(channel, FALSE, &error);
+
+ /* don't need the input buffer anymore */
+ g_string_free(buffer, TRUE);
+
+ /* remove the event source */
+ return(FALSE);
+ }
+ }
+
+ return true;
}
static void _receiver_udp_start(void)
{
int socket_fd = g_socket_get_fd(s_info.socket);
GIOChannel *channel = g_io_channel_unix_new(socket_fd);
- s_info.io_watch_id = g_io_add_watch(channel, G_IO_IN, _read_socket_cb, NULL);
+ s_info.io_watch_id = g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP, _read_socket_cb, channel);
g_io_channel_unref(channel);
}
GError *error = NULL;
static s_message message = { 0, };
- _D("Send Servo[%d], Speed[%d]", message.servo, message.speed);
+ _D("Send CMD[%d], Servo[%d], Speed[%d]", message.cmd, message.servo, message.speed);
message.cmd = command;
message.servo = servo;
message.time = time(NULL);
ASSERT(!s_info.socket, "Socket not created");
- ASSERT(!s_info.car, "Destination not set");
+ ASSERT(!s_info.car_address, "Destination not set");
GIOCondition condition = g_socket_condition_check(s_info.socket, G_IO_OUT);
+
if (condition != G_IO_OUT) {
- _D("condition != G_IO_OUT");
- return;
+ _W("condition == %d", condition);
+// return;
}
- gssize size = g_socket_send_to(s_info.socket, s_info.car,
- (const gchar *)&message, sizeof(message), NULL, &error);
+ bool connection_result = g_socket_check_connect_result(s_info.socket, &error);
+ ASSERT(error, "g_socket_check_connect_result(). Error: %s", error->message);
+ ASSERT(!connection_result, "connection_result == false")
- if (size < 0) {
- _E("Failed to send to socket: %s", error->message);
+ gssize size = g_socket_send(s_info.socket, (const gchar *)&message, sizeof(s_message), NULL, &error);
+ ASSERT(size < 0, "Failed to send to socket: %s", error->message)
+
+ if (error) {
g_error_free(error);
}
}
.type = MODEL_TYPE_FAIL,
};
- s_info.controller_update_cb(&model_data);
+ return ECORE_CALLBACK_CANCEL; //TODO Test only
+
+ if (s_info.controller_update_cb) {
+ s_info.controller_update_cb(&model_data);
+ }
+
model_car_connection_end_connection();
bool renew = (bool)data;
s_info.socket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error);
ASSERT(!s_info.socket, "Failed to get new Socket - %s", error->message);
+ if (error) {
+ g_error_free(error);
+ }
+
_receiver_udp_start();
}
void model_car_connection_model_state_change(void)
{
-// static s_model_car_connection_cb_data model_data = {
-// .type = MODEL_TYPE_END,
-// };
-
- // TODO Wait for connection
-// s_info.controller_update_cb(&model_data);
+ static s_model_car_connection_cb_data model_data = {
+ .type = MODEL_TYPE_END,
+ };
- model_car_connection_start_connection("192.168.0.1", 1234);
+ s_info.controller_update_cb(&model_data);
}
void model_car_connection_unsubscirbe_event()
{
void model_car_connection_start_connection(char *address, int port)
{
s_info.port = port;
- s_info.car = g_inet_socket_address_new_from_string(address, port);
- ASSERT_MEMORY(!s_info.car);
+ s_info.car_address = g_inet_socket_address_new_from_string(address, port);
+ ASSERT_MEMORY(!s_info.car_address);
- _send_data(MESSAGE_HELLO, 0, 0);
+ GError *error = NULL;
+ bool connected = g_socket_connect(s_info.socket, s_info.car_address, NULL, &error);
+ ASSERT(error, "g_socket_connect(): %s", error->message);
+ ASSERT(!connected, "Failed to connect to socket");
+ _send_data(MESSAGE_HELLO, 0, 0);
s_info.connection_wait_timer = ecore_timer_add(HELLO_TIMER_WAIT, _connection_wait_timer_cb, (void *)ECORE_CALLBACK_CANCEL);
+// static s_model_car_connection_cb_data model_data = {
+// .type = MODEL_TYPE_END,
+// };
- static s_model_car_connection_cb_data model_data = {
- .type = MODEL_TYPE_WAIT,
- };
- s_info.controller_update_cb(&model_data);
+// s_info.controller_update_cb(&model_data);
+
+ if (error) {
+ g_error_free(error);
+ }
+}
+
+void model_car_connection_ready_to_drive(bool is_ready)
+{
+ s_info.ready_to_drive = is_ready;
}
void model_car_connection_end_connection(void)
return;
}
- g_socket_close(s_info.socket, NULL);
- g_object_unref(s_info.socket);
- g_object_unref(s_info.car);
+ GError *error = NULL;
+ g_socket_shutdown(s_info.socket, true, true, &error);
+ ASSERT(error, "Failed to shutdown the socket");
+
+ g_object_unref(s_info.car_address);
+
+ if (error) {
+ g_error_free(error);
+ }
}
-void model_car_connection_send_stering_data(float direction, float throttle)
+void model_car_connection_send_direction(float direction)
{
- _send_data(MESSAGE_DRIVE, direction * -BASE_VALUE, throttle * -BASE_VALUE);
+ if (!s_info.ready_to_drive) {
+ return;
+ }
+
+ s_info.direction = direction;
+ _send_data(MESSAGE_DRIVE, s_info.direction * -BASE_VALUE, s_info.throttle * -BASE_VALUE);
}
+void model_car_connection_send_throttle(float throttle)
+{
+ if (!s_info.ready_to_drive) {
+ return;
+ }
+ s_info.throttle = throttle;
+ _send_data(MESSAGE_DRIVE, s_info.direction * -BASE_VALUE, s_info.throttle * -BASE_VALUE);
+}
* limitations under the License.
*/
+#include <system_info.h>
#include "view/view_base.h"
#include "view/view_car_selection.h"
#include "controller/controller_car_selection.h"
evas_object_smart_callback_add(s_info.genlist, "drag,stop", _genlist_scroll_cb, (void *)SCROLL_DRAG_STOP);
}
-static void _create_genlist(Eext_Circle_Surface *circle_surface)
+void _set_circular_parameters(Eext_Circle_Surface* circle_surface)
{
- s_info.genlist = elm_genlist_add(s_info.view_base.view);
- ASSERT_MEMORY(!s_info.genlist);
+ bool is_circular = false;
+ system_info_get_platform_bool("http://tizen.org/feature/screen.shape.circle", &is_circular);
- Evas_Object *circle_genlist = eext_circle_object_genlist_add(s_info.genlist, circle_surface);
+ if (!is_circular) {
+ _D("Circular screen shape is not supported");
+ return;
+ }
+
+ Evas_Object* circle_genlist = eext_circle_object_genlist_add(s_info.genlist, circle_surface);
ASSERT_MEMORY(!circle_genlist);
eext_circle_object_genlist_scroller_policy_set(circle_genlist, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_AUTO);
eext_circle_object_item_color_set(circle_genlist, "default", 255, 0, 0, 128);
eext_circle_object_item_color_set(circle_genlist, "vertical,scroll,bg", 255, 255, 255, 15);
eext_circle_object_line_width_set(circle_genlist, 5);
+}
+
+static void _create_genlist(Eext_Circle_Surface *circle_surface)
+{
+ s_info.genlist = elm_genlist_add(s_info.view_base.view);
+ ASSERT_MEMORY(!s_info.genlist);
+
+ _set_circular_parameters(circle_surface);
s_info.itc = elm_genlist_item_class_new();
ASSERT_MEMORY(!s_info.itc);