3 #define CMD_BYTE 0x20; /* all cmnds start with this byte */
4 #define ATS_BYTE 0x21; /* cmd to return the ats */
5 #define PRS_BYTE 0x22; /* cmd to check for the presence of a icc */
7 char cmd
[2]; /* commands */
8 int scan_sock
; /* socket to scan for devices */
9 int com_sock
; /* socket for communication */
10 fd_set socks
; /* needed for select call to check for closed connection */
11 struct timeval timeout
; /* needed for select */
12 inquiry_info
*devices
= NULL
; /* holds found device */
15 //uint32_t svc_uuid_int32 = 0x1101; /* UUID of the service */
16 //uint32_t svc_uuid_int[] = {0x0100, 0, 0, 0x34fb};
17 uint32_t svc_uuid_int32
= 0x0100;
18 //uint16_t svc_uuid_int16 = 0x1101;
20 const char *svc_name
= "SPPServer1";
38 /* scan for devices */
39 RESPONSECODE
getDevice()
44 int adapter_id
, len
, flags
;
46 char addr
[19] = { 0 };
47 char name
[248] = { 0 };
49 adapter_id
= hci_get_route(NULL
);
52 fprintf(stderr
, "couldn't get adapter: error code %d: %s\n",
53 errno
, strerror(errno
));
54 return IFD_COMMUNICATION_ERROR
;
57 scan_sock
= hci_open_dev(adapter_id
);
60 Log1(PCSC_LOG_CRITICAL
, "opening socket failed");
61 return IFD_COMMUNICATION_ERROR
;
66 flags
= IREQ_CACHE_FLUSH
;
67 devices
= (inquiry_info
*) malloc(max_rsp
* sizeof(inquiry_info
));
70 num_rsp
= hci_inquiry(adapter_id
, len
, max_rsp
, NULL
, &devices
, flags
);
74 Log1(PCSC_LOG_CRITICAL
, "hci_inquiry failed");
75 return IFD_COMMUNICATION_ERROR
;
80 Log1(PCSC_LOG_CRITICAL
, "no devices found");
81 return IFD_COMMUNICATION_ERROR
;
84 // try to find the service on every device
85 for (i
= 0; i
< num_rsp
; ++i
)
87 ba2str(&(devices
+ i
)->bdaddr
, addr
);
88 memset(name
, 0, sizeof(name
));
89 if (0 != hci_read_remote_name(scan_sock
, &(devices
+ i
)->bdaddr
,
90 sizeof(name
), name
, 0))
92 strcpy(name
, "[unknown]");
94 printf("trying: %s %s\n", addr
, name
);
97 if (getService(devices
->bdaddr
) == IFD_SUCCESS
)
102 return IFD_COMMUNICATION_ERROR
;
105 /* entry point for practical use with bt-address as string */
106 RESPONSECODE
getServiceByName(char* strAddr
)
109 str2ba(strAddr
, &target
);
110 return getService(target
);
113 /* connect to the service on the specified device */
114 RESPONSECODE
getService(bdaddr_t target
)
119 sdp_list_t
*response_list
, *search_list
, *attrid_list
;
120 sdp_session_t
*session
= 0;
121 uint32_t range
= 0x0000ffff;
124 // connect to the sdp server running on the remote machine
125 session
= sdp_connect(BDADDR_ANY
, &target
, 0);
129 fprintf(stderr
, "couldn't get session: error code %d: %s\n",
130 errno
, strerror(errno
));
131 return IFD_COMMUNICATION_ERROR
;
134 //sdp_uuid128_create(&svc_uuid, &svc_uuid_int);
135 sdp_uuid32_create(&svc_uuid
, svc_uuid_int32
);
136 search_list
= sdp_list_append(0, &svc_uuid
);
137 attrid_list
= sdp_list_append(0, &range
);
139 // get a list of service records that have UUID 0x1101
140 response_list
= NULL
;
141 status_sdp
= sdp_service_search_attr_req(session
, search_list
,
142 SDP_ATTR_REQ_RANGE
, attrid_list
, &response_list
);
146 sdp_list_t
*proto_list
= NULL
;
147 sdp_list_t
*r
= response_list
;
151 Log1(PCSC_LOG_DEBUG
, "no records matched");
154 // go through each of the service records
155 for (; r
; r
= r
->next
)
157 sdp_record_t
*rec
= (sdp_record_t
*) r
->data
;
159 // get a list of the protocol sequences
160 if (sdp_get_access_protos(rec
, &proto_list
) == 0)
162 sdp_data_t
*d
= sdp_data_get(rec
, SDP_ATTR_SVCNAME_PRIMARY
);
165 //printf("Service Name: %s\n", d->val.str);
167 if (strncmp(d
->val
.str
, svc_name
, 10) == 0)
169 // get the RFCOMM port number
170 port
= sdp_get_proto_port(proto_list
, RFCOMM_UUID
);
173 Log1(PCSC_LOG_DEBUG
, "trying L2CAP");
175 // get the L2CAP port number
176 port
= sdp_get_proto_port(proto_list
, L2CAP_UUID
);
179 sdp_list_free(proto_list
, 0);
185 fprintf(stderr
, "couldn't get access protocol: error code %d: %s\n",
186 errno
, strerror(errno
));
188 sdp_record_free(rec
);
193 fprintf(stderr
, "couldn't connect to sdp: error code %d: %s\n",
194 errno
, strerror(errno
));
197 sdp_list_free(response_list
, 0);
198 sdp_list_free(search_list
, 0);
199 sdp_list_free(attrid_list
, 0);
209 Log2(PCSC_LOG_DEBUG
, "found service running on RFCOMM port %d", port
);
211 com_sock
= socket(AF_BLUETOOTH
, SOCK_STREAM
, BTPROTO_RFCOMM
);
213 struct sockaddr_rc addrs
= { 0 };
215 // set the connection parameters (who to connect to)
216 addrs
.rc_family
= AF_BLUETOOTH
;
217 addrs
.rc_channel
= port
;
218 addrs
.rc_bdaddr
= target
;
221 status
= connect(com_sock
, (struct sockaddr
*)&addrs
, sizeof(addrs
));
225 Log2(PCSC_LOG_DEBUG
, "found service running on L2CAP psm %d", port
);
227 com_sock
= socket(AF_BLUETOOTH
, SOCK_SEQPACKET
, BTPROTO_L2CAP
);
229 struct sockaddr_l2 addrs
= { 0 };
231 // set the connection parameters (who to connect to)
232 addrs
.l2_family
= AF_BLUETOOTH
;
233 addrs
.l2_psm
= htobs(port
);
234 addrs
.l2_bdaddr
= target
;
237 status
= connect(com_sock
, (struct sockaddr
*)&addrs
, sizeof(addrs
));
240 set_l2cap_mtu(com_sock
, 257);
249 return IFD_COMMUNICATION_ERROR
;
252 int set_l2cap_mtu(int sock
, uint16_t mtu
)
254 struct l2cap_options opts
;
255 int optlen
= sizeof(opts
);
256 int status
= getsockopt(sock
, SOL_L2CAP
, L2CAP_OPTIONS
, &opts
, &optlen
);
260 opts
.omtu
= opts
.imtu
= mtu
;
261 status
= setsockopt(sock
, SOL_L2CAP
, L2CAP_OPTIONS
, &opts
, optlen
);
267 /* wrap data, transmit to the device and get answer */
268 RESPONSECODE
sendData(PUCHAR TxBuffer
, DWORD TxLength
,
269 PUCHAR RxBuffer
, PDWORD RxLength
, int wait
)
274 return IFD_COMMUNICATION_ERROR
;
276 char apdu
[TxLength
+ 2];
277 int i
, j
, response_length
, n
= 0;
280 // always use first 2 bytes byte as length of following data
281 apdu
[0] = TxLength
>> 8 & 0xFF;
282 apdu
[1] = TxLength
& 0xFF;
284 for (i
= 0; i
< TxLength
; ++i
)
286 apdu
[i
+ 2] = *(TxBuffer
+ i
);
289 //// check if write is possible
291 //FD_SET(com_sock, &socks);
292 ////sock_max = s + 1;
293 //n = select(com_sock + 1, (fd_set *) 0, &socks, (fd_set *) 0, &timeout);
296 // return IFD_COMMUNICATION_ERROR;
299 send(com_sock
, apdu
, TxLength
+ 2, 0);
301 Log2(PCSC_LOG_DEBUG
, "wrote %d data bytes", TxLength
);
307 // use select to recognize broken connection
311 FD_SET(com_sock
, &socks
);
312 n
= select(com_sock
+ 1, &socks
, (fd_set
*) 0, (fd_set
*) 0, &timeout
);
316 return IFD_COMMUNICATION_ERROR
;
318 else if (n
== 0 || !FD_ISSET(com_sock
, &socks
))
326 n
= recv(com_sock
, buffer
, sizeof(buffer
), 0);
331 n
= recv(com_sock
, buffer
, sizeof(buffer
), 0);
338 Log1(PCSC_LOG_DEBUG
, "1 byte error response");
340 return IFD_COMMUNICATION_ERROR
;
343 Log2(PCSC_LOG_DEBUG
, "got %d response bytes", n
);
345 response_length
= (int) (0xFF & buffer
[0]) << 8;
346 response_length
+= (int) (0xFF & buffer
[1]);
348 if (response_length
!= n
- 2)
350 *RxLength
= response_length
;
355 for (j
= 2; j
< n2
; ++i
)
357 *(RxBuffer
+ i
) = buffer
[j
];
362 while (n
- 2 < response_length
)
366 //Log1(PCSC_LOG_DEBUG, "rereceive");
368 n2
= recv(com_sock
, buffer
, sizeof(buffer
), 0);
372 //Log2(PCSC_LOG_DEBUG, "got %d additional response bytes", n2);
375 for (j
= 0; j
< n2
; ++i
)
377 *(RxBuffer
+ i
) = buffer
[j
];
383 Log3(PCSC_LOG_ERROR
, "response length wrong, is: %d should be: %d",
384 n
- 2, response_length
);
385 return IFD_COMMUNICATION_ERROR
;
389 //Log3(PCSC_LOG_DEBUG, "concated response length is: %d should be: %d",
390 // i, response_length);
396 *RxLength
= response_length
;
397 for (i
= 0; i
< response_length
; ++i
)
399 *(RxBuffer
+ i
) = buffer
[2 + i
];
401 //Log_Xxd(PCSC_LOG_INFO, "RAPDU: ", *RxBuffer, *RxLength);
408 "no response, meaning eof, reader not usable anymore\n");
410 rv
= IFD_COMMUNICATION_ERROR
;
415 /* get the uid from the device and return it as an atr */
416 void readUID(PDWORD Length
, PUCHAR Value
)
422 char atr
[MAX_ATR_SIZE
- 4];
425 if (sendData(&cmd
, sizeof(cmd
), &atr
, &rxLength
, 0) == IFD_SUCCESS
)
427 // construct standart contactless ATR
428 *(Value
+ 0) = 0x3B; //TS direct convention
429 *(Value
+ 1) = 0x88; //T0 TD1 available, 8 historical bytes
430 *(Value
+ 2) = 0x80; //TD1 TD2 follows, protocol T0
431 *(Value
+ 3) = 0x01; //TD2 no Tx3, protocol T1
433 char crc
= 0x88 ^ 0x80 ^ 0x01;
434 for (i
= 0; i
< rxLength
; ++i
)
436 *(Value
+ i
+ j
) = atr
[i
];
439 *(Value
+ i
+ j
) = crc
;
440 *Length
= rxLength
+ j
+ 1;
448 /* answer to the pcscd polling */
451 // construct presence cmd
458 if (sendData(&cmd
, sizeof(cmd
), &response
, &rxLength
, 1) == IFD_SUCCESS
)
460 // if icc present the response will be just 0x1
463 return (int) response
[0];