static int gsm411_mnsms_est_ind(struct gsm411_smr_inst *inst, struct msgb *msg)
{
	struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h;
	struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
	uint8_t msg_type =  rp_data->msg_type & 0x07;
	int rc;

	/* check direction */
	if (inst->network == (msg_type & 1)) {
		LOGP(DLSMS, LOGL_NOTICE,
			SMR_LOG_STR "Invalid RP type 0x%02x\n",
			inst->id, msg_type);
		gsm411_send_rp_error(inst, rp_data->msg_ref,
					  GSM411_RP_CAUSE_MSG_INCOMP_STATE);
		new_rp_state(inst, GSM411_RPS_IDLE);
		gsm411_send_release(inst);
		return -EINVAL;
	}

	switch (msg_type) {
	case GSM411_MT_RP_DATA_MT:
	case GSM411_MT_RP_DATA_MO:
		LOGP(DLSMS, LOGL_DEBUG,
			SMR_LOG_STR "RX SMS RP-DATA\n", inst->id);
		/* start TR2N and enter 'wait to send RP-ACK state' */
		osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
		new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
		rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
		break;
	case GSM411_MT_RP_SMMA_MO:
		LOGP(DLSMS, LOGL_DEBUG,
			SMR_LOG_STR "RX SMS RP-SMMA\n", inst->id);
		/* start TR2N and enter 'wait to send RP-ACK state' */
		osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
		new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
		rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
		break;
	default:
		LOGP(DLSMS, LOGL_NOTICE,
			SMR_LOG_STR "invalid RP type 0x%02x\n",
			inst->id, msg_type);
		gsm411_send_rp_error(inst, rp_data->msg_ref,
					  GSM411_RP_CAUSE_MSGTYPE_NOTEXIST);
		new_rp_state(inst, GSM411_RPS_IDLE);
		rc = -EINVAL;
		break;
	}

	return rc;
}
Beispiel #2
0
/**
 * Send a GSM08.08 Assignment Request. Right now this does not contain the
 * audio codec type or the allowed rates for the config. It is assumed that
 * this is for audio handling only. In case the current channel does not allow
 * the selected mode a new one will be allocated.
 *
 * TODO: Add multirate configuration, make it work for more than audio.
 */
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
{
	struct bsc_api *api;
	api = conn->bts->network->bsc_api;

	if (chan_compat_with_mode(conn->lchan, chan_mode, full_rate) != 0) {
		if (handle_new_assignment(conn, chan_mode, full_rate) != 0)
			goto error;
	} else {
		LOGP(DMSC, LOGL_NOTICE,
			"Sending ChanModify for speech %d %d\n", chan_mode, full_rate);
		if (chan_mode == GSM48_CMODE_SPEECH_AMR)
			handle_mr_config(conn, conn->lchan);

		gsm48_lchan_modify(conn->lchan, chan_mode);
	}

	/* we will now start the timer to complete the assignment */
	conn->T10.cb = assignment_t10_timeout;
	conn->T10.data = conn;
	osmo_timer_schedule(&conn->T10, GSM0808_T10_VALUE);
	return 0;

error:
	api->assign_fail(conn, 0, NULL);
	return -1;
}
int main(int argc, char** argv)
{
    printf("Starting... timer\n");

    osmo_timer_schedule(&timer_one, 3, 0);
    osmo_timer_schedule(&timer_two, 5, 0);
    osmo_timer_schedule(&timer_three, 4, 0);

#ifdef HAVE_SYS_SELECT_H
    while (1) {
        osmo_select_main(0);
    }
#else
    printf("Select not supported on this platform!\n");
#endif
}
static void start_timer(int sec, int micro)
{
	stop_timer();
	timer.cb = timeout_cb;
	timer.data = ms;
	osmo_timer_schedule(&timer, sec, micro);
}
Beispiel #5
0
void bsc_msc_schedule_connect(struct bsc_msc_connection *con)
{
	LOGP(DMSC, LOGL_NOTICE,
		"Attempting to reconnect to the MSC(%s)\n", con->name);
	con->reconnect_timer.cb = reconnect_msc;
	con->reconnect_timer.data = con;
	osmo_timer_schedule(&con->reconnect_timer, 5, 0);
}
Beispiel #6
0
static void sgsn_gtp_tmr_start(struct sgsn_instance *sgi)
{
	struct timeval next;

	/* Retrieve next retransmission as struct timeval */
	gtp_retranstimeout(sgi->gsn, &next);

	/* re-schedule the timer */
	osmo_timer_schedule(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000);
}
static int gsm411_rl_data_req(struct gsm411_smr_inst *inst, struct msgb *msg)
{
	LOGP(DLSMS, LOGL_DEBUG,
		SMR_LOG_STR "TX SMS RP-DATA\n", inst->id);
	/* start TR1N and enter 'wait for RP-ACK state' */
	osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR1M);
	new_rp_state(inst, GSM411_RPS_WAIT_FOR_RP_ACK);

	return inst->mn_send(inst, GSM411_MNSMS_EST_REQ, msg);
}
Beispiel #8
0
static void swd_state_reset(struct oc2gbts_mgr_instance *mgr, int outcome)
{
	if (mgr->swd.swd_from_loop) {
                mgr->swd.swd_timeout.data = mgr;
                mgr->swd.swd_timeout.cb = swd_loop_run;
                osmo_timer_schedule(&mgr->swd.swd_timeout, SWD_PERIOD, 0);
        }

        mgr->swd.state = SWD_INITIAL;
	swd_close(mgr);
}
Beispiel #9
0
static void pcu_tx_txt_retry(void *_priv)
{
	struct gprs_rlcmac_bts *bts = bts_main_data();
	struct pcu_sock_state *state = pcu_sock_state;

	if (bts->active)
		return;

	LOGP(DL1IF, LOGL_INFO, "Sending version %s to BTS.\n", PACKAGE_VERSION);
	pcu_tx_txt_ind(PCU_VERSION, "%s", PACKAGE_VERSION);
	osmo_timer_schedule(&state->timer, 5, 0);
}
Beispiel #10
0
static void mtk_timer_cb(void *p)
{
	int rc;

	if (dnload.mtk_state == MTK_INIT_1) {
		printf("Sending MTK romloader beacon...\n");
		rc = write(dnload.serial_fd.fd, &mtk_init_cmd[0], 1);

		if (!(rc == 1))
			printf("Error sending identification beacon\n");

		osmo_timer_schedule(p, 0, dnload.beacon_interval);
	}
}
Beispiel #11
0
static void beacon_timer_cb(void *p)
{
	int rc;

	if (dnload.romload_state == WAITING_IDENTIFICATION) {
		rc = write(dnload.serial_fd.fd, romload_ident_cmd,
			   sizeof(romload_ident_cmd));

		if (!(rc == sizeof(romload_ident_cmd)))
			printf("Error sending identification beacon\n");

		osmo_timer_schedule(p, 0, dnload.beacon_interval);
	}
}
Beispiel #12
0
static int __handle_ts1_write(struct osmo_fd *bfd, struct e1inp_line *line)
{
    unsigned int ts_nr = bfd->priv_nr;
    struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
    struct e1inp_sign_link *sign_link;
    struct msgb *msg;
    int ret;

    bfd->when &= ~BSC_FD_WRITE;

    /* get the next msg for this timeslot */
    msg = e1inp_tx_ts(e1i_ts, &sign_link);
    if (!msg) {
        /* no message after tx delay timer */
        return 0;
    }

    switch (sign_link->type) {
    case E1INP_SIGN_OML:
#ifdef HSL_SR_1_0
        /* HSL uses 0x81 for FOM for some reason */
        if (msg->data[0] == ABIS_OM_MDISC_FOM)
            msg->data[0] = ABIS_OM_MDISC_FOM | 0x01;
#endif
        break;
    case E1INP_SIGN_RSL:
        break;
    default:
        msgb_free(msg);
        bfd->when |= BSC_FD_WRITE; /* come back for more msg */
        return -EINVAL;
    }

    msg->l2h = msg->data;
    ipaccess_prepend_header(msg, sign_link->tei);

    DEBUGP(DLMI, "TX %u: %s\n", ts_nr, osmo_hexdump(msg->l2h, msgb_l2len(msg)));

    ret = send(bfd->fd, msg->data, msg->len, 0);
    msgb_free(msg);

    /* set tx delay timer for next event */
    e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
    e1i_ts->sign.tx_timer.data = e1i_ts;

    /* Reducing this might break the nanoBTS 900 init. */
    osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);

    return ret;
}
Beispiel #13
0
/* osmocom_on_mtk_timer */
static void _osmocom_on_mtk_timer(void * data)
{
	ModemPlugin * modem = data;
	Osmocom * osmocom = modem;
	int rc;

	if(osmocom->dnload.mtk_state == MTK_INIT_1)
	{
		printf("Sending MTK romloader beacon...\n");
		rc = write(osmocom->dnload.serial_fd.fd, &mtk_init_cmd[0], 1);
		if(rc != 1)
			printf("Error sending identification beacon\n");
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
}
static void timer_fired(void *_data)
{
    unsigned long data = (unsigned long) _data;
    printf("Fired timer: %lu\n", data);

    if (data == 1) {
        osmo_timer_schedule(&timer_one, 3, 0);
        osmo_timer_del(&timer_two);
    } else if (data == 2) {
        printf("Should not be fired... bug in del_timer\n");
    } else if (data == 3) {
        printf("Timer fired not registering again\n");
    } else  {
        printf("wtf... wrong data\n");
    }
}
Beispiel #15
0
static void ussd_start_auth(struct bsc_nat_ussd_con *conn)
{
	struct msgb *msg;

	conn->auth_timeout.data = conn;
	conn->auth_timeout.cb = ussd_auth_cb;
	osmo_timer_schedule(&conn->auth_timeout, conn->nat->auth_timeout, 0);

	msg = msgb_alloc_headroom(4096, 128, "auth message");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate auth msg\n");
		return;
	}

	msgb_v_put(msg, IPAC_MSGT_ID_GET);
	bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS);
}
Beispiel #16
0
/* osmocom_on_beacon_timer */
static void _osmocom_on_beacon_timer(void * data)
{
	ModemPlugin * modem = data;
	Osmocom * osmocom = modem;
	int rc;

	if(osmocom->dnload.romload_state == WAITING_IDENTIFICATION)
	{
		printf("Sending Calypso romloader beacon...\n");
		rc = write(osmocom->dnload.serial_fd.fd, romload_ident_cmd,
				sizeof(romload_ident_cmd));
		if(rc != sizeof(romload_ident_cmd))
			printf("Error sending identification beacon\n");
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
}
Beispiel #17
0
/* send first ctrl message and start timer */
static void trx_ctrl_send(struct trx_l1h *l1h)
{
	struct trx_ctrl_msg *tcm;

	/* get first command */
	if (llist_empty(&l1h->trx_ctrl_list))
		return;
	tcm = llist_entry(l1h->trx_ctrl_list.next, struct trx_ctrl_msg, list);

	LOGP(DTRX, LOGL_DEBUG, "Sending control '%s' to %s\n", tcm->cmd,
		phy_instance_name(l1h->phy_inst));
	/* send command */
	send(l1h->trx_ofd_ctrl.fd, tcm->cmd, strlen(tcm->cmd)+1, 0);

	/* start timer */
	l1h->trx_ctrl_timer.cb = trx_ctrl_timer_cb;
	l1h->trx_ctrl_timer.data = l1h;
	osmo_timer_schedule(&l1h->trx_ctrl_timer, 2, 0);
}
Beispiel #18
0
static void
loader_do_fprogram() {
	uint32_t rembytes = osmoload.memlen - osmoload.memoff;

	if(!rembytes) {
		puts("done.");
		osmoload.quit = 1;
		return;
	}

	osmo_timer_schedule(&osmoload.timeout, 0, 10000000);

	uint8_t reqbytes = (rembytes < MEM_MSG_MAX) ? rembytes : MEM_MSG_MAX;

	osmoload.memcrc = osmo_crc16(0, (uint8_t *) osmoload.binbuf + osmoload.memoff, reqbytes);
	osmoload.memreq = reqbytes;

	struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");

	msgb_put_u8(msg, LOADER_FLASH_PROGRAM);
	msgb_put_u8(msg, reqbytes);
	msgb_put_u16(msg, osmoload.memcrc);
	msgb_put_u8(msg, 0); // XXX: align data to 16bit
	msgb_put_u8(msg, osmoload.memchip);
	msgb_put_u32(msg, osmoload.membase + osmoload.memoff);

	unsigned char *p = msgb_put(msg, reqbytes);
	memcpy(p, osmoload.binbuf + osmoload.memoff, reqbytes);

#if 0
	printf("Sending %u bytes at offset %u to address %x with crc %x\n",
		   reqbytes, osmoload.memoff, osmoload.membase + osmoload.memoff,
		   osmoload.memcrc);
#endif

	loader_send_request(msg);

	msgb_free(msg);

	osmoload.memoff += reqbytes;
}
Beispiel #19
0
/* start to scan for one ARFCN */
static int _cinfo_start_arfcn(unsigned int band_arfcn)
{
	int rc;

	/* ask L1 to try to tune to new ARFCN */
	/* FIXME: decode band */
	rc = l1ctl_tx_fbsb_req(fps.ms, band_arfcn,
	                       L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED);
	if (rc < 0)
		return rc;

	/* allocate new cell info structure */
	fps.cur_cell = cell_info_alloc();
	fps.cur_arfcn = band_arfcn;
	fps.cur_cell->band_arfcn = band_arfcn;
	/* FIXME: start timer in case we never get a sync */
	fps.state = BSCAN_S_WAIT_DATA;
	osmo_timer_schedule(&fps.timer, 2, 0);

	return 0;
}
Beispiel #20
0
/* 'swd_num_events' configures the number of events to be monitored before notifying the
   systemd service watchdog. It must be in the range of [1,64]. Events are notified
   through the function 'oc2gbts_swd_event'
*/
int oc2gbts_swd_init(struct oc2gbts_mgr_instance *mgr, int swd_num_events)
{
	/* Checks for a valid number of events to validate */
	if (swd_num_events < 1 || swd_num_events > 64)
		return(-1);

	mgr->swd.state = SWD_INITIAL;
	mgr->swd.swd_timeout.data = mgr;
	mgr->swd.swd_timeout.cb = swd_loop_run;
	osmo_timer_schedule(&mgr->swd.swd_timeout, 0, 0);

	if (swd_num_events == 64){
		mgr->swd.swd_eventmasks = 0xffffffffffffffffULL;
	}
	else {
		mgr->swd.swd_eventmasks = ((1ULL << swd_num_events) - 1);
	}
	mgr->swd.swd_events = 0;
	mgr->swd.num_events = swd_num_events;

	return 0;
}
Beispiel #21
0
/*! \brief perform a state change of the given FSM instance
 *
 *  Best invoke via the osmo_fsm_inst_state_chg() macro which logs the source
 *  file where the state change was effected. Alternatively, you may pass \a
 *  file as NULL to use the normal file/line indication instead.
 *
 *  All changes to the FSM instance state must be made via this
 *  function.  It verifies that the existing state actually permits a
 *  transiiton to new_state.
 *
 *  timeout_secs and T are optional parameters, and only have any effect
 *  if timeout_secs is not 0.  If the timeout function is used, then the
 *  new_state is entered, and the FSM instances timer is set to expire
 *  in timeout_secs functions.   At that time, the FSM's timer_cb
 *  function will be called for handling of the timeout by the user.
 *
 *  \param[in] fi FSM instance whose state is to change
 *  \param[in] new_state The new state into which we should change
 *  \param[in] timeout_secs Timeout in seconds (if !=0)
 *  \param[in] T Timer number (if \ref timeout_secs != 0)
 *  \param[in] file Calling source file (from osmo_fsm_inst_state_chg macro)
 *  \param[in] line Calling source line (from osmo_fsm_inst_state_chg macro)
 *  \returns 0 on success; negative on error
 */
int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state,
			     unsigned long timeout_secs, int T,
			     const char *file, int line)
{
	struct osmo_fsm *fsm = fi->fsm;
	uint32_t old_state = fi->state;
	const struct osmo_fsm_state *st = &fsm->states[fi->state];

	/* validate if new_state is a valid state */
	if (!(st->out_state_mask & (1 << new_state))) {
		LOGPFSMLSRC(fi, LOGL_ERROR, file, line,
			    "transition to state %s not permitted!\n",
			    osmo_fsm_state_name(fsm, new_state));
		return -EPERM;
	}

	/* delete the old timer */
	osmo_timer_del(&fi->timer);

	if (st->onleave)
		st->onleave(fi, new_state);

	LOGPFSMSRC(fi, file, line, "state_chg to %s\n",
		   osmo_fsm_state_name(fsm, new_state));
	fi->state = new_state;
	st = &fsm->states[new_state];

	if (timeout_secs) {
		fi->T = T;
		osmo_timer_schedule(&fi->timer, timeout_secs, 0);
	}

	/* Call 'onenter' last, user might terminate FSM from there */
	if (st->onenter)
		st->onenter(fi, old_state);

	return 0;
}
static int gsm411_mmsms_send_msg(struct gsm411_smc_inst *inst)
{
	struct msgb *nmsg;

	LOGP(DLSMS, LOGL_INFO, "Send CP data\n");
	/* reset retry counter */
	if (inst->cp_state != GSM411_CPS_WAIT_CP_ACK)
		inst->cp_retx = 0;
	/* 5.2.3.1.2: enter MO-wait for CP-ACK */
	/* 5.2.3.2.3: enter MT-wait for CP-ACK */
	new_cp_state(inst, GSM411_CPS_WAIT_CP_ACK);
	inst->cp_timer.data = inst;
	inst->cp_timer.cb = cp_timer_expired;
	/* 5.3.2.1: Set Timer TC1A */
	osmo_timer_schedule(&inst->cp_timer, inst->cp_tc1, 0);
	/* clone cp_msg */
	nmsg = gsm411_msgb_alloc();
	memcpy(msgb_put(nmsg, inst->cp_msg->len), inst->cp_msg->data,
		inst->cp_msg->len);
	/* send MMSMS_DATA_REQ with CP-DATA */
	return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
				GSM411_MT_CP_DATA);
}
Beispiel #23
0
static int _l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
		   int is_system_prim, l1if_compl_cb *cb, void *data)
{
	struct wait_l1_conf *wlc;
	struct osmo_wqueue *wqueue;
	unsigned int timeout_secs;

	/* allocate new wsc and store reference to mutex and conf_id */
	wlc = talloc_zero(fl1h, struct wait_l1_conf);
	wlc->cb = cb;
	wlc->cb_data = data;

	/* Make sure we actually have received a REQUEST type primitive */
	if (is_system_prim == 0) {
		GsmL1_Prim_t *l1p = msgb_l1prim(msg);

		LOGP(DL1P, LOGL_INFO, "Tx L1 prim %s\n",
			get_value_string(lc15bts_l1prim_names, l1p->id));

		if (lc15bts_get_l1prim_type(l1p->id) != L1P_T_REQ) {
			LOGP(DL1C, LOGL_ERROR, "L1 Prim %s is not a Request!\n",
				get_value_string(lc15bts_l1prim_names, l1p->id));
			talloc_free(wlc);
			return -EINVAL;
		}
		wlc->is_sys_prim = 0;
		wlc->conf_prim_id = lc15bts_get_l1prim_conf(l1p->id);
		wlc->conf_hLayer3 = l1p_get_hLayer3(l1p);
		wqueue = &fl1h->write_q[MQ_L1_WRITE];
		timeout_secs = 30;
	} else {
		Litecell15_Prim_t *sysp = msgb_sysprim(msg);

		LOGP(DL1C, LOGL_INFO, "Tx SYS prim %s\n",
			get_value_string(lc15bts_sysprim_names, sysp->id));

		if (lc15bts_get_sysprim_type(sysp->id) != L1P_T_REQ) {
			LOGP(DL1C, LOGL_ERROR, "SYS Prim %s is not a Request!\n",
				get_value_string(lc15bts_sysprim_names, sysp->id));
			talloc_free(wlc);
			return -EINVAL;
		}
		wlc->is_sys_prim = 1;
		wlc->conf_prim_id = lc15bts_get_sysprim_conf(sysp->id);
		wqueue = &fl1h->write_q[MQ_SYS_WRITE];
		timeout_secs = 30;
	}

	/* enqueue the message in the queue and add wsc to list */
	if (osmo_wqueue_enqueue(wqueue, msg) != 0) {
		/* So we will get a timeout but the log message might help */
		LOGP(DL1C, LOGL_ERROR, "Write queue for %s full. dropping msg.\n",
			is_system_prim ? "system primitive" : "gsm");
		msgb_free(msg);
	}
	llist_add(&wlc->list, &fl1h->wlc_list);

	/* schedule a timer for timeout_secs seconds. If DSP fails to respond, we terminate */
	wlc->timer.data = wlc;
	wlc->timer.cb = l1if_req_timeout;
	osmo_timer_schedule(&wlc->timer, timeout_secs, 0);

	return 0;
}
Beispiel #24
0
int bsc_msc_connect(struct bsc_msc_connection *con)
{
	struct bsc_msc_dest *dest;
	struct osmo_fd *fd;
	struct sockaddr_in sin;
	int on = 1, ret;

	if (llist_empty(con->dests)) {
		LOGP(DMSC, LOGL_ERROR,
			"No MSC(%s) connections configured.\n",
			con->name);
		connection_loss(con);
		return -1;
	}

	/* TODO: Why are we not using the libosmocore soecket
	 * abstraction, or libosmo-netif? */

	/* move to the next connection */
	dest = (struct bsc_msc_dest *) con->dests->next;
	llist_del(&dest->list);
	llist_add_tail(&dest->list, con->dests);

	LOGP(DMSC, LOGL_NOTICE,
		"Attempting to connect MSC(%s) at %s:%d\n",
		con->name, dest->ip, dest->port);

	con->is_connected = 0;

	msgb_free(con->pending_msg);
	con->pending_msg = NULL;

	fd = &con->write_queue.bfd;
	fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	fd->priv_nr = 1;

	if (fd->fd < 0) {
		perror("Creating TCP socket failed");
		return fd->fd;
	}

	/* make it non blocking */
	setnonblocking(fd);

	/* set the socket priority */
	ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
			 &dest->dscp, sizeof(dest->dscp));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR,
			"Failed to set DSCP to %d on MSC(%s). %s\n",
			dest->dscp, con->name, strerror(errno));

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(dest->port);
	inet_aton(dest->ip, &sin.sin_addr);

	ret = setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR,
		     "Failed to set SO_REUSEADDR socket option\n");
	ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));

	if (ret == -1 && errno == EINPROGRESS) {
		LOGP(DMSC, LOGL_ERROR,
			"MSC(%s) Connection in progress\n", con->name);
		fd->when = BSC_FD_WRITE;
		fd->cb = msc_connection_connect;
		con->timeout_timer.cb = msc_con_timeout;
		con->timeout_timer.data = con;
		osmo_timer_schedule(&con->timeout_timer, 20, 0);
	} else if (ret < 0) {
		perror("Connection failed");
		connection_loss(con);
		return ret;
	} else {
		fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
		fd->cb = osmo_wqueue_bfd_cb;
		con->is_connected = 1;
		if (con->connected)
			con->connected(con);
	}

	ret = osmo_fd_register(fd);
	if (ret < 0) {
		perror("Registering the fd failed");
		close(fd->fd);
		return ret;
	}

	return ret;
}
Beispiel #25
0
static void
loader_command(char *name, int cmdc, char **cmdv) {
	if(!cmdc) {
		usage(name);
	}

	char *cmd = cmdv[0];

	char buf[MEM_MSG_MAX];
	memset(buf, 23, sizeof(buf));

	if(!strcmp(cmd, "dump")) {
		osmoload.state = STATE_DUMPING;
	} else if(!strcmp(cmd, "ping")) {
		loader_start_query(LOADER_PING);
	} else if(!strcmp(cmd, "off")) {
		loader_start_query(LOADER_POWEROFF);
	} else if(!strcmp(cmd, "reset")) {
		loader_start_query(LOADER_RESET);
	} else if(!strcmp(cmd, "jumprom")) {
		loader_start_query(LOADER_ENTER_ROM_LOADER);
	} else if(!strcmp(cmd, "jumpflash")) {
		loader_start_query(LOADER_ENTER_FLASH_LOADER);
	} else if(!strcmp(cmd, "finfo")) {
		puts("Requesting flash layout info");
		loader_start_query(LOADER_FLASH_INFO);
	} else if(!strcmp(cmd, "memput")) {
		uint32_t address;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);

		unsigned int i;
		char *hex = cmdv[2];
		if(strlen(hex)&1) {
			puts("Invalid hex string.");
			exit(2);
		}
		for(i = 0; i <= sizeof(buf) && i < strlen(hex)/2; i++) {
			if(i >= sizeof(buf)) {
				puts("Value too long for single message");
				exit(2);
			}
			unsigned int byte;
			int count = sscanf(hex + i * 2, "%02x", &byte);
			if(count != 1) {
				puts("Invalid hex string.");
				exit(2);
			}
			buf[i] = byte & 0xFF;
		}

		loader_start_memput(i & 0xFF, address, buf);
	} else if(!strcmp(cmd, "memget")) {
		uint32_t address;
		uint8_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		if(length > MEM_MSG_MAX) {
			puts("Too many bytes");
			exit(2);
		}

		loader_start_memget(length, address);
	} else if(!strcmp(cmd, "jump")) {
		uint32_t address;

		if(cmdc < 2) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);

		loader_start_jump(address);
	} else if(!strcmp(cmd, "memdump")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 4) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_memdump(length, address, cmdv[3]);
	} else if(!strcmp(cmd, "memload")) {
		uint32_t address;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);

		loader_start_memload(address, cmdv[2]);
	} else if(!strcmp(cmd, "fprogram")) {
		uint8_t chip;
		uint32_t address;

		if(cmdc < 4) {
			usage(name);
		}

		chip = strtoul(cmdv[1], NULL, 10);
		address = strtoul(cmdv[2], NULL, 16);

		loader_start_fprogram(chip, address, cmdv[3]);
	} else if(!strcmp(cmd, "ferase")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_flashrange(LOADER_FLASH_ERASE, address, length);
	} else if(!strcmp(cmd, "flock")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_flashrange(LOADER_FLASH_LOCK, address, length);
	} else if(!strcmp(cmd, "flockdown")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_flashrange(LOADER_FLASH_LOCKDOWN, address, length);
	} else if(!strcmp(cmd, "funlock")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_flashrange(LOADER_FLASH_UNLOCK, address, length);
	} else if(!strcmp(cmd, "fgetlock")) {
		uint32_t address;
		uint32_t length;

		if(cmdc < 3) {
			usage(name);
		}

		address = strtoul(cmdv[1], NULL, 16);
		length = strtoul(cmdv[2], NULL, 16);

		loader_start_flashrange(LOADER_FLASH_GETLOCK, address, length);
	} else if(!strcmp(cmd, "help")) {
		usage(name);
	} else {
		printf("Unknown command '%s'\n", cmd);
		usage(name);
	}

	if(osmoload.state == STATE_QUERY_PENDING) {
		osmoload.timeout.cb = &query_timeout;
		osmo_timer_schedule(&osmoload.timeout, 0, 5000000);
	}
	if(osmoload.state == STATE_LOAD_IN_PROGRESS) {
		osmoload.timeout.cb = &memop_timeout;
	}

}
Beispiel #26
0
static void hours_timer_cb(void *unused)
{
	sysmobts_update_hours(no_eeprom_write);

	osmo_timer_schedule(&hours_timer, HOURS_TIMER_SECS, 0);
}
Beispiel #27
0
static void check_temp_timer_cb(void *unused)
{
	sysmobts_check_temp(no_eeprom_write);

	osmo_timer_schedule(&temp_timer, TEMP_TIMER_SECS, 0);
}
Beispiel #28
0
static int _reset_open(ModemPlugin * modem)
{
	Osmocom * osmocom = modem;
	ModemPluginHelper * helper = osmocom->helper;
	char const * device;
	unsigned int baudrate;
	int flags;
	uint32_t tmpaddr = ROMLOAD_ADDRESS;
	char const * p;

	if((device = helper->config_get(helper->modem, "device")) == NULL)
		device = "/dev/modem";
	if((p = helper->config_get(helper->modem, "baudrate")) == NULL
			|| (baudrate = strtoul(p, NULL, 10)) == 0)
		baudrate = 115200;
	baudrate = _reset_baudrate(modem, baudrate);
	if((osmocom->fd.fd = osmo_serial_init(device, baudrate)) < 0)
	{
		/* XXX report error */
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno));
#endif
		return -1;
	}
	if(osmo_fd_register(&osmocom->fd) != 0)
	{
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno));
#endif
		/* XXX report error */
		return -1;
	}
	/* Set serial socket to non-blocking mode of operation */
	if((flags = fcntl(osmocom->fd.fd, F_GETFL)) != -1)
	{
		flags |= O_NONBLOCK;
		fcntl(osmocom->fd.fd, F_SETFL, flags);
	}
	osmocom->dnload.serial_fd.when = BSC_FD_READ;
	osmocom->dnload.serial_fd.cb = _osmocom_on_serial_read;
	if(osmocom->dnload.mode == MODE_ROMLOAD)
	{
		tmpaddr = ROMLOAD_ADDRESS;
		osmo_serial_set_baudrate(osmocom->fd.fd, ROMLOAD_INIT_BAUDRATE);
		osmocom->tick_timer.cb = &_osmocom_on_beacon_timer;
		osmocom->tick_timer.data = modem;
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
	else
	{
		tmpaddr = MTK_ADDRESS;
		osmo_serial_set_baudrate(osmocom->fd.fd, MTK_INIT_BAUDRATE);
		osmocom->tick_timer.cb = &_osmocom_on_mtk_timer;
		osmocom->tick_timer.data = modem;
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
	/* FIXME not endian proof */
	osmocom->dnload.load_address[0] = (tmpaddr >> 24) & 0xff;
	osmocom->dnload.load_address[1] = (tmpaddr >> 16) & 0xff;
	osmocom->dnload.load_address[2] = (tmpaddr >> 8) & 0xff;
	osmocom->dnload.load_address[3] = tmpaddr & 0xff;
	return 0;
}
Beispiel #29
0
static int handle_ts1_write(struct osmo_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	struct misdn_line *mline = line->driver_data;
	unsigned int ts_nr = bfd->priv_nr;
	struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
	struct e1inp_sign_link *sign_link;
	struct sockaddr_mISDN sa;
	struct msgb *msg;
	struct mISDNhead *hh;
	uint8_t *l2_data;
	int ret;

	bfd->when &= ~BSC_FD_WRITE;

	/* get the next msg for this timeslot */
	msg = e1inp_tx_ts(e1i_ts, &sign_link);
	if (!msg) {
		/* no message after tx delay timer */
		return 0;
	}

	if (mline->use_userspace_lapd) {
		DEBUGP(DLMI, "TX %u/%u/%u: %s\n",
			line->num, sign_link->tei, sign_link->sapi,
			osmo_hexdump(msg->data, msg->len));
		lapd_transmit(e1i_ts->lapd, sign_link->tei,
				sign_link->sapi, msg);
	} else {
		l2_data = msg->data;

		/* prepend the mISDNhead */
		hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh));
		hh->prim = DL_DATA_REQ;

		DEBUGP(DLMI, "TX channel(%d) TEI(%d) SAPI(%d): %s\n",
			sign_link->driver.misdn.channel, sign_link->tei,
			sign_link->sapi, osmo_hexdump(l2_data, msg->len - MISDN_HEADER_LEN));

		/* construct the sockaddr */
		sa.family = AF_ISDN;
		sa.sapi = sign_link->sapi;
		sa.dev = sign_link->tei;
		sa.channel = sign_link->driver.misdn.channel;

		ret = sendto(bfd->fd, msg->data, msg->len, 0,
			     (struct sockaddr *)&sa, sizeof(sa));
		if (ret < 0)
			fprintf(stderr, "%s sendto failed %d\n", __func__, ret);

		msgb_free(msg);
	}


	/* set tx delay timer for next event */
	e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
	e1i_ts->sign.tx_timer.data = e1i_ts;
	osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);

	return ret;
}