//
//  bt_l2cap_cb_service.c
//
//  Bluetooth Protocol Stack - Service management control block operation
//  Copyright (C) 2013-2018 Toyohiko Togashi tog001@nifty.com
//
//
//  This program is free software; you can redistribute it and/or modify it under the terms of the
//  GNU General Public License as published by the Free Software Foundation; either version 3
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//  See the GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License along with this program.
//  If not, see <http://www.gnu.org/licenses/>
//
//
//  Update history
//  ---------- ----- -------------------------------------------
//  2013.01.21 v0.0  First cording
//  2013.04.21 v0.1  Commit
//  2013.05.08 v0.1  Code reduction, used a malloc()
//  2014.02.23 v0.1a Supported the Security Manager, default service
//  2015.02.03 v0.3  Supported the PIC32
//  2016.02.20 v0.3c+ Bug fix, bt_l2capServiceGetNext()
//  2017.01.08 v0.3e Appended a authentication function for the classic services
//  2017.01.18 v0.3f Bug fix (Incompatibility of SDP,ATT)
//  2017.02.11 v0.3h The new "bt_config.h"
//  2017.03.10 v0.4  Supported an AVDTP
//  2018.02.10 v0.4a SDP permission (Supported the iOS+SSP)
//
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#include "bt_l2cap_cb_service.h"
#include "bt_spec_l2cap.h"
#include "bt_config.h"                                                  // ADD 2017.02.11

#include "bt_l2cap_signaling.h"
#include "bt_sdp_server.h"
#include "bt_rfcomm_server.h"
#include "bt_att_server.h"
#include "bt_security_manager.h"
#include "bt_avdtp_acceptor.h"                                          // ADD 2017.03.10


//
//    Control block entity
//
// Default services
struct bt_l2capService    bt_l2capServiceCB8 = {                        // ADD 2017.03.10
    NULL,                                                               // ADD 2017.03.10
    L2CAP_PDU_PSM_AVDTP,                                                // ADD 2017.03.10
    BT_AVDTP_PERMISSION,                                                // ADD 2017.03.10
    bt_avdtpAcceptor                                                    // ADD 2017.03.10
};                                                                      // ADD 2017.03.10
struct bt_l2capService    bt_l2capServiceCB7 = {                        // ADD 2017.01.18
//  NULL,                                                               // ADD 2017.01.18  DEL 2017.03.10
    &bt_l2capServiceCB8,                                                //                 ADD 2017.03.10
    L2CAP_PDU_PSM_ATT,                                                  // ADD 2017.01.18  Over BR/EDR  
    BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.18
    bt_attServer                                                        // ADD 2017.01.18
};                                                                      // ADD 2017.01.18
struct bt_l2capService    bt_l2capServiceCB6 = {                        // ADD 2014.02.23
//  NULL,                                                               // CHG 2014.02.23  DEL 2017.01.18
    &bt_l2capServiceCB7,                                                // CHG 2014.02.23  ADD 2017.01.18 
    L2CAP_CID_Security_Manager_Protocol | BT_L2CAP_SERVICE_CID_TO_PSM,  // ADD 2014.02.23  Fixed channel
    BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08
    bt_securityManager                                                  // ADD 2014.02.23
};                                                                      // ADD 2014.02.23
struct bt_l2capService    bt_l2capServiceCB5 = {
//  NULL,                                                               // CHG 2014.02.23
    &bt_l2capServiceCB6,                                                // CHG 2014.02.23
    L2CAP_CID_Attribute_Protocol | BT_L2CAP_SERVICE_CID_TO_PSM,         // Fixed channel   Over LE
    BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08
    bt_attServer
};
struct bt_l2capService    bt_l2capServiceCB4 = {
    &bt_l2capServiceCB5,
    L2CAP_CID_Low_Energy_L2CAP_Signaling_channel | BT_L2CAP_SERVICE_CID_TO_PSM, // Fixed channel
    BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08
    bt_l2capSignaling
};
struct bt_l2capService    bt_l2capServiceCB3 = {
    &bt_l2capServiceCB4,
    L2CAP_PDU_PSM_RFCOMM,
    BT_RFCOMM_PERMISSION,
//  BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08  DEL 2017.02.11
//  BT_L2CAP_SERVICE_PERMISSIONS_Encryption_Required,                   // ADD 2017.01.08
//  BT_L2CAP_SERVICE_PERMISSIONS_Authentication_Required,               // ADD 2017.01.08
    bt_rfcommServer
};
struct bt_l2capService    bt_l2capServiceCB2 = {
    &bt_l2capServiceCB3,
    L2CAP_PDU_PSM_Service_Discovery_Protocol,
//  BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08  DEL 2018.02.10
  	BT_L2CAP_SERVICE_PERMISSIONS_Authentication_Required,               //                 ADD 2018.02.10
    bt_sdpServer
};
struct bt_l2capService    bt_l2capServiceCB1 = {
    &bt_l2capServiceCB2,
    L2CAP_CID_L2CAP_Signaling_channel | BT_L2CAP_SERVICE_CID_TO_PSM,    // Fixed channel
    BT_L2CAP_SERVICE_PERMISSIONS_Allow,                                 // ADD 2017.01.08
    bt_l2capSignaling
};

