Browse Source

[Add][AW-CCS][main / Module_PowerSharing]

2021.03.12 / Folus Wen

Actions:
1. define.h add isEnableLocalPowerSharging variable to struct SysConfigData.
2. Module_PowerSharing implement capacipty logic and new protocol.
3. main.c Module_PowerSharing task spwn up depend on isEnableLocalPowerSharging.

Files:
1. As follow commit history

Image version: D0.48.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 4 years ago
parent
commit
3bd84a63df

+ 282 - 287
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.c

@@ -103,21 +103,21 @@ int isValidCheckSum(struct Message *message)
 {
 	uint8_t chksum = 0x00;
 
-	for(int idx=0;idx<(((message->buffer[2]) | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):((message->buffer[2]) | message->buffer[3]<<8));idx++)
+	for(int idx=0;idx<((message->buffer[1]+3)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(message->buffer[1]+3));idx++)
 	{
-		chksum ^= message->buffer[4+idx];
+		chksum ^= message->buffer[idx];
 	}
 
-	return ((chksum == message->buffer[4+((message->buffer[2] | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(message->buffer[2] | message->buffer[3]<<8))]) ? PASS : FAIL);
+	return ((chksum == message->buffer[((message->buffer[1]+3)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(message->buffer[1]+3))]) ? PASS : FAIL);
 }
 
 uint8_t chksumCal(struct Message *message)
 {
 	uint8_t chksum=0;
 
-	for(int idx=0;idx<(((message->buffer[2]) | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):((message->buffer[2]) | message->buffer[3]<<8));idx++)
+	for(int idx=0;idx<((message->buffer[1]+3)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(message->buffer[1]+3));idx++)
 	{
-		chksum ^= message->buffer[4+idx];
+		chksum ^= message->buffer[idx];
 	}
 
 	return chksum & 0xff;
@@ -206,77 +206,6 @@ int InitShareMemory()
     return result;
 }
 
-//==========================================
-// UDP socket server routine
-//==========================================
-int udpSocketServerStart(void)
-{
-	int sockFd;
-	struct sockaddr_in servaddr;
-	struct sockaddr_in peeraddr;
-	socklen_t 			peerlen = sizeof(peeraddr);
-	uint8_t 			inputBuffer[2048] = {};
-	uint8_t 			outBuffer[2048] = {};
-	int16_t				read_size;
-	int16_t				tx_size;
-
-	memset(&servaddr, 0, sizeof(servaddr));
-	servaddr.sin_family = AF_INET;
-	servaddr.sin_port = htons(LISTEN_PORT_UDP);
-	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
-	if ((sockFd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-	{
-		DEBUG_ERROR("UDP server socket create fail.\n");
-		return FAIL;
-	}
-
-	if (bind(sockFd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
-	{
-		DEBUG_ERROR("UDP server socket bind fail.\n");
-	    return FAIL;
-	}
-	else
-		DEBUG_INFO("UDP server initial.\n");
-
-	for(;;)
-	{
-		if((read_size = recvfrom(sockFd, inputBuffer, sizeof(inputBuffer), 0, (struct sockaddr *)&peeraddr, &peerlen)) > 0)
-		{
-			DEBUG_INFO("Revieve from: %s:%d\n", inet_ntoa(peeraddr.sin_addr), htons(peeraddr.sin_port));
-			DEBUG_INFO("read_size: %d\n",read_size);
-			dM(inputBuffer, read_size, YES);
-
-			if(read_size>=6)
-			{
-				/*
-				 *	TODO:
-				 *	1. Protocol validation
-				 *	2. Protocol message parsing
-				 */
-
-				if(TRUE)
-				{
-					DEBUG_INFO("Receive UDP broadcast command.\n");
-					memset(outBuffer, 0x00, ARRAY_SIZE(outBuffer));
-					tx_size = 41;
-
-					outBuffer[0] = 0xff;
-					outBuffer[1] = 0xff;
-					outBuffer[2] = (0x25 << 0x08) & 0xff;
-					outBuffer[3] = 0x25 & 0xff;
-					outBuffer[4] = 0x00;
-
-					dM(outBuffer, tx_size, NO);
-					sendto(sockFd, outBuffer, tx_size, 0, (struct sockaddr *)&peeraddr, peerlen);
-				}
-			}
-		}
-	}
-
-	return FAIL;
-}
-
 //==========================================
 // TCP socket server routine
 //==========================================
@@ -286,7 +215,7 @@ int conn_getDupFd(void)
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(!ShmPowerSharing->Connection_Info[idx].isConnected)
+		if(!ShmPowerSharing->Connection_Info[idx].isSocketConnected)
 		{
 			result = ShmPowerSharing->Connection_Info[idx].socketFd;
 			break;
@@ -302,10 +231,10 @@ int conn_register(int socketFd)
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(!ShmPowerSharing->Connection_Info[idx].isConnected)
+		if(!ShmPowerSharing->Connection_Info[idx].isSocketConnected)
 		{
 			DEBUG_INFO("Dupfd-%d register to conn-%d.\n", socketFd, idx);
-			ShmPowerSharing->Connection_Info[idx].isConnected = TRUE;
+			ShmPowerSharing->Connection_Info[idx].isSocketConnected = TRUE;
 			ShmPowerSharing->Connection_Info[idx].socketFd = socketFd;
 			ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL);
 			result = PASS;
@@ -325,8 +254,8 @@ int conn_reject(int socketFd)
 		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
 			DEBUG_INFO("Dupfd-%d register from conn_info-%d.\n", socketFd, idx);
-			ShmPowerSharing->Connection_Info[idx].isConnected = FALSE;
-			ShmPowerSharing->Connection_Info[idx].isCharging = FALSE;
+			ShmPowerSharing->Connection_Info[idx].isSocketConnected = FALSE;
+			ShmPowerSharing->Connection_Info[idx].isGunConnected = FALSE;
 			result = PASS;
 			break;
 		}
@@ -342,7 +271,7 @@ int conn_getConectedQuantity(void)
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(ShmPowerSharing->Connection_Info[idx].isConnected)
+		if(ShmPowerSharing->Connection_Info[idx].isSocketConnected)
 		{
 			result += 1;
 		}
@@ -353,64 +282,66 @@ int conn_getConectedQuantity(void)
 	return result;
 }
 
-int conn_getChargingQuantity(void)
+int conn_updateHeartBeatTime(int socketFd)
 {
-	int result = 0;
+	int result = FAIL;
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(ShmPowerSharing->Connection_Info[idx].isCharging)
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			result += 1;
+			//DEBUG_INFO("Dupfd-%d register from conn_info-%d update heart beat time.\n", socketFd, idx);
+			ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL);
+			result = PASS;
+			break;
 		}
 	}
 
-	//DEBUG_INFO("Charging quantity: %d\n", result);
 	return result;
 }
 
-int conn_getTotalAvailableSharingCurrent(void)
+int conn_getStatusStarttime(int socketFd)
 {
 	int result = 0;
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(ShmPowerSharing->Connection_Info[idx].isConnected)
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			result += ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
+			result = ShmPowerSharing->Connection_Info[idx].lastGetStatusTime;
+			break;
 		}
 	}
 
