Finished Dream/Sapphire device handlers support and moved data to sdata.
authorPaul Kocialkowski <contact@paulk.fr>
Tue, 14 Feb 2012 19:19:35 +0000 (20:19 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Wed, 18 Jul 2012 14:33:47 +0000 (16:33 +0200)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
device.c
device/DEVICE_API.txt [new file with mode: 0644]
device/dream_sapphire/dream_sapphire.c
device/dream_sapphire/dream_sapphire.h [new file with mode: 0644]
hayes-ril.c
hayes-ril.h

index c8a080f..6e1e089 100644 (file)
--- a/device.c
+++ b/device.c
@@ -36,8 +36,8 @@ int ril_device_data_create(struct ril_device *ril_device_p)
                return -1;
        }
 
-       if(ril_device_p->handlers->power->data_create == NULL ||
-               ril_device_p->handlers->power->data_destroy == NULL) {
+       if(ril_device_p->handlers->power->sdata_create == NULL ||
+               ril_device_p->handlers->power->sdata_destroy == NULL) {
                LOGE("Missing device power data handlers!");
                return -1;
        }
@@ -47,23 +47,23 @@ int ril_device_data_create(struct ril_device *ril_device_p)
                return -1;
        }
 
-       if(ril_device_p->handlers->transport->data_create == NULL ||
-               ril_device_p->handlers->transport->data_destroy == NULL) {
+       if(ril_device_p->handlers->transport->sdata_create == NULL ||
+               ril_device_p->handlers->transport->sdata_destroy == NULL) {
                LOGE("Missing device transport data handlers!");
                return -1;
        }
 
        // iface
 
-       LOGD("Creating data for transport handlers...");
-
-       rc = ril_device_p->handlers->power->data_create(ril_device_p->handlers->power->data);
+       LOGD("Creating data for power handlers...");
+       rc = ril_device_p->handlers->power->sdata_create(&ril_device_p->handlers->power->sdata);
        if(rc < 0) {
                LOGE("Creating data for power handlers failed!");
                return -1;
        }
 
-       ril_device_p->handlers->transport->data_create(ril_device_p->handlers->transport->data);
+       LOGD("Creating data for transport handlers...");
+       ril_device_p->handlers->transport->sdata_create(&ril_device_p->handlers->transport->sdata);
        if(rc < 0) {
                LOGE("Creating data for transport handlers failed!");
                return -1;
@@ -93,7 +93,7 @@ int ril_device_boot(struct ril_device *ril_device_p)
 
        LOGD("Booting modem...");
 
-       rc = ril_device_p->handlers->power->boot(ril_device_p->handlers->power->data);
+       rc = ril_device_p->handlers->power->boot(ril_device_p->handlers->power->sdata);
        return rc;
 }
 
@@ -118,7 +118,7 @@ int ril_device_power_on(struct ril_device *ril_device_p)
 
        LOGD("Powering modem on...");
 
-       rc = ril_device_p->handlers->power->power_on(ril_device_p->handlers->power->data);
+       rc = ril_device_p->handlers->power->power_on(ril_device_p->handlers->power->sdata);
        return rc;
 }
 
@@ -143,7 +143,7 @@ int ril_device_power_off(struct ril_device *ril_device_p)
 
        LOGD("Powering modem off...");
 
-       rc = ril_device_p->handlers->power->power_off(ril_device_p->handlers->power->data);
+       rc = ril_device_p->handlers->power->power_off(ril_device_p->handlers->power->sdata);
        return rc;
 }
 
@@ -168,6 +168,52 @@ int ril_device_open(struct ril_device *ril_device_p)
 
        LOGD("Opening modem...");
 
