Эх сурвалжийг харах

2019-08-13 vern.chang

    Actions:
    1. add part of CCS communication from SLAC to TCP connection

    files:
    1. EVSE/Projects/CCS/Apps/EvComm.*
    2. EVSE/Projects/CCS/Apps/define.h
vern.chang 5 жил өмнө
parent
commit
52ee12a2d6

+ 528 - 58
EVSE/Projects/CCS/Apps/EvComm.c

@@ -38,7 +38,7 @@ struct InternalComm			*ShmInternalComm;
 
 pid_t						PilotDetectionPid;
 enum MsgFlowStatus			V2gFlowStatus;
-int 							RawSock;
+int 							RawSock,UdpSock,TcpSock;
 unsigned char 					*RecvBuffer,*SendBuffer;
 int 							RecvBufferSize=64*1024;
 int 							SendBufferSize=64*1024;
@@ -50,7 +50,7 @@ struct sockaddr_ll 				DestSocketAddress;
 struct ifreq 					Req;
 unsigned int 					PwmStartTime;
 struct timeb 					SeqStartTime,SeqEndTime;
-unsigned char 					AagGroupsNum;
+unsigned char 					AagGroupsNum, MnbcSoundNum,AttenProfileNum;
 unsigned char					NewNmkKey[16],Nid[7];
 
 #ifdef SystemLogMessage
@@ -460,7 +460,9 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 	
 	MmePacket = (struct MmeHeader *)Buffer;
 	#ifdef Debug
-	printf("\n***** Received MME Packet *****\n");
+	printf("\n\n***********************************\n");
+	printf("***** Received MME Packet *****\n");
+	printf("***********************************\n");
 	printf("DataLength=%d\n",DataLength);
 	printf("ODA: %02x:%02x:%02x:%02x:%02x:%02x\n", 
 		MmePacket->ODA[0],MmePacket->ODA[1],MmePacket->ODA[2],MmePacket->ODA[3],MmePacket->ODA[4],MmePacket->ODA[5]);
@@ -516,16 +518,11 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,SlacRunId,sizeof(SlacRunId));
 			SendMmePacketSize+=sizeof(SlacRunId);
 			SendMmePacketSize+=19;	//the size before MMENTRY
-			V2gFlowStatus=CM_SLAC_PARM_CONF;
-			Rtn=sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
-			ftime(&SeqStartTime);	
-			counter=0;
 			#ifdef Debug
