6c11270c2d33fbaead5b0c79ca13b61cdacbc25d
[apps/native/blind-motor.git] / src / capability / capability_doorcontrol.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 <stdio.h>
18 #include <stdbool.h>
19 #include "st_things.h"
20 #include "log.h"
21 #include <app_common.h>
22 #include "resource/resource_servo_motor.h"
23
24 static const char *PROP_DOORSTATE = "doorState";
25 static const char *RES_CAPABILITY_DOORCONTROL_MAIN_0 = "/capability/doorControl/main/0";
26
27 #define VALUE_STR_LEN_MAX 32
28 #define AUTO_CLOSE_LUX_VALUE    40
29 #define AUTO_OPEN_LUX_VALUE             500
30 #define MAX_PATH_LEN    1024
31
32 static const char *VALUE_DOOR_STATE_OPENED = "opened";
33 static const char *VALUE_DOOR_STATE_OPENING = "opening";
34 static const char *VALUE_DOOR_STATE_CLOSING = "closing";
35 static const char *VALUE_DOOR_STATE_CLOSED = "closed";
36
37 static char g_door_state[VALUE_STR_LEN_MAX] = "closed";
38
39 char *door_state_file_name="door_state";
40
41 extern bool get_auto_operation_status(void);
42 extern void set_auto_operation_status(bool status);
43
44 extern peripheral_error_e resource_motor_driving(door_state_e mode);
45
46 bool get_door_state(char *door_state)
47 {
48         FILE * fd;
49         char file_name_path[MAX_PATH_LEN];
50         char *app_data_path = NULL;
51
52         app_data_path = app_get_data_path();
53         sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
54
55         if((fd = fopen(file_name_path, "r")) == NULL) {
56                 ERR("ERROR: can't fopen file: %s", file_name_path);
57                 free(app_data_path);
58                 return false;
59         }
60         if (fgets(door_state, 8, fd) == NULL) {
61                 ERR("fgets read string error");
62                 free(app_data_path);
63                 fclose(fd);
64                 return false;
65         }
66         INFO("door_state : %s", door_state);
67
68         fclose(fd);
69         free(app_data_path);
70
71         return true;
72 }
73
74 bool set_door_state(const char *door_state)
75 {
76         FILE *fp;
77         char buffer[16];
78         char file_name_path[MAX_PATH_LEN];
79         char *app_data_path = NULL;
80         int num;
81
82         app_data_path = app_get_data_path();
83         sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
84
85         if((fp = fopen(file_name_path, "w+")) == NULL) {
86                 ERR("ERROR: can't fopen file: %s", file_name_path);
87                 strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
88                 free(app_data_path);
89                 return false;
90         }
91         memset(buffer, 0, sizeof(buffer));
92         sprintf(buffer, "%s", door_state);
93         if ((num = fputs(buffer, fp)) == EOF) {
94                 ERR("ERROR: fputs failed");
95                 strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
96                 free(app_data_path);
97                 fclose(fp);
98                 return false;
99         }
100         fclose(fp);
101
102         strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
103         free(app_data_path);
104         return true;
105 }
106
107
108 void set_auto_motor_driving(uint16_t sensor_value)
109 {
110         bool auto_status = get_auto_operation_status();
111
112         if (auto_status == false)
113                 return;
114
115         if (sensor_value <= AUTO_CLOSE_LUX_VALUE) {
116                 if (0 != strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING))) {
117                         resource_motor_driving(DOOR_STATE_CLOSING);
118                         set_door_state(VALUE_DOOR_STATE_CLOSING);
119                         strncpy(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING));
120                 }
121         }
122         else if (sensor_value > AUTO_OPEN_LUX_VALUE) {
123                 if (0 != strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) {
124                         resource_motor_driving(DOOR_STATE_OPENING);
125                         set_door_state(VALUE_DOOR_STATE_OPENING);
126                         strncpy(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING));
127                 }
128         }
129         else {
130                 ERR("invalid sensor_value [%d]", sensor_value);
131                 return;
132         }
133
134         // notify door state to cloud
135         st_things_notify_observers(RES_CAPABILITY_DOORCONTROL_MAIN_0);
136 }
137
138 bool handle_get_request_on_resource_capability_doorcontrol(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
139 {
140         //DBG("Received a GET request on %s\n", req_msg->resource_uri);
141
142         if (req_msg->has_property_key(req_msg, PROP_DOORSTATE)) {
143                 if (get_door_state(g_door_state) != true) {
144                         set_door_state(VALUE_DOOR_STATE_CLOSED);
145                 }
146
147                 /* check door state */
148                 if ((0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED))) ||
149                         (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED)))) {
150                         INFO("g_door_state(%s) : Auto Operation OFF!!", g_door_state);
151                         set_auto_operation_status(false);
152                 } else if ((0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) ||
153                                         (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING)))) {
154                         INFO("g_door_state(%s) : Auto Operation ON!!", g_door_state);
155                         set_auto_operation_status(true);
156                 }
157
158                 resp_rep->set_str_value(resp_rep, PROP_DOORSTATE, g_door_state);
159         }
160         return true;
161 }
162
163 bool handle_set_request_on_resource_capability_doorcontrol(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
164 {
165         DBG("Received a SET request on %s\n", req_msg->resource_uri);
166
167         door_state_e state = DOOR_STATE_UNKNOWN;
168
169         char *str_value = NULL;
170         req_msg->rep->get_str_value(req_msg->rep, PROP_DOORSTATE, &str_value);
171
172         /* check validation */
173         if ((0 != strncmp(str_value, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED)))
174                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING)))
175                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING)))
176                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED)))) {
177                 ERR("Not supported value!! str_value : %s", str_value);
178                 free(str_value);
179                 return false;
180         }
181
182         if (0 != strncmp(str_value, g_door_state, strlen(g_door_state))) {
183                 strncpy(g_door_state, str_value, VALUE_STR_LEN_MAX);
184                 free(str_value);
185
186                 set_door_state(g_door_state);
187
188                 if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED))) {
189                         INFO("Door Opened");
190                         set_auto_operation_status(false);
191                         state = DOOR_STATE_OPENED;
192                 }
193                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) {
194                         INFO("Door Opening - AUTO");
195                         set_auto_operation_status(true);
196                         state = DOOR_STATE_UNKNOWN;
197                 }
198                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING))) {
199                         INFO("Door Closing - AUTO");
200                         set_auto_operation_status(true);
201                         state = DOOR_STATE_UNKNOWN;
202                 }
203                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED))) {
204                         INFO("Door Closed");
205                         set_auto_operation_status(false);
206                         state = DOOR_STATE_CLOSE;
207                 }
208                 else {
209                         INFO("Door state Unknown");
210                         state = DOOR_STATE_UNKNOWN;
211                 }
212
213                 if (state != DOOR_STATE_UNKNOWN) {
214                         if (resource_motor_driving(state) != PERIPHERAL_ERROR_NONE)
215                                 return false;
216                 }
217         }
218         resp_rep->set_str_value(resp_rep, PROP_DOORSTATE, g_door_state);
219
220         st_things_notify_observers(req_msg->resource_uri);
221
222         return true;
223 }