#include <net/if.h>
#include <linux/if_tun.h>
#include <fcntl.h>
+#include <termios.h>
#include <glib.h>
#define CHANNEL_MAX 8
+#define DEVICE_IFX "/dev/ttyIFX0"
+
#define CHANNEL_MODEM 3
#define CHANNEL_CALL 1
#define CHANNEL_SIM 1
#define CHANNEL_NONE -1
struct custom_data {
- int hal_fd;
+ GIOChannel *channel;
guint watch_id;
void *cb;
void *cb_data;
return NULL;
}
+static gboolean setup_channel(GIOChannel *io)
+{
+ GIOFlags io_flags;
+
+ if (g_io_channel_set_encoding(io, NULL, NULL) != G_IO_STATUS_NORMAL)
+ return FALSE;
+
+ g_io_channel_set_buffered(io, FALSE);
+ io_flags = g_io_channel_get_flags(io);
+ io_flags |= (G_IO_FLAG_NONBLOCK & G_IO_FLAG_SET_MASK);
+
+ if (g_io_channel_set_flags(io, io_flags, NULL) != G_IO_STATUS_NORMAL)
+ return FALSE;
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ return TRUE;
+}
+
+static void set_termio(int fd)
+{
+ struct termios newtio;
+
+ /* Switch TTY to raw mode */
+ memset(&newtio, 0, sizeof(newtio));
+ cfmakeraw(&newtio);
+
+ /* Line is local */
+ newtio.c_cflag |= CLOCAL;
+
+ tcflush(fd, TCIFLUSH);
+ tcsetattr(fd, TCSANOW, &newtio);
+}
+
+static int open_device(const char *tty)
+{
+ int fd;
+
+ fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0)
+ return -1;
+
+ set_termio(fd);
+
+ return fd;
+}
+
+static GIOChannel *tty_open(const char *tty)
+{
+ GIOChannel *channel;
+ int fd;
+
+ fd = open_device(tty);
+ if (fd < 0)
+ return NULL;
+
+ dbg("fd =%d ", fd);
+
+ channel = g_io_channel_unix_new(fd);
+ if (channel == NULL) {
+ close(fd);
+ return NULL;
+ }
+
+ setup_channel(channel);
+
+ return channel;
+}
+
static void on_cmux_init(void *user_data)
{
TcoreHal *hal = user_data;
static TReturn hal_power(TcoreHal *hal, gboolean flag,
TcoreHalPowerCallBack func, void *user_data)
{
- struct custom_data *cdata;
+ struct custom_data *cdata = tcore_hal_ref_user_data(hal);
- cdata = tcore_hal_ref_user_data(hal);
+ dbg("Entry");
/* power on */
if (flag == TRUE) {
tcore_cmux_close();
g_source_remove(cdata->watch_id);
- close(cdata->hal_fd);
+ g_io_channel_unref(cdata->channel);
g_free(cdata);
static TReturn hal_send(TcoreHal *hal, unsigned int data_len, void *data)
{
- int ret;
- struct custom_data *user_data;
+ size_t bytes_written;
+ struct custom_data *cdata;
if (tcore_hal_get_power_state(hal) == FALSE)
return TCORE_RETURN_FAILURE;
- user_data = tcore_hal_ref_user_data(hal);
- if (!user_data)
+ cdata = tcore_hal_ref_user_data(hal);
+ if (!cdata)
return TCORE_RETURN_FAILURE;
- ret = fd_write(user_data->hal_fd, data, data_len);
- if(ret < 0) {
- err("fd_write failed");
+ bytes_written = channel_write(cdata->channel, data, data_len);
+ if(bytes_written != data_len) {
+ err("channel_write failed");
return TCORE_RETURN_FAILURE;
}
- dbg("fd_write success ret=%d (fd=%d, len=%d)", ret, user_data->hal_fd, data_len);
+ dbg("channel_write success (channel=%p, len=%d)", cdata->channel, bytes_written);
return TCORE_RETURN_SUCCESS;
}
TcoreHal *hal;
TReturn ret;
+ dbg("Entry");
+
hal = get_object_hal(name);
if (hal == NULL)
return TCORE_RETURN_EINVAL;
return ret;
}
-static guint register_gio_watch(TcoreHal *h, int fd, void *callback)
+static guint register_gio_watch(GIOChannel *channel, void *callback, TcoreHal *h)
{
- GIOChannel *channel = NULL;
guint source;
- if (fd < 0 || !callback)
+ if (channel == NULL || !callback)
return 0;
- channel = g_io_channel_unix_new(fd);
source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) callback, h);
g_io_channel_unref(channel);
- channel = NULL;
return source;
}
-static int create_tun(const char **interface)
+static GIOChannel *create_tun(const char **interface)
{
GIOChannel *channel;
struct ifreq ifr;
fd = open("/dev/net/tun", O_RDWR);
if (fd < 0)
- return fd;
+ return NULL;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
err = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (err < 0) {
close(fd);
- return -1;
+ return NULL;
}
*interface = g_strdup(ifr.ifr_name);
channel = g_io_channel_unix_new(fd);
if (channel == NULL) {
close(fd);
- return -1;
+ return NULL;
}
- return fd;
+ return channel;
}
/*
static gboolean on_recv_data_message(GIOChannel *channel, GIOCondition condition, gpointer data)
{
TcoreHal *hal = data;
- struct custom_data *custom;
- char buf[BUF_LEN_MAX];
- int n = 0;
-
- custom = tcore_hal_ref_user_data(hal);
- memset(buf, 0, BUF_LEN_MAX);
- n = fd_read(custom->hal_fd, buf, BUF_LEN_MAX);
- if (n < 0) {
- err("fd_read error. return_valute = %d", n);
- return TRUE;
+ char read_buffer[BUF_LEN_MAX];
+ size_t bytes_read;
+
+ bytes_read = channel_read(channel, read_buffer, BUF_LEN_MAX);
+ if (bytes_read == 0) {
+ err("channel_read error.");
+ return FALSE;
}
msg("=== TX %s data DUMP =====", tcore_hal_get_name(hal));
- util_hex_dump(" ", n, buf);
+ util_hex_dump(" ", bytes_read, read_buffer);
msg("=== TX %s data DUMP =====", tcore_hal_get_name(hal));
/* Send to cmux data channel for encoding */
- tcore_hal_send_data(hal, n, buf);
+ tcore_hal_send_data(hal, bytes_read, read_buffer);
return TRUE;
}
*/
static void on_hal_recv(TcoreHal *hal, unsigned int data_len, const void *data, void *user_data)
{
- int ret;
- struct custom_data *cdata;
- cdata = tcore_hal_ref_user_data(hal);
+ struct custom_data *cdata = tcore_hal_ref_user_data(hal);
+ size_t bytes_written;
+
+ dbg("Entry");
if (!cdata) {
err("hal user data is NULL");
return;
}
- ret = fd_write(cdata->hal_fd, (void *)data, data_len);
- if(ret < 0)
- err("fd_write failed");
+ bytes_written = channel_write(cdata->channel, (void *)data, data_len);
+ if(bytes_written != data_len)
+ err("channel_write failed");
msg("=== RX %s data DUMP =====", tcore_hal_get_name(hal));
- util_hex_dump(" ", data_len, data);
+ util_hex_dump(" ", bytes_written, data);
msg("=== RX %s data DUMP =====", tcore_hal_get_name(hal));
}
CoreObject *co = tcore_pending_ref_core_object(p);
TcoreHalSetupPDPCallBack func = (TcoreHalSetupPDPCallBack)cdata->cb;
- dbg("Entered");
+ dbg("Entry");
if (resp->success) {
dbg("Response Ok");
- cdata->hal_fd = create_tun(&interface);
- if (cdata->hal_fd < 0) {
+ cdata->channel = create_tun(&interface);
+ if (cdata->channel == NULL) {
func(co, NULL, cdata->cb_data);
g_free(cdata);
return;
}
+ setup_channel(cdata->channel);
+
dbg("interface: %s", interface);
- cdata->watch_id= register_gio_watch(hal, cdata->hal_fd, on_recv_data_message);
+ cdata->watch_id= register_gio_watch(cdata->channel, on_recv_data_message, hal);
tcore_hal_set_mode(hal, TCORE_HAL_MODE_DATA);
tcore_hal_add_recv_callback(hal, on_hal_recv, NULL);
char *cmd_str = NULL;
struct custom_data *cdata;
- dbg("entry");
+ dbg("Entry");
if (cid == 1)
hal = tcore_cmux_get_hal_channel(CHANNEL_DATA_1);
if (tcore_hal_get_mode(hal) == TCORE_HAL_MODE_DATA) {
cdata = tcore_hal_ref_user_data(hal);
- if (cdata->hal_fd) {
- close(cdata->hal_fd);
- cdata->hal_fd = -1;
- }
+ if (cdata->channel) {
+ g_source_remove(cdata->watch_id);
+ g_io_channel_unref(cdata->channel);
- g_source_remove(cdata->watch_id);
-
- g_free(cdata);
- cdata = NULL;
+ g_free(cdata);
+ cdata = NULL;
+ }
dbg("Set MODE_AT");
tcore_hal_set_mode(hal, TCORE_HAL_MODE_AT);
- dbg("Remove old reveice cb");
+ dbg("Remove old receive cb");
tcore_hal_remove_recv_callback(hal, on_hal_recv);
}
static gboolean on_recv_tty_message(GIOChannel *channel, GIOCondition condition, gpointer data)
{
TcoreHal *hal = data;
- struct custom_data *custom;
- char buf[BUF_LEN_MAX];
- int n = 0;
-
- custom = tcore_hal_ref_user_data(hal);
- memset(buf, 0, BUF_LEN_MAX);
- n = fd_read(custom->hal_fd, buf, BUF_LEN_MAX);
- if (n < 0) {
- err("fd_read error. return_valute = %d", n);
- return TRUE;
+ char read_buffer[BUF_LEN_MAX];
+ size_t bytes_read;
+
+ dbg("Entry");
+
+ bytes_read = channel_read(channel, read_buffer, BUF_LEN_MAX);
+ if (bytes_read == 0) {
+ err("channel_read error.");
+ return FALSE;
}
- dbg("tty recv (ret = %d)", n);
- tcore_hal_emit_recv_callback(hal, n, buf);
+ dbg("bytes_read = %d", bytes_read);
+ tcore_hal_emit_recv_callback(hal, bytes_read, read_buffer);
- tcore_hal_dispatch_response_data(hal, 0, n, buf);
+ tcore_hal_dispatch_response_data(hal, 0, bytes_read, read_buffer);
return TRUE;
}
/* Phonet init */
data = g_new0(struct custom_data, 1);
- data->hal_fd = tty_open();
- if (data->hal_fd < 0) {
+ data->channel = tty_open(DEVICE_IFX);
+ if (data->channel == NULL) {
+ err("Failed to open tty port - [%s]", strerror(errno));
g_free(data);
return FALSE;
}
+ dbg("tty port (%s) opened successfully", DEVICE_IFX);
+
/* HAL init */
hal = tcore_hal_new(plugin, "imc-pr3", &hops, TCORE_HAL_MODE_AT);
- tcore_hal_link_user_data(hal, data);
+ if (hal == NULL){
+ err("Failed to create HAL");
+ g_free(data);
+ return FALSE;
+ }
+
+ data->watch_id = register_gio_watch(data->channel, on_recv_tty_message, hal);
- data->watch_id= register_gio_watch(hal, data->hal_fd, on_recv_tty_message);
+ if (data->watch_id == 0){
+ err("Failed to register gio watch ");
+ free(data);
+ tcore_hal_free(hal);
+ g_io_channel_unref(data->channel);
+ return FALSE;
+ }
- dbg("hal_fd = %d, watch_id=%d ", data->hal_fd, data->watch_id);
+ tcore_hal_link_user_data(hal, data);
+
+ dbg("HAL is imc-pr3: channel = %p, watch_id=%d ", data->channel, data->watch_id);
if (pr3_audio_init() != TRUE)
err("Error in audio initialization")
-
return TRUE;
}
#include <unistd.h>
#include <fcntl.h>
+#include <glib.h>
+
#include <log.h>
#include <util_imc.h>
-#define TTY_OPEN_PATH "/dev/ttyIFX0"
+#define MAX_READ_ATTEMPTS 4
+#define MAX_WRITE_ATTEMPTS 10
-int tty_open(void)
+/* Read data from a GIOChannel */
+size_t channel_read(GIOChannel *channel, void* buf, size_t nbytes)
{
- int fd = -1;
-
- dbg("Function Enter");
+ GIOStatus status;
+ size_t rbytes;
+ size_t toread = nbytes;
+ size_t bytes_read = 0;
+ unsigned int read_count = 0;
- fd = open(TTY_OPEN_PATH, O_RDWR);
-
- if (fd < 0) {
- err("Failed to open tty port %x", errno);
+ do {
+ rbytes = 0;
- return -1;
- } else
- dbg("tty port opened successfully. fd:%d, path:%s",
- fd, TTY_OPEN_PATH);
+ status = g_io_channel_read_chars(channel, buf, toread, &rbytes, NULL);
- return fd;
+ read_count++;
-}
+ err("g_io_channel_read_chars.. status[%d] rbytes =%d read_count = %d", status, rbytes, read_count);
-int fd_read(int nFd, void* buf, size_t nbytes)
-{
- int actual = 0;
+ bytes_read += rbytes;
+ toread -= rbytes;
- dbg("Function Enter");
+ if (rbytes > 0)
+ buf+=rbytes;
- actual = read(nFd, buf, nbytes);
- if (actual < 0) {
- dbg("fd_read failed.");
+ if (toread == 0)
+ break;
- return actual;
- }
+ } while (status == G_IO_STATUS_NORMAL && rbytes > 0 && read_count < MAX_READ_ATTEMPTS);
- return actual;
+ return bytes_read;
}
static void __selectsleep(int sec,int msec)
return;
}
-/* Write data to imc tty port */
-int fd_write(int nFd, void* buf, size_t nbytes)
+/* Write data to a GIOChannel */
+size_t channel_write(GIOChannel *channel, void* buf, size_t nbytes)
{
- int ret;
- size_t actual = 0;
- int retry = 0;
+ GIOStatus status;
+ size_t tbytes = 0;
+ size_t bytes_written = 0;
+ unsigned int retry = 0;
do {
- ret = write(nFd, (unsigned char* )buf, nbytes - actual);
+ status = g_io_channel_write_chars(channel, (const gchar*)buf, nbytes - bytes_written, &tbytes, NULL);
- if ((ret < 0 && errno == EAGAIN) ||
- (ret < 0 && errno == EBUSY)) {
- err("write failed. retry.. ret[%d] with errno[%d]",
- ret, errno);
+ if (status == G_IO_STATUS_AGAIN) {
+ err("write failed. Retry.. status[%d] Nb attempt[%d]", status, retry);
__selectsleep(0,50);
- if (retry == 10)
+ if (retry == MAX_WRITE_ATTEMPTS)
return 0;
retry = retry + 1;
continue;
}
- if (ret < 0) {
- if (actual != nbytes)
- err("write failed.ret[%d]",ret);
-
- err("errno [%d]",errno);
+ if (status != G_IO_STATUS_NORMAL) {
+ if (bytes_written != nbytes)
+ err("write failed. status[%d] with errno[%d]", status, errno);
- return actual;
+ return bytes_written;
}
- actual += ret;
- buf += ret;
+ bytes_written += tbytes;
+ buf += tbytes;
- } while (actual < nbytes);
+ } while (bytes_written < nbytes);
- return actual;
+ return bytes_written;
}
void util_hex_dump(char *pad, int size, const void *data)