* limitations under the License.
*/
+#include <pthread.h>
+
#define LOG_TAG "RIL-DEV"
#include <utils/Log.h>
#include <hayes-ril.h>
-// Create shared data for all the handlers
+int ril_device_init(struct ril_device *ril_device_p)
+{
+ int rc;
+
+ rc = ril_device_data_create(ril_device_p);
+ if(rc < 0) {
+ LOGE("Failed to create device data!");
+ return -1;
+ }
+
+ rc = ril_device_power_on(ril_device_p);
+ if(rc < 0) {
+ LOGE("Failed to power on device!");
+ return -1;
+ }
+
+ rc = ril_device_boot(ril_device_p);
+ if(rc < 0) {
+ LOGE("Failed to boot device!");
+ return -1;
+ }
+
+ rc = ril_device_open(ril_device_p);
+ if(rc < 0) {
+ LOGE("Failed to open device!");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ril_device_deinit(struct ril_device *ril_device_p)
+{
+ ril_device_close(ril_device_p);
+
+ ril_device_power_off(ril_device_p);
+
+ ril_device_data_destroy(ril_device_p);
+
+ return 0;
+}
+
int ril_device_data_create(struct ril_device *ril_device_p)
{
int rc;
return -1;
}
- if(ril_device_p->handlers->power->sdata_create == NULL ||
- ril_device_p->handlers->power->sdata_destroy == NULL) {
+ if(ril_device_p->handlers->power->sdata_create == NULL) {
LOGE("Missing device power data handlers!");
return -1;
}
+ 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;
+ }
+
if(ril_device_p->handlers->transport == NULL) {
LOGE("Missing device transport handlers!");
return -1;
}
- if(ril_device_p->handlers->transport->sdata_create == NULL ||
- ril_device_p->handlers->transport->sdata_destroy == NULL) {
+ if(ril_device_p->handlers->transport->sdata_create == NULL) {
LOGE("Missing device transport data handlers!");
return -1;
}
- // iface
+ 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;
+ }
+
+ LOGD("Creating mutex for transport handlers...");
+ pthread_mutex_init(&(ril_device_p->handlers->transport->mutex), NULL);
- LOGD("Creating data for power handlers...");
- rc = ril_device_p->handlers->power->sdata_create(&ril_device_p->handlers->power->sdata);
+ return 0;
+}
+
+int ril_device_data_destroy(struct ril_device *ril_device_p)
+{
+ int rc;
+
+ if(ril_device_p->handlers == NULL) {
+ LOGE("Missing device handlers!");
+ return -1;
+ }
+
+ if(ril_device_p->handlers->power == NULL) {
+ LOGE("Missing device power handlers!");
+ return -1;
+ }
+
+ if(ril_device_p->handlers->power->sdata_destroy == NULL) {
+ LOGE("Missing device power data handlers!");
+ return -1;
+ }
+
+ LOGD("Destroying data for power handlers...");
+ rc = ril_device_p->handlers->power->sdata_destroy(&ril_device_p->handlers->power->sdata);
if(rc < 0) {
- LOGE("Creating data for power handlers failed!");
+ LOGE("Destroying data for power handlers failed!");
return -1;
}
- LOGD("Creating data for transport handlers...");
- ril_device_p->handlers->transport->sdata_create(&ril_device_p->handlers->transport->sdata);
+ if(ril_device_p->handlers->transport == NULL) {
+ LOGE("Missing device transport handlers!");
+ return -1;
+ }
+
+ if(ril_device_p->handlers->transport->sdata_destroy == NULL) {
+ LOGE("Missing device transport data handlers!");
+ return -1;
+ }
+
+ LOGD("Destroying data for transport handlers...");
+ ril_device_p->handlers->transport->sdata_destroy(&ril_device_p->handlers->transport->sdata);
if(rc < 0) {
- LOGE("Creating data for transport handlers failed!");
+ LOGE("Destroying data for transport handlers failed!");
return -1;
}
+ LOGD("Destroying mutex for transport handlers...");
+ pthread_mutex_destroy(&(ril_device_p->handlers->transport->mutex));
+
return 0;
}
return rc;
}
+int ril_device_close(struct ril_device *ril_device_p)
+{
+ 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->close == NULL) {
+ LOGE("Missing device transport close handler!");
+ return -1;
+ }
+
+ LOGD("Closing modem...");
+
+ rc = ril_device_p->handlers->transport->close(ril_device_p->handlers->transport->sdata);
+ return rc;
+}
+
int ril_device_send(struct ril_device *ril_device_p, void *data, int length)
{
int rc;
return -1;
}
+ RIL_DEVICE_LOCK(ril_device_p);
rc = ril_device_p->handlers->transport->send(ril_device_p->handlers->transport->sdata, data, length);
+ RIL_DEVICE_UNLOCK(ril_device_p);
+
return rc;
}
return -1;
}
+ RIL_DEVICE_LOCK(ril_device_p);
rc = ril_device_p->handlers->transport->recv(ril_device_p->handlers->transport->sdata, data, length);
+ RIL_DEVICE_UNLOCK(ril_device_p);
+
+ return rc;
+}
+
+int ril_device_recv_poll(struct ril_device *ril_device_p)
+{
+ 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_poll == NULL) {
+ LOGE("Missing device transport recv poll handler!");
+ return -1;
+ }
+
+ rc = ril_device_p->handlers->transport->recv_poll(ril_device_p->handlers->transport->sdata);
return rc;
}
+
+int ril_device_recv_loop(struct ril_device *ril_device_p)
+{
+ // TODO: AT message structure
+ char *data;
+ int count;
+ int rc;
+ int i;
+
+ // Return error after 5 consecutive poll/read failures
+ for(i=5 ; i > 0 ; i--) {
+ while(1) {
+ rc = ril_device_recv_poll(ril_device_p);
+ if(rc < 0) {
+ LOGE("Polling from transport recv failed!");
+ break;
+ }
+
+ count = rc;
+
+ rc = ril_device_recv(ril_device_p, &data, count);
+ if(rc < 0) {
+ LOGE("Reading from transport recv failed!");
+ break;
+ }
+ if(rc == 0) LOGE("WERE GOING MAD!!! READING 0 BYTES!!!"); //FIXME
+
+ // Read works now
+ if(i != 5)
+ i = 5;
+
+ LOGD("GOT: '%s'", data);
+
+ //TODO: Convert AT string to AT structures
+ free(data);
+
+ //TODO: Dispatch AT structures with multi-message handling (dispatch each)
+ //TODO: Free AT structures
+ }
+
+ // When poll/read failed, close and reopen the device
+ ril_device_close(ril_device_p);
+ usleep(500);
+ ril_device_open(ril_device_p);
+
+ RIL_DEVICE_UNLOCK(ril_device_p);
+ }
+
+ return -1;
+}
+
+void *ril_device_recv_thread(void *data)
+{
+ struct ril_device *ril_device_p = (struct ril_device *) data;
+ int rc;
+ int i;
+
+ for(i = 5 ; i > 0 ; i--) {
+ rc = ril_device_recv_loop(ril_device_p);
+ if(rc < 0) {
+ LOGE("Recv loop failed too many times, restarting...");
+
+ rc = ril_device_deinit(ril_device_p);
+ if(rc < 0)
+ break;
+
+ usleep(500);
+
+ rc = ril_device_init(ril_device_p);
+ if(rc < 0)
+ break;
+ }
+ }
+
+ LOGE("Recv thread failed too many times, stopping it all...");
+ ril_device_deinit(ril_device_p);
+
+ return NULL;
+}
+
+int ril_device_recv_thread_start(struct ril_device *ril_device_p)
+{
+ pthread_attr_t attr;
+ 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;
+ }
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ rc = pthread_create(&(ril_device_p->handlers->transport->recv_thread), &attr, ril_device_recv_thread, (void *) ril_device_p);
+ if(rc != 0) {
+ LOGE("Creating transport recv thread failed!");
+ return -1;
+ }
+
+ return 0;
+}