00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <gtk/gtk.h>
00039 #include <sys/types.h>
00040 #include <sys/wait.h>
00041 #include <sys/time.h>
00042 #include <time.h>
00043
00044 #include <liberdm/display.h>
00045 #include <liberregxml/erregapi.h>
00046 #include <libermanifest/ermanifest.h>
00047
00048 #include "contentListerLog.h"
00049 #include "button.h"
00050 #include "erConnect.h"
00051 #include "erMSDisk.h"
00052 #include "system.h"
00053 #include "gtkPincodeScreen.h"
00054 #include "control.h"
00055 #include "programManager.h"
00056 #include "regValue.h"
00057 #include "toolbar.h"
00058 #include "timedids.h"
00059
00060 #define KILL_TIMEOUT 5*1000*1000// in suseconds_t
00061 #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
00062
00063
00064 static pid_t g_connect_pid = 0;
00065
00066
00067 static void *connectThread(void *arg);
00068
00069
00070 void erConnectInit(connectStruct_t * connect)
00071 {
00072 connect->command = connectCmdNone;
00073 connect->state = connectStateIdle;
00074 connect->screen = connectScrDownloadHistory;
00075 connect->background = FALSE;
00076 connect->connect_from_pincode = FALSE;
00077 connect->connect_after_reboot = FALSE;
00078 connect->szCommand[0] = '\0';
00079
00080 if (pthread_mutex_init(&(connect->mutex), NULL) )
00081 {
00082 CL_ERRORPRINTF("Could not initialize connect mutex");
00083 perror("Could not initialize mutex");
00084 }
00085 else
00086 {
00087 CL_ERRORPRINTF("Lock the connect mutex");
00088 pthread_mutex_lock( &(connect->mutex) );
00089 }
00090
00091
00092 pthread_t thread_id;
00093 if (pthread_create(&thread_id, NULL, connectThread, (void *) connect) != 0)
00094 {
00095 CL_CTPRINTF("%s %s: ", __FILE__, __FUNCTION__);
00096 perror("Could not create thread\n");
00097 }
00098
00099 timed_ids_init();
00100 }
00101
00102 pid_t erConnectPid(void)
00103 {
00104 return g_connect_pid;
00105 }
00106
00107
00108
00109 static void *connectThread(void *arg)
00110 {
00111 connectStruct_t *connect = (connectStruct_t *) arg;
00112 struct timeval tv_kill, tv;
00113 unsigned int stop = 0;
00114 unsigned int first = 1;
00115
00116 CL_CTPRINTF("enter");
00117
00118 pthread_mutex_lock( &(connect->mutex) );
00119
00120 CL_CTPRINTF("enter active part");
00121
00122 timerclear(&tv_kill);
00123 timerclear(&tv);
00124
00125 while (1)
00126 {
00127 switch (connect->state)
00128 {
00129 case connectStateIdle:
00130 {
00131 if (connect->command == connectCmdStart)
00132 {
00133 CL_CTPRINTF("connectCmdStart");
00134 connect->command = connectCmdNone;
00135
00136 switch (g_connect_pid = fork())
00137 {
00138 case 0:
00139 {
00140
00141 int nRet;
00142
00143 CL_WARNPRINTF("Calling: [%s]", connect->szCommand);
00144 nRet = shell_exec(connect->szCommand);
00145 CL_ERRORPRINTF("shell_exec of [%s] failed (returned [%d]), "
00146 "cleaning up child\n", connect->szCommand, nRet);
00147 perror("Error upon calling shell_exec");
00148 fflush(stderr);
00149 exit(1);
00150 break;
00151 }
00152
00153 case -1:
00154
00155 CL_ERRORPRINTF("Can't fork");
00156 connect->state = connectStateDisconnected;
00157 break;
00158
00159 default:
00160
00161 connect->state = connectStateConnected;
00162 }
00163 }
00164 else if (connect->command == connectCmdNone)
00165 {
00166
00167 CL_CTPRINTF("connectCmdNone");
00168 pthread_mutex_lock( &(connect->mutex) );
00169
00170 stop = 0;
00171 first = 1;
00172
00173 timerclear(&tv_kill);
00174 timerclear(&tv);
00175 }
00176 else
00177 {
00178 CL_ERRORPRINTF("unexpected connectCmd [%d]", connect->command);
00179 connect->command = connectCmdNone;
00180 }
00181 break;
00182 }
00183
00184 case connectStateConnected:
00185 {
00186 pid_t retPid;
00187 int status;
00188
00189 if (connect->command == connectCmdStop)
00190 {
00191 CL_CTPRINTF("connectCmdStop: pid [%d]", g_connect_pid);
00192 connect->command = connectCmdNone;
00193
00194 if (kill(g_connect_pid, SIGTERM) == -1)
00195 {
00196 CL_ERRORPRINTF("Failed to stop downloadMgr");
00197 perror("Error in kill");
00198 connect->state = connectStateDisconnected;
00199 }
00200
00201 gettimeofday(&tv_kill, NULL);
00202
00203 stop = 1;
00204
00205 break;
00206 }
00207
00208
00209 retPid = waitpid(g_connect_pid, &status, WNOHANG);
00210 if (retPid == 0)
00211 {
00212 CL_CTPRINTF("connectionMgr alive");
00213
00214 unsigned int kill_force = 0;
00215
00216 if (stop)
00217 {
00218 gettimeofday(&tv, NULL);
00219 suseconds_t time_diff = ((tv.tv_sec - tv_kill.tv_sec) * 1000 * 1000) + (tv.tv_usec - tv_kill.tv_usec);
00220 if (time_diff > KILL_TIMEOUT) { kill_force = 1; }
00221 CL_CTPRINTF("elapsed %d suseconds_t", (int)time_diff);
00222 }
00223
00224 if (first && kill_force)
00225 {
00226
00227 CL_CTPRINTF("Sending 'SIGKILL' to stop connectionMgr.");
00228
00229 first = 0;
00230 if (kill(g_connect_pid, SIGKILL) == -1)
00231 {
00232 CL_ERRORPRINTF("Failed to kill -9 connectionMgr");
00233 perror("Error in kill");
00234 connect->state = connectStateDisconnected;
00235 }
00236 }
00237 else
00238 {
00239
00240 CL_CTPRINTF("check again later");
00241 sleep(1);
00242 }
00243 }
00244 else
00245 {
00246
00247 connect->state = connectStateDisconnected;
00248 }
00249 break;
00250 }
00251
00252 case connectStateDisconnected:
00253 {
00254 CL_CTPRINTF( "connectStateDisconnected: background [%d] after_reboot [%d] screen [%d]",
00255 connect->background, connect->connect_after_reboot, connect->screen );
00256 connect->state = connectStateIdle;
00257
00258 gdk_threads_enter();
00259 ctrl_cleanup_download_history();
00260 ctrl_background_connect_timeout_start(FALSE);
00261 ctrl_set_connect_icon();
00262 if ( connect->background )
00263 {
00264 if (getListerState() != STATE_PINCODE)
00265 {
00266 erStartMSDiskApp();
00267 }
00268 toolbar_synchronise();
00269 }
00270 else
00271 {
00272 if (connect->connect_after_reboot)
00273 {
00274 setListerState(STATE_NORMAL);
00275 pm_setUaOnTop(CONTENTLISTER_UAID);
00276 toolbar_restore();
00277 ctrl_startup();
00278 }
00279 else if (connect->connect_from_pincode)
00280 {
00281
00282
00283
00284 ctrl_connect_back_to_pincode_screen();
00285 }
00286 else
00287 {
00288 setListerState(STATE_NORMAL);
00289 erStartMSDiskApp();
00290 toolbar_restore();
00291
00292 switch (connect->screen)
00293 {
00294 case connectScrUnchanged:
00295 CL_CTPRINTF("connectScrUnchanged");
00296 pm_setUaOnTop(CONTENTLISTER_UAID);
00297 break;
00298 case connectScrMode:
00299 ctrl_mode_button_clicked();
00300 break;
00301 case connectScrNews:
00302 ctrl_contentType_button_clicked(st_ContentTypeNews);
00303 break;
00304 case connectScrBooks:
00305 ctrl_contentType_button_clicked(st_ContentTypeBooks);
00306 break;
00307 case connectScrDocs:
00308 ctrl_contentType_button_clicked(st_ContentTypeDocs);
00309 break;
00310 case connectScrNotes:
00311 ctrl_contentType_button_clicked(st_ContentTypeNotes);
00312 break;
00313 default:
00314 ctrl_display_download_history();
00315 break;
00316 }
00317 }
00318 }
00319 gdk_threads_leave();
00320 break;
00321 }
00322
00323 default:
00324 {
00325 CL_CTPRINTF("unexpected state [%d]", connect->state);
00326 connect->state = connectStateIdle;
00327 }
00328 }
00329 }
00330
00331 pthread_exit(NULL);
00332 }
00333