-       rc = ril_device_p->handlers->transport->open(ril_device_p->handlers->transport->data);
+       rc = ril_device_p->handlers->transport->open(ril_device_p->handlers->transport->sdata);
+       return rc;
+}
+
+int ril_device_send(struct ril_device *ril_device_p, void *data, int length)
+{
+       int rc;
+
+       if(ril_device_p->handlers == NULL) {
+               LOGE("Missing device handlers!");
+               return -1;
+       }
+
+       if(ril_device_p->handlers->transport == NULL) {
+               LOGE("Missing device transport handlers!");
+               return -1;
+       }
+
+       if(ril_device_p->handlers->transport->send == NULL) {
+               LOGE("Missing device transport send handler!");
+               return -1;
+       }
+
+       rc = ril_device_p->handlers->transport->send(ril_device_p->handlers->transport->sdata, data, length);
+       return rc;
+}
+
+int ril_device_recv(struct ril_device *ril_device_p, void **data, int length)
+{
+       int rc;
+
+       if(ril_device_p->handlers == NULL) {
+               LOGE("Missing device handlers!");
+               return -1;
+       }
+
+       if(ril_device_p->handlers->transport == NULL) {
+               LOGE("Missing device transport handlers!");
+               return -1;
+       }
+
+       if(ril_device_p->handlers->transport->recv == NULL) {
+               LOGE("Missing device transport recv handler!");
+               return -1;
+       }
+
+       rc = ril_device_p->handlers->transport->recv(ril_device_p->handlers->transport->sdata, data, length);
        return rc;
 }
diff --git a/device/DEVICE_API.txt b/device/DEVICE_API.txt
new file mode 100644 (file)
index 0000000..bdfd3bb
--- /dev/null
@@ -0,0 +1,89 @@
+Hayes RIL Device API
+====================
+
+This file is part of hayes-ril.
+
+Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Purpose of this document
+------------------------
+
+This document is a guide to add support for a new device in Hayes RIL.
+It explains how to use the device API.
+
+Files
+-----
+
+The files for a new device must be placed in a specific folder contained in
+the "device" folder, on the source tree root. The name of this folder depends
+on the device.
+
+Please, make it the same as the TARGET_DEVICE var in the device config files.
+
+The source can be split in several files, though, there must be a C code file
+with the same name as the folder holding the main structures for the device.
+
+Log tag
+-------
+
+The log tag to use on device-specific code is "RIL-DEV". Please use:
+#define LOG_TAG "RIL-DEV"
+
+Structures
+----------
+
+The device structures are described in hayes-ril.h, on the source tree root.
+The main structure for the device API is: "struct ril_device"
+The fields you can set on this are:
+
+.name  : The name of the new device.
+         This is usually the human-readable name of the device.
+
+.sdata : Some shared data for the device you can specify.
+         Give that the use you want, but it's not passed as argument to
+         the handlers functions.
+
+.type  : The device type (GSM, CDMA).
+
+The handlers field is a pointer to the device handlers structure.
+
+Handlers
+--------
+
+Handlers are functions and data designed to control input/output interactions
+with the device. The handlers structure is: "struct ril_device_handlers"
+
+The handlers are categorized that way:
+* power handlers (power on, power off, suspend, resume, boot)
+* transport handlers (open, close, send, recv, poll)
+
+Each handler has shared data (sdata) that can be used by any function of the
+handlers set. This data is created with the sdata_create function and destroyed
+with the sdata_destroy function, which are part of any handler category.
+
+Return codes
+------------
+
+Any function returning success must return an integer equal or greater than 0.
+Any function returning failure must return an integer lower than 0.
+
+Registering
+-----------
+
+The device files must provide a ril_device_register following the prototype
+described in hayes-ril.h, on the source tree root.
+
+On this function, you must register the pointer to the main structure of your
+device on the memory zone identified by the given pointer.
index 461023a..bdcf9dc 100644 (file)
  * limitations under the License.
  */
 
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define LOG_TAG "RIL-DEV"
+#include <utils/Log.h>
+
+#include "dream_sapphire.h"
 #include <hayes-ril.h>
 
