/* * Get the Bluetooth MAC address. * * The MAC may be found at one of several places, depending on the phone * model and the messages that rild processes. Try the following places, * in the order listed: * * - i_atnt and i_skt rild set system property service.brcm.bt.mac after * processing GET_IMEI/GET_IMEINV. This seems reliable. * * - i_vzw rild sets system property persist.service.brcm.bt.mac after * processing some unknown sequence of (possibly proprietary) messages. * So far, this has only been observed with the vendor framework. * * - oncrpc cmd 447 retrieves the MAC on i_vzw (but not i_atnt or i_skt). * Note the octets in the returned value are reversed. */ static int set_bt_mac(void) { FILE *fd; char machex[PROPERTY_VALUE_MAX]; unsigned char macbuf[8]; property_get("service.brcm.bt.mac", machex, ""); if (!machex[0]) { property_get("persist.service.brcm.bt.mac", machex, ""); } if (!machex[0]) { memset(macbuf, 0, sizeof(macbuf)); nv_cmd_remote(0, 447, &macbuf); if (is_macbuf_valid(macbuf)) { sprintf(machex, "%02x%02x%02x%02x%02x%02x", macbuf[5], macbuf[4], macbuf[3], macbuf[2], macbuf[1], macbuf[0]); } } if (!machex[0]) return -1; fd = fopen(BT_ADDR_FILE, "w"); fprintf(fd, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c\n", machex[0], machex[1], machex[2], machex[3], machex[4], machex[5], machex[6], machex[7], machex[8], machex[9], machex[10], machex[11]); fclose(fd); return 0; }
int main() { int fd1; FILE *fd; int macbyte; int i; char mMacAddr[PROPERTY_VALUE_MAX]; int mac[2] = { 0, }; property_get("service.brcm.bt.mac",mMacAddr,"010203040506"); fd = fopen("/data/misc/bd_addr","w"); fprintf(fd,"%c%c:%c%c:%c%c:%c%c:%c%c:%c%c\n",mMacAddr[0], mMacAddr[1], mMacAddr[2], mMacAddr[3], mMacAddr[4], mMacAddr[5], mMacAddr[6], mMacAddr[7], mMacAddr[8], mMacAddr[9], mMacAddr[10], mMacAddr[11]); fclose(fd); oncrpc_init(); oncrpc_task_start(); nv_cmd_remote(0,0x1246,&mac); if (mac[0] == 0) return 0; fd = fopen("/data/misc/wifi/config","w"); fprintf(fd,"cur_etheraddr=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", mac[0]&0xFF, (mac[0]&0xFF00) >> 8, (mac[0]&0xFF0000) >> 16, (mac[0]&0xFF000000) >> 24, mac[1]&0xFF, (mac[1]&0xFF00) >> 8); fclose(fd); return 0; }
static void get_bt_mac(unsigned char *buffer) { nv_item_type nv_item; int i; /* Read the BT MAC NV Item */ nv_cmd_remote(NV_READ_F, NV_BT_MAC_ADDRESS_I, &nv_item); /* Convert endianness (reverse the order). */ for (i = 0; i < MAC_SIZE; i++) buffer[(MAC_SIZE - 1) - i] = nv_item.mac_address[i]; }
/* * Get the wlan MAC from nv. This attempts to replicate the * wifi_read_mac_address function from the stock software */ static int set_wifi_mac(void) { FILE *fd; unsigned char macbuf[8]; memset(macbuf, 0, sizeof(macbuf)*sizeof(unsigned char)); nv_cmd_remote(0, 0x1246, &macbuf); if (!is_macbuf_valid(macbuf)) return -1; fd = fopen(WIFI_ADDR_FILE, "w"); fprintf(fd,"cur_etheraddr=%02x:%02x:%02x:%02x:%02x:%02x\n", macbuf[0], macbuf[1], macbuf[2], macbuf[3], macbuf[4], macbuf[5]); fclose(fd); return 0; }
/*=========================================================================== FUNCTION cmnv_read_wait DESCRIPTION Read an item from the NV memory. Note that NV reads are done in a synchronous fashion; that is, this function only returns after the NV read is done being serviced by the NV task. DEPENDENCIES mc_task_start() must have already been called. RETURN VALUE none SIDE EFFECTS none ===========================================================================*/ void cmnv_read_wait( nv_items_enum_type nv_item, /* NV item to read */ nv_item_type *data_ptr /* pointer to buffer to place data associated with the NV item */ ) { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ CM_ASSERT(data_ptr != NULL); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Prepare the NV read command */ cmnv_cmd_sync.item = nv_item; /* Item to read */ cmnv_cmd_sync.cmd = NV_READ_F; /* NV operation */ cmnv_cmd_sync.data_ptr = data_ptr; /* Read into this buffer */ cmnv_cmd_sync.tcb_ptr = rex_self(); /* Notify CM task when done */ cmnv_cmd_sync.sigs = CM_NV_SYNC_SIG;/* Signal with this sig when done */ cmnv_cmd_sync.done_q_ptr = NULL; /* Return cmd to NO Q when done */ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /* Read from NV by: ** 1. Clearing the NV signal ** 2. Queuing a read command to the NV task ** 3. Waiting for NV task to finish servicing the read command. */ (void) rex_clr_sigs( rex_self(), CM_NV_SYNC_SIG ); cmnv_cmd_sync.tcb_ptr = rex_self(); #ifdef FEATURE_NV_RPC_SUPPORT if (0 == std_strncmp ((cmnv_cmd_sync.tcb_ptr)->task_name,"ONCR", 4)) { (void)nv_cmd_remote(cmnv_cmd_sync.cmd, cmnv_cmd_sync.item, cmnv_cmd_sync.data_ptr ); } else #endif { nv_cmd( &cmnv_cmd_sync ); } cm_wait( CM_NV_SYNC_SIG ); (void) rex_clr_sigs( rex_self(), CM_NV_SYNC_SIG ); /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /* If NV read failed, substitute a default value. */ if( cmnv_cmd_sync.status != NV_DONE_S ) { CM_MSG_HIGH( "NV read failed, item=%d, stat=%d", cmnv_cmd_sync.item, cmnv_cmd_sync.status, 0 ); /*lint -save -e641 */ switch( cmnv_cmd_sync.item ) { case NV_PREF_MODE_I: /* If this target supports ACP, default the mode preference ** to automatic. Else, default mode preference to digital only. */ #ifdef FEATURE_ACP #error code not present #else data_ptr->pref_mode.mode = NV_MODE_DIGITAL_ONLY; #endif break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_SYSTEM_PREF_I: data_ptr->system_pref.sys = NV_SP_STANDARD; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_BAND_PREF_I: data_ptr->band_pref.band = (nv_band_pref_enum_type)CM_BAND_PREF_ANY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_BAND_PREF_16_31_I: data_ptr->band_pref.band = (nv_band_pref_enum_type)(CM_BAND_PREF_ANY >> 16) ; //(NV_BAND_PREF_ANY & 0xFFFF); break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_BAND_PREF_32_63_I: data_ptr->band_pref_32_63.band = (uint32)(CM_BAND_PREF_ANY >> 32 ); break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_ROAM_PREF_I: data_ptr->roam_pref.roam = NV_ROAM_PREF_ANY; break; #if (defined (FEATURE_HDR_HYBRID) || defined(FEATURE_HYBR_GW)) #error code not present #endif /* FEATURE_HDR_HYBRID */ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_CURR_NAM_I: data_ptr->curr_nam = (int)CM_NAM_1; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_FTM_MODE_I: #if defined( FEATURE_CDMA_800 ) || defined( FEATURE_CDMA_1900 ) data_ptr->ftm_mode = DMSS_MODE; #else data_ptr->ftm_mode = AMSS_MODE; #endif /* defined( FEATURE_CDMA_800 ) || defined( FEATURE_CDMA_1900 ) */ break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_AUTO_NAM_I: data_ptr->auto_nam = FALSE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_SRDA_ENABLED_I: data_ptr->srda_enabled = FALSE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_SEC_CODE_I: (void) memset( (byte*) data_ptr->sec_code.digits, '0', sizeof(data_ptr->sec_code.digits) ); return; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_ACQ_ORDER_PREF_I: #ifdef FEATURE_WCDMA #error code not present #else data_ptr->acq_order_pref.acq_order = CM_GW_ACQ_ORDER_PREF_GSM_WCDMA; #endif break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_NET_SEL_MODE_PREF_I: data_ptr->net_sel_mode_pref.net_sel_mode = CM_NETWORK_SEL_MODE_PREF_AUTOMATIC; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_SERVICE_DOMAIN_PREF_I: data_ptr->service_domain_pref.srv_domain = CM_SRV_DOMAIN_PREF_CS_ONLY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ #if (defined(FEATURE_UIM_RUIM) && defined(FEATURE_UIM_RUN_TIME_ENABLE)) case NV_RTRE_CONFIG_I: data_ptr->rtre_config = NV_RTRE_CONFIG_NV_ONLY; break; #endif /* (defined(FEATURE_UIM_RUIM) && defined(FEATURE_UIM_RUN_TIME_ENABLE)) */ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ #if ( defined(FEATURE_DUAL_SLOTS) ) case NV_UIM_CDMA_PREF_SLOT_I: data_ptr->uim_cdma_pref_slot = NV_UIM_SLOT_NONE; break; case NV_UIM_GSM_PREF_SLOT_I: data_ptr->uim_gsm_pref_slot = NV_UIM_SLOT_NONE; break; #endif /* ( defined(FEATURE_DUAL_SLOTS) ) */ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_PS_DATA_ORIG_PREF_I: data_ptr->ps_data_orig_pref = NV_PS_DATA_ORIG_PREF_ANY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_GSM_AMR_CALL_CONFIG_I: data_ptr->gsm_amr_call_config = FALSE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_PRL_PREF_I: data_ptr->prl_pref.prl = CM_PRL_PREF_ANY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_WLAN_TECH_PREF_I: data_ptr->wlan_tech_pref.tech_pref = CM_WLAN_TECH_PREF_ANY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_WLAN_BSS_TYPE_PREF_I: data_ptr->wlan_bss_type_pref.bss_type_pref = CM_WLAN_BSS_TYPE_PREF_ANY; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_WLAN_SCAN_PREF_I: data_ptr->wlan_scan_pref.scan_mode = CM_WLAN_SCAN_PREF_AUTO; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_WLAN_NET_SEL_MODE_PREF_I: data_ptr->wlan_net_sel_mode_pref.net_sel_mode = CM_NETWORK_SEL_MODE_PREF_AUTOMATIC; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_ACCOLC_I: (void) memset( (byte*) data_ptr->accolc.ACCOLCpClass, 0, sizeof( data_ptr->accolc.ACCOLCpClass) ); return; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ #ifdef FEATURE_DDTM_CNTL case NV_DDTM_SETTINGS_I: /* Return error, the calling function should write the ** correct values to NV */ data_ptr->ddtm_settings.num_srv_opt = CM_INVALID_DDTM_NUM_SRV_OPT; return; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_GPRS_ANITE_GCF_I: data_ptr->gprs_anite_gcf = FALSE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_UMTS_CALL_VT_CODEC_LIST_I: data_ptr->umts_call_vt_codec_list = FALSE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_MOB_CAI_REV_I: #if defined( FEATURE_CDMA_800 ) || defined( FEATURE_CDMA_1900 ) /* P_REV_IS2000 (6) is the default suggested by CP */ data_ptr->mob_cai_rev = P_REV_IS2000; #else data_ptr->mob_cai_rev = 0; #endif break; case NV_ENS_ENABLED_I: #if defined(FEATURE_GSM) || defined(FEATURE_WCDMA) #error code not present #endif break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_HOME_MCC_I: data_ptr->home_mcc = CM_INVALID_MOBILE_COUNTRY_CODE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_USR_SID_TO_MCC_ASSOC_TBL_I: data_ptr->usr_sid_to_mcc_assoc_tbl.tbl_len = 0; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_HS_BASED_PLUS_DIAL_SETTING_I: data_ptr->hs_based_plus_dial_setting = CM_HS_BASED_PLUS_DIAL_DISABLED; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_IMSI_MCC_I: data_ptr->imsi_mcc.imsi_mcc = CM_INVALID_MOBILE_COUNTRY_CODE; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ case NV_DISABLE_CM_CALL_TYPE_I: data_ptr->disable_cm_call_type = CM_CALL_TYPE_NONE_MASK; break; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ default: CM_SWITCH_ERR( "Unexpected NV item=%d",cmnv_cmd_sync.item,0,0 ); break; } /* switch */ /*lint -restore */ } /* if */
int main() { FILE *fd; struct termios ios; char sync_buf[256]; char *readbuf = sync_buf; char *mMacAddr; int old_flags; int wlanmac[2] = { 0, }; int modem=0; int retries=5; int read_bytes=-1; modem=open("/dev/smd0",O_RDWR); if (modem<=0) { return 1; } tcgetattr( modem, &ios ); ios.c_lflag = 0; tcsetattr( modem, TCSANOW, &ios ); old_flags = fcntl(modem, F_GETFL, 0); fcntl(modem, F_SETFL, old_flags | O_NONBLOCK); while (read_bytes < 0 && retries) { read_bytes = write(modem,"AT%BTAD\r",8); sleep(1); retries--; } if (read_bytes > 0) { retries = 5; read_bytes = -1; } while (read_bytes < 0 && retries) { read_bytes = read(modem,sync_buf,sizeof(sync_buf)); sleep(1); retries--; } if (read_bytes > 0) { /* Skip first echoed line */ while (read_bytes && *readbuf != '\n' && *readbuf !='\0') { readbuf++; read_bytes--; } /* Nothing left */ if (!read_bytes) { return 2; } /* Skip line break */ readbuf++; read_bytes--; /* Nothing left */ if (!read_bytes) { return 2; } mMacAddr = readbuf; while (*readbuf != '\r' && *readbuf != '\n' && *readbuf !='\0' && read_bytes) { readbuf++; read_bytes--; } *readbuf='\0'; close(modem); /* Do we have something ? */ if (strlen(mMacAddr)>2) { /* Chop off first and last chars */ *mMacAddr++; *--readbuf='\0'; } if (strlen(mMacAddr)==12) { fd = fopen("/data/misc/bd_addr","w"); fprintf(fd,"%c%c:%c%c:%c%c:%c%c:%c%c:%c%c\n",mMacAddr[0], mMacAddr[1], mMacAddr[2], mMacAddr[3], mMacAddr[4], mMacAddr[5], mMacAddr[6], mMacAddr[7], mMacAddr[8], mMacAddr[9], mMacAddr[10], mMacAddr[11]); fclose(fd); } } oncrpc_init(); oncrpc_task_start(); nv_cmd_remote(0,0x1246,&wlanmac); oncrpc_task_stop(); oncrpc_deinit(); if (wlanmac[0] == 0) return 0; fd = fopen("/data/misc/wifi/config","w"); fprintf(fd,"cur_etheraddr=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", wlanmac[0]&0xFF, (wlanmac[0]&0xFF00) >> 8, (wlanmac[0]&0xFF0000) >> 16, (wlanmac[0]&0xFF000000) >> 24, wlanmac[1]&0xFF, (wlanmac[1]&0xFF00) >> 8); fclose(fd); return 0; }