Example #1
0
struct msgb *rua_new_dt(int is_ps, uint32_t context_id, struct msgb *inmsg)
{
	RUA_DirectTransfer_t out;
	RUA_DirectTransferIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_directtransferies(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_DirectTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_DirectTransfer,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_DirectTransfer, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
Example #2
0
struct msgb *rua_new_udt(struct msgb *inmsg)
{
	RUA_ConnectionlessTransfer_t out;
	RUA_ConnectionlessTransferIEs_t ies;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_connectionlesstransferies(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_ConnectionlessTransfer,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_ConnectionlessTransfer, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
Example #3
0
int main(int argc, char **argv)
{
	struct ss_request req;
	const int size = sizeof(ussd_request);
	int i;
	struct msgb *msg;

	osmo_init_logging(&info);

	memset(&req, 0, sizeof(req));
	gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request, size, &req);
	printf("Tested if it still works. Text was: %s\n", req.ussd_text);

	memset(&req, 0, sizeof(req));
	gsm0480_decode_ss_request((struct gsm48_hdr *) interrogate_ss, size, &req);
	OSMO_ASSERT(strlen((char *) req.ussd_text) == 0);
	OSMO_ASSERT(req.ss_code == 33);
	printf("interrogateSS CFU text..'%s' code %d\n", req.ussd_text, req.ss_code);

	printf("Testing parsing a USSD request and truncated versions\n");

	for (i = size; i > sizeof(struct gsm48_hdr); --i) {
		int rc = parse_ussd(&ussd_request[0], i);
		printf("Result for %d is %d\n", rc, i);
	}

	printf("Mangling the container now\n");
	for (i = size; i > sizeof(struct gsm48_hdr) + 2; --i) {
		int rc = parse_mangle_ussd(&ussd_request[0], i);
		printf("Result for %d is %d\n", rc, i);
	}

	printf("<CR> case test for 7 bit encode\n");
	test_7bit_ussd("01234567",   "b0986c46abd96e",   "");
	test_7bit_ussd("0123456",    "b0986c46abd91a",   "");
	test_7bit_ussd("01234567\r", "b0986c46abd96e0d", "");
        /* The appended \r is compliant to GSM 03.38 section 6.1.2.3.1: */
	test_7bit_ussd("0123456\r",  "b0986c46abd91a0d", "\r");
	test_7bit_ussd("012345\r",   "b0986c46ab351a",   "");

	printf("Checking GSM 04.80 USSD message generation.\n");

	test_7bit_ussd("", "", "");
	msg = gsm0480_create_unstructuredSS_Notify (0x00, "");
	printf ("Created unstructuredSS_Notify (0x00): %s\n",
			osmo_hexdump(msgb_data(msg), msgb_length(msg)));
	msgb_free (msg);

	test_7bit_ussd("forty-two", "e6b79c9e6fd1ef6f", "");
	msg = gsm0480_create_unstructuredSS_Notify (0x42, "forty-two");
	printf ("Created unstructuredSS_Notify (0x42): %s\n",
			osmo_hexdump(msgb_data(msg), msgb_length(msg)));
	msgb_free (msg);
	return 0;
}
Example #4
0
int l1ctl_sock_write_msg(struct l1ctl_sock_client *lsc, struct msgb *msg)
{
	int rc;
	rc = write(lsc->ofd.fd, msgb_data(msg), msgb_length(msg));
	msgb_free(msg);
	return rc;
}
/*
 * I get called from the LAPDm code when something was sent my way...
 */
static int bts_to_ms_tx_cb(struct msgb *in_msg, struct lapdm_entity *le, void *_ctx)
{
	struct lapdm_polling_state *state = _ctx;


	printf("%s: MS->BTS(us) message %d\n", __func__, msgb_length(in_msg));


	if (state->bts_read == 0) {
		printf("BTS: Verifying CM request.\n");
		ASSERT(msgb_l3len(in_msg) == ARRAY_SIZE(cm_padded));
		ASSERT(memcmp(in_msg->l3h, cm_padded, ARRAY_SIZE(cm_padded)) == 0);
	} else if (state->bts_read == 1) {
		printf("BTS: Verifying dummy message.\n");
		ASSERT(msgb_l3len(in_msg) == ARRAY_SIZE(dummy1));
		ASSERT(memcmp(in_msg->l3h, dummy1, ARRAY_SIZE(dummy1)) == 0);
	} else {
		printf("BTS: Do not know to verify: %d\n", state->bts_read);
	}

	state->bts_read += 1;
	msgb_free(in_msg);

	return 0;
}
static int ms_to_bts_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *_ctx)
{
	struct lapdm_polling_state *state = _ctx;

	printf("%s: BTS->MS(us) message %d\n", __func__, msgb_length(msg));

	if (state->ms_read == 0) {
		struct abis_rsl_rll_hdr hdr;

		printf("MS: Verifying incoming primitive.\n");
		ASSERT(msg->len == sizeof(struct abis_rsl_rll_hdr) + 3);

		/* verify the header */
		memset(&hdr, 0, sizeof(hdr));
		rsl_init_rll_hdr(&hdr, RSL_MT_EST_CONF);
		hdr.c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
		ASSERT(memcmp(msg->data, &hdr, sizeof(hdr)) == 0);

		/* Verify the added RSL_IE_L3_INFO but we have a bug here */
		ASSERT(msg->data[6] == RSL_IE_L3_INFO);
		#warning "RSL_IE_L3_INFO 16 bit length is wrong"
		/* ASSERT(msg->data[7] == 0x0 && msg->data[8] == 0x9c); */
		/* this should be 0x0 and 0x0... but we have a bug */
	} else if (state->ms_read == 1) {
		printf("MS: Verifying incoming MM message: %d\n", msgb_l3len(msg));
		ASSERT(msgb_l3len(msg) == 3);
		ASSERT(memcmp(msg->l3h, &mm[12], msgb_l3len(msg)) == 0);
	} else {
		printf("MS: Do not know to verify: %d\n", state->ms_read);
	}

	state->ms_read += 1;
	msgb_free(msg);
	return 0;
}
Example #7
0
static void esme_write_cb(struct osmo_fd *ofd, struct msgb *msg)
{
	struct esme *esme = ofd->data;
	int rc;

	rc = write(ofd->fd, msgb_data(msg), msgb_length(msg));
	if (rc == 0) {
		osmo_fd_unregister(&esme->wqueue.bfd);
		close(esme->wqueue.bfd.fd);
		esme->wqueue.bfd.fd = -1;
		exit(99);
	} else if (rc < msgb_length(msg)) {
		LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id);
		return;
	}
}
Example #8
0
int rua_tx_udt(struct hnb_context *hnb, const uint8_t *data, unsigned int len)
{
	RUA_ConnectionlessTransfer_t out;
	RUA_ConnectionlessTransferIEs_t ies;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	ies.ranaP_Message.buf = (uint8_t *) data;
	ies.ranaP_Message.size = len;

	/* FIXME: msgb_free(msg)? ownership not yet clear */

	memset(&out, 0, sizeof(out));
	rc = rua_encode_connectionlesstransferies(&out, &ies);
	if (rc < 0)
		return rc;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_ConnectionlessTransfer,
					      &out);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_ConnectionlessTransfer, &out);

	DEBUGP(DRUA, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	return hnbgw_rua_tx(hnb, msg);
}
/* override */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
{
	msgb_free(last_ns_tx_msg);
	last_ns_tx_msg = msg;

	return msgb_length(msg);
}
Example #10
0
static int pcu_sock_write(struct osmo_fd *bfd)
{
	struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
	int rc;

	while (!llist_empty(&state->upqueue)) {
		struct msgb *msg, *msg2;
		struct gsm_pcu_if *pcu_prim;

		/* peek at the beginning of the queue */
		msg = llist_entry(state->upqueue.next, struct msgb, list);
		pcu_prim = (struct gsm_pcu_if *)msg->data;

		bfd->when &= ~BSC_FD_WRITE;

		/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
		if (!msgb_length(msg)) {
			LOGP(DL1IF, LOGL_ERROR, "message type (%d) with ZERO "
				"bytes!\n", pcu_prim->msg_type);
			goto dontsend;
		}

		/* try to send it over the socket */
		rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
		if (rc == 0)
			goto close;
		if (rc < 0) {
			if (errno == EAGAIN) {
				bfd->when |= BSC_FD_WRITE;
				break;
			}
			goto close;
		}

dontsend:
		/* _after_ we send it, we can deueue */
		msg2 = msgb_dequeue(&state->upqueue);
		assert(msg == msg2);
		msgb_free(msg);
	}
	return 0;

close:
	pcu_sock_close(state, 1);

	return -1;
}
Example #11
0
static int smpp_handle_deliver(struct esme *esme, struct msgb *msg)
{
	struct deliver_sm_t deliver;
	struct deliver_sm_resp_t deliver_r;
	struct submit_sm_t submit;
	int rc;

	memset(&deliver, 0, sizeof(deliver));
	SMPP34_UNPACK(rc, DELIVER_SM, &deliver, msgb_data(msg), msgb_length(msg));
	if (rc < 0)
		return rc;

	INIT_RESP(DELIVER_SM_RESP, &deliver_r, &deliver);

	PACK_AND_SEND(esme, &deliver_r);

	memset(&submit, 0, sizeof(submit));
	submit.command_id = SUBMIT_SM;
	submit.command_status = ESME_ROK;
	submit.sequence_number = esme_inc_seq_nr(esme);

	submit.dest_addr_ton =  deliver.source_addr_ton;
	submit.dest_addr_npi =  deliver.source_addr_npi;
	memcpy(submit.destination_addr, deliver.source_addr,
		OSMO_MIN(sizeof(submit.destination_addr),
			 sizeof(deliver.source_addr)));

	submit.source_addr_ton = deliver.dest_addr_ton;
	submit.source_addr_npi = deliver.dest_addr_npi;
	memcpy(submit.source_addr, deliver.destination_addr,
		OSMO_MIN(sizeof(submit.source_addr),
			 sizeof(deliver.destination_addr)));

	submit.esm_class = deliver.esm_class;
	submit.protocol_id = deliver.protocol_id;
	submit.priority_flag = deliver.priority_flag;
	memcpy(submit.schedule_delivery_time, deliver.schedule_delivery_time,
	       OSMO_MIN(sizeof(submit.schedule_delivery_time),
		        sizeof(deliver.schedule_delivery_time)));
	memcpy(submit.validity_period, deliver.validity_period,
		OSMO_MIN(sizeof(submit.validity_period),
			 sizeof(deliver.validity_period)));
	submit.registered_delivery = deliver.registered_delivery;
	submit.replace_if_present_flag = deliver.replace_if_present_flag;
	submit.data_coding = deliver.data_coding;
	submit.sm_default_msg_id = deliver.sm_default_msg_id;
	submit.sm_length = deliver.sm_length;
	memcpy(submit.short_message, deliver.short_message,
		OSMO_MIN(sizeof(submit.short_message),
			 sizeof(deliver.short_message)));
	/* FIXME: TLV? */

	return PACK_AND_SEND(esme, &submit);
}
Example #12
0
struct msgb *rua_new_disc(int is_ps, uint32_t context_id, struct msgb *inmsg)
{
	RUA_Disconnect_t out;
	RUA_DisconnectIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	/* FIXME: make cause configurable */
	ies.cause.present = RUA_Cause_PR_radioNetwork;
	ies.cause.choice.radioNetwork = RUA_CauseRadioNetwork_normal;
	if (inmsg && inmsg->data&& msgb_length(inmsg)) {
		ies.presenceMask |= DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT;
		OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	}
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_disconnecties(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_Disconnect,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_Disconnect,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_Disconnect, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
Example #13
0
static struct xua_msg *m3ua_gen_error_msg(uint32_t err_code, struct msgb *msg)
{
	struct xua_msg *xua = m3ua_gen_error(err_code);
	unsigned int len_max_40 = msgb_length(msg);

	if (len_max_40 > 40)
		len_max_40 = 40;

	xua_msg_add_data(xua, M3UA_IEI_DIAG_INFO, len_max_40, msgb_data(msg));

	return xua;
}
Example #14
0
static int ranap_tx_reset_ack(struct hnb_context *hnb,
				RANAP_CN_DomainIndicator_t domain)
{
	struct msgb *msg;
	int rc;

	msg = ranap_new_msg_reset_ack(domain, NULL);
	if (!msg)
		return -1;

	rc = rua_tx_udt(hnb, msg->data, msgb_length(msg));

	msgb_free(msg);

	return rc;
}
Example #15
0
/* 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);
}
Example #16
0
int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg)
{
	RUA_RUA_PDU_t _pdu, *pdu = &_pdu;
	asn_dec_rval_t dec_ret;
	int rc;

	/* decode and handle to _hnbgw_hnbap_rx() */

	memset(pdu, 0, sizeof(*pdu));
	dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,
			      msg->data, msgb_length(msg), 0, 0);
	if (dec_ret.code != RC_OK) {
		LOGP(DRUA, LOGL_ERROR, "Error in ASN.1 decode\n");
		return rc;
	}