+int dream_sapphire_boot(void *sdata)
+{
+       struct stat smd_stat;
+       int rc;
+
+       // Just check if SMD device was correctly created
+       rc = stat(SMD_DEV, &smd_stat);
+       if(rc < 0)
+               return -1;
+
+       return 0;
+}
+
+int dream_sapphire_transport_sdata_create(void **sdata)
+{
+       struct dream_sapphire_transport_data *transport_data = NULL;
+
+       transport_data = malloc(sizeof(struct dream_sapphire_transport_data));
+       memset(transport_data, 0, sizeof(struct dream_sapphire_transport_data));
+
+       *sdata = (void *) transport_data;
+
+       return 0;
+}
+
+int dream_sapphire_transport_sdata_destroy(void *sdata)
+{
+       if(sdata == NULL)
+               return 0;
+
+       free(sdata);
+
+       return 0;
+}
+
+int dream_sapphire_transport_open(void *sdata)
+{
+       struct dream_sapphire_transport_data *transport_data = NULL;
+       int fd = -1;
+
+       struct termios term;
+       int rc;
+
+       if(sdata == NULL)
+               return -1;
+
+       transport_data = (struct dream_sapphire_transport_data *) sdata;
+
+       fd = open(SMD_DEV, O_RDWR);
+
+       if(fd < 0)
+               return -1;
+
+       /* disable echo on serial ports */
+       rc = tcgetattr(fd, &term);
+       if(rc < 0)
+               return -1;
+
+       term.c_lflag = 0;
+       rc = tcsetattr(fd, TCSANOW, &term);
+       if(rc < 0)
+               return -1;
+
+       transport_data->fd = fd;
+
+       return 0;
+}
+
+int dream_sapphire_transport_close(void *sdata)
+{
+       struct dream_sapphire_transport_data *transport_data = NULL;
+
+       if(sdata == NULL)
+               return -1;
+
+       transport_data = (struct dream_sapphire_transport_data *) sdata;
+
+       if(transport_data->fd < 0)
+               return -1;
+
+       close(transport_data->fd);
+
+       return 0;
+}
+
+int dream_sapphire_transport_send(void *sdata, void *data, int length)
+{
+       struct dream_sapphire_transport_data *transport_data = NULL;
+
+       int wc;
+       int mc; // Min count
+       int tc = 0; // Total count of written data
+
+       if(sdata == NULL || data == NULL || length <= 0)
+               return -1;
+
+       transport_data = (struct dream_sapphire_transport_data *) sdata;
+
+       if(transport_data->fd < 0)
+               return -1;
+
+       mc = length;
+       while(mc > 0) {
+               wc = write(transport_data->fd, data + (length - mc), mc);
+
+               if(wc < 0)
+                       return -1;
+
+               tc += wc;
+               mc -= wc;
+       }
+
+       return tc;
+}
+
+int dream_sapphire_transport_recv(void *sdata, void **data, int length)
+{
+       struct dream_sapphire_transport_data *transport_data = NULL;
+       int l = READ_MAX_DATA_LEN;
+       void *d = NULL;
+
+       int rc;
+       int mc = 1; // Min count is 1 byte so whatever we read is fine (even 1 byte)
+       int tc = 0; // Total count of read data
+
+       if(sdata == NULL)
+               return -1;
+
+       transport_data = (struct dream_sapphire_transport_data *) sdata;
+
+       if(transport_data->fd < 0)
+               return -1;
+
+       // The amount of data to read is fixed
+       if(length > 0) {
+               l = length;
+               mc = l;
+       }
+
+       d = malloc(l);
+       memset(d, 0, l);
+
+       while(mc > 0) {
+               rc = read(transport_data->fd, d + tc, l - tc);
+
+               if(rc < 0)
+                       return -1;
+
+               tc += rc;
+               mc -= rc;
+       }
+
+       *data = malloc(tc);
+       memset(*data, 0, tc);
+
+       memcpy(*data, d, tc);
+
+       free(d);
+
+       return tc;
+}
+
+int dream_sapphire_dummy(void *sdata)
+{
+       return 0;
+}
+
+struct ril_device_power_handlers dream_sapphire_power_handlers = {
+       .sdata = NULL,
+       .sdata_create = dream_sapphire_dummy,
+       .sdata_destroy = dream_sapphire_dummy,
+       .power_on = dream_sapphire_dummy,
+       .power_off = dream_sapphire_dummy,
+       .suspend = dream_sapphire_dummy,
+       .resume = dream_sapphire_dummy,
+       .boot = dream_sapphire_boot,
+};
+
+struct ril_device_transport_handlers dream_sapphire_transport_handlers = {
+       .sdata = NULL,
+       .sdata_create = dream_sapphire_transport_sdata_create,
+       .sdata_destroy = dream_sapphire_transport_sdata_destroy,
+       .open = dream_sapphire_transport_open,
+       .close = dream_sapphire_transport_close,
+       .send = dream_sapphire_transport_send,
+       .recv = dream_sapphire_transport_recv,
+};
+
+struct ril_device_handlers dream_sapphire_handlers = {
+       .power = &dream_sapphire_power_handlers,
+       .transport = &dream_sapphire_transport_handlers,
+};
+
 struct ril_device dream_sapphire_device = {
        .name = "HTC Dream/HTC Magic",
        .type = DEV_GSM,
+       .sdata = NULL,
+       .handlers = &dream_sapphire_handlers,
 };
 
 void ril_device_register(struct ril_device **ril_device_p)
