196 lines
5.5 KiB
C
196 lines
5.5 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include "../libsample/sample.h"
|
|
#include "amps.h"
|
|
#include "frame.h"
|
|
#include "main.h"
|
|
|
|
static struct sysinfo_reg_incr default_reg_incr = {
|
|
450,
|
|
};
|
|
|
|
static struct sysinfo_loc_area default_loc_area = {
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
static struct sysinfo_new_acc default_new_acc = {
|
|
0,
|
|
};
|
|
|
|
static struct sysinfo_overload default_overload = {
|
|
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
|
};
|
|
|
|
static struct sysinfo_acc_type default_acc_type = {
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
static struct sysinfo_acc_attempt default_acc_attempt = {
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
};
|
|
|
|
void init_sysinfo(amps_si *si, int cmac, int vmac, int dtx, int dcc, int sid1, int regh, int regr, int pureg, int pdreg, int locaid, int regincr, int bis)
|
|
{
|
|
int i;
|
|
|
|
memset(si, 0, sizeof(*si));
|
|
|
|
/* how oftern to repeat the overhead train */
|
|
if (!tacs)
|
|
si->overhead_repeat = 17;
|
|
else
|
|
si->overhead_repeat = 14;
|
|
|
|
/* all words */
|
|
si->dcc = dcc;
|
|
/* VC assginment */
|
|
si->vmac = vmac;
|
|
|
|
/* filler */
|
|
si->filler.cmac = cmac;
|
|
si->filler.sdcc1 = 0;
|
|
si->filler.sdcc2 = 0;
|
|
si->filler.wfom = (bis) ? 0 : 1; /* must be set to ignore B/I bit */
|
|
|
|
/* Word 1 */
|
|
si->word1.sid1 = sid1;
|
|
si->word1.ep = 0; /* shall be 0 */
|
|
si->word1.auth = 0;
|
|
si->word1.pci = 0;
|
|
|
|
/* Word 2 */
|
|
si->word2.s = 1;
|
|
si->word2.e = 1;
|
|
si->word2.regh = regh;
|
|
si->word2.regr = regr;
|
|
si->word2.dtx = dtx; /* DTX seems not to work with my White Dynatac 8000 */
|
|
si->word2.n_1 = 20;
|
|
si->word2.rcf = (bis) ? 0 : 1; /* must be set to ignore B/I bit */
|
|
si->word2.cpa = 1; /* must be set for combined CC+PC */
|
|
si->word2.cmax_1 = 20;
|
|
|
|
/* registration increment */
|
|
si->reg_incr.regincr = regincr;
|
|
|
|
/* location area */
|
|
si->loc_area.pureg = pureg;
|
|
si->loc_area.pdreg = pdreg;
|
|
if (locaid >= 0) {
|
|
si->loc_area.lreg = 1;
|
|
si->loc_area.locaid = locaid;
|
|
}
|
|
|
|
/* new access channel set */
|
|
si->new_acc.newacc = 0;
|
|
|
|
/* overload control */
|
|
for (i = 0; i < 16; i++)
|
|
si->overload.olc[i] = 1;
|
|
|
|
/* Acces Tyoe */
|
|
/* 'bis' must be 0, so the phone does not wait for busy bit.
|
|
* We cannot respond with B/I fast enough due to processing delay.
|
|
* So we don't set the B/I bit to busy on reception of message.
|
|
* The access type message (including this 'bis') must also be included.
|
|
*/
|
|
si->acc_type.bis = bis; /* must be clear to ignore B/I bit */
|
|
si->acc_type.pci_home = 0; /* if set, bscap must allso be set */
|
|
si->acc_type.pci_roam = 0; /* if set, bscap must allso be set */
|
|
si->acc_type.bspc = 0;
|
|
si->acc_type.bscap = 0;
|
|
|
|
/* access attempt parameters */
|
|
si->acc_attempt.maxbusy_pgr = 10;
|
|
si->acc_attempt.maxsztr_pgr = 10;
|
|
si->acc_attempt.maxbusy_other = 10;
|
|
si->acc_attempt.maxsztr_other = 10;
|
|
|
|
/* registration ID */
|
|
si->reg_id.regid = 1000;
|
|
}
|
|
|
|
void prepare_sysinfo(amps_si *si)
|
|
{
|
|
int i = 0;
|
|
|
|
si->type[i++] = SYSINFO_WORD1;
|
|
si->type[i++] = SYSINFO_WORD2;
|
|
si->type[i++] = SYSINFO_REG_ID;
|
|
/* include only messages that differ from default */
|
|
if (!!memcmp(&si->reg_incr, &default_reg_incr, sizeof(si->reg_incr)))
|
|
si->type[i++] = SYSINFO_REG_INCR;
|
|
if (!!memcmp(&si->loc_area, &default_loc_area, sizeof(si->loc_area)))
|
|
si->type[i++] = SYSINFO_LOC_AREA;
|
|
if (!!memcmp(&si->new_acc, &default_new_acc, sizeof(si->new_acc)))
|
|
si->type[i++] = SYSINFO_NEW_ACC;
|
|
if (!!memcmp(&si->overload, &default_overload, sizeof(si->overload)))
|
|
si->type[i++] = SYSINFO_OVERLOAD;
|
|
if (!!memcmp(&si->acc_type, &default_acc_type, sizeof(si->acc_type)))
|
|
si->type[i++] = SYSINFO_ACC_TYPE;
|
|
if (!!memcmp(&si->acc_attempt, &default_acc_attempt, sizeof(si->acc_attempt)))
|
|
si->type[i++] = SYSINFO_ACC_ATTEMPT;
|
|
si->num = i; /* train is running */
|
|
si->count = 0; /* first message in train */
|
|
if (i > (int)(sizeof(si->type) / sizeof(si->type[0]))) {
|
|
fprintf(stderr, "si type array overflow, pleas fix!\n");
|
|
abort();
|
|
}
|
|
}
|
|
|
|
uint64_t get_sysinfo(amps_si *si)
|
|
{
|
|
int count, nawc, end = 0;
|
|
time_t ti = time(NULL);
|
|
|
|
count = si->count;
|
|
|
|
if (++si->count == si->num) {
|
|
end = 1;
|
|
si->num = 0; /* train is over */
|
|
}
|
|
|
|
switch (si->type[count]) {
|
|
case SYSINFO_WORD1:
|
|
nawc = si->num - 1;
|
|
if (!tacs)
|
|
return amps_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc);
|
|
else
|
|
return tacs_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc);
|
|
case SYSINFO_WORD2:
|
|
return amps_encode_word2_system(si->dcc, si->word2.s, si->word2.e, si->word2.regh, si->word2.regr, si->word2.dtx, si->word2.n_1, si->word2.rcf, si->word2.cpa, si->word2.cmax_1, end);
|
|
case SYSINFO_REG_ID:
|
|
/* use time stamp to generate regid */
|
|
si->reg_id.regid = ti & 0xfffff;
|
|
return amps_encode_registration_id(si->dcc, si->reg_id.regid, end);
|
|
case SYSINFO_REG_INCR:
|
|
return amps_encode_registration_increment(si->dcc, si->reg_incr.regincr, end);
|
|
case SYSINFO_LOC_AREA:
|
|
return amps_encode_location_area(si->dcc, si->loc_area.pureg, si->loc_area.pdreg, si->loc_area.lreg, si->loc_area.locaid, end);
|
|
case SYSINFO_NEW_ACC:
|
|
return amps_encode_new_access_channel_set(si->dcc, si->new_acc.newacc, end);
|
|
case SYSINFO_OVERLOAD:
|
|
return amps_encode_overload_control(si->dcc, si->overload.olc, end);
|
|
case SYSINFO_ACC_TYPE:
|
|
return amps_encode_access_type(si->dcc, si->acc_type.bis, si->acc_type.pci_home, si->acc_type.pci_roam, si->acc_type.bspc, si->acc_type.bscap, end);
|
|
case SYSINFO_ACC_ATTEMPT:
|
|
return amps_encode_access_attempt(si->dcc, si->acc_attempt.maxbusy_pgr, si->acc_attempt.maxsztr_pgr, si->acc_attempt.maxbusy_other, si->acc_attempt.maxsztr_other, end);
|
|
}
|
|
|
|
fprintf(stderr, "get_sysinfo unknown type, please fix!\n");
|
|
abort();
|
|
}
|
|
|