0894a8743e41a2ca10d4d9d4610622e6d8c80ee5
[apps/native/gear-racing-car.git] / src / lap_counter / lap_counter.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "lap_counter/lap_counter.h"
18 #include <log.h>
19 #include <string.h>
20 #include <stdio.h>
21 #include <limits.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #include "cloud/cloud_communication.h"
25
26 #define MIN_LAP_TIME 5
27 #define MAX_NAME_LENGTH 256
28
29 typedef struct lap_counter_data {
30         char *user_name;
31         struct timespec last_timestamp;
32 } lap_counter_data_t;
33
34 static lap_counter_data_t s_info = {0, };
35
36 void lap_counter_init()
37 {
38         char buf[MAX_NAME_LENGTH];
39         snprintf(buf, MAX_NAME_LENGTH, "Default: %s %s", __DATE__, __TIME__); //
40
41         s_info.user_name = strdup(buf);
42 }
43
44 void lap_counter_set_user_name(const char *user_name)
45 {
46         retm_if(!user_name, "New user name is NULL");
47
48         free((void*)s_info.user_name);
49         s_info.user_name = strdup(user_name);
50
51         _D("User name set to %s", s_info.user_name);
52 }
53
54 const char *lap_counter_get_user_name(void)
55 {
56         return s_info.user_name;
57 }
58
59 void _print_time(const char *title, struct timespec *ts)
60 {
61         char buf[PATH_MAX];
62         struct tm *_tm = localtime(&(ts->tv_sec));
63         strftime(&buf[0], PATH_MAX, "%H:%M:%S", _tm);
64
65         snprintf(&buf[strlen(buf)], PATH_MAX, ".%03ld", ts->tv_nsec / (long)1e6);
66
67         _D ("%s %s", title, buf);
68 }
69
70 static inline struct timespec _calculate_lap_time(struct timespec *prev, struct timespec *now)
71 {
72         struct timespec lap;
73
74         lap.tv_sec = now->tv_sec - prev->tv_sec;
75         lap.tv_nsec = now->tv_nsec - prev->tv_nsec;
76
77
78         _D("----------------------------------------------");
79         _print_time("PREV:\t", prev);
80         _print_time("NOW:\t", now);
81
82         if (lap.tv_sec < MIN_LAP_TIME) {
83                 lap.tv_sec = 0;
84                 lap.tv_nsec = 0;
85                 _D ("TOO SHORT LAP");
86                 return lap;
87         }
88
89
90         _print_time("LAP:\t", &lap);
91
92         if (lap.tv_nsec < 0) {
93                 lap.tv_sec--;
94                 lap.tv_nsec = 1e9 + lap.tv_nsec;
95
96                 _print_time("LAP_MOD:\t", &lap);
97         }
98         _D("----------------------------------------------");
99
100         cloud_communication_post_lap(lap.tv_sec * 1e3 + lap.tv_nsec / 1e6, s_info.user_name);
101         return lap;
102 }
103
104 void lap_counter_get_lap_time()
105 {
106         struct timespec timestamp;
107         int ret = clock_gettime(CLOCK_MONOTONIC, &timestamp);
108         retv_error_message(ret != 0, ret);
109
110         if (s_info.last_timestamp.tv_nsec != 0 || s_info.last_timestamp.tv_sec != 0) {
111                 _calculate_lap_time(&s_info.last_timestamp, &timestamp);
112         } else {
113                 _D("Initial lap");
114         }
115
116         s_info.last_timestamp.tv_sec = timestamp.tv_sec;
117         s_info.last_timestamp.tv_nsec = timestamp.tv_nsec;
118 }
119
120 void lap_counter_shutdown()
121 {
122         free(s_info.user_name);
123 }