/* send first ctrl message and start timer */ static void trx_ctrl_timer_cb(void *data) { struct trx_l1h *l1h = data; LOGP(DTRX, LOGL_NOTICE, "No response from transceiver for %s\n", phy_instance_name(l1h->phy_inst)); trx_ctrl_send(l1h); }
/* send first ctrl message and start timer */ static void trx_ctrl_timer_cb(void *data) { struct trx_l1h *l1h = data; LOGP(DTRX, LOGL_NOTICE, "No response from transceiver for trx=%d\n", l1h->trx->nr); trx_ctrl_send(l1h); }
/* add a new ctrl command */ static int trx_ctrl_cmd(struct trx_l1h *l1h, int critical, const char *cmd, const char *fmt, ...) { struct trx_ctrl_msg *tcm; va_list ap; int l, pending = 0; if (!transceiver_available && !(!strcmp(cmd, "POWEROFF") || !strcmp(cmd, "POWERON"))) { LOGP(DTRX, LOGL_ERROR, "CTRL %s ignored: No clock from " "transceiver, please fix!\n", cmd); return -EIO; } if (!llist_empty(&l1h->trx_ctrl_list)) pending = 1; /* create message */ tcm = talloc_zero(tall_bts_ctx, struct trx_ctrl_msg); if (!tcm) return -ENOMEM; if (fmt && fmt[0]) { l = snprintf(tcm->cmd, sizeof(tcm->cmd)-1, "CMD %s ", cmd); va_start(ap, fmt); vsnprintf(tcm->cmd + l, sizeof(tcm->cmd) - l - 1, fmt, ap); va_end(ap); } else snprintf(tcm->cmd, sizeof(tcm->cmd)-1, "CMD %s", cmd); tcm->cmd_len = strlen(cmd); tcm->critical = critical; llist_add_tail(&tcm->list, &l1h->trx_ctrl_list); LOGP(DTRX, LOGL_INFO, "Adding new control '%s'\n", tcm->cmd); /* send message, if no pending message */ if (!pending) trx_ctrl_send(l1h); return 0; }
/* get response from ctrl socket */ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what) { struct trx_l1h *l1h = ofd->data; struct phy_instance *pinst = l1h->phy_inst; char buf[1500]; int len, resp; len = recv(ofd->fd, buf, sizeof(buf) - 1, 0); if (len <= 0) return len; buf[len] = '\0'; if (!strncmp(buf, "RSP ", 4)) { struct trx_ctrl_msg *tcm; char *p; int rsp_len = 0; /* calculate the length of response item */ p = strchr(buf + 4, ' '); if (p) rsp_len = p - buf - 4; else rsp_len = strlen(buf) - 4; LOGP(DTRX, LOGL_INFO, "Response message: '%s'\n", buf); /* abort timer and send next message, if any */ if (osmo_timer_pending(&l1h->trx_ctrl_timer)) osmo_timer_del(&l1h->trx_ctrl_timer); /* get command for response message */ if (llist_empty(&l1h->trx_ctrl_list)) { LOGP(DTRX, LOGL_NOTICE, "Response message without " "command\n"); return -EINVAL; } tcm = llist_entry(l1h->trx_ctrl_list.next, struct trx_ctrl_msg, list); /* check if respose matches command */ if (rsp_len != tcm->cmd_len) { notmatch: LOGP(DTRX, (tcm->critical) ? LOGL_FATAL : LOGL_NOTICE, "Response message '%s' does not match command " "message '%s'\n", buf, tcm->cmd); goto rsp_error; } if (!!strncmp(buf + 4, tcm->cmd + 4, rsp_len)) goto notmatch; /* check for response code */ sscanf(p + 1, "%d", &resp); if (resp) { LOGP(DTRX, (tcm->critical) ? LOGL_FATAL : LOGL_NOTICE, "transceiver (%s) rejected TRX command " "with response: '%s'\n", phy_instance_name(pinst), buf); rsp_error: if (tcm->critical) { bts_shutdown(pinst->trx->bts, "SIGINT"); /* keep tcm list, so process is stopped */ return -EIO; } } /* remove command from list */ llist_del(&tcm->list); talloc_free(tcm); trx_ctrl_send(l1h); } else