fix for DVDx v2 modchip users
[libogc.git] / lwbt / bte.c
blob0e6ec91926c253c65f932e127cea95e76371cae7
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 s32 err;
283 struct ctrl_req_t *req;
285 LOG("bte_process_handshake(%p)\n",pcb);
287 switch(param) {
288 case HIDP_HSHK_SUCCESSFULL:
289 req = pcb->ctrl_req_head;
290 pcb->ctrl_req_head = req->next;
292 req->err = ERR_OK;
293 req->state = STATE_SENT;
294 if(req->sent) {
295 req->sent(pcb->cbarg,pcb,ERR_OK);
296 btmemb_free(&bte_ctrl_reqs,req);
297 } else
298 LWP_ThreadSignal(pcb->cmdq);
300 err = __bte_send_pending_request(pcb);
301 break;
302 case HIDP_HSHK_NOTREADY:
303 case HIDP_HSHK_INV_REPORTID:
304 case HIDP_HSHK_NOTSUPPORTED:
305 case HIDP_HSHK_IVALIDPARAM:
306 case HIDP_HSHK_UNKNOWNERROR:
307 break;
308 case HIDP_HSHK_FATALERROR:
309 break;
310 default:
311 break;
315 static void bte_process_data(struct bte_pcb *pcb,u8_t param,void *buf,u16_t len)
317 LOG("bte_process_data(%p)\n",pcb);
318 switch(param) {
319 case HIDP_DATA_RTYPE_INPUT:
320 if(pcb->recv!=NULL) pcb->recv(pcb->cbarg,buf,len);
321 break;
322 case HIDP_DATA_RTYPE_OTHER:
323 case HIDP_DATA_RTYPE_OUPUT:
324 case HIDP_DATA_RTYPE_FEATURE:
325 break;
326 default:
327 break;
331 static err_t bte_process_input(void *arg,struct l2cap_pcb *pcb,struct pbuf *p,err_t err)
333 u8 *buf;
334 u16 len;
335 u8 hdr,type,param;
336 struct bte_pcb *bte = (struct bte_pcb*)arg;
338 LOG("bte_process_input(%p,%p)\n",bte,p);
340 if(bte->state==STATE_DISCONNECTING
341 || bte->state==STATE_DISCONNECTED) return ERR_CLSD;
343 buf = p->payload;
344 len = p->tot_len;
346 len--;
347 hdr = *buf++;
348 type = (hdr&HIDP_HDR_TRANS_MASK);
349 param = (hdr&HIDP_HDR_PARAM_MASK);
350 switch(type) {
351 case HIDP_TRANS_HANDSHAKE:
352 bte_process_handshake(bte,param,buf,len);
353 break;
354 case HIDP_TRANS_HIDCONTROL:
355 break;
356 case HIDP_TRANS_DATA:
357 bte_process_data(bte,param,buf,len);
358 break;
359 default:
360 break;
362 return ERR_OK;
365 void BTE_Init()
367 u32 level;
368 struct timespec tb;
370 LOG("BTE_Init()\n");
372 memset(&btstate,0,sizeof(struct bt_state));
374 hci_init();
375 l2cap_init();
376 physbusif_init();
378 LWP_InitQueue(&btstate.hci_cmdq);
379 SYS_CreateAlarm(&btstate.timer_svc);
381 _CPU_ISR_Disable(level);
382 bte_reset_all();
383 hci_reset_all();
384 l2cap_reset_all();
385 physbusif_reset_all();
387 hci_wlp_complete(acl_wlp_completed);
388 hci_connection_complete(acl_conn_complete);
389 _CPU_ISR_Restore(level);
391 tb.tv_sec = 1;
392 tb.tv_nsec = 0;
393 SYS_SetPeriodicAlarm(btstate.timer_svc,&tb,&tb,bt_alarmhandler, NULL);
396 void BTE_Shutdown()
398 u32 level;
400 if(btstate.hci_inited==0) return;
402 LOG("BTE_Shutdown()\n");
404 _CPU_ISR_Disable(level);
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 err_t err = ERR_OK;
866 struct bte_pcb *bte = (struct bte_pcb*)arg;
868 if(bte==NULL) return ERR_OK;
870 switch(l2cap_psm(pcb)) {
871 case HIDP_OUTPUT_CHANNEL:
872 l2cap_close(bte->out_pcb);
873 bte->out_pcb = NULL;
874 if(bte->in_pcb!=NULL) err = 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) err = l2ca_disconnect_req(bte->out_pcb,l2cap_disconnect_cfm);
880 break;
882 if(bte->in_pcb==NULL && bte->out_pcb==NULL) {
883 bte->err = ERR_OK;
884 bte->state = (u32)STATE_DISCONNECTED;
885 __bte_close_ctrl_queue(bte);
886 if(bte->disconn_cfm!=NULL) bte->disconn_cfm(bte->cbarg,bte,ERR_OK);
888 hci_cmd_complete(NULL);
889 hci_disconnect(&(bte->bdaddr),HCI_OTHER_END_TERMINATED_CONN_USER_ENDED);
892 return ERR_OK;
895 err_t link_key_not(void *arg,struct bd_addr *bdaddr,u8_t *key)
897 //printf("link_key_not\n");
898 return hci_write_stored_link_key(bdaddr,key);
902 err_t l2cap_connected(void *arg,struct l2cap_pcb *l2cappcb,u16_t result,u16_t status)
904 struct bte_pcb *btepcb = (struct bte_pcb*)arg;
906 printf("l2cap_connected(%02x)\n",result);
907 if(result==L2CAP_CONN_SUCCESS) {
908 l2cap_recv(l2cappcb,bte_input);
909 l2cap_disconnect_ind(l2cappcb,l2cap_disconnected_ind);
910 btepcb->err = ERR_OK;
911 } else {
912 l2cap_close(l2cappcb);
913 btepcb->err = ERR_CONN;
916 if(btepcb->conn_cfm) btepcb->conn_cfm(btepcb->cbarg,btepcb,btepcb->err);
917 LWP_ThreadSignal(btepcb->cmdq);
918 return ERR_OK;
921 err_t l2cap_accepted(void *arg,struct l2cap_pcb *l2cappcb,err_t err)
923 struct bte_pcb *btepcb = (struct bte_pcb*)arg;
925 //printf("l2cap_accepted(%02x)\n",err);
926 if(err==ERR_OK) {
927 l2cap_recv(l2cappcb,bte_process_input);
928 l2cap_disconnect_ind(l2cappcb,l2cap_disconnected_ind);
929 switch(l2cap_psm(l2cappcb)) {
930 case HIDP_OUTPUT_CHANNEL:
931 btepcb->out_pcb = l2cappcb;
932 break;
933 case HIDP_INPUT_CHANNEL:
934 btepcb->in_pcb = l2cappcb;
935 break;
937 if(btepcb->in_pcb && btepcb->out_pcb) {
938 btepcb->err = ERR_OK;
939 btepcb->state = (u32)STATE_CONNECTED;
940 if(btepcb->conn_cfm) btepcb->conn_cfm(btepcb->cbarg,btepcb,ERR_OK);
942 } else {
943 l2cap_close(l2cappcb);
944 btepcb->err = ERR_CONN;
945 btepcb->conn_cfm(btepcb->cbarg,btepcb,ERR_CONN);
948 return ERR_OK;
951 err_t bte_inquiry_complete(void *arg,struct hci_pcb *pcb,struct hci_inq_res *ires,u16_t result)
953 u8_t i;
954 struct hci_inq_res *p;
955 struct bt_state *state = (struct bt_state*)arg;
957 if(result==HCI_SUCCESS) {
958 if(ires!=NULL) {
960 if(btstate.info!=NULL) free(btstate.info);
961 btstate.info = NULL;
962 btstate.num_maxdevs = 0;
963 btstate.num_founddevs = 0;
965 p = ires;
966 while(p!=NULL) {
967 btstate.num_founddevs++;
968 p = p->next;
971 p = ires;
972 btstate.info = (struct inquiry_info_ex*)malloc(sizeof(struct inquiry_info_ex)*btstate.num_founddevs);
973 for(i=0;i<btstate.num_founddevs && p!=NULL;i++) {
974 bd_addr_set(&(btstate.info[i].bdaddr),&(p->bdaddr));
975 memcpy(btstate.info[i].cod,p->cod,3);
976 btstate.info[i].psrm = p->psrm;
977 btstate.info[i].psm = p->psm;
978 btstate.info[i].co = p->co;
980 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]);
981 printf("cod: %02x%02x%02x\n",p->cod[0],p->cod[1],p->cod[2]);
982 printf("psrm: %02x\n",p->psrm);
983 printf("psm: %02x\n",p->psm);
984 printf("co: %04x\n",p->co);
985 p = p->next;
987 __bte_cmdfinish(state,ERR_OK);
988 } else
989 hci_inquiry(0x009E8B33,0x03,btstate.num_maxdevs,bte_inquiry_complete);
991 return ERR_OK;
994 err_t bte_read_stored_link_key_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
996 u8_t i = 0;
997 struct hci_link_key *p;
998 struct linkkey_info *keys;
999 struct bt_state *state = (struct bt_state*)arg;
1001 if(!pcb) return ERR_CONN;
1003 LOG("bte_read_stored_link_key_complete(%02x,%p)\n",result,pcb->keyres);
1005 if(state==NULL) return ERR_VAL;
1006 if(!(ogf==HCI_HC_BB_OGF && ocf==HCI_R_STORED_LINK_KEY_OCF)) return __bte_cmdfinish(state,ERR_CONN);
1008 if(result==HCI_SUCCESS) {
1009 keys = (struct linkkey_info*)state->usrdata;
1010 if(pcb->keyres!=NULL && keys!=NULL) {
1011 for(i=0,p=pcb->keyres;i<state->num_maxdevs && p!=NULL;i++) {
1012 bd_addr_set(&(keys[i].bdaddr),&(p->bdaddr));
1013 memcpy(keys[i].key,p->key,16);
1015 p = p->next;
1018 LOG("bte_read_stored_link_key_complete(%02x,%p,%d)\n",result,pcb->keyres,i);
1019 __bte_cmdfinish(state,i);
1020 return ERR_OK;
1023 return __bte_cmdfinish(state,ERR_VAL);
1025 /* new init with patching */
1026 err_t bte_hci_initcore_complete2(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1028 err_t err = ERR_OK;
1029 u8_t dev_cod[] = {0x04, 0x02,0x40};
1030 struct bt_state *state = (struct bt_state*)arg;
1032 LOG("bte_hci_initcore_complete2(%02x,%02x)\n",ogf,ocf);
1033 switch(ogf) {
1034 case HCI_HC_BB_OGF:
1035 if(ocf==HCI_WRITE_INQUIRY_MODE) {
1036 if(result==HCI_SUCCESS) {
1037 hci_write_page_scan_type(0x01);
1038 } else
1039 err = ERR_CONN;
1040 } else if(ocf==HCI_WRITE_PAGE_SCAN_TYPE) {
1041 if(result==HCI_SUCCESS) {
1042 hci_write_inquiry_scan_type(0x01);
1043 } else
1044 err = ERR_CONN;
1045 } else if(ocf==HCI_WRITE_INQUIRY_SCAN_TYPE) {
1046 if(result==HCI_SUCCESS) {
1047 hci_write_cod(dev_cod);
1048 } else
1049 err = ERR_CONN;
1050 } else if(ocf==HCI_WRITE_COD) {
1051 if(result==HCI_SUCCESS) {
1052 hci_write_page_timeout(0x2000);
1053 } else
1054 err = ERR_CONN;
1055 } else if(ocf==HCI_WRITE_PAGE_TIMEOUT) {
1056 if(result==HCI_SUCCESS) {
1057 state->hci_inited = 1;
1058 hci_cmd_complete(NULL);
1059 return __bte_cmdfinish(state,ERR_OK);
1060 } else
1061 err = ERR_CONN;
1063 break;
1064 default:
1065 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1066 err = ERR_CONN;
1067 break;
1070 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1071 return err;
1074 err_t bte_hci_initcore_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1076 err_t err = ERR_OK;
1077 u8_t dev_cod[] = {0x00, 0x1f,0x00};
1078 struct bt_state *state = (struct bt_state*)arg;
1080 LOG("bte_hci_initcore_complete(%02x,%02x)\n",ogf,ocf);
1081 switch(ogf) {
1082 case HCI_INFO_PARAM:
1083 if(ocf==HCI_READ_BUFFER_SIZE) {
1084 if(result==HCI_SUCCESS) {
1085 hci_write_cod(dev_cod);
1086 } else
1087 err = ERR_CONN;
1088 } else if(ocf==HCI_READ_LOCAL_VERSION) {
1089 if(result==HCI_SUCCESS) {
1090 hci_read_bd_addr();
1091 } else
1092 err = ERR_CONN;
1093 } else if(ocf==HCI_READ_BD_ADDR) {
1094 if(result==HCI_SUCCESS) {
1095 hci_read_local_features();
1096 } else
1097 err = ERR_CONN;
1098 } else if(ocf==HCI_READ_LOCAL_FEATURES) {
1099 if(result==HCI_SUCCESS) {
1100 hci_cmd_complete(bte_hci_initcore_complete2);
1101 hci_write_inquiry_mode(0x01);
1102 } else
1103 err = ERR_CONN;
1105 break;
1106 case HCI_HC_BB_OGF:
1107 if(ocf==HCI_RESET) {
1108 if(result==HCI_SUCCESS) {
1109 hci_read_buffer_size();
1110 } else
1111 err = ERR_CONN;
1112 } else if(ocf==HCI_WRITE_COD) {
1113 if(result==HCI_SUCCESS) {
1114 hci_write_local_name((u8_t*)"",1);
1115 } else
1116 err = ERR_CONN;
1117 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1118 if(result==HCI_SUCCESS) {
1119 hci_write_pin_type(0x00);
1120 } else
1121 err = ERR_CONN;
1122 } else if(ocf==HCI_WRITE_PIN_TYPE) {
1123 if(result==HCI_SUCCESS) {
1124 hci_host_buffer_size();
1125 } else
1126 err = ERR_CONN;
1127 } else if(ocf==HCI_HOST_BUF_SIZE) {
1128 if(result==HCI_SUCCESS) {
1129 hci_read_local_version();
1130 } else
1131 err = ERR_CONN;
1133 break;
1134 default:
1135 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1136 err = ERR_CONN;
1137 break;
1140 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1141 return err;
1144 err_t bte_hci_apply_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1146 err_t err = ERR_OK;
1147 struct bt_state *state = (struct bt_state*)arg;
1149 LOG("bte_hci_apply_patch_complete(%02x,%02x,%02x)\n",ogf,ocf,result);
1150 switch(ogf) {
1151 case HCI_VENDOR_OGF:
1152 if(ocf==HCI_VENDOR_PATCH_START_OCF) {
1153 if(result==HCI_SUCCESS) {
1154 err = hci_vendor_specific_command(HCI_VENDOR_PATCH_CONT_OCF,HCI_VENDOR_OGF,bte_patch0,184);
1155 } else
1156 err = ERR_CONN;
1157 } else if(ocf==HCI_VENDOR_PATCH_CONT_OCF) {
1158 if(result==HCI_SUCCESS) {
1159 hci_cmd_complete(bte_hci_patch_complete);
1160 err = hci_vendor_specific_command(HCI_VENDOR_PATCH_END_OCF,HCI_VENDOR_OGF,bte_patch1,92);
1161 } else
1162 err = ERR_CONN;
1164 break;
1165 default:
1166 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1167 err = ERR_CONN;
1168 break;
1171 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1172 return err;
1175 err_t bte_hci_patch_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1177 err_t err = ERR_OK;
1178 u8_t dev_cod[] = {0x04, 0x02,0x40};
1179 struct bt_state *state = (struct bt_state*)arg;
1181 LOG("bte_hci_patch_complete(%02x,%02x,%02x)\n",ogf,ocf,result);
1182 switch(ogf) {
1183 case HCI_INFO_PARAM:
1184 if(ocf==HCI_READ_BUFFER_SIZE) {
1185 if(result==HCI_SUCCESS) {
1186 hci_write_cod(dev_cod);
1187 } else
1188 err = ERR_CONN;
1189 } else if(ocf==HCI_READ_LOCAL_VERSION) {
1190 if(result==HCI_SUCCESS) {
1191 hci_read_bd_addr();
1192 } else
1193 err = ERR_CONN;
1194 } else if(ocf==HCI_READ_BD_ADDR) {
1195 if(result==HCI_SUCCESS) {
1196 hci_read_local_features();
1197 } else
1198 err = ERR_CONN;
1199 } else if(ocf==HCI_READ_LOCAL_FEATURES) {
1200 if(result==HCI_SUCCESS) {
1201 hci_cmd_complete(NULL);
1202 return __bte_cmdfinish(state,ERR_OK);
1203 } else
1204 err = ERR_CONN;
1206 break;
1207 case HCI_HC_BB_OGF:
1208 if(ocf==HCI_RESET) {
1209 if(result==HCI_SUCCESS) {
1210 hci_read_buffer_size();
1211 } else
1212 err = ERR_CONN;
1213 } else if(ocf==HCI_WRITE_COD) {
1214 if(result==HCI_SUCCESS) {
1215 hci_write_local_name((u8_t*)"",1);
1216 } else
1217 err = ERR_CONN;
1218 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1219 if(result==HCI_SUCCESS) {
1220 hci_write_pin_type(0x00);
1221 } else
1222 err = ERR_CONN;
1223 } else if(ocf==HCI_WRITE_PIN_TYPE) {
1224 if(result==HCI_SUCCESS) {
1225 hci_host_buffer_size();
1226 } else
1227 err = ERR_CONN;
1228 } else if(ocf==HCI_HOST_BUF_SIZE) {
1229 if(result==HCI_SUCCESS) {
1230 hci_read_local_version();
1231 } else
1232 err = ERR_CONN;
1234 break;
1235 case HCI_VENDOR_OGF:
1236 if(ocf==HCI_VENDOR_PATCH_END_OCF) {
1237 if(result==HCI_SUCCESS) {
1238 err = hci_reset();
1239 } else
1240 err = ERR_CONN;
1242 break;
1243 default:
1244 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1245 err = ERR_CONN;
1246 break;
1249 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1250 return err;
1253 err_t bte_hci_initsub_complete(void *arg,struct hci_pcb *pcb,u8_t ogf,u8_t ocf,u8_t result)
1255 err_t err = ERR_OK;
1256 u8_t dev_cod[] = {0x00, 0x04,0x48};
1257 struct bt_state *state = (struct bt_state*)arg;
1259 LOG("bte_hci_initsub_complete(%02x,%02x)\n",ogf,ocf);
1260 switch(ogf) {
1261 case HCI_HC_BB_OGF:
1262 if(ocf==HCI_WRITE_INQUIRY_MODE) {
1263 if(result==HCI_SUCCESS) {
1264 hci_write_page_scan_type(0x01);
1265 } else
1266 err = ERR_CONN;
1267 } else if(ocf==HCI_WRITE_PAGE_SCAN_TYPE) {
1268 if(result==HCI_SUCCESS) {
1269 hci_write_inquiry_scan_type(0x01);
1270 } else
1271 err = ERR_CONN;
1272 } else if(ocf==HCI_WRITE_INQUIRY_SCAN_TYPE) {
1273 if(result==HCI_SUCCESS) {
1274 hci_write_cod(dev_cod);
1275 } else
1276 err = ERR_CONN;
1277 } else if(ocf==HCI_WRITE_COD) {
1278 if(result==HCI_SUCCESS) {
1279 hci_write_page_timeout(0x8000);
1280 } else
1281 err = ERR_CONN;
1282 } else if(ocf==HCI_WRITE_PAGE_TIMEOUT) {
1283 if(result==HCI_SUCCESS) {
1284 hci_write_local_name((u8_t*)"Wii",4);
1285 } else
1286 err = ERR_CONN;
1287 } else if(ocf==HCI_WRITE_LOCAL_NAME) {
1288 if(result==HCI_SUCCESS) {
1289 hci_write_scan_enable(0x02);
1290 } else
1291 err = ERR_CONN;
1292 } else if(ocf==HCI_WRITE_SCAN_ENABLE) {
1293 if(result==HCI_SUCCESS) {
1294 hci_cmd_complete(NULL);
1295 return __bte_cmdfinish(state,ERR_OK);
1296 } else
1297 err = ERR_CONN;
1299 break;
1300 default:
1301 LOG("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf);
1302 err = ERR_CONN;
1303 break;
1307 if(err!=ERR_OK) __bte_cmdfinish(state,err);
1308 return err;