www.pudn.com > spp_dev_a.rar > main.c, change:2006-12-12,size:11805b


/* Copyright (C) Cambridge Silicon Radio Ltd. 2005-2006 */ 
/* Part of BlueLab 3.6.2-release */ 
#include "spp_dev_private.h" 
#include "spp_dev_init.h" 
#include "spp_dev_inquire.h" 
#include "spp_dev_auth.h" 
#include "spp_dev_store.h" 
#include "spp_dev_connect.h" 
#include "spp_dev_led.h" 
 
#include <connection.h> 
#include <panic.h> 
#include <stdio.h> 
#include <stream.h> 
#include <pio.h> 
#include <string.h> 
 
/*#define DEBUG_ENABLED*/ 
 
#ifdef DEBUG_ENABLED 
#define DEBUG(x) {printf x;} 
#else 
#define DEBUG(x) 
#endif 
 
typedef struct 
{ 
    TaskData task; 
} PioState; 
 
static sppTaskData theSppApp; 
 
 
/* Keep a list of addresses we've tried before without success */ 
enum { FAILED_SIZE = 8 }; 
static bdaddr failed_addr[FAILED_SIZE]; 
 
static uint16 tried_and_failed(const bdaddr *addr) 
{ 
    static uint16 failed_next; 
    uint16 i; 
    for(i = 0; i < FAILED_SIZE; ++i) 
        if(failed_addr[i].lap == addr->lap 
           && failed_addr[i].nap == addr->nap 
           && failed_addr[i].uap == addr->uap) 
            return 1; 
    failed_addr[failed_next] = *addr; 
    ++failed_next; 
    if(failed_next == FAILED_SIZE) failed_next = 0; 
    return 0; 
} 
 
/************************************************************************* 
NAME     
    unhandledSppState 
     
DESCRIPTION 
    This function is called when a message arrives and the Spp app is 
    in an unexpected state.   
     
RETURNS 
     
*/ 
static void unhandledSppState(sppDevState state, MessageId id) 
{ 
    DEBUG(("UNHANDLED SPP current state %d message id 0x%x\n", state, id));  
} 
 
/************************************************************************* 
NAME     
    setSppState 
     
DESCRIPTION 
    Set the SPP State to the specified state 
 
RETURNS 
     
*/ 
void setSppState(const sppDevState state) 
{ 
    DEBUG(("SPP State - C=%d N=%d\n",theSppApp.spp_state, state)); 
    theSppApp.spp_state = state; 
    sppDevUpdateLed(state); 
} 
 
 
/************************************************************************* 
NAME     
    sppAppTask 
     
DESCRIPTION 
  Returns the spp app's main task. 
 
RETURNS 
    Task 
*/ 
Task getAppTask(void) 
{ 
    return &theSppApp.task; 
} 
 
static void pioHandler(Task task, MessageId id, Message data) 
{ 
    const MessagePioChanged *m = (const MessagePioChanged *)data; 
 
    switch(id) 
    { 
    case MESSAGE_PIO_CHANGED: 
        if (m->state == BUTTON_RESET) 
        { 
            DEBUG(("Button pressed\n")); 
             
            switch(theSppApp.spp_state) 
            {    
            case sppDevInitialising: 
                return; 
                break; 
            case sppDevReady: 
                sppDevInquire(&theSppApp); 
                break; 
            case sppDevInquiring: 
            case sppDevConnecting: 
                DEBUG(("Cancel Inquiry\n")); 
                ConnectionInquireCancel(getAppTask()); 
                break; 
            case sppDevConnected: 
                DEBUG(("Disconnect\n")); 
                SppDisconnect(theSppApp.spp); 
                break; 
            case sppDevDisconnecting: 
                break; 
            } 
             
            clear_far_addr(&theSppApp.bd_addr); 
            memset(failed_addr, 0, sizeof(failed_addr)); 
             
            DEBUG(("End of Pio handler\n")); 
             
        } 
                 
    default: 
        break; 
    } 
 
     
} 
 
static void PioInit(PioState* state) 
{ 
    state->task.handler = pioHandler; 
    MessagePioTask(&state->task); 
    PioDebounce(BUTTON_RESET, 1, 0); 
} 
 