-	DEBUG_INFO("Total sharing current: %d\n", result);
 	return result;
 }
 
-int conn_getTotalPresentOutputCurrent(void)
+int conn_getStatusStarttimeUpdate(int socketFd)
 {
-	int result = 0;
+	int result = FAIL;
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		if(ShmPowerSharing->Connection_Info[idx].isConnected && ShmPowerSharing->Connection_Info[idx].isCharging)
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			result += ShmPowerSharing->Connection_Info[idx].presentOutputCurrent;
+			ShmPowerSharing->Connection_Info[idx].lastGetStatusTime = time((time_t*)NULL);;
+			result = PASS;
+			break;
 		}
 	}
 
-	DEBUG_INFO("Total actual current: %d\n", result);
 	return result;
 }
 
-uint16_t conn_querySharingCurrent(int socketFd)
+int conn_setCapacityStarttime(int socketFd)
 {
-	uint16_t result = 0x00;
+	int result = 0;
 
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
 		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			//DEBUG_INFO("Dupfd-%d on conn_info-%d query sharing current(0.1A): %d\n", socketFd, idx, ShmPowerSharing->Connection_Info[idx].sharingCurrent);
-			result = ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
+			result = ShmPowerSharing->Connection_Info[idx].lastSetCapacityTime;
 			break;
 		}
 	}
