change PAD_ScanPads()s behaviour. the return value now contains a bitmask of the...
[libogc.git] / lwbt / bte.c
blob96a12d86303ffddbab16133a7450bce706e5317d
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <malloc.h>
5 #include <ogcsys.h>
6 #include <gccore.h>
7 #include <lwp_threads.h>
9 #include "bt.h"
10 #include "bte.h"
11 #include "hci.h"
12 #include "l2cap.h"
13 #include "btmemb.h"
14 #include "physbusif.h"
17 #define STACKSIZE 32768
18 #define MQ_BOX_SIZE 256
20 /* Vendor specific OGF */
21 #define HCI_VENDOR_OGF 0x3f
23 /* Vendor specific OCF */
24 #define HCI_VENDOR_PATCH_START_OCF 0x4f
25 #define HCI_VENDOR_PATCH_CONT_OCF 0x4c
26 #define HCI_VENDOR_PATCH_END_OCF 0x4f
28 enum bte_state {
29 STATE_NOTREADY = -1,
30 STATE_READY = 0,
31 STATE_CONNECTING,
32 STATE_CONNECTED,
33 STATE_DISCONNECTING,
34 STATE_DISCONNECTED,
35 STATE_SENDING,
36 STATE_SENT,
37 STATE_RECEIVING,
38 STATE_RECEIVED,
39 STATE_FAILED
42 struct bt_state
44 err_t last_err;
46 syswd_t timer_svc;
47 lwpq_t hci_cmdq;
48 u8_t hci_cmddone;
49 u8_t hci_inited;
51 u8_t num_maxdevs;
52 u8_t num_founddevs;
53 struct inquiry_info_ex *info;
55 btecallback cb;
56 void *usrdata;
59 struct ctrl_req_t
61 u8 err;
62 struct pbuf *p;
63 struct bte_pcb *pcb;
64 enum bte_state state;
65 s32 (*sent)(void *arg,struct bte_pcb *pcb,u8 err);
67 struct ctrl_req_t *next;
70 static struct bt_state btstate;
71 static u8_t bte_patch0[184] = {
72 0x70,0x99,0x08,0x00,0x88,0x43,0xd1,0x07,0x09,0x0c,0x08,0x43,0xa0,0x62,0x19,0x23,
73 0xdb,0x01,0x33,0x80,0x7c,0xf7,0x88,0xf8,0x28,0x76,0x80,0xf7,0x17,0xff,0x43,0x78,
74 0xeb,0x70,0x19,0x23,0xdb,0x01,0x33,0x87,0x7c,0xf7,0xbc,0xfb,0x0b,0x60,0xa3,0x7b,
75 0x01,0x49,0x0b,0x60,0x90,0xf7,0x96,0xfb,0xd8,0x1d,0x08,0x00,0x00,0xf0,0x04,0xf8,
76 0x00,0x23,0x79,0xf7,0xe3,0xfa,0x00,0x00,0x00,0xb5,0x00,0x23,0x11,0x49,0x0b,0x60,
77 0x1d,0x21,0xc9,0x03,0x0b,0x60,0x7d,0x20,0x80,0x01,0x01,0x38,0xfd,0xd1,0x0e,0x4b,
78 0x0e,0x4a,0x13,0x60,0x47,0x20,0x00,0x21,0x96,0xf7,0x96,0xff,0x46,0x20,0x00,0x21,
79 0x96,0xf7,0x92,0xff,0x0a,0x4a,0x13,0x68,0x0a,0x48,0x03,0x40,0x13,0x60,0x0a,0x4a,
80 0x13,0x68,0x0a,0x48,0x03,0x40,0x13,0x60,0x09,0x4a,0x13,0x68,0x09,0x48,0x03,0x40,
81 0x13,0x60,0x00,0xbd,0x24,0x80,0x0e,0x00,0x81,0x03,0x0f,0xfe,0x5c,0x00,0x0f,0x00,
82 0x60,0xfc,0x0e,0x00,0xfe,0xff,0x00,0x00,0xfc,0xfc,0x0e,0x00,0xff,0x9f,0x00,0x00,
83 0x30,0xfc,0x0e,0x00,0x7f,0xff,0x00,0x00
85 static u8_t bte_patch1[92] = {
86 0x07,0x20,0xbc,0x65,0x01,0x00,0x84,0x42,0x09,0xd2,0x84,0x42,0x09,0xd1,0x21,0x84,
87 0x5a,0x00,0x00,0x83,0xf0,0x74,0xff,0x09,0x0c,0x08,0x43,0x22,0x00,0x61,0x00,0x00,
88 0x83,0xf0,0x40,0xfc,0x00,0x00,0x00,0x00,0x23,0xcc,0x9f,0x01,0x00,0x6f,0xf0,0xe4,
89 0xfc,0x03,0x28,0x7d,0xd1,0x24,0x3c,0x62,0x01,0x00,0x28,0x20,0x00,0xe0,0x60,0x8d,
90 0x23,0x68,0x25,0x04,0x12,0x01,0x00,0x20,0x1c,0x20,0x1c,0x24,0xe0,0xb0,0x21,0x26,
91 0x74,0x2f,0x00,0x00,0x86,0xf0,0x18,0xfd,0x21,0x4f,0x3b,0x60
94 static u8 ppc_stack[STACKSIZE] ATTRIBUTE_ALIGN(8);
96 err_t acl_wlp_completed(void *arg,struct bd_addr *bdaddr);
97 err_t link_key_not(void *arg,struct bd_addr *bdaddr,u8_t *key);
98 err_t pin_req(void *arg,struct bd_addr *bdaddr);
99 err_t l2cap_connected(void *arg,struct l2cap_pcb *l2cappcb,u16_t result,u16_t status);
100 err_t l2cap_accepted(void *arg,struct l2cap_pcb *l2cappcb,err_t err);
101 err_t acl_conn_complete(void *arg,struct bd_addr *bdaddr);
102 err_t l2cap_disconnect_cfm(void *arg, struct l2cap_pcb *pcb);
103 err_t l2cap_disconnected_ind(void *arg, struct l2cap_pcb *pcb, err_t err);
105 err_t bte_input(void *arg,struct l2cap_pcb *pcb,struct pbuf *p,err_t err);
106 err_t bte_callback(void (*f)(void*),void *ctx);
107 err_t bte_hci_apply_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result);
108 err_t bte_hci_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result);
109 err_t bte_hci_initcore_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result);
110 err_t bte_hci_initsub_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result);
111 err_t bte_inquiry_complete(void *arg,struct hci_pcb *pcb,struct hci_inq_res *ires,u16_t result);
112 err_t bte_read_stored_link_key_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result);
114 MEMB(bte_pcbs,sizeof(struct bte_pcb),MEMP_NUM_BTE_PCB);
115 MEMB(bte_ctrl_reqs,sizeof(struct ctrl_req_t),MEMP_NUM_BTE_CTRLS);
117 static void bte_reset_all()
119 btmemb_init(&bte_pcbs);
120 btmemb_init(&bte_ctrl_reqs);
122 if(btstate.info!=NULL) free(btstate.info);
124 btstate.info = NULL;
125 btstate.hci_inited = 0;
126 btstate.hci_cmddone = 0;
127 btstate.num_founddevs = 0;
128 btstate.last_err = ERR_OK;
131 static void bt_alarmhandler(syswd_t alarm,void *cbarg)
133 __lwp_thread_dispatchdisable();
134 SYS_SwitchFiber(0,0,0,0,(u32)l2cap_tmr,(u32)(&ppc_stack[STACKSIZE]));
135 __lwp_thread_dispatchunnest();
138 static inline s32 __bte_waitcmdfinish(struct bt_state *state)
140 u32 level;
141 s32 ret;
143 if(!state) return ERR_VAL;
145 _CPU_ISR_Disable(level);
146 while(!state->hci_cmddone)
147 LWP_ThreadSleep(state->hci_cmdq);
148 ret = state->last_err;
149 _CPU_ISR_Restore(level);
151 return ret;
154 static inline s32 __bte_cmdfinish(struct bt_state *state,err_t err)
156 u32 level;
158 if(!state) return ERR_VAL;
160 _CPU_ISR_Disable(level);
161 state->last_err = err;
162 state->hci_cmddone = 1;
163 if(state->cb!=NULL)
164 state->cb(err,state->usrdata);
165 else
166 LWP_ThreadSignal(state->hci_cmdq);
167 _CPU_ISR_Restore(level);
169 return err;
172 static inline s32 __bte_waitrequest(struct ctrl_req_t *req)
174 s32 err;
175 u32 level;
177 if(!req || !req->pcb) return ERR_VAL;
179 _CPU_ISR_Disable(level);
180 while(req->state!=STATE_SENT
181 && req->state!=STATE_FAILED)
183 LWP_ThreadSleep(req->pcb->cmdq);
185 err = req->err;
186 _CPU_ISR_Restore(level);
188 return err;
191 static inline void __bte_close_ctrl_queue(struct bte_pcb *pcb)
193 struct ctrl_req_t *req;
195 while(pcb->ctrl_req_head!=NULL) {
196 req = pcb->ctrl_req_head;
197 req->err = ERR_CLSD;
198 req->state = STATE_DISCONNECTED;
199 if(req->sent!=NULL) {
200 req->sent(pcb->cbarg,pcb,ERR_CLSD);
201 btmemb_free(&bte_ctrl_reqs,req);
202 } else
203 LWP_ThreadSignal(pcb->cmdq);
205 pcb->ctrl_req_head = req->next;
207 pcb->ctrl_req_tail = NULL;
210 static s32 __bte_send_pending_request(struct bte_pcb *pcb)
212 s32 err;
213 struct ctrl_req_t *req;
215 if(pcb->ctrl_req_head==NULL) return ERR_OK;
216 if(pcb->state==STATE_DISCONNECTING || pcb->state==STATE_DISCONNECTED) return ERR_CLSD;
218 req = pcb->ctrl_req_head;
219 req->state = STATE_SENDING;
221 err = l2ca_datawrite(pcb->out_pcb,req->p);
222 btpbuf_free(req->p);
224 if(err!=ERR_OK) {
225 pcb->ctrl_req_head = req->next;
227 req->err = err;
228 req->state = STATE_FAILED;
229 if(req->sent) {
230 req->sent(pcb->cbarg,pcb,err);
231 btmemb_free(&bte_ctrl_reqs,req);
232 } else
233 LWP_ThreadSignal(pcb->cmdq);
236 return err;
239 static s32 __bte_send_request(struct ctrl_req_t *req)
241 s32 err;
242 u32 level;
244 req->next = NULL;
245 req->err = ERR_VAL;
246 req->state = STATE_READY;
248 _CPU_ISR_Disable(level);
249 if(req->pcb->ctrl_req_head==NULL) {
250 req->pcb->ctrl_req_head = req->pcb->ctrl_req_tail = req;
251 err = __bte_send_pending_request(req->pcb);
252 } else {
253 req->pcb->ctrl_req_tail->next = req;
254 req->pcb->ctrl_req_tail = req;
255 err = ERR_OK;
257 _CPU_ISR_Restore(level);
259 return err;
262 static err_t __bte_shutdown_finished(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
264 err_t err;
265 struct bt_state *state = (struct bt_state*)arg;
267 if(state==NULL) return ERR_OK;
269 state->hci_inited = 0;
270 hci_cmd_complete(NULL);
271 if(result==HCI_SUCCESS)
272 err = ERR_OK;
273 else
274 err = ERR_CONN;
276 physbusif_close();
277 return __bte_cmdfinish(state,err);
280 static void bte_process_handshake(struct bte_pcb *pcb,u8_t param,void *buf,u16_t len)
282 struct ctrl_req_t *req;
284 LOG("bte_process_handshake(%p)\n",pcb);
286 switch(param) {
287 case HIDP_HSHK_SUCCESSFULL:
288 req = pcb->ctrl_req_head;
289 pcb->ctrl_req_head = req->next;
291 req->err = ERR_OK;
292 req->state = STATE_SENT;
293 if(req->sent) {
294 req->sent(pcb->cbarg,pcb,ERR_OK);
295 btmemb_free(&bte_ctrl_reqs,req);
296 } else
297 LWP_ThreadSignal(pcb->cmdq);
299 __bte_send_pending_request(pcb);
300 break;
301 case HIDP_HSHK_NOTREADY:
302 case HIDP_HSHK_INV_REPORTID:
303 case HIDP_HSHK_NOTSUPPORTED:
304 case HIDP_HSHK_IVALIDPARAM:
305 case HIDP_HSHK_UNKNOWNERROR:
306 break;
307 case HIDP_HSHK_FATALERROR:
308 break;
309 default:
310 break;
314 static void bte_process_data(struct bte_pcb *pcb,u8_t param,void *buf,u16_t len)
316 LOG("bte_process_data(%p)\n",pcb);
317 switch(param) {
318 case HIDP_DATA_RTYPE_INPUT:
319 if(pcb->recv!=NULL) pcb->recv(pcb->cbarg,buf,len);
320 break;
321 case HIDP_DATA_RTYPE_OTHER:
322 case HIDP_DATA_RTYPE_OUPUT:
323 case HIDP_DATA_RTYPE_FEATURE:
324 break;
325 default:
326 break;
330 static err_t bte_process_input(void *arg,struct l2cap_pcb *pcb,struct pbuf *p,err_t err)
332 u8 *buf;
333 u16 len;
334 u8 hdr,type,param;
335 struct bte_pcb *bte = (struct bte_pcb*)arg;
337 LOG("bte_process_input(%p,%p)\n",bte,p);
339 if(bte->state==STATE_DISCONNECTING
340 || bte->state==STATE_DISCONNECTED) return ERR_CLSD;
342 buf = p->payload;
343 len = p->tot_len;
345 len--;
346 hdr = *buf++;
347 type = (hdr&HIDP_HDR_TRANS_MASK);
348 param = (hdr&HIDP_HDR_PARAM_MASK);
349 switch(type) {
350 case HIDP_TRANS_HANDSHAKE:
351 bte_process_handshake(bte,param,buf,len);
352 break;
353 case HIDP_TRANS_HIDCONTROL:
354 break;
355 case HIDP_TRANS_DATA:
356 bte_process_data(bte,param,buf,len);
357 break;
358 default:
359 break;
361 return ERR_OK;
364 void BTE_Init()
366 u32 level;
367 struct timespec tb;
369 LOG("BTE_Init()\n");
371 memset(&btstate,0,sizeof(struct bt_state));
373 hci_init();
374 l2cap_init();
375 physbusif_init();
377 LWP_InitQueue(&btstate.hci_cmdq);
378 SYS_CreateAlarm(&btstate.timer_svc);
380 _CPU_ISR_Disable(level);
381 bte_reset_all();
382 hci_reset_all();
383 l2cap_reset_all();
384 physbusif_reset_all();
386 hci_wlp_complete(acl_wlp_completed);
387 hci_connection_complete(acl_conn_complete);
388 _CPU_ISR_Restore(level);
390 tb.tv_sec = 1;
391 tb.tv_nsec = 0;
392 SYS_SetPeriodicAlarm(btstate.timer_svc,&tb,&tb,bt_alarmhandler, NULL);
395 void BTE_Shutdown()
397 u32 level;
399 if(btstate.hci_inited==0) return;
401 LOG("BTE_Shutdown()\n");
403 _CPU_ISR_Disable(level);
404 SYS_RemoveAlarm(btstate.timer_svc);
405 btstate.cb = NULL;
406 btstate.usrdata = NULL;
407 btstate.hci_cmddone = 0;
408 hci_arg(&btstate);
409 hci_cmd_complete(__bte_shutdown_finished);
410 hci_reset();
411 __bte_waitcmdfinish(&btstate);
412 _CPU_ISR_Restore(level);
414 physbusif_shutdown();
417 s32 BTE_InitCore(btecallback cb)
419 u32 level;
421 _CPU_ISR_Disable(level);
422 btstate.cb = cb;
423 btstate.usrdata = NULL;
424 btstate.hci_cmddone = 0;
425 hci_arg(&btstate);
426 hci_cmd_complete(bte_hci_initcore_complete);
427 hci_reset();
428 _CPU_ISR_Restore(level);
430 return ERR_OK;
433 s32 BTE_ApplyPatch(btecallback cb)
435 u32 level;
436 u8 kick = 0;
438 _CPU_ISR_Disable(level);
439 btstate.cb = cb;
440 btstate.usrdata = NULL;
441 btstate.hci_cmddone = 0;
442 hci_arg(&btstate);
443 hci_cmd_complete(bte_hci_apply_patch_complete);
444 hci_vendor_specific_command(HCI_VENDOR_PATCH_START_OCF,HCI_VENDOR_OGF,&kick,1);
445 _CPU_ISR_Restore(level);
447 return ERR_OK;
450 s32 BTE_InitSub(btecallback cb)
452 u32 level;
454 _CPU_ISR_Disable(level);
455 btstate.cb = cb;
456 btstate.usrdata = NULL;
457 btstate.hci_cmddone = 0;
458 hci_arg(&btstate);
459 hci_cmd_complete(bte_hci_initsub_complete);
460 hci_write_inquiry_mode(0x01);
461 _CPU_ISR_Restore(level);
463 return ERR_OK;
466 s32 BTE_ReadStoredLinkKey(struct linkkey_info *keys,u8 max_cnt,btecallback cb)
468 u32 level;
470 _CPU_ISR_Disable(level);
471 btstate.cb = cb;
472 btstate.usrdata = keys;
473 btstate.num_maxdevs = max_cnt;
474 btstate.hci_cmddone = 0;
475 hci_arg(&btstate);
476 hci_cmd_complete(bte_read_stored_link_key_complete);
477 hci_read_stored_link_key();
478 _CPU_ISR_Restore(level);
480 return ERR_OK;
483 void (*BTE_SetDisconnectCallback(void (*callback)(struct bd_addr *bdaddr,u8 reason)))(struct bd_addr *bdaddr,u8 reason)
485 return l2cap_disconnect_bb(callback);
488 struct bte_pcb* bte_new()
490 struct bte_pcb *pcb;
492 if((pcb=btmemb_alloc(&bte_pcbs))==NULL) return NULL;
494 memset(pcb,0,sizeof(struct bte_pcb));
496 pcb->state = (u32)STATE_NOTREADY;
497 LWP_InitQueue(&(pcb->cmdq));
499 return pcb;
502 s32 bte_registerdeviceasync(struct bte_pcb *pcb,struct bd_addr *bdaddr,s32 (*conn_cfm)(void *arg,struct bte_pcb *pcb,u8 err))
504 u32 level;
505 s32 err = ERR_OK;
506 struct l2cap_pcb *l2capcb = NULL;
508 //printf("bte_registerdeviceasync()\n");
509 _CPU_ISR_Disable(level);
510 pcb->err = ERR_USE;
511 pcb->in_pcb = NULL;
512 pcb->out_pcb = NULL;
513 pcb->conn_cfm = conn_cfm;
514 pcb->state = (u32)STATE_CONNECTING;
516 bd_addr_set(&(pcb->bdaddr),bdaddr);
517 if((l2capcb=l2cap_new())==NULL) {
518 err = ERR_MEM;
519 goto error;
521 l2cap_arg(l2capcb,pcb);
523 err = l2cap_connect_ind(l2capcb,bdaddr,HIDP_OUTPUT_CHANNEL,l2cap_accepted);
524 if(err!=ERR_OK) {
525 l2cap_close(l2capcb);
526 err = ERR_CONN;
527 goto error;
530 if((l2capcb=l2cap_new())==NULL) {
531 err = ERR_MEM;
532 goto error;
534 l2cap_arg(l2capcb,pcb);
536 err = l2cap_connect_ind(l2capcb,bdaddr,HIDP_INPUT_CHANNEL,l2cap_accepted);
537 if(err!=ERR_OK) {
538 l2cap_close(l2capcb);
539 err = ERR_CONN;
542 error:
543 _CPU_ISR_Restore(level);
544 //printf("bte_registerdeviceasync(%02x)\n",err);
545 return err;
548 s32 bte_inquiry(struct inquiry_info *info,u8 max_cnt,u8 flush)
550 s32_t i;
551 u32 level,fnd;
552 err_t last_err;
553 struct inquiry_info_ex *pinfo;
555 last_err = ERR_OK;
557 _CPU_ISR_Disable(level);
558 if(btstate.num_founddevs==0 || flush==1) {
559 btstate.hci_cmddone = 0;
560 btstate.num_maxdevs = max_cnt;
561 hci_inquiry(0x009E8B33,0x03,max_cnt,bte_inquiry_complete);
562 last_err = __bte_waitcmdfinish(&btstate);
564 fnd = btstate.num_founddevs;
565 pinfo = btstate.info;
566 _CPU_ISR_Restore(level);
568 if(last_err==ERR_OK) {
569 for(i=0;i<fnd && i<max_cnt;i++) {
570 bd_addr_set(&(info[i].bdaddr),&(pinfo[i].bdaddr));
571 memcpy(info[i].cod,pinfo[i].cod,3);
574 return (s32)((last_err==ERR_OK) ? fnd : last_err);
577 s32 bte_inquiry_ex(struct inquiry_info_ex *info,u8 max_cnt,u8 flush)
579 s32_t i;
580 u32 level,fnd;
581 err_t last_err;
582 struct inquiry_info_ex *pinfo;
584 last_err = ERR_OK;
586 _CPU_ISR_Disable(level);
587 if(btstate.num_founddevs==0 || flush==1) {
588 btstate.hci_cmddone = 0;
589 btstate.num_maxdevs = max_cnt;
590 hci_inquiry(0x009E8B33,0x03,max_cnt,bte_inquiry_complete);
591 last_err = __bte_waitcmdfinish(&btstate);
593 fnd = btstate.num_founddevs;
594 pinfo = btstate.info;
595 _CPU_ISR_Restore(level);
597 if(last_err==ERR_OK) {
598 for(i=0;i<fnd && i<max_cnt;i++) {
599 memcpy(info[i].cod,pinfo[i].cod,3);
600 bd_addr_set(&(info[i].bdaddr),&(pinfo[i].bdaddr));
601 info[i].psrm = pinfo[i].psrm;
602 info[i].psm = pinfo[i].psm;
603 info[i].co = pinfo[i].co;
606 return (s32)((last_err==ERR_OK) ? fnd : last_err);
609 s32 bte_disconnect(struct bte_pcb *pcb)
611 u32 level;
612 err_t err = ERR_OK;
614 if(pcb==NULL) return ERR_VAL;
616 _CPU_ISR_Disable(level);
617 pcb->state = (u32)STATE_DISCONNECTING;
618 if(pcb->in_pcb!=NULL )
619 err = l2ca_disconnect_req(pcb->in_pcb,l2cap_disconnect_cfm);
620 else if(pcb->out_pcb!=NULL)
621 err = l2ca_disconnect_req(pcb->out_pcb,l2cap_disconnect_cfm);
622 _CPU_ISR_Restore(level);
624 return err;
628 s32 bte_connect(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len))
630 u32 level;
631 err_t err = ERR_OK;
633 if(pcb==NULL) return ERR_VAL;
635 if((pcb->l2capcb=l2cap_new())==NULL) return ERR_MEM;
637 pcb->psm = psm;
638 pcb->recv = recv;
639 bd_addr_set(&(pcb->bdaddr),bdaddr);
641 _CPU_ISR_Disable(level);
642 pcb->err = ERR_CONN;
643 l2cap_arg(pcb->l2capcb,pcb);
644 err = l2ca_connect_req(pcb->l2capcb,bdaddr,psm,HCI_ALLOW_ROLE_SWITCH,l2cap_connected);
645 if(err==ERR_OK) {
646 LWP_ThreadSleep(pcb->cmdq);
647 err = pcb->err;
649 _CPU_ISR_Restore(level);
651 return err;
654 s32 bte_connect_ex(struct bte_pcb *pcb,struct inquiry_info_ex *info,u8 psm,s32 (*recv)(void *arg,void *buffer,u16 len))
656 err_t err;
658 if((err=hci_reg_dev_info(&(info->bdaddr),info->cod,info->psrm,info->psm,info->co))!=ERR_OK) return err;
659 return bte_connect(pcb,&(info->bdaddr),psm,recv);
662 s32 bte_listen(struct bte_pcb *pcb,struct bd_addr *bdaddr,u8 psm)
664 s32 err;
665 u32 level;
666 struct l2cap_pcb *l2capcb = NULL;
668 if(pcb==NULL) return ERR_VAL;
670 if((l2capcb=l2cap_new())==NULL) return ERR_MEM;
671 pcb->l2capcb = NULL;
673 pcb->psm = psm;
674 pcb->recv = NULL;
675 bd_addr_set(&(pcb->bdaddr),bdaddr);
677 _CPU_ISR_Disable(level);
678 pcb->err = ERR_CONN;
679 l2cap_arg(l2capcb,pcb);
680 err = l2cap_connect_ind(l2capcb,psm,l2cap_accepted);
681 if(err!=ERR_OK) l2cap_close(l2capcb);
683 _CPU_ISR_Restore(level);
684 return err;
687 s32 bte_accept(struct bte_pcb *pcb,s32 (*recv)(void *arg,void *buffer,u16 len))
689 u32 level;
690 err_t err = ERR_OK;
692 if(pcb==NULL) return ERR_VAL;
694 _CPU_ISR_Disable(level);
695 pcb->recv = recv;
696 while(pcb->l2capcb==NULL)
697 LWP_ThreadSleep(pcb->cmdq);
698 err = pcb->err;
699 _CPU_ISR_Restore(level);
701 return err;
705 s32 bte_senddata(struct bte_pcb *pcb,void *message,u16 len)
707 err_t err;
708 struct pbuf *p;
710 if(pcb==NULL || message==NULL || len==0) return ERR_VAL;
711 if(pcb->state==STATE_DISCONNECTING || pcb->state==STATE_DISCONNECTED) return ERR_CLSD;
713 if((p=btpbuf_alloc(PBUF_RAW,(1 + len),PBUF_RAM))==NULL) {
714 ERROR("bte_senddata: Could not allocate memory for pbuf\n");
715 return ERR_MEM;
718 ((u8*)p->payload)[0] = (HIDP_TRANS_DATA|HIDP_DATA_RTYPE_OUPUT);
719 memcpy(p->payload+1,message,len);
721 err = l2ca_datawrite(pcb->out_pcb,p);
722 btpbuf_free(p);
724 return err;
727 s32 bte_sendmessageasync(struct bte_pcb *pcb,void *message,u16 len,s32 (*sent)(void *arg,struct bte_pcb *pcb,u8 err))
729 struct pbuf *p;
730 struct ctrl_req_t *req;
732 //printf("bte_sendmessageasync()\n");
734 if(pcb==NULL || message==NULL || len==0) return ERR_VAL;
735 if(pcb->state==STATE_DISCONNECTING || pcb->state==STATE_DISCONNECTED) return ERR_CLSD;
737 if((req=btmemb_alloc(&bte_ctrl_reqs))==NULL) {
738 ERROR("bte_sendmessageasync: Could not allocate memory for request\n");
739 return ERR_MEM;
742 if((p=btpbuf_alloc(PBUF_RAW,(1 + len),PBUF_RAM))==NULL) {
743 ERROR("bte_sendmessageasync: Could not allocate memory for pbuf\n");
744 btmemb_free(&bte_ctrl_reqs,req);
745 return ERR_MEM;
748 ((u8*)p->payload)[0] = (HIDP_TRANS_SETREPORT|HIDP_DATA_RTYPE_OUPUT);
749 memcpy(p->payload+1,message,len);
751 req->p = p;
752 req->pcb = pcb;
753 req->sent = sent;
754 return __bte_send_request(req);
757 s32 bte_sendmessage(struct bte_pcb *pcb,void *message,u16 len)
759 s32 err = ERR_VAL;
760 struct pbuf *p;
761 struct ctrl_req_t *req;
763 //printf("bte_sendmessage()\n");
765 if(pcb==NULL || message==NULL || len==0) return ERR_VAL;
766 if(pcb->state==STATE_DISCONNECTING || pcb->state==STATE_DISCONNECTED) return ERR_CLSD;
768 if((req=btmemb_alloc(&bte_ctrl_reqs))==NULL) {
769 ERROR("bte_sendmessage: Could not allocate memory for request\n");
770 return ERR_MEM;
773 if((p=btpbuf_alloc(PBUF_RAW,(1 + len),PBUF_RAM))==NULL) {
774 ERROR("bte_sendmessage: Could not allocate memory for pbuf\n");
775 btmemb_free(&bte_ctrl_reqs,req);
776 return ERR_MEM;
779 ((u8*)p->payload)[0] = (HIDP_TRANS_SETREPORT|HIDP_DATA_RTYPE_OUPUT);
780 memcpy(p->payload+1,message,len);
782 req->p = p;
783 req->pcb = pcb;
784 req->sent = NULL;
785 err = __bte_send_request(req);
786 if(err==ERR_OK) err = __bte_waitrequest(req);
788 btmemb_free(&bte_ctrl_reqs,req);
789 return err;
792 void bte_arg(struct bte_pcb *pcb,void *arg)
794 u32 level;
795 _CPU_ISR_Disable(level);
796 pcb->cbarg = arg;
797 _CPU_ISR_Restore(level);
800 void bte_received(struct bte_pcb *pcb, s32 (*recv)(void *arg,void *buffer,u16 len))
802 u32 level;
803 _CPU_ISR_Disable(level);
804 pcb->recv = recv;
805 _CPU_ISR_Restore(level);
808 void bte_disconnected(struct bte_pcb *pcb,s32 (disconn_cfm)(void *arg,struct bte_pcb *pcb,u8 err))
810 u32 level;
811 _CPU_ISR_Disable(level);
812 pcb->disconn_cfm = disconn_cfm;
813 _CPU_ISR_Restore(level);
816 err_t acl_wlp_completed(void *arg,struct bd_addr *bdaddr)
818 //hci_sniff_mode(bdaddr,200,100,10,10);
819 return ERR_OK;
822 err_t acl_conn_complete(void *arg,struct bd_addr *bdaddr)
824 //printf("acl_conn_complete\n");
825 //memcpy(&(btstate.acl_bdaddr),bdaddr,6);
827 hci_write_link_policy_settings(bdaddr,0x0005);
828 return ERR_OK;
831 err_t pin_req(void *arg,struct bd_addr *bdaddr)
833 //printf("pin_req\n");
834 return ERR_OK;
837 err_t l2cap_disconnected_ind(void *arg, struct l2cap_pcb *pcb, err_t err)
839 struct bte_pcb *bte = (struct bte_pcb*)arg;
841 if(bte==NULL) return ERR_OK;
843 bte->state = (u32)STATE_DISCONNECTING;
844 switch(l2cap_psm(pcb)) {
845 case HIDP_OUTPUT_CHANNEL:
846 l2cap_close(bte->out_pcb);
847 bte->out_pcb = NULL;
848 break;
849 case HIDP_INPUT_CHANNEL:
850 l2cap_close(bte->in_pcb);
851 bte->in_pcb = NULL;
852 break;
854 if(bte->in_pcb==NULL && bte->out_pcb==NULL) {
855 bte->err = ERR_OK;
856 bte->state = (u32)STATE_DISCONNECTED;
857 __bte_close_ctrl_queue(bte);
858 if(bte->disconn_cfm!=NULL) bte->disconn_cfm(bte->cbarg,bte,ERR_OK);
860 return ERR_OK;
863 err_t l2cap_disconnect_cfm(void *arg, struct l2cap_pcb *pcb)
865 struct bte_pcb *bte = (struct bte_pcb*)arg;
867 if(bte==NULL) return ERR_OK;
869 switch(l2cap_psm(pcb)) {
870 case HIDP_OUTPUT_CHANNEL:
871 l2cap_close(bte->out_pcb);
872 bte->out_pcb = NULL;
873 if(bte->in_pcb!=NULL)
874 l2ca_disconnect_req(bte->in_pcb,l2cap_disconnect_cfm);
875 break;
876 case HIDP_INPUT_CHANNEL:
877 l2cap_close(bte->in_pcb);
878 bte->in_pcb = NULL;
879 if(bte->out_pcb!=NULL)
880 l2ca_disconnect_req(bte->out_pcb,l2cap_disconnect_cfm);
881 break;
883 if(bte->in_pcb==NULL && bte->out_pcb==NULL) {
884 bte->err = ERR_OK;
885 bte->state = (u32)STATE_DISCONNECTED;
886 __bte_close_ctrl_queue(bte);
887 if(bte->disconn_cfm!=NULL) bte->disconn_cfm(bte->cbarg,bte,ERR_OK);
889 hci_cmd_complete(NULL);
890 hci_disconnect(&(bte->bdaddr),HCI_OTHER_END_TERMINATED_CONN_USER_ENDED);
893 return ERR_OK;
896 err_t link_key_not(void *arg,struct bd_addr *bdaddr,u8_t *key)
898 //printf("link_key_not\n");
899 return hci_write_stored_link_key(bdaddr,key);
903 err_t l2cap_connected(void *arg,struct l2cap_pcb *l2cappcb,u16_t result,u16_t status)
905 struct bte_pcb *btepcb = (struct bte_pcb*)arg;
907 printf("l2cap_connected(%02x)\n",result);
908 if(result==L2CAP_CONN_SUCCESS) {
909 l2cap_recv(l2cappcb,bte_input);
910 l2cap_disconnect_ind(l2cappcb,l2cap_disconnected_ind);
911 btepcb->err = ERR_OK;
912 } else {
913 l2cap_close(l2cappcb);
914 btepcb->err = ERR_CONN;
917 if(btepcb->conn_cfm) btepcb->conn_cfm(btepcb->cbarg,btepcb,btepcb->err);
918 LWP_ThreadSignal(btepcb->cmdq);
919 return ERR_OK;
922 err_t l2cap_accepted(void *arg,struct l2cap_pcb *l2cappcb,err_t err)
924 struct bte_pcb *btepcb = (struct bte_pcb*)arg;
926 //printf("l2cap_accepted(%02x)\n",err);
927 if(err==ERR_OK) {
928 l2cap_recv(l2cappcb,bte_process_input);
929 l2cap_disconnect_ind(l2cappcb,l2cap_disconnected_ind);
930 switch(l2cap_psm(l2cappcb)) {
931 case HIDP_OUTPUT_CHANNEL:
932 btepcb->out_pcb = l2cappcb;
933 break;
934 case HIDP_INPUT_CHANNEL:
935 btepcb->in_pcb = l2cappcb;
936 break;
938 if(btepcb->in_pcb && btepcb->out_pcb) {
939 btepcb->err = ERR_OK;
940 btepcb->state = (u32)STATE_CONNECTED;
941 if(btepcb->conn_cfm) btepcb->conn_cfm(btepcb->cbarg,btepcb,ERR_OK);
943 } else {
944 l2cap_close(l2cappcb);
945 btepcb->err = ERR_CONN;
946 btepcb->conn_cfm(btepcb->cbarg,btepcb,ERR_CONN);
949 return ERR_OK;
952 err_t bte_inquiry_complete(void *arg,struct hci_pcb *pcb,struct hci_inq_res *ires,u16_t result)
954 u8_t i;
955 struct hci_inq_res *p;
956 struct bt_state *state = (struct bt_state*)arg;
958 if(result==HCI_SUCCESS) {
959 if(ires!=NULL) {
961 if(btstate.info!=NULL) free(btstate.info);
962 btstate.info = NULL;
963 btstate.num_maxdevs = 0;
964 btstate.num_founddevs = 0;
966 p = ires;
967 while(p!=NULL) {
968 btstate.num_founddevs++;
969 p = p->next;
972 p = ires;
973 btstate.info = (struct inquiry_info_ex*)malloc(sizeof(struct inquiry_info_ex)*btstate.num_founddevs);
974 for(i=0;i<btstate.num_founddevs && p!=NULL;i++) {
975 bd_addr_set(&(btstate.info[i].bdaddr),&(p->bdaddr));
976 memcpy(btstate.info[i].cod,p->cod,3);
977 btstate.info[i].psrm = p->psrm;
978 btstate.info[i].psm = p->psm;
979 btstate.info[i].co = p->co;
981 printf("bdaddr: %02x:%02x:%02x:%02x:%02x:%02x\n",p->bdaddr.addr[0],p->bdaddr.addr[1],p->bdaddr.addr[2],p->bdaddr.addr[3],p->bdaddr.addr[4],p->bdaddr.addr[5]);
982 printf("cod: %02x%02x%02x\n",p->cod[0],p->cod[1],p->cod[2]);
983 printf("psrm: %02x\n",p->psrm);
984 printf("psm: %02x\n",p->psm);
985 printf("co: %04x\n",p->co);
986 p = p->next;
988 __bte_cmdfinish(state,ERR_OK);
989 } else
990 hci_inquiry(0x009E8B33,0x03,btstate.num_maxdevs,bte_inquiry_complete);
992 return ERR_OK;
995 err_t bte_read_stored_link_key_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
997 u8_t i = 0;
998 struct hci_link_key *p;
999 struct linkkey_info *keys;
1000 struct bt_state *state = (struct bt_state*)arg;
1002 if(!pcb) return ERR_CONN;
1004 LOG("bte_read_stored_link_key_complete(%02x,%p)\n",result,pcb->keyres);
1006 if(state==NULL) return ERR_VAL;
1007 if(!(ogf==HCI_HC_BB_OGF && ocf==HCI_R_STORED_LINK_KEY_OCF)) return __bte_cmdfinish(state,ERR_CONN);
1009 if(result==HCI_SUCCESS) {
1010 keys = (struct linkkey_info*)state->usrdata;
1011 if(pcb->keyres!=NULL && keys!=NULL) {
1012 for(i=0,p=pcb->keyres;i<state->num_maxdevs && p!=NULL;i++) {
1013 bd_addr_set(&(keys[i].bdaddr),&(p->bdaddr));
1014 memcpy(keys[i].key,p->key,16);
1016 p = p->next;
1019 LOG("bte_read_stored_link_key_complete(%02x,%p,%d)\n",result,pcb->keyres,i);
1020 __bte_cmdfinish(state,i);
1021 return ERR_OK;
1024 return __bte_cmdfinish(state,ERR_VAL);
1026 /* new init with patching */
1027 err_t bte_hci_initcore_complete2(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1029 err_t err = ERR_OK;
1030 u8_t dev_cod[] = {0x04, 0x02,0x40};
1031 struct bt_state *state = (struct bt_state*)arg;
1033 LOG("bte_hci_initcore_complete2(%02x,%02x)\n",ogf,ocf);
1034 switch(ogf) {
1035 case HCI_HC_BB_OGF:
1036 if(ocf==HCI_WRITE_INQUIRY_MODE) {
1037 if(result==HCI_SUCCESS) {
1038 hci_write_page_scan_type(0x01);
1039 } else
1040 err = ERR_CONN;
1041 } else if(ocf==HCI_WRITE_PAGE_SCAN_TYPE) {
1042 if(result==HCI_SUCCESS) {
1043 hci_write_inquiry_scan_type(0x01);
1044 } else
1045 err = ERR_CONN;
1046 } else if(ocf==HCI_WRITE_INQUIRY_SCAN_TYPE) {
1047 if(result==HCI_SUCCESS) {
1048 hci_write_cod(dev_cod);
1049 } else
1050 err = ERR_CONN;
1051 } else if(ocf==HCI_WRITE_COD) {
1052 if(result==HCI_SUCCESS) {
1053 hci_write_page_timeout(0x2000);
1054 } else
1055 err = ERR_CONN;
1056 } else if(ocf==HCI_WRITE_PAGE_TIMEOUT) {
1057 if(result==HCI_SUCCESS) {
1058 state->hci_inited = 1;
1059 hci_cmd_complete(NULL);
1060 return __bte_cmdfinish(state,ERR_OK);
1061 } else
1062 err = ERR_CONN;
1064 break;
1065 default:
1066 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1067 err = ERR_CONN;
1068 break;
1071 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1072 return err;
1075 err_t bte_hci_initcore_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1077 err_t err = ERR_OK;
1078 u8_t dev_cod[] = {0x00, 0x1f,0x00};
1079 struct bt_state *state = (struct bt_state*)arg;
1081 LOG("bte_hci_initcore_complete(%02x,%02x)\n",ogf,ocf);
1082 switch(ogf) {
1083 case HCI_INFO_PARAM:
1084 if(ocf==HCI_READ_BUFFER_SIZE) {
1085 if(result==HCI_SUCCESS) {
1086 hci_write_cod(dev_cod);
1087 } else
1088 err = ERR_CONN;
1089 } else if(ocf==HCI_READ_LOCAL_VERSION) {
1090 if(result==HCI_SUCCESS) {
1091 hci_read_bd_addr();
1092 } else
1093 err = ERR_CONN;
1094 } else if(ocf==HCI_READ_BD_ADDR) {
1095 if(result==HCI_SUCCESS) {
1096 hci_read_local_features();
1097 } else
1098 err = ERR_CONN;
1099 } else if(ocf==HCI_READ_LOCAL_FEATURES) {
1100 if(result==HCI_SUCCESS) {
1101 hci_cmd_complete(bte_hci_initcore_complete2);
1102 hci_write_inquiry_mode(0x01);
1103 } else
1104 err = ERR_CONN;
1106 break;
1107 case HCI_HC_BB_OGF:
1108 if(ocf==HCI_RESET) {
1109 if(result==HCI_SUCCESS) {
1110 hci_read_buffer_size();
1111 } else
1112 err = ERR_CONN;
1113 } else if(ocf==HCI_WRITE_COD) {
1114 if(result==HCI_SUCCESS) {
1115 hci_write_local_name((u8_t*)"",1);
1116 } else
1117 err = ERR_CONN;
1118 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1119 if(result==HCI_SUCCESS) {
1120 hci_write_pin_type(0x00);
1121 } else
1122 err = ERR_CONN;
1123 } else if(ocf==HCI_WRITE_PIN_TYPE) {
1124 if(result==HCI_SUCCESS) {
1125 hci_host_buffer_size();
1126 } else
1127 err = ERR_CONN;
1128 } else if(ocf==HCI_HOST_BUF_SIZE) {
1129 if(result==HCI_SUCCESS) {
1130 hci_read_local_version();
1131 } else
1132 err = ERR_CONN;
1134 break;
1135 default:
1136 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1137 err = ERR_CONN;
1138 break;
1141 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1142 return err;
1145 err_t bte_hci_apply_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1147 err_t err = ERR_OK;
1148 struct bt_state *state = (struct bt_state*)arg;
1150 LOG("bte_hci_apply_patch_complete(%02x,%02x,%02x)\n",ogf,ocf,result);
1151 switch(ogf) {
1152 case HCI_VENDOR_OGF:
1153 if(ocf==HCI_VENDOR_PATCH_START_OCF) {
1154 if(result==HCI_SUCCESS) {
1155 err = hci_vendor_specific_command(HCI_VENDOR_PATCH_CONT_OCF,HCI_VENDOR_OGF,bte_patch0,184);
1156 } else
1157 err = ERR_CONN;
1158 } else if(ocf==HCI_VENDOR_PATCH_CONT_OCF) {
1159 if(result==HCI_SUCCESS) {
1160 hci_cmd_complete(bte_hci_patch_complete);
1161 err = hci_vendor_specific_command(HCI_VENDOR_PATCH_END_OCF,HCI_VENDOR_OGF,bte_patch1,92);
1162 } else
1163 err = ERR_CONN;
1165 break;
1166 default:
1167 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1168 err = ERR_CONN;
1169 break;
1172 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1173 return err;
1176 err_t bte_hci_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1178 err_t err = ERR_OK;
1179 u8_t dev_cod[] = {0x04, 0x02,0x40};
1180 struct bt_state *state = (struct bt_state*)arg;
1182 LOG("bte_hci_patch_complete(%02x,%02x,%02x)\n",ogf,ocf,result);
1183 switch(ogf) {
1184 case HCI_INFO_PARAM:
1185 if(ocf==HCI_READ_BUFFER_SIZE) {
1186 if(result==HCI_SUCCESS) {
1187 hci_write_cod(dev_cod);
1188 } else
1189 err = ERR_CONN;
1190 } else if(ocf==HCI_READ_LOCAL_VERSION) {
1191 if(result==HCI_SUCCESS) {
1192 hci_read_bd_addr();
1193 } else
1194 err = ERR_CONN;
1195 } else if(ocf==HCI_READ_BD_ADDR) {
1196 if(result==HCI_SUCCESS) {
1197 hci_read_local_features();
1198 } else
1199 err = ERR_CONN;
1200 } else if(ocf==HCI_READ_LOCAL_FEATURES) {
1201 if(result==HCI_SUCCESS) {
1202 hci_cmd_complete(NULL);
1203 return __bte_cmdfinish(state,ERR_OK);
1204 } else
1205 err = ERR_CONN;
1207 break;
1208 case HCI_HC_BB_OGF:
1209 if(ocf==HCI_RESET) {
1210 if(result==HCI_SUCCESS) {
1211 hci_read_buffer_size();
1212 } else
1213 err = ERR_CONN;
1214 } else if(ocf==HCI_WRITE_COD) {
1215 if(result==HCI_SUCCESS) {
1216 hci_write_local_name((u8_t*)"",1);
1217 } else
1218 err = ERR_CONN;
1219 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1220 if(result==HCI_SUCCESS) {
1221 hci_write_pin_type(0x00);
1222 } else
1223 err = ERR_CONN;
1224 } else if(ocf==HCI_WRITE_PIN_TYPE) {
1225 if(result==HCI_SUCCESS) {
1226 hci_host_buffer_size();
1227 } else
1228 err = ERR_CONN;
1229 } else if(ocf==HCI_HOST_BUF_SIZE) {
1230 if(result==HCI_SUCCESS) {
1231 hci_read_local_version();
1232 } else
1233 err = ERR_CONN;
1235 break;
1236 case HCI_VENDOR_OGF:
1237 if(ocf==HCI_VENDOR_PATCH_END_OCF) {
1238 if(result==HCI_SUCCESS) {
1239 err = hci_reset();
1240 } else
1241 err = ERR_CONN;
1243 break;
1244 default:
1245 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1246 err = ERR_CONN;
1247 break;
1250 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1251 return err;
1254 err_t bte_hci_initsub_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1256 err_t err = ERR_OK;
1257 u8_t dev_cod[] = {0x00, 0x04,0x48};
1258 struct bt_state *state = (struct bt_state*)arg;
1260 LOG("bte_hci_initsub_complete(%02x,%02x)\n",ogf,ocf);
1261 switch(ogf) {
1262 case HCI_HC_BB_OGF:
1263 if(ocf==HCI_WRITE_INQUIRY_MODE) {
1264 if(result==HCI_SUCCESS) {
1265 hci_write_page_scan_type(0x01);
1266 } else
1267 err = ERR_CONN;
1268 } else if(ocf==HCI_WRITE_PAGE_SCAN_TYPE) {
1269 if(result==HCI_SUCCESS) {
1270 hci_write_inquiry_scan_type(0x01);
1271 } else
1272 err = ERR_CONN;
1273 } else if(ocf==HCI_WRITE_INQUIRY_SCAN_TYPE) {
1274 if(result==HCI_SUCCESS) {
1275 hci_write_cod(dev_cod);
1276 } else
1277 err = ERR_CONN;
1278 } else if(ocf==HCI_WRITE_COD) {
1279 if(result==HCI_SUCCESS) {
1280 hci_write_page_timeout(0x8000);
1281 } else
1282 err = ERR_CONN;
1283 } else if(ocf==HCI_WRITE_PAGE_TIMEOUT) {
1284 if(result==HCI_SUCCESS) {
1285 hci_write_local_name((u8_t*)"Wii",4);
1286 } else
1287 err = ERR_CONN;
1288 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1289 if(result==HCI_SUCCESS) {
1290 hci_write_scan_enable(0x02);
1291 } else
1292 err = ERR_CONN;
1293 } else if(ocf==HCI_WRITE_SCAN_ENABLE) {
1294 if(result==HCI_SUCCESS) {
1295 hci_cmd_complete(NULL);
1296 return __bte_cmdfinish(state,ERR_OK);
1297 } else
1298 err = ERR_CONN;
1300 break;
1301 default:
1302 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1303 err = ERR_CONN;
1304 break;
1308 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1309 return err;