summaryrefslogtreecommitdiffstats
path: root/reference-ril/atchannel.c
diff options
context:
space:
mode:
authorJinhui Li <jinhui.li@intel.com>2016-03-24 08:55:10 +0800
committerbohu <bohu@google.com>2016-04-07 17:31:11 -0700
commit99f6a4e8fa12a6d54df5420aaa3eda29d9ba22a6 (patch)
tree2dc99745215baa31ddfce7d6056c73376da3a3ea /reference-ril/atchannel.c
parent1be49ba51de8b4c81132003d12b269f5d0237132 (diff)
downloadandroid_hardware_ril-99f6a4e8fa12a6d54df5420aaa3eda29d9ba22a6.tar.gz
android_hardware_ril-99f6a4e8fa12a6d54df5420aaa3eda29d9ba22a6.tar.bz2
android_hardware_ril-99f6a4e8fa12a6d54df5420aaa3eda29d9ba22a6.zip
reference-ril/atchannel.c: Fix time conversion
setTimespecRelative() converts a relative time to an absolute time, by adding the relative time to current system time. However, it fails to handle the case where the nanosecond component (tv_nsec) of the conversion result exceeds 10^9, which can cause a subsequent call to pthread_cond_timedwait() to return EINVAL. This bug is the root cause of the "no SIM card" error seen occasionally on x86_64 Android emulator. In fact, all 64-bit targets use setTimespecRelative() in conjunction with pthread_cond_timedwait() during AT handshake, but an EINVAL return value from the latter will lead to an infinite loop and hang the communication. With this fix, x86_64 emulator can boot with functional 3G networking every time. Signed-off-by: Jinhui Li <jinhui.li@intel.com> [Revised code and commit message] Signed-off-by: Yu Ning <yu.ning@intel.com> (cherry picked from commit 11476211584f1a82c870b9486ace8f6f8bb9fc7c) Change-Id: I5d7396ef7f0af5ef02ccab785046d635fb8f168c
Diffstat (limited to 'reference-ril/atchannel.c')
-rw-r--r--reference-ril/atchannel.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/reference-ril/atchannel.c b/reference-ril/atchannel.c
index f38545d..ac01cbc 100644
--- a/reference-ril/atchannel.c
+++ b/reference-ril/atchannel.c
@@ -86,6 +86,7 @@ static int writeCtrlZ (const char *s);
static int writeline (const char *s);
#ifndef USE_NP
+#define NS_PER_S 1000000000
static void setTimespecRelative(struct timespec *p_ts, long long msec)
{
struct timeval tv;
@@ -97,6 +98,11 @@ static void setTimespecRelative(struct timespec *p_ts, long long msec)
a relative time again */
p_ts->tv_sec = tv.tv_sec + (msec / 1000);
p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
+ /* assuming tv.tv_usec < 10^6 */
+ if (p_ts->tv_nsec >= NS_PER_S) {
+ p_ts->tv_sec++;
+ p_ts->tv_nsec -= NS_PER_S;
+ }
}
#endif /*USE_NP*/