📄 mfw_sms.c
字号:
error = ffs_fwrite(fname, data, len);
if (error == EFFS_OK)
{
PUSH_DET_TRACE(("MMS_SI_ind():write FFS file \"%s\" ok!", fname));
return 1;
}
else
{
PUSH_DET_TRACE(("MMS_SI_ind():P0, fail to write FFS files!"));
}
break;
}
}
PUSH_DET_TRACE(("MMS_SI_ind():P1, fail to write FFS files!"));
#endif
return 0;
}
/****
* Get the existing merge buffer for SMS concatenation
*/
T_PUSH_MERGE *push_mbuf_getSlot(USHORT ref_num)
{
UBYTE i;
PUSH_DET_TRACE(("push_mbuf_getSlot()"));
for (i = 0; i < MAX_MMS_SI; i ++)
{
if (pMergeBuf[i].ref_num == ref_num && pMergeBuf[i].fuse)
{
PUSH_DET_TRACE(("push_mbuf_getSlot():find a existing slot, idx=%d", i));
return(&pMergeBuf[i]);
}
}
return NULL;
}
/****
* Allocate and initialize a new merge buffer according to the specified
* concatenated SMS reference number and segments number
*/
T_PUSH_MERGE *push_mbuf_getNewSlot(USHORT ref_num, UBYTE max_num)
{
UBYTE i;
PUSH_DET_TRACE(("push_mbuf_getNewSlot():ref_num=%d, max_num=%d", ref_num, max_num));
for (i = 0; i < MAX_MMS_SI; i ++)
{
if (pMergeBuf[i].fuse == 0)
{
pMergeBuf[i].fuse = 1;
pMergeBuf[i].next_seg = 1;
pMergeBuf[i].ref_num = ref_num;
pMergeBuf[i].len = 0;
if (max_num > MAX_SEG_NUM)
max_num = MAX_SEG_NUM;
pMergeBuf[i].left = max_num;
pMergeBuf[i].total = max_num;
MALLOC(pMergeBuf[i].data, MAX_SM_LEN * max_num);
PUSH_DET_TRACE(("push_mbuf_getNewSlot():a buffer allocated, idx=%d", i));
return(&pMergeBuf[i]);
}
}
PUSH_DET_TRACE(("push_mbuf_getNewSlot(): failed!"));
return NULL;
}
/****
* Add a piece of SMS segment to the merge buffer specified by the SMS
* reference number
*/
T_PUSH_MERGE *push_mbuf_addData(USHORT ref_num, UBYTE max_num, UBYTE len, UBYTE *data)
{
T_PUSH_MERGE *merge_slot;
PUSH_DET_TRACE(("push_mbuf_addData():ref_num=%d,max_num=%d,len=%d", ref_num, max_num, len));
merge_slot = push_mbuf_getSlot(ref_num);
if (merge_slot == NULL)
merge_slot = push_mbuf_getNewSlot(ref_num, max_num);
if (merge_slot == NULL)
{
PUSH_DET_TRACE(("push_mbuf_addData():failed, can get buffer!"));
return NULL;
}
memcpy(merge_slot->data + merge_slot->len, data, len);
merge_slot->len += len;
merge_slot->next_seg ++;
merge_slot->left --;
PUSH_DET_TRACE(("push_mbuf_addData():after add a segment,next_seg=%d", merge_slot->next_seg));
return merge_slot;
}
/****
* Empty a merge buffer specified by a pointer or a index,
* the pointer is prefered
*/
void push_mbuf_clear(T_PUSH_MERGE *mergeBuf_slot, UBYTE startup, UBYTE idx)
{
T_PUSH_MERGE *bufPtr;
PUSH_DET_TRACE(("push_mbuf_clear():bufPtr=%d, startup=%d, idx=%d", (UINT32)mergeBuf_slot, startup, idx));
if (mergeBuf_slot != NULL)
bufPtr = mergeBuf_slot;
else
{
if (idx >= MAX_MMS_SI)
return;
else
bufPtr = &pMergeBuf[idx];
}
bufPtr->fuse = 0;
bufPtr->next_seg = 0;
bufPtr->total = 0;
bufPtr->left = 0;
bufPtr->ref_num = 0xFFFF;
bufPtr->len = 0;
if (!startup &&bufPtr->data != NULL)
{
PUSH_DET_TRACE(("push_mbuf_clear():free the merge data block!"));
MFREE(bufPtr->data);
}
bufPtr->data = NULL;
}
/****
* Get a existing segment buffer for uncontinuous SMS
*/
T_PUSH_SEGBUF *push_sbuf_getSlot(USHORT ref_num)
{
UBYTE i;
PUSH_DET_TRACE(("push_sbuf_getSlot():ref_num=%d", ref_num));
for (i = 0; i < MAX_MMS_SI; i ++)
{
if (pSegBuf[i].ref_num == ref_num && pSegBuf[i].fuse)
{
PUSH_DET_TRACE(("push_sbuf_getSlot():existing!"));
return(&pSegBuf[i]);
}
}
return NULL;
}
/****
* Allocate and initialize a segment buffer accoring to the concatenation
* SMS reference number.
*/
T_PUSH_SEGBUF *push_sbuf_getNewSlot(USHORT ref_num)
{
UBYTE i;
PUSH_DET_TRACE(("push_sbuf_getNewSlot():ref_num=%d", ref_num));
for (i = 0; i < MAX_MMS_SI; i ++)
{
if (pSegBuf[i].fuse == 0)
{
memset((void*)pSegBuf[i].mem_idx, 0xFF, MAX_SEG_NUM);
//memset((void*)pSegbuf[i].seg_seq, 0xFF, MAX_SEG_NUM);
pSegBuf[i].idx_num = 0;
pSegBuf[i].fuse = 1;
pSegBuf[i].ref_num = ref_num;
pSegBuf[i].list = NULL;
PUSH_DET_TRACE(("push_sbuf_getSlot():allocate a new buffer,idx=%d", i));
return(&pSegBuf[i]);
}
}
return NULL;
}
/****
* Add uncontinuous segment data to segment buf
*/
UBYTE push_sbuf_addSeg(USHORT ref_num, UBYTE seq_num, UBYTE mem_idx, UBYTE len, UBYTE *data)
{
UBYTE i;
T_PUSH_SEGBUF *segbuf_slot;
T_PUSH_SEG *seg_elem, *list, *pre;
PUSH_DET_TRACE(("push_sbuf_addSeg():ref_num=%d,seq_num=%d,mem_idx=%d,len=%d,data=%d",ref_num, seq_num, mem_idx, len, (UINT32)data));
if (seq_num > MAX_SEG_NUM)
return 1;
segbuf_slot = push_sbuf_getSlot(ref_num);
if (segbuf_slot == NULL)
{
segbuf_slot = push_sbuf_getNewSlot(ref_num);
}
if (segbuf_slot != NULL)
{
for (i = 0; i < segbuf_slot->idx_num; i ++)
{
if (segbuf_slot->mem_idx[i] == mem_idx)
break;
}
if (i >= segbuf_slot->idx_num)
{
segbuf_slot->mem_idx[segbuf_slot->idx_num] = mem_idx;
segbuf_slot->idx_num ++;
}
if (data != NULL) //need add data block
{
MALLOC(seg_elem, sizeof(T_PUSH_SEG));
seg_elem->seq = seq_num;
seg_elem->idx = mem_idx;
seg_elem->len = len;
seg_elem->data = NULL;
seg_elem->next = NULL;
MALLOC(seg_elem->data, seg_elem->len);
memcpy(seg_elem->data, data, seg_elem->len);
/* insert to seg chain */
list = segbuf_slot->list;
pre = NULL;
while (list)
{
if (seg_elem->seq >= list->seq)
{
pre = list;
list = list->next;
}
else
break;
}
if (pre == NULL) // the first element of the list
{
segbuf_slot->list = seg_elem;
seg_elem->next = list;
}
else
{
if (pre->seq == seg_elem->seq)
return 1; // don't save the same seg twice
else
{
seg_elem->next = list;
pre->next = seg_elem;
}
}
return 1;
}
return 1;
}
return 0;
}
/****
* Get a piece of SMS segment specified by SMS reference number and
* sequence number from the segment buffer
*/
T_PUSH_SEG *push_sbuf_removeSeg(USHORT ref_num, UBYTE seq_num)
{
T_PUSH_SEGBUF *segbuf_slot;
T_PUSH_SEG *pre = NULL, *cur;
PUSH_DET_TRACE(("push_sbuf_removeSeg():ref_num=%d, seq_num=%d", ref_num, seq_num));
segbuf_slot = push_sbuf_getSlot(ref_num);
if (segbuf_slot == NULL)
return NULL;
cur = segbuf_slot->list;
if (cur == NULL)
return NULL;
while (cur != NULL)
{
if (cur->seq == seq_num)
break;
pre = cur;
cur = cur->next;
}
if (pre == NULL)
{
segbuf_slot->list = cur->next;
}
else
{
if (cur != NULL)
pre->next = cur->next;
}
return(cur);
}
/****
* Empty a seg buffer specified by a pointer or a index, the pointer
* is prefered
*/
void push_sbuf_clear(T_PUSH_SEGBUF *segbuf_slot, UBYTE startup, UBYTE idx)
{
UBYTE i;
T_PUSH_SEG *list, *del;
T_PUSH_SEGBUF *bufPtr;
PUSH_DET_TRACE(("push_sbuf_clear():segbuf=%d, startup=%d, idx=%d", (UINT32)segbuf_slot, startup, idx));
if (segbuf_slot != NULL)
bufPtr = segbuf_slot;
else
{
if (idx >= MAX_MMS_SI)
return;
else
bufPtr = &pSegBuf[idx];
}
bufPtr->fuse = 0;
bufPtr->ref_num = 0xFFFF;
if (!startup)
{
list = bufPtr->list;
while (list != NULL)
{
del = list;
list = del->next;
if (del->data)
MFREE(del->data);
MFREE(del);
}
}
bufPtr->list = NULL;
/* delete all SMS of the same reference number */
if (!startup)
push_delLst_add(bufPtr->mem_idx, bufPtr->idx_num);
memset(bufPtr->mem_idx, 0xFF, MAX_SEG_NUM);
bufPtr->idx_num = 0;
}
/****
* Initialize the data for WAP PUSH SMS concatenation
*/
void push_init()
{
UBYTE i;
PUSH_DET_TRACE(("push_init()"));
for (i = 0; i < MAX_MMS_SI; i ++)
{
push_sbuf_clear(NULL, 1, i);
push_mbuf_clear(NULL, 1, i);
}
/* clear delete list */
memset((char*)pushDelList.mem_idx, 0xff, sizeof(pushDelList.mem_idx));
pushDelList.rd = pushDelList.wr = 0;
pushDelList.t_post = NULL;
}
/****
* Merge concatenation SMS to a push message, return status code when everytime
* invoked, the returned idx is available if the returned status code is complete
*
* RETURN 0 continue, 1 completed, 2 error.
*/
UBYTE push_merge_sms(T_ACI_CMGL_SM *sm, T_PUSH_MERGE **idx)
{
UBYTE i, error;
UBYTE max_num, seq_num;
UBYTE *add_data, add_data_len;
UBYTE except_num;
USHORT ref_num;
T_PUSH_MERGE *merge_slot;
T_PUSH_SEGBUF *segbuf_slot;
T_PUSH_SEG *seg_slot;
/* parsing user data header */
if (sm->udh.data[0] EQ SMS_IEI_CONC_8BIT) /* 8-bit reference number */
{
ref_num = sm->udh.data[2];
max_num = sm->udh.data[3];
seq_num = sm->udh.data[4];
}
else if (sm->udh.data[0] EQ SMS_IEI_CONC_16BIT) /* 16-bit reference number */
{
ref_num = (sm->udh.data[2] & 0x00FF) << 8; /* MSB */
ref_num += sm->udh.data[3]; /* LSB */
max_num = sm->udh.data[4];
seq_num = sm->udh.data[5];
}
else
return MERGE_STA_ERROR;
PUSH_DET_TRACE(("push_merge_sms():ref_num=%d, max_num=%d, seq_num=%d", ref_num, max_num, seq_num));
merge_slot = push_mbuf_getSlot(ref_num);
if (merge_slot == NULL)
except_num = 1;
else
except_num = merge_slot->next_seg;
PUSH_DET_TRACE(("push_merge_sms():except segment=%d",except_num));
if (seq_num == 0 || seq_num > max_num || seq_num < except_num)
return MERGE_STA_ERROR;
if (seq_num > MAX_SEG_NUM)
{
push_delLst_add(&seq_num, 1);
return MERGE_STA_CONTINUE;
}
/* only add memory index info */
push_sbuf_addSeg( ref_num, seq_num, sm->msg_ref, 0, NULL);
add_data = sm->data.data;
add_data_len = sm->data.len;
if (seq_num > except_num)
{
error = push_sbuf_addSeg(ref_num, seq_num, sm->msg_ref, add_data_len, add_data);
if (error == 0)
{
PUSH_DET_TRACE(("push_merge_sms():error to add seg %d", seq_num));
return MERGE_STA_ERROR;
}
return MERGE_STA_CONTINUE;
}
else
{
while (1)
{
merge_slot = push_mbuf_addData(ref_num, max_num, add_data_len, add_data);
if (sm->data.data != add_data)
{
MFREE(add_data);
}
if (merge_slot == NULL)
{
PUSH_DET_TRACE(("push_merge_sms(): buffer full!"));
return MERGE_STA_ERROR;
}
if (merge_slot->left == 0)
{
PUSH_DET_TRACE(("push_merge_sms(): complete!"));
*idx = merge_slot;
return MERGE_STA_COMPLETE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -