淺談MTK平臺用Socket實現(xiàn)HTTP請求過程
MTK平臺用Socket實現(xiàn)HTTP請求過程是本文要介紹的內(nèi)容,主要是來了解并學(xué)習(xí)MTK平臺的應(yīng)用,通過MTK平臺中數(shù)據(jù)的請求的案例,來學(xué)習(xí)MTK平臺的應(yīng)用,具體內(nèi)容的實現(xiàn)來看本文詳解。
一、MTK平臺Socket聯(lián)網(wǎng)過程
熟悉PC機編程的人都知道,Socket編程接口分兩套:TCP和UDP;TCP和UDP中又有服務(wù)器端和客戶端的概念,這里講的是TCP的客戶端編程接口。
MTK平臺中Socket創(chuàng)建步驟:
1、soc_create()創(chuàng)建Socket;
2、soc_setsockopt設(shè)置Socket為非阻塞模式;
3、soc_setsockopt設(shè)置Socket選項為連接,讀,寫,關(guān)閉;不清楚為什么要連續(xù)設(shè)置兩次;
4、如果是CMNET聯(lián)網(wǎng)并且請求中用到了英文域名還需要解析域名soc_gethostbyname,除非使用ip作為域名,解析出來的IP作為我們建立連接的目標(biāo)IP;如果是CMWAP聯(lián)網(wǎng),直接跳到第5步,直接連接移動或聯(lián)通的網(wǎng)關(guān):10.0.0.172:80;
5、soc_connect與服務(wù)器建立連接;
6、soc_send發(fā)送請求;
7、soc_recv接收服務(wù)器返回的數(shù)據(jù);
8、soc_close關(guān)閉Socket;
9、如果需要關(guān)閉數(shù)據(jù)賬戶soc_close_nwk_account
二、CMNET,CMWAP方式下的HTTP請求內(nèi)容格式
HTTP請求格式:
GET方法
MTK平臺中模擬器里wap瀏覽器發(fā)送的請求內(nèi)容
- “GET/go_13596557HTTP/1.1
- Host:kong.net
- User-Agent:SQH_D480B_01/LB19504/WAP2.0Profile
- Accept:application/vnd.wap.wmlc,**//(想當(dāng)長,省去后面部分)
- Accept-Charset:utf-8,utf-16,iso-8859-1,iso-10646-ucs-2,GB2312,windows-1252,us-ascii
- Accept-Language:zh-tw,zh-cn,en
- Cookie:JSESSIONID=aAQP0FIXp3z7
- Connection:Keep-Alive
- ”
POST方法
對一些需要向服務(wù)器傳入?yún)?shù)的請求,按名稱搜索等請求。還以空中網(wǎng)天氣查詢?yōu)槔械钠渌鞘刑鞖獠樵?,輸入其他城市名稱或電話區(qū)號查詢:
- “POST/weather/search.jsp?setcity=1HTTP/1.1
- Host:kong.net
- User-Agent:SQH_D480B_01/LB19504/WAP2.0Profile
- Accept:application/vnd.wap.wmlc,*/*//(想當(dāng)長,省去后面部分)
- Accept-Charset:utf-8,utf-16,iso-8859-1,iso-10646-ucs-2,GB2312,windows-1252,us-ascii
- Accept-Language:zh-tw,zh-cn,en
- Content-Type:application/x-www-form-urlencoded;charset=utf-8
- Cookie:KONG_ACCESS=AWYZhg==;JSESSIONID=a91MDc6qoMYf
- Connection:Keep-Alive
- Content-Length:46//get方法沒有這一項
- ××××××//傳給服務(wù)器46字節(jié)長的數(shù)據(jù)(參數(shù))
- ”
當(dāng)然如果是CMWAP聯(lián)網(wǎng)方式也要和上述的GET方法一樣設(shè)置Host和X-Online-Host項,Host:10.0.0.172
- X-Online-Host:kong.net
以上的內(nèi)容,可以在調(diào)試狀態(tài)下運行模擬器的wap瀏覽器,在soc_send方法處插入斷點觀察。
#p#
三、CMNET,CMWAP連接差別
1、GPRS賬戶:
與pc機上的socket客戶端接口不同,手機客戶端在soc_create,soc_gethostbyname接口中都多了參數(shù)nwt_acount_id,只的是一般在“網(wǎng)絡(luò)服務(wù)”->“數(shù)據(jù)賬戶”->“GPRS”下的GPRS數(shù)據(jù)賬戶id,一般起始的一個賬戶id是10,往下遞增1,在建立連接過程中,如果是CMWAP方式聯(lián)網(wǎng),soc_create,soc_gethostbyname接口就要設(shè)置接入點為CMWAP的賬戶id,CMNET就要設(shè)置接入點為CMNET的賬戶。
2、目標(biāo)服務(wù)器:
還以空中網(wǎng)的天氣服務(wù)為例,CMNET情況下,soc_connect需要連接”221.179.172.2”這個ip,如果請求的url為”http://kong.net/weather/home.jsp”,還需要調(diào)用soc_gethostbyname接口去解析域名;
如果是CMWAP方式聯(lián)網(wǎng),soc_connect只需要連接移動或聯(lián)動的網(wǎng)關(guān)”10.0.0.172:80”。
3、HTTP請求內(nèi)容格式(或稱報文):
如第二節(jié)所述。
四、SIM1還是SIM2聯(lián)網(wǎng)
SIM1還是SIM2聯(lián)網(wǎng),MTK平臺是通過創(chuàng)建socket時傳入的nwt_acount_id區(qū)分的,如果是SIM1上網(wǎng),賬號就是指的是一般在“網(wǎng)絡(luò)服務(wù)”->“數(shù)據(jù)賬戶”->“GPRS”下的對應(yīng)的GPRS數(shù)據(jù)賬戶id;如果是SIM2,通過在四字節(jié)的賬戶id其他字節(jié)設(shè)置掩碼來區(qū)分。
設(shè)置接口比如07B平臺的always_ask_encode_data_account_id,6235_08A的cbm_encode_data_account_id接口。不同MTK平臺可能略有差別。
五、聯(lián)通卡還是移動卡?
參考其他Socket聯(lián)網(wǎng)代碼中有的以接入點是否為”uniwap”來判斷是不是聯(lián)通的代理上網(wǎng),但是通過實驗,即使在聯(lián)通卡時連接移動的”cmwap”賬戶,也是可以正常聯(lián)網(wǎng)的。不知道設(shè)計“GPRS數(shù)據(jù)賬戶”的最初意圖是什么?通過apn來區(qū)分同一內(nèi)部ip地址網(wǎng)關(guān)不同的公網(wǎng)ip嗎?如有高人路過,請指點;
六、HTTP1.1與Transfer-Encoding為chunked的編碼方式
發(fā)送一個請求后,如果服務(wù)器返回的消息頭內(nèi)容包括“Transfer-Encoding:chunked”那么他的傳輸編碼為“chunked”類型。這種傳輸類型的數(shù)據(jù)體內(nèi)容格式是這樣:
[16進制數(shù)字字符串1到4個字節(jié)len]\r\n
[len長的數(shù)據(jù)體]\r\n
[16進制數(shù)字字符串1到4個字節(jié)len]\r\n
[len長的數(shù)據(jù)體]\r\n
[16進制數(shù)字字符串1到4個字節(jié)len==0]\r\n\r\n
其中,長度len是16進制的數(shù)字,表示本段數(shù)據(jù)體的長度(字節(jié)數(shù)),回車換行后,就是這一段數(shù)據(jù)真實內(nèi)容,這就是一段數(shù)據(jù)體的格式,一段接一段;直到數(shù)據(jù)體長度為0的數(shù)據(jù)段出現(xiàn),緊接著兩個回車換行,標(biāo)識本次請求的數(shù)據(jù)均已接收完畢。不過socket可以根據(jù)soc_recv返回值等于0來判斷接收數(shù)據(jù)結(jié)束。如果收到的是這個編碼類型的內(nèi)容,需要對接收到的數(shù)據(jù)進行處理。
七、MTK平臺的S8類型的誤導(dǎo)
MTK平臺定義的兩個數(shù)據(jù)類型U8和S8,一看名稱我們可能會以為是unsignedchar和signedchar,但事實并非如此,
- typedefcharS8;
- typedefunsignedcharU8;
MTK平臺的char默認(rèn)也是unsignedchar類型的,soc_gethostbyname返回值類型是kal_int8(typedefsignedcharkal_int8;),如果S8或平臺的char類型是有符號的字符型,那么,kal_int8和S8應(yīng)該是等價的,但用S8類型變量作為soc_gethostbyname的返回值時,經(jīng)常返回254導(dǎo)致域名不會被正常解析,其實應(yīng)該返回SOC_WOULDBLOCK(-2),應(yīng)該是阻塞碼,將soc_gethostbyname返回值類型改為kal_int8后,就能正常處理域名解析了。這證明平臺的S8類型及char類型默認(rèn)是無符號的。
mtk平臺camera流程原理(轉(zhuǎn)+改)
以23C的平臺為例子。
1.mmi_camera_entry_app_screen進入MMI,CAMERA進行分配動態(tài)內(nèi)存,供采集數(shù)據(jù)處理。
2.mmi_camera_entry_app_screen_internal,進入判斷T卡等環(huán)境相關(guān),---》CAMERA_ENTER_STATE(CAMERA_STATE_PREVIEW),進入預(yù)覽狀態(tài),mmi_camera_entry_preview_state,獲取用戶的對CAMERA的設(shè)置參數(shù),如大小,特效等參數(shù)。同時,注冊進入CAMERA后的快捷鍵,為CAMERA的界面,畫OSD層,畫出左右軟鍵到OSDLAYER的BUFFER中,通過該函數(shù)mmi_camera_preview_set_blt_layer合并OSD層和基層,通過函數(shù)gdi_layer_blt_previous實現(xiàn)把合并后的層數(shù)據(jù)刷到LCD上。
3.mmi_camera_preview_start,開始進入CAMERA預(yù)覽狀態(tài),獲得并初始化CAMERA驅(qū)動所要的設(shè)置參數(shù)(camera_setting_data),通過gdi_layer_push_and_set_active函數(shù)激活CAMERA的PREVIEW層,也就是預(yù)覽時的BUFFER用來保存SENSOR輸出的數(shù)據(jù)。
4.mdi_camera_preview_start,--》mdi_camera_preview_start_internal,設(shè)置好狀態(tài),準(zhǔn)備打開SENSOR了,取得驅(qū)動需要的各種參數(shù)(cam_preview_data),
5.media_cam_preview,發(fā)送消息到下層,通知打開SENSOR,設(shè)置好CAMERA預(yù)覽的事件,
6.cam_preview_req_hdlr,下層開始啟動CAMERA預(yù)覽事件。
接下來,預(yù)覽的刷屏都是通過SENSOR的VSYC接到中斷上來實現(xiàn)的,每來個VSYC中斷,把PREVIEWLAYER的BUFFER,經(jīng)過YUV-RGB的轉(zhuǎn)換,通過DMA配置來刷到LCD上。
由于MTK把刷屏的那部分沒有開放,所以跟到6就跟不下去了,在6那里有幾個CAM_SET_EVENT(CAM_EVT_PREVIEW);由于對MTK的操作系統(tǒng)不是很熟悉,不知道這句話是什么意思,#defineCAM_SET_EVENT(evt_)do{\
- kal_set_eg_events(cam_context_p->cam_event,(evt_),KAL_OR);\
- CAM_SET_EVT(evt_,__LINE__);\
- }while(0)
預(yù)覽過程中通過一個while循環(huán)不斷發(fā)中斷完成
#p#
mtk平臺,相關(guān)問題總結(jié)
下面是在mtk平臺,遇到的一些問題,我將其保存,大家可以看看:
編譯前請將..customcommonvram_lid_statistics.h文件和tst文件夾的屬性、plutommiCustomerCustomize下的GCML.txt改為可讀寫。
Release版本的時候,MMI/MiscFramework/MiscFrameworkSrc/UCS2.c不能刪除,因為,resgen要用倒ucs2.c
1:深路經(jīng)覆蓋淺路徑文件
2:只有ADD_APPLICATION_MENUITEM,ADD_APPLICATION_MENUITEM2兩種添加菜單方式
3:添加菜單的時候一定要,指定子菜單的個數(shù)
4:CmsWapMmsAdp.h文件中,如果是26項目,不要打開28開關(guān)
- #defineSUPPORT_MTK_6226
- #if0
- #ifdefSUPPORT_MTK_6228
- #defineCMS_SURPPORT_PNG_BMP
- #endif
- #endif
5:Res_SAT.c中,如果用移軟的庫,要將
- #ifndefCMS_NEW_APP
- ADD_APPLICATION_MENUITEM((SERVICES_WAP_MENU_ID,MAIN_MENU_SERVICES_MENUID,0,SHOW,NONMOVEABLE|SHORTCUTABLE,DISP_LIST,
- SERVICES_WAP_STRING_ID,SERVICES_WAP_IMAGE_ID));
- #endif
注釋掉
6:DataAccountDef.h中添加
- #include"custom_mmi_default_value.h"
用來防止
- #ifdefMAX_GPRS_USER_NAME_LEN
- #defineMAX_GPRS_USERNAMEMAX_GPRS_USER_NAME_LEN-1
- #else
- #defineMAX_GPRS_USERNAME15
- #endif
- #ifdefMAX_GPRS_PASSWORD_LEN
- #defineMAX_GPRS_USERPASSWDMAX_GPRS_PASSWORD_LEN-1
- #else
- #defineMAX_GPRS_USERPASSWD15
- #endif
的偏差
7:頭文件打不開,很可能在
make中的相應(yīng)文件里,沒有加這個路徑
如:plutommi.inc文件中沒有包含相應(yīng)路徑
8:useragentprofile在文件cmswapmmsadp.c
9:mtk28,在mms_send_message函數(shù)中,要將
- MMS_SetMaxSize(gconfig.sendsize,gconfig.retrievesize);
放在
- MMS_Init();
之后,否則,發(fā)彩信會重啟
10:mms_init_global_param此函數(shù)中設(shè)置了mms的相關(guān)參數(shù),
還有
- mms_init_pre_setting_file_chinamobile
改為gconfigtemp.gprs_mode=4
[2wap]
wap里的wap_init_pre_setting_file_chinamobile函數(shù)
帳號改為
- gWapTemp.gprs_mode=14//WAP_SERVICE_CHINAMOBILE+GSM_NET_ACCOUNT;
11:cmswapmmsadp.h中有wap,mms相關(guān)設(shè)置
12:將開關(guān)
- #ifdefined(CMS_NEW_APP)||defined(MMS_SUPPORT)
- #define__MMI_STATUS_ICON_MMS__
- #endif
打開,否則來彩信的時候沒有未讀圖標(biāo)
13:收發(fā)彩信的時候,底下的白色部分
修改mmi_mms_show_send_receive_status函數(shù)中的
- UI_fill_rectangle(0,MMS_PROGRESS_INDICATOR_HEIGHT,UI_device_width-1,
- 10,UI_color(255,255,255));
14、我們發(fā)了新版本給貴方,如果需要打trace請在手機上開啟trace,方法:
1:Idle->輸入*#34364#,選擇第2項設(shè)備,--〉7項,setuart->1項TSTConfig-〉
uartport選擇uart1完成,重啟
15、gif重復(fù)播放,gif圖像消失的解決方式
(1)在播放前添加gdi_image_gif_reset();
#p#
16:Idle來短信進入了短信inbox,沒有進合一接口
- #ifdefined(CMS_NEW_APP)&&defined(SUPPORT_SMSMMS_COMBINE)
- externvoidmmi_mms_entry_inbox(void);
- #endif
- voidmmi_msg_exit_inbox_list_dummy(void)
- {
- memset(&currHistory,0,sizeof(currHistory));
- #ifdefined(CMS_NEW_APP)&&defined(SUPPORT_SMSMMS_COMBINE)
- currHistory.scrnID=SCR_ID_MMS_INBOX;
- #else
- currHistory.scrnID=SCR_ID_MSG_INBOX_LIST;
- #endif
- SetMessagesCurrScrnID(0);
- g_msg_cntx.MessagesScrnIdToDelHistoryNodes=SCR_ID_MSG_INBOX_LIST;
- g_msg_cntx.MessagesScrnIdDelUptoHistoryNodes=SCR_ID_MSG_INBOX_LIST;
- #ifdefined(CMS_NEW_APP)&&defined(SUPPORT_SMSMMS_COMBINE)
- currHistory.entryFuncPtr=mmi_mms_entry_inbox;
- #else
- currHistory.entryFuncPtr=mmi_msg_entry_inbox_list;
- #endif
17、filter.txt文件用于模擬器的編譯,此文件中定義的開關(guān),都將被模擬器過濾掉,所以如果第三方release的軟件不能支持模擬器就要將其在模擬器上過濾掉
18、MTK23:我們模擬器在開機無法正常啟動時,可以將MTK23_07AW0736MPmodisWIN32FSDRIVE_CNVRAMNVD_DATA下的數(shù)據(jù)文件全部清除,在從新啟動模擬器,一般都可以成功啟動。這是因為我們在修改nvram值的時候,這個目錄下的值沒有從新生成,所以會出現(xiàn)錯誤
19、editor出現(xiàn)滾動條覆蓋虛擬鍵盤的情況,有可能是mmi_pen_editor_vk_show()中算的changed_height不對
20、去掉手機觸摸屏校驗在PhnsetNeedFactoryDefaultCalibration()中
21、recorder在退出的時候,要清除與hmchip之間所注冊的handler
此外:mdi_video_rec_save_file()中一句代碼不應(yīng)該注釋掉,記得要打開media_vid_file_merge()
vis_merge_recorder_file()是用來保存視頻文件的
22、recorder在stop的時候,沒有stoppreview,所以我們要加上stoppreview的消息,然后我們還需要closefile。media_vid_close()是player用的
23、默認(rèn)支持超級終端,如果要使用Mtk的Trace,設(shè)置步驟:
1.輸入*#3646633#,進入工程模式
2.DeviceSetUARTTracesetting選擇TracesettingON手機重起之后就可以了
3.如果只關(guān)心cdma_print的Trace信息。只選擇MOD_DISPATCH模塊即可
24、指定模擬器heap大小,ZM300300指定義的大?。ㄊ謱憰r候出現(xiàn)的問題)
25、手寫在imeres.c中,參數(shù)
- IME_HAND_WRITING_ATTRIB(MMI_FALSE,IME_HAN_WRITING_INVALID_INPUT_MODE,GUI_VIRTUAL_KEYBOARD_TRAY,PEN_EDITOR_SIMPLIFIED_CHINESE)
中
PEN_EDITOR_SIMPLIFIED_CHINESE用于在手寫時,獲取當(dāng)前的輸入法后,此參數(shù)將被mmi_pen_editor_get_hand_writing_type_by_input_mode()返回并傳給手寫模塊,用于識別當(dāng)前輸入法,給出相近文字
26:手寫可以用庫來調(diào)試,步驟如下:
1、用wentonginterface.c替換掉原來的文件,并將WTRecognizeUShort定義換為WTRecognize。
- #ifdefDEBUG_IN_WIN32_FOR_HANDWRIGING
- WTErrorWTRecognize(unsignedshort*PointData,shortPointsNumber,unsignedshort*CandidateResult,char*RamAddress);
- #else
- WTErrorWTRecognizeUShort(unsignedshort*PointData,shortPointsNumber,unsignedshort*CandidateResult,char*RamAddress);
- #endif
2、RecoCore.obj為手寫模擬器的庫,加入即可。此過程遇到模擬器heap大小問題,如25所示修改
27:修改editor默認(rèn)輸入法的時候,在Nvram_cust_pack.c中數(shù)組
- kal_uint8constNVRAM_CACHE_SHORT_DEFAULT[NVRAM_CACHE_SIZE]=
- {
- }
中修改
- 0x0E,0x00,
記住此時還需修改
- 0x0E,0x00,
后者用于恢復(fù)出廠設(shè)置的時候,系統(tǒng)來取值
修改nvram的時候,要相應(yīng)升級custom_nvram_editor_data_item.h中,
- #defineNVRAM_EF_CACHE_SHORT_LID_VERNO"004"
我們現(xiàn)在發(fā)現(xiàn)一個問題,如果我們修改了nvram里面的一個默認(rèn)設(shè)置的值,如果我們不修改對應(yīng)的版本號的話,在升級手機的時候就必須要format才可以正常讀出我們新設(shè)置的值,但是在實際的操作中,這樣會把經(jīng)過硬件校準(zhǔn)過的數(shù)據(jù)清除掉(尤其是客戶在量產(chǎn)后進行升級),會造成一些預(yù)想不到的錯誤,所以請大家在修改了nvram的值以后,一定要修改相應(yīng)的版本號。舉例如下:
如果我們修改了:
- NVRAM_EF_PHB_COMPARE_DIGIT_DEFAULT
那應(yīng)該同時修改與其對應(yīng)的NVRAM_EF_PHB_COMPARE_DIGIT_LID的版本:
- VER(NVRAM_EF_PHB_COMPARE_DIGIT_LID)
- 即:
- NVRAM_EF_PHB_COMPARE_DIGIT_LID_VERNO
一般的情況,我們修改的方法是:增加一個版本號
請各個reviewleader在給大家review的時候一定要注意這個問題。
28:
將lib解開的命令
- ar-xcustom.lib
將文件打包成lib的命令
- ar-cruscustom.lib*.obj
29:vc模擬器出現(xiàn)errorLNK2005錯誤,如:
- mstdXXXX.lib(afxmem.obj):errorLNK2005:"void__cdecloperatordelete(void*)"(??3@YAXPAX@Z)alreadydefinedinLIBCD.lib(delop.obj)
這是因為兩個vc庫沖突,把后者LIBCD.lib在vc設(shè)置中屏蔽掉即可。
方法如下:
Vc設(shè)置==》link==》選擇input選項,在ignorelibraries中寫上LIBCD.lib(要屏蔽的庫)
即可
30:mtk平臺底層聲音轉(zhuǎn)換在InitializeResourceVariables()函數(shù)中,諸如:
- resource_tones=
- resource_midis=
小結(jié):淺談MTK平臺用Socket實現(xiàn)HTTP請求過程的內(nèi)容介紹完了,通過請求數(shù)據(jù)的案例來了解到了MTK平臺的內(nèi)容,希望通過MTK平臺的應(yīng)用內(nèi)容的學(xué)習(xí)能對你有所幫助!