// Control block root pointer
struct bt_l2capService    *bt_l2capServiceRoot = &bt_l2capServiceCB1;

                                        // ADD START 2015.02.03
//
//    Sequential access
//
struct bt_l2capService *bt_l2capServiceGetNext(struct bt_l2capService **id) {
    struct bt_l2capService *p;

#ifdef UPD20160220                      // DEL START 2016.02.20
    if (*id == NULL) {
        p = bt_l2capServiceRoot;
    } else {
        p = (*id)->next;
    }
#else                                   // DEL END ADD START 2016.02.20
    p = bt_l2capServiceRoot;
    if ((id != NULL) && (*id != NULL)) {
        for(; p != NULL; p = p->next) {
            if (p == *id) {
                p = (*id)->next;
                break;
            }
        }
    }
#endif                                  // ADD END 2016.02.20
    *id = p;
    return(p);
}
                                        // ADD END 2015.02.03

//
// Search entry
//
struct bt_l2capService *bt_l2capServiceFind(unsigned short psm) {
    struct bt_l2capService    *p;

    for(p = bt_l2capServiceRoot; p != NULL; p = p->next) {
        if (p->psm == psm) {
            break;
        }
    }
    return(p);
}

//
// Add entry
//
struct bt_l2capService *bt_l2capServiceAdd(unsigned short psm){
    struct bt_l2capService    *p;

    p = bt_l2capServiceFind(psm);
    if (p == NULL) {
        if ((p = calloc(1, sizeof(struct bt_l2capService))) != NULL) {
            p->psm  = psm;
            p->next = bt_l2capServiceRoot;
            bt_l2capServiceRoot = p;
        }
    }
    return(p);
}

//
// Delete entry
//
void bt_l2capServiceDelete(struct bt_l2capService *entry){
    struct bt_l2capService *p;
    struct bt_l2capService *z;

    z = NULL;
//  for(p = bt_l2capServiceRoot; p != NULL; p = p->next) {                                  // CHG 2015.02.03
    for(p = bt_l2capServiceRoot; (p != NULL) && (p != &bt_l2capServiceCB1); p = p->next) {  // CHG 2015.02.03
        if (p == entry) {
            if (z == NULL) {
                bt_l2capServiceRoot = p->next;
            } else {
                z->next = p->next;
            }
            free(p);
            break;
        }
        z = p;
    }
    return;
}

                                        // ADD START 2015.02.03
//
// Delete all entry
//
void bt_l2capServiceClear(void) {
    struct bt_l2capService *p;
    struct bt_l2capService *i;

    i = NULL;
    while((p = bt_l2capServiceGetNext(&i)) != NULL) {
        bt_l2capServiceDelete(p);
    }
    return;
}
                                        // ADD END 2015.02.03
