//
//  bt_l2cap_cb_device.c
//
//  Bluetooth Protocol Stack - Remote BT controller device management control block operation
//  Copyright (C) 2013-2016 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()
//  2015.02.03 v0.3  Supported the PIC32
//  2016.02.20 v0.3c+ Bug fix
//
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include "bt_l2cap_cb_device.h"
#include "bt_l2cap_cb_link.h"


//
//    Static area
//
struct bt_l2capDevice    *bt_l2capDeviceRoot = NULL;

                                        // ADD START 2015.02.03
//
//    Sequential access
//
struct bt_l2capDevice *bt_l2capDeviceGetNext(struct bt_l2capDevice **id) {
    struct bt_l2capDevice *p;

#ifdef UPD20160220                      // DEL START 2016.02.20
    if (*id == NULL) {
        p = bt_l2capDeviceRoot;
    } else {
        p = (*id)->next;
    }
#else                                   // DEL END ADD START 2016.02.20
    p = bt_l2capDeviceRoot;
    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_l2capDevice *bt_l2capDeviceFind(unsigned char *bdAddr) {
    struct bt_l2capDevice    *p;

    if (bdAddr != NULL) {
        for(p = bt_l2capDeviceRoot; p != NULL; p = p->next) {
            if (memcmp(p->bdAddr, bdAddr, sizeof(p->bdAddr)) == 0) {
                break;
            }
        }
    } else {
        p = NULL;
    }
    return(p);
}

//
// Add entry
//
struct bt_l2capDevice *bt_l2capDeviceAdd(unsigned char *bdAddr) {
    struct bt_l2capDevice    *p;

    p = bt_l2capDeviceFind(bdAddr);
    if ((p == NULL) && (bdAddr != NULL)) {
        if ((p = calloc(1, sizeof(struct bt_l2capDevice))) != NULL) {
            memcpy(p->bdAddr, bdAddr, sizeof(p->bdAddr));
            p->bdAddrValid     = 1;
            p->next            = bt_l2capDeviceRoot;
            bt_l2capDeviceRoot = p;
        }
    }
    return(p);
}

//
// Delete entry
//
void bt_l2capDeviceDelete(struct bt_l2capDevice *entry) {
    struct bt_l2capDevice *p;
    struct bt_l2capDevice *z;

    z = NULL;
    for(p = bt_l2capDeviceRoot; p != NULL; p = p->next) {
        if (p == entry) {
            struct bt_l2capLink *l;

//          while((l = bt_l2capLinkFind(p->bdAddr, 0)) != NULL) {   // DEL 2017.01.03
            while((l = bt_l2capLinkFindByDevice(p, 0)) != NULL) {   // ADD 2017.01.03
                bt_l2capLinkDelete(l);
            }
            if (z == NULL) {
                bt_l2capDeviceRoot = p->next;
            } else {
                z->next = p->next;
            }
            free(p);
            break;
        }
        z = p;
    }
    return;
}
                                        // ADD START 2015.02.03
//
// Delete all entry
//
void bt_l2capDeviceClear(void) {
    struct bt_l2capDevice  *p;
    struct bt_l2capDevice  *i;

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