Add metering information from osmo-cc to B-Netz and C-Netz
Untested!
This commit is contained in:
parent
da9b0a0f8d
commit
2dcf10b1b1
|
@ -990,7 +990,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include "../libsample/sample.h"
|
||||
#include "../liblogging/logging.h"
|
||||
#include "../libmobile/call.h"
|
||||
|
|
|
@ -433,7 +433,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
#define TRENN_COUNT 5 /* min. 720 ms release 'Trennsignal' (according to FTZ 1727 Pfl 32 Clause 3.2.2.2.6) */
|
||||
|
||||
#define METERING_DURATION 0,140000 /* duration of metering pulse (according to FTZ 1727 Pfl 32 Clause 3.2.6.6.1) */
|
||||
#define METERING_DURATION_US 140000 /* duration of metering pulse (according to FTZ 1727 Pfl 32 Clause 3.2.6.6.1) */
|
||||
#define METERING_START 1,0 /* start metering 1 second after call start */
|
||||
|
||||
const char *bnetz_state_name(enum bnetz_state state)
|
||||
|
@ -419,9 +419,12 @@ void bnetz_receive_tone(bnetz_t *bnetz, int bit)
|
|||
osmo_timer_del(&bnetz->timer);
|
||||
bnetz_new_state(bnetz, BNETZ_GESPRAECH);
|
||||
bnetz_set_dsp_mode(bnetz, DSP_MODE_AUDIO);
|
||||
/* start metering pulses if forced */
|
||||
if (bnetz->metering < 0)
|
||||
/* start metering pulses, if forced (mobile terminating call) */
|
||||
if (bnetz->metering < 0) {
|
||||
bnetz->metering_tv.tv_sec = abs(bnetz->metering);
|
||||
bnetz->metering_tv.tv_usec = 0;
|
||||
osmo_timer_schedule(&bnetz->timer, METERING_START);
|
||||
}
|
||||
call_up_answer(bnetz->callref, bnetz->station_id);
|
||||
break;
|
||||
}
|
||||
|
@ -584,9 +587,6 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm)
|
|||
osmo_timer_del(&bnetz->timer);
|
||||
bnetz_set_dsp_mode(bnetz, DSP_MODE_AUDIO);
|
||||
bnetz_new_state(bnetz, BNETZ_GESPRAECH);
|
||||
/* start metering pulses if enabled and supported by phone or if forced */
|
||||
if (bnetz->metering < 0 || (bnetz->metering > 0 && (bnetz->dial_type == DIAL_TYPE_METER || bnetz->dial_type == DIAL_TYPE_METER_MUENZ)))
|
||||
osmo_timer_schedule(&bnetz->timer, METERING_START);
|
||||
|
||||
/* setup call */
|
||||
LOGP(DBNETZ, LOGL_INFO, "Setup call to network.\n");
|
||||
|
@ -635,6 +635,7 @@ lets see, if noise will not generate a release signal....
|
|||
static void bnetz_timeout(void *data)
|
||||
{
|
||||
bnetz_t *bnetz = data;
|
||||
int to_sec, to_usec;
|
||||
|
||||
switch (bnetz->state) {
|
||||
case BNETZ_WAHLABRUF:
|
||||
|
@ -673,12 +674,21 @@ static void bnetz_timeout(void *data)
|
|||
case DSP_MODE_AUDIO:
|
||||
/* turn on merting pulse */
|
||||
bnetz_set_dsp_mode(bnetz, DSP_MODE_AUDIO_METER);
|
||||
osmo_timer_schedule(&bnetz->timer, METERING_DURATION);
|
||||
osmo_timer_schedule(&bnetz->timer, 0, METERING_DURATION_US);
|
||||
break;
|
||||
case DSP_MODE_AUDIO_METER:
|
||||
/* turn off and wait given seconds for next metering cycle */
|
||||
bnetz_set_dsp_mode(bnetz, DSP_MODE_AUDIO);
|
||||
osmo_timer_schedule(&bnetz->timer, (double)abs(bnetz->metering) - METERING_DURATION);
|
||||
/* if metering has been disabled due to disconnect (must be at least 1s) */
|
||||
if (!bnetz->metering_tv.tv_sec)
|
||||
break;
|
||||
to_sec = bnetz->metering_tv.tv_sec;
|
||||
to_usec = bnetz->metering_tv.tv_usec - METERING_DURATION_US;
|
||||
if (to_usec < 0) {
|
||||
to_usec += 1000000;
|
||||
to_sec--;
|
||||
}
|
||||
osmo_timer_schedule(&bnetz->timer, to_sec, to_usec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -726,8 +736,35 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int callref, struct timeval *tv_meter)
|
||||
{
|
||||
sender_t *sender;
|
||||
bnetz_t *bnetz;
|
||||
|
||||
LOGP(DBNETZ, LOGL_INFO, "Call has been answered by network.\n");
|
||||
|
||||
for (sender = sender_head; sender; sender = sender->next) {
|
||||
bnetz = (bnetz_t *) sender;
|
||||
if (bnetz->callref == callref)
|
||||
break;
|
||||
}
|
||||
if (!sender) {
|
||||
LOGP(DBNETZ, LOGL_NOTICE, "Incoming answer, but no callref!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* At least tone second! */
|
||||
if (tv_meter->tv_sec) {
|
||||
LOGP(DBNETZ, LOGL_INFO, "Network starts metering pulses every %lu.%03lu seconds.\n", tv_meter->tv_sec, tv_meter->tv_usec / 1000);
|
||||
memcpy(&bnetz->metering_tv, tv_meter, sizeof(bnetz->metering_tv));
|
||||
osmo_timer_schedule(&bnetz->timer, METERING_START);
|
||||
} else if (bnetz->metering < 0 || (bnetz->metering > 0 && (bnetz->dial_type == DIAL_TYPE_METER || bnetz->dial_type == DIAL_TYPE_METER_MUENZ))) {
|
||||
/* start metering pulses if enabled and supported by phone or if forced (mobile origninating call) */
|
||||
LOGP(DBNETZ, LOGL_INFO, "Command line options starts metering pulses every %d seconds.\n", abs(bnetz->metering));
|
||||
bnetz->metering_tv.tv_sec = abs(bnetz->metering);
|
||||
bnetz->metering_tv.tv_usec = 0;
|
||||
osmo_timer_schedule(&bnetz->timer, METERING_START);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call control sends disconnect (with tones).
|
||||
|
@ -753,8 +790,12 @@ void call_down_disconnect(int callref, int cause)
|
|||
}
|
||||
|
||||
/* Release when not active */
|
||||
if (bnetz->state == BNETZ_GESPRAECH)
|
||||
if (bnetz->state == BNETZ_GESPRAECH) {
|
||||
/* stop metering */
|
||||
bnetz->metering_tv.tv_sec = 0;
|
||||
bnetz->metering_tv.tv_usec = 0;
|
||||
return;
|
||||
}
|
||||
switch (bnetz->state) {
|
||||
case BNETZ_SELEKTIVRUF_EIN:
|
||||
case BNETZ_SELEKTIVRUF_AUS:
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct bnetz {
|
|||
/* system info */
|
||||
int gfs; /* 'Gruppenfreisignal' */
|
||||
int metering; /* use metering pulses in seconds 0 = off, < 0 = force */
|
||||
struct timeval metering_tv; /* time to repeat metering pulse (current call) */
|
||||
|
||||
/* switch sender to channel 19 */
|
||||
char paging_file[256]; /* if set, write to given file to switch to channel 19 or back */
|
||||
|
|
|
@ -58,6 +58,8 @@ void print_help(const char *arg0)
|
|||
printf(" Pulses will be sent on outgoing calls only and only if mobile station\n");
|
||||
printf(" requests it. Use negative value to force metering pulses for all calls.\n");
|
||||
printf(" (default = %d)\n", metering);
|
||||
printf(" If metering pulses are sent via Osmo-CC interface, pulses are always\n");
|
||||
printf(" sent, if mobile station requests it. This overrides this option.\n");
|
||||
printf(" -P --paging tone | notone | positive | negative | <file>=<on>:<off>\n");
|
||||
printf(" Send a tone, give a signal or write to a file when switching to\n");
|
||||
printf(" channel 19. (paging the phone).\n");
|
||||
|
|
|
@ -667,8 +667,35 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int callref, struct timeval *tv_meter)
|
||||
{
|
||||
sender_t *sender;
|
||||
cnetz_t *cnetz;
|
||||
transaction_t *trans;
|
||||
|
||||
LOGP(DCNETZ, LOGL_INFO, "Call has been answered by network.\n");
|
||||
|
||||
for (sender = sender_head; sender; sender = sender->next) {
|
||||
cnetz = (cnetz_t *) sender;
|
||||
trans = search_transaction_callref(cnetz, callref);
|
||||
if (trans)
|
||||
break;
|
||||
}
|
||||
if (!sender) {
|
||||
LOGP(DCNETZ, LOGL_NOTICE, "Incoming answer, but no callref!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* At least tone second! */
|
||||
if (tv_meter->tv_sec) {
|
||||
LOGP(DCNETZ, LOGL_INFO, "Network starts metering pulses every %lu.%03lu seconds.\n", tv_meter->tv_sec, tv_meter->tv_usec / 1000);
|
||||
trans->meter_start = get_time();
|
||||
trans->metering_time = (double)tv_meter->tv_sec + (double)tv_meter->tv_usec / 1000000.0;
|
||||
} else if (cnetz->metering) {
|
||||
LOGP(DCNETZ, LOGL_INFO, "Command line options starts metering pulses every %d seconds.\n", cnetz->metering);
|
||||
trans->meter_start = get_time();
|
||||
trans->metering_time = (double)cnetz->metering;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call control sends disconnect (with tones).
|
||||
|
@ -700,6 +727,8 @@ void call_down_disconnect(int callref, int cause)
|
|||
|
||||
switch (cnetz->dsp_mode) {
|
||||
case DSP_MODE_SPK_V:
|
||||
/* stop metering */
|
||||
trans->meter_end = get_time();
|
||||
return;
|
||||
case DSP_MODE_SPK_K:
|
||||
LOGP(DCNETZ, LOGL_INFO, "Call control disconnects on speech channel, releasing towards mobile station.\n");
|
||||
|
@ -1667,11 +1696,11 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
|
|||
|
||||
memset(&telegramm, 0, sizeof(telegramm));
|
||||
|
||||
if (cnetz->metering) {
|
||||
double now = get_time();
|
||||
if (!trans->call_start)
|
||||
trans->call_start = now;
|
||||
meter = (now - trans->call_start) / (double)cnetz->metering + 1;
|
||||
if (trans->metering_time) {
|
||||
/* get end time. if not set, use current time. (still running) */
|
||||
double end = (trans->meter_end) ? : get_time();
|
||||
/* add one unit, because when metering is started, the first unit is counted. */
|
||||
meter = (end - trans->meter_start) / (double)trans->metering_time + 1.0;
|
||||
}
|
||||
|
||||
telegramm.max_sendeleistung = cnetz_power2bits(cnetz->ms_power);
|
||||
|
|
|
@ -82,7 +82,7 @@ struct cnetz {
|
|||
int response_valid; /* expect authorizaton response */
|
||||
uint64_t response; /* authorization response */
|
||||
int warteschlange; /* use queue */
|
||||
int metering; /* use metering pulses in seconds 0 = off */
|
||||
int metering; /* send metering units in seconds 0 = off */
|
||||
|
||||
/* all cnetz states */
|
||||
enum cnetz_state state; /* main state of sender */
|
||||
|
|
|
@ -124,6 +124,8 @@ void print_help(const char *arg0)
|
|||
printf(" -G --gebuehren <seconds> | 0\n");
|
||||
printf(" Increment metering counter every given number of seconds.\n");
|
||||
printf(" To turn off, use 0. (default = %d)\n", metering);
|
||||
printf(" If metering pulses are sent via Osmo-CC interface, pulses are always\n");
|
||||
printf(" increment metering counter. This overrides this option.\n");
|
||||
printf(" -V --voice-deviation <2400..4000 Hz>\n");
|
||||
printf(" It is unclear what the actual voice deviation is. Please increase, if\n");
|
||||
printf(" mobile's earpiece is too quiet and the microphone is too loud.\n");
|
||||
|
|
|
@ -54,7 +54,9 @@ typedef struct transaction {
|
|||
int mo_call; /* flags a moile originating call */
|
||||
int mt_call; /* flags a moile terminating call */
|
||||
int page_failed; /* failed to get a response from MS */
|
||||
double call_start; /* when did the call start? (used for metering) */
|
||||
double metering_time; /* time between units (0.0 if no metering set) */
|
||||
double meter_start; /* when did the metering start? (0.0 if not yet started) */
|
||||
double meter_end; /* when did the metering end? (0.0 if not yet ended) */
|
||||
int queue_position; /* to find next transaction in queue */
|
||||
double rf_level_db; /* level of first contact, so we can detect correct channel at multiple receptions */
|
||||
} transaction_t;
|
||||
|
|
|
@ -684,7 +684,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
euro_call_t *call;
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1360,7 +1360,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int callref)
|
||||
void call_down_answer(int callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
transaction_t *trans;
|
||||
uint8_t opcode, *data;
|
||||
|
|
|
@ -263,7 +263,7 @@ void call_down_clock(void) {}
|
|||
|
||||
int call_down_setup(int __attribute__((unused)) callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char __attribute__((unused)) *dialing) { return 0; }
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref) { }
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter) { }
|
||||
|
||||
void call_down_disconnect(int __attribute__((unused)) callref, int __attribute__((unused)) cause) { }
|
||||
|
||||
|
|
|
@ -845,7 +845,7 @@ int call_down_setup(int __attribute__((unused)) callref, const char *caller_id,
|
|||
return -CAUSE_NORMAL;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1203,7 +1203,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -660,9 +660,10 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref,
|
|||
{
|
||||
process_t *process;
|
||||
uint8_t coding, location, progress, isdn_cause, socket_cause;
|
||||
uint16_t sip_cause;
|
||||
uint16_t sip_cause, metering_connect_units, metering_unit_period_decisecs;
|
||||
uint8_t type, plan, present, screen, caller_type;
|
||||
char caller_id[33], number[33];
|
||||
struct timeval tv_meter = {};
|
||||
const char *suffix, *invalid;
|
||||
int rc;
|
||||
|
||||
|
@ -704,6 +705,13 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref,
|
|||
return;
|
||||
}
|
||||
|
||||
/* get metering information */
|
||||
rc = osmo_cc_get_ie_metering(msg, 0, &metering_connect_units, &metering_unit_period_decisecs);
|
||||
if (rc >= 0) {
|
||||
tv_meter.tv_sec = metering_unit_period_decisecs / 10;
|
||||
tv_meter.tv_usec = (metering_unit_period_decisecs % 10) / 10;
|
||||
}
|
||||
|
||||
switch(msg->type) {
|
||||
case OSMO_CC_MSG_SETUP_REQ:
|
||||
{
|
||||
|
@ -852,7 +860,7 @@ void ll_msg_cb(osmo_cc_endpoint_t __attribute__((unused)) *ep, uint32_t callref,
|
|||
goto nego_failed;
|
||||
new_state_process(callref, PROCESS_CONNECT);
|
||||
LOGP(DCALL, LOGL_INFO, "Call answered\n");
|
||||
call_down_answer(callref);
|
||||
call_down_answer(callref, &tv_meter);
|
||||
indicate_answer_ack(callref);
|
||||
break;
|
||||
case OSMO_CC_MSG_DISC_REQ:
|
||||
|
|
|
@ -31,7 +31,7 @@ void call_tone_recall(int callref, int on);
|
|||
|
||||
/* send messages */
|
||||
int call_down_setup(int callref, const char *caller_id, enum number_type caller_type, const char *dialing);
|
||||
void call_down_answer(int callref);
|
||||
void call_down_answer(int callref, struct timeval *tv_meter);
|
||||
void call_down_disconnect(int callref, int cause);
|
||||
void call_down_release(int callref, int cause);
|
||||
|
||||
|
|
|
@ -1598,7 +1598,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1869,7 +1869,7 @@ int sms_out_setup(char *dialing, const char *caller_id, enum number_type caller_
|
|||
return _out_setup(0, caller_id, caller_type, dialing, sms);
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -541,7 +541,7 @@ void pocsag_msg_done(pocsag_t *pocsag)
|
|||
pocsag_scan_or_loopback(pocsag);
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1434,7 +1434,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
}
|
||||
|
||||
/* Call control answers call toward station mobile. */
|
||||
void call_down_answer(int callref)
|
||||
void call_down_answer(int callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
sender_t *sender;
|
||||
r2000_t *r2000;
|
||||
|
|
|
@ -358,7 +358,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void call_down_answer(int __attribute__((unused)) callref)
|
||||
void call_down_answer(int __attribute__((unused)) callref, struct timeval __attribute__((unused)) *tv_meter)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue