Ejemplo n.º 1
0
void act_CLOSE(void)
{
    if (acctlog && (acctfp = fopen(acctlog,"a")) != NULL) {
        int duration = -call_start_time;
        char *tm;
        tm = cdate();
        duration += call_start_time;
        fprintf(acctfp,"%s: Disconnected. Call duration %d seconds.\n",
                tm,duration);
        fprintf(acctfp,"      IP transmitted %d bytes and received %d bytes.\n",
                txtotal,rxtotal);
        fclose(acctfp);
    }
    close_modem();
    interface_down();
    if (no_redial_delay == 0) {
        if (redial_rtimeout == -1)
            redial_rtimeout = redial_timeout;
        syslog(LOG_INFO,"Delaying %d seconds before clear to dial.",
               redial_rtimeout);
        state_timeout = redial_rtimeout;
    } else if (no_redial_delay == 2) {
        syslog(LOG_INFO,"Delaying %d seconds before clear to dial.",
               nodev_retry_timeout);
        state_timeout = nodev_retry_timeout;
    }
}
void* pppd_thread(void *param)
{
    LOGD("%s: pppd_thread enter", logtime());
    
    requestsWaitComplete("pppd_thread");
    
    pppd_pid = fork();
    if(pppd_pid == 0) {
        
        char buff[256];
        kill(getppid(), SIGSTOP); //stop stealing my mojo 
        
        int act=0;
        
        send_modem("AT+CGACT?");
        do {
            read_modem(buff, sizeof(buff));
            char* actpos=strstr(buff, "+CGACT: 1,");
            if(actpos!=NULL) act=atoi(actpos+10);
        }while(buff[0]!='0');
        
        if(act!=0) {
            kill(getppid(), SIGCONT);
            exit(202);
        }

        sprintf(buff, "AT+CGDCONT=1,\"IP\",\"%s\",,0,0", current_apn);
        send_modem(buff);
        read_modem(buff, sizeof(buff));
        
        send_modem("ATD*99***1#");
        //send_modem("AT+CGDATA=\"PPP\",1");
        while(read_modem(buff, sizeof(buff))>0 && buff[0]=='+');
        //read_modem(buff, sizeof(buff));
        
        kill(getppid(), SIGCONT);

        int atd=atoi(buff);
        if(atd!=1 && atd!=3) exit(201); 

        sleep(1);

        close_modem(); //close modem handle before we transform to pppd
        int err = execl("/system/bin/pppd", "pppd", "/dev/smd1", "local","nodetach", "defaultroute", "noipdefault", "usepeerdns", "user", current_user, "debug", NULL);
        LOGE("%s: PPPD EXEC FAILED (%d)", logtime(),err);
        exit(200);
    } else {
        LOGD("%s: pppd pid is %d", logtime(),pppd_pid);
        
        int status=0;
        time_t start = time(NULL);
        waitpid(pppd_pid, &status, 0);
        pppd_pid=0;
        int runTime = time(NULL)-start;
        LOGD("%s: PPPD DIED after %d seconds with status %d", logtime(), runTime, status);
        
        if(lastDataError==PDP_FAIL_ERROR_UNSPECIFIED && WIFEXITED(status)){
            switch(WEXITSTATUS(status))
            {
                case 1: lastDataError=PDP_FAIL_INSUFFICIENT_RESOURCES; break;
                case 2: lastDataError=PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED; break;
                case 3: 
                case 4:
                    lastDataError=PDP_FAIL_PROTOCOL_ERRORS; break;
                case 19: lastDataError=PDP_FAIL_USER_AUTHENTICATION; break;
            }
        }
        
        requestsWaitComplete("pppd_thread");
        send_modem("AT+CGACT=0,1"); 
        
        if(dataConnectionState==DATA_STATE_CONNECTED || dataConnectionState==DATA_STATE_CONNECTION_KILL) {
            dataConnectionState=DATA_STATE_DISCONNECTED;
            RIL_Data_Call_Response dataCall={ .cid=1, .active=0, .type="IP", .apn=current_apn, .address=current_addr };
            s_rilenv->OnUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, &dataCall, sizeof(RIL_Data_Call_Response));
        }
    }

    LOGD("%s: pppd_thread exit", logtime());
    return NULL;
}