]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/transport/ndk/nimu_icss/example/CCLink/cclink_slave/sample/src/SLMP_SERVER.c
transport: add to PDK
[processor-sdk/pdk.git] / packages / ti / transport / ndk / nimu_icss / example / CCLink / cclink_slave / sample / src / SLMP_SERVER.c
1 /*\r
2  * Copyright (C) 2017-2019 Texas Instruments Incorporated - http://www.ti.com/\r
3  * Copyright (C) 2016 CC-Link Partner Association -http://am.cc-link.org/\r
4  * \r
5  * \r
6  *  Redistribution and use in source and binary forms, with or without \r
7  *  modification, are permitted provided that the following conditions \r
8  *  are met:\r
9  *\r
10  *    Redistributions of source code must retain the above copyright \r
11  *    notice, this list of conditions and the following disclaimer.\r
12  *\r
13  *    Redistributions in binary form must reproduce the above copyright\r
14  *    notice, this list of conditions and the following disclaimer in the \r
15  *    documentation and/or other materials provided with the   \r
16  *    distribution.\r
17  *\r
18  *    Neither the name of Texas Instruments Incorporated nor the names of\r
19  *    its contributors may be used to endorse or promote products derived\r
20  *    from this software without specific prior written permission.\r
21  *\r
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
33  *\r
34 */\r
35 \r
36 #include "SLMP.h"\r
37 #include "CCIEF_BASIC_SLAVE.h"\r
38 #include "SLMP_SERVER.h"\r
39 #include "SOCKET.h"\r
40 #include "TIMER.h"\r
41 \r
42 #ifdef _WIN32\r
43 #include <stdint.h>\r
44 #include <winsock2.h>\r
45 #include <Ws2tcpip.h>\r
46 #elif __linux__\r
47 #include <netinet/in.h>\r
48 #elif __TIRTOS__\r
49 #include <ti/ndk/inc/stkmain.h>\r
50 #include <ti/ndk/inc/netmain.h>\r
51 #endif\r
52 #include <stdio.h>\r
53 #include <string.h>\r
54 \r
55 /*[ Structure for sample code ]*/\r
56 typedef struct \r
57 {\r
58         int                     iTimerFlag;                     /* Flag for response wait timer.(0:Not start timer  1:Starting timer) */\r
59         int                     iTimerId;                       /* Id for response wait timer */\r
60         SLMP_INFO       source;                         /* Information of SLMP source */\r
61         uint32_t        ulSendAddr;                     /* Address of the target */\r
62         uint16_t        usPortNumber;           /* Port number of the target */\r
63         uint8_t         *pucSendData;           /* Send response data */\r
64         uint16_t        usSendDataSize;         /* Size of the send response data */\r
65 #ifdef __TIRTOS__ \r
66         SOCKET          sock;                           /* Socket for sending response */\r
67 #elif _WIN32\r
68         SOCKET          sock;                           /* Socket for sending response */\r
69 #elif __linux__\r
70         int                     sock;                           /* Socket for sending response */\r
71 #endif\r
72 } SLMP_SERVER_SEND_RESPONSE_INFO;\r
73 \r
74 #ifdef _WIN32\r
75 static SOCKET sock_server;                      /* SCOKET for SLMP Server */\r
76 static SOCKET sock_ccief_basic;         /* SCOKET for CC-LinkIEF Basic */\r
77 static SOCKET sock_ccief_paramset;      /* SCOKET for parameter set */\r
78 #elif __linux__\r
79 static int              sock_server;                    /* SCOKET for SLMP Server */\r
80 static int              sock_ccief_basic;               /* SCOKET for CC-LinkIEF Basic */\r
81 static int              sock_ccief_paramset;    /* SCOKET for parameter set */\r
82 #elif __TIRTOS__\r
83 static SOCKET sock_server;          /* SCOKET for SLMP Server */\r
84 static SOCKET sock_ccief_basic;     /* SCOKET for CC-LinkIEF Basic */\r
85 static SOCKET sock_ccief_paramset;  /* SCOKET for parameter set */\r
86 #endif\r
87 \r
88 static uint8_t aucSendData[SLMP_SERVER_MAX_FRAME_SIZE];         /* Data for sending packet */\r
89 static uint8_t aucRecvData[SLMP_SERVER_MAX_FRAME_SIZE];         /* Data for receiving packet */\r
90 static uint8_t aucSendPacket[SLMP_SERVER_MAX_FRAME_SIZE];       /* Buffer for sending packet */\r
91 static uint8_t aucRecvPacket[SLMP_SERVER_MAX_FRAME_SIZE];       /* Buffer for receiving packet */\r
92 static uint8_t aucSendDataNodeSearch[SLMP_SERVER_MAX_FRAME_SIZE];       /* Buffer for sending packet of NodeSearch */\r
93 \r
94 static SLMP_SERVER_INFO ServerInfo;\r
95 \r
96 static int                              iParameterSetFlag = 0;          /* 0:Enable ParameterSet  1:Disable ParameterSet */\r
97 static unsigned long    ulParameterSetTimer = 0;        /* Timer-value of after executing ParameterSet */\r
98 \r
99 static SLMP_SERVER_CALLBACK_IPADDRESS_SET_BASIC         pUserIpAddresSetFunc;\r
100 static SLMP_SERVER_CALLBACK_PARAMETER_GET                       pUserSlaveParameterGetFunc;\r
101 static SLMP_SERVER_CALLBACK_PARAMETER_SET                       pUserSlaveParameterSetFunc;\r
102 static SLMP_SERVER_CALLBACK_PARAMETER_SET_END           pUserSlaveParameterSetEndFunc;\r
103 static SLMP_SERVER_CALLBACK_REMOTE_RESET                        pUserRemoteResetFunc;\r
104 \r
105 /*[ Service Function Table ]*/\r
106 static SLMP_SERVICE service_table[] =\r
107 {\r
108         { SLMP_COMMAND_MEMORY_READ, slmp_server_memory_read },\r
109         { SLMP_COMMAND_MEMORY_WRITE, slmp_server_memory_write },\r
110         { SLMP_COMMAND_DEVICE_INFO_COMPARE, slmp_server_device_info_compare },\r
111         { SLMP_COMMAND_PARAMETER_GET, slmp_server_parameter_get },\r
112         { SLMP_COMMAND_PARAMETER_SET, slmp_server_parameter_set },\r
113         { SLMP_COMMAND_PARAMETER_SET_START, slmp_server_parameter_set_start },\r
114         { SLMP_COMMAND_PARAMETER_SET_END, slmp_server_parameter_set_end },\r
115         { SLMP_COMMAND_PARAMETER_SET_CANCEL, slmp_server_parameter_set_cancel },\r
116         { SLMP_COMMAND_REMOTE_READ_TYPE_NAME, slmp_server_read_type_name },\r
117         { SLMP_COMMAND_REMOTE_RESET, slmp_server_remote_reset },\r
118         /* Add the other Service here. */\r
119 };\r
120 \r
121 /*[ Service Function Table for CC-LinkIEF Basic]*/\r
122 static SLMP_SERVICE service_table_basic[] =\r
123 {\r
124         { SLMP_COMMAND_NODE_SEARCH_BASIC, slmp_server_node_search_basic },\r
125         { SLMP_COMMAND_IP_ADDRESS_SET_BASIC, slmp_server_ip_address_set_basic },\r
126 };\r
127 \r
128 /*[ Service Function Table use in parameter set port]*/\r
129 static SLMP_SERVICE service_table_paramset[] =\r
130 {\r
131         { SLMP_COMMAND_COMMUNICATION_SETTING_GET, slmp_server_communication_setting_get },\r
132 };\r
133 \r
134 /* Information for NodeSearch response */\r
135 SLMP_SERVER_SEND_RESPONSE_INFO  NodeSearchResponseInfo;\r
136 \r
137 \r
138 extern const char *inet_ntop(int af, const void *src, char *dst, int cnt);\r
139 extern int inet_pton(int af, const char *src, void *dst);\r
140 \r
141 /* Definition of Internal API */\r
142 #ifdef __TIRTOS__\r
143 static int slmp_server_slmp_send_response( SOCKET sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
144                                                                                    uint8_t *pucSendData, uint16_t usSendDataSize );\r
145 static int slmp_server_slmp_send_err_response( SOCKET sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber );\r
146 #elif  _WIN32\r
147 static int slmp_server_slmp_send_response( SOCKET sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
148                                                                                    uint8_t *pucSendData, uint16_t usSendDataSize );\r
149 static int slmp_server_slmp_send_err_response( SOCKET sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber );\r
150 #elif __linux__\r
151 static int slmp_server_slmp_send_response( int sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
152                                                                                    uint8_t *pucSendData, uint16_t usSendDataSize );\r
153 static int slmp_server_slmp_send_err_response( int sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber );\r
154 #endif\r
155 static void slmp_server_node_search_send_response_timeout( int iId, void *pCallbackArg );\r
156 \r
157 /************************************************************************************/\r
158 /* This is an user defined function for initialization of the SLMP Server.                      */\r
159 /************************************************************************************/\r
160 int slmp_server_initialize( SLMP_SERVER_INFO *pServerInfo, SLMP_SERVER_CALLBACK_IPADDRESS_SET_BASIC pIpAddresSetFunc,\r
161                                                         SLMP_SERVER_CALLBACK_PARAMETER_GET pParameterGetFunc, SLMP_SERVER_CALLBACK_PARAMETER_SET pParameterSetFunc,\r
162                                                         SLMP_SERVER_CALLBACK_PARAMETER_SET_END pParameterSetEndFunc, SLMP_SERVER_CALLBACK_REMOTE_RESET pRemoteResetFunc )\r
163 {\r
164         int iErrCode = 0;\r
165 \r
166         /* Getting the information of SLMP Server */\r
167         memcpy( &ServerInfo, pServerInfo, sizeof( ServerInfo ) );\r
168 \r
169         /* Initialization of socket */\r
170         /* for User port */\r
171         iErrCode = socket_initialize( &sock_server, ServerInfo.ulIpAddress, pServerInfo->usPortNumber );\r
172         if( iErrCode !=SOCKET_ERR_OK )\r
173         {\r
174                 return iErrCode;\r
175         }\r
176         /* for CC-LinkIEF Basic port */\r
177         iErrCode = socket_initialize( &sock_ccief_basic, ServerInfo.ulIpAddress, SLMP_SERVER_PORT_NUMBER );\r
178         if( iErrCode !=SOCKET_ERR_OK )\r
179         {\r
180                 return iErrCode;\r
181         }\r
182         /* for parameter get port */\r
183         iErrCode = socket_initialize( &sock_ccief_paramset, ServerInfo.ulIpAddress, SLMP_SERVER_PORT_NUMBER_PARAMSET );\r
184         if( iErrCode !=SOCKET_ERR_OK )\r
185         {\r
186                 return iErrCode;\r
187         }\r
188 \r
189         /* Callback function for exectute user ParameterSetting */\r
190         pUserIpAddresSetFunc = pIpAddresSetFunc;\r
191         pUserSlaveParameterGetFunc = pParameterGetFunc;\r
192         pUserSlaveParameterSetFunc = pParameterSetFunc;\r
193         pUserSlaveParameterSetEndFunc = pParameterSetEndFunc;\r
194         pUserRemoteResetFunc = pRemoteResetFunc;\r
195 \r
196         /* Sets the ParameterSet Flag Enabled */ \r
197         iParameterSetFlag = 0;\r
198 \r
199         /* Initialization of NodeSearch response information */\r
200         NodeSearchResponseInfo.iTimerFlag = 0;\r
201 \r
202         return SLMP_SERVER_ERR_OK;\r
203 }\r
204 \r
205 /************************************************************************************/\r
206 /* This is an user defined function for termination of the SLMP Server.                         */\r
207 /************************************************************************************/\r
208 void slmp_server_terminate( void )\r
209 {\r
210         /* Termination of socket */\r
211         socket_terminate( sock_server );\r
212 \r
213         return;\r
214 }\r
215 \r
216 /************************************************************************************/\r
217 /* This is an user defined function for main of the SLMP Server.                                        */\r
218 /************************************************************************************/\r
219 int slmp_server_main( void )\r
220 {\r
221         int                                             iErrCode = 0;\r
222 \r
223         /* Received at the user port */\r
224         iErrCode = slmp_server_user_port();\r
225         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
226         {\r
227                 return iErrCode;\r
228         }\r
229 \r
230         /* Received at the CC-Link IEF Basic port */\r
231         iErrCode = slmp_server_basic_port();\r
232         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
233         {\r
234                 return iErrCode;\r
235         }\r
236         /* Received at the parameter set port */\r
237         iErrCode = slmp_server_paramset_port();\r
238         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
239         {\r
240                 return iErrCode;\r
241         }\r
242 \r
243         return SLMP_SERVER_ERR_OK;\r
244 \r
245 }\r
246 \r
247 /************************************************************************************/\r
248 /* This is an user defined function for received at the user port of the SLMP           */\r
249 /* Server.                                                                                                                                                      */\r
250 /************************************************************************************/\r
251 int slmp_server_user_port( void )\r
252 {\r
253         SLMP_INFO                               source;                 /* SLMP Infomation for received packet */\r
254         int                                             iErrCode = 0;\r
255         uint32_t                                ulRecvAddr;\r
256         uint16_t                                usRecvPortNumber;\r
257         struct in_addr                  addrSender;\r
258         int_fast8_t                             Ipaddr[16];\r
259 #ifdef _WIN32\r
260 #elif __linux__\r
261         uint32_t                                ulMyNetAddress;\r
262         uint32_t                                ulOtherNetAddress;\r
263 #endif\r
264 \r
265         /* Receive a request packet. */\r
266         iErrCode = socket_recv( sock_server, aucRecvPacket, sizeof( aucRecvPacket ), &ulRecvAddr, &usRecvPortNumber );\r
267         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
268         {\r
269                 if ( iErrCode == SOCKET_ERR_NO_RECEIVABLE )\r
270                 {\r
271                         return SLMP_SERVER_ERR_OK;\r
272                 }\r
273                 else\r
274                 {\r
275                         return iErrCode;\r
276                 }\r
277         }\r
278 \r
279 #ifdef _WIN32\r
280 #elif __linux__\r
281         ulMyNetAddress = ( ServerInfo.ulIpAddress & ServerInfo.ulSubnetMask );\r
282         ulOtherNetAddress = ( ulRecvAddr & ServerInfo.ulSubnetMask );\r
283 \r
284         /* Other network broadcast break*/\r
285         if( ulMyNetAddress != ulOtherNetAddress )\r
286         {\r
287                 return SLMP_SERVER_ERR_OK;\r
288         }\r
289 #endif\r
290 \r
291         /* Sets the SLMP Information for receiving. */\r
292         source.pucData = aucRecvData;\r
293 \r
294         /* Get the SLMP Information from the request packet using the SLMP library. */\r
295         iErrCode = SLMP_GetSlmpInfo( &source, aucRecvPacket );\r
296         if ( iErrCode != SLMP_ERR_OK )\r
297         {\r
298                 #ifdef __TIRTOS__\r
299                 UART_printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
300                 #else\r
301                 printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
302                 #endif\r
303                 return SLMP_SERVER_ERR_OK;\r
304         }\r
305 \r
306         /* Check the frame type */\r
307         if( (source.ulFrameType == SLMP_FTYPE_BIN_REQ_ST) || (source.ulFrameType == SLMP_FTYPE_BIN_REQ_MT) )\r
308         {       /* Request */\r
309                 /* Display the received packet information. */\r
310 #ifdef __TIRTOS__ \r
311         addrSender.s_addr = NDK_htonl(ulRecvAddr);\r
312 #elif _WIN32\r
313                 addrSender.S_un.S_addr = htonl(ulRecvAddr);\r
314 #elif __linux__\r
315                 addrSender.s_addr = htonl(ulRecvAddr);\r
316 #endif\r
317                 inet_ntop(AF_INET, &addrSender, (char*)Ipaddr, sizeof(Ipaddr) );\r
318                 #ifdef __TIRTOS__\r
319                 UART_printf("SLMP: Receive: %s:%u  Command: %04X  Subcommand: %04X\n", Ipaddr, usRecvPortNumber,source.usCommand,source.usSubCommand);\r
320                 #else\r
321                 printf("SLMP: Receive: %-15s:%-5u  Command: %04X  Subcommand: %04X\n", Ipaddr, usRecvPortNumber,source.usCommand,source.usSubCommand);\r
322                 #endif\r
323 \r
324                 /* Execute a request service. */\r
325                 iErrCode = slmp_server_service( sock_server, &source, ulRecvAddr, usRecvPortNumber, service_table, (sizeof( service_table ) / sizeof( service_table[0] )) );\r
326                 if ( iErrCode != SLMP_SERVER_ERR_OK )\r
327                 {\r
328                         #ifdef __TIRTOS__\r
329                         UART_printf("ERR : SLMP Service  %d\n",iErrCode);\r
330                         #else\r
331                         printf("ERR : SLMP Service  %d\n",iErrCode);\r
332                         #endif\r
333                         return SLMP_SERVER_ERR_OK;\r
334                 }\r
335         }\r
336 \r
337         return SLMP_SERVER_ERR_OK;\r
338 }\r
339 \r
340 /************************************************************************************/\r
341 /* This is an user defined function for received at the CC-LinkIEF Basic port of        */\r
342 /* the SLMP Server.                                                                                                                             */\r
343 /************************************************************************************/\r
344 int slmp_server_basic_port( void )\r
345 {\r
346         SLMP_INFO                               source;                 /* SLMP Infomation for received packet */\r
347         int                                             iErrCode = 0;\r
348         uint32_t                                ulRecvAddr;\r
349         uint16_t                                usRecvPortNumber;\r
350         int_fast8_t                             Ipaddr[16];\r
351         struct in_addr                  addrSender;\r
352 \r
353         /* Receive a request packet. */\r
354         iErrCode = socket_recv( sock_ccief_basic, aucRecvPacket, sizeof( aucRecvPacket ), &ulRecvAddr, &usRecvPortNumber );\r
355         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
356         {\r
357                 if ( iErrCode == SOCKET_ERR_NO_RECEIVABLE )\r
358                 {\r
359                         return SLMP_SERVER_ERR_OK;\r
360                 }\r
361                 else\r
362                 {\r
363                         return iErrCode;\r
364                 }\r
365         }\r
366 \r
367         /* Sets the SLMP Information for receiving. */\r
368         source.pucData = aucRecvData;\r
369 \r
370         /* Get the SLMP Information from the request packet using the SLMP library. */\r
371         iErrCode = SLMP_GetSlmpInfo( &source, aucRecvPacket );\r
372         if ( iErrCode != SLMP_ERR_OK )\r
373         {\r
374                 #ifdef __TIRTOS__\r
375                 UART_printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
376                 #else\r
377                 printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
378                 #endif\r
379                 return SLMP_SERVER_ERR_OK;\r
380         }\r
381 \r
382         /* Check the frame type */\r
383         if( (source.ulFrameType == SLMP_FTYPE_BIN_REQ_ST) || (source.ulFrameType == SLMP_FTYPE_BIN_REQ_MT) )\r
384         {       /* Request */\r
385                 /* Display the received packet information. */\r
386 #ifdef __TIRTOS__ \r
387         addrSender.s_addr = NDK_htonl(ulRecvAddr);\r
388 #elif _WIN32\r
389                 addrSender.S_un.S_addr = htonl(ulRecvAddr);\r
390 #elif __linux__\r
391                 addrSender.s_addr = htonl(ulRecvAddr);\r
392 #endif\r
393                 inet_ntop(AF_INET, &addrSender, (char*)Ipaddr, sizeof(Ipaddr) );\r
394                 #ifdef __TIRTOS__\r
395                 UART_printf("SLMP: Receive: %s:%u  Command: %04X  Subcommand: %04X\n", Ipaddr, usRecvPortNumber,source.usCommand,source.usSubCommand);\r
396                 #else\r
397                 printf("SLMP: Receive: %-15s:%-5u  Command: %04X  Subcommand: %04X\n", Ipaddr, usRecvPortNumber,source.usCommand,source.usSubCommand);\r
398                 #endif\r
399 \r
400                 /* Execute a request service. */\r
401                 iErrCode = slmp_server_service( sock_ccief_basic, &source, ulRecvAddr, usRecvPortNumber, service_table_basic, (sizeof( service_table_basic ) / sizeof( service_table_basic[0] )) );\r
402                 if ( iErrCode != SLMP_SERVER_ERR_OK )\r
403                 {\r
404                         #ifdef __TIRTOS__\r
405                         UART_printf("ERR : SLMP Service  %d\n",iErrCode);\r
406                         #else\r
407                         printf("ERR : SLMP Service  %d\n",iErrCode);\r
408                         #endif\r
409                         return SLMP_SERVER_ERR_OK;\r
410                 }\r
411         }\r
412 \r
413         return SLMP_SERVER_ERR_OK;\r
414 \r
415 }\r
416 \r
417 /************************************************************************************/\r
418 /* This is an user defined function for received at the parameter set port of           */\r
419 /* the SLMP Server.                                                                                                                             */\r
420 /************************************************************************************/\r
421 int slmp_server_paramset_port( void )\r
422 {\r
423         SLMP_INFO                               source;                 /* SLMP Infomation for received packet */\r
424         int                                             iErrCode = 0;\r
425         uint32_t                                ulRecvAddr;\r
426         uint16_t                                usRecvPortNumber;\r
427         int_fast8_t                             Ipaddr[16];\r
428         struct in_addr                  addrSender;\r
429 #ifdef _WIN32\r
430 #elif __linux__\r
431         uint32_t                                ulMyNetAddress;\r
432         uint32_t                                ulOtherNetAddress;\r
433 #endif\r
434 \r
435         /* Receive a request packet. */\r
436         iErrCode = socket_recv( sock_ccief_paramset, aucRecvPacket, sizeof( aucRecvPacket ), &ulRecvAddr, &usRecvPortNumber );\r
437         if ( iErrCode != SLMP_SERVER_ERR_OK )\r
438         {\r
439                 if ( iErrCode == SOCKET_ERR_NO_RECEIVABLE )\r
440                 {\r
441                         return SLMP_SERVER_ERR_OK;\r
442                 }\r
443                 else\r
444                 {\r
445                         return iErrCode;\r
446                 }\r
447         }\r
448 \r
449 #ifdef _WIN32\r
450 #elif __linux__\r
451         ulMyNetAddress = ( ServerInfo.ulIpAddress & ServerInfo.ulSubnetMask );\r
452         ulOtherNetAddress = ( ulRecvAddr & ServerInfo.ulSubnetMask );\r
453 \r
454         /* Other network broadcast break*/\r
455         if( ulMyNetAddress != ulOtherNetAddress )\r
456         {\r
457                 return SLMP_SERVER_ERR_OK;\r
458         }\r
459 #endif\r
460 \r
461         /* Sets the SLMP Information for receiving. */\r
462         source.pucData = aucRecvData;\r
463 \r
464         /* Get the SLMP Information from the request packet using the SLMP library. */\r
465         iErrCode = SLMP_GetSlmpInfo( &source, aucRecvPacket );\r
466         if ( iErrCode != SLMP_ERR_OK )\r
467         {\r
468                 #ifdef __TIRTOS__\r
469                 UART_printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
470                 #else\r
471                 printf("ERR : SLMP_GetSlmpInfo  %d\n",iErrCode);\r
472                 #endif\r
473                 return SLMP_SERVER_ERR_OK;\r
474         }\r
475 \r
476         /* Check the frame type */\r
477         if( (source.ulFrameType == SLMP_FTYPE_BIN_REQ_ST) || (source.ulFrameType == SLMP_FTYPE_BIN_REQ_MT) )\r
478         {       /* Request */\r
479                 /* Display the received packet information. */\r
480 #ifdef __TIRTOS__ \r
481         addrSender.s_addr = NDK_htonl(ulRecvAddr);\r
482 #elif _WIN32\r
483                 addrSender.S_un.S_addr = htonl(ulRecvAddr);\r
484 #elif __linux__\r
485                 addrSender.s_addr = htonl(ulRecvAddr);\r
486 #endif\r
487                 inet_ntop(AF_INET, &addrSender, (char*)Ipaddr, sizeof(Ipaddr) );\r
488                 #ifdef __TIRTOS__\r
489                 UART_printf("SLMP: Receive: %s:%u  Command: %04X  Subcommand: %04X\n", Ipaddr ,usRecvPortNumber,source.usCommand,source.usSubCommand);\r
490                 #else\r
491                 printf("SLMP: Receive: %-15s:%-5u  Command: %04X  Subcommand: %04X\n", Ipaddr ,usRecvPortNumber,source.usCommand,source.usSubCommand);\r
492                 #endif\r
493 \r
494                 /* Execute a request service. */\r
495                 iErrCode = slmp_server_service( sock_ccief_basic, &source, ulRecvAddr, usRecvPortNumber, service_table_paramset, (sizeof( service_table_paramset ) / sizeof( service_table_paramset[0] )) );\r
496                 if ( iErrCode != SLMP_SERVER_ERR_OK )\r
497                 {\r
498                         #ifdef __TIRTOS__\r
499                         UART_printf("ERR : SLMP Service  %d\n",iErrCode);\r
500                         #else\r
501                         printf("ERR : SLMP Service  %d\n",iErrCode);\r
502                         #endif\r
503                         return SLMP_SERVER_ERR_OK;\r
504                 }\r
505         }\r
506 \r
507         return SLMP_SERVER_ERR_OK;\r
508 \r
509 }\r
510 \r
511 /************************************************************************************/\r
512 /* This is an user defined function for setting the status of the SLMP Server.          */\r
513 /************************************************************************************/\r
514 void slmp_server_set_status( uint16_t usStatus )\r
515 {\r
516         ServerInfo.usStatus = usStatus;\r
517 \r
518         return;\r
519 }\r
520 \r
521 /************************************************************************************/\r
522 /* This is an user defined function for sending SLMP frame.                                                     */\r
523 /************************************************************************************/\r
524 #ifdef __TIRTOS__ \r
525 int slmp_server_slmp_send_response( SOCKET sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
526                                                                         uint8_t *pucSendData, uint16_t usSendDataSize )\r
527 #elif _WIN32\r
528 int slmp_server_slmp_send_response( SOCKET sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
529                                                                         uint8_t *pucSendData, uint16_t usSendDataSize )\r
530 #elif __linux__\r
531 int slmp_server_slmp_send_response( int sock, const SLMP_INFO *source, uint32_t ulSendAddr, uint16_t usSendPortNumber,\r
532                                                                         uint8_t *pucSendData, uint16_t usSendDataSize )\r
533 #endif\r
534 {\r
535         static SLMP_INFO        target;                 /* SLMP Infomation for sending packet*/\r
536         int                                     iErrCode = 0;\r
537         struct in_addr          addrSender;\r
538         int_fast8_t                     Ipaddr[16];\r
539 \r
540         /* Sets the SLMP Information for sending. */\r
541         target.ulFrameType = SLMP_RESPONSE_FRAME_TYPE(source->ulFrameType);\r
542         target.usSerialNumber = source->usSerialNumber;\r
543         target.usNetNumber = source->usNetNumber;\r
544         target.usNodeNumber = source->usNodeNumber;\r
545         target.usProcNumber = source->usProcNumber;\r
546         target.usTimer = source->usTimer;\r
547         target.usCommand = source->usCommand;\r
548         target.usSubCommand = source->usSubCommand;\r
549         target.usDataLength = usSendDataSize;\r
550         target.usEndCode = SLMP_ERR_OK;\r
551         target.pucData = pucSendData;\r
552 \r
553         /* Make a packet stream using the SLMP library. */\r
554         iErrCode = SLMP_MakePacketStream( target.ulFrameType, &target, aucSendPacket );\r
555         if ( iErrCode != SLMP_ERR_OK )\r
556         {\r
557                 #ifdef __TIRTOS__\r
558                 UART_printf("ERR : SLMP_MakePacketStream  %d\n", iErrCode);\r
559                 #else\r
560                 printf("ERR : SLMP_MakePacketStream  %d\n", iErrCode);\r
561                 #endif\r
562                 return SLMP_SERVER_ERR_OK;\r
563         }\r
564 \r
565         /* Send the packet for service response. */\r
566         iErrCode = socket_send( sock, aucSendPacket, usSendDataSize + SLMP_HEADER_SIZE(target.ulFrameType), ulSendAddr, usSendPortNumber );\r
567         if( iErrCode != SOCKET_ERR_OK )\r
568         {\r
569                 return iErrCode;\r
570         }\r
571 \r
572         /* Display the sending packet information. */\r
573 #ifdef __TIRTOS__ \r
574     addrSender.s_addr = NDK_htonl(ulSendAddr);\r
575 #elif _WIN32\r
576         addrSender.S_un.S_addr = htonl(ulSendAddr);\r
577 #elif __linux__\r
578         addrSender.s_addr = htonl(ulSendAddr);\r
579 #endif\r
580         inet_ntop(AF_INET, &addrSender, (char*)Ipaddr, sizeof(Ipaddr) );\r
581         #ifdef __TIRTOS__\r
582         UART_printf("SLMP: Send:    %s:%u  Endcode: %04X\n", Ipaddr, usSendPortNumber, SLMP_ERR_OK );\r
583         #else\r
584         printf("SLMP: Send:    %-15s:%-5u  Endcode: %04X\n", Ipaddr, usSendPortNumber, SLMP_ERR_OK );\r
585         #endif\r
586 \r
587         return SLMP_SERVER_ERR_OK;\r
588 }\r
589 \r
590 /************************************************************************************/\r
591 /* This is an user defined function for sending SLMP Error frame.                                       */\r
592 /************************************************************************************/\r
593 #ifdef __TIRTOS__ \r
594 int slmp_server_slmp_send_err_response( SOCKET sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber )\r
595 #elif _WIN32\r
596 int slmp_server_slmp_send_err_response( SOCKET sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber )\r
597 #elif __linux__\r
598 int slmp_server_slmp_send_err_response( int sock, const SLMP_INFO *source, uint16_t usEndCode, uint32_t ulSendAddr, uint16_t usSendPortNumber )\r
599 #endif\r
600 {\r
601         static SLMP_INFO        target;                 /* SLMP Infomation for sending packet*/\r
602         uint8_t                         *pucSendData;\r
603         uint16_t                        usSendDataSize;\r
604         int                                     iErrCode = 0;\r
605         struct in_addr          addrSender;\r
606         int_fast8_t                     Ipaddr[16];\r
607 \r
608         pucSendData = aucSendData;\r
609 \r
610         /* Make a error response data. */\r
611         iErrCode = SLMP_MakeErrorData( source, aucSendData, &usSendDataSize );\r
612         if( iErrCode != SLMP_ERR_OK )\r
613         {\r
614                 #ifdef __TIRTOS__\r
615                 UART_printf("ERR : SLMP_MakeErrorData  %d\n", iErrCode);\r
616                 #else\r
617                 printf("ERR : SLMP_MakeErrorData  %d\n", iErrCode);\r
618                 #endif\r
619                 return SLMP_SERVER_ERR_OK;\r
620         }\r
621 \r
622         /* Sets the SLMP Information for sending. */\r
623         target.ulFrameType = SLMP_RESPONSE_FRAME_TYPE(source->ulFrameType);\r
624         target.usSerialNumber = source->usSerialNumber;\r
625         target.usNetNumber = source->usNetNumber;\r
626         target.usNodeNumber = source->usNodeNumber;\r
627         target.usProcNumber = source->usProcNumber;\r
628         target.usTimer = source->usTimer;\r
629         target.usCommand = source->usCommand;\r
630         target.usSubCommand = source->usSubCommand;\r
631         target.usDataLength = usSendDataSize;\r
632         target.usEndCode = usEndCode;\r
633         target.pucData = pucSendData;\r
634 \r
635         /* Make a packet stream using the SLMP library. */\r
636         iErrCode = SLMP_MakePacketStream( target.ulFrameType, &target, aucSendPacket );\r
637         if ( iErrCode != SLMP_ERR_OK )\r
638         {\r
639                 #ifdef __TIRTOS__\r
640                 UART_printf("ERR : SLMP_MakePacketStream  %d\n", iErrCode);\r
641                 #else\r
642                 printf("ERR : SLMP_MakePacketStream  %d\n", iErrCode);\r
643                 #endif\r
644                 return SLMP_SERVER_ERR_OK;\r
645         }\r
646 \r
647         /* Send the packet for service response. */\r
648         iErrCode = socket_send( sock, aucSendPacket, usSendDataSize + SLMP_HEADER_SIZE(target.ulFrameType), ulSendAddr, usSendPortNumber );\r
649         if( iErrCode != SOCKET_ERR_OK )\r
650         {\r
651                 return iErrCode;\r
652         }\r
653 \r
654         /* Display the sending packet information. */\r
655 #ifdef __TIRTOS__ \r
656     addrSender.s_addr = NDK_htonl(ulSendAddr);\r
657 #elif _WIN32\r
658         addrSender.S_un.S_addr = htonl(ulSendAddr);\r
659 #elif __linux__\r
660         addrSender.s_addr = htonl(ulSendAddr);\r
661 #endif\r
662         inet_ntop(AF_INET, &addrSender, (char*)Ipaddr, sizeof(Ipaddr) );\r
663         #ifdef __TIRTOS__\r
664         UART_printf("SLMP: Send:    %s:%u  Endcode: %04X\n", Ipaddr, usSendPortNumber, usEndCode );\r
665         #else\r
666         printf("SLMP: Send:    %-15s:%-5u  Endcode: %04X\n", Ipaddr, usSendPortNumber, usEndCode );\r
667         #endif\r
668 \r
669         return SLMP_SERVER_ERR_OK;\r
670 }\r
671 \r
672 /************************************************************************************/\r
673 /* This is an user defined function for SLMP service execute. The following is          */\r
674 /* one of a sample in the Windows OS. Please rewrite if necessary.                                      */\r
675 /* The following is one of a sample in the Linux. Please rewrite if necessary.          */\r
676 /************************************************************************************/\r
677 #ifdef __TIRTOS__ \r
678 int slmp_server_service( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber,\r
679                                                  SLMP_SERVICE *pServiceTable, int iServiceTableNumber )\r
680 #elif _WIN32\r
681 int slmp_server_service( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber,\r
682                                                  SLMP_SERVICE *pServiceTable, int iServiceTableNumber )\r
683 #elif __linux__\r
684 int slmp_server_service( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber,\r
685                                                  SLMP_SERVICE *pServiceTable, int iServiceTableNumber )\r
686 #endif\r
687 {\r
688         uint32_t ulDataCode;\r
689         int i, iErrCode = SLMP_SERVER_ERR_UNSUPPORT_SERVICE;\r
690 \r
691         /* Gets a data code of the SLMP packet. */\r
692         ulDataCode = SLMP_DATA_CODE(source->ulFrameType);\r
693 \r
694         /* Search a service and execute the function. */\r
695         for( i = 0; i < iServiceTableNumber; i ++ )\r
696         {\r
697                 if ( source->usCommand == pServiceTable[i].usCommand )\r
698                 {\r
699                         /*[ Binary Mode ]*/\r
700                         if ( ulDataCode == SLMP_DATA_CODE_BIN )\r
701                         {\r
702                                 /* Execute a service function. */\r
703                                 iErrCode = pServiceTable[i].pFunc( sock, source, ulRecvAddr, usRecvPortNumber );\r
704                                 break;\r
705                         }\r
706                         /*[ Data Code Error ]*/\r
707                         else\r
708                         {\r
709                                 /* Send error response */\r
710                                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_WRONG_DATA, ulRecvAddr, usRecvPortNumber );\r
711                                 break;\r
712                         }\r
713                 }\r
714         }\r
715 \r
716         return iErrCode;\r
717 }\r
718 \r
719 /************************************************************************************/\r
720 /* This is an user defined function for Memory Read (Command: 0613)                                     */\r
721 /************************************************************************************/\r
722 #ifdef __TIRTOS__ \r
723 int slmp_server_memory_read( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
724 #elif _WIN32\r
725 int slmp_server_memory_read( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
726 #elif __linux__\r
727 int slmp_server_memory_read( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
728 #endif\r
729 {\r
730         uint8_t *pucRecvData;\r
731         uint8_t *pucSendData;\r
732         uint16_t usSendDataSize;\r
733         int iErrCode;\r
734         unsigned int i;\r
735         unsigned int uiHeadAddress = 0;\r
736         unsigned int uiWordLength = 0;\r
737 \r
738         if ( source->usSubCommand != 0x0000 )\r
739         {\r
740                 /* Send error response */\r
741                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
742 \r
743                 return iErrCode;\r
744         }\r
745 \r
746         /*[ Request data of Memory Read ]*/\r
747         pucRecvData = source->pucData;\r
748         /* Head Address */\r
749         uiHeadAddress = CONCAT_4BIN(pucRecvData[3], pucRecvData[2], pucRecvData[1], pucRecvData[0]);\r
750         /* Word Length */\r
751         uiWordLength = CONCAT_2BIN(pucRecvData[5], pucRecvData[4]);\r
752 \r
753         /* Checked a range of Memory */\r
754         if (( ServerInfo.pusMemory == NULL) || ( ServerInfo.uiMemorySize <= (uiHeadAddress+uiWordLength) ))\r
755         {\r
756                 /* Send error response */\r
757                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_DATA_LENGTH, ulRecvAddr, usRecvPortNumber );\r
758 \r
759                 return iErrCode;\r
760         }\r
761 \r
762         /*[ Response data of Memory Read ]*/\r
763         /* Read data of Memory */\r
764         usSendDataSize = 0;\r
765         pucSendData = aucSendData;\r
766         for( i = 0; i < uiWordLength; i ++ )\r
767         {\r
768                 pucSendData[i * 2] = SHIFT_R0(ServerInfo.pusMemory[uiHeadAddress + i]);\r
769                 pucSendData[( i * 2 ) + 1] = SHIFT_R8(ServerInfo.pusMemory[uiHeadAddress + i]);\r
770                 usSendDataSize += 2;\r
771         }\r
772 \r
773         /* Send response data */\r
774         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
775 \r
776         return iErrCode;\r
777 }\r
778 \r
779 /************************************************************************************/\r
780 /* This is an user defined function for Memory Write (Command: 1613)                            */\r
781 /************************************************************************************/\r
782 #ifdef __TIRTOS__ \r
783 int slmp_server_memory_write( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
784 #elif _WIN32\r
785 int slmp_server_memory_write( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
786 #elif __linux__\r
787 int slmp_server_memory_write( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
788 #endif\r
789 {\r
790         uint8_t *pucRecvData;\r
791         uint8_t *pucSendData;\r
792         uint16_t usSendDataSize;\r
793         int iErrCode;\r
794         unsigned int i;\r
795         unsigned int uiHeadAddress = 0;\r
796         unsigned int uiWordLength = 0;\r
797 \r
798         if ( source->usSubCommand != 0x0000 )\r
799         {\r
800                 /* Send error response */\r
801                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
802 \r
803                 return iErrCode;\r
804         }\r
805 \r
806         /*[ Request data of Memory Write ]*/\r
807         pucRecvData = source->pucData;\r
808         /* Head Address */\r
809         uiHeadAddress = CONCAT_4BIN(pucRecvData[3], pucRecvData[2], pucRecvData[1], pucRecvData[0]);\r
810         /* Word Length */\r
811         uiWordLength = CONCAT_2BIN(pucRecvData[5], pucRecvData[4]);\r
812 \r
813         /* Checked a range of Memory */\r
814         if (( ServerInfo.pusMemory == NULL) || ( ServerInfo.uiMemorySize <= (uiHeadAddress+uiWordLength) ))\r
815         {\r
816                 /* Send error response */\r
817                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_DATA_LENGTH, ulRecvAddr, usRecvPortNumber );\r
818 \r
819                 return iErrCode;\r
820         }\r
821 \r
822         /* Write data of Memory */\r
823         usSendDataSize = 0;\r
824         pucSendData = aucSendData;\r
825         for( i = 0; i < uiWordLength; i ++ )\r
826         {\r
827                 ServerInfo.pusMemory[uiHeadAddress + i] = SHIFT_L8(pucRecvData[(( i * 2 ) + 1) + 6]) + SHIFT_R0(pucRecvData[( i * 2 ) + 6]);\r
828         }\r
829 \r
830         usSendDataSize = 0;\r
831 \r
832         /* Send response data */\r
833         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
834 \r
835         return iErrCode;\r
836 }\r
837 \r
838 /************************************************************************************/\r
839 /* This is an user defined function for NodeSearch (Command: 0E30)                                      */\r
840 /* For CC-Link IEF Basic use.                                                                                                           */\r
841 /************************************************************************************/\r
842 #ifdef __TIRTOS__ \r
843 int slmp_server_node_search_basic( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
844 #elif _WIN32\r
845 int slmp_server_node_search_basic( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
846 #elif __linux__\r
847 int slmp_server_node_search_basic( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
848 #endif\r
849 {\r
850         uint8_t *pucRecvData;\r
851         uint8_t *pucSendData;\r
852         uint16_t usSendDataSize;\r
853         uint32_t ulSendDelayTime;               /* Timer-value of sending a broadcast */\r
854         int iErrCode;\r
855         int iIndex = 0, iLength;\r
856 \r
857         /* Subcommand Check */\r
858         if ( source->usSubCommand != 0x0000 )\r
859         {\r
860                 /* Send error response */\r
861                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
862 \r
863                 return iErrCode;\r
864         }\r
865 \r
866         /*[ Request data of NodeSearch ]*/\r
867         pucRecvData = source->pucData;\r
868         /* Client MAC Address */\r
869         /* Client IP Address Size */\r
870         /* Client IP Address */\r
871 \r
872         /*[ Check the response wait timer ]*/\r
873         if ( NodeSearchResponseInfo.iTimerFlag != 0 )\r
874         {\r
875                 /* Destruction of a packet */\r
876                 return SLMP_SERVER_ERR_OK;\r
877         }\r
878 \r
879         /*[ Response data of NodeSearch ]*/\r
880         pucSendData = aucSendDataNodeSearch;\r
881         /* Client MAC Address */\r
882         memcpy( &pucSendData[0], &pucRecvData[0], 6 );\r
883         iIndex = 6;\r
884         /* Client IP Address Size */\r
885         pucSendData[iIndex] = pucRecvData[6];\r
886         iIndex += 1;\r
887         /* Client IP Address */\r
888         memcpy( &pucSendData[iIndex], &pucRecvData[7], pucRecvData[6] );\r
889         iIndex += pucRecvData[6];\r
890         /* Server MAC Address */\r
891         memcpy( &pucSendData[iIndex], &ServerInfo.aucMacAddress, 6 );\r
892         iIndex += 6;\r
893         /* Server IP Address Size */\r
894         pucSendData[iIndex] = sizeof( ServerInfo.ulIpAddress );\r
895         iIndex += 1;\r
896         /* Server IP Address */\r
897         memcpy( &pucSendData[iIndex], &ServerInfo.ulIpAddress, sizeof( ServerInfo.ulIpAddress ) );\r
898         iIndex += sizeof( ServerInfo.ulIpAddress );\r
899         /* Server Subnet Mask */\r
900         memcpy( &pucSendData[iIndex], &ServerInfo.ulSubnetMask, sizeof( ServerInfo.ulSubnetMask ) );\r
901         iIndex += sizeof( ServerInfo.ulSubnetMask );\r
902         /* Server Default Gateway IP Address(fixed value:0xFFFFFFFF) */\r
903         pucSendData[iIndex    ] = 0xFF;\r
904         pucSendData[iIndex + 1] = 0xFF;\r
905         pucSendData[iIndex + 2] = 0xFF;\r
906         pucSendData[iIndex + 3] = 0xFF;\r
907         iIndex += 4;\r
908         /* Server Hostname Size(fixed value:0) */\r
909         iLength = 0x00;\r
910         pucSendData[iIndex] = 0x00;\r
911         iIndex += 1;\r
912         /* Server Hostname */\r
913         memcpy( &pucSendData[iIndex], ServerInfo.acHostname, iLength );\r
914         iIndex += iLength;\r
915         /* Server Vendor Code */\r
916         memcpy( &pucSendData[iIndex], &ServerInfo.usVenderCode, 2 );\r
917         iIndex += 2;\r
918         /* Server Model Code */\r
919         memcpy( &pucSendData[iIndex], &ServerInfo.ulModelCode, 4 );\r
920         iIndex += 4;\r
921         /* Server Machine Version */\r
922         memcpy( &pucSendData[iIndex], &ServerInfo.usMachineVersion, 2 );\r
923         iIndex += 2;\r
924         /* Target Unit IP Address Size(fixed value:4[IPv4]) */\r
925         pucSendData[iIndex] = 0x04;\r
926         iIndex += 1;\r
927         /* Target Unit IP Address(fixed value:0xFFFFFFFFFF) */\r
928         pucSendData[iIndex    ] = 0xFF;\r
929         pucSendData[iIndex + 1] = 0xFF;\r
930         pucSendData[iIndex + 2] = 0xFF;\r
931         pucSendData[iIndex + 3] = 0xFF;\r
932         iIndex += 4;\r
933         /* Target Port Number(fixed value:0xFFFF) */\r
934         pucSendData[iIndex    ] = 0xFF;\r
935         pucSendData[iIndex + 1] = 0xFF;\r
936         iIndex += 2;\r
937         /* Server Status */\r
938         memcpy( &pucSendData[iIndex], &ServerInfo.usStatus, 2 );\r
939         iIndex += 2;\r
940         /* Server Port Number */\r
941         pucSendData[iIndex    ] = SHIFT_R0(SLMP_SERVER_PORT_NUMBER);\r
942         pucSendData[iIndex + 1] = SHIFT_R8(SLMP_SERVER_PORT_NUMBER);\r
943         iIndex += 2;\r
944         /* Server Protocol(fixed value:1[UDP]) */\r
945         pucSendData[iIndex    ] = 1;\r
946         iIndex += 1;\r
947 \r
948         usSendDataSize = (uint16_t)iIndex;\r
949 \r
950         /* Set response data information */\r
951         memcpy( &NodeSearchResponseInfo.source, source, sizeof( NodeSearchResponseInfo.source ) );\r
952         inet_pton( AF_INET, "255.255.255.255", &NodeSearchResponseInfo.ulSendAddr );\r
953         NodeSearchResponseInfo.usPortNumber = usRecvPortNumber;\r
954         NodeSearchResponseInfo.pucSendData = pucSendData;\r
955         NodeSearchResponseInfo.usSendDataSize = usSendDataSize;\r
956         NodeSearchResponseInfo.sock = sock;\r
957 \r
958         /* Start the response wait timer */\r
959         ulSendDelayTime = timer_broadcast_send_wait_time( SLMP_SERVER_MAX_BROADCAST_SEND_WAIT_TIME );\r
960         timer_start( ulSendDelayTime, &NodeSearchResponseInfo.iTimerId,\r
961                                  &slmp_server_node_search_send_response_timeout, (void *)&NodeSearchResponseInfo );\r
962 \r
963         NodeSearchResponseInfo.iTimerFlag = 1;\r
964 \r
965         return SLMP_SERVER_ERR_OK;\r
966 }\r
967 \r
968 /************************************************************************************/\r
969 /* This is an user defined function of timeout for sending NodeSearch response.         */\r
970 /************************************************************************************/\r
971 void slmp_server_node_search_send_response_timeout( int iId, void *pCallbackArg )\r
972 {\r
973         SLMP_SERVER_SEND_RESPONSE_INFO  *pNodeSearchResponseInfo;\r
974 \r
975         pNodeSearchResponseInfo = (SLMP_SERVER_SEND_RESPONSE_INFO *)pCallbackArg;\r
976 \r
977         /* Send response data */\r
978         (void)slmp_server_slmp_send_response( pNodeSearchResponseInfo->sock, &pNodeSearchResponseInfo->source, pNodeSearchResponseInfo->ulSendAddr, pNodeSearchResponseInfo->usPortNumber,\r
979                                                                                   pNodeSearchResponseInfo->pucSendData, pNodeSearchResponseInfo->usSendDataSize );\r
980 \r
981         NodeSearchResponseInfo.iTimerFlag = 0;\r
982 \r
983         return;\r
984 }\r
985 \r
986 /************************************************************************************/\r
987 /* This is an user defined function for IPAddressSet (Command: 0E31)                            */\r
988 /* For CC-Link IEF Basic use.                                                                                                           */\r
989 /************************************************************************************/\r
990 #ifdef __TIRTOS__ \r
991 int slmp_server_ip_address_set_basic( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
992 #elif _WIN32\r
993 int slmp_server_ip_address_set_basic( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
994 #elif __linux__\r
995 int slmp_server_ip_address_set_basic( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
996 #endif\r
997 {\r
998         uint8_t *pucRecvData;\r
999         uint8_t *pucSendData;\r
1000         uint16_t usSendDataSize;\r
1001         int iErrCode;\r
1002         uint32_t ulSendAddr;\r
1003         int iIndex = 0;\r
1004         uint8_t aucClientMacAddr[6];\r
1005         int iIpAddressSize, iHostnameSize;\r
1006         uint8_t aucTemp[6];\r
1007         uint32_t ulRequestIpAddress, ulRequestSubnetMask, ulRequestDefaultGatewayIPAddress;\r
1008 \r
1009         /* Subcommand Check */\r
1010         if ( source->usSubCommand != 0x0000 )\r
1011         {\r
1012                 /* Send error response */\r
1013                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1014 \r
1015                 return iErrCode;\r
1016         }\r
1017 \r
1018         /*[ Request data of IPAddressSet ]*/\r
1019         pucRecvData = source->pucData;\r
1020         /* Server MAC Address */\r
1021         iIndex = 6 + 1 + pucRecvData[6];\r
1022         memcpy( aucTemp, &pucRecvData[iIndex], 6 );\r
1023 \r
1024         /*[ Check Server MAC Address ]*/\r
1025         if ( memcmp( ServerInfo.aucMacAddress, aucTemp, sizeof( aucTemp ) ) != 0 )\r
1026         {\r
1027                 /* Destruction of a packet */\r
1028                 return SLMP_SERVER_ERR_OK;\r
1029         }\r
1030 \r
1031         /* Client MAC Address */\r
1032         iIndex = 0;\r
1033         memcpy( aucClientMacAddr, &pucRecvData[iIndex], 6 );\r
1034         iIndex = 6;\r
1035         /* Client IP Address Size */\r
1036         iIpAddressSize = pucRecvData[iIndex];\r
1037         iIndex += 1;\r
1038         /* Client IP Address */\r
1039         iIndex += iIpAddressSize;\r
1040         /* Skip Server MAC Address */\r
1041         iIndex += 6;\r
1042         /* Server IP Address Size */\r
1043         iIpAddressSize = pucRecvData[iIndex];\r
1044         iIndex += 1;\r
1045         /* Server IP Address */\r
1046         memcpy( &ulRequestIpAddress, &pucRecvData[iIndex], iIpAddressSize );\r
1047         iIndex += iIpAddressSize;\r
1048         /* Server Subnet Mask */\r
1049         memcpy( &ulRequestSubnetMask, &pucRecvData[iIndex], iIpAddressSize );\r
1050         iIndex += iIpAddressSize;\r
1051         /* Server Default Gateway IP Address */\r
1052         memcpy( &ulRequestDefaultGatewayIPAddress, &pucRecvData[iIndex], iIpAddressSize );\r
1053         iIndex += iIpAddressSize;\r
1054         /* Server Hostname Size */\r
1055         iHostnameSize = pucRecvData[iIndex];\r
1056         iIndex += 1;\r
1057         /* Server Hostname */\r
1058         /* Do not support */\r
1059         iIndex += iHostnameSize;\r
1060         /* Target Unit IP Address Size */\r
1061         /* Do not support */\r
1062         iIpAddressSize = pucRecvData[iIndex];\r
1063         iIndex += 1;\r
1064         /* Target Unit IP Address */\r
1065         /* Do not support */\r
1066         iIndex += iIpAddressSize;\r
1067         /* Target Port Number */\r
1068         /* Do not support */\r
1069         iIndex += 2;\r
1070         /* Server Protocol */\r
1071         /* Do not support */\r
1072         iIndex += 1;\r
1073 \r
1074         /*[ Response data of IPAddressSet ]*/\r
1075         pucSendData = aucSendData;\r
1076         /* Client MAC Address */\r
1077         memcpy( &pucSendData[0], aucClientMacAddr, 6 );\r
1078         iIndex = 6;\r
1079 \r
1080         usSendDataSize = (uint16_t)iIndex;\r
1081 \r
1082         /* Execute user callback function */\r
1083         if ( pUserIpAddresSetFunc != NULL )\r
1084         {\r
1085                 pUserIpAddresSetFunc( ulRequestIpAddress, ulRequestSubnetMask );\r
1086         }\r
1087 \r
1088         /* Sets a broadcast address */\r
1089         inet_pton( AF_INET, "255.255.255.255", &ulSendAddr );\r
1090 \r
1091         /* Send response data */\r
1092         iErrCode = slmp_server_slmp_send_response( sock, source, ulSendAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1093 \r
1094         return iErrCode;\r
1095 }\r
1096 \r
1097 /************************************************************************************/\r
1098 /* This is an user defined function for DeviceInfoCompare (Command: 0E32)                       */\r
1099 /************************************************************************************/\r
1100 #ifdef __TIRTOS__ \r
1101 int slmp_server_device_info_compare( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1102 #elif _WIN32\r
1103 int slmp_server_device_info_compare( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1104 #elif __linux__\r
1105 int slmp_server_device_info_compare( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1106 #endif\r
1107 {\r
1108         uint8_t *pucRecvData;\r
1109         uint8_t *pucSendData;\r
1110         uint16_t usSendDataSize;\r
1111         int iErrCode;\r
1112         int iIndex = 0;\r
1113         uint16_t usCompareTarget;               /* Compare Target  */\r
1114         uint16_t usTempVenderCode;              /* Server Vendor Code */\r
1115         uint32_t ulTempTypeNameCode;    /* Server Model Code */\r
1116         uint16_t usTempVersion;                 /* Server Machine Version */\r
1117         uint16_t usCompareResult;               /* Compare Result  */\r
1118 \r
1119         /* Subcommand Check */\r
1120         if ( source->usSubCommand != 0x0000 )\r
1121         {\r
1122                 /* Send error response */\r
1123                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1124 \r
1125                 return iErrCode;\r
1126         }\r
1127 \r
1128         /*[ Request data of DeviceInfoCompare ]*/\r
1129         pucRecvData = source->pucData;\r
1130         /* Compare Target */\r
1131         usCompareTarget = SHIFT_L8(pucRecvData[1])+SHIFT_L0(pucRecvData[0]);\r
1132         /* Vendor Code */\r
1133         usTempVenderCode = SHIFT_L8(pucRecvData[3])+SHIFT_L0(pucRecvData[2]);\r
1134         /* Model Code */\r
1135         ulTempTypeNameCode = SHIFT_L24(pucRecvData[7])+SHIFT_L16(pucRecvData[6])+\r
1136                                                  SHIFT_L8(pucRecvData[5])+SHIFT_L0(pucRecvData[4]);\r
1137         /* MachineVersion */\r
1138         usTempVersion = SHIFT_L8(pucRecvData[9])+SHIFT_L0(pucRecvData[8]);\r
1139 \r
1140         /*[ Response data of DeviceInfoCompare ]*/\r
1141         pucSendData = aucSendData;\r
1142         iIndex = 0;\r
1143         /* Compare Target */\r
1144         memcpy( &pucSendData[iIndex], &usCompareTarget, 2 );\r
1145         iIndex += 2;\r
1146 \r
1147         usCompareResult = 0x0000;\r
1148         /* Compare the Vendor Code */\r
1149         if ( (usCompareTarget & 0x0001) == 0x0001 )\r
1150         {\r
1151                 if ( ServerInfo.usVenderCode != usTempVenderCode )\r
1152                 {\r
1153                         usCompareResult |= 0x0001;\r
1154                 }\r
1155         }\r
1156         /* Compare the Model Code */\r
1157         if ( (usCompareTarget & 0x0002) == 0x0002 )\r
1158         {\r
1159                 if ( ServerInfo.ulModelCode != ulTempTypeNameCode )\r
1160                 {\r
1161                         usCompareResult |= 0x0002;\r
1162                 }\r
1163         }\r
1164         /* Compare the Machine Version */\r
1165         if ( (usCompareTarget & 0x0004) == 0x0004 )\r
1166         {\r
1167                 if ( ServerInfo.usMachineVersion != usTempVersion )\r
1168                 {\r
1169                         usCompareResult |= 0x0004;\r
1170 \r
1171                         /* Detailed Information */\r
1172                         if ( ServerInfo.usMachineVersion > usTempVersion )\r
1173                         {\r
1174                                 usCompareResult |= 0x4000;\r
1175                         }\r
1176 \r
1177                         else if ( ServerInfo.usMachineVersion < usTempVersion )\r
1178                         {\r
1179                                 usCompareResult |= 0x8000;\r
1180                         }\r
1181 \r
1182                         else\r
1183                         {\r
1184                                 usCompareResult |= 0xC000;\r
1185                         }\r
1186                 }\r
1187         }\r
1188         /* Compare Result */\r
1189         memcpy( &pucSendData[iIndex], &usCompareResult, 2 );\r
1190         iIndex += 2;\r
1191 \r
1192         usSendDataSize = (uint16_t)iIndex;\r
1193 \r
1194         /* Send response data */\r
1195         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1196 \r
1197         return iErrCode;\r
1198 }\r
1199 \r
1200 /************************************************************************************/\r
1201 /* This is an user defined function for ParameterGet (Command: 0E33)                            */\r
1202 /************************************************************************************/\r
1203 #ifdef __TIRTOS__ \r
1204 int slmp_server_parameter_get( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1205 #elif _WIN32\r
1206 int slmp_server_parameter_get( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1207 #elif __linux__\r
1208 int slmp_server_parameter_get( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1209 #endif\r
1210 {\r
1211         uint8_t *pucRecvData;\r
1212         uint8_t *pucSendData;\r
1213         uint16_t usSendDataSize;\r
1214         int iErrCode, iEndCode;\r
1215         int i, j;\r
1216         int iIndex = 0;\r
1217         uint16_t usGetParameter;\r
1218         uint16_t ausParameterId[3];\r
1219         uint16_t usParameterSize;\r
1220         uint8_t *pucParameterData;\r
1221 \r
1222         /* Subcommand Check */\r
1223         if ( source->usSubCommand != 0x0000 )\r
1224         {\r
1225                 /* Send error response */\r
1226                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1227 \r
1228                 return iErrCode;\r
1229         }\r
1230 \r
1231         /*[ Request data of ParameterGet ]*/\r
1232         pucRecvData = source->pucData;\r
1233         /* Parameter Number */\r
1234         usGetParameter = SHIFT_L8(pucRecvData[1])+SHIFT_L0(pucRecvData[0]);\r
1235 \r
1236         if ( (usGetParameter == 0) || (3 < usGetParameter) )\r
1237         {\r
1238                 /* Send error response */\r
1239                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_WRONG_DATA, ulRecvAddr, usRecvPortNumber );\r
1240 \r
1241                 return iErrCode;\r
1242         }\r
1243 \r
1244         /* ParameterID */\r
1245         for( i = 0; i < usGetParameter; i ++ )\r
1246         {\r
1247                 ausParameterId[i] = SHIFT_L8(pucRecvData[( i * 2 + 1 ) + 2])+SHIFT_L0(pucRecvData[( i * 2 ) + 2]);\r
1248         }\r
1249 \r
1250         /*[ Response data of ParameterGet ]*/\r
1251         pucSendData = aucSendData;\r
1252         /* Parameter Number */\r
1253         pucSendData[0] = SHIFT_R0(usGetParameter);\r
1254         pucSendData[1] = SHIFT_R8(usGetParameter);\r
1255         iIndex += 2;\r
1256         for( i = 0; i < usGetParameter; i ++ )\r
1257         {\r
1258                 /* Execute user callback function */\r
1259                 if ( pUserSlaveParameterGetFunc != NULL )\r
1260                 {\r
1261                         iEndCode = pUserSlaveParameterGetFunc( ausParameterId[i], &usParameterSize, &pucParameterData );\r
1262                         if ( iEndCode != SLMP_ERR_OK )\r
1263                         {\r
1264                                 /* Send error response */\r
1265                                 iErrCode = slmp_server_slmp_send_err_response( sock, source, (uint16_t)iEndCode, ulRecvAddr, usRecvPortNumber );\r
1266 \r
1267                                 return iErrCode;\r
1268                         }\r
1269                         /* ParameterID */\r
1270                         pucSendData[iIndex] = SHIFT_R0(ausParameterId[i]);\r
1271                         pucSendData[iIndex+1] = SHIFT_R8(ausParameterId[i]);\r
1272                         /* Parameter Size */\r
1273                         pucSendData[iIndex+2] = SHIFT_R0(usParameterSize);\r
1274                         pucSendData[iIndex+3] = SHIFT_R8(usParameterSize);\r
1275                         /* Parameter Data */\r
1276                         for( j = 0; j < usParameterSize; j ++ )\r
1277                         {\r
1278                                 pucSendData[iIndex + 4 + j] = pucParameterData[j];\r
1279                         }\r
1280                         iIndex += 4 + usParameterSize;\r
1281                 }\r
1282                 else\r
1283                 {\r
1284                         /* Send error response */\r
1285                         iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_NO_EXIST_PARAM_ID, ulRecvAddr, usRecvPortNumber );\r
1286 \r
1287                         return iErrCode;\r
1288                 }\r
1289         }\r
1290 \r
1291         usSendDataSize = (uint16_t)iIndex;\r
1292 \r
1293         /* Send response data */\r
1294         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1295 \r
1296         return iErrCode;\r
1297 }\r
1298 \r
1299 /************************************************************************************/\r
1300 /* This is an user defined function for ParameterSet (Command: 0E34)                            */\r
1301 /************************************************************************************/\r
1302 #ifdef __TIRTOS__ \r
1303 int slmp_server_parameter_set( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1304 #elif _WIN32\r
1305 int slmp_server_parameter_set( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1306 #elif __linux__\r
1307 int slmp_server_parameter_set( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1308 #endif\r
1309 {\r
1310         uint8_t *pucRecvData;\r
1311         uint8_t *pucSendData;\r
1312         uint16_t usSendDataSize;\r
1313         int iErrCode, iEndCode;\r
1314         int i;\r
1315         int iIndex = 0;\r
1316         uint16_t usSetParameter;\r
1317         uint16_t usParameterId;\r
1318         uint16_t usParameterSize;\r
1319         static uint8_t aucParameterData[512 + 1];\r
1320 \r
1321         /* Subcommand Check */\r
1322         if ( source->usSubCommand != 0x0000 )\r
1323         {\r
1324                 /* Send error response */\r
1325                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1326 \r
1327                 return iErrCode;\r
1328         }\r
1329 \r
1330         /* Check the ParameterSet Start */ \r
1331         if ( iParameterSetFlag == 0 )\r
1332         {\r
1333                 /* Send error response */\r
1334                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_CAN_NOT_PARAMETER_SET, ulRecvAddr, usRecvPortNumber );\r
1335 \r
1336                 return iErrCode;\r
1337         }\r
1338         else\r
1339         {\r
1340                 ulParameterSetTimer = timer_get_time();\r
1341         }\r
1342 \r
1343         /*[ Request data of ParameterSet ]*/\r
1344         pucRecvData = source->pucData;\r
1345         /* Parameter Number */\r
1346         usSetParameter = SHIFT_L8(pucRecvData[1]) + SHIFT_L0(pucRecvData[0]);\r
1347         iIndex += 2;\r
1348 \r
1349         if ( (usSetParameter == 0) || (3 < usSetParameter) )\r
1350         {\r
1351                 /* Send error response */\r
1352                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_WRONG_DATA, ulRecvAddr, usRecvPortNumber );\r
1353 \r
1354                 return iErrCode;\r
1355         }\r
1356                 \r
1357         for( i = 0; i < usSetParameter; i ++ )\r
1358         {\r
1359                 /* ParameterID */\r
1360                 usParameterId = SHIFT_L8(pucRecvData[iIndex + 1]) + SHIFT_L0(pucRecvData[iIndex]);\r
1361 \r
1362                 /* Parameter Size */\r
1363                 usParameterSize = SHIFT_L8(pucRecvData[iIndex + 3]) + SHIFT_L0(pucRecvData[iIndex + 2]);\r
1364 \r
1365                 /* Parameter Data */\r
1366                 memcpy( aucParameterData, &pucRecvData[iIndex + 4], usParameterSize );\r
1367                 aucParameterData[ usParameterSize ] = 0x00;\r
1368 \r
1369                 /* Execute user callback function */\r
1370                 if ( pUserSlaveParameterSetFunc != NULL )\r
1371                 {\r
1372                         iEndCode = pUserSlaveParameterSetFunc( usParameterId, usParameterSize, aucParameterData );\r
1373                         if ( iEndCode != SLMP_ERR_OK )\r
1374                         {\r
1375                                 /* Send error response */\r
1376                                 iErrCode = slmp_server_slmp_send_err_response( sock, source, (uint16_t)iEndCode, ulRecvAddr, usRecvPortNumber );\r
1377 \r
1378                                 return iErrCode;\r
1379                         }\r
1380                 }\r
1381                 else\r
1382                 {\r
1383                         /* Send error response */\r
1384                         iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_NO_EXIST_PARAM_ID, ulRecvAddr, usRecvPortNumber );\r
1385 \r
1386                         return iErrCode;\r
1387                 }\r
1388 \r
1389                 iIndex += 4 + usParameterSize;\r
1390         }\r
1391 \r
1392         /*[ Response data of ParameterSet ]*/\r
1393         pucSendData = aucSendData;\r
1394 \r
1395         usSendDataSize = 0;\r
1396 \r
1397         /* Send response data */\r
1398         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1399 \r
1400         return iErrCode;\r
1401 }\r
1402 \r
1403 /************************************************************************************/\r
1404 /* This is an user defined function for ParameterSetStart (Command: 0E35)                       */\r
1405 /************************************************************************************/\r
1406 #ifdef __TIRTOS__ \r
1407 int slmp_server_parameter_set_start( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1408 #elif _WIN32\r
1409 int slmp_server_parameter_set_start( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1410 #elif __linux__\r
1411 int slmp_server_parameter_set_start( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1412 #endif\r
1413 {\r
1414         uint8_t *pucSendData;\r
1415         uint16_t usSendDataSize;\r
1416         int iErrCode;\r
1417         uint32_t ulCheckTimeout;\r
1418 \r
1419         /* Subcommand Check */\r
1420         if ( source->usSubCommand != 0x0000 )\r
1421         {\r
1422                 /* Send error response */\r
1423                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1424 \r
1425                 return iErrCode;\r
1426         }\r
1427 \r
1428         /* Check the ParameterSet Flag */ \r
1429         if ( iParameterSetFlag == 1 )\r
1430         {\r
1431                 /* Check the ParameterSet Timeout */ \r
1432                 ulCheckTimeout = timer_get_time() - ulParameterSetTimer;\r
1433 \r
1434                 if ( SLMP_SERVER_SET_PARAMETER_TIMEOUT <= ulCheckTimeout )\r
1435                 {\r
1436                         /* Start ParameterSet */ \r
1437                         ulParameterSetTimer = timer_get_time();\r
1438                 }\r
1439                 else\r
1440                 {\r
1441                         /* Send error response */\r
1442                         iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_CAN_NOT_PARAMETER_SET, ulRecvAddr, usRecvPortNumber );\r
1443 \r
1444                         return iErrCode;\r
1445                 }\r
1446         }\r
1447         else\r
1448         {\r
1449                 /* Sets the ParameterSet Flag Disabled */ \r
1450                 iParameterSetFlag = 1;\r
1451                 ulParameterSetTimer = timer_get_time();\r
1452         }\r
1453 \r
1454         /*[ Response data of ParameterSetStart ]*/\r
1455         pucSendData = aucSendData;\r
1456 \r
1457         usSendDataSize = 0;\r
1458 \r
1459         /* Send response data */\r
1460         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1461 \r
1462         return iErrCode;\r
1463 }\r
1464 \r
1465 /************************************************************************************/\r
1466 /* This is an user defined function for ParameterSetEnd (Command: 0E36)                         */\r
1467 /************************************************************************************/\r
1468 #ifdef __TIRTOS__ \r
1469 int slmp_server_parameter_set_end( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1470 #elif _WIN32\r
1471 int slmp_server_parameter_set_end( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1472 #elif __linux__\r
1473 int slmp_server_parameter_set_end( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1474 #endif\r
1475 {\r
1476         uint8_t *pucSendData;\r
1477         uint16_t usSendDataSize;\r
1478         int iErrCode, iEndCode;\r
1479 \r
1480         /* Subcommand Check */\r
1481         if ( source->usSubCommand != 0x0000 )\r
1482         {\r
1483                 /* Send error response */\r
1484                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1485 \r
1486                 return iErrCode;\r
1487         }\r
1488 \r
1489         /* Execute user callback function */\r
1490         if ( pUserSlaveParameterSetEndFunc != NULL )\r
1491         {\r
1492                 iEndCode = pUserSlaveParameterSetEndFunc();\r
1493                 if ( iEndCode != SLMP_ERR_OK )\r
1494                 {\r
1495                         /* Send error response */\r
1496                         iErrCode = slmp_server_slmp_send_err_response( sock, source, (uint16_t)iEndCode, ulRecvAddr, usRecvPortNumber );\r
1497 \r
1498                         return iErrCode;\r
1499                 }\r
1500         }\r
1501 \r
1502         /* Sets the ParameterSet Flag Enable */ \r
1503         iParameterSetFlag = 0;\r
1504 \r
1505         /*[ Response data of ParameterSetEnd ]*/\r
1506         pucSendData = aucSendData;\r
1507 \r
1508         usSendDataSize = 0;\r
1509 \r
1510         /* Send response data */\r
1511         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1512 \r
1513         return iErrCode;\r
1514 }\r
1515 \r
1516 /************************************************************************************/\r
1517 /* This is an user defined function for ParameterSetCancel (Command: 0E3A)                      */\r
1518 /************************************************************************************/\r
1519 #ifdef __TIRTOS__ \r
1520 int slmp_server_parameter_set_cancel( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1521 #elif _WIN32\r
1522 int slmp_server_parameter_set_cancel( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1523 #elif __linux__\r
1524 int slmp_server_parameter_set_cancel( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1525 #endif\r
1526 {\r
1527         uint8_t *pucSendData;\r
1528         uint16_t usSendDataSize;\r
1529         int iErrCode;\r
1530 \r
1531         /* Subcommand Check */\r
1532         if ( source->usSubCommand != 0x0000 )\r
1533         {\r
1534                 /* Send error response */\r
1535                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1536 \r
1537                 return iErrCode;\r
1538         }\r
1539 \r
1540         /* Sets the ParameterSet Flag Enabled */ \r
1541         iParameterSetFlag = 0;\r
1542 \r
1543         /*[ Response data of ParameterSetCancel ]*/\r
1544         pucSendData = aucSendData;\r
1545 \r
1546         usSendDataSize = 0;\r
1547 \r
1548         /* Send response data */\r
1549         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1550 \r
1551         return iErrCode;\r
1552 }\r
1553 \r
1554 /************************************************************************************/\r
1555 /* This is an user defined function for CommunicationSettingGet (Command: 0E45)         */\r
1556 /************************************************************************************/\r
1557 #ifdef __TIRTOS__ \r
1558 int slmp_server_communication_setting_get( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1559 #elif _WIN32\r
1560 int slmp_server_communication_setting_get( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1561 #elif __linux__\r
1562 int slmp_server_communication_setting_get( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1563 #endif\r
1564 {\r
1565         uint8_t *pucRecvData;\r
1566         uint8_t *pucSendData;\r
1567         uint16_t usSendDataSize;\r
1568         int iErrCode;\r
1569         int iIndex = 0;\r
1570         uint16_t usGetTarget;\r
1571         uint32_t ulTimeoutValue;\r
1572 \r
1573         if ( source->usSubCommand != 0x0000 )\r
1574         {\r
1575                 /* Send error response */\r
1576                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1577 \r
1578                 return iErrCode;\r
1579         }\r
1580 \r
1581         /*[ Request data of CommunicationSettingGet ]*/\r
1582         pucRecvData = source->pucData;\r
1583         /* Get Target */\r
1584         usGetTarget = SHIFT_L8(pucRecvData[1]) + SHIFT_L0(pucRecvData[0]);\r
1585 \r
1586         /*[ Response data of CommunicationSettingGet ]*/\r
1587         pucSendData = aucSendData;\r
1588         iIndex = 0;\r
1589         /* Get Target */\r
1590         memcpy( &pucSendData[iIndex], &usGetTarget, 2 );\r
1591         iIndex += 2;\r
1592 \r
1593         /* Port Number */\r
1594         if ( (usGetTarget & 0x0001) == 0x0001 )\r
1595         {\r
1596                 pucSendData[iIndex    ] = SHIFT_R0(ServerInfo.usPortNumber);\r
1597                 pucSendData[iIndex + 1] = SHIFT_R8(ServerInfo.usPortNumber);\r
1598         }\r
1599         else\r
1600         {\r
1601                 memset( &pucSendData[iIndex], 0, 2 );\r
1602         }\r
1603         iIndex += 2;\r
1604 \r
1605         /* Timeout Value */\r
1606         if ( (usGetTarget & 0x0002) == 0x0002 )\r
1607         {\r
1608                 ulTimeoutValue = SLMP_SERVER_TIMEOUT;\r
1609                 memcpy( &pucSendData[iIndex], &ulTimeoutValue, 4 );\r
1610         }\r
1611         else\r
1612         {\r
1613                 memset( &pucSendData[iIndex], 0, 4 );\r
1614         }\r
1615         iIndex += 4;\r
1616 \r
1617         usSendDataSize = (uint16_t)iIndex;\r
1618 \r
1619         /* Send response data */\r
1620         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1621 \r
1622         return iErrCode;\r
1623 }\r
1624 \r
1625 /************************************************************************************/\r
1626 /* This is an user defined function for ReadTypeName (Command: 0101)                            */\r
1627 /************************************************************************************/\r
1628 #ifdef __TIRTOS__ \r
1629 int slmp_server_read_type_name( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1630 #elif _WIN32\r
1631 int slmp_server_read_type_name( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1632 #elif __linux__\r
1633 int slmp_server_read_type_name( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1634 #endif\r
1635 {\r
1636         uint8_t *pucSendData;\r
1637         uint16_t usSendDataSize;\r
1638         int iErrCode;\r
1639         int iIndex = 0;\r
1640 \r
1641         /*[ Response data of ReadTypeName ]*/\r
1642         pucSendData = aucSendData;\r
1643         iIndex = 0;\r
1644         /* Type Name */\r
1645         memcpy( &pucSendData[iIndex], &ServerInfo.acTypeName, 16 );\r
1646         iIndex += 16;\r
1647         /* Type Name Code */\r
1648         pucSendData[iIndex    ] = SHIFT_R0(ServerInfo.usTypeNameCode);\r
1649         pucSendData[iIndex + 1] = SHIFT_R8(ServerInfo.usTypeNameCode);\r
1650         iIndex += 2;\r
1651 \r
1652         usSendDataSize = (uint16_t)iIndex;\r
1653 \r
1654         /* Send response data */\r
1655         iErrCode = slmp_server_slmp_send_response( sock, source, ulRecvAddr, usRecvPortNumber, pucSendData, usSendDataSize );\r
1656 \r
1657         return iErrCode;\r
1658 }\r
1659 \r
1660 /************************************************************************************/\r
1661 /* This is an user defined function for RemoteReset (Command: 1006)                                     */\r
1662 /************************************************************************************/\r
1663 #ifdef __TIRTOS__ \r
1664 int slmp_server_remote_reset( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1665 #elif _WIN32\r
1666 int slmp_server_remote_reset( SOCKET sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1667 #elif __linux__\r
1668 int slmp_server_remote_reset( int sock, const SLMP_INFO *source, uint32_t ulRecvAddr, uint16_t usRecvPortNumber )\r
1669 #endif\r
1670 {\r
1671         int iErrCode = 0, iEndCode = 0;\r
1672 \r
1673         /* Execute user callback function */\r
1674         if ( pUserRemoteResetFunc != NULL )\r
1675         {\r
1676                 iEndCode = pUserRemoteResetFunc();\r
1677                 if ( iEndCode != SLMP_ERR_OK )\r
1678                 {\r
1679                         /* Send error response */\r
1680                         iErrCode = slmp_server_slmp_send_err_response( sock, source, (uint16_t)iEndCode, ulRecvAddr, usRecvPortNumber );\r
1681 \r
1682                         return iErrCode;\r
1683                 }\r
1684         }\r
1685         else\r
1686         {\r
1687                 /* Send error response */\r
1688                 iErrCode = slmp_server_slmp_send_err_response( sock, source, SLMP_ERR_COMMAND_SUBCOMMAND, ulRecvAddr, usRecvPortNumber );\r
1689         }\r
1690 \r
1691         return iErrCode;\r
1692 }\r