Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: bc76416b6157d983d2b91f15a69b795665b66055 (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                                                   

                               

                                                     

                           














                                                                                                               

                                                 
                                                  
                                                                


                                                                











                                                                        


                                                               

                                                                                            
                                      

                                                                        
                                                  
                                                                          
                                         





                                                                                                                                                                      
                                 
                                                                          
                                                  
                                                                         
                                         






                                                                                
                                 



                                                                       



                                                                                                                
                                 
                                                                     
                                                                             

                                                                       

                                                                         
                                 

                                                                     
                                                             



                                                                        

                                         
                                               
                                               


                                                 
                                                                        
                                 





                               

                                                     

                           













                                                                                                                                            

                                                 
                                                  
                                                                


                                                                    










                                                                        


                                                               

                                                                                            
                                      
                                                                    
                                                                              
                                 
                                                                       
                                                  
                                                                      
                                         


                                                                                                                                          
                                 
                                                                          
                                                  
                                                                         
                                         




                                                                              
                                 
                                                                     
                                                                             
                                 
                                                                       

                                                                         
                                 
                                                                        
                                                  
                                                                          
                                         



                                                                                                                                  


                                                                     
                                                             



                                                                        


                                               



                                                 
                                                                        
                                 





                                   
                                                    
                                            

                          

                                              





                                       
                                                        

                          
                                                        










                                             



















                                                                                       

         

                                                                       
 
RoomModel room.basic.service.tcp {

	import room.basic.types.* from "Types.room"

	ActorClass ATcpServer {
		Interface {
			Port controlPort: PTcpControl
			Port payloadPort: PTcpPayload
		}
		Structure {
			usercode1 '''#include "osal/etTcpSockets.h"'''
			usercode3 '''
				static int8* bufferProvider(void* slf, int* size) {
					ATcpServer* self = (ATcpServer*) slf;
					*size = DTcpPayload_getMaxLength(&payloadRecvBuffer);
					return payloadRecvBuffer.data;
				}
				
				static int socketReceiver(void* slf, int channel, int size, const int8* data) {
					ATcpServer* self = (ATcpServer*) slf;
					DTcpPayload_setData(&payloadRecvBuffer, data, size);
					payloadPort_dataPackage(&payloadRecvBuffer);
					return ETSOCKET_OK;
				}
			'''
			external Port controlPort
			external Port payloadPort
			Attribute lastError: int32
			Attribute payloadRecvBuffer: DTcpPayload
			Attribute server: etSocketServerData ref
		}
		Behavior {
			ctor '''
				setErrorCode(etInitSockets());
				server = etCreateSocketServerData();
				server->receiver = socketReceiver;
				server->bufferProvider = bufferProvider;
				server->userData = self;
			'''
			dtor '''
				etCleanupSockets();
				etFreeSocketServerData(server);
			'''

//			Operation stopUser() {
//				"/* stop user: close socket */"
//			}
			Operation hasError(): boolean '''return lastError != ETSOCKET_OK;'''
			Operation setErrorCode(value: int32) '''lastError = value;'''
			StateMachine {
				Transition init: initial -> cp cp0
				Transition tr5: connected -> connected {
					triggers {
						<dataPackage: payloadPort>
					}
					action '''
						/* send payload to connection */
						setErrorCode(etWriteServerSocket(server, transitionData->connectionId, transitionData->length, transitionData->data));
						if(hasError())
							controlPort.error();
					'''
				}
				Transition tr6: connected -> unconnected {
					triggers {
						<disconnect: controlPort>
					}
					action '''
						/* close accept thread */
						etCloseAllServerSockets(server);
						etStopSocketServer(server);
						
						controlPort.disconnected();
					'''
				}
				Transition tr7: unconnected -> cp cp1 {
					triggers {
						<connect: controlPort>
					}
					action '''
						/* start accept thread */
						setErrorCode(etStartListening(server, transitionData->TcpPort));
					'''
				}
				Transition tr4: cp cp1 -> connected {
					action '''controlPort.connected();'''
				}
				Transition tr8: cp cp1 -> unconnected {
					cond '''hasError()'''
					action '''controlPort.error();'''
				}
				Transition tr0: cp cp0 -> unconnected
				Transition tr1: cp cp0 -> initError {
					cond '''hasError()'''
				}
				Transition tr2: initError -> initError {
					triggers {
						<connect: controlPort>
					}
				}
				ChoicePoint cp1
				ChoicePoint cp0
				State connected
				State unconnected
				State initError {
					entry '''controlPort.error();'''
				}
			}
		}
	}

	ActorClass ATcpClient {
		Interface {
			Port controlPort: PTcpControl
			Port payloadPort: PTcpPayload
		}
		Structure {
			usercode1 '''#include "osal/etTcpSockets.h"'''
			usercode3 '''
				static int8* bufferProvider(void* slf, int* size) {
					ATcpClient* self = (ATcpClient*) slf;
					*size = DTcpPayload_getMaxLength(&payloadRecvBuffer);
					return payloadRecvBuffer.data;
				}
				
				static int socketReceiver(void* slf, int channel, int size, const int8* data) {
					ATcpClient* self = (ATcpClient*) slf;
					DTcpPayload_setData(&payloadRecvBuffer, /* cast away constness to avoid warning*/(int8*)data, size);
					payloadPort_dataPackage(&payloadRecvBuffer);
					return ETSOCKET_OK;
				}'''
			external Port controlPort
			external Port payloadPort
			Attribute lastError: int32
			Attribute payloadRecvBuffer: DTcpPayload
			Attribute client: etSocketConnectionData ref
		}
		Behavior {
			ctor '''
				setErrorCode(etInitSockets());
				client = etCreateSocketConnectionData();
				client->receiver = socketReceiver;
				client->bufferProvider = bufferProvider;
				client->userData = self;'''
			dtor '''
				etCloseSocket(client);
				etCleanupSockets();
				etFreeSocketConnectionData(client);'''

//			Operation stopUser() {
//				"/* stop user: close socket */"
//			}
			Operation hasError(): boolean '''return lastError != ETSOCKET_OK;'''
			Operation setErrorCode(value: int32) '''lastError = value;'''
			StateMachine {
				Transition init: initial -> cp cp1 {
					action '''printf("Client Init!\n");'''
				}
				Transition tr0: unconnected -> cp cp0 {
					triggers {
						<connect: controlPort>
					}
					action '''
						/* connect to server */
						setErrorCode(etConnectServer(client, transitionData->IPAddr, transitionData->TcpPort));'''
				}
				Transition tr1: connected -> unconnected {
					triggers {
						<disconnect: controlPort>
					}
					action '''
						/* close read thread */
						etCloseSocket(client);
						
						controlPort.disconnected();'''
				}
				Transition tr2: cp cp0 -> connected {
					action '''controlPort.connected();'''
				}
				Transition tr7: cp cp0 -> unconnected {
					cond '''hasError()'''
					action '''controlPort.error();'''
				}
				Transition tr3: connected -> connected {
					triggers {
						<dataPackage: payloadPort>
					}
					action '''
						setErrorCode(etWriteSocket(client, transitionData->length, transitionData->data));
						if(hasError())
							controlPort.error();'''
				}
				Transition tr4: cp cp1 -> unconnected
				Transition tr5: cp cp1 -> initError {
					cond '''hasError()'''
				}
				Transition tr6: initError -> initError {
					triggers {
						<connect: controlPort>
					}
				}
				ChoicePoint cp0
				ChoicePoint cp1
				State unconnected
				State connected
				State initError {
					entry '''controlPort.error();'''
				}
			}
		}
	}

	ProtocolClass PTcpControl {
		incoming {
			Message connect(DTcpControl)
			Message disconnect()
		}
		outgoing {
			Message connected()
			Message disconnected()
			Message error()
		}
	}

	ProtocolClass PTcpPayload {
		incoming {
			Message dataPackage(DTcpPayload)
		}
		outgoing {
			Message dataPackage(DTcpPayload)
		}
	}

	DataClass DTcpControl {
		Attribute IPAddr: string
		Attribute TcpPort: int32
	}

	DataClass DTcpPayload {
		Attribute connectionId: int32
		Attribute length: int32
		Attribute data [32]: int8

		Operation getMaxLength(): int32 '''return 32;'''

		Operation setAsString(value: charPtr) '''
			/* used macros: data, length */
			int valLength = (strlen(value)+1 > 32)? 32 : strlen(value) + 1;
			memcpy(data, value, valLength);
			data[31] = '\0';
			length = valLength;'''

		Operation setData(value: int8 ref, size: int32) '''
			/* used macros: data, length */
			strncpy(data, value, ((size>32)?32:size));
			length = size;'''

		Operation getAsString(): charPtr '''
			/* used macros: data */
			data[31] = '\0';
			return data;'''
	}

	ExternalType etSocketServerData -> "etSocketServerData"
	ExternalType etSocketConnectionData -> "etSocketConnectionData"
}

Back to the top