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