示例#1
0
/* write a frame into the tx queue */
static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
				uint8_t chan_nr, uint8_t link_id, uint8_t pad)
{
	struct lapdm_entity *le = dl->entity;
	struct osmo_phsap_prim pp;

	/* if there is a pending message, queue it */
	if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) {
		*msgb_push(msg, 1) = pad;
		*msgb_push(msg, 1) = link_id;
		*msgb_push(msg, 1) = chan_nr;
		msgb_enqueue(&dl->dl.tx_queue, msg);
		return -EBUSY;
	}

	osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
			PRIM_OP_REQUEST, msg);
	pp.u.data.chan_nr = chan_nr;
	pp.u.data.link_id = link_id;

	/* send the frame now */
	le->tx_pending = 0; /* disabled flow control */
	lapdm_pad_msgb(msg, pad);

	return le->l1_prim_cb(&pp.oph, le->l1_ctx);
}
示例#2
0
void ipa_prepend_header_ext(struct msgb *msg, int proto)
{
	struct ipaccess_head_ext *hh_ext;

	/* prepend the osmo ip.access header extension */
	hh_ext = (struct ipaccess_head_ext *) msgb_push(msg, sizeof(*hh_ext));
	hh_ext->proto = proto;
}
示例#3
0
static void ipaccess_prepend_header_quirk(struct msgb *msg, int proto)
{
	struct ipaccess_head *hh;

	/* prepend the ip.access header */
	hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh) + 1);
	hh->len = htons(msg->len - sizeof(*hh) - 1);
	hh->proto = proto;
}
示例#4
0
void ipa_msg_push_header(struct msgb *msg, uint8_t proto)
{
	struct ipaccess_head *hh;

	msg->l2h = msg->data;
	hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh));
	hh->proto = proto;
	hh->len = htons(msgb_l2len(msg));
}
示例#5
0
/* send a data frame to layer 1 */
static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg)
{
	uint8_t l3_len = msg->tail - msg->data;
	struct lapd_datalink *dl = lctx->dl;
	struct lapdm_datalink *mdl =
		container_of(dl, struct lapdm_datalink, dl);
	struct lapdm_msg_ctx *mctx = &mdl->mctx;
	int format = lctx->format;

	/* prepend l2 header */
	msg->l2h = msgb_push(msg, 3);
	msg->l2h[0] = LAPDm_ADDR(lctx->lpd, lctx->sapi, lctx->cr);
					/* EA is set here too */
	switch (format) {
	case LAPD_FORM_I:
		msg->l2h[1] = LAPDm_CTRL_I(lctx->n_recv, lctx->n_send,
						lctx->p_f);
		break;
	case LAPD_FORM_S:
		msg->l2h[1] = LAPDm_CTRL_S(lctx->n_recv, lctx->s_u, lctx->p_f);
		break;
	case LAPD_FORM_U:
		msg->l2h[1] = LAPDm_CTRL_U(lctx->s_u, lctx->p_f);
		break;
	default:
		msgb_free(msg);
		return -EINVAL;
	}
	msg->l2h[2] = LAPDm_LEN(l3_len); /* EL is set here too */
	if (lctx->more)
		msg->l2h[2] |= LAPDm_MORE;

	/* add ACCH header with last indicated tx-power and TA */
	if ((mctx->link_id & 0x40)) {
		struct lapdm_entity *le = mdl->entity;

		msg->l2h = msgb_push(msg, 2);
		msg->l2h[0] = le->tx_power;
		msg->l2h[1] = le->ta;
	}

	return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
			23);
}
示例#6
0
文件: octpkt.c 项目: osmocom/osmo-bts
/* push a control header (3 dwords) to the start of a msgb. This format
 * is used for command and response packets */
void octvocnet_push_ctl_hdr(struct msgb *msg, uint32_t dest_fifo_id,
			uint32_t src_fifo_id, uint32_t socket_id)
{
	tOCTVOCNET_PKT_CTL_HEADER *ch;

	ch = (tOCTVOCNET_PKT_CTL_HEADER *) msgb_push(msg, sizeof(*ch));

	ch->ulDestFifoId = htonl(dest_fifo_id);
	ch->ulSourceFifoId = htonl(src_fifo_id);
	ch->ulSocketId = htonl(socket_id);
}
示例#7
0
/* iterate over all chunks in one RTCP message, look for CNAME IEs and
 * replace all of those with 'new_cname' */
