Example #1
0
void at_cmd(hd_data_t *hd_data, char *at, int raw, int log_it)
{
  static unsigned u = 1;
  char *s, *s0;
  ser_device_t *sm;
  str_list_t *sl;
  int modems = 0;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      sm->buf_len = 0;
      modems++;
    }
  }

  if(modems == 0) return;

  PROGRESS(9, u, "write at cmd");
  write_modem(hd_data, at);
  PROGRESS(9, u, "read at resp");
  usleep (200000);
  read_modem(hd_data);
  PROGRESS(9, u, "read ok");
  u++;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      sm->at_resp = free_str_list(sm->at_resp);
      if(sm->buf_len == 0 || raw) continue;
      s0 = sm->buf;
      while((s = strsep(&s0, "\r\n"))) {
        if(*s) add_str_list(&sm->at_resp, s);
      }
    }
  }

  if(!(hd_data->debug & HD_DEB_MODEM) || !log_it) return;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      ADD2LOG("%s@%u: %s\n", sm->dev_name, sm->cur_baud, at);
      if(raw) {
        ADD2LOG("  ");
        hexdump(&hd_data->log, 1, sm->buf_len, sm->buf);
        ADD2LOG("\n");
      }
      else {
        for(sl = sm->at_resp; sl; sl = sl->next) ADD2LOG("  %s\n", sl->str);
      }
    }
  }
}
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;
}