2 * This file is part of hayes-ril.
4 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #define LOG_TAG "RIL-DEV"
26 #include <utils/Log.h>
29 #include <hayes-ril.h>
31 int gta04_power_boot(void *sdata)
33 struct stat tty_node_stat;
38 for(i=0 ; i < TTY_NODE_MAX ; i++) {
39 asprintf(&tty_node, "%s/%s%d", TTY_DEV_BASE, TTY_NODE_BASE, i);
41 rc = stat(tty_node, &tty_node_stat);
53 int gta04_transport_sdata_create(void **sdata)
55 struct gta04_transport_data *transport_data = NULL;
57 transport_data = malloc(sizeof(struct gta04_transport_data));
58 memset(transport_data, 0, sizeof(struct gta04_transport_data));
60 *sdata = (void *) transport_data;
65 int gta04_transport_sdata_destroy(void *sdata)
75 int gta04_transport_find_node(char **tty_node, char *name)
77 char *tty_sysfs_node = NULL;
83 if(tty_node == NULL || name == NULL)
86 name_length = strlen(name);
87 buf = calloc(1, name_length);
89 for(i=0 ; i < TTY_NODE_MAX ; i++) {
90 asprintf(&tty_sysfs_node, "%s/%s%d/%s",
91 TTY_SYSFS_BASE, TTY_NODE_BASE, i, TTY_HSOTYPE);
93 fd = open(tty_sysfs_node, O_RDONLY);
99 read(fd, buf, name_length);
100 if(strncmp(name, buf, name_length) == 0) {
101 asprintf(tty_node, "%s/%s%d", TTY_DEV_BASE, TTY_NODE_BASE, i);
103 free(tty_sysfs_node);
106 free(tty_sysfs_node);
115 int gta04_transport_open(void *sdata)
117 struct gta04_transport_data *transport_data = NULL;
119 char *dev_node = NULL;
126 transport_data = (struct gta04_transport_data *) sdata;
129 if(transport_data->modem_fd <= 0) {
130 rc = gta04_transport_find_node(&dev_node, "Modem");
132 LOGE("Unable to find Modem node, aborting!");
136 fd = open(dev_node, O_RDWR | O_NOCTTY | O_NDELAY);
138 LOGE("Unable to open Modem node, aborting!");
142 rc = tcgetattr(fd, &term);
144 LOGE("Unable to get Modem note attrs, aborting!");
148 term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
149 cfsetispeed(&term, B115200);
150 cfsetospeed(&term, B115200);
152 rc = tcsetattr(fd, TCSANOW, &term);
154 LOGE("Unable to set Modem note attrs, aborting!");
158 LOGD("Opened Modem node");
159 transport_data->modem_fd = fd;
162 // Open Application node
163 if(transport_data->application_fd <= 0) {
164 rc = gta04_transport_find_node(&dev_node, "Application");
166 LOGE("Unable to find Application node, aborting!");
170 fd = open(dev_node, O_RDWR | O_NOCTTY | O_NDELAY);
172 LOGE("Unable to open Application node, aborting!");
176 rc = tcgetattr(fd, &term);
178 LOGE("Unable to get Application note attrs, aborting!");
182 term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
183 cfsetispeed(&term, B115200);
184 cfsetospeed(&term, B115200);
186 rc = tcsetattr(fd, TCSANOW, &term);
188 LOGE("Unable to set Application note attrs, aborting!");
192 LOGD("Opened Application node");
193 transport_data->application_fd = fd;
205 int gta04_transport_close(void *sdata)
207 struct gta04_transport_data *transport_data = NULL;
212 transport_data = (struct gta04_transport_data *) sdata;
214 if(transport_data->modem_fd > 0)
215 close(transport_data->modem_fd);
217 if(transport_data->application_fd > 0)
218 close(transport_data->application_fd);
223 int gta04_transport_send(void *sdata, void *data, int length)
225 struct gta04_transport_data *transport_data = NULL;
227 // Written data count
231 // Total written data count
234 if(sdata == NULL || data == NULL || length <= 0)
237 transport_data = (struct gta04_transport_data *) sdata;
239 if(transport_data->modem_fd < 0)
244 // Outgoing AT data must be written to the Modem node apparently
245 wc = write(transport_data->modem_fd, data + (length - mc), mc);
256 int gta04_transport_recv(void *sdata, void **data, int length)
258 struct gta04_transport_data *transport_data = NULL;
266 // Total read data count
272 transport_data = (struct gta04_transport_data *) sdata;
274 if(transport_data->modem_fd < 0)
276 if(transport_data->application_fd < 0)
279 if(transport_data->modem_ac > 0) {
280 fd = transport_data->modem_fd;
281 mc = transport_data->modem_ac;
282 } else if(transport_data->application_ac > 0) {
283 fd = transport_data->application_fd;
284 mc = transport_data->application_ac;
290 if(length == 1 && mc == 1) {
291 // Read an unknown number of bytes
293 buffer = (char *) calloc(1, RECV_BYTES_MAX);
295 rc = read(fd, (void *) buffer, RECV_BYTES_MAX);
303 // Read the exact number of bytes
305 buffer = (char *) calloc(1, mc);
308 rc = read(fd, (void *) (buffer + tc), mc - tc);
322 *data = (void *) buffer;
324 if(transport_data->modem_ac > 0)
325 transport_data->modem_ac = 0;
326 else if(transport_data->application_ac > 0)
327 transport_data->application_ac = 0;
332 int gta04_transport_recv_poll(void *sdata)
334 struct gta04_transport_data *transport_data = NULL;
340 transport_data = (struct gta04_transport_data *) sdata;
342 if(transport_data->modem_fd < 0)
344 if(transport_data->application_fd < 0)
348 FD_SET(transport_data->modem_fd, &fds);
349 FD_SET(transport_data->application_fd, &fds);
351 select(FD_SETSIZE, &fds, NULL, NULL, NULL);
353 // Process one at a time
354 if(FD_ISSET(transport_data->modem_fd, &fds)) {
355 transport_data->modem_ac = 1;
356 } else if(FD_ISSET(transport_data->application_fd, &fds)) {
357 transport_data->application_ac = 1;
363 int gta04_dummy(void *sdata)
368 struct ril_device_power_handlers gta04_power_handlers = {
370 .sdata_create = gta04_dummy,
371 .sdata_destroy = gta04_dummy,
372 .power_on = gta04_dummy,
373 .power_off = gta04_dummy,
374 .suspend = gta04_dummy,
375 .resume = gta04_dummy,
376 .boot = gta04_power_boot,
379 struct ril_device_transport_handlers gta04_transport_handlers = {
381 .sdata_create = gta04_transport_sdata_create,
382 .sdata_destroy = gta04_transport_sdata_destroy,
383 .open = gta04_transport_open,
384 .close = gta04_transport_close,
385 .send = gta04_transport_send,
386 .recv = gta04_transport_recv,
387 .recv_poll = gta04_transport_recv_poll,
390 struct ril_device_handlers gta04_handlers = {
391 .power = >a04_power_handlers,
392 .transport = >a04_transport_handlers,
395 struct ril_device gta04_device = {
396 .name = "Goldelico GTA04",
399 .handlers = >a04_handlers,
402 void ril_device_register(struct ril_device **ril_device_p)
404 *ril_device_p = >a04_device;