static gn_error presskey(gn_data *data, struct gn_statemachine *state) { gn_error error; error = gn_sm_functions(GN_OP_PressPhoneKey, data, state); if (error == GN_ERR_NONE) error = gn_sm_functions(GN_OP_ReleasePhoneKey, data, state); if (error != GN_ERR_NONE) fprintf(stderr, _("Failed to press key: %s\n"), gn_error_print(error)); return error; }
static void gn_atem_answer_phone(void) { /* For now we'll also initialise the datapump + rlp code again */ dp_Initialise(PtyRDFD, PtyWRFD); data.call_notification = dp_CallPassup; gn_sm_functions(GN_OP_SetCallNotification, &data, sm); data.call_info->call_id = IncomingCallNo; gn_sm_functions(GN_OP_AnswerCall, &data, sm); CommandMode = false; }
gn_error getlocksinfo(gn_data *data, struct gn_statemachine *state) { gn_locks_info locks_info[4]; gn_error error; char *locks_names[] = {"MCC+MNC", "GID1", "GID2", "MSIN"}; int i; gn_data_clear(data); data->locks_info = locks_info; if ((error = gn_sm_functions(GN_OP_GetLocksInfo, data, state)) != GN_ERR_NONE) { fprintf(stderr, _("Error: %s\n"), gn_error_print(error)); return error; } for (i = 0; i < 4; i++) { fprintf(stdout, _("%7s : %10s, %7s, %6s, counter %d\n"), locks_names[i], locks_info[i].data, locks_info[i].userlock ? "user" : "factory", locks_info[i].closed ? "CLOSED" : "open", locks_info[i].counter); } return GN_ERR_NONE; }
// refinement of this function needed..into the TODO list static VALUE gn_lib_get_phone_information(void) { gn_data *data = &state->sm_data; const char *unknown = _("Unknown"); gn_error error; gn_data_clear(data); data->model = state->config.m_model; data->manufacturer = state->config.m_manufacturer; data->revision = state->config.m_revision; data->imei = state->config.m_imei; error = gn_sm_functions(GN_OP_Identify, data, state); if (!data->model[0]) snprintf(data->model, GN_MODEL_MAX_LENGTH, "%s", unknown); if (!data->manufacturer[0]) snprintf(data->manufacturer, GN_MANUFACTURER_MAX_LENGTH, "%s", unknown); if (!data->revision[0]) snprintf(data->revision, GN_REVISION_MAX_LENGTH, "%s", unknown); if (!data->imei[0]) snprintf(data->imei, GN_IMEI_MAX_LENGTH, "%s", unknown); printf("\n MODEL = %s \n IMEI = %s \n REVISION = %s\n MANUFACTURER =%s\n",data->model,data->imei,data->revision,data->manufacturer); printf("%d", gn_sms_send(data,state)); return INT2NUM(error); }
/* Parser for DIR sub mode of SMS interactive mode. */ void gn_atem_dir_parse(char *buff) { switch (toupper(*buff)) { case 'P': SMSNumber--; gn_atem_sms_handle(); return; case 'N': SMSNumber++; gn_atem_sms_handle(); return; case 'D': data.sms->memory_type = SMSType; data.sms->number = SMSNumber; if (gn_sm_functions(GN_OP_DeleteSMS, &data, sm) == GN_ERR_NONE) { gn_atem_modem_result(MR_OK); } else { gn_atem_modem_result(MR_ERROR); } return; case 'Q': Parser= gn_atem_sms_parse; gn_atem_modem_result(MR_OK); return; } gn_atem_modem_result(MR_ERROR); }
gn_error enterchar(gn_data *data, struct gn_statemachine *state) { unsigned char ch; gn_error error = GN_ERR_NONE; gn_data_clear(data); console_raw(); while ((error = GN_ERR_NONE) && (read(0, &ch, 1) > 0)) { switch (ch) { case '\r': break; case '\n': data->key_code = GN_KEY_MENU; presskey(data, state); break; #ifdef WIN32 case '\033': #else case '\e': #endif data->key_code = GN_KEY_NAMES; presskey(data, state); break; default: data->character = ch; error = gn_sm_functions(GN_OP_EnterChar, data, state); if (error != GN_ERR_NONE) fprintf(stderr, _("Error entering char: %s\n"), gn_error_print(error)); break; } } return error; }
gboolean libgnokii_signal_info_api(pegang *unit) { gn_data data; gn_error error; //prepare a place on memory gn_data_clear(&data); //sinyalling //paramter requirement of GN_OP_GetRFLevel printf("initiating get antena sinyal...\n"); gn_rf_unit rfunit = GN_RF_Percentage; float rflevel; data.rf_unit = &rfunit; data.rf_level = &rflevel; if((error = gn_sm_functions(GN_OP_GetRFLevel, &data, state)) == GN_ERR_NONE) { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(unit->info_dialog_main->progressbar_sinyal),(float)rflevel/100); printf("sinyal = %f\n",(float)rflevel/100); return TRUE; } else { down(unit); return FALSE; } }
/* Writes profiles to phone */ gn_error setprofile(gn_data *data, struct gn_statemachine *state) { int n; gn_profile p; gn_error error = GN_ERR_NONE; char line[256], ch; gn_data_clear(data); data->profile = &p; while (fgets(line, sizeof(line), stdin)) { n = strlen(line); if (n > 0 && line[n-1] == '\n') { line[--n] = 0; } n = sscanf(line, "%d;%39[^;];%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d%c", &p.number, p.name, &p.default_name, &p.keypad_tone, &p.lights, &p.call_alert, &p.ringtone, &p.volume, &p.message_tone, &p.vibration, &p.warning_tone, &p.caller_groups, &p.automatic_answer, &ch); if (n != 13) { fprintf(stderr, _("Input line format isn't valid\n")); return GN_ERR_WRONGDATAFORMAT; } error = gn_sm_functions(GN_OP_SetProfile, data, state); if (error != GN_ERR_NONE) { fprintf(stderr, _("Cannot set profile: %s\n"), gn_error_print(error)); return error; } } return error; }
gn_error deleteringtone(int argc, char *argv[], gn_data *data, struct gn_statemachine *state) { gn_ringtone ringtone; gn_error error; int i, start, end; memset(&ringtone, 0, sizeof(ringtone)); gn_data_clear(data); data->ringtone = &ringtone; start = gnokii_atoi(optarg); if (errno || start < 0) return deleteringtone_usage(stderr, -1); end = parse_end_value_option(argc, argv, optind, start); if (errno || end < 0) return deleteringtone_usage(stderr, -1); for (i = start; i <= end; i++) { ringtone.location = i; if ((error = gn_sm_functions(GN_OP_DeleteRingtone, data, state)) == GN_ERR_NONE) fprintf(stderr, _("Ringtone %d deleted\n"), i); else fprintf(stderr, _("Failed to delete ringtone %d: %s\n"), i, gn_error_print(error)); } return GN_ERR_NONE; }
// get number of entries in this phone memory type (internal/SIM-card) static gn_error read_phone_memstat( gn_memory_type memtype, gn_memory_status *memstat ) { gn_error error; gn_data_clear(&data); memset(memstat, 0, sizeof(*memstat)); memstat->memory_type = memtype; data.memory_status = memstat; error = gn_sm_functions(GN_OP_GetMemoryStatus, &data, &state); GNOKII_CHECK_ERROR(error); if (error != GN_ERR_NONE) { switch (memtype) { case GN_MT_SM: // use at least 100 entries memstat->used = 0; memstat->free = 100; break; default: case GN_MT_ME: // Phone doesn't support ME (5110) memstat->used = memstat->free = 0; break; } } GNOKII_DEBUG( QString("\n\nMobile phone memory status: Type: %1, used=%2, free=%3, total=%4\n\n") .arg(memtype).arg(memstat->used).arg(memstat->free).arg(memstat->used+memstat->free) ); return error; }
/* If initialised in debug mode, stdin/out is used instead of ptys for interface. */ bool gn_atem_initialise(int read_fd, int write_fd, struct gn_statemachine *vmsm) { PtyRDFD = read_fd; PtyWRFD = write_fd; gn_data_clear(&data); memset(&sms, 0, sizeof(sms)); memset(&callinfo, 0, sizeof(callinfo)); data.sms = &sms; data.call_info = &callinfo; data.manufacturer = manufacturer; data.model = model; data.revision = revision; data.imei = imei; sm = vmsm; /* Initialise command buffer variables */ CurrentCmdBuffer = 0; CurrentCmdBufferIndex = 0; /* Initialise registers */ gn_atem_registers_init(); /* Initial parser is AT routine */ Parser = gn_atem_at_parse; /* Setup defaults for AT*C interpreter. */ SMSNumber = 1; SMSType = GN_MT_ME; /* Default message format is PDU */ MessageFormat = PDU_MODE; /* Set the call passup so that we get notified of incoming calls */ data.call_notification = gn_atem_call_passup; gn_sm_functions(GN_OP_SetCallNotification, &data, sm); /* query model, revision and imei */ if (gn_sm_functions(GN_OP_Identify, &data, sm) != GN_ERR_NONE) return false; /* We're ready to roll... */ gn_atem_initialised = true; return (true); }
// read phone entry #index from memory #memtype static gn_error read_phone_entry( int index, gn_memory_type memtype, gn_phonebook_entry *entry ) { gn_error error; entry->memory_type = memtype; entry->location = index; data.phonebook_entry = entry; error = gn_sm_functions(GN_OP_ReadPhonebook, &data, &state); GNOKII_CHECK_ERROR(error); return error; }
static int ping(gn_data *data, struct gn_statemachine *state) { gn_error err; err = gn_sm_functions(GN_OP_Ping, data, state); if (err == GN_ERR_NONE) fprintf(stdout, _("Device responded OK.\n")); else fprintf(stdout, _("Device did not respond.\n")); return err; }
/* Application should call gn_vm_terminate to shut down the virtual modem thread */ void gn_vm_terminate(void) { /* Request termination of thread */ GTerminateThread = true; close (PtyRDFD); close (PtyWRFD); /* Shutdown device */ gn_sm_functions(GN_OP_Terminate, NULL, sm); }
gn_error sendringtone(int argc, char *argv[], gn_data *data, struct gn_statemachine *state) { gn_sms sms; gn_error error = GN_ERR_NOTSUPPORTED; gn_sms_default_submit(&sms); sms.user_data[0].type = GN_SMS_DATA_Ringtone; sms.user_data[1].type = GN_SMS_DATA_None; if ((error = gn_file_ringtone_read(optarg, &sms.user_data[0].u.ringtone))) { fprintf(stderr, _("Failed to load ringtone: %s\n"), gn_error_print(error)); return error; } /* The second argument is the destination, ie the phone number of recipient. */ snprintf(sms.remote.number, sizeof(sms.remote.number) - 1, "%s", argv[optind]); if (sms.remote.number[0] == '+') sms.remote.type = GN_GSM_NUMBER_International; else sms.remote.type = GN_GSM_NUMBER_Unknown; /* Get the SMS Center */ if (!sms.smsc.number[0]) { data->message_center = calloc(1, sizeof(gn_sms_message_center)); data->message_center->id = 1; if (gn_sm_functions(GN_OP_GetSMSCenter, data, state) == GN_ERR_NONE) { snprintf(sms.smsc.number, sizeof(sms.smsc.number), "%s", data->message_center->smsc.number); sms.smsc.type = data->message_center->smsc.type; } free(data->message_center); } if (!sms.smsc.type) sms.smsc.type = GN_GSM_NUMBER_Unknown; /* Send the message. */ data->sms = &sms; error = gn_sms_send(data, state); if (error == GN_ERR_NONE) { if (sms.parts > 1) { int j; fprintf(stderr, _("Message sent in %d parts with reference numbers:"), sms.parts); for (j = 0; j < sms.parts; j++) fprintf(stderr, " %d", sms.reference[j]); fprintf(stderr, "\n"); } else fprintf(stderr, _("Send succeeded with reference %d!\n"), sms.reference[0]); } else fprintf(stderr, _("SMS Send failed (%s)\n"), gn_error_print(error)); return error; }
static void gn_atem_hangup_phone(void) { if (IncomingCallNo > 0) { rlp_user_request_set(Disc_Req, true); gn_sm_loop(10, sm); } if (IncomingCallNo > 0) { data.call_info->call_id = IncomingCallNo; gn_sm_functions(GN_OP_CancelCall, &data, sm); IncomingCallNo = -1; } dp_Initialise(PtyRDFD, PtyWRFD); }
/* Deleting all ToDo notes */ gn_error deletealltodos(gn_data *data, struct gn_statemachine *state) { gn_error error; gn_data_clear(data); error = gn_sm_functions(GN_OP_DeleteAllToDos, data, state); if (error == GN_ERR_NONE) fprintf(stderr, _("Successfully deleted all ToDo notes!\n")); else fprintf(stderr, _("Failed to delete ToDo note: %s\n"), gn_error_print(error)); return error; }
/* Queries the active profile */ gn_error getactiveprofile(gn_data *data, struct gn_statemachine *state) { gn_profile p; gn_error error; gn_data_clear(data); data->profile = &p; error = gn_sm_functions(GN_OP_GetActiveProfile, data, state); if (error != GN_ERR_NONE) { fprintf(stderr, _("Cannot get active profile: %s\n"), gn_error_print(error)); return error; } error = gn_sm_functions(GN_OP_GetProfile, data, state); if (error != GN_ERR_NONE) fprintf(stderr, _("Cannot get profile %d\n"), p.number); else fprintf(stdout, _("Active profile: %d (%s)\n"), p.number, p.name); return error; }
static bool gn_atem_cops_set(char **buf, struct gn_atem_op *op, char *val) { data.network_change_notification = gn_atem_network_msg; /* Syntax is <mode>[,<format>[,<oper>]] */ switch (gn_atem_num_get(buf)) { /* Parse <mode> */ case 0: case 1: case 4: if (gn_sm_functions(GN_OP_NetworkRegister, &data, sm) != GN_ERR_NONE) break; return (false); case 2: if (gn_sm_functions(GN_OP_NetworkUnregister, &data, sm) != GN_ERR_NONE) break; return (false); case 3: /* Only sets <format>, TODO */ return (false); } return (true); }
/* Select the specified profile */ gn_error setactiveprofile(int argc, char *argv[], gn_data *data, struct gn_statemachine *state) { gn_profile p; gn_error error; gn_data_clear(data); data->profile = &p; p.number = gnokii_atoi(optarg); if (errno || p.number < 0) return setactiveprofile_usage(stderr, -1); error = gn_sm_functions(GN_OP_SetActiveProfile, data, state); if (error != GN_ERR_NONE) fprintf(stderr, _("Cannot set active profile to %d: %s\n"), p.number, gn_error_print(error)); return error; }
gn_error changesecuritycode(char *type, gn_data *data, struct gn_statemachine *state) { gn_error error; gn_security_code security_code; char newcode2[10]; memset(&security_code, 0, sizeof(security_code)); if (!strcmp(type, "PIN")) security_code.type = GN_SCT_Pin; else if (!strcmp(type, "PUK")) security_code.type = GN_SCT_Puk; else if (!strcmp(type, "PIN2")) security_code.type = GN_SCT_Pin2; else if (!strcmp(type, "PUK2")) security_code.type = GN_SCT_Puk2; /* FIXME: Entering of security_code does not work :-( else if (!strcmp(type, "security_code")) security_code.type = GN_SCT_security_code; */ else return changesecuritycode_usage(stderr, -1); get_password(_("Enter your code: "), security_code.code, sizeof(security_code.code)); get_password(_("Enter new code: "), security_code.new_code, sizeof(security_code.new_code)); get_password(_("Retype new code: "), newcode2, sizeof(newcode2)); if (strcmp(security_code.new_code, newcode2)) { fprintf(stderr, _("Error: new code differs\n")); return GN_ERR_FAILED; } gn_data_clear(data); data->security_code = &security_code; error = gn_sm_functions(GN_OP_ChangeSecurityCode, data, state); switch (error) { case GN_ERR_NONE: fprintf(stderr, _("Code changed.\n")); break; default: fprintf(stderr, _("Error: %s\n"), gn_error_print(error)); break; } return error; }
static void gn_atem_signal_quality(struct gn_statemachine *state) { float rflevel = -1; gn_rf_unit rfunits = GN_RF_CSQ; char buffer[MAX_LINE_LENGTH]; if (!data.csq) return; data.rf_unit = &rfunits; data.rf_level = &rflevel; if (gn_sm_functions(GN_OP_GetRFLevel, &data, sm) == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "%%CSQ: %.f, 99, 2\r\n", *(data.rf_level)); gn_atem_string_out(buffer); } }
gn_error getsecuritycode(gn_data *data, struct gn_statemachine *state) { gn_error error; gn_security_code sc; memset(&sc, 0, sizeof(sc)); sc.type = GN_SCT_SecurityCode; data->security_code = ≻ fprintf(stderr, _("Getting security code... \n")); error = gn_sm_functions(GN_OP_GetSecurityCode, data, state); switch (error) { case GN_ERR_NONE: fprintf(stdout, _("Security code is: %s\n"), sc.code); break; default: fprintf(stderr, _("Error: %s\n"), gn_error_print(error)); break; } return error; }
int KMobileGnokii::numCalendarEntries() { gn_data_clear(&data); gn_calnote entry; memset(&entry, 0, sizeof(entry)); data.calnote = &entry; entry.location = 1; data.calnote_list = &calnote_list; gn_error error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state); switch (error) { case GN_ERR_NONE: case GN_ERR_INVALIDLOCATION: case GN_ERR_EMPTYLOCATION: return calnote_list.number; default: GNOKII_CHECK_ERROR(error); return 0; } }
static void init_ringtone_list(gn_data *data, struct gn_statemachine *state) { gn_error error; if (ringtone_list_initialised) return; memset(&ringtone_list, 0, sizeof(ringtone_list)); data->ringtone_list = &ringtone_list; error = gn_sm_functions(GN_OP_GetRingtoneList, data, state); data->ringtone_list = NULL; if (error != GN_ERR_NONE) { ringtone_list.count = 0; ringtone_list.userdef_location = 0; ringtone_list.userdef_count = 0; ringtone_list_initialised = -1; } else ringtone_list_initialised = 1; }
gn_error getsecuritycodestatus(gn_data *data, struct gn_statemachine *state) { gn_security_code security_code; gn_error err; gn_data_clear(data); data->security_code = &security_code; err = gn_sm_functions(GN_OP_GetSecurityCodeStatus, data, state); if (err == GN_ERR_NONE) { fprintf(stdout, _("Security code status: ")); switch(security_code.type) { case GN_SCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break; case GN_SCT_Pin: fprintf(stdout, _("waiting for PIN.\n")); break; case GN_SCT_Pin2: fprintf(stdout, _("waiting for PIN2.\n")); break; case GN_SCT_Puk: fprintf(stdout, _("waiting for PUK.\n")); break; case GN_SCT_Puk2: fprintf(stdout, _("waiting for PUK2.\n")); break; case GN_SCT_None: fprintf(stdout, _("nothing to enter.\n")); break; default: fprintf(stdout, _("unknown\n")); break; } } else fprintf(stderr, _("Error: %s\n"), gn_error_print(err)); return err; }
/* In this mode we get the code from the keyboard and send it to the mobile phone. */ gn_error entersecuritycode(char *type, gn_data *data, struct gn_statemachine *state) { gn_error error; gn_security_code security_code; if (!strcmp(type, "PIN")) security_code.type = GN_SCT_Pin; else if (!strcmp(type, "PUK")) security_code.type = GN_SCT_Puk; else if (!strcmp(type, "PIN2")) security_code.type = GN_SCT_Pin2; else if (!strcmp(type, "PUK2")) security_code.type = GN_SCT_Puk2; else if (!strcmp(type, "SEC")) security_code.type = GN_SCT_SecurityCode; else return entersecuritycode_usage(stderr, -1); memset(&security_code.code, 0, sizeof(security_code.code)); get_password(_("Enter your code: "), security_code.code, sizeof(security_code.code)); gn_data_clear(data); data->security_code = &security_code; error = gn_sm_functions(GN_OP_EnterSecurityCode, data, state); switch (error) { case GN_ERR_NONE: fprintf(stderr, _("Code ok.\n")); break; default: fprintf(stderr, _("Error: %s\n"), gn_error_print(error)); break; } return error; }
gn_error getnetworkinfo(gn_data *data, struct gn_statemachine *state) { gn_network_info networkinfo; gn_error error; int lac, cid; char country[4] = {0, 0, 0, 0}; gn_data_clear(data); memset(&networkinfo, 0, sizeof(networkinfo)); data->network_info = &networkinfo; state->callbacks.reg_notification = NULL; data->callback_data = NULL; if ((error = gn_sm_functions(GN_OP_GetNetworkInfo, data, state)) != GN_ERR_NONE) { fprintf(stderr, _("Error: %s\n"), gn_error_print(error)); return error; } /* Ugly, ugly, ... */ if (networkinfo.cell_id[2] == 0 && networkinfo.cell_id[3] == 0) cid = (networkinfo.cell_id[0] << 8) + networkinfo.cell_id[1]; else cid = (networkinfo.cell_id[0] << 24) + (networkinfo.cell_id[1] << 16) + (networkinfo.cell_id[2] << 8) + networkinfo.cell_id[3]; lac = (networkinfo.LAC[0] << 8) + networkinfo.LAC[1]; memcpy(country, networkinfo.network_code, 3); fprintf(stdout, _("Network : %s (%s)\n"), gn_network_name_get((char *)networkinfo.network_code), gn_country_name_get((char *)country)); fprintf(stdout, _("Network code : %s\n"), (*networkinfo.network_code ? networkinfo.network_code : _("undefined"))); fprintf(stdout, _("LAC : %04x (%d)\n"), lac, lac); fprintf(stdout, _("Cell id : %08x (%d)\n"), cid, cid); return GN_ERR_NONE; }
gn_error do_auth(gn_auth_type auth_type, struct gn_statemachine *state) { gn_error err; gn_data *data; gn_security_code sc; data = calloc(1, sizeof(gn_data)); data->security_code = ≻ err = gn_sm_functions(GN_OP_GetSecurityCodeStatus, data, state); /* GN_ERR_SIMPROBLEM can be returned in the following cases: * - CME ERROR: 10 - SIM not inserted * - CME ERROR: 13 - SIM failure * - CME ERROR: 15 - SIM wrong * We should ignore these situations. If there is an real error the * next command will detect it anyway. But if it is just SIM not * inserted (we cannot distinguish here between these three * situations), gnokii is still usable. */ if (err != GN_ERR_NONE) { if (err == GN_ERR_SIMPROBLEM) err = GN_ERR_NONE; goto out; } switch (sc.type) { case GN_SCT_SecurityCode: case GN_SCT_Pin: case GN_SCT_Pin2: case GN_SCT_Puk: case GN_SCT_Puk2: break; case GN_SCT_None: /* err is GN_ERR_NONE but this is to make it explicit */ err = GN_ERR_NONE; goto out; default: err = GN_ERR_NOTSUPPORTED; goto out; } switch (auth_type) { case GN_AUTH_TYPE_TEXT: err = auth_pin(auth_type, data, state); break; case GN_AUTH_TYPE_INTERACTIVE: case GN_AUTH_TYPE_NONINTERACTIVE: if (!state->callbacks.auth_interactive) err = auth_pin(auth_type, data, state); else err = state->callbacks.auth_interactive(data, state); break; case GN_AUTH_TYPE_NONE: case GN_AUTH_TYPE_BINARY: err = GN_ERR_NONE; break; default: err = GN_ERR_NOTSUPPORTED; break; } if (err == GN_ERR_NONE) err = gn_sm_functions(GN_OP_EnterSecurityCode, data, state); out: free(data); return err; }
gn_error playringtone(int argc, char *argv[], gn_data *data, struct gn_statemachine *state) { gn_ringtone ringtone; gn_tone tone; gn_error error; char *filename = optarg; int i, ulen; struct timeval dt; #if (defined HAVE_TIMEOPS) && (defined HAVE_GETTIMEOFDAY) struct timeval t1, t2; #endif int volume = 5; struct option options[] = { { "volume", required_argument, NULL, 'v'}, { NULL, 0, NULL, 0} }; while ((i = getopt_long(argc, argv, "v:", options, NULL)) != -1) { switch (i) { case 'v': volume = gnokii_atoi(optarg); if (errno || volume < 0) return playringtone_usage(stderr, -1); break; default: return playringtone_usage(stderr, -1); } } if (argc > optind) { /* There are too many arguments that don't start with '-' */ return playringtone_usage(stderr, -1); } memset(&ringtone, 0, sizeof(ringtone)); memset(&tone, 0, sizeof(tone)); gn_data_clear(data); data->ringtone = &ringtone; data->tone = &tone; if (!filename) { fprintf(stderr, _("Internal gnokii error: null filename\n")); return GN_ERR_FAILED; } if ((error = gn_file_ringtone_read(filename, &ringtone))) { fprintf(stderr, _("Failed to load ringtone: %s\n"), gn_error_print(error)); return error; } #if (defined HAVE_TIMEOPS) && (defined HAVE_GETTIMEOFDAY) gettimeofday(&t1, NULL); tone.frequency = 0; tone.volume = 0; gn_sm_functions(GN_OP_PlayTone, data, state); gettimeofday(&t2, NULL); timersub(&t2, &t1, &dt); #else dt.tv_sec = 0; dt.tv_usec = 20000; #endif signal(SIGINT, interrupted); for (i = 0; !bshutdown && i < ringtone.notes_count; i++) { tone.volume = volume; gn_ringtone_get_tone(&ringtone, i, &tone.frequency, &ulen); if ((error = gn_sm_functions(GN_OP_PlayTone, data, state)) != GN_ERR_NONE) break; if (ulen > 2 * dt.tv_usec + 20000) usleep(ulen - 2 * dt.tv_usec - 20000); tone.volume = 0; if ((error = gn_sm_functions(GN_OP_PlayTone, data, state)) != GN_ERR_NONE) break; usleep(20000); } tone.frequency = 0; tone.volume = 0; gn_sm_functions(GN_OP_PlayTone, data, state); if (error == GN_ERR_NONE) fprintf(stderr, _("Play succeeded!\n")); else fprintf(stderr, _("Play failed: %s\n"), gn_error_print(error)); return error; }