diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen.h b/src/mod/endpoints/mod_gsmopen/gsmopen.h index f56866a587..80bee58265 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen.h +++ b/src/mod/endpoints/mod_gsmopen/gsmopen.h @@ -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]; diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp index 8e618c50ab..eb2e8c75d5 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp @@ -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) { diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index a17c539b06..82b2eb39c6 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -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);