⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mnotify.c

📁 彩信MMS的全部代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (C) Obigo AB, 2002-2005.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and Obigo AB, and may be 
 * used and copied only in accordance with the terms of the 
 * said agreement.
 *
 * Obigo AB assumes no responsibility or 
 * liability for any errors or inaccuracies in this software, 
 * or any consequential, incidental or indirect damage arising
 * out of the use of the software.
 *
 */

















#include "cansilib.h"   
#include "cmnconf.h"    
#include "aapifile.h"   
#include "cmntypes.h"   
#include "aapicmn.h"    
#include "fldrmgr.h"    
#include "gmem.h"       
#include "cutils.h"     
#include "chartype.h"   

#include "mmstypes.h"   
#include "mmsconf.h"    
#include "aapimms.h"    
#include "msig.h"       
#include "mtimer.h"     
#include "mmem.h"       
#include "mcpdu.h"      
#include "mconfig.h"    
#include "mutils.h"     
#include "mfreemms.h"   
#include "mmpdup.h"      
#include "mfetch.h"     

#include "mnotify.h"    
#include "mreceive.h"   
#include "mcnotif.h"    
#include "mrptr.h"      


#define NOTIF_TABLE_FILE_ID         0
#define MMS_NOTIFY_TIMEOUT          1200    
#define MMS_NOTIFY_TIMEOUT_INIT     450     
#define MMS_IMMEDIATE_RETRIEVAL_CHECKS_PER_ITERATION 1






typedef struct
{
    UINT32 fileId;          
    MmsMsrNotifStorageType type;  
    UINT8 retries;          



    char *uri;              
} MsrNotifTableData;





typedef struct
{
    int count;  
    MsrNotifTableData notif[MMS_MAX_DUPLICATE_NOTIFICATION_CHECK];
} MsrNotifTable;


typedef enum
{
    MSR_IDLE,                   
    MSR_IMMEDIATELY_RETRIEVING  
} MsrNotifyFsmState;


typedef struct
{
    MsrNotifyFsmState state;    
    MsrNotifTable notifTable;   
} MsrNotifyInstanceData;















static MsrNotifyInstanceData fsm;


static char *getTransactionId(unsigned char *pdu, UINT32 len);
static CMN_BOOL handleNotification( MmsMsrNotifStorageType storage, UINT32 fileId, 
    MmsTimeSec time, CMN_BOOL isSmsBearer, UINT32 len, unsigned char *pdu);
static void immediateRetrievalCheck(void);
static void immediateRetrievalFinished( MmsSigMsrReceiveParam *p);
static CMN_BOOL isImmediateRetrieval(const MmsNotification *mmsNotification);
static CMN_BOOL isInServerList( const char *server, const char *uri);
static CMN_BOOL moreAttempts( UINT32 fileId);
static void msrNotifyMain(MmsSignal *sig);
static void notifInit(void);
static CMN_BOOL notifIsEqual( const char *uri, const MmsNotification *notif);
static CMN_BOOL notifFileRead(UINT32 fileId, MmsTimeSec *time, 
    CMN_BOOL *isSmsBearer, UINT32 *len, unsigned char **pdu);
static UINT32 notifFileWrite(MmsTimeSec time, CMN_BOOL isSmsBearer, 
    unsigned char *pdu, UINT32 len);
static UINT32 notifTableDecodeData( const char *buf, UINT32 len);
static MmsMsrNotifStorageType notifTableEntryExists(const MmsNotification *notif);
static void notifTableFreeMemory(void);
static void notifTableInsert( MmsMsrNotifStorageType type, UINT32 fileId, 
    const char *uri);
static void notifTableRead(void);
static void notifTableRemove(int index);
static void notifTableSaveAll(void);
static void notifTableSaveAllNoCache(void);
static void sendNotifyRespInd( CMN_BOOL isSmsBearer, const char *trId, 
    MmsStatus mgsStatus, MmsClassIdentifier msgClass, MmsVersion version);
static MmsResult storeDelayedRetrieval( MmsMsrNotifStorageType storage, UINT32 fileId, 
    MmsTimeSec time, CMN_BOOL isSmsBearer, UINT32 len, unsigned char *pdu, 
    MmsVersion version, MmsNotificationReason reason, UINT32 seqId);
static CMN_BOOL transientError( MmsRetrieveStatus retrieveStatus);










static char *getTransactionId(unsigned char *pdu, UINT32 len)
{
    MmsHeaderValue trId;

    if (!mmsPduGet( pdu, len, X_MMS_TRANSACTION_ID, &trId) || 
        trId.transactionId == NULL)
    {
         return NULL; 
    }   

    return trId.transactionId; 
} 