@@ -418,7 +349,7 @@ uint16_t conn_querySharingCurrent(int socketFd)
 	return result;
 }
 
-int conn_updateHeartBeatTime(int socketFd)
+int conn_setCapacityStarttimeUpdate(int socketFd)
 {
 	int result = FAIL;
 
@@ -426,8 +357,7 @@ int conn_updateHeartBeatTime(int socketFd)
 	{
 		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			//DEBUG_INFO("Dupfd-%d register from conn_info-%d update heart beat time.\n", socketFd, idx);
-			ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL);
+			ShmPowerSharing->Connection_Info[idx].lastSetCapacityTime = time((time_t*)NULL);;
 			result = PASS;
 			break;
 		}
@@ -436,16 +366,33 @@ int conn_updateHeartBeatTime(int socketFd)
 	return result;
 }
 
-int conn_updatePresentCurrentOutput(int socketFd, uint8_t isCharging, uint16_t outputCurrent)
+int conn_update_status(int socketFd, uint8_t pilotState, uint8_t availableCurrent, uint8_t presentCurrent, uint16_t acPhase)
 {
 	int result = FAIL;
 	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
 		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			//DEBUG_INFO("Dupfd-%d on conn_info-%d update actual output current(0.1A): %d\n", socketFd, idx, outputCurrent);
-			ShmPowerSharing->Connection_Info[idx].isCharging = isCharging;
-			ShmPowerSharing->Connection_Info[idx].presentOutputCurrent = outputCurrent;
+			if(!ShmPowerSharing->Connection_Info[idx].isGunConnected &&
+			   (2<=pilotState) &&
+			   (pilotState<=7))
+			{
+				ShmPowerSharing->hasNewConn = YES;
+			}
+
+			if((ShmPowerSharing->Connection_Info[idx].isGunConnected != (2<=pilotState)&&(pilotState<=7)?YES:NO) ||
+			   (ShmPowerSharing->Connection_Info[idx].presentOutputCurrent != presentCurrent) ||
+			   (ShmPowerSharing->Connection_Info[idx].acPhase != acPhase))
+			{
+				DEBUG_INFO("Connection-%d pilot state: %d \n", idx, pilotState);
+				DEBUG_INFO("Connection-%d available current: %d \n", idx, availableCurrent);
+				DEBUG_INFO("Connection-%d preset output current: %d \n", idx, presentCurrent);
+				DEBUG_INFO("Connection-%d ac power phase: %d \n", idx, acPhase);
+			}
+
+			ShmPowerSharing->Connection_Info[idx].isGunConnected = (2<=pilotState)&&(pilotState<=7)?YES:NO;
+			ShmPowerSharing->Connection_Info[idx].presentOutputCurrent = presentCurrent;
+			ShmPowerSharing->Connection_Info[idx].acPhase = acPhase;
 			result = PASS;
 		}
 	}
@@ -453,48 +400,54 @@ int conn_updatePresentCurrentOutput(int socketFd, uint8_t isCharging, uint16_t o
 	return result;
 }
 
-int conn_check_loop(void)
+int conn_getOnHandCurrent(void)
 {
-	for(;;)
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 	{
-		// Check conn heart beat
-		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+		if(ShmPowerSharing->Connection_Info[idx].isSocketConnected)
 		{
-			if(ShmPowerSharing->Connection_Info[idx].isConnected &&
-			   (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) > 300))
-			{
-				DEBUG_INFO("SocketFd-%d heart beat is over 300 seconds.\n", ShmPowerSharing->Connection_Info[idx].socketFd);
-				ShmPowerSharing->Connection_Info[idx].isCharging = FALSE;
-				ShmPowerSharing->Connection_Info[idx].isConnected = FALSE;
-			}
+			result += ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
 		}
+	}
 
