aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo/misc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-07-01 20:56:27 +0200
committerHolger Freyther <holger@freyther.de>2017-04-30 21:45:08 +0000
commit40dca8f991465aaa8e3c95c23d00f155106f584d (patch)
tree71caca18dd3a73decd177a274431f24fa985e37b /src/osmo-bts-sysmo/misc
parentd62a58dbfb4424a104960bca7ffff01a173c101f (diff)
sysmobts: Store a simple network config in the EEPROM as well
Make it possible to store: * Static vs. DHCP mode * IPv4 address * Netmask * GW IPv4 address * DNS IPv4 address Add a simple CRC8 and pick 0xFF as initial value so an all zero EEPROM will not generate a 0 CRC. The code tries to differentiate exit code between unreadable EEPROM and CRC error. This is a reference to see if we want to have store it in the EEPROM or not. Change-Id: Id8a37fe952ef2a8ef36778729f506f900accf8d1
Diffstat (limited to 'src/osmo-bts-sysmo/misc')
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_eeprom.h16
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_par.c52
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_par.h4
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_util.c104
4 files changed, 168 insertions, 8 deletions
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h b/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h
index 120d9687..b7a27fb7 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_eeprom.h
@@ -3,6 +3,14 @@
#include <stdint.h>
+struct sysmobts_net_cfg {
+ uint8_t mode; /* 0 */
+ uint32_t ip; /* 1 - 4 */
+ uint32_t mask; /* 5 - 8 */
+ uint32_t gw; /* 9 - 12 */
+ uint32_t dns; /* 13 - 16 */
+} __attribute__((packed));
+
struct sysmobts_eeprom { /* offset */
uint8_t eth_mac[6]; /* 0-5 */
uint8_t _pad0[10]; /* 6-15 */
@@ -17,13 +25,7 @@ struct sysmobts_eeprom { /* offset */
uint8_t trx_nr; /* 36 */
uint8_t boot_state[48]; /* 37-84 */
uint8_t _pad1[18]; /* 85-102 */
- struct {
- uint8_t mode; /* 103 */
- uint32_t ip; /* 104 - 107 */
- uint32_t mask; /* 108 - 111 */
- uint32_t gw; /* 112 - 115 */
- uint32_t dns; /* 116 - 119 */
- } __attribute__((packed)) net_cfg;
+ struct sysmobts_net_cfg net_cfg;/* 103-119 */
uint8_t crc; /* 120 */
uint8_t gpg_key[128]; /* 121-249 */
} __attribute__((packed));
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.c b/src/osmo-bts-sysmo/misc/sysmobts_par.c
index e3a3c56b..98fe02b5 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_par.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_par.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <osmocom/core/crc8gen.h>
#include <osmocom/core/utils.h>
#include "sysmobts_eeprom.h"
@@ -38,6 +39,13 @@
#define EEPROM_PATH "/sys/devices/platform/i2c_davinci.1/i2c-1/1-0050/eeprom"
+static const struct osmo_crc8gen_code crc8_ccit = {
+ .bits = 8,
+ .poly = 0x83,
+ .init = 0xFF,
+ .remainder = 0x00,
+};
+
const struct value_string sysmobts_par_names[_NUM_SYSMOBTS_PAR+1] = {
{ SYSMOBTS_PAR_MAC, "ethaddr" },
{ SYSMOBTS_PAR_CLK_FACTORY, "clk-factory" },
@@ -291,6 +299,50 @@ int sysmobts_par_set_buf(enum sysmobts_par par, const uint8_t *buf,
return len;
}
+int sysmobts_par_get_net(struct sysmobts_net_cfg *cfg)
+{
+ struct sysmobts_eeprom *ee = get_eeprom(0);
+ ubit_t bits[sizeof(*cfg) * 8];
+ uint8_t crc;
+ int rc;
+
+ if (!ee)
+ return -EIO;
+
+ /* convert the net_cfg to unpacked bits */
+ rc = osmo_pbit2ubit(bits, (uint8_t *) &ee->net_cfg, sizeof(bits));
+ if (rc != sizeof(bits))
+ return -EFAULT;
+ /* compute the crc and compare */
+ crc = osmo_crc8gen_compute_bits(&crc8_ccit, bits, sizeof(bits));
+ if (crc != ee->crc) {
+ fprintf(stderr, "Computed CRC(%d) wanted CRC(%d)\n", crc, ee->crc);
+ return -EBADMSG;
+ }
+ /* return the actual data */
+ *cfg = ee->net_cfg;
+ return 0;
+}
+
+int sysmobts_par_set_net(struct sysmobts_net_cfg *cfg)
+{
+ struct sysmobts_eeprom *ee = get_eeprom(1);
+ ubit_t bits[sizeof(*cfg) * 8];
+ int rc;
+
+ if (!ee)
+ return -EIO;
+
+ /* convert the net_cfg to unpacked bits */
+ rc = osmo_pbit2ubit(bits, (uint8_t *) cfg, sizeof(bits));
+ if (rc != sizeof(bits))
+ return -EFAULT;
+ /* compute and store the result */
+ ee->net_cfg = *cfg;
+ ee->crc = osmo_crc8gen_compute_bits(&crc8_ccit, bits, sizeof(bits));
+ return set_eeprom(ee);
+}
+
osmo_static_assert(offsetof(struct sysmobts_eeprom, trx_nr) == 36, offset_36);
osmo_static_assert(offsetof(struct sysmobts_eeprom, boot_state) == 37, offset_37);
osmo_static_assert(offsetof(struct sysmobts_eeprom, _pad1) == 85, offset_85);
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.h b/src/osmo-bts-sysmo/misc/sysmobts_par.h
index 64803221..5a603cc0 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_par.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_par.h
@@ -3,6 +3,8 @@
#include <osmocom/core/utils.h>
+struct sysmobts_net_cfg;
+
enum sysmobts_par {
SYSMOBTS_PAR_MAC,
SYSMOBTS_PAR_CLK_FACTORY,
@@ -26,6 +28,8 @@ int sysmobts_par_get_buf(enum sysmobts_par par, uint8_t *buf,
unsigned int size);
int sysmobts_par_set_buf(enum sysmobts_par par, const uint8_t *buf,
unsigned int size);
+int sysmobts_par_get_net(struct sysmobts_net_cfg *cfg);
+int sysmobts_par_set_net(struct sysmobts_net_cfg *cfg);
int sysmobts_par_is_int(enum sysmobts_par par);
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_util.c b/src/osmo-bts-sysmo/misc/sysmobts_util.c
index d2b09a81..c9930d8f 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_util.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_util.c
@@ -25,23 +25,35 @@
#include <errno.h>
#include <getopt.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "sysmobts_par.h"
+#include "sysmobts_eeprom.h"
enum act {
ACT_GET,
ACT_SET,
+ ACT_NET_GET,
+ ACT_NET_SET,
};
static enum act action;
static char *write_arg;
static int void_warranty;
+
+static struct in_addr net_ip = { 0, }, net_dns = { 0, }, net_gw = { 0, }, net_mask = { 0, };
+static uint8_t net_mode = 0;
+
static void print_help()
{
const struct value_string *par = sysmobts_par_names;
printf("sysmobts-util [--void-warranty -r | -w value] param_name\n");
+ printf("sysmobts-util --net-read\n");
+ printf("sysmobts-util --net-write --mode INT --ip IP_STR --gw IP_STR --dns IP_STR --net-mask IP_STR\n");
printf("Possible param names:\n");
for (; par->str != NULL; par += 1) {
@@ -60,6 +72,13 @@ static int parse_options(int argc, char **argv)
{ "read", 0, 0, 'r' },
{ "void-warranty", 0, 0, 1000},
{ "write", 1, 0, 'w' },
+ { "ip", 1, 0, 241 },
+ { "gw", 1, 0, 242 },
+ { "dns", 1, 0, 243 },
+ { "net-mask", 1, 0, 244 },
+ { "mode", 1, 0, 245 },
+ { "net-read", 0, 0, 246 },
+ { "net-write", 0, 0, 247 },
{ 0, 0, 0, 0 }
};
@@ -83,7 +102,29 @@ static int parse_options(int argc, char **argv)
printf("Will void warranty on write.\n");
void_warranty = 1;
break;
+ case 246:
+ action = ACT_NET_GET;
+ break;
+ case 247:
+ action = ACT_NET_SET;
+ break;
+ case 245:
+ net_mode = atoi(optarg);
+ break;
+ case 244:
+ inet_aton(optarg, &net_mask);
+ break;
+ case 243:
+ inet_aton(optarg, &net_dns);
+ break;
+ case 242:
+ inet_aton(optarg, &net_gw);
+ break;
+ case 241:
+ inet_aton(optarg, &net_ip);
+ break;
default:
+ printf("Unknown option %d/%c\n", c, c);
return -1;
}
}
@@ -91,6 +132,64 @@ static int parse_options(int argc, char **argv)
return 0;
}
+static const char *make_addr(uint32_t saddr)
+{
+ struct in_addr addr;
+ addr.s_addr = ntohl(saddr);
+ return inet_ntoa(addr);
+}
+
+static void dump_net_cfg(struct sysmobts_net_cfg *net_cfg)
+{
+ if (net_cfg->mode == NET_MODE_DHCP) {
+ printf("IP=dhcp\n");
+ printf("DNS=\n");
+ printf("GATEWAY=\n");
+ printf("NETMASK=\n");
+ } else {
+ printf("IP=%s\n", make_addr(net_cfg->ip));
+ printf("GATEWAY=%s\n", make_addr(net_cfg->gw));
+ printf("DNS=%s\n", make_addr(net_cfg->dns));
+ printf("NETMASK=%s\n", make_addr(net_cfg->mask));
+ }
+}
+
+static int handle_net(void)
+{
+ struct sysmobts_net_cfg net_cfg;
+ int rc;
+
+ switch (action) {
+ case ACT_NET_GET:
+ rc = sysmobts_par_get_net(&net_cfg);
+ if (rc != 0) {
+ fprintf(stderr, "Error %d\n", rc);
+ exit(rc);
+ }
+ dump_net_cfg(&net_cfg);
+ break;
+ case ACT_NET_SET:
+ memset(&net_cfg, 0, sizeof(net_cfg));
+ net_cfg.mode = net_mode;
+ net_cfg.ip = htonl(net_ip.s_addr);
+ net_cfg.mask = htonl(net_mask.s_addr);
+ net_cfg.gw = htonl(net_gw.s_addr);
+ net_cfg.dns = htonl(net_dns.s_addr);
+ printf("Going to write\n");
+ dump_net_cfg(&net_cfg);
+
+ rc = sysmobts_par_set_net(&net_cfg);
+ if (rc != 0) {
+ fprintf(stderr, "Error %d\n", rc);
+ exit(rc);
+ }
+ break;
+ default:
+ printf("Unhandled action %d\n", action);
+ }
+ return 0;
+}
+
int main(int argc, char **argv)
{
const char *parname;
@@ -101,7 +200,10 @@ int main(int argc, char **argv)
if (rc < 0)
exit(2);
- if (optind >= argc) {
+ if (action > ACT_SET)
+ return handle_net();
+
+ if (optind >= argc && action <+ ACT_NET_GET) {
fprintf(stderr, "You must specify the parameter name\n");
exit(2);
}