Modify Consumer Logic
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerScheduler.c
1 //******************************************************************
2 //
3 // Copyright 2016 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
21 #include "NSConsumerScheduler.h"
22
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <unistd.h>
26
27 #include "oic_malloc.h"
28 #include "oic_string.h"
29 #include "ocrandom.h"
30
31 #include "NSStructs.h"
32 #include "NSConstants.h"
33 #include "NSConsumerCommon.h"
34 #include "NSConsumerCommunication.h"
35
36 #include "NSThread.h"
37 #include "NSConsumerQueue.h"
38
39 #include "NSConsumerDiscovery.h"
40 #include "NSConsumerInternalTaskController.h"
41 #include "NSConsumerNetworkEventListener.h"
42 #include "NSConsumerSystem.h"
43
44 void * NSConsumerMsgHandleThreadFunc(void * handle);
45
46 void * NSConsumerMsgPushThreadFunc(void * data);
47
48 void NSConsumerTaskProcessing(NSTask * task);
49
50 NSConsumerThread ** NSGetMsgHandleThreadHandle()
51 {
52     static NSConsumerThread * handle = NULL;
53     return & handle;
54 }
55
56 void NSSetMsgHandleThreadHandle(NSConsumerThread * handle)
57 {
58    *(NSGetMsgHandleThreadHandle()) = handle;
59 }
60
61 NSConsumerQueue ** NSGetMsgHandleQueue()
62 {
63     static NSConsumerQueue * queue = NULL;
64     return & queue;
65 }
66
67 void NSSetMsgHandleQueue(NSConsumerQueue * queue)
68 {
69    *(NSGetMsgHandleQueue()) = queue;
70 }
71
72 NSResult NSConsumerMessageHandlerInit()
73 {
74     NSConsumerThread * handle = NULL;
75     NSConsumerQueue * queue = NULL;
76
77     uint8_t uuid[UUID_SIZE];
78     char uuidString[UUID_STRING_SIZE];
79     OCGenerateUuid(uuid);
80     OCConvertUuidToString(uuid, uuidString);
81     NSSetConsumerId(uuidString);
82     NS_LOG_V(DEBUG, "Consumer ID : %s", *NSGetConsumerId());
83
84     NS_LOG(DEBUG, "listener init");
85     NSResult ret = NSConsumerListenerInit();
86     NS_VERIFY_NOT_NULL(ret == NS_OK ? (void *) 1 : NULL, NS_ERROR);
87
88     NS_LOG(DEBUG, "system init");
89     ret = NSConsumerSystemInit();
90     NS_VERIFY_NOT_NULL(ret == NS_OK ? (void *) 1 : NULL, NS_ERROR);
91
92     NS_LOG(DEBUG, "queue thread init");
93     handle = NSThreadInit(NSConsumerMsgHandleThreadFunc, NULL);
94     NS_VERIFY_NOT_NULL(handle, NS_ERROR);
95     NSSetMsgHandleThreadHandle(handle);
96
97     NS_LOG(DEBUG, "create queue");
98     queue = NSCreateQueue();
99     NS_VERIFY_NOT_NULL(queue, NS_ERROR);
100     NSSetMsgHandleQueue(queue);
101
102     return NS_OK;
103 }
104
105 NSResult NSConsumerPushEvent(NSTask * task)
106 {
107     NSConsumerThread * thread = NSThreadInit(NSConsumerMsgPushThreadFunc, (void *) task);
108     NS_VERIFY_NOT_NULL(thread, NS_ERROR);
109
110     return NS_OK;
111 }
112
113 void NSConsumerMessageHandlerExit()
114 {
115     NSDestroyMessageCacheList();
116     NSDestroyProviderCacheList();
117     NSConsumerListenerTermiate();
118     NSThreadStop(*(NSGetMsgHandleThreadHandle()));
119     NSDestroyQueue(*(NSGetMsgHandleQueue()));
120 }
121
122 void * NSConsumerMsgHandleThreadFunc(void * threadHandle)
123 {
124     NSConsumerQueue * queue = NULL;
125     NSConsumerQueueObject * obj = NULL;
126
127     NS_LOG(DEBUG, "create thread for consumer message handle");
128     NSConsumerThread * queueHandleThread = (NSConsumerThread *) threadHandle;
129     NS_VERIFY_NOT_NULL(queueHandleThread, NULL);
130
131     while (true)
132     {
133         if (!queueHandleThread->isStarted)
134         {
135             NS_LOG(ERROR, "msg handler thread will be terminated");
136             break;
137         }
138
139         queue = *(NSGetMsgHandleQueue());
140         if (!queue)
141         {
142             continue;
143         }
144
145         if (NSIsQueueEmpty(queue))
146         {
147             usleep(2000);
148             continue;
149         }
150
151         NSThreadLock(queueHandleThread);
152         NS_LOG(DEBUG, "msg handler working");
153         obj = NSPopQueue(queue);
154
155         if (obj)
156         {
157             NSConsumerTaskProcessing((NSTask *)(obj->data));
158         }
159
160         NSThreadUnlock(queueHandleThread);
161
162     }
163
164     return NULL;
165 }
166
167 void * NSConsumerMsgPushThreadFunc(void * data)
168 {
169     NSConsumerQueueObject * obj = NULL;
170     NSConsumerQueue * queue = NULL;
171
172     NS_LOG(DEBUG, "get queueThread handle");
173     NSConsumerThread * msgHandleThread = *(NSGetMsgHandleThreadHandle());
174     NS_VERIFY_NOT_NULL(msgHandleThread, NULL);
175
176     NS_LOG(DEBUG, "create queue object");
177     obj = (NSConsumerQueueObject *)OICMalloc(sizeof(NSConsumerQueueObject));
178     NS_VERIFY_NOT_NULL(obj, NULL);
179
180     obj->data = data;
181     obj->next = NULL;
182
183     NSThreadLock(msgHandleThread);
184
185     queue = *(NSGetMsgHandleQueue());
186     if (!queue)
187     {
188         NS_LOG(ERROR, "NSQueue is null. can not insert to queue");
189         OICFree(data);
190         OICFree(obj);
191     }
192     else
193     {
194         NSPushQueue(queue, obj);
195     }
196
197     NSThreadUnlock(msgHandleThread);
198
199     return NULL;
200 }
201
202 void NSConsumerTaskProcessing(NSTask * task)
203 {
204     switch (task->taskType)
205     {
206     case TASK_EVENT_CONNECTED:
207     case TASK_CONSUMER_REQ_DISCOVER:
208     {
209         NSConsumerDiscoveryTaskProcessing(task);
210         break;
211     }
212     case TASK_CONSUMER_REQ_SUBSCRIBE:
213     case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
214     case TASK_SEND_SYNCINFO:
215     {
216         NSConsumerCommunicationTaskProcessing(task);
217         break;
218     }
219     case TASK_RECV_SYNCINFO:
220     case TASK_CONSUMER_RECV_MESSAGE:
221     case TASK_CONSUMER_PROVIDER_DISCOVERED:
222     case TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED:
223     case TASK_MAKE_SYNCINFO:
224     {
225         NSConsumerInternalTaskProcessing(task);
226         break;
227     }
228     default:
229         NS_LOG(ERROR, "Unknown type of task");
230         break;
231     }
232 }
233
234 NSMessage_consumer * NSConsumerFindNSMessage(const char* messageId)
235 {
236     NS_VERIFY_NOT_NULL(messageId, NULL);
237
238     return NSMessageCacheFind(messageId);
239 }
240
241 NSProvider_internal * NSConsumerFindNSProvider(const char * providerId)
242 {
243     NS_VERIFY_NOT_NULL(providerId, NULL);
244
245     return NSProviderCacheFind(providerId);
246 }