static void handleDeliveryReport(UINT32 len, unsigned char *pdu)
{
    MmsDeliveryInd *mmsDelivery;
    INT32 origMsgId; 
    
    mmsDelivery = (MmsDeliveryInd *)M_CALLOC(sizeof(MmsDeliveryInd)); 

    
    parseDeliveryReport(pdu, len, mmsDelivery); 
   
    

    if ((origMsgId = mrpthGetMsgId(mmsDelivery->messageId)) == -1) 
    {
        origMsgId = 0;
    }  
   
    MMSa_deliveryReportReceived(mmsDelivery->messageId, mmsDelivery->to, 
         mmsDelivery->date, mmsDelivery->status, (MmsMsgId)origMsgId);

#ifndef MMS_RETAIN_ADAPTER_PARAMETERS    
    freeMmsAddress(mmsDelivery->to);
    M_FREE(mmsDelivery->to);
    M_FREE(mmsDelivery->messageId);
#endif
    M_FREE(mmsDelivery);
} 













static CMN_BOOL handleNotification( MmsMsrNotifStorageType storage, UINT32 fileId, 
    MmsTimeSec time, CMN_BOOL isSmsBearer, UINT32 len, unsigned char *pdu)
{
    char *trId = NULL;
    CMN_BOOL pduInUse = FALSE;
    CMN_BOOL isStarted = FALSE;
    MmsVersion version;
    MmsNotification *mmsNotification;
    MmsSigMsrReceiveParam *param;
    MmsMsrNotifStorageType type;
    MmsMessageClass mc;

    mmsNotification = (MmsNotification *)M_CALLOC( sizeof(MmsNotification));
    
    
    if (parseMmsNotification( pdu, len, mmsNotification, &version) != MMS_RESULT_OK)
    {
        if (storage == NOTIF_IMMEDIATE)
        {
            msrNotifyRemoveId( NOTIF_IMMEDIATE, fileId);
        } 

        MMS_LOG_I(("%s(%d): Parse Notification failed!\n", __FILE__, __LINE__)); 
    }
    else if ( (trId = getTransactionId(pdu, len)) == NULL)
    {
        if (storage == NOTIF_IMMEDIATE)
        {
            msrNotifyRemoveId( NOTIF_IMMEDIATE, fileId);
        } 

        MMS_LOG_I(("%s(%d): Missing X_MMS_TRANSACTION_ID\n", __FILE__, __LINE__));            
    }
    else if ( storage == NOTIF_UNSTORED && 
        (type = notifTableEntryExists(mmsNotification)) != NOTIF_UNSTORED)
    {
        
        if (type == NOTIF_IMMEDIATE)
        {
            MMS_LOG_I(("handleNotification: duplicate notification for %s.\n"
                "\tStored for IMMEDIATE retrieval. This one is ignored.\n", 
                mmsNotification->contentLocation == NULL ? "NULL" :
                    mmsNotification->contentLocation)); 
        }
        else 
        {
            


            MMS_LOG_I(("handleNotification: duplicate notification for %s.\n"
                "\tDELAYED. Already stored. Send a new M-NotifyResp.ind.\n", 
                mmsNotification->contentLocation == NULL ? "NULL" :
                    mmsNotification->contentLocation)); 

            mmsPduGetMessageClass( pdu, len, &mc);
            sendNotifyRespInd( isSmsBearer, trId , MMS_STATUS_DEFERRED, 
                mc.classIdentifier, version);
        } 
    }
    else if (cfgGetInt(MMS_CFG_IMMEDIATE_RETRIEVAL) == FALSE)
    {   
        
        (void)storeDelayedRetrieval( storage, fileId, time, isSmsBearer, len, 
            pdu, version, MMS_NOTIFICATION_REASON_NORMAL, 0);
    }
    else if (cfgGetInt(MMS_CFG_IMMEDIATE_RETRIEVAL) == TRUE &&
        isImmediateRetrieval(mmsNotification))
    {
        


        



        if (cfgGetInt(MMS_CFG_MAX_DOWNLOAD_SIZE) > 0 && 
            mmsNotification->length > cfgGetInt(MMS_CFG_MAX_DOWNLOAD_SIZE))
        {
            
            (void)storeDelayedRetrieval( storage, fileId, time, isSmsBearer, len, 
                pdu, version, MMS_NOTIFICATION_REASON_MAX_DOWNLOAD_SIZE_EXCEEDED, 0);
        }
        else
        {
            

            
            if (storage == NOTIF_UNSTORED)
            {
                fileId = notifFileWrite( time, isSmsBearer, pdu, len);

                if (fileId != 0)
                {
                    notifTableInsert( NOTIF_IMMEDIATE, fileId, 
                        mmsNotification->contentLocation);
                } 
            } 

            if (fsm.state == MSR_IMMEDIATELY_RETRIEVING)
            {
                isStarted = TRUE;   
            }
            else if (fileId != 0)
            {
                param = M_CALLOC(sizeof(MmsSigMsrReceiveParam));
                

                param->notifId = fileId;
                param->category = MMS_FILE_CATEGORY_IMMEDIATE;
                param->pdu = pdu;
                param->len = len;
                param->isSmsBearer = isSmsBearer;
                param->time = time;
                M_SIGNAL_SENDTO_IUP( M_FSM_MSR_RECEIVE, MMS_SIG_MSR_RECEIVE_IMMEDIATE,
                    MMS_SIG_MSR_IMMEDIATE_RETRIEVAL_FINISHED, M_FSM_MSR_NOTIFY,
                    param);

                pduInUse = TRUE;    
                isStarted = TRUE;
                fsm.state = MSR_IMMEDIATELY_RETRIEVING;
            } 
        } 
    } 
        


    else if (cfgGetInt(MMS_CFG_TREAT_AS_DELAYED_RETRIEVAL))
    {
        (void)storeDelayedRetrieval( storage, fileId, time, isSmsBearer, len, pdu, 
            version, MMS_NOTIFICATION_REASON_CONDITION_NOT_FULFILLED, 0);
    }
    else  
    {  
        MMS_LOG_I(("handleNotification: Notification rejected!\n")); 
        sendNotifyRespInd( isSmsBearer, trId, MMS_STATUS_REJECTED,
            mmsNotification->msgClass.classIdentifier, version);
    } 

    freeMmsNotification(mmsNotification);
    M_FREE(mmsNotification);

    if ( !pduInUse )
    {
        M_FREE(pdu);
    } 

    return isStarted;
} 








  
static void handleReadReport(UINT32 len, unsigned char *pdu)
{
    MmsReadOrigInd *mmsOrigInd = NULL;
    INT32 origMsgId;

    
    mmsOrigInd = parseReadReport(pdu, len); 
   
    

    if ((origMsgId = mrpthGetMsgId(mmsOrigInd->serverMessageId)) == -1) 
    {
        origMsgId = 0;
    } 

    MMSa_readReportIndication(mmsOrigInd, (MmsMsgId)origMsgId);

#ifndef MMS_RETAIN_ADAPTER_PARAMETERS
    freeMmsReadOrigInd(mmsOrigInd);
#endif
} 





