00001 #include <config.h>
00002 #ifdef OASYS_BLUETOOTH_ENABLED
00003
00004 #include <errno.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007
00008 extern int errno;
00009
00010 #include <sys/socket.h>
00011 #include <bluetooth/bluetooth.h>
00012 #include <bluetooth/hci.h>
00013 #include <bluetooth/rfcomm.h>
00014
00015 #include "BluetoothSDP.h"
00016
00017
00018 namespace oasys {
00019
00020 BluetoothServiceDiscoveryClient::
00021 BluetoothServiceDiscoveryClient(const char* logpath) :
00022 Logger("BluetoothServiceDiscoveryClient",logpath),
00023 response_list_(NULL),
00024 session_handle_(NULL)
00025 {
00026 bacpy(&local_addr_,BDADDR_ANY);
00027 }
00028
00029 BluetoothServiceDiscoveryClient::
00030 ~BluetoothServiceDiscoveryClient()
00031 {
00032
00033 close();
00034
00035
00036 if (response_list_) {
00037 delete response_list_;
00038 response_list_ = NULL;
00039 }
00040 }
00041
00042 bool
00043 BluetoothServiceDiscoveryClient::
00044 connect()
00045 {
00046 if (session_handle_ != NULL) return true;
00047
00048
00049 session_handle_ = sdp_connect(
00050 &local_addr_,
00051 &remote_addr_,
00052 SDP_RETRY_IF_BUSY);
00053
00054 if ( ! session_handle_ ) {
00055
00056 log_debug("failed to connect to SDP server: %s (%d)\n",
00057 strerror(errno), errno);
00058 return false;
00059 }
00060
00061 return true;
00062 }
00063
00064 bool
00065 BluetoothServiceDiscoveryClient::
00066 close()
00067 {
00068 if (session_handle_) {
00069 sdp_close(session_handle_);
00070 session_handle_ = NULL;
00071 return true;
00072 }
00073 return false;
00074 }
00075
00076 sdp_list_t*
00077 BluetoothServiceDiscoveryClient::
00078 do_search() {
00079
00080
00081 if (connect()) {
00082
00083
00084 const uint32_t dtn_svc_uuid_int[] = OASYS_BLUETOOTH_SDP_UUID;
00085 uuid_t svc_uuid;
00086
00087
00088
00089
00090 uint32_t range = 0x0000ffff;
00091
00092
00093 sdp_uuid128_create(&svc_uuid,&dtn_svc_uuid_int);
00094
00095
00096
00097 sdp_list_t *search = sdp_list_append(NULL,&svc_uuid);
00098
00099
00100 sdp_list_t *attrid = sdp_list_append(NULL,&range);
00101
00102
00103 sdp_list_t *response_list;
00104
00105
00106 int err = sdp_service_search_attr_req(
00107 session_handle_,
00108 search,
00109 SDP_ATTR_REQ_RANGE,
00110 attrid,
00111 &response_list);
00112
00113
00114
00115
00116
00117 sdp_list_free(attrid,0);
00118 sdp_list_free(search,0);
00119
00120 if (err != 0) {
00121 log_debug("problems with sdp search: %s (%d)\n",
00122 strerror(errno),errno);
00123 return NULL;
00124 }
00125
00126 return response_list;
00127 }
00128
00129
00130 return NULL;
00131 }
00132
00133 sdp_record_t *
00134 BluetoothServiceDiscoveryClient::
00135 get_next_service_record()
00136 {
00137
00138
00139
00140 if (response_list_ == NULL) {
00141 sdp_list_t* search = do_search();
00142 if (search == NULL) return NULL;
00143 response_list_ = new SDPListHead(search);
00144
00145 }
00146
00147
00148 if (sdp_list_t* record_elem = response_list_->next()) {
00149
00150 sdp_record_t *service_record = (sdp_record_t*) record_elem->data;
00151 return service_record;
00152 }
00153
00154
00155
00156
00157 delete response_list_;
00158 response_list_ = NULL;
00159
00160
00161 return NULL;
00162 }
00163
00164 bool
00165 BluetoothServiceDiscoveryClient::
00166 is_dtn_router(bdaddr_t addr)
00167 {
00168 bacpy(&remote_addr_,&addr);
00169 int is_dtn_host = 0;
00170
00171
00172 while (sdp_record_t *record = get_next_service_record()) {
00173
00174
00175 sdp_list_t *proto_list;
00176
00177
00178 if (sdp_get_access_protos(record,&proto_list) == 0) {
00179
00180 sdp_list_t* proto_seq_iter = proto_list;
00181
00182
00183 while (proto_seq_iter) {
00184
00185 sdp_list_t* ps_list_iter = (sdp_list_t*)proto_seq_iter->data;
00186
00187
00188
00189 while (ps_list_iter) {
00190
00191 sdp_data_t* attr_list_iter =
00192 (sdp_data_t*) ps_list_iter->data;
00193 int proto = 0;
00194
00195 while (attr_list_iter) {
00196
00197 switch( attr_list_iter->dtd ) {
00198 case SDP_UUID16:
00199 case SDP_UUID32:
00200 case SDP_UUID128:
00201 proto = sdp_uuid_to_proto(
00202 &attr_list_iter->val.uuid);
00203 if (proto == RFCOMM_UUID) {
00204 is_dtn_host++;
00205 }
00206 break;
00207 }
00208
00209 sdp_data_t* ali_next = attr_list_iter->next;
00210
00211 sdp_data_free(attr_list_iter);
00212
00213 attr_list_iter = ali_next;
00214
00215 }
00216
00217 sdp_list_t* pli_next = ps_list_iter->next;
00218
00219 free(ps_list_iter);
00220
00221 ps_list_iter = pli_next;
00222
00223 }
00224
00225 sdp_list_t* psi_next = proto_seq_iter->next;
00226
00227 free(proto_seq_iter);
00228
00229 proto_seq_iter = psi_next;
00230
00231 }
00232 } else {
00233 log_debug("Failed to retrieve list of protocol sequences: "
00234 "%s (%d)\n", strerror(errno),errno);
00235 return false;
00236 }
00237
00238 }
00239
00240 return (is_dtn_host > 0);
00241 }
00242
00243 BluetoothServiceRegistration::
00244 BluetoothServiceRegistration(bdaddr_t* local, const char* logpath) :
00245 Logger("BluetoothServiceRegistration",logpath),
00246 session_handle_(NULL)
00247 {
00248 bacpy(&local_addr_,local);
00249 status_ = register_service();
00250 }
00251
00252 BluetoothServiceRegistration::
00253 ~BluetoothServiceRegistration()
00254 {
00255 if (session_handle_)
00256 sdp_close(session_handle_);
00257 }
00258
00259 bool
00260 BluetoothServiceRegistration::
00261 register_service()
00262 {
00263 uint32_t service_uuid_int[] = OASYS_BLUETOOTH_SDP_UUID;
00264 const char *service_name = OASYS_BLUETOOTH_SDP_NAME;
00265 const char *service_dsc = OASYS_BLUETOOTH_SDP_DESC;
00266 const char *service_prov = OASYS_BLUETOOTH_SDP_PROV;
00267
00268 uuid_t root_uuid,
00269 l2cap_uuid,
00270 rfcomm_uuid,
00271 svc_uuid;
00272 sdp_list_t *l2cap_list = 0,
00273 *rfcomm_list = 0,
00274 *root_list = 0,
00275 *proto_list = 0,
00276 *access_proto_list = 0;
00277 int err = 0;
00278
00279 sdp_record_t *record = sdp_record_alloc();
00280
00281
00282 sdp_uuid128_create(&svc_uuid,&service_uuid_int);
00283 sdp_set_service_id(record,svc_uuid);
00284
00285
00286 sdp_uuid16_create(&root_uuid,PUBLIC_BROWSE_GROUP);
00287 root_list = sdp_list_append(0,&root_uuid);
00288 sdp_set_browse_groups(record,root_list);
00289
00290
00291 sdp_uuid16_create(&l2cap_uuid,L2CAP_UUID);
00292 l2cap_list = sdp_list_append(0,&l2cap_uuid);
00293 proto_list = sdp_list_append(0,l2cap_list);
00294
00295
00296 sdp_uuid16_create(&rfcomm_uuid,RFCOMM_UUID);
00297 rfcomm_list = sdp_list_append(0,&rfcomm_uuid);
00298 sdp_list_append(proto_list,rfcomm_list);
00299
00300
00301 access_proto_list = sdp_list_append(0,proto_list);
00302 sdp_set_access_protos(record,access_proto_list);
00303
00304
00305 sdp_set_info_attr(record,service_name,service_prov,service_dsc);
00306
00307
00308
00309 session_handle_ = sdp_connect(
00310 &local_addr_,
00311 BDADDR_LOCAL,
00312 SDP_RETRY_IF_BUSY);
00313 err = sdp_record_register(session_handle_,record,0);
00314
00315
00316 sdp_list_free(l2cap_list,0);
00317 sdp_list_free(rfcomm_list,0);
00318 sdp_list_free(root_list,0);
00319 sdp_list_free(proto_list,0);
00320 sdp_list_free(access_proto_list,0);
00321 sdp_record_free(record);
00322
00323 return (err == 0);
00324 }
00325
00326 }
00327 #endif // OASYS_BLUETOOTH_ENABLED