	rc = _hnbgw_rua_rx(msg, pdu);

	return rc;
}
Example #17
0
int rua_tx_disc(struct hnb_context *hnb, int is_ps, uint32_t context_id,
	        const RUA_Cause_t *cause, const uint8_t *data, unsigned int len)
{
	RUA_Disconnect_t out;
	RUA_DisconnectIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	memcpy(&ies.cause, cause, sizeof(ies.cause));
	if (data && len) {
		ies.presenceMask |= DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT;
		ies.ranaP_Message.buf = (uint8_t *) data;
		ies.ranaP_Message.size = len;
	}

	/* FIXME: msgb_free(msg)? ownership not yet clear */

	memset(&out, 0, sizeof(out));
	rc = rua_encode_disconnecties(&out, &ies);
	if (rc < 0)
		return rc;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_Disconnect,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_Disconnect,
					      &out);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_Disconnect, &out);

	DEBUGP(DRUA, "transmitting RUA (cn=%s) payload of %u bytes\n",
		is_ps ? "ps" : "cs", msgb_length(msg));


	return hnbgw_rua_tx(hnb, msg);
}
Example #18
0
/*! \brief process M3UA message received from socket
 *  \param[in] asp Application Server Process receiving \ref msg
 *  \param[in] msg received message buffer
 *  \returns 0 on success; negative on error */