/* Task handler function */ 
static void app_handler(Task task, MessageId id, Message message) 
{ 
    sppDevState state = theSppApp.spp_state; 
    switch(id) 
    { 
    case CL_INIT_CFM: 
        DEBUG(("CL_INIT_CFM\n")); 
        if(((CL_INIT_CFM_T*)message)->status == success) 
            /* Connection Library initialisation was a success */ 
            sppDevInit();    
        else 
            Panic(); 
        break; 
    case SPP_INIT_CFM: 
        DEBUG(("SPP_INIT_CFM\n")); 
        switch(state) 
        { 
        case sppDevInitialising: 
            /* Check for spp_init_success. What do we do if it failed? */ 
            if (((SPP_INIT_CFM_T *) message)->status == spp_init_success) 
            { 
                theSppApp.spp = ((SPP_INIT_CFM_T *) message)->spp; 
             
                if (know_far_addr(theSppApp.bd_addr)) 
                { 
                    /*  We paired with a device previously so now try  
                        and connect to this device */ 
                    sppDevConnect(&theSppApp); 
                } 
                else 
                { 
                    sppDevInquire(&theSppApp); 
                } 
            } 
            break; 
        case sppDevReady: 
        case sppDevInquiring: 
        case sppDevConnecting: 
        case sppDevConnected: 
        case sppDevDisconnecting: 
        default: 
            unhandledSppState(state, id); 
            break; 
        } 
        break; 
    case CL_DM_INQUIRE_RESULT: 
        DEBUG(("CL_DM_INQUIRE_RESULT\n")); 
        switch(state) 
        { 
        case sppDevInquiring: 
        case sppDevConnecting: 
            if (((CL_DM_INQUIRE_RESULT_T*)message)->status == inquiry_status_ready) 
            { 
                DEBUG(("Inquiry complete\n")); 
                /* Inquiry complete. End of inquiry */ 
                sppDevInquiryComplete(&theSppApp); 
            } 
            else 
            { 
                DEBUG(("Found device\n")); 
                /* Inquiry Result. We found a device! */ 
                if(!tried_and_failed(&((CL_DM_INQUIRE_RESULT_T*)message)->bd_addr)) 
                { 
                    DEBUG(("Not already tried to connect\n")); 
                    sppDevInquiryResult(&theSppApp, (CL_DM_INQUIRE_RESULT_T*)message); 
                } 
                else 
                    DEBUG(("Already tried to connect\n")); 
            } 
            break; 
        case sppDevInitialising: 
        case sppDevReady: 
        case sppDevConnected: 
        case sppDevDisconnecting: 
        default: 
            unhandledSppState(state, id); 
            break; 
        } 
        break; 
    case SPP_CONNECT_CFM: 
        DEBUG(("SPP_CONNECT_CFM result = %d\n",((SPP_CONNECT_CFM_T*)message)->status)); 
        switch(state) 
        { 
        case sppDevConnecting: 
        case sppDevInquiring: 
            /* Connect cfm, but must check status as connection may have failed */ 
            if (((SPP_CONNECT_CFM_T*)message)->status == rfcomm_connect_success) 
            { 
                /* Connection Success */ 
                DEBUG(("Device connected...\n")); 
                /* Connect Uart to Rfcomm */ 
        		(void) StreamConnect(StreamUartSource(), ((SPP_CONNECT_CFM_T*)message)->sink); 
	            (void) StreamConnect(StreamSourceFromSink(((SPP_CONNECT_CFM_T*)message)->sink), StreamUartSink()); 
         
                setSppState(sppDevConnected); 
                /* Store to persistent store the address of the device we've connected with */ 
                write_far_addr(&theSppApp.bd_addr); 
            } 
            else 
            { 
                /* Connection failed */  
                bdaddr temp_addr; 
                DEBUG(("Connection failed\n")); 
                /* If PS addr is the same as the one of the device we just 
                   tried to connect with then try again, else look for a new device 
                */ 
                read_far_addr(&temp_addr); 
                if ((temp_addr.lap == theSppApp.bd_addr.lap) && 
                    (temp_addr.uap == theSppApp.bd_addr.uap) && 
                    (temp_addr.nap == theSppApp.bd_addr.nap) && 
                    know_far_addr(temp_addr)) 
                { 
                    sppDevConnect(&theSppApp); 
                } 
                else 
                { 
                    /* Restart enquiry process */ 
                    memset(&theSppApp.bd_addr, 0, sizeof(bdaddr)); 
                    sppDevInquire(&theSppApp); 
                } 
            } 
            break; 
        case sppDevInitialising: 
        case sppDevReady: 
        case sppDevConnected: 
        case sppDevDisconnecting: 
        default: 
            unhandledSppState(state, id); 
            break; 
        } 
        break; 
    case SPP_CONNECT_IND: 
        DEBUG(("SPP_CONNECT_IND\n")); 
        switch(state) 
        { 
        case sppDevReady: 
        case sppDevInquiring: 
            /* Received command that a device is trying to connect. Send response. */ 
            sppDevAuthoriseConnectInd(&theSppApp,(SPP_CONNECT_IND_T*)message); 
            break; 
        case sppDevConnected: 
        case sppDevInitialising: 
        case sppDevConnecting: 
        case sppDevDisconnecting: 
        default: 
            unhandledSppState(state, id); 
            break; 
        } 
        break; 
    case SPP_DISCONNECT_IND: 
        DEBUG(("SPP_DISCONNECT_IND\n")); 
        /* Disconnect message has arrived */ 
        switch(state) 
        { 
        case sppDevReady: 
        case sppDevConnected:    
        case sppDevDisconnecting: 
            if (know_far_addr(theSppApp.bd_addr)) 
            { 
                /* Try again to connect to this device */ 
                sppDevConnect(&theSppApp); 
            } 
            else 
            { 
                /* Look for a new device */ 
                sppDevInquire(&theSppApp); 
            } 
            break; 
        case sppDevInquiring: 
        case sppDevInitialising: 
        case sppDevConnecting: 
        default: 
            unhandledSppState(state, id); 
            break; 
        } 
        break; 
         
    case SPP_DEV_UDPATE_LED: 
        DEBUG(("SPP_DEV_UDPATE_LED\n")); 
        sppDevUpdateLed(theSppApp.spp_state); 
        break; 
         
    case CL_SM_PIN_CODE_IND: 
        DEBUG(("CL_SM_PIN_CODE_IND\n")); 
        sppDevHandlePinCodeRequest((CL_SM_PIN_CODE_IND_T *) message); 
        break; 
    case CL_SM_AUTHORISE_IND:   
        DEBUG(("CL_SM_AUTHORISE_IND\n")); 
        sppDevAuthoriseResponse((CL_SM_AUTHORISE_IND_T*) message); 
        break; 
    case CL_SM_AUTHENTICATE_CFM: 
        DEBUG(("CL_SM_AUTHENTICATE_CFM\n")); 
        sppDevSetTrustLevel(&theSppApp, (CL_SM_AUTHENTICATE_CFM_T*)message);     
        break; 
    case CL_DM_LINK_POLICY_IND: 
        DEBUG(("CL_DM_LINK_POLICY_IND\n")); 
        break; 
    case SPP_MESSAGE_MORE_DATA: 
        DEBUG(("SPP_MESSAGE_MORE_DATA\n")); 
        break; 
    case SPP_MESSAGE_MORE_SPACE: 
        DEBUG(("SPP_MESSAGE_MORE_SPACE\n")); 
        break; 
    default: 
        /* An unexpected message has arrived - must handle it */ 
        DEBUG(("main app - msg type  not yet handled 0x%x\n", id)); 
        break; 
    } 
} 
 
int main(void) 
{ 
    PioState pio_state; 
             
    DEBUG(("Main Started...\n")); 
     
#ifndef NO_UART_CHECK 
    /* Make sure Uart has been successfully initialised before running */ 
    if (StreamUartSource()) 
#endif 
    { 
 
        /* Set up task 1 handler */ 
        theSppApp.task.handler = app_handler; 
         
        setSppState(sppDevInitialising); 
         
        /* Read stored bluetooth address from persistent store */ 
        read_far_addr(&theSppApp.bd_addr); 
         
        PioInit(&pio_state); 
         
        sppDevLedInit(); 
     
        /* Init the Connection Manager */ 
        ConnectionInit(&theSppApp.task); 
 
        /* Start the message scheduler loop */ 
        MessageLoop(); 
    } 
     
    /* Will never get here! */ 
    DEBUG(("Main Ended!\n")); 
     
    return 0; 
}