Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / service / resource-directory / src / internal / rd_storage.c
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics 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 #include "rd_storage.h"
21
22 #include <pthread.h>
23 #include <string.h>
24
25 #include "payload_logging.h"
26 #include "oic_malloc.h"
27
28 #include "rdpayload.h"
29
30 #define TAG  PCF("RDStorage")
31
32 pthread_mutex_t storageMutex = PTHREAD_MUTEX_INITIALIZER;
33 // This variable holds the published resources on the RD.
34 static OCRDStorePublishResources *g_rdStorage = NULL;
35
36 static void printStoragedResources(OCRDStorePublishResources *payload)
37 {
38     OC_LOG(DEBUG, TAG, "Print Storage Resources ... ");
39     for (OCRDStorePublishResources *temp = payload; temp; temp = temp->next)
40     {
41         if (temp->publishedResource)
42         {
43             OCTagsLog(DEBUG, temp->publishedResource->tags);
44             OCLinksLog(DEBUG, temp->publishedResource->setLinks);
45         }
46     }
47 }
48
49 OCStackResult OCRDStorePublishedResources(const OCResourceCollectionPayload *payload)
50 {
51     OCResourceCollectionPayload *storeResource = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
52     if (!storeResource)
53     {
54         OC_LOG(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
55         return OC_STACK_NO_MEMORY;
56     }
57
58     OC_LOG(DEBUG, TAG, "Storing Resources ... ");
59
60     OCTagsPayload *tags = payload->tags;
61     storeResource->tags = OCCopyTagsResources(tags->n.deviceName, tags->di.id, tags->baseURI,
62         tags->bitmap, tags->port, tags->ins, tags->rts, tags->drel, tags->ttl);
63     if (!storeResource->tags)
64     {
65         OC_LOG(ERROR, TAG, "Failed allocating memory for tags.");
66         OCFreeCollectionResource(storeResource);
67         return OC_STACK_NO_MEMORY;
68     }
69
70     for (OCLinksPayload *links = payload->setLinks; links; links = links->next)
71     {
72         if (!storeResource->setLinks)
73         {
74             storeResource->setLinks = OCCopyLinksResources(links->href, links->rt, links->itf,
75                 links->rel, links->obs, links->title, links->uri, links->ins, links->mt);
76             if (!storeResource->setLinks)
77             {
78                 OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
79                 OCFreeCollectionResource(storeResource);
80                 return OC_STACK_NO_MEMORY;
81             }
82         }
83         else
84         {
85             OCLinksPayload *temp = storeResource->setLinks;
86             while (temp->next)
87             {
88                 temp = temp->next;
89             }
90             temp->next = OCCopyLinksResources(links->href, links->rt, links->itf, links->rel,
91                 links->obs, links->title, links->uri, links->ins, links->mt);
92             if (!temp->next)
93             {
94                 OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
95                 OCFreeCollectionResource(storeResource);
96                 return OC_STACK_NO_MEMORY;
97             }
98         }
99
100     }
101     storeResource->next = NULL;
102     OCRDStorePublishResources *resources = (OCRDStorePublishResources *)OICCalloc(1, sizeof(OCRDStorePublishResources));
103     if (!resources)
104     {
105         OCFreeCollectionResource(storeResource);
106         return OC_STACK_NO_MEMORY;
107     }
108     resources->publishedResource = storeResource;
109
110     pthread_mutex_lock(&storageMutex);
111     if (g_rdStorage)
112     {
113         OCRDStorePublishResources *temp = g_rdStorage;
114         while (temp->next)
115         {
116             temp = temp->next;
117         }
118         temp->next = resources;
119     }
120     else
121     {
122         g_rdStorage = resources;
123     }
124     pthread_mutex_unlock(&storageMutex);
125
126     printStoragedResources(g_rdStorage);
127     return OC_STACK_OK;
128 }
129
130 OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
131         OCResourceCollectionPayload **payload)
132 {
133     // ResourceType and InterfaceType if both are NULL it will return. If either is
134     // not null it will continue execution.
135     if (!resourceType && !interfaceType)
136     {
137         OC_LOG(DEBUG, TAG, "Missing resource type and interace type.");
138         return OC_STACK_INVALID_PARAM;
139     }
140
141     OC_LOG(DEBUG, TAG, "Check Resource in RD");
142     if (g_rdStorage && g_rdStorage->publishedResource)
143     {
144         for (OCRDStorePublishResources *pResource = g_rdStorage;
145                 pResource; pResource = pResource->next)
146         {
147             if (pResource->publishedResource->setLinks)
148             {
149                 for (OCLinksPayload *tLinks = pResource->publishedResource->setLinks; tLinks; tLinks = tLinks->next)
150                 {
151                     // If either rt or itf are NULL, it should skip remaining code execution.
152                     if (!tLinks->rt || !tLinks->itf)
153                     {
154                         OC_LOG(DEBUG, TAG, "Either resource type and interface type are missing.");
155                         continue;
156                     }
157                     if (resourceType)
158                     {
159                         OCStringLL *temp = tLinks->rt;
160                         while(temp)
161                         {
162                             OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, temp->value);
163                             if (strcmp(resourceType, temp->value) == 0)
164                             {
165                                 OCTagsPayload *tag = pResource->publishedResource->tags;
166                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
167                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
168                                 if (!tags)
169                                 {
170                                     return OC_STACK_NO_MEMORY;
171                                 }
172                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->href, tLinks->rt, tLinks->itf,
173                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
174                                 if (!links)
175                                 {
176                                     OCFreeTagsResource(tags);
177                                     return OC_STACK_NO_MEMORY;
178                                 }
179                                 *payload = OCCopyCollectionResource(tags, links);
180                                 if (!*payload)
181                                 {
182                                     OCFreeTagsResource(tags);
183                                     OCFreeLinksResource(links);
184                                     return OC_STACK_NO_MEMORY;
185                                 }
186                                 return OC_STACK_OK;
187                             }
188                             temp = temp->next;
189                         }
190                     }
191                     if (interfaceType)
192                     {
193                         OCStringLL *temp = tLinks->itf;
194                         while (temp)
195                         {
196                             OC_LOG_V(DEBUG, TAG, "Interface Type: %s %s", interfaceType, temp->value);
197                             if (strcmp(interfaceType, temp->value) == 0)
198                             {
199                                 OCTagsPayload *tag = pResource->publishedResource->tags;
200                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
201                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
202                                 if (!tags)
203                                 {
204                                     return OC_STACK_NO_MEMORY;
205                                 }
206                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->uri, tLinks->rt, tLinks->itf,
207                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
208                                 if (!links)
209                                 {
210                                     OCFreeTagsResource(tags);
211                                     return OC_STACK_NO_MEMORY;
212                                 }
213                                 *payload = OCCopyCollectionResource(tags, links);
214                                 if (!*payload)
215                                 {
216                                     OCFreeTagsResource(tags);
217                                     OCFreeLinksResource(links);
218                                     return OC_STACK_NO_MEMORY;
219                                 }
220                                 return OC_STACK_OK;
221                             }
222                             temp = temp->next;
223                         }
224                     }
225                 }
226             }
227         }
228     }
229     return OC_STACK_ERROR;
230 }