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; }
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; }