Expose PISetup() API in Plugin Interface.
[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         OC_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             OC_LOG_V(ERROR, TAG, "Error sending response %u", result);
92             ehResult = OC_EH_ERROR;
93         }
94     }
95     else
96     {
97         OC_LOG_V(ERROR, TAG, "Error handling request %u", ehResult);
98         PIResource * piResource = NULL;
99         result = GetResourceFromHandle(plugin, &piResource, response->resourceHandle);
100         OC_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             OC_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     OC_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, const char * uri)
142 {
143     if(!plugin || !uri)
144     {
145         return;
146     }
147     PIResource * piResource = NULL;
148
149     OCStackResult result = GetResourceFromURI(plugin, &piResource, uri);
150     if(result != OC_STACK_OK)
151     {
152         OC_LOG(ERROR, TAG, "Failed to find a matching URI based on observe notification update.");
153         return;
154     }
155
156     result = OCNotifyAllObservers(piResource->resourceHandle, OC_LOW_QOS);
157     if(result != OC_STACK_OK && result != OC_STACK_NO_OBSERVERS)
158     {
159         OC_LOG_V(ERROR, TAG, "Failed to notify observers of update. Result: %d", result);
160     }
161 }
162
163 OCStackResult PIStartPlugin(const char * comPort, PIPluginType pluginType, PIPlugin ** plugin)
164 {
165     if (!plugin || !comPort || strlen(comPort) == 0)
166     {
167         return OC_STACK_INVALID_PARAM;
168     }
169     OCStackResult result = OC_STACK_ERROR;
170     if (pluginType == PLUGIN_ZIGBEE)
171     {
172         result = ZigbeeInit(comPort,
173                             (PIPlugin_Zigbee **) plugin,
174                             piNewResourceCB,
175                             piObserveNotificationUpdate);
176         if (result != OC_STACK_OK)
177         {
178             return result;
179         }
180         if (!*plugin)
181         {
182             return OC_STACK_ERROR;
183         }
184         result = AddPlugin((PIPluginBase *)*plugin);
185         if(result != OC_STACK_OK)
186         {
187             return result;
188         }
189     }
190     return result;
191 }
192
193 OCStackResult PIStopPlugin(PIPlugin * plugin)
194 {
195     if (!plugin)
196     {
197         return OC_STACK_INVALID_PARAM;
198     }
199
200     return DeletePlugin((PIPluginBase *) plugin);
201 }
202
203 OCStackResult PIStopAll()
204 {
205     return DeletePluginList();
206 }
207
208 OCStackResult PISetup(PIPlugin * plugin)
209 {
210     if (!plugin)
211     {
212         return OC_STACK_INVALID_PARAM;
213     }
214     OCStackResult result = OC_STACK_ERROR;
215     if (((PIPluginBase *)plugin)->type == PLUGIN_ZIGBEE)
216     {
217         result = ZigbeeDiscover((PIPlugin_Zigbee *) plugin);
218         if( result != OC_STACK_OK)
219         {
220             return result;
221         }
222     }
223     return result;
224 }
225
226 OCStackResult PIProcess(PIPlugin * p_plugin)
227 {
228     PIPluginBase * plugin = (PIPluginBase *) p_plugin;
229     if (!plugin)
230     {
231         return OC_STACK_INVALID_PARAM;
232     }
233     OCStackResult result = OC_STACK_ERROR;
234     if (plugin->type == PLUGIN_ZIGBEE)
235     {
236         result = ZigbeeProcess((PIPlugin_Zigbee *)plugin);
237     }
238     return result;
239 }
240