summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-04-28 14:43:50 +0200
committerHarald Welte <laforge@gnumonks.org>2017-04-28 14:43:50 +0200
commitca0042dbbbca3d249557c1c2a7992f462d38adc3 (patch)
treef0b1d07d721e50f16929c7f5f8ab20e6257b1bf0
parent0f3c33dc4f008a1fc404de1d2a6ee756801219eb (diff)
WIP: DEVCFG to set baud ratelaforge/burst_ind
-rw-r--r--include/l1ctl_proto.h19
-rw-r--r--src/target/firmware/layer1/l23_api.c61
2 files changed, 80 insertions, 0 deletions
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h
index ab80aa1..7fc5955 100644
--- a/include/l1ctl_proto.h
+++ b/include/l1ctl_proto.h
@@ -57,6 +57,8 @@ enum {
L1CTL_TRAFFIC_CONF,
L1CTL_TRAFFIC_IND,
L1CTL_BURST_IND,
+ L1CTL_DEVCFG_REQ,
+ L1CTL_DEVCFG_CONF,
};
enum ccch_mode {
@@ -315,4 +317,21 @@ struct l1ctl_traffic_req {
uint8_t data[TRAFFIC_DATA_LEN];
} __attribute__((packed));
+/* device configuration request and response */
+enum l1ctl_devcfg_cmd {
+ L1CTL_DEVCFG_CMD_BAUDRATE,
+};
+
+struct l1ctl_devcfg_req {
+ uint8_t cmd;
+ union {
+ uint32_t baudrate;
+ };
+} __attribute__((packed));
+
+struct l1ctl_devcfg_resp {
+ uint8_t cmd;
+ uint8_t result;
+} __attribute__((packed));
+
#endif /* __L1CTL_PROTO_H__ */
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 6ada2e4..5e91eeb 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -583,6 +583,65 @@ static void l1ctl_sim_req(struct msgb *msg)
sim_apdu(len, data);
}
+static void l1ctl_tx_devcfg_conf(uint8_t cmd, uint8_t result)
+{
+ struct msgb *msg = l1ctl_msgb_alloc(L1CTL_DEVCFG_CONF);
+ struct l1ctl_devcfg_resp *dr;
+
+ dr = (struct l1ctl_devcfg_resp *) msgb_put(msg, sizeof(*dr));
+ dr->cmd = cmd;
+ dr->result = result;
+
+ l1_queue_for_l2(msg);
+}
+
+static int uard_baudrt_by_l1ctl(uint32_t baudrt)
+{
+ switch (baudrt) {
+ case 38400:
+ return UART_38400;
+ case 57600:
+ return UART_57600;
+ case 115200:
+ return UART_115200;
+ case 230400:
+ return UART_230400;
+ case 460800:
+ return UART_460800;
+ case 614400:
+ return UART_614400;
+ case 921600:
+ return UART_921600;
+ default:
+ return -1;
+ }
+}
+
+static void l1ctl_devcfg_req(struct msgb *msg)
+{
+ struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data;
+ struct l1ctl_devcfg_req *dr = (struct l1ctl_devcfg_req *) l1h->data;
+ int rc;
+
+ switch (dr->cmd) {
+ case L1CTL_DEVCFG_CMD_BAUDRATE:
+ rc = uard_baudrt_by_l1ctl(dr->baudrate);
+ if (rc < 0) {
+ printf("Unsupported baudrate %u\n", dr->baudrate);
+ l1ctl_tx_devcfg_conf(dr->cmd, 0xff);
+ return;
+ }
+ printf("Sending response at old baud rate\n");
+ l1ctl_tx_devcfg_conf(dr->cmd, 0);
+ printf("Changing to new baud rate %u (%d)...\n", dr->baudrate, rc);
+ sercomm_change_speed(rc);
+ break;
+ default:
+ l1ctl_tx_devcfg_conf(dr->cmd, 0xff);
+ return;
+ }
+}
+
static struct llist_head l23_rx_queue = LLIST_HEAD_INIT(l23_rx_queue);
/* callback from SERCOMM when L2 sends a message to L1 */
@@ -673,6 +732,8 @@ void l1a_l23_handler(void)
goto exit_nofree;
case L1CTL_SIM_REQ:
l1ctl_sim_req(msg);
+ case L1CTL_DEVCFG_REQ:
+ l1ctl_devcfg_req(msg);
break;
}