Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
server-node
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ThiefSil
server-node
Commits
cefd8e8c
Commit
cefd8e8c
authored
6 months ago
by
천 진강
Browse files
Options
Downloads
Patches
Plain Diff
feat(c): 컨트롤 및 C 서버
parent
232d5e7a
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
server-node-control/control.c
+309
-0
309 additions, 0 deletions
server-node-control/control.c
with
309 additions
and
0 deletions
server-node-control/control.c
0 → 100644
+
309
−
0
View file @
cefd8e8c
#include
<stdio.h>
#include
<fcntl.h>
#include
<stdlib.h>
#include
<string.h>
#include
<unistd.h>
#include
<arpa/inet.h>
#include
<pthread.h>
#define BUFFER_SIZE 1024
#define PORT 12345
#define MAX_CLIENTS 5
#define PWM 0
#define VALUE_MAX 256
#define DIRECTION_MAX 256
typedef
struct
{
int
socket
;
struct
sockaddr_in
address
;
}
ClientData
;
int
pySocket
,
cSocket
,
clientCnt
=
0
;
pthread_t
pyThread
,
clientThreads
[
MAX_CLIENTS
];
ClientData
clients
[
MAX_CLIENTS
];
static
int
PWMExport
(
int
pwmnum
)
{
#define BUFFER_MAX 3
char
buffer
[
BUFFER_MAX
];
int
fd
,
byte
;
// TODO: Enter the export path.
fd
=
open
(
"/sys/class/pwm/pwmchip0/export"
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open export for export!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pwmnum
);
write
(
fd
,
buffer
,
byte
);
close
(
fd
);
sleep
(
1
);
return
(
0
);
}
static
int
PWMUnexport
(
int
pwmnum
)
{
#define BUFFER_MAX 3
char
buffer
[
BUFFER_MAX
];
int
fd
,
byte
;
// TODO: Enter the export path.
fd
=
open
(
"/sys/class/pwm/pwmchip0/unexport"
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open export for unexport!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pwmnum
);
write
(
fd
,
buffer
,
byte
);
close
(
fd
);
sleep
(
1
);
return
(
0
);
}
static
int
PWMEnable
(
int
pwmnum
)
{
static
const
char
s_enable_str
[]
=
"1"
;
char
path
[
DIRECTION_MAX
];
int
fd
;
// TODO: Enter the enable path.
snprintf
(
path
,
DIRECTION_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/enable"
,
pwmnum
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open in enable!
\n
"
);
return
-
1
;
}
write
(
fd
,
s_enable_str
,
strlen
(
s_enable_str
));
close
(
fd
);
return
(
0
);
}
static
int
PWMWritePeriod
(
int
pwmnum
,
int
value
)
{
char
s_value_str
[
VALUE_MAX
];
char
path
[
VALUE_MAX
];
int
fd
,
byte
;
// TODO: Enter the period path.
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/period"
,
pwmnum
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open in period!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
s_value_str
,
VALUE_MAX
,
"%d"
,
value
);
if
(
-
1
==
write
(
fd
,
s_value_str
,
byte
))
{
fprintf
(
stderr
,
"Failed to write value in period!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
(
0
);
}
static
int
PWMWriteDutyCycle
(
int
pwmnum
,
int
value
)
{
char
s_value_str
[
VALUE_MAX
];
char
path
[
VALUE_MAX
];
int
fd
,
byte
;
// TODO: Enter the duty_cycle path.
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/duty_cycle"
,
pwmnum
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open in duty cycle!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
s_value_str
,
VALUE_MAX
,
"%d"
,
value
);
if
(
-
1
==
write
(
fd
,
s_value_str
,
byte
))
{
fprintf
(
stderr
,
"Failed to write value in duty cycle!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
(
0
);
}
// 수신 스레드 함수
void
*
ClientToServer
(
void
*
idx
)
{
int
i
=
*
((
int
*
)
idx
);
char
buffer
[
BUFFER_SIZE
];
char
ip
[
INET_ADDRSTRLEN
];
int
len
;
while
((
len
=
recv
(
clients
[
i
].
socket
,
buffer
,
BUFFER_SIZE
,
0
))
>
0
)
{
buffer
[
len
]
=
'\0'
;
printf
(
"Received from client %d: %s"
,
&
clients
[
i
].
address
.
sin_addr
,
buffer
);
inet_ntop
(
AF_INET
,
&
clients
[
i
].
address
.
sin_addr
,
ip
,
INET_ADDRSTRLEN
);
if
(
send
(
pySocket
,
buffer
,
strlen
(
buffer
),
0
)
<
0
)
{
perror
(
"Error sending message to server"
);
}
}
if
(
len
==
0
)
{
printf
(
"Client disconnected: %d
\n
"
,
clients
[
i
].
socket
);
}
else
if
(
len
==
-
1
)
{
perror
(
"recv failed"
);
}
clientCnt
--
;
close
(
clients
[
i
].
socket
);
}
// 서버에서 메시지 수신하는 스레드
void
*
ServerToClient
()
{
char
buffer
[
BUFFER_SIZE
];
int
len
;
while
(
1
)
{
len
=
read
(
pySocket
,
buffer
,
BUFFER_SIZE
-
1
);
if
(
len
<=
0
)
{
printf
(
"Server disconnected
\n
"
);
close
(
pySocket
);
exit
(
0
);
}
buffer
[
len
]
=
'\0'
;
printf
(
"Received from server: %s
\n
"
,
buffer
);
if
(
buffer
[
2
]
==
'Y'
)
{
// 차단기 개방
printf
(
"차단기 개방
\n
"
);
if
(
PWMExport
(
PWM
))
printf
(
"export error
\n
"
);
if
(
PWMWritePeriod
(
PWM
,
20000000
))
printf
(
"period error
\n
"
);
if
(
PWMWriteDutyCycle
(
PWM
,
0
))
printf
(
"duty error
\n
"
);
if
(
PWMEnable
(
PWM
))
printf
(
"enable error
\n
"
);
if
(
PWMWriteDutyCycle
(
PWM
,
2000000
))
printf
(
"duty error2
\n
"
);
usleep
(
100000
);
if
(
PWMUnexport
(
PWM
))
printf
(
"unexport error
\n
"
);
}
else
if
(
buffer
[
2
]
==
'P'
)
{
// 충전기 노드에 주차 사실 알림
if
(
send
(
clients
[
0
].
socket
,
buffer
,
strlen
(
buffer
),
0
)
<
0
)
{
perror
(
"Error forwarding message to client"
);
}
}
else
if
(
buffer
[
2
]
==
'E'
)
{
// 충전기 노드에 주차 사실 알림
if
(
send
(
clients
[
0
].
socket
,
buffer
,
strlen
(
buffer
),
0
)
<
0
)
{
perror
(
"Error forwarding message to client"
);
}
if
(
PWMExport
(
PWM
))
printf
(
"export error
\n
"
);
if
(
PWMWritePeriod
(
PWM
,
20000000
))
printf
(
"period error
\n
"
);
if
(
PWMWriteDutyCycle
(
PWM
,
0
))
printf
(
"duty error
\n
"
);
if
(
PWMEnable
(
PWM
))
printf
(
"enable error
\n
"
);
if
(
PWMWriteDutyCycle
(
PWM
,
950000
))
printf
(
"duty error2
\n
"
);
usleep
(
100000
);
if
(
PWMUnexport
(
PWM
))
printf
(
"unexport error
\n
"
);
}
else
if
(
buffer
[
2
]
==
'F'
)
{
// 충전기 노드에 화재 사실 알림
// 화재 노드에 화재 사실 알림
if
(
send
(
clients
[
0
].
socket
,
buffer
,
strlen
(
buffer
),
0
)
<
0
)
{
perror
(
"Error forwarding message to client"
);
}
if
(
send
(
clients
[
3
].
socket
,
buffer
,
strlen
(
buffer
),
0
)
<
0
)
{
perror
(
"Error forwarding message to client"
);
}
}
}
}
int
main
()
{
struct
sockaddr_in
pyAddr
,
cAddr
,
clientAddr
;
pthread_attr_t
attr
,
attr2
,
at
[
3
];
struct
sched_param
param
,
param2
;
socklen_t
clientAddrLen
=
sizeof
(
clientAddr
);
param
.
sched_priority
=
3
;
param2
.
sched_priority
=
2
;
pthread_attr_init
(
&
attr
);
pthread_attr_setschedpolicy
(
&
attr
,
SCHED_RR
);
pthread_attr_setinheritsched
(
&
attr
,
PTHREAD_EXPLICIT_SCHED
);
pthread_attr_setschedparam
(
&
attr
,
&
param
);
pthread_attr_init
(
&
attr2
);
pthread_attr_setschedpolicy
(
&
attr2
,
SCHED_RR
);
pthread_attr_setinheritsched
(
&
attr2
,
PTHREAD_EXPLICIT_SCHED
);
pthread_attr_setschedparam
(
&
attr2
,
&
param2
);
at
[
0
]
=
at
[
1
]
=
attr2
;
at
[
2
]
=
attr
;
// 서버로 연결할 클라이언트 소켓 생성
if
((
pySocket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
<
0
)
{
perror
(
"Socket creation error"
);
return
-
1
;
}
// 서버로 메시지 전송할 소켓 설정
pyAddr
.
sin_family
=
AF_INET
;
pyAddr
.
sin_port
=
htons
(
49152
);
if
(
inet_pton
(
AF_INET
,
"127.0.0.1"
,
&
pyAddr
.
sin_addr
)
<=
0
)
{
perror
(
"Invalid address / Address not supported"
);
return
-
1
;
}
if
(
connect
(
pySocket
,
(
struct
sockaddr
*
)
&
pyAddr
,
sizeof
(
pyAddr
))
<
0
)
{
perror
(
"Connection failed"
);
return
-
1
;
}
printf
(
"서버에 연결되었습니다.
\n
"
);
// 클라이언트를 받을 서버 소켓 설정
if
((
cSocket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
==
0
)
{
perror
(
"Socket failed"
);
return
-
1
;
}
cAddr
.
sin_family
=
AF_INET
;
cAddr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
cAddr
.
sin_port
=
htons
(
PORT
);
if
(
bind
(
cSocket
,
(
struct
sockaddr
*
)
&
cAddr
,
sizeof
(
cAddr
))
<
0
)
{
perror
(
"Bind failed"
);
close
(
cSocket
);
return
-
1
;
}
if
(
listen
(
cSocket
,
3
)
<
0
)
{
perror
(
"Listen failed"
);
close
(
cSocket
);
return
-
1
;
}
// 서버 수신용 스레드 시작
pthread_create
(
&
pyThread
,
NULL
,
ServerToClient
,
NULL
);
while
(
clientCnt
<
MAX_CLIENTS
)
{
int
x
;
char
ip
[
INET_ADDRSTRLEN
];
if
((
x
=
accept
(
cSocket
,
(
struct
sockaddr
*
)
&
clientAddr
,
&
clientAddrLen
))
<
0
)
{
perror
(
"Accept failed"
);
continue
;
}
ClientData
*
tmp
=
(
ClientData
*
)
malloc
(
sizeof
(
ClientData
));
tmp
->
socket
=
x
;
tmp
->
address
=
clientAddr
;
clients
[
clientCnt
]
=
*
tmp
;
inet_ntop
(
AF_INET
,
&
tmp
->
address
.
sin_addr
,
ip
,
INET_ADDRSTRLEN
);
int
idx
=
ip
[
11
]
-
'7'
;
if
(
pthread_create
(
&
clientThreads
[
idx
],
&
at
[
idx
],
ClientToServer
,
(
void
*
)
&
idx
)
<
0
)
{
perror
(
"Failed to create thread"
);
close
(
x
);
}
}
close
(
pySocket
);
close
(
cSocket
);
return
0
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment