#include "socket.h"

#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/sco.h>

int set_l2cap_mtu( int sock, uint16_t mtu ) {
	struct l2cap_options opts;
	int optlen = sizeof(opts), err;
	err = getsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen );
	if( ! err ) {
        	opts.omtu = opts.imtu = mtu;
        	err = setsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen );
    	}
	return err;
}

int set_l2cap_mode( int sock, uint8_t mode) {
	struct l2cap_options opts;
	int optlen = sizeof(opts), err;
	err = getsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen );
	if( ! err ) {
        	opts.mode = mode;
        	err = setsockopt( sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen );
    	}
	return err;
}

int create_bound_socket(bt_intfr_config * config) {
	struct sockaddr_l2 addr = { 0 };
	struct sockaddr_l2 loc_addr = { 0 };
	struct sockaddr_sco addr1 = { 0 };
	struct sockaddr_sco loc_addr1 = { 0 };	
	int s, status;

	bdaddr_t src_bda; // = {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};

	switch(config->protocol) {

		case L2CAP:
			printf("%s: creating l2cap socket\n", __func__);		
			s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	    		set_l2cap_mode(s, config->mode);
    			set_l2cap_mtu(s, 1021);

			if (config->interface != NULL) {
				str2ba(config->interface, &src_bda);
    				loc_addr.l2_family = AF_BLUETOOTH;
    				loc_addr.l2_bdaddr = src_bda;
    				loc_addr.l2_psm = htobs(0x1001);

    				bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
			}
			break;

		case SCO:
			printf("%s: creating sco socket\n", __func__);
			s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);

			if (config->interface != NULL) {
				str2ba(config->interface, &src_bda);
		    		loc_addr1.sco_family = AF_BLUETOOTH;
		    		loc_addr1.sco_bdaddr = src_bda;

				int retval = bind(s, (struct sockaddr *)&loc_addr1, sizeof(loc_addr1));
				if (retval == -1) {
					perror("sco socket bind failed");
				} else {
					printf("%s: socket s = %d bound correctly\n", __func__, s);
				}
			} else {
				printf("%s: interface to bind to is not set!\n", __func__);
			}
			break;
		default:
			break;
	}
	printf("%s: returning socket s = %d\n", __func__, s);
	return s;
}



