Sending lap time to cloud
[apps/native/gear-racing-car.git] / src / cloud / car_info.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 <stdlib.h>
18 #include <stdio.h>
19 #include <glib.h>
20 #include <string.h>
21 #include <regex.h>
22 #include <arpa/inet.h>
23 #include <ctype.h>
24 #include "cloud/car_info.h"
25 #include "log.h"
26
27 #define MAX_CAR_ID_LENGTH 256
28 #define MAX_LENGTH_IP 16
29 #define MAX_LENGTH_MAC 18
30 #define MAX_LENGTH_SSID 33
31
32 #define SAFE_STR_CPY(src, obj, size)\
33 do {\
34     if(obj)\
35         src = strndup(obj, size);\
36 } while(0)
37
38 static int validate_ip_address(const char *ip_address);
39 static int validate_mac_address(const char *mac_address);
40
41 struct car_info
42 {
43     char *id;
44     char *name;
45     char *ip;
46     char *ap_mac;
47     char *ap_ssid;
48 };
49
50 car_info_t *car_info_create()
51 {
52     struct car_info *car_info = g_new0(struct car_info, 1);
53     retvm_if(!car_info, NULL, "Could not allocate memory!");
54
55     return car_info;
56 }
57
58 car_info_t *car_info_copy(const car_info_t *car_info)
59 {
60     retv_if(!car_info, NULL);
61
62     struct car_info *car_info_cpy = g_new0(struct car_info, 1);
63     SAFE_STR_CPY(car_info_cpy->id, car_info->id, MAX_CAR_ID_LENGTH);
64     SAFE_STR_CPY(car_info_cpy->name, car_info->name, MAX_CAR_ID_LENGTH);
65     SAFE_STR_CPY(car_info_cpy->ip, car_info->ip, MAX_LENGTH_IP);
66     SAFE_STR_CPY(car_info_cpy->ap_mac, car_info->ap_mac, MAX_LENGTH_MAC);
67     SAFE_STR_CPY(car_info_cpy->ap_ssid, car_info->ap_ssid, MAX_LENGTH_SSID);
68
69     return car_info_cpy;
70 }
71
72 void car_info_destroy(car_info_t *car_info)
73 {
74     ret_if(!car_info);
75
76     free(car_info->id);
77     free(car_info->name);
78     free(car_info->ip);
79     free(car_info->ap_mac);
80     free(car_info->ap_ssid);
81
82     g_free(car_info);
83 }
84
85 bool car_info_is_valid(car_info_t *car_info)
86 {
87     return (car_info->id && car_info->ip && car_info->ap_mac && car_info->ap_ssid);
88 }
89
90 const char *car_info_get_car_id(car_info_t *car_info)
91 {
92     retv_if(!car_info, NULL);
93
94     return car_info->id;
95 }
96
97 int car_info_set_car_id(car_info_t *car_info, const char *car_id)
98 {
99     retv_if(!car_info, -1);
100     retv_if(car_id == NULL, -1);
101     retv_if(strlen(car_id) >= MAX_CAR_ID_LENGTH, -1);
102
103     if (!car_info->id)
104         car_info->id = (char *)g_malloc(MAX_CAR_ID_LENGTH * sizeof(char));
105
106     snprintf(car_info->id, MAX_CAR_ID_LENGTH, "%s", car_id);
107     return 0;
108 }
109
110 const char *car_info_get_car_name(car_info_t *car_info)
111 {
112     retv_if(!car_info, NULL);
113     return car_info->name;
114 }
115
116 int car_info_set_car_name(car_info_t *car_info, const char *car_name)
117 {
118     retv_if(!car_info, -1);
119     retv_if(car_name == NULL, -1);
120     retv_if(strlen(car_name) >= MAX_CAR_ID_LENGTH, -1);
121
122     if (!car_info->name)
123         car_info->name = (char *)g_malloc(MAX_CAR_ID_LENGTH * sizeof(char));
124
125     snprintf(car_info->name, MAX_CAR_ID_LENGTH, "%s", car_name);
126     return 0;
127 }
128
129 const char *car_info_get_car_ip(car_info_t *car_info)
130 {
131     retv_if(!car_info, NULL);
132     return car_info->ip;
133 }
134
135 int car_info_set_car_ip(car_info_t *car_info, const char *car_ip)
136 {
137     retv_if(!car_info, -1);
138     retv_if(car_ip == NULL, -1);
139     retv_if(strlen(car_ip) >= MAX_LENGTH_IP, -1);
140     retv_if(validate_ip_address(car_ip) != 0, -1);
141
142     if (!car_info->ip)
143         car_info->ip = (char *)g_malloc(MAX_LENGTH_IP * sizeof(char));
144
145     snprintf(car_info->ip, MAX_LENGTH_IP, "%s", car_ip);
146     return 0;
147 }
148
149 const char *car_info_get_ap_mac(car_info_t *car_info)
150 {
151     retv_if(!car_info, NULL);
152     return car_info->ap_mac ? car_info->ap_mac : "NULL";
153 }
154
155 int car_info_set_car_ap_mac(car_info_t *car_info, const char *ap_mac)
156 {
157     retv_if(!car_info, -1);
158     retv_if(ap_mac == NULL, -1);
159     retv_if(strlen(ap_mac) >= MAX_LENGTH_MAC, -1);
160     retv_if(validate_mac_address(ap_mac) != 0, -1);
161
162     if (!car_info->ap_mac)
163         car_info->ap_mac = (char *)g_malloc(MAX_LENGTH_MAC * sizeof(char));
164
165     snprintf(car_info->ap_mac, MAX_LENGTH_MAC, "%s", ap_mac);
166     return 0;
167 }
168
169 const char *car_info_get_ap_ssid(car_info_t *car_info)
170 {
171     retv_if(!car_info, NULL);
172     return car_info->ap_ssid;
173 }
174
175 int car_info_set_ap_ssid(car_info_t *car_info, const char *ap_ssid)
176 {
177     retv_if(!car_info, -1);
178     retv_if(ap_ssid == NULL, -1);
179     retv_if(strlen(ap_ssid) >= MAX_LENGTH_SSID, -1);
180
181     if (!car_info->ap_ssid)
182         car_info->ap_ssid = (char *)g_malloc(MAX_LENGTH_SSID * sizeof(char));
183
184     snprintf(car_info->ap_ssid, MAX_LENGTH_SSID, "%s", ap_ssid);
185     return 0;
186 }
187
188 static int validate_ip_address(const char *ip_address)
189 {
190     struct sockaddr_in sa;
191     int result = inet_pton(AF_INET, ip_address, &(sa.sin_addr));
192     return result == 1 ? 0 : -1;
193 }
194
195 static int validate_mac_address(const char *mac_address)
196 {
197     int i = 0;
198     int segments = 1;
199
200     while(*mac_address)
201     {
202         if (isxdigit(*mac_address))
203         {
204             i++;
205             if (i > 2) return -1;
206         }
207         else if (*mac_address == ':')
208         {
209             if (i != 2) return -1;
210             i = 0;
211             segments++;
212         }
213         else {
214             return -1;
215         }
216         mac_address++;
217     }
218
219     return (segments == 6 && i == 2) ? 0 : -1;
220 }