Removed unneccessary code for stack
[platform/upstream/iotivity.git] / resource / csdk / stack / src / occlientcb.c
1 //******************************************************************
2 //
3 // Copyright 2014 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 #include "occlientcb.h"
23 #include "utlist.h"
24 #include "logger.h"
25 #include "oic_malloc.h"
26 #include <string.h>
27
28 #ifdef WITH_ARDUINO
29 #include "Time.h"
30 #else
31 #include <sys/time.h>
32 #endif
33 #include "coap_time.h"
34
35 #include "cacommon.h"
36 #include "cainterface.h"
37
38 /// Module Name
39 #define TAG "occlientcb"
40
41 struct ClientCB *cbList = NULL;
42 static OCMulticastNode * mcPresenceNodes = NULL;
43
44 OCStackResult
45 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
46              CAToken_t token, uint8_t tokenLength,
47              OCDoHandle *handle, OCMethod method,
48              OCDevAddr *devAddr, char * requestUri,
49              char * resourceTypeName, uint32_t ttl)
50 {
51     if (!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
52     {
53         return OC_STACK_INVALID_PARAM;
54     }
55
56     ClientCB *cbNode = NULL;
57
58 #ifdef WITH_PRESENCE
59     if (method == OC_REST_PRESENCE)
60     {   // Retrieve the presence callback structure for this specific requestUri.
61         cbNode = GetClientCB(NULL, 0, NULL, requestUri);
62     }
63
64     if (!cbNode)// If it does not already exist, create new node.
65 #endif // WITH_PRESENCE
66     {
67         cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
68         if (!cbNode)
69         {
70             *clientCB = NULL;
71             goto exit;
72         }
73         else
74         {
75             OC_LOG(INFO, TAG, "Adding client callback with token");
76             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
77             cbNode->callBack = cbData->cb;
78             cbNode->context = cbData->context;
79             cbNode->deleteCallback = cbData->cd;
80             //Note: token memory is allocated in the caller OCDoResource
81             //but freed in DeleteClientCB
82             cbNode->token = token;
83             cbNode->tokenLength = tokenLength;
84             cbNode->handle = *handle;
85             cbNode->method = method;
86             cbNode->sequenceNumber = 0;
87 #ifdef WITH_PRESENCE
88             cbNode->presence = NULL;
89             cbNode->filterResourceType = NULL;
90 #endif // WITH_PRESENCE
91
92             if (method == OC_REST_PRESENCE ||
93                 method == OC_REST_OBSERVE  ||
94                 method == OC_REST_OBSERVE_ALL)
95             {
96                 cbNode->TTL = 0;
97             }
98             else
99             {
100                 cbNode->TTL = ttl;
101             }
102             cbNode->requestUri = requestUri;    // I own it now
103             cbNode->devAddr = devAddr;          // I own it now
104             OC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
105             LL_APPEND(cbList, cbNode);
106             *clientCB = cbNode;
107         }
108     }
109 #ifdef WITH_PRESENCE
110     else
111     {
112         // Ensure that the handle the SDK hands back up to the application layer for the
113         // OCDoResource call matches the found ClientCB Node.
114         *clientCB = cbNode;
115
116         if (cbData->cd)
117         {
118             cbData->cd(cbData->context);
119         }
120
121         OICFree(token);
122         OICFree(*handle);
123         OICFree(requestUri);
124         OICFree(devAddr);
125         *handle = cbNode->handle;
126     }
127
128     if (method == OC_REST_PRESENCE && resourceTypeName)
129     {
130         // Amend the found or created node by adding a new resourceType to it.
131         return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
132         // I own resourceTypName now.
133     }
134     else
135     {
136         OICFree(resourceTypeName);
137     }
138 #else
139     OICFree(resourceTypeName);
140 #endif
141
142     return OC_STACK_OK;
143
144 exit:
145     return OC_STACK_NO_MEMORY;
146 }
147
148 void DeleteClientCB(ClientCB * cbNode)
149 {
150     if (cbNode)
151     {
152         LL_DELETE(cbList, cbNode);
153         OC_LOG (INFO, TAG, "Deleting token");
154         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
155         CADestroyToken (cbNode->token);
156         OICFree(cbNode->devAddr);
157         OICFree(cbNode->handle);
158         OC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
159         OICFree(cbNode->requestUri);
160         if (cbNode->deleteCallback)
161         {
162             cbNode->deleteCallback(cbNode->context);
163         }
164
165 #ifdef WITH_PRESENCE
166         if (cbNode->presence)
167         {
168             OICFree(cbNode->presence->timeOut);
169             OICFree(cbNode->presence);
170         }
171         if (cbNode->method == OC_REST_PRESENCE)
172         {
173             OCResourceType * pointer = cbNode->filterResourceType;
174             OCResourceType * next = NULL;
175             while(pointer)
176             {
177                 next = pointer->next;
178                 OICFree(pointer->resourcetypename);
179                 OICFree(pointer);
180                 pointer = next;
181             }
182         }
183 #endif // WITH_PRESENCE
184         OICFree(cbNode);
185         cbNode = NULL;
186     }
187 }
188
189 /*
190  * This function checks if the node is past its time to live and
191  * deletes it if timed-out. Calling this function with a  presence or observe
192  * callback with ttl set to 0 will not delete anything as presence nodes have
193  * their own mechanisms for timeouts. A null argument will cause the function to
194  * silently return.
195  */
196 static void CheckAndDeleteTimedOutCB(ClientCB* cbNode)
197 {
198     if (!cbNode)
199     {
200         return;
201     }
202     if (cbNode->TTL == 0)
203     {
204         return;
205     }
206     coap_tick_t now;
207     coap_ticks(&now);
208
209     if (cbNode->TTL < now)
210     {
211         OC_LOG(INFO, TAG, "Deleting timed-out callback");
212         DeleteClientCB(cbNode);
213     }
214 }
215
216 ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
217         OCDoHandle handle, const char * requestUri)
218 {
219     ClientCB* out = NULL;
220
221     if (token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
222     {
223         OC_LOG (INFO, TAG,  "Looking for token");
224         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
225         OC_LOG(INFO, TAG, "\tFound in callback list");
226         LL_FOREACH(cbList, out)
227         {
228             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
229
230             if (memcmp(out->token, token, tokenLength) == 0)
231             {
232                 return out;
233             }
234             CheckAndDeleteTimedOutCB(out);
235         }
236     }
237     else if (handle)
238     {
239         LL_FOREACH(cbList, out)
240         {
241             if (out->handle == handle)
242             {
243                 return out;
244             }
245             CheckAndDeleteTimedOutCB(out);
246         }
247     }
248     else if (requestUri)
249     {
250         OC_LOG_V(INFO, TAG, "Looking for uri %s", requestUri);
251         LL_FOREACH(cbList, out)
252         {
253             OC_LOG_V(INFO, TAG, "\tFound %s", out->requestUri);
254             if (out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
255             {
256                 return out;
257             }
258             CheckAndDeleteTimedOutCB(out);
259         }
260     }
261     OC_LOG(INFO, TAG, "Callback Not found !!");
262     return NULL;
263 }
264
265 #ifdef WITH_PRESENCE
266 OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeName)
267 {
268     OCResourceType * newResourceType = NULL;
269     if (cbNode && resourceTypeName)
270     {
271         // Form a new resourceType member.
272         newResourceType = (OCResourceType *) OICMalloc(sizeof(OCResourceType));
273         if (!newResourceType)
274         {
275             return OC_STACK_NO_MEMORY;
276         }
277
278         newResourceType->next = NULL;
279         newResourceType->resourcetypename = resourceTypeName;
280
281         LL_APPEND(cbNode->filterResourceType, newResourceType);
282         return OC_STACK_OK;
283     }
284     return OC_STACK_ERROR;
285 }
286 #endif // WITH_PRESENCE
287
288 void DeleteClientCBList()
289 {
290     ClientCB* out;
291     ClientCB* tmp;
292     LL_FOREACH_SAFE(cbList, out, tmp)
293     {
294         DeleteClientCB(out);
295     }
296     cbList = NULL;
297 }
298
299 void FindAndDeleteClientCB(ClientCB * cbNode)
300 {
301     ClientCB* tmp;
302     if (cbNode)
303     {
304         LL_FOREACH(cbList, tmp)
305         {
306             if (cbNode == tmp)
307             {
308                 DeleteClientCB(tmp);
309                 break;
310             }
311         }
312     }
313 }
314
315 OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, char* uri, uint32_t nonce)
316 {
317     if (!outnode)
318     {
319         return OC_STACK_INVALID_PARAM;
320     }
321
322     OCMulticastNode *node = (OCMulticastNode*) OICMalloc(sizeof(*node));
323     if (node)
324     {
325         node->nonce = nonce;
326         node->uri = uri;
327         LL_APPEND(mcPresenceNodes, node);
328         *outnode = node;
329         return OC_STACK_OK;
330     }
331     *outnode = NULL;
332     return OC_STACK_NO_MEMORY;
333 }
334
335 OCMulticastNode* GetMCPresenceNode(const char * uri)
336 {
337     if (uri)
338     {
339         OCMulticastNode* out = NULL;
340         LL_FOREACH(mcPresenceNodes, out)
341         {
342             if (out->uri && strcmp(out->uri, uri) == 0)
343             {
344                 return out;
345             }
346         }
347     }
348     OC_LOG(INFO, TAG, "MulticastNode Not found !!");
349     return NULL;
350 }