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