int m3ua_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg)
{
	struct xua_msg *xua = NULL, *err = NULL;
	int rc = 0;

	OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA);

	/* caller owns msg memory, we shall neither free it here nor
	 * keep references beyond the executin of this function and its
	 * callees */

	xua = xua_from_msg(M3UA_VERSION, msgb_length(msg), msgb_data(msg));
	if (!xua) {
		struct xua_common_hdr *hdr = (struct xua_common_hdr *) msg->data;

		LOGPASP(asp, DLM3UA, LOGL_ERROR, "Unable to parse incoming "
			"M3UA message\n");

		if (hdr->version != M3UA_VERSION)
			err = m3ua_gen_error_msg(M3UA_ERR_INVALID_VERSION, msg);
		else
			err = m3ua_gen_error_msg(M3UA_ERR_PARAM_FIELD_ERR, msg);
		goto out;
	}

	LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n",
		xua_hdr_dump(xua, &xua_dialect_m3ua));

	if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) {
		err = m3ua_gen_error_msg(M3UA_ERR_MISSING_PARAM, msg);
		goto out;
	}

	/* TODO: check if any AS configured in ASP */
	/* TODO: check for valid routing context */

	switch (xua->hdr.msg_class) {
	case M3UA_MSGC_XFER:
		/* The DATA message MUST NOT be sent on stream 0. */
		if (msgb_sctp_stream(msg) == 0) {
			rc = M3UA_ERR_INVAL_STREAM_ID;
			break;
		}
		rc = m3ua_rx_xfer(asp, xua);
		break;
	case M3UA_MSGC_ASPSM:
	case M3UA_MSGC_ASPTM:
		rc = m3ua_rx_asp(asp, xua);
		break;
	case M3UA_MSGC_MGMT:
		rc = m3ua_rx_mgmt(asp, xua);
		break;
	case M3UA_MSGC_RKM:
		rc = m3ua_rx_rkm(asp, xua);
		break;
	case M3UA_MSGC_SNM:
		/* FIXME */
		LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unsupported M3UA "
			"Message Class %u\n", xua->hdr.msg_class);
		err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg);
		break;
	default:
		LOGPASP(asp, DLM3UA, LOGL_NOTICE, "Received unknown M3UA "
			"Message Class %u\n", xua->hdr.msg_class);
		err = m3ua_gen_error_msg(M3UA_ERR_UNSUPP_MSG_CLASS, msg);
		break;
	}

	if (rc > 0)
		err = m3ua_gen_error_msg(rc, msg);

