Improve typing of constants data
[platform/core/messaging/msg-service.git] / framework / main.cpp
1 /*
2  * msg-service
3  *
4  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18 */
19
20 /*==================================================================================================
21                                          INCLUDE FILES
22 ==================================================================================================*/
23 #include "MsgDebug.h"
24 #include "MsgException.h"
25 #include "MsgContact.h"
26 #include "MsgMemory.h"
27 #include "MsgGconfWrapper.h"
28 #include "MsgPluginManager.h"
29 #include "MsgSettingHandler.h"
30 #include "MsgStorageHandler.h"
31 #include "MsgSubmitHandler.h"
32 #include "MsgDeliverHandler.h"
33 #include "MsgTransManager.h"
34 #include "MsgStorageTypes.h"
35 #include "MsgSoundPlayer.h"
36 #include "MsgCmdHandler.h"
37 #include "MsgUtilStorage.h"
38 #include "MsgNotificationWrapper.h"
39
40 #include <errno.h>
41 #include <glib.h>
42 #include <dbus/dbus-glib.h>
43 #include <sys/stat.h>
44 #include <wait.h>
45
46 static GMainLoop* mainloop = NULL;
47
48
49 /*==================================================================================================
50                                      DEFINES
51 ==================================================================================================*/
52 #define MSG_MOBILE_TRACKER_MSG "Mobile Tracker Alert"
53
54
55 /*==================================================================================================
56                                      FUNCTION IMPLEMENTATION
57 ==================================================================================================*/
58 msg_error_t InitMmsDir()
59 {
60         if (mkdir(MSG_DATA_ROOT_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
61         {
62                 if (errno == EEXIST)
63                 {
64                         MSG_DEBUG("The %s already exists", MSG_DATA_ROOT_PATH);
65                 }
66                 else
67                 {
68                         MSG_DEBUG("Error while mkdir %s", MSG_DATA_ROOT_PATH);
69                         return MSG_ERR_DB_MAKE_DIR;
70                 }
71         }
72
73         if (mkdir(MSG_SMIL_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
74         {
75                 if (errno == EEXIST)
76                 {
77                         MSG_DEBUG("The %s already exists", MSG_SMIL_FILE_PATH);
78                 }
79                 else
80                 {
81                         MSG_DEBUG("Error while mkdir %s", MSG_SMIL_FILE_PATH);
82                         return MSG_ERR_DB_MAKE_DIR;
83                 }
84         }
85
86         if (mkdir(MSG_DATA_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
87         {
88                 if (errno == EEXIST)
89                 {
90                         MSG_DEBUG("The %s already exists", MSG_DATA_PATH);
91                 }
92                 else
93                 {
94                         MSG_DEBUG("Error while mkdir %s", MSG_DATA_PATH);
95                         return MSG_ERR_DB_MAKE_DIR;
96                 }
97         }
98
99         if (mkdir(MSG_THUMBNAIL_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
100                 if (errno == EEXIST) {
101                         MSG_DEBUG("The %s already exists.", MSG_THUMBNAIL_PATH);
102                 } else {
103                         MSG_DEBUG(" Error while mkdir %s", MSG_THUMBNAIL_PATH);
104                         return MSG_ERR_DB_MAKE_DIR;
105                 }
106         }
107
108         if (mkdir(MSG_IPC_DATA_PATH, S_IRWXU ) < 0)
109         {
110                 if (errno == EEXIST)
111                 {
112                         MSG_DEBUG("The %s already exists", MSG_IPC_DATA_PATH);
113
114                         // if IPC data path is already exist, clear all files in folder.
115                         char exeStr[1024];
116                         snprintf(exeStr, 1024, "rm %s/*.DATA", MSG_IPC_DATA_PATH);
117                         system(exeStr);
118                 }
119                 else
120                 {
121                         MSG_DEBUG("Error while mkdir %s", MSG_IPC_DATA_PATH);
122                         return MSG_ERR_DB_MAKE_DIR;
123                 }
124         }
125
126         if(chmod( MSG_IPC_DATA_PATH, S_IRWXU | S_IRWXG ) !=0) { //public shared file: pass data by file
127                 MSG_DEBUG("Fail to chmod [%s].", MSG_IPC_DATA_PATH);
128         }
129         chown( MSG_IPC_DATA_PATH, 0, 6502 );
130
131         return MSG_SUCCESS;
132 }
133
134
135 void SendMobileTrackerMsg()
136 {
137         MSG_BEGIN();
138
139         bool bEnabled = false;
140
141         if (MsgSettingGetBool(VCONFKEY_SETAPPL_FIND_MY_MOBILE_SIM_CHANGE_ALERT_BOOL, &bEnabled) < 0)
142         {
143                 MSG_DEBUG("Can't read VCONFKEY_SETAPPL_FIND_MY_MOBILE_SIM_CHANGE_ALERT_BOOL");
144                 return;
145         }
146
147         if (bEnabled == false)
148         {
149                 MSG_DEBUG("Mobile Tracker Option [%d]", bEnabled);
150                 return;
151         }
152         // to wait modem init
153         // temporary code.
154         else
155         {
156                 MSG_DEBUG("Waiting for modem ready, 22 sec.");
157                 sleep(22);
158         }
159
160         MSG_REQUEST_INFO_S req = {0};
161
162         req.sendOptInfo.bSetting = false;
163
164         req.msgInfo.msgId = 0;
165         req.msgInfo.threadId = 0;
166         req.msgInfo.folderId = MSG_DRAFT_ID;
167         req.msgInfo.msgType.mainType = MSG_SMS_TYPE;
168         req.msgInfo.msgType.subType = MSG_NORMAL_SMS;
169         req.msgInfo.msgType.classType = MSG_CLASS_NONE;
170         req.msgInfo.storageId = MSG_STORAGE_PHONE;
171         req.msgInfo.displayTime = 0;
172         req.msgInfo.networkStatus = MSG_NETWORK_NOT_SEND;
173         req.msgInfo.encodeType = MSG_ENCODE_AUTO;
174         req.msgInfo.bRead = false;
175         req.msgInfo.bProtected = false;
176         req.msgInfo.priority = MSG_MESSAGE_PRIORITY_NORMAL;
177         req.msgInfo.direction = MSG_DIRECTION_TYPE_MO;
178         req.msgInfo.msgPort.valid = false;
179         req.msgInfo.bTextSms = true;
180
181         // Get Message Text
182         char* msgText = NULL;
183
184         msgText = MsgSettingGetString(VCONFKEY_SETAPPL_FIND_MY_MOBILE_MESSAGE_STR);
185
186         if (msgText == NULL)
187         {
188                 MSG_DEBUG("Assign Default Msg");
189                 msgText = strdup(MSG_MOBILE_TRACKER_MSG);
190                 if (msgText == NULL) {
191                         MSG_DEBUG("msgText is NULL.");
192                         return;
193                 }
194         }
195
196         MSG_DEBUG("mobile tracker msg : [%s]", msgText);
197
198         req.msgInfo.dataSize = strlen(msgText);
199         strncpy(req.msgInfo.msgText, msgText, req.msgInfo.dataSize);
200
201         // Get Address List
202         char *orgRecipientList = NULL;
203
204         orgRecipientList = MsgSettingGetString(VCONFKEY_SETAPPL_FIND_MY_MOBILE_RECIPIENTS_STR);
205
206         if (orgRecipientList == NULL)
207         {
208                 MSG_DEBUG("recipient list is NULL");
209                 free(msgText);
210                 msgText = NULL;
211                 return;
212         }
213
214         int len = strlen(orgRecipientList);
215         char recipientList[len + 1];
216
217         memset(recipientList, 0, len + 1);
218         memcpy(recipientList, orgRecipientList, len);
219
220         MSG_DEBUG("recipient list : [%s]", recipientList);
221
222         req.msgInfo.nAddressCnt = 1;
223
224         char *token;
225
226         token = strtok(recipientList, "|");
227
228         MSG_MAIN_TYPE_T mainType = MSG_SMS_TYPE;
229         MsgPlugin* plg = MsgPluginManager::instance()->getPlugin(mainType);
230
231         msg_error_t err = MSG_SUCCESS;
232
233         while (token)
234         {
235                 req.msgInfo.addressList[0].addressType = MSG_ADDRESS_TYPE_PLMN;
236                 req.msgInfo.addressList[0].recipientType = MSG_RECIPIENTS_TYPE_TO;
237
238                 memset(req.msgInfo.addressList[0].addressVal, 0x00, MAX_ADDRESS_VAL_LEN);
239                 strncpy(req.msgInfo.addressList[0].addressVal, token, MAX_ADDRESS_VAL_LEN);
240
241                 MSG_DEBUG("address : [%s]", req.msgInfo.addressList[0].addressVal);
242
243                 if (plg != NULL)
244                 {
245                         MSG_DEBUG("mobile tracker msg : [%s]", msgText);
246
247                         err = plg->submitReq(&req);
248
249                         if (err != MSG_SUCCESS)
250                         {
251                                 MSG_DEBUG("fail to send mobile tracker msg : [%d]", err);
252                                 break;
253                         }
254                 }
255
256                 token = strtok(NULL, "|");
257         }
258
259         if (msgText) {
260                 free(msgText);
261                 msgText = NULL;
262         }
263
264         if (orgRecipientList) {
265                 free(orgRecipientList);
266                 orgRecipientList = NULL;
267         }
268
269
270         MSG_END();
271
272         return;
273 }
274
275
276 void* StartMsgServer(void*)
277 {
278
279         MsgOpenContactSvc();
280
281         try
282         {
283                 MsgTransactionManager::instance()->run();
284         }
285         catch (MsgException& e)
286         {
287                 MSG_FATAL("%s", e.what());
288         }
289         catch (exception& e)
290         {
291                 MSG_FATAL("%s", e.what());
292         }
293
294         if (g_main_loop_is_running(mainloop))
295                 g_main_loop_quit(mainloop);
296
297         MsgCloseContactSvc();
298
299         return (void*)0;
300 }
301
302
303 void* InitMsgServer(void*)
304 {
305         msg_error_t err = MSG_SUCCESS;
306
307         MsgOpenContactSvc();
308
309         try
310         {
311                 // plugin manager initialize
312                 MsgPluginManager::instance()->initialize();
313         }
314         catch (MsgException& e)
315         {
316                 MSG_FATAL("%s", e.what());
317         }
318         catch (exception& e)
319         {
320                 MSG_FATAL("%s", e.what());
321         }
322
323         MSG_MAIN_TYPE_T mainType = MSG_SMS_TYPE;
324         MsgPlugin* plg = MsgPluginManager::instance()->getPlugin(mainType);
325
326         // storage handler initialize
327         err = MsgStoInitDB(false);
328
329         if (err != MSG_SUCCESS) {
330                 MSG_DEBUG("FAIL TO INITIALIZE STORAGE HANDLER [%d]", err);
331         }
332
333         // Set Msg FW Ready Flag
334         if(MsgSettingSetBool(VCONFKEY_MSG_SERVER_READY, true) != MSG_SUCCESS)
335                 MSG_DEBUG("MsgSettingSetBool FAIL : VCONFKEY_MSG_SERVER_READY");
336         MSG_DEBUG("### VCONFKEY_MSG_SERVER_READY ###");
337
338         if (plg == NULL) {
339                 MSG_DEBUG("No plugin for %d type", mainType);
340
341                 MsgReleaseMemory();
342                 return (void*)0;
343         }
344
345         // Clear and reset notification
346         MsgCleanAndResetNoti();
347
348         MSG_SIM_STATUS_T simStatus = MSG_SIM_STATUS_NORMAL;
349
350         // Check Sim Status
351         if (plg->checkSimStatus(&simStatus) == MSG_SUCCESS) {
352
353                 // Add the change of SIM to vconf
354                 if (MsgSettingSetInt(MSG_SIM_CHANGED, (int)simStatus) != MSG_SUCCESS) {
355                         MSG_DEBUG("Error to set config data [%s]", MSG_SIM_CHANGED);
356                 }
357
358                 if (simStatus != MSG_SIM_STATUS_NOT_FOUND) {
359                         // Check Device Status
360                         if (plg->checkDeviceStatus() != MSG_SUCCESS) {
361                                 MSG_DEBUG("checkDeviceStatus() error");
362
363                                 MsgReleaseMemory();
364
365                                 return (void*)0;
366                         }
367                 }
368
369                 // Init SIM Message
370                 if (MsgInitSimMessage(simStatus) != MSG_SUCCESS) {
371                         MSG_DEBUG("Fail to Initialize SIM Message");
372                 }
373
374                 // Init SIM Configuration
375                 if (MsgInitSimConfig(simStatus) != MSG_SUCCESS) {
376                         MSG_DEBUG("Fail to Initialize SIM Configuration");
377                 }
378
379                 // Add SendMobileTrackerMsg() to GMainLoop
380                 if (simStatus == MSG_SIM_STATUS_CHANGED) {
381                         MSG_DEBUG("Send Mobile Tracker Message");
382
383                         SendMobileTrackerMsg();
384                 }
385         } else {
386                 MSG_DEBUG("checkSimStatus() error");
387         }
388
389         MsgReleaseMemory();
390
391         // Register Callback to get the change of contact
392         MsgInitContactSvc(&MsgContactChangedCallback);
393
394         MsgSoundInitRepeatAlarm();
395
396         return (void*)0;
397 }
398
399
400 static gboolean InitThreadFunc(void* pData)
401 {
402         MSG_BEGIN();
403
404         pthread_t initThreadId;
405
406         // initialize msg fw
407         if (pthread_create(&initThreadId, NULL, InitMsgServer, NULL) != 0)
408         {
409                 MSG_DEBUG("InitMsgFw not invoked: %s", strerror(errno));
410                 return -1;
411         }
412
413         pthread_detach(initThreadId);
414
415         MSG_END();
416
417         return FALSE;
418 }
419
420
421 int main(void)
422 {
423 #if !GLIB_CHECK_VERSION(2, 31, 0)
424         g_thread_init(NULL);
425 #endif
426         dbus_g_thread_init();
427
428 ////////////////////////////////////
429
430 /// set to ignore child process terminated signal.
431 signal( SIGCHLD, SIG_IGN );
432
433 ////////////////////////////////////
434
435
436         MSG_DEBUG("===========START MESSAGING FRAMEWORK==========");
437
438         // Reset message server ready flag
439         if(MsgSettingSetBool(VCONFKEY_MSG_SERVER_READY, false) != MSG_SUCCESS)
440                 MSG_DEBUG("MsgSettingSetBool FAIL: VCONFKEY_MSG_SERVER_READY");
441
442         // Connect to DB
443         //      MsgStoConnectDB();
444
445         // Open Contact Service
446         MsgOpenContactSvc();
447
448         // Clean up mms dir
449         InitMmsDir();
450
451         // Regist vconf CB.
452         MsgSettingRegVconfCB();
453
454         pthread_t startThreadId;
455
456         // start transaction manager
457         if (pthread_create(&startThreadId, NULL, StartMsgServer, NULL) != 0)
458         {
459                 MSG_DEBUG("StartMsgServer not invoked: %s", strerror(errno));
460                 return -1;
461         }
462
463         MsgTransactionManager::instance()->getTMStatus();
464
465         mainloop = g_main_loop_new(NULL, FALSE);
466
467 #if !GLIB_CHECK_VERSION(2,35,0)
468         g_type_init ();
469 #endif
470
471         g_idle_add(InitThreadFunc, NULL);
472
473         if (mainloop != NULL)
474         {
475                 MSG_DEBUG("Start Messaging Framework!!!");
476
477                 // Run GMainLoop
478                 g_main_loop_run(mainloop);
479         }
480         else
481         {
482                 MSG_DEBUG("Fail to start Messaging Framework!!!");
483         }
484
485         // Remove vconf CB
486         MsgSettingRemoveVconfCB();
487
488         // Close Contact Sevice
489         MsgCloseContactSvc();
490
491         // Disconnect to DB
492         MsgStoDisconnectDB();
493
494         return 0;
495 }
496