Merge pull request #52 in FS/freeswitch from ~DDRAGIC/freeswitch:gsmopen_feature_additions to master

* commit 'a9b2e061dcd1d95322d27e169ac2f0016aa628a3':
  mod_gsmopen: clean up "gsm list" output a little
  mod_gsmopen: convert reported RSSI from AT+CSQ to dBm.
  mod_gsmopen: get device manufacturer, model and firmware version info.
  mod_gsmopen: add support for reading own number from ON phonebook using AT+CNUM
  mod_gsmopen: add AT+COPS support to get operator name.
This commit is contained in:
Giovanni Maruzzelli 2014-09-26 10:17:14 -05:00
commit 4ce990504e
3 changed files with 145 additions and 4 deletions

View File

@ -445,10 +445,21 @@ struct private_object {
int roaming_registered;
int not_registered;
int got_signal;
int signal_strength;
char imei[128];
int requesting_imei;
char imsi[128];
int requesting_imsi;
char operator_name[128];
int requesting_operator_name;
char subscriber_number[128];
int requesting_subscriber_number;
char device_mfg[128];
int requesting_device_mfg;
char device_model[128];
int requesting_device_model;
char device_firmware[128];
int requesting_device_firmware;
int network_creg_not_supported;
char creg[128];

View File

@ -330,17 +330,29 @@ int gsmopen_serial_config_AT(private_t *tech_pvt)
}
/* phone manufacturer */
tech_pvt->requesting_device_mfg = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMI");
tech_pvt->requesting_device_mfg = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CGMI failed\n", GSMOPEN_P_LOG);
}
/* phone model */
tech_pvt->requesting_device_model = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMM");
tech_pvt->requesting_device_model = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CGMM failed\n", GSMOPEN_P_LOG);
}
/* phone firmware */
tech_pvt->requesting_device_firmware = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMR");
tech_pvt->requesting_device_firmware = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CGMR failed\n", GSMOPEN_P_LOG);
}
/* signal network registration with a +CREG unsolicited msg */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG=1");
if (res) {
@ -358,6 +370,23 @@ int gsmopen_serial_config_AT(private_t *tech_pvt)
if (res) {
DEBUGA_GSMOPEN("AT+CSQ failed\n", GSMOPEN_P_LOG);
}
/* operator name */
tech_pvt->requesting_operator_name = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+COPS?");
tech_pvt->requesting_operator_name = 0;
if (res) {
DEBUGA_GSMOPEN("AT+COPS? failed\n", GSMOPEN_P_LOG);
}
/* subscriber number */
tech_pvt->requesting_subscriber_number = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNUM");
tech_pvt->requesting_subscriber_number = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CNUM failed, continue\n", GSMOPEN_P_LOG);
}
/* IMEI */
tech_pvt->requesting_imei = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+GSN");
@ -967,6 +996,12 @@ int gsmopen_serial_read_AT(private_t *tech_pvt, int look_for_ack, int timeout_us
tech_pvt->got_signal = 2;
}
if (signal_quality == 99) {
tech_pvt->signal_strength = 0;
} else {
tech_pvt->signal_strength = (signal_quality * 2) - 113; /* RSSI [dBm] = reported_value * 2 - 113dB */
}
}
}
@ -1006,6 +1041,58 @@ int gsmopen_serial_read_AT(private_t *tech_pvt, int look_for_ack, int timeout_us
}
if ((strncmp(tech_pvt->line_array.result[i], "+COPS:", 6) == 0)) {
int mode, format, rat, err;
char oper[128] = "";
mode = format = rat = err = 0;
err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d,%*[\"]%[^\"]%*[\"],%d", &mode, &format, &oper, &rat);
if (err < 3) {
DEBUGA_GSMOPEN("|%s| is not formatted as: |+COPS: xx,yy,ssss,nn|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if (option_debug > 1) {
DEBUGA_GSMOPEN("|%s| +COPS: : Mode %d, Format %d, Operator %s, Rat %d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], mode, format, oper, rat);
}
/* if we are requesting the operator name, copy it over */
if (tech_pvt->requesting_operator_name)
strncpy(tech_pvt->operator_name, oper, sizeof(tech_pvt->operator_name));
}
if ((strncmp(tech_pvt->line_array.result[i], "+CNUM:", 6) == 0) || (strncmp(tech_pvt->line_array.result[i], "ERROR+CNUM:", 11) == 0)) {
int skip_chars, err, type;
char number[128] = "";
char *in_ptr, *out_ptr;
skip_chars = err = type = 0;
in_ptr = out_ptr = number;
/* +CNUM or ERROR+CNUM ? */
if ((strncmp(tech_pvt->line_array.result[i], "+CNUM:", 6) == 0))
skip_chars = 7;
else
skip_chars = 12;
err = sscanf(&tech_pvt->line_array.result[i][skip_chars], "%*[^,],%[^,],%d", &number, &type);
/* Remove any double quotes */
while (*in_ptr) {
if (*in_ptr != '\"') *out_ptr++ = *in_ptr;
in_ptr++;
}
*out_ptr = '\0';
if (err < 2) {
DEBUGA_GSMOPEN("|%s| is not formatted as: |+CNUM: \"Name\", \"+39025458068\", 145|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if (option_debug) {
DEBUGA_GSMOPEN("|%s| +CNUM: Subscriber number = %s, Type = %d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], number, type);
}
/* Copy only the first number listed if there are more then one */
if (tech_pvt->requesting_subscriber_number && !strlen(tech_pvt->subscriber_number))
strncpy(tech_pvt->subscriber_number, number, sizeof(tech_pvt->subscriber_number));
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMGW:", 6) == 0)) {
int err;
@ -1611,13 +1698,33 @@ int gsmopen_serial_read_AT(private_t *tech_pvt, int look_for_ack, int timeout_us
}
}
/* if we are requesting IMSI, put the line into the imei buffer if the line is not "OK" or "ERROR" */
/* if we are requesting IMSI, put the line into the imsi buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->requesting_imsi && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMSI */
strncpy(tech_pvt->imsi, tech_pvt->line_array.result[i], sizeof(tech_pvt->imsi));
}
}
/* if we are requesting device manufacturer, model or firmware version,
* put the line into the buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->requesting_device_mfg && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) {
strncpy(tech_pvt->device_mfg, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_mfg));
}
}
if (tech_pvt->requesting_device_model && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) {
strncpy(tech_pvt->device_model, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_model));
}
}
if (tech_pvt->requesting_device_firmware && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) {
strncpy(tech_pvt->device_firmware, tech_pvt->line_array.result[i], sizeof(tech_pvt->device_firmware));
}
}
/* if we are reading an sms message from memory, put the line into the sms buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->reading_sms_msg > 1 && at_ack == -1) {

View File

@ -2225,8 +2225,8 @@ SWITCH_STANDARD_API(gsm_function)
unsigned int ob_failed = 0;
char next_flag_char = ' ';
stream->write_function(stream, "F ID\t Name \tIB (F/T) OB (F/T)\tState\tCallFlw\t\tUUID\n");
stream->write_function(stream, "= ====\t ======== \t======= =======\t======\t============\t======\n");
stream->write_function(stream, "F ID Name Operator IMEI IB (F/T) OB (F/T) State CallFlw UUID\n");
stream->write_function(stream, "= == ========== ================ =============== ========= ========= ======= =============== ====\n");
for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
@ -2239,9 +2239,11 @@ SWITCH_STANDARD_API(gsm_function)
stream->write_function(stream,
"%c %d\t[%6s]\t%3u/%u\t%6u/%u\t%s\t%s\t%s\n",
"%c %-2d %-10s %-16.16s %-15s %4u/%-4u %4u/%-4u %-7s %-15s %s\n",
next_flag_char,
i, globals.GSMOPEN_INTERFACES[i].name,
globals.GSMOPEN_INTERFACES[i].operator_name,
globals.GSMOPEN_INTERFACES[i].imei,
globals.GSMOPEN_INTERFACES[i].ib_failed_calls,
globals.GSMOPEN_INTERFACES[i].ib_calls,
globals.GSMOPEN_INTERFACES[i].ob_failed_calls,
@ -2421,8 +2423,15 @@ SWITCH_STANDARD_API(gsmopen_dump_function)
}
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal);
stream->write_function(stream, "got_signal = %s\n", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength);
stream->write_function(stream, "signal_strength = %s\n", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running);
stream->write_function(stream, "running = %s\n", value);
stream->write_function(stream, "subscriber_number = %s\n", tech_pvt->subscriber_number);
stream->write_function(stream, "device_manufacturer = %s\n", tech_pvt->device_mfg);
stream->write_function(stream, "device_model = %s\n", tech_pvt->device_model);
stream->write_function(stream, "device_firmware = %s\n", tech_pvt->device_firmware);
stream->write_function(stream, "operator = %s\n", tech_pvt->operator_name);
stream->write_function(stream, "imei = %s\n", tech_pvt->imei);
stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead);
@ -2479,8 +2488,15 @@ SWITCH_STANDARD_API(gsmopen_dump_function)
}
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal);
stream->write_function(stream, "got_signal = %s\n", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength);
stream->write_function(stream, "signal_strength = %s\n", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running);
stream->write_function(stream, "running = %s\n", value);
stream->write_function(stream, "subscriber_number = %s\n", tech_pvt->subscriber_number);
stream->write_function(stream, "device_manufacturer = %s\n", tech_pvt->device_mfg);
stream->write_function(stream, "device_model = %s\n", tech_pvt->device_model);
stream->write_function(stream, "device_firmware = %s\n", tech_pvt->device_firmware);
stream->write_function(stream, "operator = %s\n", tech_pvt->operator_name);
stream->write_function(stream, "imei = %s\n", tech_pvt->imei);
stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead);
@ -2808,8 +2824,15 @@ int dump_event_full(private_t *tech_pvt, int is_alarm, int alarm_code, const cha
}
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->got_signal);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "got_signal", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->signal_strength);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "signal_strength", value);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->running);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "running", value);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subscriber_number", tech_pvt->subscriber_number);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_manufacturer", tech_pvt->device_mfg);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_model", tech_pvt->device_model);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device_firmware", tech_pvt->device_firmware);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "operator", tech_pvt->operator_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imei", tech_pvt->imei);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imsi", tech_pvt->imsi);
snprintf(value, sizeof(value) - 1, "%d", tech_pvt->controldev_dead);