out:
	if (err)
		m3ua_tx_xua_asp(asp, err);

	xua_msg_free(xua);

	return rc;
}
Example #19
0
static int feed_write_cb(struct osmo_fd *ofd, struct msgb *msg)
{
	return write(ofd->fd, msgb_data(msg), msgb_length(msg));
}
Example #20
0
static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep,
	const char *name1, unsigned int index1, const char *name2, int64_t value,
	const char *unit)
{
	char *buf;
	int buf_size;
	int nchars, rc = 0;
	char *fmt = NULL;
	char *prefix = srep->name_prefix;
	int old_len = msgb_length(srep->buffer);

	if (prefix) {
		if (name1) {
			if (index1 != 0)
				fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s";
			else
				fmt = "%1$s.%2$s.%3$s:%4$d|%5$s";
		} else {
			fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s";
		}
	} else {
		prefix = "";
		if (name1) {
			if (index1 != 0)
				fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s";
			else
				fmt = "%1$s%2$s.%3$s:%4$d|%5$s";
		} else {
			fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s";
		}
	}

	if (srep->agg_enabled) {
		if (msgb_length(srep->buffer) > 0 &&
			msgb_tailroom(srep->buffer) > 0)
		{
			msgb_put_u8(srep->buffer, '\n');
		}
	}

	buf = (char *)msgb_put(srep->buffer, 0);
	buf_size = msgb_tailroom(srep->buffer);

	nchars = snprintf(buf, buf_size, fmt,
		prefix, name1, name2,
		value, unit, index1);

	if (nchars >= buf_size) {
		/* Truncated */
		/* Restore original buffer (without trailing LF) */
		msgb_trim(srep->buffer, old_len);
		/* Send it */
		rc = osmo_stats_reporter_send_buffer(srep);

		/* Try again */
		buf = (char *)msgb_put(srep->buffer, 0);
		buf_size = msgb_tailroom(srep->buffer);

		nchars = snprintf(buf, buf_size, fmt,
			prefix, name1, name2,
			value, unit, index1);

		if (nchars >= buf_size)
			return -EMSGSIZE;
	}

	if (nchars > 0)
		msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars);

	if (!srep->agg_enabled)
		rc = osmo_stats_reporter_send_buffer(srep);

	return rc;
}
Example #21
0
static void test_bssgp_flow_control_bvc(void)
{
	struct bssgp_bvc_ctx bctx = {
		.nsei = 0x1234,
		.bvci = 0x5678,
	};
	const uint8_t  tag = 42;
	const uint32_t bmax = 0x1022 * 100;
	const uint32_t rate = 0xc040 / 8 * 100;
	const uint32_t bmax_ms = bmax / 2;
	const uint32_t rate_ms = rate / 2;
	uint8_t  ratio = 0x78;
	uint32_t qdelay = 0x1144 * 10;
	int rc;

	static uint8_t expected_simple_msg[] = {
		0x26,
		0x1e, 0x81, 0x2a,		/* tag */
		0x05, 0x82, 0x10, 0x22,		/* Bmax */
		0x03, 0x82, 0xc0, 0x40,		/* R */
		0x01, 0x82, 0x08, 0x11,		/* Bmax_MS */
		0x1c, 0x82, 0x60, 0x20,		/* R_MS */
	};

	static uint8_t expected_ext_msg[] = {
		0x26,
		0x1e, 0x81, 0x2a,		/* tag */
		0x05, 0x82, 0x10, 0x22,		/* Bmax */
		0x03, 0x82, 0xc0, 0x40,		/* R */
		0x01, 0x82, 0x08, 0x11,		/* Bmax_MS */
		0x1c, 0x82, 0x60, 0x20,		/* R_MS */
		0x3c, 0x81, 0x78,		/* ratio */
		0x06, 0x82, 0x11, 0x44,		/* Qdelay */
	};

	printf("----- %s START\n", __func__);

	rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms,
		NULL, NULL);

	OSMO_ASSERT(rc >= 0);
	OSMO_ASSERT(last_ns_tx_msg != NULL);
	printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg));
	OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_simple_msg));
	OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg),
			expected_simple_msg, sizeof(expected_simple_msg)));

	rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms,
		&ratio, &qdelay);

	OSMO_ASSERT(rc >= 0);
	OSMO_ASSERT(last_ns_tx_msg != NULL);
	printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg));
	OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_ext_msg));
	OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg),
			expected_ext_msg, sizeof(expected_ext_msg)));

	msgb_free(last_ns_tx_msg);
	last_ns_tx_msg = NULL;

	printf("----- %s END\n", __func__);
}

static struct log_info info = {};

int main(int argc, char **argv)
{
	struct sockaddr_in bss_peer= {0};

	osmo_init_logging(&info);
	log_set_use_color(osmo_stderr_target, 0);
	log_set_print_filename(osmo_stderr_target, 0);

	bssgp_nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);

	bss_peer.sin_family = AF_INET;
	bss_peer.sin_port = htons(32000);
	bss_peer.sin_addr.s_addr = htonl(0x7f0000ff);

	gprs_ns_nsip_connect(bssgp_nsi, &bss_peer, BSS_NSEI, BSS_NSEI+1);


	printf("===== BSSGP test START\n");
	test_bssgp_suspend_resume();
	test_bssgp_status();
	test_bssgp_bad_reset();
	test_bssgp_flow_control_bvc();
	printf("===== BSSGP test END\n\n");

	exit(EXIT_SUCCESS);
}