This shows you the differences between two versions of the page.
— | sdk:scripts:dynamic-operator [2015/05/05 15:04] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== SDK Script dynamic-operator.are ====== | ||
+ | <code c dynamic-operator.are> | ||
+ | /* DESC: This script will scan Mobile2 and dial the appropriate SIM on Mobile1 | ||
+ | * Copyright (C) 2013 NetModule AG, Switzerland | ||
+ | * | ||
+ | */ | ||
+ | |||
+ | template operator { | ||
+ | prio; | ||
+ | sim; | ||
+ | lai; | ||
+ | apn; | ||
+ | username; | ||
+ | password; | ||
+ | |||
+ | int operator (int p, int s, string l, string a, string usr, string pwd) { | ||
+ | this.prio = p; | ||
+ | this.sim = s; | ||
+ | this.lai = l; | ||
+ | this.apn = a; | ||
+ | this.username = usr; | ||
+ | this.password = pwd; | ||
+ | return 0; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | ME = argv[0]; | ||
+ | ARGV1 = argv[1]; | ||
+ | FORCE = 0; /* force operator switch even if wanlink is up */ | ||
+ | VALID_ONLY = 1; /* only register to networks which are allowed by SIM */ | ||
+ | SCAN_INTERVAL = 30; /* network scan interval in seconds */ | ||
+ | TEST = 0; /* run test */ | ||
+ | |||
+ | /* example list of operators */ | ||
+ | OPCNT = 0; | ||
+ | OPERATORS = mkarray(); | ||
+ | |||
+ | OPERATORS[OPCNT++] = new operator | ||
+ | (1, /* prio */ | ||
+ | | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | OPERATORS[OPCNT++] = new operator | ||
+ | (2, /* prio */ | ||
+ | | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | OPERATORS[OPCNT++] = new operator | ||
+ | (3, /* prio */ | ||
+ | | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | "" | ||
+ | ); | ||
+ | |||
+ | |||
+ | /* creates file at path */ | ||
+ | int touch (string path) | ||
+ | { | ||
+ | fd = open(path, O_CREAT | O_WRONLY); | ||
+ | if (fd < 0) return -1; | ||
+ | close(fd); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | /* checks if path exists */ | ||
+ | int exists (string path) | ||
+ | { | ||
+ | fd = open(path, O_RDONLY); | ||
+ | if (fd < 0) return 0; | ||
+ | close(fd); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | /* copies a file */ | ||
+ | int copy (string from, string to) | ||
+ | { | ||
+ | fpin = fopen(from, " | ||
+ | if (is_void(fpin)) { | ||
+ | nb_syslog(" | ||
+ | return -1; | ||
+ | } | ||
+ | fpout = fopen(to, " | ||
+ | if (is_void(fpout)) { | ||
+ | fclose(fpin); | ||
+ | nb_syslog(" | ||
+ | return -1; | ||
+ | } | ||
+ | while (1) { | ||
+ | buf = fread(fpin, 1024); | ||
+ | if (is_void(buf)) break; | ||
+ | |||
+ | len = strlen(buf); | ||
+ | if (len == 0) break; | ||
+ | | ||
+ | fwrite(fpout, | ||
+ | } | ||
+ | fclose(fpin); | ||
+ | fclose(fpout); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | /* mkdir -p */ | ||
+ | int makedir (string path, int mode) | ||
+ | { | ||
+ | pc = explode(path); | ||
+ | |||
+ | if (pc[0] != "/" | ||
+ | nb_syslog(" | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | len = length(pc); | ||
+ | if (pc[len-1] != "/" | ||
+ | p = ""; | ||
+ | |||
+ | for (i = 0; i < len; i++) { | ||
+ | if (pc[i] == "/" | ||
+ | mkdir(p, mode); | ||
+ | } | ||
+ | p = strcat(p, pc[i]); | ||
+ | } | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | /* returns operator index for specified lai */ | ||
+ | int find_operator (string lai) | ||
+ | { | ||
+ | if (lai != "" | ||
+ | /* search by lai first */ | ||
+ | for (o = 0; o < OPCNT; o++) { | ||
+ | if (OPERATORS[o].lai == lai) return o; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return -1; /* not a known operator */ | ||
+ | } | ||
+ | |||
+ | /* returns wwan interface index for specified sim index */ | ||
+ | int find_wwan_interface (int sim) | ||
+ | { | ||
+ | for (o = 0; o < OPCNT; o++) { | ||
+ | op = OPERATORS[o]; | ||
+ | |||
+ | if (op.sim == sim) { | ||
+ | return o; | ||
+ | } | ||
+ | } | ||
+ | return -1; /* no wwan interface with this sim */ | ||
+ | } | ||
+ | |||
+ | /* returns current wwan interface index */ | ||
+ | int current_operator () | ||
+ | { | ||
+ | n = nb_config_get(" | ||
+ | if (strlen(n) >= 5 && left(n, 4) == " | ||
+ | return (int)substr(n, | ||
+ | } | ||
+ | |||
+ | return -1; /* not configured */ | ||
+ | } | ||
+ | |||
+ | /* activates specified operator */ | ||
+ | int activate_operator (int op) | ||
+ | { | ||
+ | current = current_operator(); | ||
+ | |||
+ | if (current != -1 && current == op) { | ||
+ | nb_syslog(" | ||
+ | return 0; | ||
+ | } | ||
+ | nb_syslog(" | ||
+ | |||
+ | if (nb_config_set(sprintf(" | ||
+ | nb_syslog(" | ||
+ | return -1; | ||
+ | } | ||
+ | /* re-configuration triggered */ | ||
+ | nb_syslog(" | ||
+ | |||
+ | /* give modem some time to register */ | ||
+ | nb_syslog(" | ||
+ | sleep(30); /* needed for SIM switch */ | ||
+ | |||
+ | /* wait for wanlink to come up */ | ||
+ | for (i = 0; i < 20; i++) { | ||
+ | sleep(10); | ||
+ | |||
+ | nb_syslog(" | ||
+ | st = nb_status(" | ||
+ | |||
+ | ifc = struct_get(st, | ||
+ | if (ifc != sprintf(" | ||
+ | nb_syslog(" | ||
+ | continue; | ||
+ | } | ||
+ | state = struct_get(st, | ||
+ | if (state == " | ||
+ | nb_syslog(" | ||
+ | return 0; | ||
+ | } | ||
+ | attempts = (int) struct_get(st, | ||
+ | nb_syslog(" | ||
+ | if (attempts > 2) { | ||
+ | nb_syslog(" | ||
+ | return -1; | ||
+ | } | ||
+ | } | ||
+ | nb_syslog(" | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | /* returns true if wanlink is up */ | ||
+ | bool wanup () | ||
+ | { | ||
+ | st = nb_status(" | ||
+ | state = struct_get(st, | ||
+ | return (state == " | ||
+ | } | ||
+ | |||
+ | /* scan test */ | ||
+ | struct nb_scan_test () | ||
+ | { | ||
+ | return mkstruct( | ||
+ | " | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | /* installs config and script */ | ||
+ | int install () | ||
+ | { | ||
+ | path = "/ | ||
+ | cfg = sprintf(" | ||
+ | |||
+ | makedir(sprintf(" | ||
+ | |||
+ | touch(cfg); | ||
+ | fp = fopen(cfg, " | ||
+ | if (!fp) { | ||
+ | printf(" | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | /* basic system config */ | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, sprintf(" | ||
+ | |||
+ | /* set up OPERATORS */ | ||
+ | for (o = 0; o < OPCNT; o++) { | ||
+ | op = OPERATORS[o]; | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | fwrite(fp, sprintf(" | ||
+ | } | ||
+ | |||
+ | /* enable first wwan interface */ | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | |||
+ | /* install this script */ | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | fwrite(fp, " | ||
+ | |||
+ | scriptpath = sprintf(" | ||
+ | makedir(scriptpath, | ||
+ | fclose(fp); | ||
+ | |||
+ | if (copy(ME, sprintf(" | ||
+ | printf(" | ||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | return nb_update_config(sprintf(" | ||
+ | } | ||
+ | |||
+ | |||
+ | /* -------------------------------- main -------------------------------- */ | ||
+ | |||
+ | nb_syslog(" | ||
+ | |||
+ | |||
+ | if (ARGV1 == " | ||
+ | /* script installation requested */ | ||
+ | printf(" | ||
+ | |||
+ | if (install() != 0) { | ||
+ | printf(" | ||
+ | exit(1); | ||
+ | } else { | ||
+ | printf(" | ||
+ | } | ||
+ | /* script will terminate at this point */ | ||
+ | exit(0); | ||
+ | } | ||
+ | |||
+ | /* re-read operators */ | ||
+ | OPCNT = 0; | ||
+ | OPERATORS = mkarray(); | ||
+ | |||
+ | for (i = 0; i < 14; i++) { | ||
+ | status = nb_config_get(sprintf(" | ||
+ | if (status != " | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | sim = nb_config_get(sprintf(" | ||
+ | if (sim < 0) { | ||
+ | nb_syslog(" | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | lai = nb_config_get(sprintf(" | ||
+ | |||
+ | OPERATORS[OPCNT].prio = i; | ||
+ | OPERATORS[OPCNT].lai = lai; | ||
+ | OPERATORS[OPCNT].sim = sim; | ||
+ | OPERATORS[OPCNT].username = nb_config_get(sprintf(" | ||
+ | OPERATORS[OPCNT].password = nb_config_get(sprintf(" | ||
+ | OPERATORS[OPCNT].apn = nb_config_get(sprintf(" | ||
+ | |||
+ | nb_syslog(" | ||
+ | OPCNT, i, sim, lai); | ||
+ | |||
+ | OPCNT++; | ||
+ | } | ||
+ | |||
+ | while (1) { | ||
+ | nb_syslog(" | ||
+ | sleep(SCAN_INTERVAL); | ||
+ | |||
+ | /* get wanlink state */ | ||
+ | up = wanup(); | ||
+ | if (up) { | ||
+ | nb_syslog(" | ||
+ | } else { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | |||
+ | /* get current operator */ | ||
+ | current = current_operator(); | ||
+ | if (current != -1) { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | |||
+ | if (up && current != -1) { | ||
+ | nb_syslog(" | ||
+ | if (FORCE != 1) continue; | ||
+ | } | ||
+ | |||
+ | /* scan networks */ | ||
+ | nb_syslog(" | ||
+ | if (TEST == 1) { | ||
+ | nets = nb_scan_test(); | ||
+ | } else { | ||
+ | nets = nb_scan_networks(" | ||
+ | } | ||
+ | nr_nets = struct_get(nets, | ||
+ | |||
+ | if (is_void(nr_nets) || nr_nets < 1) { | ||
+ | nb_syslog(" | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | nb_syslog(" | ||
+ | |||
+ | best = -1; | ||
+ | prio = -1; | ||
+ | for (i = 1; i <= nr_nets; i++) { | ||
+ | net = trim(struct_get(nets, | ||
+ | lai = trim(struct_get(nets, | ||
+ | status = trim(struct_get(nets, | ||
+ | |||
+ | nb_syslog(" | ||
+ | |||
+ | if (VALID_ONLY == 1 && status != " | ||
+ | |||
+ | op = find_operator(lai, | ||
+ | if (op == -1) { | ||
+ | nb_syslog(" | ||
+ | continue; | ||
+ | } | ||
+ | if (current != -1 && op == current) { | ||
+ | /* skip current operator */ | ||
+ | continue; | ||
+ | } | ||
+ | if (prio == -1 || OPERATORS[op].prio < prio) { | ||
+ | best = op; | ||
+ | prio = OPERATORS[op].prio; | ||
+ | } | ||
+ | } | ||
+ | if (best != -1) { | ||
+ | /* activate best operator */ | ||
+ | activate_operator(best); | ||
+ | } else { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | exit(0); | ||
+ | |||
+ | </ | ||