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; }