static void immediateRetrievalCheck(void)
{
    int     nrOfFiles = 0;
    int     nrToCheck = 0;
    MmsTimeSec time;
    CMN_BOOL isSmsBearer;
    CMN_BOOL isStarted = FALSE;
    UINT32 len;
    unsigned char *pdu;
    
    UINT32  allFileIds[MMS_IMMEDIATE_RETRIEVAL_CHECKS_PER_ITERATION + 1];

    if (fsm.state == MSR_IMMEDIATELY_RETRIEVING || 
        cfgGetInt(MMS_CFG_IMMEDIATE_RETRIEVAL) == MMS_IMMEDIATE_RETRIEVAL_PAUSED)
    {   

        return;
    } 

    
    nrOfFiles = FILEa_getFileIds( MMS_FILE_CATEGORY_IMMEDIATE, NULL, 0);
    if (nrOfFiles <= 1)
    {   
        return;
    } 

    

    nrToCheck = FILEa_getFileIds( MMS_FILE_CATEGORY_IMMEDIATE, allFileIds, 
        sizeof(allFileIds) / sizeof(UINT32));

    
    if (nrToCheck > (int)(sizeof(allFileIds) / sizeof(UINT32)))
    {
        MMS_LOG_I(("%s(%d): FILEa_getFileIds return more than requested %d > %d\n", 
            __FILE__, __LINE__, nrToCheck, 
            (int)(sizeof(allFileIds) / sizeof(UINT32))));
        MMSa_error(MMS_RESULT_ERROR);
        return;
    } 

    



    while ( --nrToCheck >= 0 && !isStarted )
    {
        if (allFileIds[nrToCheck] == NOTIF_TABLE_FILE_ID)
        {
            
        }
        else if (notifFileRead( allFileIds[nrToCheck], &time, &isSmsBearer, 
            &len, &pdu))
        {
            isStarted = handleNotification( NOTIF_IMMEDIATE, 
                allFileIds[nrToCheck], time, isSmsBearer, len, pdu);
        }
        else
        {
            MMS_LOG_I(("%s(%d): Couldn't read stored notif\n", __FILE__, __LINE__));
            FILEa_delete( MMS_FILE_CATEGORY_IMMEDIATE, allFileIds[nrToCheck]);
        } 
    } 

    


    if ( !isStarted && nrOfFiles > nrToCheck )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -