Example #1
0
int ipa_ccm_tlv_to_unitdata(struct ipaccess_unit *ud,
			     const struct tlv_parsed *tp)
{
	int rc = 0;

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_SERNR, 1))
		ud->serno = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_SERNR));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_UNITNAME, 1))
		ud->unit_name = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_UNITNAME));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_LOCATION1, 1))
		ud->location1 = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_LOCATION1));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_LOCATION2, 1))
		ud->location2 = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_LOCATION2));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_EQUIPVERS, 1))
		ud->equipvers = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_EQUIPVERS));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_SWVERSION, 1))
		ud->swversion = talloc_strdup(ud, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_SWVERSION));

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_MACADDR, 17)) {
		rc = osmo_macaddr_parse(ud->mac_addr, (char *)
					TLVP_VAL(tp, IPAC_IDTAG_MACADDR));
		if (rc < 0)
			goto out;
	}

	if (TLVP_PRES_LEN(tp, IPAC_IDTAG_UNIT, 1))
		rc = ipa_parse_unitid((char *)
					TLVP_VAL(tp, IPAC_IDTAG_UNIT), ud);

out:
	return rc;
}
Example #2
0
int ipa_server_conn_ccm(struct ipa_server_conn *conn, struct msgb *msg)
{
	struct tlv_parsed tlvp;
	uint8_t msg_type = *(msg->l2h);
	struct ipaccess_unit unit_data = {};
	char *unitid;
	int len, rc;

	/* shared CCM handling on both server and client */
	rc = ipa_ccm_rcvmsg_base(msg, &conn->ofd);
	switch (rc) {
	case -1:
		/* error in IPA CCM processing */
		goto err;
	case 1:
		/* IPA CCM message that was handled in _base */
		return 0;
	case 0:
		/* IPA CCM message that we need to handle */
		break;
	default:
		/* Error */
		LOGIPA(conn, LOGL_ERROR, "Unexpected return from "
		     "ipa_ccm_rcvmsg_base: %d\n", rc);
		goto err;
	}

	switch (msg_type) {
	case IPAC_MSGT_ID_RESP:
		rc = ipa_ccm_id_resp_parse(&tlvp, (const uint8_t *)msg->l2h+1, msgb_l2len(msg)-1);
		if (rc < 0) {
			LOGIPA(conn, LOGL_ERROR, "IPA CCM RESPonse with "
				"malformed TLVs\n");
			goto err;
		}
		if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT)) {
			LOGIPA(conn, LOGL_ERROR, "IPA CCM RESP without "
				"unit ID\n");
			goto err;
		}
		len = TLVP_LEN(&tlvp, IPAC_IDTAG_UNIT);
		if (len < 1) {
			LOGIPA(conn, LOGL_ERROR, "IPA CCM RESP with short"
				"unit ID\n");
			goto err;
		}
		unitid = (char *) TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT);
		unitid[len-1] = '\0';
		ipa_parse_unitid(unitid, &unit_data);

		/* FIXME */
		rc = conn->ccm_cb(conn, msg, &tlvp, &unit_data);
		if (rc < 0)
			goto err;
		break;
	default:
		LOGIPA(conn, LOGL_ERROR, "Unknown IPA message type\n");
		break;
	}
	return 0;
err:
	/* in case of any error, we close the connection */
	ipa_server_conn_destroy(conn);
	return -1;
}