static int rtcp_sdes_cname_mangle(struct msgb *msg, struct rtcp_hdr *rh,
				  u_int16_t *rtcp_len, const char *new_cname)
{
	u_int8_t *rtcp_end;
	u_int8_t *cur = (u_int8_t *) rh;
	u_int8_t tag, len = 0;

	rtcp_end = cur + *rtcp_len;
	/* move cur to end of RTP header */
	cur += sizeof(*rh);

	/* iterate over Chunks */
	while (cur+4 < rtcp_end) {
		/* skip four bytes SSRC/CSRC */
		cur += 4;
	
		/* iterate over IE's inside the chunk */
		while (cur+1 < rtcp_end) {
			tag = *cur++;
			if (tag == 0) {
				/* end of chunk, skip additional zero */
				while (*cur++ == 0) { }
				break;
			}
			len = *cur++;
	
			if (tag == RTCP_IE_CNAME) {
				/* we've found the CNAME, lets mangle it */
				if (len < strlen(new_cname)) {
					/* we need to make more space */
					int increase = strlen(new_cname) - len;

					msgb_push(msg, increase);
					memmove(cur+len+increase, cur+len,
						rtcp_end - (cur+len));
					/* FIXME: we have to respect RTCP
					 * padding/alignment rules! */
					len += increase;
					*(cur-1) += increase;
					rtcp_end += increase;
					*rtcp_len += increase;
				}
				/* copy new CNAME into message */
				memcpy(cur, new_cname, strlen(new_cname));
				/* FIXME: zero the padding in case new CNAME
				 * is smaller than old one !!! */
			}
			cur += len;
		}
	}

	return 0;
}
示例#8
0
文件: misdn.c 项目: techniker/openBSC
static int handle_ts1_write(struct bsc_fd *bfd)
{
	struct e1inp_line *line = bfd->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;
	u_int8_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;
	}

	l2_data = msg->data;

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

	DEBUGP(DMI, "TX channel(%d) TEI(%d) SAPI(%d): %s\n",
		sign_link->driver.misdn.channel, sign_link->tei,
		sign_link->sapi, 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;
	bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 50000);

	return ret;
}
示例#9
0
/* Prefix msg with a RP-DATA header and send as CP-DATA */
static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg,
			     uint8_t rp_msg_type, uint8_t rp_msg_ref,
			     int mnsms_msg_type)
{
	struct gsm411_rp_hdr *rp;
	uint8_t len = msg->len;

	/* GSM 04.11 RP-DATA header */
	rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
	rp->len = len + 2;
	rp->msg_type = rp_msg_type;
	rp->msg_ref = rp_msg_ref;

	return inst->mn_send(inst, mnsms_msg_type, msg);
}
示例#10
0
static int gsm_recv_voice(struct osmocom_ms *ms, struct msgb *msg)
{
    struct gsm_data_frame *mncc;

    /* distribute and then free */
    if (ms->mncc_entity.mncc_recv && ms->mncc_entity.ref) {
        /* push mncc header in front of data */
        mncc = (struct gsm_data_frame *)
               msgb_push(msg, sizeof(struct gsm_data_frame));
        mncc->msg_type = GSM_TCHF_FRAME;
        mncc->callref =  ms->mncc_entity.ref;
        ms->mncc_entity.mncc_recv(ms, mncc->msg_type, mncc);
    }

    msgb_free(msg);
    return 0;
}
示例#11
0
文件: octpkt.c 项目: osmocom/osmo-bts
/* push a common header (1 dword) to the start of a msgb */
void octpkt_push_common_hdr(struct msgb *msg, uint8_t format,
			    uint8_t trace, uint32_t ptype)
{
	uint32_t ch;
	uint32_t *chptr;
	uint32_t tot_len = msgb_length(msg) + sizeof(ch);

	ch = ((format & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_FORMAT_BIT_MASK)
		<< cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_FORMAT_BIT_OFFSET) |
	     ((trace & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_TRACE_BIT_MASK)
	      	<< cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_TRACE_BIT_OFFSET) |
	     ((ptype & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_CONTROL_PROTOCOL_TYPE_BIT_MASK)
	        << cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_CONTROL_PROTOCOL_TYPE_BIT_OFFSET) |
	     (tot_len & cOCTPKT_HDR_FORMAT_PROTO_TYPE_LEN_MASK_LENGTH_BIT_MASK);

	chptr = (uint32_t *) msgb_push(msg, sizeof(ch));
	*chptr = htonl(ch);
}
示例#12
0
/* Take a B4 format message from L1 and create RSLms UNIT DATA IND */
static int send_rslms_rll_l3_ui(struct lapdm_msg_ctx *mctx, struct msgb *msg)
{
	uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
	struct abis_rsl_rll_hdr *rllh;

	/* Add the RSL + RLL header */
	msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
	msgb_push(msg, 2 + 2);
	rsl_rll_push_hdr(msg, RSL_MT_UNIT_DATA_IND, mctx->chan_nr,
		mctx->link_id, 1);
	rllh = (struct abis_rsl_rll_hdr *)msgb_l2(msg);

	rllh->data[0] = RSL_IE_TIMING_ADVANCE;
	rllh->data[1] = mctx->ta_ind;

	rllh->data[2] = RSL_IE_MS_POWER;
	rllh->data[3] = mctx->tx_power_ind;
	
	return rslms_sendmsg(msg, mctx->dl->entity);
}
示例#13
0
/*! \brief call-back from LAPD code, called when it wants to Tx data */
static void misdn_write_msg(struct msgb *msg, void *cbdata)
{
	struct osmo_fd *bfd = cbdata;
//	struct e1inp_line *line = bfd->data;
//	unsigned int ts_nr = bfd->priv_nr;
//	struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
	struct mISDNhead *hh;
	int ret;

	DEBUGP(DLMI, "PH_DATA_REQ: len=%d %s\n", msg->len,
		osmo_hexdump(msg->data, msg->len));

	hh = (struct mISDNhead *) msgb_push(msg, MISDN_HEADER_LEN);
	hh->prim = PH_DATA_REQ;
	hh->id = 0;

	ret = write(bfd->fd, msg->data, msg->len);
	if (ret < 0)
		LOGP(DLMI, LOGL_NOTICE, "write failed %d\n", ret);

	msgb_free(msg);
}
示例#14
0
/*! \brief RL-UL-UNITDATA.req (Chapter 10.2.2)
 *  \param[in] bctx BVC Context
 *  \param[in] tlli TLLI to identify MS
 *  \param[in] qos_profile Pointer to three octests of QoS profile
 *  \param[in] llc_pdu msgb pointer containing UL Unitdata IE payload
 */
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
		   const uint8_t *qos_profile, struct msgb *llc_pdu)
{
	struct msgb *msg = llc_pdu;
	uint8_t bssgp_cid[8];
	uint8_t bssgp_align[3] = {0, 0, 0};
	struct bssgp_ud_hdr *budh;
	int align = sizeof(*budh);

	/* FIXME: Optional LSA Identifier List, PFI */

	/* Cell Identifier */
	bssgp_create_cell_id(bssgp_cid, &bctx->ra_id, bctx->cell_id);
	align += 2; /* add T+L */
	align += sizeof(bssgp_cid);

	/* First push alignment IE */
	align += 2; /* add T+L */
	align = (4 - align) & 3; /* how many octest are required to align? */
	msgb_tvlv_push(msg, BSSGP_IE_ALIGNMENT, align, bssgp_align);

	/* Push other IEs */
	msgb_tvlv_push(msg, BSSGP_IE_CELL_ID, sizeof(bssgp_cid), bssgp_cid);

	/* User Data Header */
	budh = (struct bssgp_ud_hdr *) msgb_push(msg, sizeof(*budh));
	budh->tlli = htonl(tlli);
	memcpy(budh->qos_profile, qos_profile, 3);
	budh->pdu_type = BSSGP_PDUT_UL_UNITDATA;

	/* set NSEI and BVCI in msgb cb */
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;

	rate_ctr_inc(&bctx->ctrg->ctr[BSSGP_CTR_PKTS_OUT]);
	rate_ctr_add(&bctx->ctrg->ctr[BSSGP_CTR_BYTES_OUT], msg->len);

	return gprs_ns_sendmsg(bssgp_nsi, msg);
}
示例#15
0
文件: client.c 项目: key2/libuma
int ga_csr_uplink_dtap_sms(int sock, char *dest, char *text, uint8_t tpdu_mr, uint8_t rpdu_mr){
	struct uma_msg_s *uma_msg;
	u_int8_t *titi, *tata;
	int j, i, len;
	struct gsm48_hdr *ngh;
	struct gsm411_rp_hdr *rph;
	struct msgb *nmsg;
	struct gsm_sms *sms = malloc(sizeof(struct gsm_sms));
	uint8_t *data;
	uint8_t oa[12];
	uint8_t oa_len;
	uint8_t *rp_ud_len;

	if(strlen(dest) >= sizeof(sms->dest_addr)){
		fprintf(stderr, "Broken destination number\n");
		return -2;
	}

	memset(sms, 0, sizeof(struct gsm_sms));

	sms->validity_period = 0xff;
	sms->status_rep_req = 0;
	sms->ud_hdr_ind = 0;
	sms->protocol_id = 0;
	sms->data_coding_scheme = 0;
	sms->reject_duplicates = 0;
	sms->msg_ref = tpdu_mr;
	sms->user_data_len =  gsm_7bit_encode(sms->user_data, text);
	/* workaround that libosmocore is currently returning the number of
	   encoded octets and not septets
	*/
	sms->user_data_len = (sms->user_data_len*8)/7;
	strncpy(sms->dest_addr, dest, sizeof(sms->dest_addr) - 1);

	nmsg = gsm411_msgb_alloc();
	if (!nmsg){
		return -1;
	}
	rph = (struct gsm411_rp_hdr *)msgb_push(nmsg, sizeof(*rph));
	rph->msg_type = GSM411_MT_RP_DATA_MO;
	rph->msg_ref = rpdu_mr;

	data = (u_int8_t *)msgb_put(nmsg, 1);
	data[0] = 0;

	/* hardcode smsc address for now */
	data = (u_int8_t *)msgb_put(nmsg, 8);
	data[0] = 0x07;
	data[1] = 0x91;
	data[2] = 0x33;
	data[3] = 0x06;
	data[4] = 0x09;
	data[5] = 0x10;
	data[6] = 0x93;
	data[7] = 0xf0;

	ngh = (struct gsm48_hdr *) msgb_push(nmsg, sizeof(*ngh));

	ngh->proto_discr = GSM48_PDISC_SMS;
	ngh->msg_type = GSM411_MT_CP_DATA;

	data = msgb_put(nmsg, 1);
	rp_ud_len = data;

	*rp_ud_len = gsm340_tpdu_encode(nmsg, sms);
	/* substract rpdu length, type and ref from total length */
	rph->len = nmsg->len - 3;

	uma_msg = uma_create_msg(GA_CSR_UPLINK_DIRECT_TRANSFER, 0, GA_CSR);
	uma_msg->tlv[uma_msg->ntlv++] = create_IEI_L3_Message(nmsg->data, nmsg->len);
	j = uma_create_buffer(&titi, uma_msg);

	printf("Sending GA-CSR UPLINK DIRECT TRANSFER CP-DATA RP-DATA...");
	write(sock, titi, j);
	printf("passed to proxy\n");
	// there seems to be a memory corruption in libosmocore/libuma, hence not freeing even though i should :/
	//uma_delete_msg(uma_msg);
	//msgb_free(nmsg);

	return 0;
}
示例#16
0
文件: sim.c 项目: lgphone/osmocom-bb
/* handling sim events */
void sim_handler(void)
{
    static struct msgb *msg;
    struct l1ctl_hdr *l1h;
    static uint8_t mode;
    static uint8_t *response;
    static uint16_t length;

    switch (sim_state) {
    case SIM_STATE_IDLE:
        if (!sim_len)
            break; /* wait for SIM command */
        /* check if instructions expects a response */
        if (/* GET RESPONSE needs SIM_APDU_GET */
            (sim_len == 5 && sim_data[0] == SIM_CLASS &&
             sim_data[1] == SIM_GET_RESPONSE && sim_data[2] == 0x00 &&
             sim_data[3] == 0x00) ||
            /* READ BINARY/RECORD needs SIM_APDU_GET */
            (sim_len >= 5 && sim_data[0] == SIM_CLASS &&
             (sim_data[1] == SIM_READ_BINARY ||
              sim_data[1] == SIM_READ_RECORD)))
            mode = SIM_APDU_GET;
        else
            mode = SIM_APDU_PUT;

        length = sim_data[4];

        /* allocate space for expected response */
        msg = msgb_alloc_headroom(256, L3_MSG_HEAD
                                  + sizeof(struct l1ctl_hdr), "l1ctl1");
        response = msgb_put(msg, length + 2 + 1);

        sim_state = SIM_STATE_TX_HEADER;

        /* send APDU header */
        calypso_sim_transmit(sim_data, 5);
        break;
    case SIM_STATE_TX_HEADER:
        if (!txDoneFlag)
            break; /* wait until header is transmitted */
        /* Disable all interrupt driven functions */
        writew(0xFF, REG_SIM_MASKIT);
        /* Case 1: No input, No Output */
        if (length == 0) {
            sim_state = SIM_STATE_RX_STATUS;
            calypso_sim_receive(response + 1, 2);
            break;
        }
        /* Case 2: No input / Output of known length */
        if (mode == SIM_APDU_PUT) {
            sim_state = SIM_STATE_RX_ACK;
            calypso_sim_receive(response, 1);
            break;
            /* Case 4: Input / No output */
        } else {
            sim_state = SIM_STATE_RX_ACK_DATA;
            calypso_sim_receive(response, length + 1 + 2);
        }
        break;
    case SIM_STATE_RX_STATUS:
        if (!rxDoneFlag)
            break; /* wait until data is received */
        /* Disable all interrupt driven functions */
        writew(0xFF, REG_SIM_MASKIT);
        /* disable special ignore case */
        sim_ignore_waiting_char = 0;
        /* wrong number of bytes received */
        if (sim_rx_character_count != 2) {
            puts("SIM: Failed to read status\n");
            goto error;
        }
        msgb_pull(msg, length + 1); /* pull up to status info */
        goto queue;
    case SIM_STATE_RX_ACK:
        if (!rxDoneFlag)
            break; /* wait until data is received */
        /* Disable all interrupt driven functions */
        writew(0xFF, REG_SIM_MASKIT);
        /* error received */
        if (sim_rx_character_count == 2) {
            puts("SIM: command failed\n");
            msgb_pull(msg, msg->len - 2);
            msg->data[0] = response[0];
            msg->data[1] = response[1];
            goto queue;
        }
        /* wrong number of bytes received */
        if (sim_rx_character_count != 1) {
            puts("SIM: ACK read failed\n");
            goto error;
        }
        if (response[0] != sim_data[1]) {
            puts("SIM: ACK does not match request\n");
            goto error;
        }
        sim_state = SIM_STATE_TX_DATA;
        calypso_sim_transmit(sim_data + 5, length);
        break;
    case SIM_STATE_TX_DATA:
        if (!txDoneFlag)
            break; /* wait until data is transmitted */
        /* Disable all interrupt driven functions */
        writew(0xFF, REG_SIM_MASKIT);
        /* Ignore waiting char for RUN GSM ALGORITHM */
        /* TODO: implement proper handling of the "Procedure Bytes"
           than this is no longer needed */
        if(sim_data[1] == 0x88)
            sim_ignore_waiting_char = 1;
        sim_state = SIM_STATE_RX_STATUS;
        calypso_sim_receive(response + length + 1, 2);
        break;
    case SIM_STATE_RX_ACK_DATA:
        if (!rxDoneFlag)
            break; /* wait until data is received */
        /* Disable all interrupt driven functions */
        writew(0xFF, REG_SIM_MASKIT);
        /* error received */
        if (sim_rx_character_count == 2) {
            puts("SIM: command failed\n");
            msgb_pull(msg, msg->len - 2);
            msg->data[0] = response[0];
            msg->data[1] = response[1];
            goto queue;
        }
        /* wrong number of bytes received */
        if (sim_rx_character_count != length + 1 + 2) {
            puts("SIM: Failed to read data\n");
            goto error;
        }
        msgb_pull(msg, 1); /* pull ACK byte */
        goto queue;
    }

    return;

error:
    msgb_pull(msg, msg->len - 2);
    msg->data[0] = 0;
    msg->data[1] = 0;
queue:
    printf("SIM Response (%d): %s\n", msg->len,
           osmo_hexdump(msg->data, msg->len));
    l1h = (struct l1ctl_hdr *) msgb_push(msg, sizeof(*l1h));
    l1h->msg_type = L1CTL_SIM_CONF;
    l1h->flags = 0;
    msg->l1h = (uint8_t *)l1h;
    l1_queue_for_l2(msg);
    /* go IDLE */
    sim_state = SIM_STATE_IDLE;
    sim_len = 0;

    return;
}