-		// Check available power
-		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	result = ShmCharger->gun_info[0].primaryMcuState.rating_current - result;
+
+	DEBUG_INFO("Total on hand available current: %d\n", result);
+	return result;
+}
+
+void create_cmd_getStatus(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 4;
+	out->buffer[0] = 0x55;
+	out->buffer[1] = 0x00;
+	out->buffer[2] = SHARING_CMD_GET_STATUS;
+	out->buffer[3] = chksumCal(out);
+
+	dM(out->buffer, out->size, FALSE);
+}
+
+void create_cmd_SetAvailableCurrent(struct Message *out, int socketFd)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 5;
+	out->buffer[0] = 0x55;
+	out->buffer[1] = 0x01;
+	out->buffer[2] = SHARING_CMD_SET_CAPACITY;
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
 		{
-			if(ShmPowerSharing->Connection_Info[idx].isConnected &&
-			   ShmPowerSharing->Connection_Info[idx].isCharging)
-			{
-				if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent != ((ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity()))
-				{
-					DEBUG_INFO("Dupfd-%d on conn_info-%d update sharing current(0.1A): %d\n", ShmPowerSharing->Connection_Info[idx].socketFd, idx, ((ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity()));
-				}
-				ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = (ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity();
-			}
-			else
-			{
-				if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent != 0)
-				{
-					DEBUG_INFO("Dupfd-%d on conn_info-%d update sharing current(0.1A): 0\n", ShmPowerSharing->Connection_Info[idx].socketFd, idx);
-				}
-				ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = 0;
-			}
+			out->buffer[3] = ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
 		}
-
-		sleep(1);
 	}
-
-	return FAIL;
+	out->buffer[4] = chksumCal(out);
+	dM(out->buffer, out->size, FALSE);
 }
 
 int tcpSocketServerStart(void)
@@ -506,7 +459,6 @@ int tcpSocketServerStart(void)
 	struct Message		output;
 	struct sockaddr_in 	serverInfo, clientInfo;
 	socklen_t 			addrlen = sizeof(clientInfo);
-	uint16_t 			sharingCurrent=0;
 
 	sockFd = socket(AF_INET , SOCK_STREAM , 0);
 	if(sockFd == -1)
