sbcap: Request and handle Write Replace Warning Indication
Change-Id: I563e7d1c999f14b8197bb41e85b7bcf6262fe2a0
This commit is contained in:
parent
1429377005
commit
4a9d22e5a0
|
@ -16,6 +16,7 @@ enum cbc_cell_id_type {
|
||||||
CBC_CELL_ID_LAI,
|
CBC_CELL_ID_LAI,
|
||||||
CBC_CELL_ID_LAC,
|
CBC_CELL_ID_LAC,
|
||||||
CBC_CELL_ID_CI,
|
CBC_CELL_ID_CI,
|
||||||
|
CBC_CELL_ID_ECGI,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cbc_cell_id {
|
struct cbc_cell_id {
|
||||||
|
@ -27,6 +28,7 @@ struct cbc_cell_id {
|
||||||
struct osmo_location_area_id lai;
|
struct osmo_location_area_id lai;
|
||||||
uint16_t lac;
|
uint16_t lac;
|
||||||
uint16_t ci;
|
uint16_t ci;
|
||||||
|
struct osmo_eutran_cell_global_id ecgi;
|
||||||
} u;
|
} u;
|
||||||
/* only in failure list */
|
/* only in failure list */
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -11,3 +11,6 @@ typedef struct SBcAP_SBC_AP_PDU SBcAP_SBC_AP_PDU_t;
|
||||||
SBcAP_SBC_AP_PDU_t *sbcap_gen_write_replace_warning_req(void *ctx, const struct cbc_message *cbcmsg);
|
SBcAP_SBC_AP_PDU_t *sbcap_gen_write_replace_warning_req(void *ctx, const struct cbc_message *cbcmsg);
|
||||||
SBcAP_SBC_AP_PDU_t *sbcap_gen_stop_warning_req(void *ctx, const struct cbc_message *cbcmsg);
|
SBcAP_SBC_AP_PDU_t *sbcap_gen_stop_warning_req(void *ctx, const struct cbc_message *cbcmsg);
|
||||||
SBcAP_SBC_AP_PDU_t *sbcap_gen_error_ind(void *ctx, SBcAP_Cause_t cause, SBcAP_SBC_AP_PDU_t *rx_pdu);
|
SBcAP_SBC_AP_PDU_t *sbcap_gen_error_ind(void *ctx, SBcAP_Cause_t cause, SBcAP_SBC_AP_PDU_t *rx_pdu);
|
||||||
|
|
||||||
|
|
||||||
|
void cci_from_sbcap_bcast_cell_id(struct cbc_cell_id *cci, const SBcAP_CellId_Broadcast_List_Item_t *it);
|
||||||
|
|
|
@ -31,6 +31,8 @@ enum smscb_fsm_event {
|
||||||
/* SBc-AP peer confirms delete */
|
/* SBc-AP peer confirms delete */
|
||||||
SMSCB_E_SBCAP_DELETE_ACK,
|
SMSCB_E_SBCAP_DELETE_ACK,
|
||||||
SMSCB_E_SBCAP_DELETE_NACK,
|
SMSCB_E_SBCAP_DELETE_NACK,
|
||||||
|
/* SBc-AP peer sends Write Replace Warning Indication to us */
|
||||||
|
SMSCB_E_SBCAP_WRITE_IND,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum smscb_fsm_state {
|
enum smscb_fsm_state {
|
||||||
|
|
|
@ -61,6 +61,10 @@ const char *cbc_cell_id2str(const struct cbc_cell_id *cid)
|
||||||
case CBC_CELL_ID_CI:
|
case CBC_CELL_ID_CI:
|
||||||
snprintf(buf, sizeof(buf), "CI %u", cid->u.ci);
|
snprintf(buf, sizeof(buf), "CI %u", cid->u.ci);
|
||||||
break;
|
break;
|
||||||
|
case CBC_CELL_ID_ECGI:
|
||||||
|
snprintf(buf, sizeof(buf), "ECGI %s-%05X-%02X", osmo_plmn_name(&cid->u.ecgi.plmn),
|
||||||
|
cid->u.ecgi.eci >> 8, cid->u.ecgi.eci & 0xff);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(buf, sizeof(buf), "<invalid>");
|
snprintf(buf, sizeof(buf), "<invalid>");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -333,6 +333,8 @@ int cbc_sbcap_link_rx_cb(struct cbc_sbcap_link *link, SBcAP_SBC_AP_PDU_t *pdu)
|
||||||
switch (pdu->present) {
|
switch (pdu->present) {
|
||||||
case SBcAP_SBC_AP_PDU_PR_initiatingMessage:
|
case SBcAP_SBC_AP_PDU_PR_initiatingMessage:
|
||||||
switch (pdu->choice.initiatingMessage.procedureCode) {
|
switch (pdu->choice.initiatingMessage.procedureCode) {
|
||||||
|
case SBcAP_ProcedureId_Write_Replace_Warning_Indication:
|
||||||
|
return osmo_fsm_inst_dispatch(mp->fi, SMSCB_E_SBCAP_WRITE_IND, pdu);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,6 +225,14 @@ SBcAP_SBC_AP_PDU_t *sbcap_gen_write_replace_warning_req(void *ctx, const struct
|
||||||
ASN_SEQUENCE_ADD(as_pdu, ie);
|
ASN_SEQUENCE_ADD(as_pdu, ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send Write-Replace-Warning-Indication
|
||||||
|
* 3GPP TS 36.413 4.3.4.3.5, 3GPP TS 23.041 9.3.39
|
||||||
|
* static const long asn_VAL_14_SBcAP_id_Send_Write_Replace_Warning_Indication = 24; */
|
||||||
|
ie = sbcap_alloc_Write_Replace_Warning_Request_IE(24, SBcAP_Criticality_ignore,
|
||||||
|
SBcAP_Write_Replace_Warning_Request_IEs__value_PR_Send_Write_Replace_Warning_Indication);
|
||||||
|
ie->value.choice.Send_Write_Replace_Warning_Indication = SBcAP_Send_Write_Replace_Warning_Indication_true;
|
||||||
|
ASN_SEQUENCE_ADD(as_pdu, ie);
|
||||||
|
|
||||||
return pdu;
|
return pdu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,3 +344,15 @@ SBcAP_SBC_AP_PDU_t *sbcap_gen_error_ind(void *ctx, SBcAP_Cause_t cause, SBcAP_SB
|
||||||
}
|
}
|
||||||
return pdu;
|
return pdu;
|
||||||
}
|
}
|
||||||
|
static void cci_from_sbcap_ecgi(struct cbc_cell_id *cci, const SBcAP_EUTRAN_CGI_t *eCGI)
|
||||||
|
{
|
||||||
|
cci->id_discr = CBC_CELL_ID_ECGI;
|
||||||
|
cci->u.ecgi.eci = (osmo_load32be(&eCGI->cell_ID.buf[0]) >> 4);
|
||||||
|
osmo_plmn_from_bcd(eCGI->pLMNidentity.buf, &cci->u.ecgi.plmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill a cbc_cell_id from a SBcAP_CellId_Broadcast_List_Item */
|
||||||
|
void cci_from_sbcap_bcast_cell_id(struct cbc_cell_id *cci, const SBcAP_CellId_Broadcast_List_Item_t *it)
|
||||||
|
{
|
||||||
|
cci_from_sbcap_ecgi(cci, &it->eCGI);
|
||||||
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ const struct value_string smscb_fsm_event_names[] = {
|
||||||
{ SMSCB_E_SBCAP_WRITE_NACK, "SBcAP_WRITE_NACK" },
|
{ SMSCB_E_SBCAP_WRITE_NACK, "SBcAP_WRITE_NACK" },
|
||||||
{ SMSCB_E_SBCAP_DELETE_ACK, "SBcAP_DELETE_ACK" },
|
{ SMSCB_E_SBCAP_DELETE_ACK, "SBcAP_DELETE_ACK" },
|
||||||
{ SMSCB_E_SBCAP_DELETE_NACK, "SBcAP_DELETE_NACK" },
|
{ SMSCB_E_SBCAP_DELETE_NACK, "SBcAP_DELETE_NACK" },
|
||||||
|
{ SMSCB_E_SBCAP_WRITE_IND, "SBcAP_WRITE_IND" },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,6 +283,37 @@ static void cbsp_append_cell_list(struct osmo_cbsp_cell_list *out, void *ctx,
|
||||||
out->id_discr = cell_id_from_ccid_discr(id_discr);
|
out->id_discr = cell_id_from_ccid_discr(id_discr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* append SBcAP cells to msg_peer compl list */
|
||||||
|
void msg_peer_append_compl_sbcap_bcast_area_list(struct cbc_message_peer *mp,
|
||||||
|
const SBcAP_Broadcast_Scheduled_Area_List_t *bcast)
|
||||||
|
{
|
||||||
|
SBcAP_CellId_Broadcast_List_t *cell_id_bscat = bcast->cellId_Broadcast_List;
|
||||||
|
A_SEQUENCE_OF(struct SBcAP_CellId_Broadcast_List_Item) *as_cell_id_bcast;
|
||||||
|
SBcAP_CellId_Broadcast_List_Item_t *it;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!cell_id_bscat)
|
||||||
|
return;
|
||||||
|
|
||||||
|
as_cell_id_bcast = (void *) &cell_id_bscat->list;
|
||||||
|
for (i = 0; i < as_cell_id_bcast->count; i++) {
|
||||||
|
it = (SBcAP_CellId_Broadcast_List_Item_t *)(as_cell_id_bcast->array[i]);
|
||||||
|
OSMO_ASSERT(it);
|
||||||
|
struct cbc_cell_id *cci = NULL; // FIXME: lookup
|
||||||
|
if (!cci) {
|
||||||
|
cci = talloc_zero(mp, struct cbc_cell_id);
|
||||||
|
if (!cci)
|
||||||
|
return;
|
||||||
|
llist_add_tail(&cci->list, &mp->num_compl_list);
|
||||||
|
}
|
||||||
|
cci_from_sbcap_bcast_cell_id(cci, it);
|
||||||
|
LOGPFSML(mp->fi, LOGL_DEBUG, "Appending CellId %s to Broadcast Completed list\n",
|
||||||
|
cbc_cell_id2str(cci));
|
||||||
|
cci->num_compl.num_compl += 1;
|
||||||
|
cci->num_compl.num_bcast_info += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* actual FSM
|
* actual FSM
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -532,6 +564,8 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
|
||||||
struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv;
|
struct cbc_message_peer *mp = (struct cbc_message_peer *) fi->priv;
|
||||||
struct osmo_cbsp_decoded *cbsp;
|
struct osmo_cbsp_decoded *cbsp;
|
||||||
SBcAP_SBC_AP_PDU_t *sbcap;
|
SBcAP_SBC_AP_PDU_t *sbcap;
|
||||||
|
A_SEQUENCE_OF(void) *as_pdu;
|
||||||
|
SBcAP_Write_Replace_Warning_Indication_IEs_t *ie;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SMSCB_E_DELETE: /* send KILL to BSC */
|
case SMSCB_E_DELETE: /* send KILL to BSC */
|
||||||
|
@ -575,6 +609,18 @@ static void smscb_p_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void
|
||||||
}
|
}
|
||||||
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK);
|
osmo_fsm_inst_state_chg(fi, SMSCB_S_WAIT_DELETE_ACK, 10, T_WAIT_DELETE_ACK);
|
||||||
break;
|
break;
|
||||||
|
case SMSCB_E_SBCAP_WRITE_IND:
|
||||||
|
sbcap = (SBcAP_SBC_AP_PDU_t *)data;
|
||||||
|
OSMO_ASSERT(sbcap->present == SBcAP_SBC_AP_PDU_PR_initiatingMessage);
|
||||||
|
OSMO_ASSERT(sbcap->choice.initiatingMessage.procedureCode == SBcAP_ProcedureId_Write_Replace_Warning_Indication);
|
||||||
|
as_pdu = (void *)&sbcap->choice.initiatingMessage.value.choice.Write_Replace_Warning_Indication.protocolIEs.list;
|
||||||
|
/* static const long asn_VAL_36_SBcAP_id_Broadcast_Scheduled_Area_List = 23; */
|
||||||
|
ie = sbcap_as_find_ie(as_pdu, 23);
|
||||||
|
if (!ie)
|
||||||
|
return; /* IE is optional */
|
||||||
|
OSMO_ASSERT(ie->value.present == SBcAP_Write_Replace_Warning_Indication_IEs__value_PR_Broadcast_Scheduled_Area_List);
|
||||||
|
msg_peer_append_compl_sbcap_bcast_area_list(mp, &ie->value.choice.Broadcast_Scheduled_Area_List);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
OSMO_ASSERT(0);
|
OSMO_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
@ -647,7 +693,8 @@ struct osmo_fsm smscb_p_fsm = {
|
||||||
.name = "SMSCB-PEER",
|
.name = "SMSCB-PEER",
|
||||||
.states = smscb_p_fsm_states,
|
.states = smscb_p_fsm_states,
|
||||||
.num_states = ARRAY_SIZE(smscb_p_fsm_states),
|
.num_states = ARRAY_SIZE(smscb_p_fsm_states),
|
||||||
.allstate_event_mask = S(SMSCB_E_DELETE),
|
.allstate_event_mask = S(SMSCB_E_DELETE) |
|
||||||
|
S(SMSCB_E_SBCAP_WRITE_IND),
|
||||||
.allstate_action = smscb_p_fsm_allstate,
|
.allstate_action = smscb_p_fsm_allstate,
|
||||||
.timer_cb = smscb_p_fsm_timer_cb,
|
.timer_cb = smscb_p_fsm_timer_cb,
|
||||||
.log_subsys = DCBSP,
|
.log_subsys = DCBSP,
|
||||||
|
|
Loading…
Reference in New Issue