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