Beispiel #1
0
/*******************************************************************************
**
** Function         SMP_SecurityGrant
**
** Description      This function is called to grant security process.
**
** Parameters       bd_addr - peer device bd address.
**                  res     - result of the operation SMP_SUCCESS if success.
**                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
**
** Returns          None
**
*******************************************************************************/
void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
{
    SMP_TRACE_EVENT0 ("SMP_SecurityGrant ");
    if (smp_cb.state != SMP_ST_WAIT_APP_RSP ||
            (smp_cb.cb_evt != SMP_SEC_REQUEST_EVT && smp_cb.cb_evt != SMP_PASSKEY_REQ_EVT) ||
            memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
        return;

    smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
}
Beispiel #2
0
/*******************************************************************************
**
** Function         SMP_Init
**
** Description      This function initializes the SMP unit.
**
** Returns          void
**
*******************************************************************************/
void SMP_Init(void)
{

    SMP_TRACE_EVENT0 ("SMP_Init");
    memset(&smp_cb, 0, sizeof(tSMP_CB));

#if defined(SMP_INITIAL_TRACE_LEVEL)
    smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL;
#else
    smp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif

    smp_l2cap_if_init();
}
Beispiel #3
0
/*******************************************************************************
**
** Function     smp_sm_event
**
** Description  Handle events to the state machine. It looks up the entry
**              in the smp_entry_table array.
**              If it is a valid entry, it gets the state table.Set the next state,
**              if not NULL state.Execute the action function according to the
**              state table. If the state returned by action function is not NULL
**              state, adjust the new state to the returned state.If (api_evt != MAX),
**              call callback function.
**
** Returns      void.
**
*******************************************************************************/
void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
{
    UINT8           curr_state = p_cb->state;
    tSMP_SM_TBL     state_table;
    UINT8           action, entry, i;
    tSMP_ENTRY_TBL  entry_table =  smp_entry_table[p_cb->role];

    SMP_TRACE_EVENT0("main smp_sm_event");
    if (curr_state >= SMP_ST_MAX)
    {
        SMP_TRACE_DEBUG1( "Invalid state: %d", curr_state) ;
        return;
    }

    SMP_TRACE_DEBUG5( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
                      (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
                      p_cb->state, smp_get_event_name(event), event) ;

    /* look up the state table for the current state */
    /* lookup entry /w event & curr_state */
    /* If entry is ignore, return.
     * Otherwise, get state table (according to curr_state or all_state) */
    if ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE )
    {
        if (entry & SMP_ALL_TBL_MASK)
        {
            entry &= ~SMP_ALL_TBL_MASK;
            state_table = smp_all_table;
        }
        else
            state_table = smp_state_table[curr_state][p_cb->role];
    }
    else
    {
        SMP_TRACE_DEBUG4( "Ignore event [%s (%d)] in state [%s (%d)]",
                          smp_get_event_name(event), event, smp_get_state_name(curr_state), curr_state);
        return;
    }

    /* Get possible next state from state table. */

    smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);

    /* If action is not ignore, clear param, exec action and get next state.
     * The action function may set the Param for cback.
     * Depending on param, call cback or free buffer. */
    /* execute action */
    /* execute action functions */
    for (i = 0; i < SMP_NUM_ACTIONS; i++)
    {
        if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
        {
            (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
        }
        else
        {
            break;
        }
    }
    SMP_TRACE_DEBUG1( "result state = %s", smp_get_state_name( p_cb->state ) ) ;
}
Beispiel #4
0
/*******************************************************************************
**
** Function     smp_sm_event
**
** Description  Handle events to the state machine. It looks up the entry
**              in the smp_entry_table array.
**              If it is a valid entry, it gets the state table.Set the next state,
**              if not NULL state.Execute the action function according to the
**              state table. If the state returned by action function is not NULL
**              state, adjust the new state to the returned state.If (api_evt != MAX),
**              call callback function.
**
** Returns      void.
**
*******************************************************************************/
void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data)
{
    UINT8           curr_state = p_cb->state;
    tSMP_SM_TBL     state_table;
    UINT8           action, entry, i;
    tSMP_ENTRY_TBL  entry_table =  smp_entry_table[p_cb->role];

    SMP_TRACE_EVENT0("main smp_sm_event");
    if (curr_state >= SMP_ST_MAX)
    {
        SMP_TRACE_DEBUG1( "Invalid state: %d", curr_state) ;
        return;
    }

    SMP_TRACE_DEBUG5( "SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",\
                      (p_cb->role == 0x01) ?"Slave" : "Master", smp_get_state_name( p_cb->state),
                      p_cb->state, smp_get_event_name(event), event) ;

    /* look up the state table for the current state */
    /* lookup entry /w event & curr_state */
    /* If entry is ignore, return.
     * Otherwise, get state table (according to curr_state or all_state) */
    if ((event < SMP_MAX_EVT) && ( (entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE ))
    {
        if (entry & SMP_ALL_TBL_MASK)
        {
            entry &= ~SMP_ALL_TBL_MASK;
            state_table = smp_all_table;
        }
        else
            state_table = smp_state_table[curr_state][p_cb->role];
    }
    else
    {
#ifdef BLUETOOTH_RTK
        if(event == SMP_MASTER_ID_EVT && p_cb->state == SMP_ST_ENC_PENDING) {
            SMP_TRACE_EVENT1("need to pending event(%d) until SMP_BOND_REQ_EVT", event);
            master_id_pending.pending = TRUE;
            master_id_pending.p_cb = p_cb;
            master_id_pending.event = event;
            master_id_pending.p_data = GKI_getbuf(sizeof(BT_OCTET16)+sizeof(BT_OCTET8));
            memcpy(master_id_pending.p_data, p_data, sizeof(BT_OCTET16)+sizeof(BT_OCTET8));
        } else if(event == SMP_ENCRPTION_INFO_EVT && p_cb->state == SMP_ST_ENC_PENDING) {
            SMP_TRACE_EVENT1("need to pending event(%d) until SMP_BOND_REQ_EVT", event);
            enc_info_pending.pending = TRUE;
            enc_info_pending.p_cb = p_cb;
            enc_info_pending.event = event;
            enc_info_pending.p_data = GKI_getbuf(sizeof(BT_OCTET16));
            memcpy(enc_info_pending.p_data, p_data, sizeof(BT_OCTET16));
        } else
#endif
        SMP_TRACE_DEBUG4( "Ignore event [%s (%d)] in state [%s (%d)]",
                          smp_get_event_name(event), event, smp_get_state_name(curr_state), curr_state);
        return;
    }

    /* Get possible next state from state table. */

    smp_set_state(state_table[entry-1][SMP_SME_NEXT_STATE]);

    /* If action is not ignore, clear param, exec action and get next state.
     * The action function may set the Param for cback.
     * Depending on param, call cback or free buffer. */
    /* execute action */
    /* execute action functions */
    for (i = 0; i < SMP_NUM_ACTIONS; i++)
    {
        if ((action = state_table[entry-1][i]) != SMP_SM_NO_ACTION)
        {
            (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data);
        }
        else
        {
            break;
        }
    }
    SMP_TRACE_DEBUG1( "result state = %s", smp_get_state_name( p_cb->state ) ) ;

#ifdef BLUETOOTH_RTK
    if(event == SMP_BOND_REQ_EVT && enc_info_pending.pending == TRUE) {
        SMP_TRACE_EVENT0("to process pending event SMP_ENCRPTION_INFO_EVT");
        smp_sm_event(enc_info_pending.p_cb, enc_info_pending.event, enc_info_pending.p_data);
        enc_info_pending.pending = FALSE;
        GKI_freebuf(enc_info_pending.p_data);
    }

    if(event == SMP_BOND_REQ_EVT && master_id_pending.pending == TRUE) {
        SMP_TRACE_EVENT0("to process pending event SMP_ID_INFO_EVT");
        smp_sm_event(master_id_pending.p_cb, master_id_pending.event, master_id_pending.p_data);
        master_id_pending.pending = FALSE;
        GKI_freebuf(master_id_pending.p_data);
    }

    if(event == SMP_L2CAP_CONN_EVT && p_cb->state == SMP_ST_IDLE) {
        SMP_TRACE_EVENT0("clean enc_info_pending");
        memset(&enc_info_pending, 0 , sizeof(enc_info_pending));
        memset(&master_id_pending, 0 , sizeof(master_id_pending));
    }
#endif
}