Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / plugins / src / plugininterface.c
1 //******************************************************************
2 //
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 /**
22  * @file
23  *
24  * This file contains APIs for Plugin Interface module to be implemented.
25  */
26
27 #include "plugininterface.h"
28 #include "plugintranslatortypes.h"
29 #include "pluginlist.h"
30 #include "zigbee_wrapper.h"
31 #include "oic_string.h"
32 #include "oic_malloc.h"
33 #include "ocstack.h"
34 #include "ocpayload.h"
35 #include "logger.h"
36
37 #include <string.h>
38 #include <stdlib.h>
39
40 #define TAG PCF("pluginInterface")
41
42 /**
43  * Entity handler callback that fills the resPayload of the entityHandlerRequest.
44  */
45 OCEntityHandlerResult PluginInterfaceEntityHandler(OCEntityHandlerFlag flag,
46                                                    OCEntityHandlerRequest * entityHandlerRequest,
47                                                    void* callbackParam)
48 {
49     if (!entityHandlerRequest)
50     {
51         OIC_LOG (ERROR, TAG, "Invalid request pointer");
52         return OC_EH_ERROR;
53     }
54
55     OCEntityHandlerResult ehResult = OC_EH_ERROR;
56     OCStackResult result = OC_STACK_ERROR;
57     PIPluginBase * plugin = (PIPluginBase *) callbackParam;
58
59     OCEntityHandlerResponse * response =
60                         (OCEntityHandlerResponse *) OICCalloc(1, sizeof(*response));
61
62     if (!response)
63     {
64         return OC_EH_ERROR;
65     }
66
67     OCRepPayload* payload = (OCRepPayload *) entityHandlerRequest->payload;
68
69     if (flag & OC_REQUEST_FLAG)
70     {
71         if (plugin->processEHRequest)
72         {
73             ehResult = plugin->processEHRequest(plugin, entityHandlerRequest, &payload);
74         }
75     }
76
77     // If the result isn't an error or forbidden, send response
78     if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
79     {
80         // Format the response.  Note this requires some info about the request
81         response->requestHandle = entityHandlerRequest->requestHandle;
82         response->resourceHandle = entityHandlerRequest->resource;
83         response->ehResult = ehResult;
84         response->payload = (OCPayload*) payload;
85         // Indicate that response is NOT in a persistent buffer
86         response->persistentBufferFlag = 0;
87
88         result = OCDoResponse(response);
89         if (result != OC_STACK_OK)
90         {
91             OIC_LOG_V(ERROR, TAG, "Error sending response %u", result);
92             ehResult = OC_EH_ERROR;
93         }
94     }
95     else
96     {
97         OIC_LOG_V(ERROR, TAG, "Error handling request %u", ehResult);
98         PIResource * piResource = NULL;
99         result = GetResourceFromHandle(plugin, &piResource, response->resourceHandle);
100         OIC_LOG_V(ERROR, TAG, "Deleting resource \"%s\" because of failed request.", piResource->uri);
101         result = DeleteResource(plugin, piResource);
102         if(result != OC_STACK_OK)
103         {
104             OIC_LOG_V(ERROR, TAG, "Failed to delete resource after failed request.");
105             ehResult = OC_EH_ERROR;
106         }
107     }
108
109     OCPayloadDestroy(response->payload);
110     OICFree(response);
111     return ehResult;
112 }
113
114 void piNewResourceCB(PIPluginBase * p_plugin, PIResourceBase * r_newResource)
115 {
116     if (!p_plugin || !r_newResource)
117     {
118         return;
119     }
120
121     r_newResource->piResource.resourceProperties = OC_DISCOVERABLE | OC_OBSERVABLE;
122     OCStackResult result = OCCreateResource(&r_newResource->piResource.resourceHandle,
123                                             r_newResource->piResource.resourceTypeName,
124                                             r_newResource->piResource.resourceInterfaceName,
125                                             r_newResource->piResource.uri,
126                                             PluginInterfaceEntityHandler,
127                                             (void *) p_plugin,
128                                             r_newResource->piResource.resourceProperties);
129     if (result != OC_STACK_OK)
130     {
131         OICFree (r_newResource->piResource.uri);
132         OICFree (r_newResource);
133         return;
134     }
135     OIC_LOG_V(INFO, TAG, "Created resource of type: %s\n",
136         r_newResource->piResource.resourceTypeName);
137
138     result = AddResourceToPlugin(p_plugin, r_newResource);
139 }
140
141 void piObserveNotificationUpdate(PIPluginBase * plugin, OCResourceHandle resourceHandle)
142 {
143     if(!plugin)
144     {
145         return;
146     }
147
148     OCStackResult result = OCNotifyAllObservers(resourceHandle, OC_LOW_QOS);
149     if(result != OC_STACK_OK && result != OC_STACK_NO_OBSERVERS)
150     {
151         OIC_LOG_V(ERROR, TAG, "Failed to notify observers of update. Result: %d", result);
152     }
153 }
154
155 OCStackResult PIStartPlugin(const char * comPort, PIPluginType pluginType, PIPlugin ** plugin)
156 {
157     if (!plugin || !comPort || strlen(comPort) == 0)
158     {
159         return OC_STACK_INVALID_PARAM;
160     }
161     OCStackResult result = OC_STACK_ERROR;
162     if (pluginType == PLUGIN_ZIGBEE)
163     {
164         result = ZigbeeInit(comPort,
165                             (PIPlugin_Zigbee **) plugin,
166                             piNewResourceCB,
167                             piObserveNotificationUpdate);
168         if (result != OC_STACK_OK)
169         {
170             return result;
171         }
172         if (!*plugin)
173         {
174             return OC_STACK_ERROR;
175         }
176         result = AddPlugin((PIPluginBase *)*plugin);
177         if(result != OC_STACK_OK)
178         {
179             return result;
180         }
181     }
182     return result;
183 }
184
185 OCStackResult PIStopPlugin(PIPlugin * plugin)
186 {
187     if (!plugin)
188     {
189         return OC_STACK_INVALID_PARAM;
190     }
191
192     return DeletePlugin((PIPluginBase *) plugin);
193 }
194
195 OCStackResult PIStopAll()
196 {
197     return DeletePluginList();
198 }
199
200 OCStackResult PISetup(PIPlugin * plugin)
201 {
202     if (!plugin)
203     {
204         return OC_STACK_INVALID_PARAM;
205     }
206     OCStackResult result = OC_STACK_ERROR;
207     if (((PIPluginBase *)plugin)->type == PLUGIN_ZIGBEE)
208     {
209         result = ZigbeeDiscover((PIPlugin_Zigbee *) plugin);
210         if( result != OC_STACK_OK)
211         {
212             return result;
213         }
214     }
215     return result;
216 }
217
218 OCStackResult PIProcess(PIPlugin * p_plugin)
219 {
220     PIPluginBase * plugin = (PIPluginBase *) p_plugin;
221     if (!plugin)
222     {
223         return OC_STACK_INVALID_PARAM;
224     }
225     OCStackResult result = OC_STACK_ERROR;
226     if (plugin->type == PLUGIN_ZIGBEE)
227     {
228         result = ZigbeeProcess((PIPlugin_Zigbee *)plugin);
229     }
230     return result;
231 }
232