diff --git a/device/dream_sapphire/dream_sapphire.h b/device/dream_sapphire/dream_sapphire.h
new file mode 100644 (file)
index 0000000..a15db1d
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * This file is part of hayes-ril.
+ *
+ * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hayes-ril.h>
+
+#ifndef _HAYES_RIL_DREAM_SAPPHIRE_H
+#define _HAYES_RIL_DREAM_SAPPHIRE_H
+
+#define READ_MAX_DATA_LEN      0x1000
+#define SMD_DEV                        "/dev/smd0"
+
+struct dream_sapphire_transport_data {
+       int fd;
+       // send/recv mutex
+};
+
+#endif
index 0ec85f6..1113220 100644 (file)
@@ -30,7 +30,7 @@
 
 struct ril_device *ril_device;
 
-const char *getVersion(void)
+const char *ril_get_version(void)
 {
        return RIL_VERSION_STRING;
 }
@@ -42,10 +42,9 @@ static const RIL_RadioFunctions ril_ops = {
        NULL,
        NULL,
        NULL,
-       getVersion
+       ril_get_version
 };
 
-
 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
 {
        int rc;
index e410476..55120cb 100644 (file)
@@ -34,31 +34,31 @@ enum ril_device_type {
 };
 
 struct ril_device_power_handlers {
-       void *data;
-       int (*data_create)(void **data);
-       int (*data_destroy)(void *data);
+       void *sdata;
+       int (*sdata_create)(void **sdata);
+       int (*sdata_destroy)(void *sdata);
 
-       int (*power_on)(void *data);
-       int (*power_off)(void *data);
+       int (*power_on)(void *sdata);
+       int (*power_off)(void *sdata);
 
-       int (*suspend)(void *data);
-       int (*resume)(void *data);
+       int (*suspend)(void *sdata);
+       int (*resume)(void *sdata);
 
-       int (*boot)(void *data);
+       int (*boot)(void *sdata);
 };
 
 struct ril_device_transport_handlers {
-       void *data;
-       int (*data_create)(void **data);
-       int (*data_destroy)(void *data);
+       void *sdata;
+       int (*sdata_create)(void **sdata);
+       int (*sdata_destroy)(void *sdata);
 
-       int (*open)(void *data);
-       int (*close)(void *data);
+       int (*open)(void *sdata);
+       int (*close)(void *sdata);
 
-       int (*send)(void *data);
-       int (*recv)(void *data);
+       int (*send)(void *sdata, void **data, int length);
+       int (*recv)(void *sdata, void **data, int length);
 
-       int (*poll)(void *data);
+       int (*poll)(void *sdata);
 };
 
 struct ril_device_handlers {
@@ -68,7 +68,7 @@ struct ril_device_handlers {
 
 struct ril_device {
        char *name;
-       void *data;
+       void *sdata;
 
        enum ril_device_type type;
        struct ril_device_handlers *handlers;
@@ -76,10 +76,11 @@ struct ril_device {
 
 // Device
 void ril_device_register(struct ril_device **ril_device_p);
-int ril_device_data_create(struct ril_device*ril_device_p);
-int ril_device_boot(struct ril_device*ril_device_p);
+int ril_device_data_create(struct ril_device *ril_device_p);
+int ril_device_boot(struct ril_device *ril_device_p);
 int ril_device_power_on(struct ril_device *ril_device_p);
 int ril_device_power_off(struct ril_device *ril_device_p);
 int ril_device_open(struct ril_device *ril_device_p);
-
+int ril_device_send(struct ril_device *ril_device_p, void *data, int length);
+int ril_device_recv(struct ril_device *ril_device_p, void **data, int length);
 #endif