天天看點

使用GSM6315子產品,采用http或者https協定與伺服器通信筆記

最近半年時間因為一直在忙項目的問題,一直沒有新的跟新。現在項目已經接近尾聲,自己也有一定的free時間,這次把該項目的一個新的知識點記成筆記,來提供大家學習分享。

1、項目内容

這個項目有使用到一個2G子產品(GSM6315)和nrf51822,使用2G網絡,與伺服器通信。通信方式為post,每次都是我(裝置端),去擷取伺服器的資料或者發送采集的資料給伺服器。協定是使用http/https,每次post資料時候,我需要把自己采集的資料加載到http、https協定裡面,一起給伺服器。

2、操作方式。

相信熟悉2G子產品的一個童鞋應該都知道,該子產品使用AT指令的,而且,我看了一下這個子產品的指令集資料,盡然和M26 的AT指令 有相似之處。不知道是不是互相參考了。這個地方不做辯解,随他們怎麼搞,我們主要是如何在http、https裡面增加自己的資料。大緻操作如下。

1、激活sim卡,進行入網配置

2、進行http或者https配置

3、拼接資料

4、post資料

5、從伺服器擷取資料。

3、具體操作和相關代碼

代碼隻給出部分代碼,因為這個函數是單獨封裝的,在200ms的定時器裡面進行輪詢,裡面有指令回饋逾時處理,指令錯誤處理,指令解析,資料解析等等,造成代碼很多,很長,很複雜。這裡隻給出發送指令部分,其他的需要童鞋自己去敲了 。

相關代碼(大家可以直接複制,然後修改進行使用)

