GSM-Gnokii
view release on metacpan or search on metacpan
fi->year, fi->month, fi->day, fi->hour, fi->minute, fi->second);
hv_puts (f, "date", date);
hv_puti (f, "size", fi->file_length);
hv_puti (f, "folder_id", fi->folderId);
hv_puts (f, "file", fi->file);
snprintf (full_name, 512, "%s\\%s", path, fi->name);
if (*(fi->name)) {
gn_file ff;
clear_data ();
Zero (&ff, 1, ff);
strcpy (ff.name, full_name);
data->file = &ff;
if (gn_sm_func (self, GN_OP_GetFileId)) {
char buf[24];
sprintf (buf, "%02x.%02x.%02x.%02x.%02x.%02x",
ff.id[0], ff.id[1], ff.id[2], ff.id[3], ff.id[4], ff.id[5]);
hv_puts (f, "id", buf);
}
}
if (fi->file_length == 0 && *(fi->name)) { /* dir ? */
gn_file_list dl;
clear_data ();
Zero (&dl, 1, dl);
sprintf (dl.path, "%s\\*", full_name);
data->file_list = &dl;
if (gn_sm_func (self, GN_OP_GetFileList) && dl.file_count > 0) {
hv_puts (f, "path", full_name);
hv_puti (f, "file_count", dl.file_count);
hv_puti (f, "dir_size", dl.size);
if (depth > 0)
hv_putr (f, "tree", walk_tree (self, full_name, &dl, depth - 1));
}
}
free (fi);
av_addr (t, f);
}
return (t);
} /* walk_tree */
MODULE = GSM::Gnokii PACKAGE = GSM::Gnokii
void
PrintError (self, errno)
HvObject *self;
CODE:
if (opt_v) warn ("PrintError (%d)\n", errno);
warn ("%s\n", gn_error_print (errno));
/* PrintError */
void
_Initialize (self)
HV *self;
PPCODE:
opt_v = SvIV (*hv_fetch (self, "verbose", 7, 0));
if (opt_v) warn ("initialize ({ ... })\n");
unless (gn_lib_init () == GN_ERR_NONE)
croak (_("Failed to initialize libgnokii.\n"));
hv_puts (self, "libgnokii_version", LIBGNOKII_VERSION_STRING);
XSRETURN (0);
/* _Initialise */
void
_Connect (self)
HV *self;
PPCODE:
gn_error err;
if (opt_v) warn ("connect ()\n");
err = gn_lib_phoneprofile_load_from_file (configfile, configmodel, &state);
unless (err == GN_ERR_NONE) {
set_errori (err);
if (configfile)
warn (_("File: %s\n"), configfile);
if (configmodel)
warn (_("Phone section: [phone_%s]\n"), configmodel);
croak ("no profile loaded");
}
if (opt_v) warn ("Phone profile loaded\n");
/* register cleanup function */
atexit (busterminate);
/* signal(SIGINT, bussignal); */
if (opt_v) warn ("Opening phone ...\n");
unless ((err = gn_lib_phone_open (state)) == GN_ERR_NONE) {
set_errori (err);
croak ("connect failed");
}
clear_err ();
data = &state->sm_data;
XS_RETURNi (1);
/* _Connect */
void
disconnect (self)
HvObject *self;
PPCODE:
if (opt_v) warn ("disconnect ()\n");
if (hv_exists (self, "connected", 9)) {
(void)hv_del (self, "connected");
busterminate ();
}
XSRETURN (0);
/* disconnect */
/* ###########################################################################
* Phonebook Functionality
* ###########################################################################
*
* GetPhonebook (memtype, start, end)
* WritePhonebook ({ ... })
* GetSpeedDial (location)
* SetSpeedDial (memtype, location, number)
* DeletePhonebook (); -- TODO
*
* ###########################################################################
*/
void
GetPhonebook (self, memtype, start, end)
HvObject *self;
char *memtype;
int start;
int end;
PPCODE:
gn_phonebook_entry entry;
int mt, i, j;
AV *pb;
if (opt_v) warn ("GetPhonebook (%s, %d, %d)\n", memtype, start, end);
clear_data ();
if (start < 0 || start > 255) {
set_errors ("phonebook location should be in valid range 0..255");
XSRETURN_UNDEF;
}
set_memtype (mt, memtype);
if (end <= 0 || end > 255) {
gn_memory_status ms = {mt, 0, 0};
data->memory_status = &ms;
if (gn_sm_func (self, GN_OP_GetMemoryStatus)) {
end = ms.used + 1;
if (end < start)
end = start;
}
}
pb = newAV ();
data->phonebook_entry = &entry;
for (i = start; i <= end; i++) {
HV *abe = newHV ();
Zero (&entry, 1, entry);
entry.memory_type = mt;
memset (entry.name, ' ', GN_PHONEBOOK_NAME_MAX_LENGTH + 1);
memset (entry.number, ' ', GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1);
if (opt_v > 1) warn ("Reading %s Entry %d\n", memtype, i);
entry.location = i;
entry.caller_group = i;
data->phonebook_entry = &entry;
op_error = gn_sm_functions (GN_OP_ReadPhonebook, data, state);
if (op_error == GN_ERR_NONE && ! entry.empty) {
#ifdef DEBUG_MODULE
printf (
"Name: %s\n"
"Number: %s\n"
"Group: %d\n"
"Location %d\n",
entry.name, entry.number, entry.caller_group,
entry.location);
#endif
hv_puts (abe, "memorytype", memtype);
hv_puti (abe, "location", entry.location);
hv_puts (abe, "number", entry.number);
hv_puts (abe, "name", entry.name);
hv_puts (abe, "caller_group", gn_phonebook_group_type2str (entry.caller_group));
if (entry.person.has_person) {
HV *p = newHV ();
if (entry.person.honorific_prefixes[0])
hv_puts (p, "formal_name", entry.person.honorific_prefixes);
break;
case GN_PHONEBOOK_NUMBER_Work:
hv_puts (abe, "tel_work", entry.subentries[j].data.number);
break;
case GN_PHONEBOOK_NUMBER_None:
if (strcmp (entry.subentries[j].data.number, entry.number))
hv_puts (abe, "tel_none", entry.subentries[j].data.number);
break;
case GN_PHONEBOOK_NUMBER_Common:
hv_puts (abe, "tel_common", entry.subentries[j].data.number);
break;
case GN_PHONEBOOK_NUMBER_General:
hv_puts (abe, "tel_general", entry.subentries[j].data.number);
break;
default:
sprintf (str, "tel_%03d_%03d",
entry.subentries[j].number_type, entry.subentries[j].id);
hv_puts (abe, str, entry.subentries[j].data.number);
break;
}
break;
case GN_PHONEBOOK_ENTRY_URL:
hv_puts (abe, "url", entry.subentries[j].data.number);
break;
case GN_PHONEBOOK_ENTRY_Company:
hv_puts (abe, "company", entry.subentries[j].data.number);
break;
default:
sprintf (str, "item_%04d_%03d_%03d", entry.subentries[j].entry_type,
entry.subentries[j].number_type, entry.subentries[j].id);
hv_puts (abe, str, entry.subentries[j].data.number);
break;
}
}
av_addr (pb, abe);
}
#ifdef DEBUG_MODULE
else
warn ("DEF: %s;%s;%s;%d;%d;%d\n", entry.name, entry.number,
memtype, entry.location, entry.caller_group,
entry.subentries_count);
#endif
}
XS_RETURNr (pb);
/* GetPhonebook */
void
WritePhonebookEntry (self, pbh)
HvObject *self;
HV *pbh;
PPCODE:
gn_error err;
gn_phonebook_entry entry;
int mt, i;
SV **value;
char *str;
STRLEN l;
if (opt_v) warn ("WritePhonebookEntry ({ ... })\n");
unless (hv_gets (pbh, "memorytype", str, l)) {
set_errors ("memorytype is a required attribute in WritePhonebookEntry ()");
XSRETURN_UNDEF;
}
clear_data ();
Zero (&entry, 1, entry);
set_memtype (mt, str);
entry.memory_type = mt;
if (hv_geti (pbh, "location", i)) {
if (i < 0 || i > 255) {
set_errors ("phonebook location should be in valid range 0..255");
XSRETURN_UNDEF;
}
if (i == 0) { /* find first free slot */
for (i = 1; ; i++) {
gn_phonebook_entry aux;
memcpy (&aux, &entry, sizeof (gn_phonebook_entry));
data->phonebook_entry = &aux;
data->phonebook_entry->location = i;
err = gn_sm_functions (GN_OP_ReadPhonebook, data, state);
unless (err == GN_ERR_NONE || err == GN_ERR_EMPTYLOCATION)
break;
if (aux.empty || err == GN_ERR_EMPTYLOCATION) {
i = aux.location;
err = GN_ERR_NONE;
break;
}
}
}
}
else {
gn_memory_status ms = { mt, 0, 0 };
data->memory_status = &ms;
if (gn_sm_func (self, GN_OP_GetMemoryStatus))
i = ms.used + 1;
}
entry.location = i;
memset (entry.number, ' ', GN_PHONEBOOK_NUMBER_MAX_LENGTH + 1);
unless (hv_gets (pbh, "number", str, l)) {
set_errors ("number is a required attribute in WritePhonebookEntry ()");
XSRETURN_UNDEF;
}
if (l > GN_PHONEBOOK_NUMBER_MAX_LENGTH) {
set_errors ("Number is too long");
XSRETURN_UNDEF;
}
entry.subentries[entry.subentries_count].data.date.year = dt;\
entry.subentries[entry.subentries_count++].entry_type = type;\
}\
}
hv_getsubdt ("birthday", GN_PHONEBOOK_ENTRY_Birthday);
hv_getsubdt ("date", GN_PHONEBOOK_ENTRY_Date);
if (entry.subentries_count)
hv_getsubn ("number", GN_PHONEBOOK_NUMBER_None);
gn_phonebook_entry_sanitize (&entry);
if (opt_v > 5 ) {
warn (
" location => %d,\n"
" number => '%s',\n"
" name => '%s',\n"
" group => %d,\n"
" person => {\n"
" formal_name => '%s',\n"
" formal_suffix => '%s',\n"
" given_name => '%s',\n"
" family_name => '%s',\n"
" additional_names => '%s',\n"
" },\n"
" address => {\n"
" postal => '%s',\n"
" extended_address => '%s',\n"
" street => '%s',\n"
" city => '%s',\n"
" state_province => '%s',\n"
" zipcode => '%s',\n"
" country => '%s',\n"
" },\n [\n",
entry.location, entry.number, entry.name, entry.caller_group,
entry.person.honorific_prefixes, entry.person.honorific_suffixes,
entry.person.given_name, entry.person.family_name,
entry.person.additional_names,
entry.address.post_office_box, entry.address.extended_address,
entry.address.street, entry.address.city,
entry.address.state_province, entry.address.zipcode,
entry.address.country);
for (i = 0; i < entry.subentries_count; i++) {
warn (" %02d: %02x %02x '%s',\n", i,
entry.subentries[i].entry_type, entry.subentries[i].number_type,
entry.subentries[i].data.number);
}
warn (" ]\n }\n");
}
data->phonebook_entry = &entry;
if (gn_sm_func (self, GN_OP_WritePhonebook))
XS_RETURNi (entry.location);
XSRETURN_UNDEF;
/* WritePhonebookEntry */
void
GetSpeedDial (self, location)
HvObject *self;
int location;
PPCODE:
gn_speed_dial *speeddial;
if (opt_v) warn ("Get Speed Dial %d\n", location);
if (location < 0)
croak ("Speed dial number should be >= 0\n");
clear_data ();
Newxz (speeddial, 1, gn_speed_dial);
speeddial->number = location;
data->speed_dial = speeddial;
if (gn_sm_func (self, GN_OP_GetSpeedDial)) {
HV *sd = newHV ();
hv_puti (sd, "number", speeddial->number);
hv_puti (sd, "location", speeddial->location);
hv_puts (sd, "memory", gn_memory_type2str (speeddial->memory_type));
XS_RETURNr (sd);
}
XSRETURN_UNDEF;
/* GetSpeedDial */
void
SetSpeedDial (self, memtype, location, number)
HvObject *self;
char *memtype;
int location;
int number;
PPCODE:
/* TODO: This funtion is untested */
gn_error err;
gn_speed_dial entry;
clear_data ();
Zero (&entry, 1, entry);
set_memtype (entry.memory_type, memtype);
entry.number = number;
entry.location = location;
data->speed_dial = &entry;
err = gn_sm_functions (GN_OP_SetSpeedDial, data, state);
set_errori (err);
XS_RETURNi (err);
/* SetSpeedDial */
/* ###########################################################################
* Date/Time/Calendar Functionality
* ###########################################################################
*
* GetGateTime ()
* SetDateTime (timestamp)
* GetAlarm ()
* SetAlarm (hour, minute)
* GetCalendarNotes (start, end)
* WriteCalendarNote ({ ... })
* GetTodo (start, end)
* WriteTodo ({ ... })
* DeleteAllTodos ()
*
* ###########################################################################
*/
void
GetDateTime (self)
HvObject *self;
PPCODE:
gn_timestamp date_time;
if (opt_v) warn ("GetDateTime ()\n");
clear_data ();
data->datetime = &date_time;
if (gn_sm_func (self, GN_OP_GetDateTime)) {
HV *dt = newHV ();
GSMDATE_TO_TM ("date", date_time, dt);
XS_RETURNr (dt);
}
XSRETURN_UNDEF;
/* GetDateTime */
void
SetDateTime (self, timestamp)
HvObject *self;
time_t timestamp;
PPCODE:
gn_error err;
gn_timestamp date;
/* TODO: This funtion is untested */
if (opt_v) warn ("SetDateTime (%ld)\n", (long)timestamp);
clear_data ();
Zero (&date, 1, date);
data->datetime = &date;
HASH_TO_GSMDT (data->datetime, ×tamp);
err = gn_sm_functions (GN_OP_SetDateTime, data, state);
set_errori (err);
XS_RETURNi (err);
/* SetDateTime */
void
GetAlarm (self)
HvObject *self;
PPCODE:
gn_calnote_alarm alrm;
if (opt_v) warn ("GetAlarm ()\n");
clear_data ();
data->alarm = &alrm;
if (gn_sm_functions (GN_OP_GetAlarm, data, state) == GN_ERR_NONE) {
char tm[8];
HV *ah = newHV ();
sprintf (tm, "%02d:%02d", alrm.timestamp.hour, alrm.timestamp.minute);
hv_puts (ah, "alarm", tm);
hv_puts (ah, "state", (alrm.enabled ? "on" : "off"));
XS_RETURNr (ah);
}
XSRETURN_UNDEF;
/* GetAlarm */
void
SetAlarm (self, hour, minute)
HvObject *self;
int hour;
int minute;
PPCODE:
gn_calnote_alarm at;
int err;
clear_data ();
if (hour < 0 || hour > 23) {
set_errors ("Alarm hour must be in [0..23]");
XSRETURN_UNDEF;
}
if (minute < 0 || minute > 59) {
set_errors ("Alarm minute must be in [0..59]");
XSRETURN_UNDEF;
}
Zero (&at, 1, gn_calnote_alarm);
at.timestamp.hour = hour;
at.timestamp.minute = minute;
at.timestamp.second = 0;
at.enabled = true;
data->alarm = &at;
err = gn_sm_functions (GN_OP_SetAlarm, data, state);
set_errori (err);
XS_RETURNi (err);
/* SetAlarm */
void
GetCalendarNotes (self, start, end)
HvObject *self;
int start;
int end;
PPCODE:
gn_calnote_list calendarnoteslist;
gn_calnote calendarnote;
int i, err;
AV *cnl = newAV ();
if (opt_v) warn ("GetCalenderNotes (%d, %d)\n", start, end);
if (start < 0) {
set_errors ("calendarnote location should be in positive");
XSRETURN_UNDEF;
}
if (end < 0 || (start && end == 0))
end = INT_MAX;
for (i = start; i <= end; i++) {
clear_data ();
calendarnote.location = i;
data->calnote = &calendarnote;
data->calnote_list = &calendarnoteslist;
err = gn_sm_functions (GN_OP_GetCalendarNote, data, state);
if (err == GN_ERR_INVALIDLOCATION)
break;
if (err == GN_ERR_EMPTYLOCATION) {
av_push (cnl, &PL_sv_undef);
continue;
}
if (err == GN_ERR_NONE) {
HV *note = newHV ();
hv_puti (note, "location", i);
hv_puts (note, "type", gn_calnote_type2str (calendarnote.type));
hv_puts (note, "recurrence", gn_calnote_recurrence2str (calendarnote.recurrence));
if (calendarnote.phone_number[0])
hv_puts (note, "number", calendarnote.phone_number);
if (calendarnote.mlocation[0])
hv_puts (note, "mlocation", calendarnote.mlocation);
hv_puts (note, "text", calendarnote.text);
if (calendarnote.alarm.timestamp.year)
GSMDATE_TO_TM ("alarm", calendarnote.alarm.timestamp, note);
calendarnote.time.second = 0;
calendarnote.time.minute = 0;
calendarnote.time.hour = 0;
GSMDATE_TO_TM ("date", calendarnote.time, note);
av_addr (cnl, note);
}
else
set_errori (err);
}
XS_RETURNr (cnl);
/* GetCalendarNotes */
void
WriteCalendarNote (self, calhash)
HvObject *self;
HV *calhash;
PPCODE:
gn_calnote calnote;
char *buf;
time_t t1, *t2;
gn_timestamp *timestamp;
int err;
SV **value;
clear_data ();
Zero (&calnote, 1, calnote);
if ((value = hv_fetch (calhash, "date", 4, 0)) == NULL) {
set_errors ("date is a required attribute for WriteCalendarNote ()");
XSRETURN_UNDEF;
}
t1 = (time_t)SvIV (*value);
t2 = &t1;
timestamp = &(calnote.time);
HASH_TO_GSMDT (timestamp, t2);
if ((value = hv_fetch (calhash, "text", 4, 0)) == NULL) {
set_errors ("text is a required attribute for WriteCalendarNote ()");
XSRETURN_UNDEF;
}
strcpy (calnote.text, SvPV_nolen (*value));
if ((value = hv_fetch (calhash, "type", 4, 0)) == NULL)
buf = "MEMO";
else
buf = SvPV_nolen (*value);
if (!strncasecmp (buf, "misc", 4) || !strncasecmp (buf, "remi", 4))
calnote.type = GN_CALNOTE_REMINDER;
else if (!strncasecmp (buf, "call", 4))
calnote.type = GN_CALNOTE_CALL;
else if (!strncasecmp (buf, "meet", 4))
calnote.type = GN_CALNOTE_MEETING;
else if (!strncasecmp (buf, "birt", 4))
calnote.type = GN_CALNOTE_BIRTHDAY;
else if (!strncasecmp (buf, "memo", 4))
calnote.type = GN_CALNOTE_MEMO;
value = hv_fetch (calhash, "number", 6, 0);
if (calnote.type == GN_CALNOTE_CALL && !value) {
set_errors ("number is a required attribute for WriteCalendarNote (CALL)");
XSRETURN_UNDEF;
}
if (value)
strcpy (calnote.phone_number, SvPV_nolen (*value));
if ((value = hv_fetch (calhash, "mlocation", 9, 0)))
strcpy (calnote.mlocation, SvPV_nolen (*value));
if ((value = hv_fetch (calhash, "alarm", 5, 0))) {
t1 = (time_t)SvIV (*value);
t2 = &t1;
calnote.alarm.enabled = true;
timestamp = &(calnote.alarm.timestamp);
HASH_TO_GSMDT (timestamp, t2);
}
if ((value = hv_fetch (calhash, "recurrence", 10, 0)) == NULL)
buf = "NEVER";
else
buf = SvPV_nolen (*value);
if (!strncasecmp (buf, "neve", 4))
calnote.recurrence = GN_CALNOTE_NEVER;
else if (!strncasecmp (buf, "dail", 4))
calnote.recurrence = GN_CALNOTE_DAILY;
else if (!strncasecmp (buf, "week", 4))
calnote.recurrence = GN_CALNOTE_WEEKLY;
else if (!strncasecmp (buf, "2wee", 4))
calnote.recurrence = GN_CALNOTE_2WEEKLY;
else if (!strncasecmp (buf, "year", 4))
calnote.recurrence = GN_CALNOTE_YEARLY;
data->calnote = &calnote;
err = gn_sm_functions (GN_OP_WriteCalendarNote, data, state);
set_errori (err);
XS_RETURNi (calnote.location);
/* WriteCalendarNote */
void
GetTodo (self, start, end)
HvObject *self;
int start;
int end;
PPCODE:
gn_todo_list todolist;
gn_todo todo;
int i, err;
AV *tdl = newAV ();
if (opt_v) warn ("GetTodo (%d, %d)\n", start, end);
if (start < 0) {
set_errors ("todo location should be positive");
XSRETURN_UNDEF;
}
if (end < 0 || (start && end == 0))
end = INT_MAX;
for (i = start; i < end; i++) {
clear_data ();
Zero (&todolist, 1, todolist);
Zero (&todo, 1, gn_todo);
todo.location = i;
data->todo = &todo;
data->todo_list = &todolist;
err = gn_sm_functions (GN_OP_GetToDo, data, state);
if (err == GN_ERR_INVALIDLOCATION)
break;
if (err == GN_ERR_EMPTYLOCATION) {
av_push (tdl, &PL_sv_undef);
continue;
}
if (err == GN_ERR_NONE) {
HV *t = newHV ();
hv_puti (t, "location", i);
hv_puts (t, "text", todo.text);
switch (todo.priority) {
case GN_TODO_LOW: hv_puts (t, "priority", "low"); break;
case GN_TODO_MEDIUM: hv_puts (t, "priority", "medium"); break;
case GN_TODO_HIGH: hv_puts (t, "priority", "high"); break;
default: hv_puts (t, "priority", "unknown"); break;
}
av_addr (tdl, t);
}
else
set_errori (err);
}
XS_RETURNr (tdl);
/* GetTodo */
void
WriteTodo (self, todohash)
HvObject *self;
HV *todohash;
PPCODE:
gn_todo todo;
char *buf;
int err;
clear_data ();
Zero (&todo, 1, todo);
strcpy (todo.text, SvPV_nolen (*hv_fetch (todohash, "text", 4, 0)));
buf = SvPV_nolen (*hv_fetch (todohash, "priority", 8, 0));
if (!strcasecmp (buf, "low"))
todo.priority = GN_TODO_LOW;
else if (!strcasecmp (buf, "medium"))
todo.priority = GN_TODO_MEDIUM;
else if (!strcasecmp (buf, "high"))
todo.priority = GN_TODO_HIGH;
data->todo = &todo;
err = gn_sm_functions (GN_OP_WriteToDo, data, state);
set_errori (err);
XS_RETURNi (todo.location);
/* WriteTodo */
void
DeleteAllTodos (self)
HvObject *self;
PPCODE:
int err;
clear_data ();
err = gn_sm_functions (GN_OP_DeleteAllToDos, data, state);
set_errori (err);
XS_RETURNi (err);
/* DeleteAllTodos */
/* ###########################################################################
* Profile/Status Functionality
* ###########################################################################
*
* GetDisplayStatus ()
* GetIMEI ()
* GetPowerStatus ()
* GetMemoryStatus ()
* GetProfiles ()
* GetSecurity ()
* GetLogo ({ ... })
* GetRingtoneList ()
* GetRingtone (location)
* GetDirTree (memorytype, depth)
* GetDir (memorytype, path, depth)
* GetFile (path)
*
* ###########################################################################
*/
void
Ping (self)
HvObject *self;
PPCODE:
gn_error err;
if (opt_v) warn ("Ping ()\n");
unless (can_ping)
XSRETURN_UNDEF;
clear_data ();
if (gn_sm_func (self, GN_OP_Ping))
XS_RETURNi (1);
XS_RETURNi (0);
/* Ping */
void
GetDisplayStatus (self)
HvObject *self;
PPCODE:
int status = 0;
if (opt_v) warn ("GetDisplayStatus ()\n");
clear_data ();
data->display_status = &status;
if (gn_sm_func (self, GN_OP_GetDisplayStatus)) {
HV *ds = newHV ();
hv_puti (ds, "call_in_progress", status & (1 << GN_DISP_Call_In_Progress) ? 1 : 0);
hv_puti (ds, "unknown", status & (1 << GN_DISP_Unknown) ? 1 : 0);
hv_puti (ds, "unread_SMS", status & (1 << GN_DISP_Unread_SMS) ? 1 : 0);
hv_puti (ds, "voice_call", status & (1 << GN_DISP_Voice_Call) ? 1 : 0);
hv_puti (ds, "fax_call_active", status & (1 << GN_DISP_Fax_Call) ? 1 : 0);
hv_puti (ds, "data_call_active", status & (1 << GN_DISP_Data_Call) ? 1 : 0);
hv_puti (ds, "keyboard_lock", status & (1 << GN_DISP_Keyboard_Lock) ? 1 : 0);
hv_puti (ds, "sms_storage_full", status & (1 << GN_DISP_SMS_Storage_Full) ? 1 : 0);
XS_RETURNr (ds);
}
XSRETURN_UNDEF;
/* GetDisplayStatus */
void
GetIMEI (self)
HvObject *self;
PPCODE:
char imei[64], model[64], rev[64], manufacturer[64];
if (opt_v) warn ("GetIMEI ()\n");
clear_data ();
Zero (imei, 64, char);
Zero (model, 64, char);
Zero (rev, 64, char);
Zero (manufacturer, 64, char);
data->imei = imei;
data->model = model;
data->revision = rev;
data->manufacturer = manufacturer;
if (gn_sm_functions (GN_OP_Identify, data, state) == GN_ERR_NONE) {
HV *ih = newHV ();
hv_puts (ih, "imei", data->imei);
hv_puts (ih, "model", data->model);
hv_puts (ih, "revision", data->revision);
hv_puts (ih, "manufacturer", data->manufacturer);
XS_RETURNr (ih);
}
XSRETURN_UNDEF;
/* GetIMEI */
void
GetPowerStatus (self)
HvObject *self;
PPCODE:
gn_power_source powersource = -1;
float batterylevel = -1;
gn_battery_unit batt_units = GN_BU_Arbitrary;
HV *ps = newHV ();
if (opt_v) warn ("GetPowerStatus ()\n");
clear_data ();
data->battery_unit = &batt_units;
data->battery_level = &batterylevel;
data->power_source = &powersource;
if (gn_sm_functions (GN_OP_GetBatteryLevel, data, state) == GN_ERR_NONE)
hv_putn (ps, "level", batterylevel);
if (gn_sm_functions (GN_OP_GetPowersource, data, state) == GN_ERR_NONE)
hv_puts (ps, "source", gn_power_source2str (powersource));
XS_RETURNr (ps);
/* GetPowerStatus */
void
GetMemoryStatus (self)
HvObject *self;
PPCODE:
HV *ms = newHV ();
if (opt_v) warn ("GetMemoryStatus ()\n");
clear_data ();
data->memory_status = &SIMMemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "simused", SIMMemoryStatus.used);
hv_puti (ms, "simfree", SIMMemoryStatus.free);
}
data->memory_status = &PhoneMemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "phoneused", PhoneMemoryStatus.used);
hv_puti (ms, "phonefree", PhoneMemoryStatus.free);
}
data->memory_status = &DC_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "dcused", DC_MemoryStatus.used);
hv_puti (ms, "dcfree", DC_MemoryStatus.free);
}
data->memory_status = &EN_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "enused", EN_MemoryStatus.used);
hv_puti (ms, "enfree", EN_MemoryStatus.free);
}
data->memory_status = &FD_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "fdused", FD_MemoryStatus.used);
hv_puti (ms, "fdfree", FD_MemoryStatus.free);
}
data->memory_status = &LD_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "ldused", LD_MemoryStatus.used);
hv_puti (ms, "ldfree", LD_MemoryStatus.free);
}
data->memory_status = &MC_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "mcused", MC_MemoryStatus.used);
hv_puti (ms, "mcfree", MC_MemoryStatus.free);
}
data->memory_status = &ON_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "onused", ON_MemoryStatus.used);
hv_puti (ms, "onfree", ON_MemoryStatus.free);
}
data->memory_status = &RC_MemoryStatus;
if (gn_sm_functions (GN_OP_GetMemoryStatus, data, state) == GN_ERR_NONE) {
hv_puti (ms, "rcused", RC_MemoryStatus.used);
hv_puti (ms, "rcfree", RC_MemoryStatus.free);
}
XS_RETURNr (ms);
/* GetMemoryStatus */
void
GetProfiles (self, start, end)
HvObject *self;
int start;
int end;
PPCODE:
gn_profile profile;
gn_ringtone_list rtl;
char model[64] = "";
int i, max_profiles = 7;
HV *p;
AV *pl = newAV ();
if (opt_v) warn ("GetProfiles (%d, %d)\n", start, end);
warn ("GetProfile () @ %d\n", __LINE__);
clear_data ();
data->model = model;
unless (gn_sm_func (self, GN_OP_GetModel))
XSRETURN_UNDEF;
if (strcmp (model, "NSE-1") == 0)
max_profiles = 3;
warn ("GetProfile () @ %d (%s)\n", __LINE__, model);
if (start < 0 || start > max_profiles) {
set_errors ("profile location should be in valid range 1..7");
XSRETURN_UNDEF;
}
if (end <= 0 || end > max_profiles)
end = max_profiles;
warn ("GetProfile () @ %d\n", __LINE__);
Zero (&rtl, 1, rtl);
Zero (&profile, 1, profile);
profile.number = 0;
data->profile = &profile;
data->ringtone_list = &rtl;
unless (gn_sm_func (self, GN_OP_GetProfile)) /* use GN_OP_GetActiveProfile? */
XSRETURN_UNDEF;
warn ("GetProfile () @ %d\n", __LINE__);
for (i = start; i < end; i++) {
if (i) {
clear_data ();
Zero (&profile, 1, profile);
Zero (&rtl, 1, rtl);
data->profile = &profile;
data->ringtone_list = &rtl;
profile.number = i;
unless (gn_sm_func (self, GN_OP_GetProfile))
continue;
}
warn ("GetProfile () @ %d\n", __LINE__);
p = newHV ();
hv_puti (p, "number", i);
hv_puts (p, "name", profile.name);
hv_puts (p, "defaultname", profile.default_name);
hv_puts (p, "call_alert", gn_profile_callalert_type2str (profile.call_alert));
hv_puti (p, "ringtonenumber", profile.ringtone);
hv_puts (p, "volume_level", gn_profile_volume_type2str (profile.volume));
hv_puts (p, "message_tone", gn_profile_message_type2str (profile.message_tone));
hv_puts (p, "keypad_tone", gn_profile_keyvol_type2str (profile.keypad_tone));
hv_puts (p, "warning_tone", gn_profile_warning_type2str (profile.warning_tone));
hv_puts (p, "vibration", gn_profile_vibration_type2str (profile.vibration));
hv_puti (p, "caller_groups", profile.caller_groups);
hv_puts (p, "automatic_answer", profile.automatic_answer ? "On" : "Off");
av_addr (pl, p);
}
XS_RETURNr (pl);
/* GetProfiles */
void
GetSecurity (self)
HvObject *self;
PPCODE:
gn_security_code sc;
if (opt_v) warn ("GetSecurity ()\n");
clear_data ();
Zero (&sc, 1, sc);
sc.type = GN_SCT_SecurityCode;
data->security_code = ≻
if (gn_sm_functions (GN_OP_GetSecurityCodeStatus, data, state) == GN_ERR_NONE) {
char *key;
HV *si = newHV ();
key = "status";
switch (sc.type) {
case GN_SCT_SecurityCode: hv_puts (si, key, "Waiting for Security Code"); break;
case GN_SCT_Pin: hv_puts (si, key, "Waiting for PIN"); break;
case GN_SCT_Pin2: hv_puts (si, key, "Waiting for PIN2"); break;
case GN_SCT_Puk: hv_puts (si, key, "Waiting for PUK"); break;
case GN_SCT_Puk2: hv_puts (si, key, "Waiting for PUK2"); break;
case GN_SCT_None: hv_puts (si, key, "Nothing to enter"); break;
default: hv_puts (si, key, "Unknown"); break;
}
if (gn_sm_functions (GN_OP_GetSecurityCode, data, state) == GN_ERR_NONE)
hv_puts (si, "security_code", sc.code);
if (0) { /* *** stack smashing detected *** */
gn_locks_info li[4];
clear_data ();
Zero (li, 4, li);
data->locks_info = li;
if (gn_sm_functions (GN_OP_GetLocksInfo, data, state) == GN_ERR_NONE) {
char *lock_names[] = {"MCC+MNC", "GID1", "GID2", "MSIN"};
int i;
AV *lil = newAV ();
for (i = 0; i < 4; i++) {
HV *l = newHV ();
hv_puts (l, "name", lock_names[i]);
hv_puts (l, "type", li[i].userlock ? "user" : "factory");
hv_puts (l, "state", li[i].closed ? "closed" : "open");
hv_puts (l, "data", li[i].data);
hv_puti (l, "counter", li[i].counter);
av_addr (lil, l);
}
hv_putr (si, "locks", lil);
}
}
XS_RETURNr (si);
}
XSRETURN_UNDEF;
/* GetSecurity */
void
GetLogo (self, logodata)
HvObject *self;
HV *logodata;
PPCODE:
gn_bmp bitmap;
char *type;
if (opt_v) warn ("GetLogo ({ type => ... })\n");
clear_data ();
Zero (&bitmap, 1, gn_bmp);
type = SvPV_nolen (*hv_fetch (logodata, "type", 4, 0));
if (!strcmp (type, "text")) bitmap.type = GN_BMP_WelcomeNoteText;
else if (!strcmp (type, "dealer")) bitmap.type = GN_BMP_DealerNoteText;
else if (!strcmp (type, "op")) bitmap.type = GN_BMP_OperatorLogo;
else if (!strcmp (type, "startup")) bitmap.type = GN_BMP_StartupLogo;
else if (!strcmp (type, "caller")) bitmap.type = GN_BMP_CallerLogo;
else if (!strcmp (type, "picture")) bitmap.type = GN_BMP_PictureMessage;
else if (!strcmp (type, "emspicture")) bitmap.type = GN_BMP_EMSPicture;
else if (!strcmp (type, "emsanimation")) bitmap.type = GN_BMP_EMSAnimation;
if ((bitmap.type == GN_BMP_CallerLogo) &&
(hv_fetch (logodata, "callerindex", 11, 0) == NULL))
bitmap.number = 0; /* das muss noch anders werden */
data->bitmap = &bitmap;
if (gn_sm_functions (GN_OP_GetBitmap, data, state) == GN_ERR_NONE) {
HV *l = newHV ();
switch (bitmap.type) {
case GN_BMP_DealerNoteText:
case GN_BMP_WelcomeNoteText:
hv_puts (l, "text", bitmap.text);
break;
case GN_BMP_OperatorLogo:
case GN_BMP_NewOperatorLogo:
case GN_BMP_StartupLogo:
hv_puts (l, "netcode", bitmap.netcode);
hv_puts (l, "newname", (char *)gn_network_name_get (bitmap.netcode));
break;
default:
warn ("Bitmap type %d not yet handled\n", bitmap.type);
}
hv_puts (l, "type", type);
hv_putS (l, "bitmap", bitmap.bitmap, bitmap.size);
hv_puti (l, "size", bitmap.size);
hv_puti (l, "height", bitmap.height);
hv_puti (l, "width", bitmap.width);
XS_RETURNr (l);
}
XSRETURN_UNDEF;
/* GetLogo */
void
GetRingtoneList (self)
HV *self;
PPCODE:
gn_ringtone_list ringtone_list;
if (opt_v) warn ("GetRingtoneList ()\n");
clear_data ();
Zero (&ringtone_list, 1, ringtone_list);
data->ringtone_list = &ringtone_list;
if (gn_sm_functions (GN_OP_GetRingtoneList, data, state) == GN_ERR_NONE) {
HV *rl = newHV ();
hv_puti (rl, "count", ringtone_list.count);
hv_puti (rl, "userdef_location", ringtone_list.userdef_location);
hv_puti (rl, "userdef_count", ringtone_list.userdef_count);
XS_RETURNr (rl);
}
XSRETURN_UNDEF;
/* GetRingtoneList */
void
GetRingtone (self, location)
HvObject *self;
int location;
PPCODE:
gn_ringtone ringtone;
gn_raw_data rawdata;
unsigned char buff[512];
if (opt_v) warn ("GetRingtone (%d)\n", location);
Zero (&ringtone, 1, ringtone);
rawdata.data = buff;
rawdata.length = sizeof (buff);
clear_data ();
data->ringtone = &ringtone;
data->raw_data = &rawdata;
ringtone.location = location;
if (gn_sm_functions (GN_OP_GetRingtone, data, state) == GN_ERR_NONE) {
HV *rt = newHV ();
int i = 2000;
unsigned char buffer[2000];
hv_puti (rt, "location", location);
hv_puts (rt, "name", ringtone.name);
gn_ringtone_pack (&ringtone, buffer, &i);
hv_puts (rt, "ringtone", buffer);
hv_puti (rt, "length", i);
XS_RETURNr (rt);
}
XSRETURN_UNDEF;
/* GetRingtone */
void
GetDirTree (self, memorytype, depth)
HvObject *self;
char *memorytype;
int depth;
PPCODE:
char *mt;
gn_file_list fl;
HV *dt;
if (opt_v) warn ("GetDirTree (%s, %d)\n", memorytype, depth);
if (!strcmp (memorytype, "ME"))
mt = "A:";
else if (!strcmp (memorytype, "SM"))
mt = "B:";
else {
set_errors ("usage: GetDirTree ('ME' | 'SM', depth)");
XSRETURN_UNDEF;
}
clear_data ();
Zero (&fl, 1, fl);
sprintf (fl.path, "%s\\*", mt);
data->file_list = &fl;
unless (gn_sm_func (self, GN_OP_GetFileList))
XSRETURN_UNDEF;
dt = newHV ();
hv_puts (dt, "memorytype", memorytype);
hv_puts (dt, "path", mt);
hv_puti (dt, "file_count", fl.file_count);
hv_puti (dt, "dir_size", fl.size);
if (depth <= 0 || depth > 0x7fff) depth = 0x7fff;
hv_putr (dt, "tree", walk_tree (self, mt, &fl, depth));
XS_RETURNr (dt);
/* GetDirTree */
void
GetDir (self, memorytype, path, depth)
HvObject *self;
char *memorytype;
char *path;
int depth;
PPCODE:
char *mt;
gn_file_list fl;
HV *dt;
if (opt_v) warn ("GetDir (%s, %s, %d)\n", memorytype, path, depth);
if (!strcmp (memorytype, "ME"))
mt = "A:";
else if (!strcmp (memorytype, "SM"))
mt = "B:";
else {
set_errors ("usage: GetDir ('ME' | 'SM', path, depth)");
XSRETURN_UNDEF;
}
clear_data ();
Zero (&fl, 1, fl);
sprintf (fl.path, "%s%s\\*", mt, path);
if (opt_v > 1) warn ("GetDir (%s)\n", fl.path);
data->file_list = &fl;
unless (gn_sm_func (self, GN_OP_GetFileList))
XSRETURN_UNDEF;
dt = newHV ();
hv_puts (dt, "memorytype", memorytype);
hv_puts (dt, "path", mt);
hv_puti (dt, "file_count", fl.file_count);
hv_puti (dt, "dir_size", fl.size);
if (depth <= 0 || depth > 0x7fff) depth = 1;
hv_putr (dt, "tree", walk_tree (self, mt, &fl, depth));
XS_RETURNr (dt);
/* GetDir */
void
GetFile (self, path)
HvObject *self;
char *path;
PPCODE:
gn_file fi;
HV *dt;
if (opt_v) warn ("GetFile (%s)\n", path);
clear_data ();
Zero (&fi, 1, fi);
snprintf (fi.name, sizeof (fi.name), "%s", path);
data->file = &fi;
unless (gn_sm_func (self, GN_OP_GetFile)) {
set_errors ("GetFile () failed to get file");
XSRETURN_UNDEF;
}
if (opt_v > 1) warn ("GetFile (%s) -> size %d\n", fi.name, fi.file_length);
dt = newHV ();
hv_puti (dt, "size", fi.file_length);
hv_putS (dt, "file", fi.file, fi.file_length);
XS_RETURNr (dt);
/* GetFile */
/* ###########################################################################
* SMS Functionality
* ###########################################################################
*
* GetSMSCenter (start, end)
* GetSMSFolderList ()
* CreateSMSFolder (name)
* DeleteSMSFolder (location)
* GetSMSStatus ()
* GetSMS (memtype, location)
* DeleteSMS (memtype, location, foldername) TODO
* SendSMS ({ ... })
*
* ###########################################################################
*/
void
GetSMSCenter (self, start, end)
HvObject *self;
int start;
int end;
PPCODE:
gn_sms_message_center messagecenter;
int i, err;
AV *scl = newAV ();
if (opt_v) warn ("GetSMSCenter (%d, %d)\n", start, end);
if (start < 1 || start > 5) {
set_errors ("messagecenter location should be in valid range 1..5");
XSRETURN_UNDEF;
}
if (end <= 0 || end > 5)
end = 5;
for (i = start; i <= end; i++) {
HV *mc = newHV ();
clear_data ();
Zero (&messagecenter, 1, messagecenter);
messagecenter.id = i;
data->message_center = &messagecenter;
err = gn_sm_functions (GN_OP_GetSMSCenter, data, state);
if (err == GN_ERR_INVALIDLOCATION)
break;
if (err == GN_ERR_EMPTYLOCATION) {
av_push (scl, &PL_sv_undef);
continue;
}
if (err == GN_ERR_NONE) {
hv_puti (mc, "id", messagecenter.id);
hv_puts (mc, "name", messagecenter.name);
hv_puti (mc, "defaultname", messagecenter.default_name);
switch (messagecenter.format) {
case GN_SMS_MF_Text: hv_puts (mc, "format", "Text"); break;
case GN_SMS_MF_Voice: hv_puts (mc, "format", "VoiceMail"); break;
case GN_SMS_MF_Fax: hv_puts (mc, "format", "Fax"); break;
case GN_SMS_MF_Email:
case GN_SMS_MF_UCI: hv_puts (mc, "format", "Email"); break;
case GN_SMS_MF_ERMES: hv_puts (mc, "format", "Fermes"); break;
case GN_SMS_MF_X400: hv_puts (mc, "format", "X.400"); break;
case GN_SMS_MF_Paging: hv_puts (mc, "format", "Paging"); break;
default: hv_puts (mc, "format", "unknown"); break;
}
switch (messagecenter.validity) {
case GN_SMS_VP_1H: hv_puts (mc, "validity", "1 hour"); break;
case GN_SMS_VP_6H: hv_puts (mc, "validity", "6 hours"); break;
case GN_SMS_VP_24H: hv_puts (mc, "validity", "24 hours"); break;
case GN_SMS_VP_72H: hv_puts (mc, "validity", "72 hours"); break;
case GN_SMS_VP_1W: hv_puts (mc, "validity", "1 Week"); break;
case GN_SMS_VP_Max: hv_puts (mc, "validity", "Maximum Time"); break;
default: hv_puts (mc, "validity", "unknown"); break;
}
hv_puti (mc, "type", messagecenter.smsc.type);
hv_puts (mc, "smscnumber", messagecenter.smsc.number);
hv_puti (mc, "recipienttype", messagecenter.recipient.type);
hv_puts (mc, "recipientnumber", messagecenter.recipient.number);
av_addr (scl, mc);
}
else
set_errori (err);
}
XS_RETURNr (scl);
/* GetSMSCenter */
void
GetSMSFolderList (self)
HvObject *self;
PPCODE:
gn_sms_folder_list folderlist;
AV *fl;
int i;
if (opt_v) warn ("GetSMSFolderList ()\n");
clear_data ();
Zero (&folderlist, 1, folderlist);
data->sms_folder_list = &folderlist;
unless (gn_sm_func (self, GN_OP_GetSMSFolders))
XSRETURN_UNDEF;
fl = newAV ();
for (i = 0; i < (int)folderlist.number; i++) {
HV *f = newHV ();
if (opt_v > 1) warn (" + GetSMSFolderStatus (%d)", i);
hv_puti (f, "location", i);
hv_puts (f, "memorytype", gn_memory_type2str (folderlist.folder_id[i]));
data->sms_folder = folderlist.folder + i;
if (gn_sm_func (self, GN_OP_GetSMSFolderStatus)) {
hv_puts (f, "name", folderlist.folder[i].name);
hv_puti (f, "count", folderlist.folder[i].number);
}
av_addr (fl, f);
}
XS_RETURNr (fl);
/* GetSMSFolderList */
void
CreateSMSFolder (self, name)
HvObject *self;
char *name;
PPCODE:
gn_sms_folder folder;
int err;
if (strlen (name) >= GN_SMS_FOLDER_NAME_MAX_LENGTH) {
set_errors ("Folder name too long");
XSRETURN_UNDEF;
}
clear_data ();
Zero (&folder, 1, folder);
strcpy (folder.name, name);
data->sms_folder = &folder;
err = gn_sm_functions (GN_OP_CreateSMSFolder, data, state);
set_errori (err);
XS_RETURNi (err);
/* CreateSMSFolder */
void
DeleteSMSFolder (self, location)
HvObject *self;
int location;
PPCODE:
gn_sms_folder folder;
int err;
if (location <= 0 || location > GN_SMS_FOLDER_MAX_NUMBER) {
set_errori (GN_ERR_INVALIDLOCATION);
XSRETURN_UNDEF;
}
clear_data ();
folder.folder_id = location;
data->sms_folder = &folder;
err = gn_sm_functions (GN_OP_DeleteSMSFolder, data, state);
set_errori (err);
XS_RETURNi (err);
/* DeleteSMSFolder */
void
GetSMSStatus (self)
HvObject *self;
PPCODE:
gn_sms_status SMSStatus;
if (opt_v) warn ("GetSMSStatus ()\n");
clear_data ();
Zero (&SMSStatus, 1, gn_sms_status);
data->sms_status = &SMSStatus;
if (gn_sm_func (self, GN_OP_GetSMSStatus)) {
HV *ss = newHV ();
hv_puti (ss, "unread", SMSStatus.unread);
hv_puti (ss, "read", SMSStatus.number);
XS_RETURNr (ss);
}
XSRETURN_UNDEF;
/* GetSMSStatus */
void
GetSMS (self, memtype, location)
HvObject *self;
char *memtype;
int location;
PPCODE:
gn_sms message;
gn_sms_folder folder;
gn_sms_folder_list folderlist;
int i;
if (opt_v) warn ("GetSMS (%s, %d)\n", memtype, location);
clear_data ();
Zero (&message, 1, message);
set_memtype (message.memory_type, memtype);
message.memory_type = gn_str2memory_type (memtype);
message.number = location;
Zero (&folder, 1, folder);
/*folder->FolderID = 2;*/
Zero (&folderlist, 1, folderlist);
data->sms = &message;
data->sms_folder = &folder;
data->sms_folder_list = &folderlist;
if (gn_sms_get (data, state) == GN_ERR_NONE) {
HV *sms = newHV ();
hv_puts (sms, "memorytype", memtype);
hv_puti (sms, "location", location);
switch (message.type) {
case 0: /* normal SMS */
hv_puts (sms, "text", message.user_data[0].u.text);
hv_puts (sms, "sender", message.remote.number);
hv_puts (sms, "smsc", message.smsc.number);
GSMDATE_TO_TM ("smscdate", message.smsc_time, sms);
GSMDATE_TO_TM ("date", message.time, sms);
switch (message.status) {
case GN_SMS_Unknown: hv_puts (sms, "status", "unknown"); break;
case GN_SMS_Read: hv_puts (sms, "status", "read"); break;
case GN_SMS_Unread: hv_puts (sms, "status", "unread"); break;
case GN_SMS_Sent: hv_puts (sms, "status", "sent"); break;
case GN_SMS_Unsent: hv_puts (sms, "status", "unsent"); break;
default: hv_puts (sms, "status", "unknown"); break;
}
break;
default:
warn ("SMS message type '%s' not yet dealt with\n", gn_sms_message_type2str (message.type));
}
unless (message.udh.number)
message.udh.udh[0].type = GN_SMS_UDH_None;
switch (message.udh.udh[0].type) {
case GN_SMS_UDH_None:
break;
case GN_SMS_UDH_ConcatenatedMessages:
hv_puti (sms, "concat_current", message.udh.udh[0].u.concatenated_short_message.current_number);
hv_puti (sms, "concat_max", message.udh.udh[0].u.concatenated_short_message.maximum_number);
break;
default:
warn ("Warning: GetSMS: Unhandled message type of '%d': continuing\n", message.udh.udh[0].type);
break;
}
#ifdef DEBUG_MODULE
warn ("Type: %d\n"
"DataType: %d\n"
"Text: %s\n"
"SMSCTime.Year %d\n"
"FolderCount: %d\n"
"Foldername: %s\n",
message.type, message.user_data[0].type,
message.user_data[0].u.text, message.smsc_time.year,
data->sms_folder_list->number, data->sms_folder->name);
#endif
for (i = 0; i < (int)data->sms_folder_list->number; i++) {
#ifdef DEBUG_MODULE
int j;
warn ("ID: %d\n"
"Name: %s\n"
"Number: %d\n",
data->sms_folder_list->folder_id[i],
data->sms_folder_list->folder[i].name,
data->sms_folder_list->folder[i].number);
for (j = 0; j < data->sms_folder_list->folder[i].number; j++)
warn ("\tLoca: %d\n", data->sms_folder_list->folder[i].locations[j]);
#endif
}
XS_RETURNr (sms);
}
XSRETURN_UNDEF;
/* GetSMS */
void
DeleteSMS (self, memtype, location)
HvObject *self;
char *memtype;
int location;
PPCODE:
gn_error err;
gn_sms message;
gn_sms_folder folder;
gn_sms_folder_list folderlist;
if (opt_v) warn ("DeleteSMS (%s, %d)\n", memtype, location);
clear_data ();
Zero (&message, 1, message);
Zero (&folder, 1, folder);
Zero (&folderlist, 1, folderlist);
set_memtype (message.memory_type, memtype);
message.number = location;
data->sms = &message;
data->sms_folder = &folder;
data->sms_folder_list = &folderlist;
err = gn_sms_delete (data, state);
set_errori (err);
XS_RETURNi (err);
/* DeleteSMS */
void
SendSMS (self, smshash)
HvObject *self;
HV *smshash;
PPCODE:
gn_sms sms;
SV **value;
char *str;
STRLEN l;
int err = GN_ERR_NONE;
if (opt_v) warn ("SendSMS ({ destination => ..., message => ... })\n");
/* Options in gnokii:
* smsc
* smscno
* long
* report
* validity
* class
* 8bit
* imelody
* animation
* concat
* wappush
*/
clear_data ();
gn_sms_default_submit (&sms);
if ((value = hv_fetch (smshash, "report", 6, 0)) && (SvTRUE (*value)))
sms.delivery_report = true;
else
sms.delivery_report = false;
sms.type = GN_SMS_MT_Submit;
unless ((value = hv_fetch (smshash, "destination", 11, 0))) {
set_errors ("destination is a required attribute in SendSMS ()");
XSRETURN_UNDEF;
}
str = SvPV (*value, l);
if (l >= sizeof (sms.remote.number)) {
set_errors ("Destination is too long");
XSRETURN_UNDEF;
}
strcpy (sms.remote.number, str);
sms.remote.type = get_number_type (str);
if (sms.remote.type == GN_GSM_NUMBER_Alphanumeric) {
set_errors ("Invalid phone number");
XSRETURN_UNDEF;
}
#ifdef DEBUG_MODULE
warn ("SendSMS: destination set to '%s'\n", str);
#endif
if ((value = hv_fetch (smshash, "message", 7, 0)) ||
(value = hv_fetch (smshash, "text", 4, 0))) {
char *text = SvPV (*value, l);
unsigned int i = 0;
#ifdef DEBUG_MODULE
warn ("SendSMS: got text: '%s' (%d)\n", text, l);
#endif
if (l > GN_SMS_MAX_LENGTH) {
set_errors ("No support (yet) for long messages");
}
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d: smsc number = %s\n", __LINE__, sms.smsc.number);
#endif
}
unless (sms.smsc.number[0]) {
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d: set default smsc\n", __LINE__);
#endif
Newxz (data->message_center, 1, 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);
}
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d: set validity\n", __LINE__);
#endif
if ((value = hv_fetch (smshash, "validity", 8, 0)))
sms.validity = SvIV (*value);
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d: msg: '%s'\n", __LINE__, sms.user_data[0].u.text);
#endif
data->sms = &sms;
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d before send\n", __LINE__);
#endif
if (err == GN_ERR_NONE)
err = gn_sms_send (data, state);
set_errori (err);
#ifdef DEBUG_MODULE
warn ("SendSMS @ %d after send\n", __LINE__);
#endif
XS_RETURNi (err);
/* SendSMS */
/* ###########################################################################
* Network Functionality
* ###########################################################################
*
* GetRF ()
* GetNetworkInfo ()
* GetWapSettings (location)
* WriteWapSettings ({ ... })
* ActivateWapSetting (location)
* GetWapBookmark (location)
* WriteWapBookmark ({ ... })
* DeleteWapBookmark (location)
*
* ###########################################################################
*/
void
GetRF (self)
HvObject *self;
PPCODE:
float rflevel = -1;
gn_rf_unit rfunit = GN_RF_Arbitrary;
HV *rf = newHV ();;
if (opt_v) warn ("GetRF ()\n");
clear_data ();
data->rf_unit = &rfunit;
data->rf_level = &rflevel;
if (gn_sm_func (self, GN_OP_GetRFLevel)) {
hv_putn (rf, "level", rflevel);
hv_puti (rf, "unit", rfunit);
}
XS_RETURNr (rf);
/* GetRF */
void
GetNetworkInfo (self)
HvObject *self;
PPCODE:
gn_network_info NetworkInfo;
char buffer[10];
if (opt_v) warn ("GetNetworkInfo ()\n");
clear_data ();
data->network_info = &NetworkInfo;
if (gn_sm_func (self, GN_OP_GetNetworkInfo)) {
HV *ni = newHV ();
hv_puts (ni, "name", (char *)gn_network_name_get (NetworkInfo.network_code));
hv_puts (ni, "countryname", (char *)gn_country_name_get (NetworkInfo.network_code));
hv_puts (ni, "networkcode", NetworkInfo.network_code);
Zero (buffer, 10, char);
sprintf (buffer, "%02x%02x", NetworkInfo.cell_id[0], NetworkInfo.cell_id[1]);
hv_puts (ni, "cellid", buffer);
Zero (buffer, 10, char);
sprintf (buffer, "%02x%02x", NetworkInfo.LAC[0], NetworkInfo.LAC[1]);
hv_puts (ni, "lac", buffer);
XS_RETURNr (ni);
}
XSRETURN_UNDEF;
/* GetNetworkInfo */
void
GetWapSettings (self, location)
HvObject *self;
int location;
PPCODE:
gn_wap_setting entry;
HV *ws;
if (opt_v) warn ("GetWapSettings (%d)\n", location);
clear_data ();
Zero (&entry, 1, entry);
entry.location = location;
data->wap_setting = &entry;
unless (gn_sm_func (self, GN_OP_GetWAPSetting))
XSRETURN_UNDEF;
ws = newHV ();
hv_puti (ws, "location", location);
hv_puts (ws, "name", entry.name);
hv_puts (ws, "home", entry.home);
hv_puts (ws, "session", gn_wap_session2str (entry.session));
hv_puts (ws, "security", entry.security ? "yes" : "no");
hv_puts (ws, "bearer", gn_wap_bearer2str (entry.bearer));
hv_puts (ws, "call_type", gn_wap_call_type2str (entry.call_type));
hv_puts (ws, "call_speed", gn_wap_call_speed2str (entry.call_speed));
hv_puts (ws, "number", entry.number);
hv_puts (ws, "gsm_data_auth", gn_wap_authentication2str (entry.gsm_data_authentication));
hv_puts (ws, "gsm_data_ip", entry.gsm_data_ip);
hv_puts (ws, "gsm_data_login", gn_wap_login2str (entry.gsm_data_login));
hv_puts (ws, "gsm_data_pass", entry.gsm_data_password);
hv_puts (ws, "gsm_data_user", entry.gsm_data_username);
hv_puts (ws, "gprs_auth", gn_wap_authentication2str (entry.gprs_authentication));
hv_puts (ws, "gprs_connection", gn_wap_gprs2str (entry.gprs_connection));
hv_puts (ws, "gprs_ip", entry.gprs_ip);
hv_puts (ws, "gprs_login", gn_wap_login2str (entry.gprs_login));
hv_puts (ws, "gprs_pass", entry.gprs_password);
hv_puts (ws, "gprs_user", entry.gprs_username);
hv_puts (ws, "access_point", entry.access_point_name);
hv_puts (ws, "sms_servicenr", entry.sms_service_number);
hv_puts (ws, "sms_servernr", entry.sms_server_number);
XS_RETURNr (ws);
/* GetWapSettings */
void
WriteWapSetting (self, wh)
HvObject *self;
HV *wh;
PPCODE:
gn_error err;
gn_wap_setting entry;
char *buf;
STRLEN l;
clear_data ();
/* TODO: This funtion is untested */
Zero (&entry, 1, entry);
hv_geti (wh, "location", entry.location);
l = WAP_SETTING_NAME_MAX_LENGTH;
hv_getsl (wh, "number", l, entry.number);
hv_getsl (wh, "gsm_data_ip", l, entry.gsm_data_ip);
hv_getsl (wh, "gprs_ip", l, entry.gprs_ip);
hv_getsl (wh, "name", l, entry.name);
hv_getsl (wh, "gsm_data_pass", l, entry.gsm_data_password);
hv_getsl (wh, "gprs_pass", l, entry.gprs_password);
hv_getsl (wh, "sms_servicenr", l, entry.sms_service_number);
hv_getsl (wh, "sms_servernr", l, entry.sms_server_number);
l = WAP_SETTING_HOME_MAX_LENGTH;
hv_getsl (wh, "home", l, entry.home);
l = WAP_SETTING_USERNAME_MAX_LENGTH;
hv_getsl (wh, "gprs_user", l, entry.gprs_username);
hv_getsl (wh, "gsm_data_user", l, entry.gsm_data_username);
l = WAP_SETTING_APN_MAX_LENGTH;
hv_getsl (wh, "access_point", l, entry.access_point_name);
hv_getb (wh, "security", entry.security);
hv_gets (wh, "session", buf, l);
if (buf && (*buf == 'p' || *buf == 'P'))
entry.session = GN_WAP_SESSION_PERMANENT;
else
entry.session = GN_WAP_SESSION_TEMPORARY;
hv_gets (wh, "bearer", buf, l);
if (buf && (*buf == 'u' || *buf == 'U'))
entry.bearer = GN_WAP_BEARER_USSD;
else
if (buf && (*buf == 's' || *buf == 'S'))
entry.bearer = GN_WAP_BEARER_SMS;
else
if (buf && (*buf == 'g' || *buf == 'G') && (buf[1] == 'p' || buf[1] == 'P'))
entry.bearer = GN_WAP_BEARER_GPRS;
else
entry.bearer = GN_WAP_BEARER_GSMDATA;
hv_gets (wh, "gsm_data_auth", buf, l);
if (buf && (*buf == 's' || *buf == 'S'))
entry.gsm_data_authentication = GN_WAP_AUTH_SECURE;
else
entry.gsm_data_authentication = GN_WAP_AUTH_NORMAL;
hv_gets (wh, "gprs_auth", buf, l);
if (buf && (*buf == 's' || *buf == 'S'))
entry.gprs_authentication = GN_WAP_AUTH_SECURE;
else
entry.gprs_authentication = GN_WAP_AUTH_NORMAL;
hv_gets (wh, "call_type", buf, l);
if (buf && (*buf == 'i' || *buf == 'I'))
entry.call_type = GN_WAP_CALL_ISDN;
else
entry.call_type = GN_WAP_CALL_ANALOGUE;
hv_gets (wh, "call_speed", buf, l);
if (buf && *buf == '9')
entry.call_speed = GN_WAP_CALL_9600;
else
if (buf && *buf == '1')
entry.call_speed = GN_WAP_CALL_14400;
else
entry.call_speed = GN_WAP_CALL_AUTOMATIC;
hv_gets (wh, "gsm_data_login", buf, l);
if (buf && (*buf == 'm' || *buf == 'M'))
entry.gsm_data_login = GN_WAP_LOGIN_MANUAL;
else
entry.gsm_data_login = GN_WAP_LOGIN_AUTOLOG;
hv_gets (wh, "gprs_login", buf, l);
if (buf && (*buf == 'm' || *buf == 'M'))
entry.gprs_login = GN_WAP_LOGIN_MANUAL;
else
entry.gprs_login = GN_WAP_LOGIN_AUTOLOG;
hv_gets (wh, "gprs_connection", buf, l);
if (buf && (*buf == 'a' || *buf == 'A'))
entry.gprs_connection = GN_WAP_GPRS_ALWAYS;
else
entry.gprs_connection = GN_WAP_GPRS_WHENNEEDED;
data->wap_setting = &entry;
err = gn_sm_functions (GN_OP_WriteWAPSetting, data, state);
set_errori (err);
XS_RETURNi (err);
/* WriteWapSetting */
void
ActivateWapSetting (self, location)
HvObject *self;
int location;
PPCODE:
gn_error err;
gn_wap_setting entry;
clear_data ();
Zero (&entry, 1, entry);
entry.location = location;
data->wap_setting = &entry;
err = gn_sm_functions (GN_OP_ActivateWAPSetting, data, state);
set_errori (err);
XS_RETURNi (err);
/* ActivateWapSetting */
void
GetWapBookmark (self, location)
HvObject *self;
int location;
PPCODE:
gn_wap_bookmark entry;
if (opt_v) warn ("GetWapBookmark (%d)\n", location);
clear_data ();
Zero (&entry, 1, entry);
entry.location = location;
data->wap_bookmark = &entry;
if (gn_sm_func (self, GN_OP_GetWAPBookmark)) {
HV *wbm = newHV ();
hv_puti (wbm, "location", location);
hv_puts (wbm, "name", entry.name);
hv_puts (wbm, "url", entry.URL);
XS_RETURNr (wbm);
}
XSRETURN_UNDEF;
/* GetWapBookmark */
void
WriteWapBookmark (self, wh)
HvObject *self;
HV *wh;
PPCODE:
gn_wap_bookmark entry;
clear_data ();
Zero (&entry, 1, entry);
hv_geti (wh, "location", entry.location);
hv_getsl (wh, "name", WAP_NAME_MAX_LENGTH, entry.name);
hv_getsl (wh, "url", WAP_URL_MAX_LENGTH, entry.URL);
data->wap_bookmark = &entry;
if (gn_sm_func (self, GN_OP_WriteWAPBookmark))
XS_RETURNi (entry.location);
XSRETURN_UNDEF;
/* WriteWapBookmark */
void
DeleteWapBookmark (self, location)
HvObject *self;
int location;
PPCODE:
gn_error err;
gn_wap_bookmark entry;
clear_data ();
Zero (&entry, 1, entry);
entry.location = location;
data->wap_bookmark = &entry;
err = gn_sm_functions (GN_OP_DeleteWAPBookmark, data, state);
set_errori (err);
XS_RETURNi (err);
/* DeleteWapBookmark */
( run in 1.054 second using v1.01-cache-2.11-cpan-c221a9de4ec )