rohc team mailing list archive
-
rohc team
-
Mailing list archive
-
Message #00466
[Question #191211]: modify the feedback system in O-mode
New question #191211 on rohc:
https://answers.launchpad.net/rohc/+question/191211
hello,
I try to modify the feedback system. I mainly change three files : rohc_decomp.h/c and d_generic.c. I set the situation "ROHC_ERROR" to "ROHC_ERROR_CRC", ie, if decompression is failure, it always returns ROHC_ERROR_CRC. I change feedback from piggybacking to interspersing. So I add ROHC_ERROR_FEEDBACK when feedback is decompressed unsuccessfully.
Here are the main code:
first, in file rohc_decomp.h
add #define N and #define K
in struct d_context add:
/// create a window for feedback interval in NO CONTEXT state
struct c_wlsb *curvalnc;
/// create a window for feedback interval in STATIC CONTEXT state
struct c_wlsb *curvalsc;
/// create a window for feedback interval in FULL CONTEXT state
struct c_wlsb *curvalfc;
/// create a window for feedback interval in case of ROHC_ERROR_NO_CONTEXT
struct c_wlsb *curvalenc;
/// create a window for feedback interval in STATIC CONTEXT state
struct c_wlsb *curvalsc0;
///The number of received packets in NO CONTEXT state
int num_recv_nc;
///The number of received packets in STATIC CONTEXT state
int num_recv_sc;
///The number of received packets in FULL CONTEXT state
int num_recv_fc;
///The number of received packets in case of ROHC_ERROR_CONTEXT
int num_recv_enc;
///The number of received packets in STATIC CONTEXT state(type0,1)
int num_recv_sc0;
second, in file rohc_decomp.c
in function rohc_decompress():
switch(ret)
{
case ROHC_ERROR_PACKET_FAILED:
break;
//BY SQ
case ROHC_ERROR_FEEDBACK:
break;
case ROHC_ERROR_CRC:
decomp->statistics.packets_failed_crc++;
switch(ddata.active->state)
{
case NO_CONTEXT:
ddata.active->num_recv_nc++;
rohc_debugf(2, "num_recv_nc = %d\n", ddata.active->num_recv_nc);
c_add_wlsb(ddata.active->curvalnc, 0, 0, 1);
if(ddata.active->num_recv_nc >= N && c_sum_wlsb(ddata.active->curvalnc)>= K &&
c_sum_wlsb(ddata.active->curvalnc) <= N)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(ddata.active->curvalnc, 0, 0, 0);
ddata.active->curvalnc->next--;
ddata.active->curvalnc->window[ddata.active->curvalnc->next].used = ROHC_FALSE;
ddata.active->curvalnc->next++;
}
ddata.active->curvalnc->next = 0;
ddata.active->curvalnc->oldest = 0;
ddata.active->num_recv_nc = 0;
rohc_debugf(2, "feedback curr %d\n", c_sum_wlsb(ddata.active->curvalnc));
rohc_debugf(2, "feedback max %d no context\n", N);
d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
ddata.addcidUsed, ddata.largecidUsed,
ddata.active->mode, ddata.active);
}
break;
case STATIC_CONTEXT:
ddata.active->num_recv_sc++;
rohc_debugf(2, "num_recv_sc = %d\n", ddata.active->num_recv_sc);
c_add_wlsb(ddata.active->curvalsc, 0, 0, 1);
if(ddata.active->num_recv_sc >= N && c_sum_wlsb(ddata.active->curvalsc)>= K &&
c_sum_wlsb(ddata.active->curvalsc) <= N)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(ddata.active->curvalsc, 0, 0, 0);
ddata.active->curvalsc->next--;
ddata.active->curvalsc->window[ddata.active->curvalsc->next].used = ROHC_FALSE;
ddata.active->curvalsc->next++;
}
ddata.active->curvalsc->next = 0;
ddata.active->curvalsc->oldest = 0;
ddata.active->num_recv_sc = 0;
rohc_debugf(2, "feedback curr %d\n", c_sum_wlsb(ddata.active->curvalsc));
rohc_debugf(2, "feedback max %d static context %d\n", N);
d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
ddata.addcidUsed, ddata.largecidUsed,
ddata.active->mode, ddata.active);
}
break;
case FULL_CONTEXT:
ddata.active->num_recv_fc++;
rohc_debugf(2, "num_recv_fc = %d\n", ddata.active->num_recv_fc);
c_add_wlsb(ddata.active->curvalfc, 0, 0, 1);
if(ddata.active->num_recv_fc >= N && c_sum_wlsb(ddata.active->curvalfc)>= K &&
c_sum_wlsb(ddata.active->curvalfc) <= N)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(ddata.active->curvalfc, 0, 0, 0);
ddata.active->curvalfc->next--;
ddata.active->curvalfc->window[ddata.active->curvalfc->next].used = ROHC_FALSE;
ddata.active->curvalfc->next++;
}
ddata.active->curvalfc->next = 0;
ddata.active->curvalfc->oldest = 0;
ddata.active->num_recv_fc = 0;
rohc_debugf(2, "feedback curr %d\n", c_sum_wlsb(ddata.active->curvalfc));
rohc_debugf(2, "feedback max %d full context\n", N);
d_operation_mode_feedback(decomp, ROHC_ERROR_CRC, ddata.cid,
ddata.addcidUsed, ddata.largecidUsed,
ddata.active->mode, ddata.active);
}
break;
}
case ROHC_ERROR_NO_CONTEXT:
decomp->statistics.packets_failed_no_context++;
ddata.active->num_recv_enc++;
rohc_debugf(2, "num_recv_enc = %d\n", ddata.active->num_recv_enc);
c_add_wlsb(ddata.active->curvalenc, 0, 0, 1);
if(ddata.active->num_recv_enc >= N && c_sum_wlsb(ddata.active->curvalenc)>= K &&
c_sum_wlsb(ddata.active->curvalenc) <= N)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(ddata.active->curvalenc, 0, 0, 0);
ddata.active->curvalenc->next--;
ddata.active->curvalenc->window[ddata.active->curvalenc->next].used = ROHC_FALSE;
ddata.active->curvalenc->next++;
}
ddata.active->curvalenc->next = 0;
ddata.active->curvalenc->oldest = 0;
ddata.active->num_recv_enc = 0;
rohc_debugf(2, "feedback curr %d\n", c_sum_wlsb(ddata.active->curvalenc));
rohc_debugf(2, "feedback max %d error no context\n", N);
d_operation_mode_feedback(decomp, ROHC_ERROR_NO_CONTEXT, ddata.cid,
ddata.addcidUsed, ddata.largecidUsed,
O_MODE, NULL);
}
break;
case ROHC_ERROR_SC:
ddata.active->num_recv_sc0++;
rohc_debugf(2, "num_recv_sc0 = %d\n", ddata.active->num_recv_sc0);
c_add_wlsb(ddata.active->curvalsc0, 0, 0, 1);
if(ddata.active->num_recv_sc0 >= N && c_sum_wlsb(ddata.active->curvalsc0)>= K &&
c_sum_wlsb(ddata.active->curvalsc0) <= N)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(ddata.active->curvalsc0, 0, 0, 0);
ddata.active->curvalsc0->next--;
ddata.active->curvalsc0->window[ddata.active->curvalsc0->next].used = ROHC_FALSE;
ddata.active->curvalsc0->next++;
}
ddata.active->curvalsc0->next = 0;
ddata.active->curvalsc0->oldest = 0;
ddata.active->num_recv_sc0 = 0;
rohc_debugf(2, "feedback curr %d\n", c_sum_wlsb(ddata.active->curvalsc0));
rohc_debugf(2, "feedback max %d sc(recieve type1,0)\n", N);
d_operation_mode_feedback(decomp, ROHC_ERROR_NO_CONTEXT, ddata.cid,
ddata.addcidUsed, ddata.largecidUsed,
O_MODE, NULL);
}
break;
default: /* ROHC_OK_NO_DATA, ROHC_OK */
if(decomp->compressor != NULL && decomp->ack_sent < MAX_ACK)
{
/* switch active context to O-mode */
ddata.active->mode = O_MODE;
d_operation_mode_feedback(decomp, ROHC_OK, ddata.cid, ddata.addcidUsed,
ddata.largecidUsed, ddata.active->mode,
ddata.active);
decomp->ack_sent++;
rohc_debugf(2, "the number of transition ack is %d\n", decomp->ack_sent);
}
break;
}
in function d_optimistic_feedback():
switch(rohc_status)
{
case ROHC_OK:
/* create an ACK feedback */
rohc_debugf(1, "send an ACK feedback\n");
f_feedback2(ACKTYPE_ACK, context->mode, context->profile->get_sn(context), &sfeedback);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, WITH_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create an ACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* destroy the feedback */
zfree(feedback);
break;
case ROHC_ERROR_NO_CONTEXT:
/* create a STATIC NACK feedback */
rohc_debugf(1, "send a STATIC NACK feedback\n");
f_feedback2(ACKTYPE_STATIC_NACK, O_MODE, 0, &sfeedback);
f_add_option(&sfeedback, OPT_TYPE_SN_NOT_VALID, NULL);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, NO_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create a STATIC NACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* destroy the feedback */
zfree(feedback);
break;
case ROHC_ERROR_SC:
if(context->state != STATIC_CONTEXT)
{
return;
}
/* create a NACK feedback */
rohc_debugf(1, "send a NACK feedback\n");
f_feedback2(ACKTYPE_NACK, context->mode, context->profile->get_sn(context), &sfeedback);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, WITH_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create a NACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* destroy the feedback */
zfree(feedback);
break;
case ROHC_ERROR_CRC:
//context->num_sent_feedbacks++;
switch(context->state)
{
case NO_CONTEXT:
/* create a STATIC NACK feedback */
rohc_debugf(1, "send a STATIC NACK feedback\n");
f_feedback2(ACKTYPE_STATIC_NACK, context->mode, context->profile->get_sn(context), &sfeedback);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, WITH_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create a STATIC NACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* destroy the feedback */
zfree(feedback);
break;
case STATIC_CONTEXT:
/* create a STATIC NACK feedback*/
rohc_debugf(1, "send a STATIC NACK feedback\n");
f_feedback2(ACKTYPE_STATIC_NACK, context->mode, context->profile->get_sn(context), &sfeedback);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, WITH_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create a STATIC NACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* change state */
rohc_debugf(1, "change decompressor state from SC to NC");
context->state = NO_CONTEXT;
/* destroy the feedback */
zfree(feedback);
break;
case FULL_CONTEXT:
/* create a NACK feedback */
rohc_debugf(1, "send a NACK feedback\n");
f_feedback2(ACKTYPE_NACK, context->mode, context->profile->get_sn(context), &sfeedback);
feedback = f_wrap_feedback(&sfeedback, cid, largecidUsed, WITH_CRC, &feedbacksize);
if(feedback == NULL)
{
rohc_debugf(0, "failed to create a NACK feedback\n");
return;
}
/* send the feedback via the compressor associated
* with the decompressor */
context->num_sent_feedbacks++;
c_piggyback_feedback(decomp->compressor, feedback, feedbacksize);
/* change state */
rohc_debugf(1, "change decompressor state from FC to SC");
context->state = STATIC_CONTEXT;
/* destroy the feedback */
zfree(feedback);
break;
default:
rohc_debugf(0, "should not arrive: unknown state value (%d)\n",
context->state);
break;
}
break;
}
in function struct d_context * context_create():
context->num_recv_nc = 0;
context->num_recv_sc = 0;
context->num_recv_fc = 0;
context->num_recv_enc = 0;
context->num_recv_sc0 = 0;
context->curvalnc = c_create_wlsb(32, N, 0);
context->curvalsc = c_create_wlsb(32, N, 0);
context->curvalfc = c_create_wlsb(32, N, 0);
context->curvalenc = c_create_wlsb(32, N, 0);
context->curvalsc0 = c_create_wlsb(32, N, 0);
in function context_free():
c_destroy_wlsb(context->curvalnc);
c_destroy_wlsb(context->curvalsc);
c_destroy_wlsb(context->curvalfc);
c_destroy_wlsb(context->curvalenc);
c_destroy_wlsb(context->curvalsc0);
third, in file d_generic.c
in function decode_generic_decode_ir(), add code before context->state = FULL_CONTEXT:
//set wlsb window value to zero when change state
if(context->state == NO_CONTEXT)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(context->curvalnc, 0, 0, 0);
context->curvalnc->next--;
context->curvalnc->window[context->curvalnc->next].used = ROHC_FALSE;
context->curvalnc->next++;
}
context->curvalnc->next = 0;
context->curvalnc->oldest = 0;
context->num_recv_nc = 0;
}
else if(context->state == STATIC_CONTEXT)
{
int i;
//set wlsb window value to zero
for(i = 0; i < N; i++)
{
c_add_wlsb(context->curvalsc, 0, 0, 0);
context->curvalsc->next--;
context->curvalsc->window[context->curvalsc->next].used = ROHC_FALSE;
context->curvalsc->next++;
c_add_wlsb(context->curvalsc0, 0, 0, 0);
context->curvalsc0->next--;
context->curvalsc0->window[context->curvalsc0->next].used = ROHC_FALSE;
context->curvalsc0->next++;
}
context->curvalsc->next = 0;
context->curvalsc->oldest = 0;
context->num_recv_sc = 0;
context->curvalsc0->next = 0;
context->curvalsc0->oldest = 0;
context->num_recv_sc0 = 0;
}
in function decode_irdyn, add code after context->state = FULL_CONTEXT:
int i1;
//set wlsb window value to zero when change state
for(i1 = 0; i1 < N; i1++)
{
c_add_wlsb(context->curvalsc, 0, 0, 0);
context->curvalsc->next--;
context->curvalsc->window[context->curvalsc->next].used = ROHC_FALSE;
context->curvalsc->next++;
c_add_wlsb(context->curvalsc0, 0, 0, 0);
context->curvalsc0->next--;
context->curvalsc0->window[context->curvalsc0->next].used = ROHC_FALSE;
context->curvalsc0->next++;
}
context->curvalsc->next = 0;
context->curvalsc->oldest = 0;
context->num_recv_sc = 0;
context->curvalsc0->next = 0;
context->curvalsc0->oldest = 0;
context->num_recv_sc0 = 0;
in function decode_uor2(), add code after context->state = FULL_CONTEXT:
int i1;
//set wlsb window value to zero when change state
for(i1 = 0; i1 < N; i1++)
{
c_add_wlsb(context->curvalsc, 0, 0, 0);
context->curvalsc->next--;
context->curvalsc->window[context->curvalsc->next].used = ROHC_FALSE;
context->curvalsc->next++;
c_add_wlsb(context->curvalsc0, 0, 0, 0);
context->curvalsc0->next--;
context->curvalsc0->window[context->curvalsc0->next].used = ROHC_FALSE;
context->curvalsc0->next++;
}
context->curvalsc->next = 0;
context->curvalsc->oldest = 0;
context->num_recv_sc = 0;
context->curvalsc0->next = 0;
context->curvalsc0->oldest = 0;
context->num_recv_sc0 = 0;
in function d_generic_decode:
in switch(find_packet_type(decomp, context, packet, second_byte)): case PACKET_UO_0, case PACKET_UO_1, case PACKET_UO_1_ID, change "goto error" to "return ROHC_ERROR_SC".
I change the code in that way according to RFC 3095 5.3.2.2.3 and 5.4.2.2.
--
You received this question notification because you are a member of ROHC
Team, which is an answer contact for rohc.