5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include <connman/log.h>
50 struct modem_callback {
63 static int send_command(struct modem_data *modem, struct modem_cmd *cmd)
68 if (cmd->arg == NULL) {
69 DBG("AT%s", cmd->cmd);
70 buf = g_strdup_printf("AT%s\r\n", cmd->cmd);
72 DBG("AT%s=%s", cmd->cmd, cmd->arg);
73 buf = g_strdup_printf("AT%s=%s\r\n", cmd->cmd, cmd->arg);
76 fd = g_io_channel_unix_get_fd(modem->channel);
77 err = write(fd, buf, strlen(buf));
86 static int queue_command(struct modem_data *modem, struct modem_cmd *cmd)
88 modem->commands = g_slist_append(modem->commands, cmd);
90 if (g_slist_length(modem->commands) > 1)
93 return send_command(modem, cmd);
96 struct modem_data *modem_create(const char *device)
98 struct modem_data *modem;
100 DBG("device %s", device);
102 modem = g_try_new0(struct modem_data, 1);
106 modem->device = g_strdup(device);
108 DBG("modem %p", modem);
113 void modem_destroy(struct modem_data *modem)
115 DBG("modem %p", modem);
120 g_free(modem->device);
124 static gboolean modem_event(GIOChannel *channel,
125 GIOCondition condition, gpointer user_data)
127 struct modem_data *modem = user_data;
128 struct modem_cmd *cmd;
133 if (condition & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
136 err = g_io_channel_read(channel, modem->buf + modem->offset,
137 sizeof(modem->buf) - modem->offset, &len);
139 if (err == G_IO_ERROR_AGAIN)
144 DBG("Read %d bytes (offset %d)", len, modem->offset);
146 if (g_str_has_suffix(modem->buf, "\r\n") == TRUE) {
147 for (list = modem->callbacks; list; list = list->next) {
148 struct modem_callback *callback = list->data;
150 if (callback->function == NULL)
153 if (g_strrstr(modem->buf, callback->command) != NULL)
154 callback->function(modem->buf,
155 callback->user_data);
159 if (g_strrstr(modem->buf, "\r\nERROR\r\n") == NULL &&
160 g_strrstr(modem->buf, "\r\nOK\r\n") == NULL) {
161 modem->offset += len;
165 memset(modem->buf, 0, sizeof(modem->buf));
168 cmd = g_slist_nth_data(modem->commands, 0);
172 modem->commands = g_slist_remove(modem->commands, cmd);
174 DBG("AT%s", cmd->cmd);
177 cmd->callback(modem->buf, cmd->user_data);
183 cmd = g_slist_nth_data(modem->commands, 0);
187 send_command(modem, cmd);
192 static int open_device(const char *device)
197 fd = open(device, O_RDWR | O_NOCTTY);
201 tcflush(fd, TCIOFLUSH);
203 /* Switch TTY to raw mode */
204 memset(&ti, 0, sizeof(ti));
207 tcsetattr(fd, TCSANOW, &ti);
212 int modem_open(struct modem_data *modem)
216 DBG("modem %p", modem);
222 fd = open_device(modem->device);
231 connman_error("Can't open %s device", modem->device);
235 modem->channel = g_io_channel_unix_new(fd);
236 g_io_channel_set_close_on_unref(modem->channel, TRUE);
238 modem->watch = g_io_add_watch(modem->channel,
239 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
245 int modem_close(struct modem_data *modem)
247 DBG("modem %p", modem);
252 g_source_remove(modem->watch);
255 g_io_channel_unref(modem->channel);
256 modem->channel = NULL;
261 int modem_add_callback(struct modem_data *modem, const char *command,
262 modem_cb_t function, void *user_data)
264 struct modem_callback *callback;
266 callback = g_try_new0(struct modem_callback, 1);
267 if (callback == NULL)
270 callback->command = g_strdup(command);
271 callback->function = function;
272 callback->user_data = user_data;
274 modem->callbacks = g_slist_append(modem->callbacks, callback);
279 static int modem_command_valist(struct modem_data *modem, modem_cb_t callback,
280 void *user_data, const char *command,
281 const char *format, va_list var_args)
283 struct modem_cmd *cmd;
285 cmd = g_try_new0(struct modem_cmd, 1);
289 cmd->cmd = g_strdup(command);
291 cmd->arg = g_strdup_vprintf(format, var_args);
293 cmd->callback = callback;
294 cmd->user_data = user_data;
296 return queue_command(modem, cmd);
299 int modem_command(struct modem_data *modem,
300 modem_cb_t callback, void *user_data,
301 const char *command, const char *format, ...)
306 DBG("modem %p", modem);
311 va_start(args, format);
312 err = modem_command_valist(modem, callback, user_data,
313 command, format, args);