/*封信,准备发送*/
MAILBOX_EXTERN int mailbox_sealup_buff(struct mb_buff * mb_buf , unsigned int usr_size)
{

    struct mb_mail        mail = {0};
    struct mb_queue      *m_queue   = MAILBOX_NULL;
    unsigned int         time_stamp;
    unsigned long         mail_addr;

    m_queue = &mb_buf->mail_queue;

    /*判断是否超过单次发送最大大小*/
    if (usr_size > (mb_buf->config->single_max - sizeof(struct mb_mail) )){
        return (int) mailbox_logerro_p2(MAILBOX_ERR_GUT_WRITE_EXCEED_MAX_SIZE,
            usr_size ,mb_buf->mailcode);
    } else {
    }

    time_stamp = (unsigned int)mailbox_get_timestamp();
    /*填充消息头*/
    mail.ulPartition   =  MAILBOX_MSGHEAD_NUMBER;
    mail.ulWriteSlice  =  time_stamp;
    mail.ulReadSlice   =  0;
    mail.ulPriority    =  0;/*此属性和OM核对已废弃,不使用*/
    mail.ulSeqNum      =  mb_buf->seq_num;
    mail.ulMsgLength   =  usr_size ;
    mail.ulMailCode    =  mb_buf->mailcode;

    if (MAILBOX_SEQNUM_START == mb_buf->seq_num) {
        (void)mailbox_logerro_p1(MAILBOX_INFO_SEND_FIRST_MAIL, mb_buf->mailcode);
    }

    mb_buf->seq_num++;

    /*向邮箱队列中写入邮件头,并更新队列状态记录临时结构体*/
    mail_addr = m_queue->front;
    (void)mailbox_queue_write(m_queue, (char*)(&mail), sizeof(struct mb_mail));

    /*更新邮箱环形缓存信息*/
    m_queue->front = mailbox_align_size(mb_buf->usr_queue.front, MAILBOX_ALIGN);

    (void)mailbox_flush_buff(mb_buf); /*把邮箱通道操作符的信息写回邮箱头。*/

#ifdef MAILBOX_OPEN_MNTN
    mailbox_record_send(&(mb_buf->mntn), mb_buf->mailcode, time_stamp, mail_addr);
#endif

    /*准备下一封邮件写入*/
    return mailbox_init_usr_queue(mb_buf);
}
/*****************************************************************************
 函 数 名  : mailbox_read_mail
 接口类型  : 对内接口
 功能描述  : 读取并处理一封邮箱的正文数据内容,接受邮箱数据的数据层入口,
                并且调用上层注册的邮件数据处理回调函数
 输入参数  : mb_buff*       mbuff  - 邮箱通道操作符

 输出参数  : 无
 返 回 值  : 读取的邮件数据长度,包括邮件头,返回0表示失败。
 调用函数  :
 被调函数  :

 修改历史      :
  1.日    期   : 2012年9月24日
    作    者   : 莫南 00176101
    修改内容   : 新生成函数

*****************************************************************************/
MAILBOX_LOCAL long mailbox_read_mail(struct mb_buff *mbuff)
{
    struct mb_mail        mail;
    struct mb_cb         *read_cb = MAILBOX_NULL;/*此邮箱通道的功能回调函数队列*/
    struct mb_queue       tmp_queue;
    struct mb_queue      *usr_queue   = MAILBOX_NULL;
    struct mb_queue      *m_queue   = MAILBOX_NULL;
    unsigned long         use_id;
    unsigned long         slice_start;
    unsigned long         to_bottom;
    void                 *usr_handle;
    void                 *usr_data;
    void (*usr_func)(void *mbuf, void *handle, void *data);

    m_queue = &(mbuff->mail_queue);
    usr_queue = &(mbuff->usr_queue);
    mailbox_memcpy((void *) usr_queue, (const void *) m_queue, sizeof(struct mb_queue));

    /*保存临时队列状态,交换读写指针。*/
    tmp_queue.base   = usr_queue->base;
    tmp_queue.length = usr_queue->length;
    tmp_queue.front  = usr_queue->rear;
    tmp_queue.rear   = usr_queue->front;

    /*读取邮件的头信息*/
    mailbox_queue_read(usr_queue, (char*)&mail, sizeof(struct mb_mail));

    /*1.检查邮件头,判断读到的消息是否存在异常,包括SN号是否连续、消息滞留时间是否过长。
      2.填充信息读取时间*/
    mailbox_check_mail(mbuff, &mail, m_queue->rear);

    /*把读取时间写回邮箱队列*/
    mailbox_queue_write(&tmp_queue, (char*)&mail, sizeof(struct mb_mail));
    use_id = mailbox_get_use_id(mail.ulMailCode);

    /*检查Use ID的有效性*/
    if (use_id >= mailbox_get_use_id(mbuff->config->butt_id)) {
        mailbox_logerro_p1(MAILBOX_ERR_GUT_INVALID_USER_ID, mail.ulMailCode);
        goto EXIT;
    }

    read_cb = &mbuff->read_cb[use_id];
    mailbox_mutex_lock(&mbuff->mutex);
    usr_handle = read_cb->handle;
    usr_data = read_cb->data;
    usr_func = read_cb->func;
    mailbox_mutex_unlock(&mbuff->mutex);
    if (MAILBOX_NULL != usr_func) {
        usr_queue->size = mail.ulMsgLength;
        slice_start = mailbox_get_timestamp();
        usr_func(mbuff, usr_handle , usr_data);

        /*记录可维可测信息*/
#ifdef MAILBOX_OPEN_MNTN
         mailbox_record_receive(&mbuff->mntn, mbuff->channel_id, slice_start);
#endif
    } else {
        mailbox_logerro_p1(MAILBOX_ERR_GUT_READ_CALLBACK_NOT_FIND, mail.ulMailCode);
    }

EXIT:

    /*不管用户有没有用回调读数据,读了多少数据,邮箱队列的读指针都需要按实际
      大小偏移,以保证后面邮件读取的正确性。*/
    to_bottom  = (m_queue->base + m_queue->length) - m_queue->rear;
    if (to_bottom > (mail.ulMsgLength + sizeof(struct mb_mail))) {
        m_queue->rear += (mail.ulMsgLength + sizeof(struct mb_mail));
    } else {
        m_queue->rear = m_queue->base + ((mail.ulMsgLength +
            sizeof(struct mb_mail)) - to_bottom);
    }

    /*读保证指针4字节对齐*/
    m_queue->rear = mailbox_align_size(m_queue->rear, MAILBOX_ALIGN);

    return (mailbox_align_size(mail.ulMsgLength, MAILBOX_ALIGN)
            + sizeof(struct mb_mail));

}