@@ -544,92 +496,88 @@ int tcpSocketServerStart(void)
 				// Fork a child process to handle the new conn
 				if(fork()==0)
 				{
+					uint8_t idxStep = 0;
+					uint8_t socketEnable = YES;
+					struct timeval	tv;
+					tv.tv_sec = 0;
+					tv.tv_usec = 500000;
+					setsockopt(clientSockFd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
 					// Assign socket handle as available handle in conn info pool
 					dupFd = dup2(clientSockFd, conn_getDupFd());
 					conn_register(dupFd);
-					while((input.size = recv(dupFd, input.buffer, sizeof(input.buffer), 0)) > 0)
-					{
-						dM(input.buffer, input.size, YES);
 
-						if(isValidCheckSum(&input))
+					while(socketEnable)
+					{
+						if((input.size = recv(dupFd, input.buffer, sizeof(input.buffer), 0)) > 0)
 						{
-							conn_updateHeartBeatTime(dupFd);
+							dM(input.buffer, input.size, YES);
 
-							memset(output.buffer, 0x00, ARRAY_SIZE(output.buffer));
-							switch(input.buffer[1])
+							if(isValidCheckSum(&input))
 							{
-								case SHARING_CMD_QUERY_SHARING:
-									sharingCurrent = conn_querySharingCurrent(dupFd);
-									output.size = 7;
-									output.buffer[0] = 0xaa;
-									output.buffer[1] = SHARING_CMD_QUERY_SHARING;
-									output.buffer[2] = 0x02;
-									output.buffer[3] = 0x00;
-									output.buffer[4] = ((sharingCurrent>>0) & 0xff);
-									output.buffer[5] = ((sharingCurrent>>8) & 0xff);
-									output.buffer[6] = chksumCal(&output);
-									break;
+								conn_updateHeartBeatTime(dupFd);
 
-								case SHARING_CMD_SYNC_INFO:
-									conn_updatePresentCurrentOutput(dupFd, input.buffer[4], (input.buffer[5] | (input.buffer[6]<<0x08)));
-									output.size = 6;
-									output.buffer[0] = 0xaa;
-									output.buffer[1] = SHARING_CMD_SYNC_INFO;
-									output.buffer[2] = 0x01;
-									output.buffer[3] = 0x00;
-									output.buffer[4] = 0x01;
-									output.buffer[5] = chksumCal(&output);
+								memset(output.buffer, 0x00, ARRAY_SIZE(output.buffer));
+								switch(input.buffer[2])
+								{
+									case SHARING_CMD_GET_STATUS:
+										conn_update_status(dupFd, input.buffer[3], input.buffer[4], input.buffer[5], input.buffer[6]);
 
-									break;
+										break;
 
-								default:
-									DEBUG_WARN("Receive unknown command.\n");
-									output.size = 5;
-									output.buffer[0] = 0xaa;
-									output.buffer[1] = SHARING_CMD_UNKNOWN;
-									output.buffer[2] = 0x00;
-									output.buffer[3] = 0x00;
-									output.buffer[4] = chksumCal(&output);
+									case SHARING_CMD_SET_CAPACITY:
+										if(!input.buffer[3])
+											DEBUG_INFO("Set connection-%d available current fail \n");
+										break;
 
-									break;
+									default:
+										DEBUG_WARN("Receive unknown command.\n");
+										break;
+								}
+							}
+							else
+							{
+								DEBUG_WARN("Receive command check sum error.\n");
 							}
 						}
-						else
+						else if(input.size == 0)
 						{
-							DEBUG_WARN("Receive command check sum error.\n");
-							output.size = 5;
-							output.buffer[0] = 0xaa;
-							output.buffer[1] = SHARING_CMD_CHKSUM_ERROR;
-							output.buffer[2] = 0x00;
-							output.buffer[3] = 0x00;
-							output.buffer[4] = chksumCal(&output);
+							DEBUG_INFO("Client disSocketConnected.\n");
+							conn_reject(dupFd);
+							socketEnable = NO;
+							close(dupFd);
+							close(clientSockFd);
+							fflush(stdout);
+						}
+						else if(input.size == -1)
+						{
+							// Server slave handler
+							switch(idxStep)
+							{
+								case 0:
+									if(difftime(time((time_t*)NULL), conn_getStatusStarttime(dupFd)) >= 3)
+									{
+										create_cmd_getStatus(&output);
+										conn_getStatusStarttimeUpdate(dupFd);
+										send(clientSockFd, output.buffer, output.size, 0);
+									}
+
+									idxStep++;
+									break;
+								default:
+									if((difftime(time((time_t*)NULL), conn_setCapacityStarttime(dupFd)) >= 1))
+									{
+										create_cmd_SetAvailableCurrent(&output, dupFd);
+										conn_setCapacityStarttimeUpdate(dupFd);
+										send(clientSockFd, output.buffer, output.size, 0);
+									}
+
+									idxStep = 0;
+									break;
+							}
 						}
-
-						dM(output.buffer, output.size, NO);
-						send(clientSockFd, output.buffer, output.size, 0);
-					}
-
-					if(input.size == 0)
-					{
-						DEBUG_INFO("Client disconnected.\n");
-
-						conn_reject(dupFd);
-						close(dupFd);
-						close(clientSockFd);
-						fflush(stdout);
-					}
-					else if(input.size == -1)
-					{
-						DEBUG_ERROR("Socket recv failed.\n");
-
-						conn_reject(dupFd);
-						close(dupFd);
-						close(clientSockFd);
-						fflush(stdout);
 					}
 
 					conn_getConectedQuantity();
-
 					exit(0);
 				}
 				else
@@ -641,12 +589,11 @@ int tcpSocketServerStart(void)
 			else
 			{
 				DEBUG_WARN("Connection is over limit.\n");
-				output.size = 5;
-				output.buffer[0] = 0xaa;
-				output.buffer[1] = SHARING_CMD_CONNECTION_FULL;
-				output.buffer[2] = 0x00;
-				output.buffer[3] = 0x00;
-				output.buffer[4] = chksumCal(&output);
+				output.size = 4;
+				output.buffer[0] = 0x55;
+				output.buffer[1] = 0x00;
+				output.buffer[2] = SHARING_CMD_CONNECTION_FULL;
+				output.buffer[3] = chksumCal(&output);
 				send(clientSockFd, output.buffer, output.size, 0);
 				close(clientSockFd);
 			}
@@ -661,36 +608,6 @@ int tcpSocketServerStart(void)
 //==========================================
 // Client routine
 //==========================================
-void create_cmd_sync(struct Message *out)
-{
-	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
-
-	out->size = 8;
-	out->buffer[0] = 0xaa;
-	out->buffer[1] = SHARING_CMD_SYNC_INFO;
-	out->buffer[2] = 0x03;
-	out->buffer[3] = 0x00;
-	out->buffer[4] = (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus == SYS_MODE_CHARGING?YES:NO);
-	out->buffer[5] = (((uint16_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PresentChargingCurrent*10))>>0) & 0xff;
-	out->buffer[6] = (((uint16_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PresentChargingCurrent*10))>>8) & 0xff;
-	out->buffer[7] = chksumCal(out);
-
-	dM(out->buffer, out->size, FALSE);
-}
-
-void create_cmd_query(struct Message *out)
-{
-	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
-
-	out->size = 5;
-	out->buffer[0] = 0xaa;
-	out->buffer[1] = SHARING_CMD_QUERY_SHARING;
-	out->buffer[2] = 0x00;
-	out->buffer[3] = 0x00;
-	out->buffer[4] = chksumCal(out);
-	dM(out->buffer, out->size, FALSE);
-}
-
 int tcpSocketClientStart(void)
 {
 	int 				sockfd;
@@ -702,8 +619,6 @@ int tcpSocketClientStart(void)
 	struct Message		input;
 	struct Message		output;
 
-	uint8_t				cmdIdx;
-
 	bzero(&info,sizeof(info));
 	ghbn = gethostbyname((char*)"192.168.10.10");
 	info.sin_family = PF_INET;
@@ -732,6 +647,7 @@ int tcpSocketClientStart(void)
 		tv.tv_usec = 500000;
 		setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
 		socketEnable = ON;
+		ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = ON;
 	}
 
 	while(socketEnable)
@@ -740,64 +656,154 @@ int tcpSocketClientStart(void)
 		if((input.size = recv(sockfd, input.buffer, ARRAY_SIZE(input.buffer), 0)) > 0)
 		{
 			//DEBUG_INFO("Receive size: %d.\n", input.size);
-			dM(input.buffer, input.size, TRUE);
+			dM(input.buffer, input.size, YES);
 
 			if(isValidCheckSum(&input))
 			{
-				switch(input.buffer[1])
+				switch(input.buffer[2])
 				{
-					case SHARING_CMD_QUERY_SHARING:
-						if(ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent != ((input.buffer[4] | (input.buffer[5] << 8))/10))
-						{
-							ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent = ((input.buffer[4] | (input.buffer[5] << 8))/10);
-							DEBUG_INFO("Update available sharing current(A): %d\n", ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent);
-						}
-						ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = ON;
+					case SHARING_CMD_GET_STATUS:
+						output.size = 8;
+						output.buffer[0] = 0x55;
+						output.buffer[1] = 0x04;
+						output.buffer[2] = input.buffer[2];
+						output.buffer[3] = ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PilotState;
+						output.buffer[4] = ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent;
+						output.buffer[5] = ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PresentChargingCurrent;
+						output.buffer[6] = ShmSysConfigAndInfo->SysConfig.AcPhaseCount;
+						output.buffer[7] = chksumCal(&output);
 
 						break;
 
-					case SHARING_CMD_SYNC_INFO:
-						if(!input.buffer[4])
-							DEBUG_INFO("Charger status sync reject.\n");
-
+					case SHARING_CMD_SET_CAPACITY:
+						output.size = 5;
+						output.buffer[0] = 0x55;
+						output.buffer[1] = 0x01;
+						output.buffer[2] = input.buffer[2];
+						output.buffer[3] = 0x01;
+						output.buffer[4] = chksumCal(&output);
+						if(ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent != input.buffer[3])
+						{
+							ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent = input.buffer[3];
+							DEBUG_INFO("Get available current from server: %d\n", ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent);
+						}
 						break;
 
 					default:
 						DEBUG_WARN("Receive unknown command.\n");
+						output.size = 4;
+						output.buffer[0] = 0x55;
+						output.buffer[1] = 0x00;
+						output.buffer[2] = SHARING_CMD_UNKNOWN;
+						output.buffer[3] = chksumCal(&output);
 						break;
 				}
 			}
 			else
 			{
 				DEBUG_WARN("Receive command check sum error.\n");
+				output.size = 4;
+				output.buffer[0] = 0x55;
+				output.buffer[1] = 0x00;
+				output.buffer[2] = SHARING_CMD_CHKSUM_ERROR;
+				output.buffer[3] = chksumCal(&output);
 			}
+
+			dM(output.buffer, output.size, NO);
+			send(sockfd, output.buffer, output.size, 0);
 		}
 		else if(input.size == 0)
 		{
-			DEBUG_INFO("Disconnected.\n");
+			DEBUG_INFO("DisSocketConnected.\n");
 			fflush(stdout);
 
 			socketEnable = OFF;
 			ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF;
 		}
 		else if(input.size == -1)
+		{}
+		usleep(1000000);
+	}
+	close(sockfd);
+
+	return FAIL;
+}
+
+//==========================================
+// Local loading balance check
+//==========================================
+int balance_check_loop(void)
+{
+	for(;;)
+	{
+		// Check conn heart beat
+		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 		{
-			switch(cmdIdx)
+			if(ShmPowerSharing->Connection_Info[idx].isSocketConnected &&
+			   (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) > 300))
 			{
-				case 0:
-					create_cmd_sync(&output);
-					cmdIdx += 1;
-					break;
-				default:
-					create_cmd_query(&output);
-					cmdIdx = 0;
-					break;
+				DEBUG_INFO("SocketFd-%d heart beat is over 300 seconds.\n", ShmPowerSharing->Connection_Info[idx].socketFd);
+				ShmPowerSharing->Connection_Info[idx].isGunConnected = FALSE;
+				ShmPowerSharing->Connection_Info[idx].isSocketConnected = FALSE;
 			}
-			send(sockfd, output.buffer, output.size, 0);
 		}
-		usleep(1000000);
+
+		// Check available power
+		if(ShmPowerSharing->hasNewConn)
+		{
+			DEBUG_INFO("New connection gun connected and re-allocate available current to each connection.\n");
+
+			for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+			{
+				if(ShmPowerSharing->Connection_Info[idx].isSocketConnected &&
+				   ShmPowerSharing->Connection_Info[idx].isGunConnected)
+				{
+					ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = 6;
+				}
+				else
+				{
+					ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = 0;
+				}
+			}
+
+			ShmPowerSharing->hasNewConn = NO;
+		}
+
+		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+		{
+			if(ShmPowerSharing->Connection_Info[idx].isSocketConnected &&
+			   ShmPowerSharing->Connection_Info[idx].isGunConnected)
+			{
+				if((difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastCheckCapacityTime) > 10))
+				{
+					if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent >= (ShmPowerSharing->Connection_Info[idx].presentOutputCurrent+2))
+					{
+						if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent >= 8)
+							ShmPowerSharing->Connection_Info[idx].availableSharingCurrent -= 2;
+					}
+					else if(((ShmPowerSharing->Connection_Info[idx].presentOutputCurrent-1) < ShmPowerSharing->Connection_Info[idx].availableSharingCurrent) &&
+							(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent < (ShmPowerSharing->Connection_Info[idx].presentOutputCurrent+1)) &&
+							(conn_getOnHandCurrent() > 2))
+					{
+						ShmPowerSharing->Connection_Info[idx].availableSharingCurrent += 2;
+					}
+					else
+					{}
+					ShmPowerSharing->Connection_Info[idx].lastCheckCapacityTime = time((time_t*)NULL);
+				}
+			}
+			else
+			{
+				if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent != 0)
+				{
+					DEBUG_INFO("Dupfd-%d on conn_info-%d update sharing current(A): 0\n", ShmPowerSharing->Connection_Info[idx].socketFd, idx);
+				}
+				ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = 0;
+			}
+		}
+
+		sleep(1);
 	}