-			printf("\n***** Response MME Packet *****\n");
-			printf("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);
-			printf("SendMmePacket->ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+			printf("\n\n***** Response MME Packet *****\n");
+			printf("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
 				SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
-			printf("SendMmePacket->OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+			printf("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
 				SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
 			printf("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
 			printf("MMV: 0x%x\n", SendMmePacket.MMV);
@@ -547,13 +544,21 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 				SendMmePacket.MMENTRY[17],SendMmePacket.MMENTRY[18],SendMmePacket.MMENTRY[19],SendMmePacket.MMENTRY[20],
 				SendMmePacket.MMENTRY[21],SendMmePacket.MMENTRY[22],SendMmePacket.MMENTRY[23],SendMmePacket.MMENTRY[24]);
 			#endif
+			V2gFlowStatus=CM_SLAC_PARM_CONF;
+			Rtn=sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
+			#ifdef Debug
+			printf("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);
+			#endif
+			ftime(&SeqStartTime);	
+			counter=0;
 			break;	
 		case MMTYPE_CM_START_ATTEN_CHAR_IND:
 			#ifdef Debug
-			printf("--- MMTYPE_CM_START_ATTEN_CHAR_IND (counter : %d) ---\n",counter+1);
+			printf("--- MMTYPE_CM_START_ATTEN_CHAR_IND (counter : %d/3 ) ---\n",counter+1);
 			printf("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
 			printf("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
 			printf("NUM_SOUNDS: 0x%x\n", MmePacket->MMENTRY[2]);
+			MnbcSoundNum=MmePacket->MMENTRY[2];
 			printf("Time_Out 0x%x\n", MmePacket->MMENTRY[3]);
 			printf("RESP_TYPE 0x%x\n", MmePacket->MMENTRY[4]);//Fixed value (0x01) indicating ¡§other Green PHY station¡¨
 			printf("FORWARDING_STA: %02x:%02x:%02x:%02x:%02x:%02x\n", 
@@ -567,8 +572,9 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			counter++;
 			if(counter==1)
 			{
-				ftime(&SeqStartTime);	//start TT_EVSE_match_MNBC
 				memset(Aag,0,sizeof(Aag));
+				AttenProfileNum=0;
+				ftime(&SeqStartTime);	//start TT_EVSE_match_MNBC
 			}	
 			else if(counter>=3)
 			{
@@ -576,8 +582,10 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			}	
 			break;	
 		case MMTYPE_CM_MNBC_SOUND_IND:
+			if(V2gFlowStatus>=CM_ATTEN_CHAR_IND)
+				break;
 			#ifdef Debug
-			printf("--- MMTYPE_CM_MNBC_SOUND_IND (counter : %d) ---\n",counter+1);
+			printf("--- MMTYPE_CM_MNBC_SOUND_IND (counter : %d/%d) ---\n",counter+1,MnbcSoundNum);
 			printf("APPLICATION_TYPE: 0x%x\n", MmePacket->MMENTRY[0]);
 			printf("SECURITY_TYPE: 0x%x\n", MmePacket->MMENTRY[1]);
 			printf("SenderID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", 
@@ -603,8 +611,10 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			counter++;
 			break;		
 		case MMTYPE_CM_ATTEN_PROFILE_IND:
+			if(V2gFlowStatus>=CM_ATTEN_CHAR_IND)
+				break;
 			#ifdef Debug
-			printf("--- MMTYPE_CM_ATTEN_PROFILE_IND (counter : %d) ---\n",counter+1);
+			printf("--- MMTYPE_CM_ATTEN_PROFILE_IND (counter : %d/%d) ---\n",counter,MnbcSoundNum);
 			printf("EV MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", 
 				MmePacket->MMENTRY[0],MmePacket->MMENTRY[1],MmePacket->MMENTRY[2],MmePacket->MMENTRY[3],
 				MmePacket->MMENTRY[4],MmePacket->MMENTRY[5]);
@@ -618,6 +628,7 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			AagGroupsNum=MmePacket->MMENTRY[6];
 			for(Rtn=0;Rtn<MmePacket->MMENTRY[6];Rtn++)
 				Aag[Rtn]+=MmePacket->MMENTRY[8+Rtn];
+			AttenProfileNum++;
 			V2gFlowStatus=CM_MNBC_SOUND_IND;
 			break;	
 		case MMTYPE_CM_ATTN_CHAR_RSP:
@@ -751,7 +762,7 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			memcpy(SendMmePacket.OSA,CsuMac,6);
 			SendMmePacket.MTYPE=htons(EtherType_HomePlug);
 			SendMmePacket.MMV=MmePacket->MMV;
-			SendMmePacket.MMTYPE=MMTYPE_CM_SLAC_PARM_CNF;
+			SendMmePacket.MMTYPE=MMTYPE_CM_SLAC_MATCH_CNF;
 			SendMmePacket.FMI[0]=SendMmePacket.FMI[1]=0;
 			SendMmePacketSize=0;
 			SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;//Fixed value (0x00) indicating ¡§PEV-EVSE matching¡¨
@@ -775,9 +786,115 @@ int MmeProcess(unsigned char *Buffer, int DataLength)
 			SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;//RSVD
 			memcpy(SendMmePacket.MMENTRY+SendMmePacketSize,NewNmkKey,sizeof(NewNmkKey));
 			SendMmePacketSize+=sizeof(NewNmkKey);
+			SendMmePacketSize+=19;	//the size before MMENTRY
+			#ifdef Debug
+			printf("\n\n***** Response MME Packet *****\n");
+			printf("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+				SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
+			printf("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+				SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
+			printf("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
+			printf("MMV: 0x%x\n", SendMmePacket.MMV);
+			printf("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
+			printf("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
+			printf("--- CM_SLAC_MATCH_CNF ---\n");
+			printf("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
+			printf("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
+			printf("MVFLength: 0x%x, 0x%x\n", SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3]);
+			printf("PEV ID: \n");	
+			for(Rtn=0;Rtn<17;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[4+Rtn]);
+			printf("\n");		
+			printf("PEV MAC: \n");	
+			for(Rtn=0;Rtn<6;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[21+Rtn]);
+			printf("\n");	
+			printf("EVSE ID: \n");	
+			for(Rtn=0;Rtn<17;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[27+Rtn]);
+			printf("\n");		
+			printf("EVSE MAC: \n");	
+			for(Rtn=0;Rtn<6;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[44+Rtn]);
+			printf("\n");		
+			printf("RunID: \n");	
+			for(Rtn=0;Rtn<8;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[50+Rtn]);
+			printf("\n");		
+			printf("RSVD: \n");	
+			for(Rtn=0;Rtn<8;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[58+Rtn]);
+			printf("\n");		
+			printf("NID: \n");	
+			for(Rtn=0;Rtn<7;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[66+Rtn]);
+			printf("\n");	
+			printf("RSVD: 0x%x\n", SendMmePacket.MMENTRY[73]);
+			printf("NMK: \n");	
+			for(Rtn=0;Rtn<16;Rtn++)
+				printf("%02x, ",SendMmePacket.MMENTRY[74+Rtn]);
+			printf("\n");	
+			#endif
 			V2gFlowStatus=CM_SLAC_MATCH_CNF;
 			Rtn=sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
+			#ifdef Debug
+			printf("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,Rtn);
+			#endif
 			ftime(&SeqStartTime);	
+			break;
+		case MMTYPE_VENDOR_VS_HOST_ACTION:
+			{
+				struct QcaVendorMmeHeader *RecvPacket;
+				RecvPacket = (struct QcaVendorMmeHeader *)Buffer;
+				//#ifdef Debug
+				printf("--- MMTYPE_VENDOR_VS_HOST_ACTION ---\n");
+				//#endif
+				switch (RecvPacket->MBODY[0])
+				{
+					case 0x00:
+						//Loader (Device Softloader or Bootloader) ready
+						printf("QCA7K: Loader Ready\n");
+						break;
+					case 0x01:
+						//Firmware Upgrade Ready
+						printf("QCA7K: Firmware Upgrade Ready\n");
+						break;	
+					case 0x02:
+						//PIB Update Ready
+						printf("QCA7K: PIB Update Ready\n");
+						break;	
+					case 0x03:
+						//Firmware Upgrade and PIB Update ready
+						printf("QCA7K: Firmware Upgrade and PIB Update ready\n");
+						break;		
+					case 0x04:
+						//Loader (Bootloader) ready to receive SDRAM configuration.
+						printf("QCA7K: Loader ready to receive SDRAM configuration\n");
+						break;			
+					case 0x05:
+						//Reset to Factory Defaults.
+						printf("QCA7K: Reset to Factory Defaults\n");
+						break;	
+					default:
+						//Reserved
+						printf("QCA7K: Reserved\n");
+						break;			
+				}
+			}
+			break;		
+		case MMTYPE_VENDOR_ATTEN_CHAR:
+			#ifdef Debug
+			printf("--- MMTYPE_VENDOR_ATTEN_CHAR ---\n");
+			#endif
+			break;		
+		case MMTYPE_VENDOR_VS_NW_INFO_CNF:		
+			memcpy(QcaMac,MmePacket->OSA,6);
+			#ifdef Debug
+			printf("--- MMTYPE_VENDOR_VS_NW_INFO_CNF ---\n");
+			printf("QcaMac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
+				QcaMac[0],QcaMac[1],QcaMac[2],QcaMac[3],QcaMac[4],QcaMac[5]);
+			#endif
+			V2gFlowStatus=CM_SET_KEY_REQ;
 		default:
 			break;
 	}
@@ -806,7 +923,7 @@ int SendSetKey()
 	memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,2);//PRN, Fixed value(0x00), encrypted payload not used
 	SendMmePacketSize+=2;
 	SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;//PMN, Fixed value(0x00) encrypted payload not used
-	SendMmePacket.MMENTRY[SendMmePacketSize++]=0x00;//CCo Capablility
+	SendMmePacket.MMENTRY[SendMmePacketSize++]=0x01;//CCo Capablility
 	srand(time(NULL));
 	for(i=10;i<16;i++)
 	{
@@ -833,21 +950,41 @@ int SendSetKey()
 	V2gFlowStatus=CM_SET_KEY_REQ;
 	i=sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
 	#ifdef Debug
-	printf("i=%d\n",i);
+	printf("SendSetKey: send size =%d\n",i);
 	#endif
 	
 }
+
+int GetQca7kMac()
+{
+	int i = 0;
+	struct QcaVendorMmeHeader SendPacket;
+	
+	memset(&SendPacket,0,sizeof(struct QcaVendorMmeHeader));
+	memset(SendPacket.ODA, 0xFF, 6);
+	memcpy(SendPacket.OSA,CsuMac,6);
+	SendPacket.MTYPE=htons(EtherType_HomePlug);
+	SendPacket.MMV=0x00;
+	SendPacket.MMTYPE=MMTYPE_VENDOR_VS_NW_INFO;
+	SendPacket.OUI[0]=0x00;
+	SendPacket.OUI[1]=0xB0;
+	SendPacket.OUI[2]=0x52;
+	
+	i=sendto(RawSock, &SendPacket, 20, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
+	#ifdef Debug
+	printf("GetQca7kMac: send size =%d\n",i);
+	#endif
+}
  
 int SlacComm()
 {
 	int packet_size,count;
+	static unsigned int STime;
 	
 	if(RawSock>=0)	
 	{
+		memset(RecvBuffer,0,RecvBufferSize);
 		packet_size = recvfrom(RawSock , RecvBuffer , RecvBufferSize , 0 , NULL, NULL);
-		#ifdef Debug
-		printf("packet_size=%d\n",packet_size);
-		#endif
 		if(packet_size>0)
 		{
 			/*#ifdef Debug
@@ -900,14 +1037,37 @@ int SlacComm()
 				   	return -1;	
 				}
 				memset( &DestSocketAddress, 0, sizeof(struct sockaddr_ll) );
-				//DestSocketAddress.sll_family   = PF_PACKET;
-	  			//DestSocketAddress.sll_protocol = 0;
 				DestSocketAddress.sll_ifindex = Req.ifr_ifindex;
 				DestSocketAddress.sll_halen = ETH_ALEN;
-				//CM_SET_KEY_REQ
-				SendSetKey();
+				//Get QCA7K MAC address
+				GetQca7kMac();
+				PwmStartTime=0;
+				count=0;
+				STime=time(NULL);
 			}	
 			else
+			{
+				if((time(NULL)-STime)>=3)
+				{
+					if((count++) >=3)
+						V2gFlowStatus=Sequence_Timeout;
+					else
+					{		
+						GetQca7kMac();
+						STime=time(NULL);
+					}
+				}	
+			}
+			break;
+		case CM_SET_KEY_REQ:	
+			//CM_SET_KEY_REQ
+			SendSetKey();
+			break;
+		case CM_SET_KEY_CNF:
+			OutputCpPwmDuty(5);
+			if(PwmStartTime<=0)
+				PwmStartTime=time(NULL);
+			else
 			{
 				if((time(NULL)-PwmStartTime)>TT_EVSE_SLAC_init)
 				{
@@ -917,11 +1077,7 @@ int SlacComm()
 					V2gFlowStatus=Sequence_Timeout;
 				   	return -1;	
 				}	
-			}
-			break;
-		case CM_SET_KEY_CNF:
-			OutputCpPwmDuty(5);
-			PwmStartTime=time(NULL);
+			}		
 			break;	
 		case CM_SLAC_PARM_CONF:
 			ftime(&SeqEndTime);	
@@ -967,12 +1123,48 @@ int SlacComm()
 				SendMmePacketSize+=17;
 				memset(SendMmePacket.MMENTRY+SendMmePacketSize,0,17);//RESP_ID
 				SendMmePacketSize+=17;
-				SendMmePacket.MMENTRY[SendMmePacketSize++]=C_EV_match_MNBC;//NumSounds
+				SendMmePacket.MMENTRY[SendMmePacketSize++]=AttenProfileNum;//NumSounds
 				for(count=0;count<AagGroupsNum;count++)
-					SendMmePacket.MMENTRY[SendMmePacketSize++]=(Aag[count]/C_EV_match_MNBC)&0xFF;
+					SendMmePacket.MMENTRY[SendMmePacketSize++]=(Aag[count]/AttenProfileNum)&0xFF;
 				SendMmePacketSize+=19;	//the size before MMENTRY
+				#ifdef Debug
+				printf("\n\n***** Send MME Packet *****\n");
+				printf("SendMmePacket.ODA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+					SendMmePacket.ODA[0],SendMmePacket.ODA[1],SendMmePacket.ODA[2],SendMmePacket.ODA[3],SendMmePacket.ODA[4],SendMmePacket.ODA[5]);
+				printf("SendMmePacket.OSA: %02x:%02x:%02x:%02x:%02x:%02x:\n", 
+					SendMmePacket.OSA[0],SendMmePacket.OSA[1],SendMmePacket.OSA[2],SendMmePacket.OSA[3],SendMmePacket.OSA[4],SendMmePacket.OSA[5]);
+				printf("MTYPE: 0x%x\n", htons(SendMmePacket.MTYPE));
+				printf("MMV: 0x%x\n", SendMmePacket.MMV);
+				printf("MMTYPE: 0x%x\n", SendMmePacket.MMTYPE);
+				printf("FMI 0x%x, 0x%x\n", SendMmePacket.FMI[0],SendMmePacket.FMI[1]);
+				printf("--- CM_ATTEN_CHAR_IND ---\n");
+				printf("APPLICATION_TYPE: 0x%x\n", SendMmePacket.MMENTRY[0]);
+				printf("SECURITY_TYPE: 0x%x\n", SendMmePacket.MMENTRY[1]);
+				printf("SOURCE_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\n", 
+					SendMmePacket.MMENTRY[2],SendMmePacket.MMENTRY[3],SendMmePacket.MMENTRY[4],SendMmePacket.MMENTRY[5],
+					SendMmePacket.MMENTRY[6],SendMmePacket.MMENTRY[7]);
+				printf("RunID: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\n", 
+					SendMmePacket.MMENTRY[8],SendMmePacket.MMENTRY[9],SendMmePacket.MMENTRY[10],SendMmePacket.MMENTRY[11],
+					SendMmePacket.MMENTRY[12],SendMmePacket.MMENTRY[13],SendMmePacket.MMENTRY[14],SendMmePacket.MMENTRY[15]);	
+				printf("SOURCE_ID: \n");	
+				for(count=0;count<17;count++)
+					printf("%02x, ",SendMmePacket.MMENTRY[16+count]);
+				printf("\n");		
+				printf("RESP_ID: \n");	
+				for(count=0;count<17;count++)
+					printf("%02x, ",SendMmePacket.MMENTRY[33+count]);
+				printf("\n");		
+				printf("NumSounds: 0x%x\n", SendMmePacket.MMENTRY[50]);
+				printf("ATTEN_PROFILE: \n");	
+				for(count=0;count<AagGroupsNum;count++)
+					printf("%02x, ",SendMmePacket.MMENTRY[51+count]);
+				printf("\n");		
+				#endif
 				V2gFlowStatus=CM_ATTEN_CHAR_IND;
 				count=sendto(RawSock, &SendMmePacket, SendMmePacketSize, 0, (struct sockaddr*)&DestSocketAddress, sizeof(struct sockaddr_ll));
+				#ifdef Debug
+				printf("SendMmePacketSize=%d,Rtn=%d\n",SendMmePacketSize,count);
+				#endif
 				ftime(&SeqStartTime);	
 			}	
 			break;	
@@ -1010,15 +1202,18 @@ int SlacComm()
 			}	
 			break;			
 		case CM_SLAC_MATCH_CNF:	
-			ftime(&SeqEndTime);	
-			if(DiffTimeb(SeqStartTime, SeqEndTime)>TT_match_join)
+			if(UdpSock>0)
 			{
-				#ifdef SystemLogMessage	
-				StoreLogMsg("[EvComm]SlacComm: Wait CM_VALIDATE_CNF or CM_SLAC_MATCH_REQ Timeout - TT_match_join ");
-				#endif	
-				V2gFlowStatus=Sequence_Timeout;
-				return -1;	
+				close(UdpSock);
+				UdpSock=-1;
+			}	
+			if(TcpSock>0)
+			{
+				close(TcpSock);
+				TcpSock=-1;
 			}	
+			ftime(&SeqStartTime);	
+			V2gFlowStatus=SLACC_SDP_UDP_Connection;
 			break;				
 		defaudlt:
 			break;		
@@ -1026,53 +1221,328 @@ int SlacComm()
     return 0;  
 } 
 
-int V2gComm()
+int V2gMsgProcess(unsigned char *Buffer, int DataLength)
+{
+	struct V2gtpHeader *RecvHeader;
+       	unsigned char *PayloadData;
+       	
+       	RecvHeader= (struct V2gtpHeader *) Buffer;
+	#ifdef Debug
+	printf("\n\n***********************************\n");
+	printf("***** Received V2G Packet *****\n");
+	printf("***********************************\n");
+	printf("ProtocolVersion=%d\n",RecvHeader->ProtocolVersion);
+	printf("InverseProtocolVersion=0x%x\n",RecvHeader->InverseProtocolVersion);
+	printf("PayloadType=0x%x\n",htons(RecvHeader->PayloadType));
+	printf("PayloadLength=0x%x\n",htonl(RecvHeader->PayloadLength));
+	#endif
+	if(htons(RecvHeader->PayloadType)!=V2GTP_PAYLOAD_TYPE_EXI_MSG)
+	{
+		#ifdef SystemLogMessage	
+		StoreLogMsg("[EvComm]V2gMsgProcess: Wrong Payload Type");
+		#endif	
+		return 0;  
+	}
+	//EXI decode 
+	//process received message and change status flag
+	
+}
+
+int V2gComm(int AcceptFd)
 {
+	int packet_size,count;
+			
+	memset(RecvBuffer,0,RecvBufferSize);
+	packet_size=recv(AcceptFd, RecvBuffer, RecvBufferSize, 0);
+	if(packet_size>0)
+	{
+		/*#ifdef Debug
+		printf("V2gComm Data: ");
+		for(count=0;count<packet_size;count++)
+			printf("0x%x, ",RecvBuffer[count]);
+		printf("\n");
+		#endif*/
+		V2gMsgProcess(RecvBuffer, packet_size);
+	}	
+	//following are the response message handling according to status flag
+	switch(V2gFlowStatus)
+	{
+		case SupportedAppProtocolRequest:
+			break;
+		default:
+			break;	
+	}
+	return 0;
+}
+
+int SdpUdpConnected()
+{
+	int packet_size,Rtn;
+	struct sockaddr_in6 ServerAddr,ClientAddr; 
+       	struct V2gtpHeader *RecvHeader;
+       	unsigned char *PayloadData;
+        
+	if(UdpSock<=0)
+	{
+		if ((UdpSock = socket(AF_INET6, SOCK_DGRAM, 0)) <0) 
+		{
+	                #ifdef SystemLogMessage	
+			StoreLogMsg("[EvComm]SdpUdpConnected: Fail to open UdpSock");
+			#endif	
+	                return 0;  
+		}
+		memset(&ServerAddr,0, sizeof(struct sockaddr_in));
+		ServerAddr.sin6_family = AF_INET6;
+        	ServerAddr.sin6_addr=in6addr_any;
+        	ServerAddr.sin6_port = htons(SdpUdpServerPort);
+		if(bind(UdpSock, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) <0)
+		{
+                  	#ifdef SystemLogMessage	
+			StoreLogMsg("[EvComm]SdpUdpConnected: Fail to bind UdpSock");
+			#endif	
+			close(UdpSock);
+			UdpSock=-1;
+	                return 0;  
+       		}
+       		#ifdef Debug
+       		printf("UdpSock=%d\n",UdpSock);
+       		#endif	
+	}
+	memset(RecvBuffer,0,RecvBufferSize);
+	memset(&ClientAddr,0, sizeof(struct sockaddr_in));
+	Rtn=sizeof(struct sockaddr_in6);
+	packet_size = recvfrom(UdpSock , RecvBuffer , RecvBufferSize , MSG_DONTWAIT , (struct sockaddr *)&ClientAddr, &Rtn);
+	#ifdef Debug
+       	printf("packet_size=%d\n",packet_size);
+       	#endif	
+	if(packet_size>0)
+	{		
+		RecvHeader= (struct V2gtpHeader *) RecvBuffer;
+		PayloadData=RecvBuffer+sizeof(struct V2gtpHeader);
+		#ifdef Debug
+		printf("\n\n***********************************\n");
+		printf("***** Received SDP Packet *****\n");
+		printf("***********************************\n");
+		printf("ClientAddress=");
+		for(Rtn=0;Rtn<16;Rtn+=2)
+			printf("%02x%02x:",ClientAddr.sin6_addr.s6_addr[Rtn],ClientAddr.sin6_addr.s6_addr[Rtn+1]);
+		printf("\n");	
+		printf("ClientPort=%d\n",ClientAddr.sin6_port);
+		printf("ProtocolVersion=%d\n",RecvHeader->ProtocolVersion);
+		printf("InverseProtocolVersion=0x%x\n",RecvHeader->InverseProtocolVersion);
+		printf("PayloadType=0x%x\n",htons(RecvHeader->PayloadType));
+		printf("PayloadLength=0x%x\n",htonl(RecvHeader->PayloadLength));
+		#endif
+		if((RecvHeader->ProtocolVersion==0x01)&&(RecvHeader->InverseProtocolVersion==0xFE)&&(htons(RecvHeader->PayloadType)==V2GTP_PAYLOAD_TYPE_SDP_REQUEST))
+		{
+			#ifdef Debug
+			printf("Security=0x%x\n",*(PayloadData+0));
+			printf("TransportProtocol=0x%x\n",*(PayloadData+1));
+			#endif
+			RecvHeader->PayloadType=htons(V2GTP_PAYLOAD_TYPE_SDP_RESPONSE);
+			RecvHeader->PayloadLength=htonl(20);	//Fixed Length=20
+			memset(PayloadData,0,20);
+			// MAC address[0:2] + FFFE + MAC address[3:5]
+			PayloadData[0]=(IPV6_LINK_LOCAL_PREFIX>>8)&0xFF;  
+			PayloadData[1]=IPV6_LINK_LOCAL_PREFIX&0xFF;
+			PayloadData[8]=CsuMac[0];
+			PayloadData[8]^=0x02;// bit 1 should complemented.
+			PayloadData[9]=CsuMac[1];
+			PayloadData[10]=CsuMac[2];
+			PayloadData[11]=0xFF;
+			PayloadData[12]=0xFE;
+			PayloadData[13] =CsuMac[3];
+			PayloadData[14]=CsuMac[4];
+			PayloadData[15]=CsuMac[5];
+			//TCP port
+			PayloadData[16]=(SdpTcpServerPort>>8)&0xFF;
+			PayloadData[17]=SdpTcpServerPort&0xFF;
+			PayloadData[18]=SDP_PAYLOAD_SECURITY_NONE;		//Security
+			PayloadData[19]=SDP_PAYLOAD_TRANS_PROTOCOL_TCP;	//Transport protocol
+			Rtn=sendto(UdpSock, RecvBuffer, sizeof(struct V2gtpHeader)+htonl(RecvHeader->PayloadLength), 0, (struct sockaddr *)&ClientAddr, sizeof(struct sockaddr_in6));
+			#ifdef Debug
+			printf("\n\n***** Response SDP Packet *****\n");
+			printf("Send size=%d\n",Rtn);
+			printf("Destination Address=");
+			for(Rtn=0;Rtn<16;Rtn++)
+				printf("%02x, ",ClientAddr.sin6_addr.s6_addr[Rtn]);
+			printf("\n");	
+			printf("Destination Port=%d\n",ClientAddr.sin6_port);
+			printf("ProtocolVersion=%d\n",RecvHeader->ProtocolVersion);
+			printf("InverseProtocolVersion=0x%x\n",RecvHeader->InverseProtocolVersion);
+			printf("PayloadType=0x%x\n",htons(RecvHeader->PayloadType));
+			printf("PayloadLength=0x%x\n",htonl(RecvHeader->PayloadLength));
+			printf("SECC Ipv6 Address=");
+			for(Rtn=0;Rtn<16;Rtn++)
+				printf("%02x:",PayloadData[Rtn]);
+			printf("\n");	
+			printf("SECC Port=%d\n",(PayloadData[16]<<8|PayloadData[17]));
+			printf("Security=0x%x\n",PayloadData[19]);
+			printf("TransportProtocol=0x%x\n",PayloadData[20]);
+			#endif
+			if(Rtn>0)
+				return 1;
+		}
+	}	
 	return 0;  
 }
+
+int V2gTcpConnected()
+{
+	int packet_size,Rtn,AcceptFd;
+	struct sockaddr_in6 ServerAddr,ClientAddr; 
+       
+	if(TcpSock<=0)
+	{
+		if ((TcpSock = socket(PF_INET6, SOCK_STREAM, 0)) <0) 
+		{
+	                #ifdef SystemLogMessage	
+			StoreLogMsg("[EvComm]V2gTcpConnected: Fail to open TcpSock");
+			#endif	
+	                return 0;  
+		}
+		fcntl(TcpSock, F_SETFL, O_NONBLOCK);	//set to O_NONBLOCK
+		memset(&ServerAddr,0, sizeof(struct sockaddr_in));
+		ServerAddr.sin6_family = PF_INET6;
+        	ServerAddr.sin6_addr=in6addr_any;
+        	ServerAddr.sin6_port = htons(SdpTcpServerPort);
+		if(bind(TcpSock, (struct sockaddr *)&ServerAddr, sizeof(struct sockaddr_in6)) <0)
+		{
+                  	#ifdef SystemLogMessage	
+			StoreLogMsg("[EvComm]V2gTcpConnected: Fail to bind TcpSock");
+			#endif	
+			close(TcpSock);
+			TcpSock=-1;
+	                return 0;  
+       		}
+       		if(listen(TcpSock, 1) == -1) //only accept one connection
+       		{
+       			#ifdef SystemLogMessage	
+			StoreLogMsg("[EvComm]V2gTcpConnected: Fail to listen TcpSock");
+			#endif	
+			close(TcpSock);
+			TcpSock=-1;
+	                return 0;  
+       		}
+       		#ifdef Debug
+      	 	printf("TcpSock=%d\n",TcpSock);
+      	 	#endif	
+	}
+	Rtn=sizeof(struct sockaddr_in6);
+	if((AcceptFd=accept(TcpSock,(struct sockaddr *)&ClientAddr,&Rtn))==-1)
+	{
+		#ifdef Debug
+		printf("Wait TCP connection\n");
+		#endif
+		return 0;
+	}
+	#ifdef Debug
+	printf("Accept one TCP connection:\n");
+	printf("AcceptFd=%d\n",AcceptFd);
+	printf("ClientAddress=");
+		for(Rtn=0;Rtn<16;Rtn+=2)
+			printf("%02x%02x:",ClientAddr.sin6_addr.s6_addr[Rtn],ClientAddr.sin6_addr.s6_addr[Rtn+1]);
+		printf("\n");	
+		printf("ClientPort=%d\n",ClientAddr.sin6_port);
+	#endif
+	return AcceptFd;  
+}
  
 int main(int argc,char *argv[])
 {
-
+	unsigned char Rtn;
+	int TcpAcceptFd;
 	//Initialization	
 	InitShareMemory();
-	//CreatShareMemory();
-	//Qca7kPowerReset();
-	//PilotDetectionPid=0;
-	//PilotDetection();
-	GetEthMac("eth1",CsuMac);
-	GetEthMac(QcaInterface, QcaMac);
+	//start to detect pilot state
+	PilotDetectionPid=0;
+	PilotDetection();
+	//Init communication parameters
+	GetEthMac(QcaInterface, CsuMac);
 	RecvBuffer=(unsigned char *)malloc(RecvBufferSize);
 	memset(RecvBuffer,0,RecvBufferSize);
 	SendBuffer=(unsigned char *)malloc(SendBufferSize);
 	memset(SendBuffer,0,SendBufferSize);
-	RawSock=-1;
+	if(RawSock>0)
+		close(RawSock);
+	if(UdpSock>0)
+		close(UdpSock);
+	if(TcpSock>0)
+		close(TcpSock);
+	RawSock=UdpSock=TcpSock=-1;
 	V2gFlowStatus=0;
+	AttenProfileNum=0;
 	while(1)
 	{
-		SlacComm();
-		continue;
-		
-		if((ShmInternalComm->ChargingPermission==0x01)&&(ConnectorPlugIn()==1))
+		#ifdef Debug
+		printf("V2gFlowStatus=%d\n",V2gFlowStatus);
+		#endif
+		//if((ShmInternalComm->ChargingPermission==0x01)&&(ConnectorPlugIn()==1))
+		if(1)
 		{
-			if(V2gFlowStatus<=CM_AMP_MAP_CNF)
+			if(V2gFlowStatus<SLACC_SDP_UDP_Connection)
 				SlacComm();
-			else 	if(V2gFlowStatus<=Performance_Timeout)
-				V2gComm();
+			else if(V2gFlowStatus==SLACC_SDP_UDP_Connection)
+			{
+				if(SdpUdpConnected()==1)
+				{
+					V2gFlowStatus=SLACC_SDP_TCP_Connection;
+					continue;
+				}	
+				ftime(&SeqEndTime);	
+				if(DiffTimeb(SeqStartTime, SeqEndTime)>TT_match_join)
+				{
+					#ifdef SystemLogMessage	
+					StoreLogMsg("[EvComm]main: Wait SLACC_SDP_UDP_Connection Timeout - TT_match_join ");
+					#endif	
+					V2gFlowStatus=Sequence_Timeout;
+				}	
+			}			
+			else if(V2gFlowStatus==SLACC_SDP_TCP_Connection)
+			{
+				if((TcpAcceptFd=V2gTcpConnected())>0)
+				{
+					V2gFlowStatus=SupportedAppProtocolRequest;
+					continue;
+				}	
+				ftime(&SeqEndTime);	
+				if(DiffTimeb(SeqStartTime, SeqEndTime)>TT_match_join)
+				{
+					#ifdef SystemLogMessage	
+					StoreLogMsg("[EvComm]main: Wait SLACC_SDP_TCP_Connection Timeout - TT_match_join ");
+					#endif	
+					V2gFlowStatus=Sequence_Timeout;
+				}
+			}		
+			else 	if(V2gFlowStatus<Performance_Timeout)
+				V2gComm(TcpAcceptFd);
 		}
 		if(V2gFlowStatus>=Performance_Timeout)	
 		{
 			//Normal Stop
 			//alarm and duty to 100%
+			OutputCpPwmDuty(100);
 			goto ReSet;
 		}	
-		else if((ConnectorPlugIn()==0)&&(V2gFlowStatus>Idle))
+		/*else if((ConnectorPlugIn()==0)&&(V2gFlowStatus>Idle))
 		{
 			//Emergency stop
+			OutputCpPwmDuty(100);
 			goto ReSet;
-		}	
+		}*/	
+		continue;
+		
 ReSet:
-		RawSock=-1;
+		if(RawSock>0)
+			close(RawSock);
+		if(UdpSock>0)
+			close(UdpSock);
+		if(TcpSock>0)
+		{	
+			close(TcpSock);
+			close(TcpAcceptFd);
+		}
+		RawSock=UdpSock=TcpSock=TcpAcceptFd=-1;
 		V2gFlowStatus=0;
 		while(1)
 		{

+ 44 - 1
EVSE/Projects/CCS/Apps/EvComm.h

@@ -3,7 +3,11 @@
 
 
 #define	QcaInterface						"eth0"
-#define SupportBcbToggle					
+#define 	SupportBcbToggle					
+#define	SdpUdpServerPort					15118
+#define	SdpTcpServerPort					59438	//49152-65535
+#define	IPV6_LINK_LOCAL_PREFIX				0xFE80
+
 /***********************************************/
 /*********** Ethernet Type ********************/
 /**********************************************/
@@ -25,7 +29,23 @@
 #define MMTYPE_CM_SLAC_MATCH_REQ			0x607C
 #define MMTYPE_CM_SLAC_MATCH_CNF		0x607D
 #define MMTYPE_CM_ATTEN_PROFILE_IND		0x6086
+//following are the vendor specific type
+#define MMTYPE_VENDOR_VS_HOST_ACTION	 	0xA062		//Embedded Host Action Requested Indication MME
+#define MMTYPE_VENDOR_ATTEN_CHAR			0xA14E		//Attenuation Characteristics MME (VS_ATTEN_CHAR)
+#define MMTYPE_VENDOR_VS_NW_INFO			0xA038		//Network Info MME
+#define MMTYPE_VENDOR_VS_NW_INFO_CNF		0xA039		//Network Info MME
 
+/***********************************************/
+/************** V2GTP Payload Type ************/
+/**********************************************/
+#define V2GTP_PAYLOAD_TYPE_SDP_REQUEST		0x9000		//SDP request message
+#define V2GTP_PAYLOAD_TYPE_SDP_RESPONSE	0x9001		//SDP response message
+#define V2GTP_PAYLOAD_TYPE_EXI_MSG			0x8001		//EXI encoded V2G Message
+//Payload
+#define SDP_PAYLOAD_SECURITY_TLS			0x00			//0x00 = secured with TLS
+#define SDP_PAYLOAD_SECURITY_NONE			0x10			//0x10 = No transport layer security
+#define SDP_PAYLOAD_TRANS_PROTOCOL_TCP	0x00			//0x00= TCP
+#define SDP_PAYLOAD_TRANS_PROTOCOL_UDP	0x10			//0x10 = reserved for UDP
 /***********************************************/
 /****** Timing and constant values **********/
 /*********** [2015] ISO 15118_3 ***************/
@@ -54,4 +74,27 @@ struct MmeHeader
     unsigned char MMENTRY[256];	//Management Message Entry Data
 }__attribute__((packed));
 
+//Qualcomm Atheros Vendor Specific MME Format
+struct QcaVendorMmeHeader
+{
+    unsigned char ODA[6];		//Original Destination Address
+    unsigned char OSA[6];			//Original source Address
+    //unsigned int VLAN Tag; 		//IEEE802.1Q VLAN Tag (optional)
+    unsigned short MTYPE;			//Ethernet Type for HomePlug, should be 0x88E1
+    unsigned char MMV;			//Management Message Version
+    unsigned short MMTYPE;		//Management Message Type
+    unsigned char OUI[3];			//Fragmentation Management Information, Fragmentation Message Sequence Number
+    unsigned char MBODY[1024];	//Management Message Entry Data
+}__attribute__((packed));
+
+struct V2gtpHeader
+{
+    unsigned char 	ProtocolVersion;		//0x01: V2GTP version 1, 0x00, 0x02-0xFF reserved
+    unsigned char 	InverseProtocolVersion;	//Equals the <Protocol_Version> XOR 0xFF, 0xFE: V2GTP Version 1
+    unsigned short 	PayloadType;			//0x8001:	EXI encoded V2G Message, 
+    									//0x9000:	SDP request message,
+    									//0x9001:	SDP response message,
+    									//0xA000 - 0xFFFF:	Manufacturer specific use
+    unsigned int 	PayloadLength;		//excluding the generic V2GTP header byte		
+}__attribute__((packed));
 #endif

+ 1 - 1
EVSE/Projects/CCS/Apps/define.h

@@ -679,7 +679,7 @@ enum CostKindType						{ relativePricePercentage = 0, RenewableGenerationPercent
 
 enum MsgFlowStatus		 			{ Idle = 0, CM_SLAC_PARM_REQ = 1, CM_SLAC_PARM_CONF = 2, CM_START_ATTEN_CHAR_IND = 3,  CM_MNBC_SOUND_IND = 4, CM_ATTEN_CHAR_IND = 5,
 									  CM_ATTEN_CHAR_RSP = 6, CM_VALIDATE_REQ = 7, CM_VALIDATE_CNF = 8, CM_SLAC_MATCH_REQ = 9, CM_SLAC_MATCH_CNF = 10, CM_AMP_MAP_REQ = 11,
-									  CM_AMP_MAP_CNF = 12, CM_SET_KEY_REQ=13, CM_SET_KEY_CNF = 14,
+									  CM_AMP_MAP_CNF = 12, CM_SET_KEY_REQ=13, CM_SET_KEY_CNF = 14, SLACC_SDP_UDP_Connection = 15,
 									  SLACC_SDP_TCP_Connection = 16, SupportedAppProtocolRequest = 17, SupportedAppProtocolResponse = 18, SessionSetupRequest = 19, SessionSetupResponse = 20,
 									  ServiceDiscoveryRequest = 21, ServiceDiscoveryResponse = 22, ServiceDetailRequest = 23, ServiceDetailResponse = 24, ServiceAndPaymentSelectionRequest = 25, ServiceAndPaymentSelectionResponse = 26,
 									  PaymentDetailsRequest = 27, PaymentDetailsResponse = 28, AuthorizationRequest = 29, AuthorizationResponse = 30, CertificateUpdateRequest = 31, CertificateUpdateResponse = 32,