switch(livall_Send_case_flag)
			{
				case 0 :
							GSM6315_Send("ATE0",4);  //關閉回顯
						   livall_Send_case_flag = 1;
						 Timeout_count_flag =10;//200ms*10 = 2000ms //指令逾時
				      SEGGER_RTT_printf(0,"==>1 ATE0 <==\r\n");						
					break  ;
				case 1 :
					//等待序列槽指令回報
					break ;
				
				case 2:
						sprintf(temp_buffer,"AT+CGDCONT=%d,\"%s\",\"%s\"",1,"IP","CMNET");	//營運商配置
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag =20;//200*20 = 4000ms//指令逾時
					   livall_Send_case_flag = 3;
				     SEGGER_RTT_printf(0,"==>2 AT+CGDCONT=1 IP,CMNET <==\r\n");						 
					break ; 
				case 3:
					 	//µÈ´ý½á¹û·µ»Ø
					break ;
				
				case 4:
				    sprintf(temp_buffer,"AT+CGACT=%d,%d",1,1);
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag = 40;//20*20 = 400ms
					  livall_Send_case_flag = 5;	
				    SEGGER_RTT_printf(0,"==> 3 AT+CGACT=1.1<==\r\n");		 
					break ; 
				case 5:
					 //等待序列槽指令回報
					break ;
				
				case 6:
					  sprintf(temp_buffer,"AT+QNTP=\"cn.ntp.org.cn\",123");//擷取中原標準時間配置
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag = 20;//200*20 = 4000ms
					  livall_Send_case_flag = 7;	
				    SEGGER_RTT_printf(0,"==> 4 AT+QNTP=\"cn.ntp.org.cn\",123 <==\r\n");			 
					break ; 
				case 7:
	                  //等待序列槽指令回報
					break ;
				case 8:
					GSM6315_Send("AT+CCLK?",8);//擷取中原標準時間
					Timeout_count_flag = 100;
					livall_Send_case_flag = 9;
				  SEGGER_RTT_printf(0,"==> 5 AT+CCLK? <==\r\n");		 
					break ;	
				case 9:
						//等待序列槽指令回報
				    break;
				case 10:
						 if(send_ready_flag==GSM_POST_DATA )
						 {
							 lv_POST_DATA_TO_Sever(); //資料拼接
						 }
						 else if( send_ready_flag==GSM_GET_CONFIG)
						 {
							 lv_POST_GET_Helmet_Config();//資料拼接
						 }
						 else if( send_ready_flag==GSM_GET_ThresholdInfo) 
						 {
							 lv_POST_GET_Helmet_ThresholdInfo();//資料拼接
						 }
						 else if(send_ready_flag==GSM_POST_SW_VER)
						 {
						 lv_POST_Helmet_SW_VER();//資料拼接
						 }
						livall_Send_case_flag = 11;	
						SEGGER_RTT_printf(0,"==> 6  copy data to buffer <==\r\n");							
                       Timeout_count_flag = 0;
					break ;
				
				case 11:	
					 sprintf(temp_buffer,"AT+QHTTPCFG=\"requestheader\",%d",1);//http/https配置 1
						 GSM6315_Send(temp_buffer,strlen(temp_buffer));
						 Timeout_count_flag = 50;	
						 livall_Send_case_flag = 12;	
				     SEGGER_RTT_printf(0,"==> 7 AT+QHTTPCFG=requestheader<==\r\n");
					break ;
				case 12:
					//等待回報
					break ;
				
					case 13:
				sprintf(temp_buffer,"AT+QHTTPCFG =\"responseheader\",%d",1);//http/https配置 2
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag = 50;
					  livall_Send_case_flag = 14;	
					  SEGGER_RTT_printf(0,"==> 8 AT+QHTTPCFG = responseheader<==\r\n");
					break ;
				case 14:
					//µÈ´ý½á¹û·µ»Ø
					break ;
				
				case 15:
					  POST_data_len  = (strlen(buffer_URL)+2);//設定URL
						sprintf(temp_buffer,"AT+QHTTPURL=%d",POST_data_len);  //URL
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag = 50;
					  livall_Send_case_flag = 16;		
				SEGGER_RTT_printf(0,"==> 9 AT+QHTTPURL <==\r\n");
					break ;
				case 16:
						//µÈ´ý½á¹û·µ»Ø
					break ;
				case 17:
						sprintf(temp_buffer,"%s",buffer_URL);//發送URL
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
				    SEGGER_RTT_printf(0,"===>url = %s<===\r\n",temp_buffer);
					  Timeout_count_flag = 50;
					  livall_Send_case_flag = 18;	
				    SEGGER_RTT_printf(0,"==> 10 buffer_URL<==\r\n");
					break ;
				case 18:
						//µÈ´ý½á¹û·µ»Ø
					break;
				
				case 19:
					sprintf(temp_buffer,"AT+QSSLCFG=\"httpsctxi\",%d",0);  //https配置 1
					GSM6315_Send(temp_buffer,strlen(temp_buffer));
					Timeout_count_flag = 50;
					 livall_Send_case_flag = 20;		
				   SEGGER_RTT_printf(0,"==> 11 AT+QSSLCFG = httpsctxi <==\r\n");
					break ;
				case 20:
					break ;
				case 21:
				   sprintf(temp_buffer,"AT+QSSLCFG=\"https\",%d",1);  //https 配置2
					GSM6315_Send(temp_buffer,strlen(temp_buffer));
					Timeout_count_flag = 50;
					 livall_Send_case_flag = 22;		
				   SEGGER_RTT_printf(0,"==> 12 AT+QSSLCFG = https <==\r\n");
					break ;
				case 22:
					break ;
				
				case 23:
					sprintf(temp_buffer,"AT+QSSLCFG=\"seclevel\",%d,%d",0,0);  //https 配置 3
					GSM6315_Send(temp_buffer,strlen(temp_buffer));
					Timeout_count_flag = 50;//20*10 = 200ms
					 livall_Send_case_flag = 24;		
				   SEGGER_RTT_printf(0,"==> 13 AT+QSSLCFG=seclevel<==\r\n");
					break ;
				case 24:
					break ;
				
				case 25:
					  POST_data_len  = strlen(buffer_data);  //Êý¾Ý´óС
					sprintf(temp_buffer,"AT+QHTTPPOST=%d",POST_data_len);  //post  資料的長度
						GSM6315_Send(temp_buffer,strlen(temp_buffer));
						Timeout_count_flag = 50;//20*20 = 400ms
						livall_Send_case_flag = 26;	
				 SEGGER_RTT_printf(0,"==> 14 AT+QHTTPPOST <==\r\n");
					break ;
				case 26:
						//µÈ´ý½á¹û·µ»Ø
					break;
				
				case 27:
					
					  SEGGER_RTT_printf(0,"%s",buffer_data);
					  GSM6315_Send(buffer_data,strlen(buffer_data));//開始post資料
					  Timeout_count_flag = 50;//20*100= 2000ms
					  livall_Send_case_flag = 28;	
				    SEGGER_RTT_printf(0,"\r\n==> 15 buffer_data <==\r\n");
					break ;	
				case 28:
						//µÈ´ý½á¹û·µ»Ø
            break ;	
				
				case 29:
					sprintf(temp_buffer,"AT+QHTTPREAD=%d",30)//從伺服器擷取資料
					GSM6315_Send(temp_buffer,strlen(temp_buffer));
					Timeout_count_flag = 30;//20*10 = 200ms
				  livall_Send_case_flag = 30;	
				  SEGGER_RTT_printf(0,"==> 16 AT+QHTTPREAD <==\r\n");
					break ;
				case 30:
						//µÈ´ý½á¹û·µ»Ø
					break ;

				case  31:
					sprintf(temp_buffer,"AT+QPOWD=%d",1);  //關機。
					GSM6315_Send(temp_buffer,strlen(temp_buffer));
					Timeout_count_flag = 50;
					livall_Send_case_flag = 32;	
				  SEGGER_RTT_printf(0,"==> 17 AT+QPOWD <==\r\n");
					break ;
				case 32:
					break ;
           

4、代碼講解

這裡給大家細細講解。

①、case 10 的資料拼接?

case 10的拼接是本次的重點的重點,大家要自己看一下。下面貼出case 10 裡面的資料 拼接的部分代碼(這個涉及到項目的安全問題,暫時隻能貼出該部分)。

static void sprintf_post_data(uint8_t *buffer,uint8_t *strbuffer,uint16_t post_data_len)
{
    uint8_t data_sprintf_buffer[750];
	  uint8_t buffer_len ;
	  ①、http、https協定部分,必須要有不能缺少
    sprintf(buffer,"POST /helmet/reportHelmetData HTTP/1.1\r\nHost: deliveryopenapi.meituan.com\r\nAccept: */*\r\nUser-Agent: QUECTEL_MODULE\r\nConnection: Keep-Alive\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length:",post_data_len);//²»Êä³ö·´À¡ÐÅÏ¢
    ②、此處是①部分後面協定的部分與自己私有資料的長度
		 sprintf(data_sprintf_buffer," %d\r\n\r\n",post_data_len);
		 buffer_len = strlen(data_sprintf_buffer);
		 ③、拼接自己的私有資料
		 memcpy(data_sprintf_buffer+buffer_len,strbuffer,post_data_len);
		 memcpy((buffer+204),data_sprintf_buffer,strlen(data_sprintf_buffer));
}
           

下面是case 10 的完成輸出樣式,自己的資料必須是字元串格式,16進制也是可以的,但是伺服器會接收錯誤。(這裡吐槽幾句:伺服器還真是牛逼,全部都是字元串,一點不用考慮晶片資源問題。),

使用GSM6315子產品,采用http或者https協定與伺服器通信筆記

上面的資料拼接好了以後,就是在case 25 把整個資料(包括http,https協定資料和自己的資料)長度計算出來,通過AT指令告知2G子產品,然後在case 27把整個資料丢給子產品,子產品就會把資料丢給你的URL所指定的伺服器

②、case 11 和case 13 是http,https協定配置裡面的必要部分,不可缺少的指令、

③、case 15 是告知2G子產品,自己的URL長度 case 17 是告知2g 子產品自己的URL路勁(比如:www.baidu.com ,在case 15就是長度15(網址13位元組資料需要加上\r\n的2位元組進行換行,子產品才能接收),case 17 就是把這個路勁發送給子產品。)

④、case 19 ,case 21 ,case 23 是https協定的配置,如果使用http,這裡就不需要配置了 ,直接進入case 25 。如果使用https,這裡必須要配置并且不需要在發送URL成功以後,才能進行配置。

⑤、case 25 和 case 27 就是把case 10 拼接的資料發送給伺服器。

好了 ,到這裡酸水講解完了 。有興趣的童鞋可以自己琢磨一下。