1 /** @file
2  * Copyright (c) 2022, Arm Limited or its affiliates. All rights reserved.
3  * SPDX-License-Identifier : Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16 **/
17 
18 #include "platform.h"
19 #include <pal_interfaces.h>
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #if !defined(_MSC_VER)
26     #include <unistd.h>
27 #else // !defined(_MSC_VER)
28     #include <io.h>
29 
30     // Disable warning about POSIX function names.
31     #pragma warning(disable : 4996)
32 #endif // !defined(_MSC_VER)
33 
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netdb.h>
38 
39 #define PAL_STATUS_UNSUPPORTED_FUNC      0xFF
40 
41 typedef enum {
42     PAL_STATUS_SUCCESS = 0x0,
43     PAL_STATUS_ERROR   = 0x80
44 } pal_status_t;
45 
46 static int sockfd;
47 static struct sockaddr_in serveraddr;
48 static struct hostent *server;
49 
pal_print(const char * str,int32_t data)50 int pal_print(const char *str, int32_t data)
51 {
52     if (printf(str, data) < 0)
53     {
54         return PAL_STATUS_ERROR;
55     }
56     return PAL_STATUS_SUCCESS;
57 }
58 
pal_terminate_simulation(void)59 void pal_terminate_simulation(void)
60 {
61     ;
62 }
63 
pal_system_reset(void)64 int pal_system_reset(void)
65 {
66     return PAL_STATUS_UNSUPPORTED_FUNC;
67 }
68 
pal_msg_interface_init(void * ctx)69 int pal_msg_interface_init(void *ctx)
70 {
71     udp_socket_desc_t *desc = NULL;
72 
73     if (ctx == NULL)
74         return -1;
75     else
76         desc = (udp_socket_desc_t *)(ctx);
77 
78     // Creating socket file descriptor
79     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
80     if (sockfd < 0) {
81         perror("socket creation failed");
82         exit(-1);
83     }
84 
85     // gethostbyname: get the server's DNS entry
86     server = gethostbyname(desc->hostname);
87     if (server == NULL) {
88         fprintf(stderr, "ERROR, no such host as %s\n", desc->hostname);
89         exit(-1);
90     }
91 
92     // Build the server's Internet address
93     bzero((char *) &serveraddr, sizeof(serveraddr));
94     serveraddr.sin_family = AF_INET;
95     bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);
96     serveraddr.sin_port = htons(desc->port_num);
97 
98     return 0;
99 }
100 
pal_msg_interface_free(void * ctx)101 int pal_msg_interface_free(void *ctx)
102 {
103     close(sockfd);
104     return 0;
105 }
106 
pal_message_send(uint8_t buffer[],size_t size)107 int pal_message_send(uint8_t buffer[], size_t size)
108 {
109     sendto(sockfd, (const char *)buffer, size, 0, (const struct sockaddr *) &serveraddr,
110                                                    sizeof(serveraddr));
111     return (int)size;
112 }
113 
pal_message_receive(uint8_t buffer[],size_t size)114 int pal_message_receive(uint8_t buffer[], size_t size)
115 {
116     int n = 0, len = 0;
117 	do {
118 		n = recvfrom(sockfd, (char *)buffer, 4096, MSG_WAITALL,
119                              (struct sockaddr *) &serveraddr, &len);
120 	} while (n == 0);
121 
122 	if (len < 0) {
123 		close(sockfd);
124 		exit(-1);
125 	}
126 	return size;
127 }
128 
129