100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* //device/libs/telephony/ril_event.cpp 200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** 300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Copyright 2008, The Android Open Source Project 400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** 5510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** Licensed under the Apache License, Version 2.0 (the "License"); 6510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** you may not use this file except in compliance with the License. 7510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** You may obtain a copy of the License at 800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** 9510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** http://www.apache.org/licenses/LICENSE-2.0 1000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** 11510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** Unless required by applicable law or agreed to in writing, software 12510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** distributed under the License is distributed on an "AS IS" BASIS, 13510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville** See the License for the specific language governing permissions and 1500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** limitations under the License. 1600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project*/ 1700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 1800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LOG_TAG "RILC" 1900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 2000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdlib.h> 2100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <unistd.h> 2200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <errno.h> 2300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <fcntl.h> 2400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <utils/Log.h> 2500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <ril_event.h> 2600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <string.h> 2700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/time.h> 2800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <time.h> 2900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 3000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <pthread.h> 3100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic pthread_mutex_t listMutex; 3200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex) 3300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex) 3400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL) 3500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex) 3600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 3700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifndef timeradd 3800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define timeradd(tvp, uvp, vvp) \ 3900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project do { \ 4000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 4100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 4200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if ((vvp)->tv_usec >= 1000000) { \ 4300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (vvp)->tv_sec++; \ 4400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (vvp)->tv_usec -= 1000000; \ 4500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } \ 4600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } while (0) 4700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif 4800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 4900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifndef timercmp 5000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define timercmp(a, b, op) \ 5100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ((a)->tv_sec == (b)->tv_sec \ 5200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ? (a)->tv_usec op (b)->tv_usec \ 5300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project : (a)->tv_sec op (b)->tv_sec) 5400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif 5500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 5600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifndef timersub 5700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define timersub(a, b, res) \ 5800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project do { \ 5900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 6000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ 6100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if ((res)->tv_usec < 0) { \ 6200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (res)->tv_usec += 1000000; \ 6300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (res)->tv_sec -= 1; \ 6400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } \ 6500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } while(0); 6600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif 6700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 6800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic fd_set readFds; 6900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int nfds = 0; 7000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 7100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic struct ril_event * watch_table[MAX_FD_EVENTS]; 7200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic struct ril_event timer_list; 7300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic struct ril_event pending_list; 7400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 7500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define DEBUG 0 7600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 7700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#if DEBUG 784dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville#define dlog(x...) RLOGD( x ) 7900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void dump_event(struct ril_event * ev) 8000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 8100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ Event %x ~~~~", (unsigned int)ev); 8200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" next = %x", (unsigned int)ev->next); 8300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" prev = %x", (unsigned int)ev->prev); 8400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" fd = %d", ev->fd); 8500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" pers = %d", ev->persist); 8600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec); 8700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" func = %x", (unsigned int)ev->func); 8800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog(" param = %x", (unsigned int)ev->param); 8900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~~~~~~~~~~~~~~~"); 9000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 9100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else 92510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#define dlog(x...) do {} while(0) 93510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#define dump_event(x) do {} while(0) 9400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif 9500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 9600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void getNow(struct timeval * tv) 9700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 9800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS 9900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timespec ts; 10000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project clock_gettime(CLOCK_MONOTONIC, &ts); 10100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project tv->tv_sec = ts.tv_sec; 10200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project tv->tv_usec = ts.tv_nsec/1000; 10300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else 10400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project gettimeofday(tv, NULL); 10500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif 10600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 10700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 10800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void init_list(struct ril_event * list) 10900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 11000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project memset(list, 0, sizeof(struct ril_event)); 11100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list->next = list; 11200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list->prev = list; 11300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list->fd = -1; 11400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 11500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 11600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void addToList(struct ril_event * ev, struct ril_event * list) 11700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 11800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->next = list; 11900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->prev = list->prev; 12000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->prev->next = ev; 12100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list->prev = ev; 12200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dump_event(ev); 12300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 12400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 12500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void removeFromList(struct ril_event * ev) 12600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 12700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ Removing event ~~~~"); 12800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dump_event(ev); 12900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 13000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->next->prev = ev->prev; 13100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->prev->next = ev->next; 13200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->next = NULL; 13300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->prev = NULL; 13400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 13500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 13600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 13700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void removeWatch(struct ril_event * ev, int index) 13800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 13900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project watch_table[index] = NULL; 14000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->index = -1; 14100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 14200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project FD_CLR(ev->fd, &readFds); 14300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 14400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (ev->fd+1 == nfds) { 14500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project int n = 0; 14600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 14700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project for (int i = 0; i < MAX_FD_EVENTS; i++) { 14800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * rev = watch_table[i]; 14900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 15000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if ((rev != NULL) && (rev->fd > n)) { 15100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project n = rev->fd; 15200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 15300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 154510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville nfds = n + 1; 15500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ nfds = %d ~~~~", nfds); 15600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 15700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 15800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 15900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void processTimeouts() 16000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 16100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ +processTimeouts ~~~~"); 16200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_ACQUIRE(); 16300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timeval now; 16400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * tev = timer_list.next; 16500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * next; 16600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 16700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project getNow(&now); 16800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // walk list, see if now >= ev->timeout for any events 16900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 17000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); 17100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) { 17200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // Timer expired 17300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ firing timer ~~~~"); 17400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project next = tev->next; 17500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project removeFromList(tev); 17600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project addToList(tev, &pending_list); 17700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project tev = next; 17800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 17900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_RELEASE(); 18000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -processTimeouts ~~~~"); 18100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 18200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 18300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void processReadReadies(fd_set * rfds, int n) 18400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 18500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ +processReadReadies (%d) ~~~~", n); 18600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_ACQUIRE(); 18700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 18800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) { 18900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * rev = watch_table[i]; 19000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (rev != NULL && FD_ISSET(rev->fd, rfds)) { 19100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project addToList(rev, &pending_list); 19200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (rev->persist == false) { 19300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project removeWatch(rev, i); 19400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 19500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project n--; 19600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 19700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 19800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 19900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_RELEASE(); 20000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -processReadReadies (%d) ~~~~", n); 20100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 20200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 20300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void firePending() 20400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 20500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ +firePending ~~~~"); 20600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * ev = pending_list.next; 20700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project while (ev != &pending_list) { 20800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * next = ev->next; 20900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project removeFromList(ev); 210510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville ev->func(ev->fd, 0, ev->param); 21100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev = next; 21200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 21300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -firePending ~~~~"); 21400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 21500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 21600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int calcNextTimeout(struct timeval * tv) 21700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 21800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * tev = timer_list.next; 21900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timeval now; 22000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 22100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project getNow(&now); 22200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 22300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // Sorted list, so calc based on first node 22400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (tev == &timer_list) { 22500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // no pending timers 22600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project return -1; 22700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 22800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 22900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); 23000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ next = %ds + %dus ~~~~", 23100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec); 23200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (timercmp(&tev->timeout, &now, >)) { 23300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project timersub(&tev->timeout, &now, tv); 23400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } else { 23500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // timer already expired. 23600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project tv->tv_sec = tv->tv_usec = 0; 23700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 23800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project return 0; 23900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 24000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 24100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Initialize internal data structs 24200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_event_init() 24300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 24400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_INIT(); 24500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 24600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project FD_ZERO(&readFds); 24700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project init_list(&timer_list); 24800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project init_list(&pending_list); 24900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project memset(watch_table, 0, sizeof(watch_table)); 25000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 25100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 25200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Initialize an event 25300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param) 25400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 25500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev); 25600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project memset(ev, 0, sizeof(struct ril_event)); 25700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->fd = fd; 25800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->index = -1; 25900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->persist = persist; 26000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->func = func; 26100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->param = param; 26200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project fcntl(fd, F_SETFL, O_NONBLOCK); 26300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 26400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 26500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Add event to watch list 26600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_event_add(struct ril_event * ev) 26700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 26800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ +ril_event_add ~~~~"); 26900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_ACQUIRE(); 27000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project for (int i = 0; i < MAX_FD_EVENTS; i++) { 27100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (watch_table[i] == NULL) { 27200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project watch_table[i] = ev; 27300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->index = i; 27400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ added at %d ~~~~", i); 27500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dump_event(ev); 27600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project FD_SET(ev->fd, &readFds); 27700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (ev->fd >= nfds) nfds = ev->fd+1; 27800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ nfds = %d ~~~~", nfds); 27900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project break; 280510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville } 28100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 28200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_RELEASE(); 28300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -ril_event_add ~~~~"); 28400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 28500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 28600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Add timer event 28700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_timer_add(struct ril_event * ev, struct timeval * tv) 28800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 28900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ +ril_timer_add ~~~~"); 29000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_ACQUIRE(); 29100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 29200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct ril_event * list; 29300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (tv != NULL) { 29400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // add to timer list 29500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list = timer_list.next; 29600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ev->fd = -1; // make sure fd is invalid 29700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 29800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timeval now; 29900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project getNow(&now); 30000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project timeradd(&now, tv, &ev->timeout); 30100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 30200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // keep list sorted 30300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project while (timercmp(&list->timeout, &ev->timeout, < ) 30400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project && (list != &timer_list)) { 30500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project list = list->next; 30600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 30700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // list now points to the first event older than ev 30800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project addToList(ev, list); 309510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville } 31000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 31100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_RELEASE(); 31200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -ril_timer_add ~~~~"); 31300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 31400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 31500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Remove event from watch or timer list 31600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_event_del(struct ril_event * ev) 31700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 3182932f31296822b86ed945e09cadaabf2a453843cWink Saville dlog("~~~~ +ril_event_del ~~~~"); 31900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_ACQUIRE(); 32000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 32100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) { 32211b35e613debbc9bcc162111d104e4c9f90fdbb8Axel Lin MUTEX_RELEASE(); 32300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project return; 32400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 32500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 32600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project removeWatch(ev, ev->index); 32700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 32800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project MUTEX_RELEASE(); 32900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ -ril_event_del ~~~~"); 33000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 33100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 332510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#if DEBUG 333510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Savillestatic void printReadies(fd_set * rfds) 334510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville{ 335510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville for (int i = 0; (i < MAX_FD_EVENTS); i++) { 336510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville struct ril_event * rev = watch_table[i]; 337510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville if (rev != NULL && FD_ISSET(rev->fd, rfds)) { 338510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville dlog("DON: fd=%d is ready", rev->fd); 339510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville } 340510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville } 341510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville} 342510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#else 343510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#define printReadies(rfds) do {} while(0) 344510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville#endif 345510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville 34600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectvoid ril_event_loop() 34700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{ 34800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project int n; 34900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project fd_set rfds; 35000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timeval tv; 35100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project struct timeval * ptv; 35200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 35300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 35400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project for (;;) { 35500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 35600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // make local copy of read fd_set 35700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project memcpy(&rfds, &readFds, sizeof(fd_set)); 35800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (-1 == calcNextTimeout(&tv)) { 35900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // no pending timers; block indefinitely 36000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ no timers; blocking indefinitely ~~~~"); 36100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ptv = NULL; 36200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } else { 36300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec); 36400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project ptv = &tv; 36500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 366510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville printReadies(&rfds); 36700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project n = select(nfds, &rfds, NULL, NULL, ptv); 368510a9bc7e2444cdb2b6a923ca3c4d0b45eebc400Wink Saville printReadies(&rfds); 36900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project dlog("~~~~ %d events fired ~~~~", n); 37000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (n < 0) { 37100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project if (errno == EINTR) continue; 37200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 3734dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville RLOGE("ril_event: select error (%d)", errno); 37400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // bail? 37500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project return; 37600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 37700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project 37800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // Check for timeouts 37900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project processTimeouts(); 38000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // Check for read-ready 38100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project processReadReadies(&rfds, n); 38200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project // Fire away 38300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project firePending(); 38400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project } 38500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project} 386