9c8e1119a2b8d4d6afc42724994decf55af0e758
[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 "ocmalloc.h"
26 #include <string.h>
27
28 #include "cacommon.h"
29 #include "cainterface.h"
30
31 /// Module Name
32 #define TAG PCF("occlientcb")
33
34 struct ClientCB *cbList = NULL;
35 static OCMulticastNode * mcPresenceNodes = NULL;
36
37 OCStackResult
38 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
39              CAToken_t * token, OCDoHandle *handle, OCMethod method,
40              char * requestUri, char * resourceTypeName)
41 {
42     if(!clientCB || !cbData || !token || !handle || !requestUri)
43     {
44         return OC_STACK_INVALID_PARAM;
45     }
46
47     ClientCB *cbNode = NULL;
48
49     #ifdef WITH_PRESENCE
50     if(method == OC_REST_PRESENCE)
51     {   // Retrieve the presence callback structure for this specific requestUri.
52         cbNode = GetClientCB(NULL, NULL, requestUri);
53     }
54     #endif // WITH_PRESENCE
55
56     if(!cbNode)// If it does not already exist, create new node.
57     {
58         cbNode = (ClientCB*) OCMalloc(sizeof(ClientCB));
59         if(!cbNode)
60         {
61             *clientCB = NULL;
62             goto exit;
63         }
64         else
65         {
66             cbNode->callBack = cbData->cb;
67             cbNode->context = cbData->context;
68             cbNode->deleteCallback = cbData->cd;
69             //Note: token memory is allocated in the caller OCDoResource
70             //but freed in DeleteClientCB
71             cbNode->token = *token;
72             cbNode->handle = *handle;
73             cbNode->method = method;
74             cbNode->sequenceNumber = 0;
75             #ifdef WITH_PRESENCE
76             cbNode->presence = NULL;
77             cbNode->filterResourceType = NULL;
78             #endif // WITH_PRESENCE
79             cbNode->requestUri = requestUri;
80             LL_APPEND(cbList, cbNode);
81             *clientCB = cbNode;
82         }
83     }
84     else
85     {
86         // Ensure that the handle the SDK hands back up to the application layer for the
87         // OCDoResource call matches the found ClientCB Node.
88         *clientCB = cbNode;
89
90         if (cbData->cd)
91         {
92             cbData->cd(cbData->context);
93         }
94
95         OCFree(*token);
96         OCFree(*handle);
97         OCFree(requestUri);
98         *handle = cbNode->handle;
99     }
100
101     #ifdef WITH_PRESENCE
102     if(method == OC_REST_PRESENCE && resourceTypeName)
103     {
104         // Amend the found or created node by adding a new resourceType to it.
105         return InsertResourceTypeFilter(cbNode, resourceTypeName);
106     }
107     else
108     {
109         OCFree(resourceTypeName);
110     }
111     #else
112     OCFree(resourceTypeName);
113     #endif
114
115     return OC_STACK_OK;
116
117     exit:
118         return OC_STACK_NO_MEMORY;
119 }
120
121 void DeleteClientCB(ClientCB * cbNode)
122 {
123     if(cbNode) {
124         LL_DELETE(cbList, cbNode);
125         OC_LOG(INFO, TAG, PCF("deleting tokens"));
126         CADestroyToken (cbNode->token);
127         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, CA_MAX_TOKEN_LEN);
128         OCFree(cbNode->handle);
129         OCFree(cbNode->requestUri);
130         if(cbNode->deleteCallback)
131         {
132             cbNode->deleteCallback(cbNode->context);
133         }
134
135         #ifdef WITH_PRESENCE
136         if(cbNode->presence) {
137             OCFree(cbNode->presence->timeOut);
138             OCFree(cbNode->presence);
139         }
140         if(cbNode->method == OC_REST_PRESENCE)
141         {
142             OCResourceType * pointer = cbNode->filterResourceType;
143             OCResourceType * next = NULL;
144             while(pointer)
145             {
146                 next = pointer->next;
147                 OCFree(pointer->resourcetypename);
148                 OCFree(pointer);
149                 pointer = next;
150             }
151         }
152         #endif // WITH_PRESENCE
153         OCFree(cbNode);
154         cbNode = NULL;
155     }
156 }
157
158 ClientCB* GetClientCB(const CAToken_t * token, OCDoHandle handle, const char * requestUri)
159 {
160     ClientCB* out = NULL;
161     if(token) {
162         LL_FOREACH(cbList, out) {
163             OC_LOG(INFO, TAG, PCF("comparing tokens"));
164             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)*token, CA_MAX_TOKEN_LEN);
165             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, CA_MAX_TOKEN_LEN);
166             if(memcmp(out->token, *token, CA_MAX_TOKEN_LEN) == 0)
167             {
168                 return out;
169             }
170         }
171     }
172     else if(handle) {
173         LL_FOREACH(cbList, out) {
174             if(out->handle == handle) {
175                 return out;
176             }
177         }
178     }
179     else if(requestUri) {
180         LL_FOREACH(cbList, out) {
181             if(out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
182             {
183                 return out;
184             }
185         }
186     }
187     OC_LOG(INFO, TAG, PCF("Callback Not found !!"));
188     return NULL;
189 }
190
191 #ifdef WITH_PRESENCE
192 OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeName)
193 {
194     OCResourceType * newResourceType = NULL;
195     if(cbNode && resourceTypeName)
196     {
197         // Form a new resourceType member.
198         newResourceType = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
199         if(!newResourceType)
200         {
201             return OC_STACK_NO_MEMORY;
202         }
203
204         newResourceType->next = NULL;
205         newResourceType->resourcetypename = resourceTypeName;
206
207         LL_APPEND(cbNode->filterResourceType, newResourceType);
208         return OC_STACK_OK;
209     }
210     return OC_STACK_ERROR;
211 }
212 #endif // WITH_PRESENCE
213
214 void DeleteClientCBList() {
215     ClientCB* out;
216     ClientCB* tmp;
217     LL_FOREACH_SAFE(cbList, out, tmp) {
218         DeleteClientCB(out);
219     }
220     cbList = NULL;
221 }
222
223 void FindAndDeleteClientCB(ClientCB * cbNode) {
224     ClientCB* tmp;
225     if(cbNode)
226     {
227         LL_FOREACH(cbList, tmp)
228         {
229             if (cbNode == tmp)
230             {
231                 DeleteClientCB(tmp);
232                 break;
233             }
234         }
235     }
236 }
237
238 OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, char* uri, uint32_t nonce)
239 {
240     if(!outnode)
241     {
242         return OC_STACK_INVALID_PARAM;
243     }
244
245     OCMulticastNode *node;
246
247     node = (OCMulticastNode*) OCMalloc(sizeof(OCMulticastNode));
248
249     if (node) {
250         node->nonce = nonce;
251         node->uri = uri;
252         LL_APPEND(mcPresenceNodes, node);
253         *outnode = node;
254         return OC_STACK_OK;
255     }
256     *outnode = NULL;
257     return OC_STACK_NO_MEMORY;
258 }
259
260 OCMulticastNode* GetMCPresenceNode(const char * uri) {
261     OCMulticastNode* out = NULL;
262
263     if(uri) {
264         LL_FOREACH(mcPresenceNodes, out) {
265             if(out->uri && strcmp(out->uri, uri) == 0) {
266                 return out;
267             }
268         }
269     }
270     OC_LOG(INFO, TAG, PCF("MulticastNode Not found !!"));
271     return NULL;
272 }
273