-	close(sockfd);
 
 	return FAIL;
 }
@@ -826,17 +832,6 @@ int main(void)
 	if((ShmCharger->gun_info[0].primaryMcuState.rotatory_switch != SWITCH_F_SLAVE) &&
 	   (AC_QUANTITY==1?TRUE:(ShmCharger->gun_info[1].primaryMcuState.rotatory_switch != SWITCH_F_SLAVE)))
 	{
-		// UDP socket server start
-		/*
-		if(fork() == 0)
-		{
-			if(udpSocketServerStart() == FAIL)
-			{
-				DEBUG_ERROR("UDP socket server down.\n");
-				return 0;
-			}
-		}*/
-
 		// TCP socket server start
 		if(fork() == 0)
 		{
@@ -850,9 +845,9 @@ int main(void)
 		// Connection check loop
 		if(fork() == 0)
 		{
-			if(conn_check_loop() == FAIL)
+			if(balance_check_loop() == FAIL)
 			{
-				DEBUG_ERROR("Connection check loop fail.\n");
+				DEBUG_ERROR("Local loading balance check loop fail.\n");
 				return 0;
 			}
 		}

+ 15 - 10
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.h

@@ -57,11 +57,10 @@
 #define true			    		1
 #define false						0
 
-#define LISTEN_PORT_UDP				8421
-#define LISTEN_PORT_TCP				8422
-#define	CONNECTION_LIMIT			8
+#define LISTEN_PORT_TCP				118
+#define	CONNECTION_LIMIT			5
 
-#define ShmPowerShargingKey			LISTEN_PORT_TCP
+#define ShmPowerShargingKey			LISTEN_PORT_TCP+8000
 
 enum ROTARY_SWITCH_LIMIT
 {
@@ -85,8 +84,8 @@ enum ROTARY_SWITCH_LIMIT
 
 enum SHARING_COMMAND
 {
-	SHARING_CMD_QUERY_SHARING=0x01,
-	SHARING_CMD_SYNC_INFO=0x81,
+	SHARING_CMD_GET_STATUS=0x01,
+	SHARING_CMD_SET_CAPACITY=0x02,
 	SHARING_CMD_CONNECTION_FULL=0xfd,
 	SHARING_CMD_CHKSUM_ERROR=0xfe,
 	SHARING_CMD_UNKNOWN=0xff
@@ -101,19 +100,25 @@ struct Message
 struct CONNECTION_INFO
 {
 	int 		socketFd;					// Socket file description
-	uint16_t	availableSharingCurrent;	// Each connection available sharing current, resolution: 0.1A
-	uint16_t	presentOutputCurrent;		// Each connection preset output current, resolution: 0.1A
+	uint16_t	availableSharingCurrent;	// Each connection available sharing current, resolution: 1A
+	uint16_t	presentOutputCurrent;		// Each connection preset output current, resolution: 1A
+	uint8_t		acPhase;					// Each connection ac power phase
 	uint16_t	SOC;						// Each connection preset SOC, resolution: 0.1%
 	uint16_t	remindTime;					// Each connection remind charging time, resolution: 1min
 	time_t		lastHeartBeatTime;			// Each connection latest get heart beat start time
-	uint8_t		isConnected:1;				// Each connection connected flag
-	uint8_t 	isCharging:1;				// Each connection charging state flag
+	time_t		lastGetStatusTime;			// Each connection latest get status start time
+	time_t		lastSetCapacityTime;		// Each connection latest set capacity start time
+	time_t		lastCheckCapacityTime;		// Each connection latest check capacity start time
+	uint8_t		isSocketConnected:1;		// Each connection socket connected flag
+	uint8_t		isGunConnected:1;			// Each connection gun connected flag
 };
 
 struct POWER_SHARING
 {
 	uint8_t					connectedQty;
+	uint16_t				onHandCurrent;
 	struct CONNECTION_INFO	Connection_Info[CONNECTION_LIMIT];
+	uint8_t					hasNewConn:1;
 };
 
 #endif /* MODULE_POWERSHARING_H_ */

+ 3 - 2
EVSE/Projects/AW-CCS/Apps/main.c

@@ -2122,7 +2122,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.47.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.48.00.0000.00");
 
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
@@ -3021,7 +3021,8 @@ void checkTask()
 		system ("/root/Module_LcmControl &");
 	}
 
-	if(system("pidof -s Module_PowerSharing > /dev/null") != 0)
+	if((system("pidof -s Module_PowerSharing > /dev/null") != 0) &&
+		ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharging)
 	{
 		DEBUG_INFO("Module_PowerSharing not running, restart it.\n");
 		system ("/root/Module_PowerSharing &");

+ 1 - 0
EVSE/Projects/define.h

@@ -463,6 +463,7 @@ struct SysConfigData
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
+	unsigned char			isEnableLocalPowerSharging; //0: Disable power sharing	1: Enable power sharing
 };
 
 struct ChargingInfoData

+ 1 - 1
EVSE/rootfs/etc/logrotate.d/evse

@@ -1,6 +1,6 @@
 /Storage/**/*Log /Storage/**/*.log{
 	weekly
-        rotate 24
+        rotate 10
 	size 10M
         missingok
         compress