Add license
[apps/agl-service-can-low-level.git] / iotbzh-CAN-binding.c
1 /*
2  * Copyright (C) 2015, 2016 "IoT.bzh"
3  * Author "Romain Forlot" <romain.forlot@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #define _GNU_SOURCE
18
19 #include <string.h>
20 #include <stdbool.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/ioctl.h>
25 #include <net/if.h>
26 #include <sys/time.h>
27 #include <linux/can.h>
28 #include <math.h>
29 #include <fcntl.h>
30 #include <systemd/sd-event.h>
31
32 #include <json-c/json.h>
33
34 #include <afb/afb-binding.h>
35 #include <afb/afb-service-itf.h>
36
37 /*****************************************************************************************/
38 /*****************************************************************************************/
39 /**                                                                                     **/
40 /**                                                                                     **/
41 /**        SECTION: GLOBAL VARIABLES                                                    **/
42 /**                                                                                     **/
43 /**                                                                                     **/
44 /*****************************************************************************************/
45 /*****************************************************************************************/
46
47 /*
48  * Interface between the daemon and the binding
49  */
50 static const struct afb_binding_interface *interface;
51
52 /*
53  * the type of position expected
54  *
55  * here, this type is the selection of protocol
56  */
57 enum type {
58         type_OBDII,
59         type_CAN,
60         type_DEFAULT = type_CAN,
61         type_INVALID = -1
62 };
63
64 #define type_size sizeof(enum type)-2
65
66 /*
67  * names of the types
68  */
69 static const char * const type_NAMES[type_size] = {
70         "OBDII",
71         "CAN"
72 };
73
74 struct can_handler {
75         int socket;
76         char *device;
77         char *send_msg;
78         char *read_msg;
79         struct sockaddr_can txAddress;
80 };
81
82 static struct can_handler can_handler = {
83         .socket = -1,
84         .device = "vcan0"
85 };
86
87 struct can_frame can_frame;
88
89 /*****************************************************************************************/
90 /*****************************************************************************************/
91 /**                                                                                     **/
92 /**                                                                                     **/
93 /**        SECTION: UTILITY FUNCTIONS                                                   **/
94 /**                                                                                     **/
95 /**                                                                                     **/
96 /*****************************************************************************************/
97 /*****************************************************************************************/
98
99 /*
100  * @brief Retry a function 3 times
101  *
102  * @param int function(): function that return an int wihtout any parameter
103  *
104  * @ return : 0 if ok, -1 if failed
105  *
106  */
107 static int retry( int(*func)());
108 static int retry( int(*func)())
109 {
110         int i;
111
112         for (i=0;i<4;i++)
113         {
114                 if ( (*func)() >= 0)
115                 {
116                         return 0;
117                 }
118                 usleep(100000);
119         }
120         return -1;
121 }
122
123 /*****************************************************************************************/
124 /*****************************************************************************************/
125 /**                                                                                     **/
126 /**                                                                                     **/
127 /**        SECTION: HANDLE CAN DEVICE                                                   **/
128 /**                                                                                     **/
129 /**                                                                                     **/
130 /*****************************************************************************************/
131 /*****************************************************************************************/
132
133 static int connect_to_event_loop();
134
135 /*
136  * Parse the CAN frame data payload as a CANopen packet
137  * TODO: define can_frame_t
138  */
139 int can_frame_parse(canopen_frame_t *canopen_frame, struct can_frame *can_frame)
140 {
141     int i;
142
143     if (canopen_frame == NULL || can_frame == NULL)
144     {
145         return -1;
146     }
147
148     bzero((void *)canopen_frame, sizeof(canopen_frame_t));
149
150     //
151     // Parse basic protocol fields
152     //
153
154     if (can_frame->can_id & CAN_EFF_FLAG)
155     {
156         canopen_frame->type = CANOPEN_FLAG_EXTENDED;
157         canopen_frame->id   = can_frame->can_id & CAN_EFF_MASK;
158     }
159     else
160     {
161         canopen_frame->type = CANOPEN_FLAG_STANDARD;
162         canopen_frame->function_code = (can_frame->can_id & 0x00000780U) >> 7;
163         canopen_frame->id            = (can_frame->can_id & 0x0000007FU);
164     }
165
166     canopen_frame->rtr = (can_frame->can_id & CAN_RTR_FLAG) ?
167                          CANOPEN_FLAG_RTR : CANOPEN_FLAG_NORMAL;
168
169     canopen_frame->data_len = can_frame->can_dlc;
170     for (i = 0; i < can_frame->can_dlc; i++)
171     {
172         canopen_frame->payload.data[i] = can_frame->data[i];
173     }
174
175     //
176     // Parse payload data
177     //
178
179     // NMT protocol
180     switch (canopen_frame->function_code)
181     {
182         // ---------------------------------------------------------------------
183         // Network ManagemenT frame: Module Control
184         //
185         case CANOPEN_FC_NMT_MC:
186
187             break;
188
189         // ---------------------------------------------------------------------
190         // Network ManagemenT frame: Node Guarding
191         //
192         case CANOPEN_FC_NMT_NG:
193
194
195             break;
196
197         //default:
198             // unhandled type...
199     }
200
201     return 0;
202 }
203
204 /*
205  * Read on CAN bus
206  */
207 static int read_can()
208 {
209         int byte_read;
210
211         byte_read = read(can_handler.socket, &can_frame, sizeof(struct can_frame));
212
213         if (byte_read < 0)
214         {
215                 ERROR(interface, "Error reading CAN bus");
216                 return -1;
217         }
218
219         if (byte_read < (int)sizeof(struct can_frame))
220         {
221                 ERROR(interface, "CAN frame incomplete");
222                 return -2;
223         }
224 }
225
226 /*
227  * called on an event on the CAN bus
228  */
229 static int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata)
230 {
231         /* read available data */
232         if ((revents & EPOLLIN) != 0)
233         {
234                 read_can();
235 //              event_send();
236         }
237
238         /* check if error or hangup */
239         if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0)
240         {
241                 sd_event_source_unref(s);
242                 close(fd);
243                 connect_to_event_loop();
244         }
245
246         return 0;
247 }
248
249 /*
250  * open the can socket
251  */
252 static int open_can_dev()
253 {
254         struct ifreq ifr;
255         struct timeval timeout = {1,0};
256
257         DEBUG(interface, "open_can_dev: CAN Handler socket : %d", can_handler.socket);
258         close(can_handler.socket);
259
260         can_handler.socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
261         if (can_handler.socket < 0)
262         {
263                 ERROR(interface, "open_can_dev: socket could not be created");
264         }
265         else
266         {
267                 // Set timeout for read
268                 setsockopt(can_handler.socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
269                 // Attempts to open a socket to CAN bus
270                 strcpy(ifr.ifr_name, can_handler.device);
271                 if(ioctl(can_handler.socket, SIOCGIFINDEX, &ifr) < 0)
272                 {
273                         ERROR(interface, "open_can_dev: ioctl failed");
274                 }
275                 else
276                 {
277                         can_handler.txAddress.can_family = AF_CAN;
278                         can_handler.txAddress.can_ifindex = ifr.ifr_ifindex;
279
280                         // And bind it to txAddress
281                         if (bind(can_handler.socket, (struct sockaddr *)&can_handler.txAddress, sizeof(can_handler.txAddress)) < 0)
282                         {
283                                 ERROR(interface, "open_can_dev: bind failed");
284                         }
285                         else
286                         {
287                                 fcntl(can_handler.socket, F_SETFL, O_NONBLOCK);
288                                 return 0;
289                         }
290                 }
291                 close(can_handler.socket);
292                 can_handler.socket = -1;
293         }
294         return -1;
295 }
296
297 static int write_can()
298 {
299         int rc = 0;
300
301         rc = can_handler.socket;
302         if (rc >= 0)
303         {
304 /*
305  * TODO change old hvac write can frame to generic on_event
306  */
307                 can_frame.can_id = 0x30;
308                 can_frame.can_dlc = 8;
309                 can_frame.data[0] = 0;
310                 can_frame.data[1] = 0;
311                 can_frame.data[2] = 0;
312                 can_frame.data[3] = 0xf0;
313                 can_frame.data[4] = 0;
314                 can_frame.data[5] = 1;
315                 can_frame.data[6] = 0;
316                 can_frame.data[7] = 0;
317
318                 DEBUG(interface, "%s: %d %d [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
319                         can_handler.send_msg,
320                         can_frame.can_id, can_frame.can_dlc,
321                         can_frame.data[0], can_frame.data[1], can_frame.data[2], can_frame.data[3],
322                         can_frame.data[4], can_frame.data[5], can_frame.data[6], can_frame.data[7]);
323
324                 rc = sendto(can_handler.socket, &can_frame, sizeof(struct can_frame), 0,
325                             (struct sockaddr*)&can_handler.txAddress, sizeof(can_handler.txAddress));
326                 if (rc < 0)
327                 {
328                         ERROR(interface, "Sending CAN frame failed.");
329                 }
330         }
331         else
332         {
333                 ERROR(interface, "socket not initialized. Attempt to reopen can device socket.");
334                 retry(open_can_dev);
335         }
336         return rc;
337 }
338
339 /***************************************************************************************/
340 /***************************************************************************************/
341 /**                                                                                   **/
342 /**                                                                                   **/
343 /**       SECTION: MANAGING EVENTS                                                    **/
344 /**                                                                                   **/
345 /**                                                                                   **/
346 /***************************************************************************************/
347 /***************************************************************************************/
348
349 /*
350  * get or create an event handler for the type
351  * TODO: implement function and handle retrieve or create an event as needed
352  */
353 static struct event *event_get(enum type type)
354 {
355
356 }
357
358 static struct event *event_of_id(int id)
359 {
360
361 }
362
363 /*****************************************************************************************/
364 /*****************************************************************************************/
365 /**                                                                                     **/
366 /**                                                                                     **/
367 /**        SECTION: BINDING VERBS IMPLEMENTATION                                        **/
368 /**                                                                                     **/
369 /**                                                                                     **/
370 /*****************************************************************************************/
371 /*****************************************************************************************/
372 /*
373  * Returns the type corresponding to the given name
374  */
375 static enum type type_of_name(const char *name)
376 {
377         enum type result;
378         if (name == NULL)
379                 return type_DEFAULT;
380         for (result = 0 ; result < type_size; result++)
381                 if (strcmp(type_NAMES[result], name) == 0)
382                         return result;
383         return type_INVALID;
384 }
385
386 /*
387  * extract a valid type from the request
388  */
389 static int get_type_for_req(struct afb_req req, enum type *type)
390 {
391         if ((*type = type_of_name(afb_req_value(req, "type"))) != type_INVALID)
392                 return 1;
393         afb_req_fail(req, "unknown-type", NULL);
394         return 0;
395 }
396
397 /*
398  * subscribe to notification of new CAN messages
399  *
400  * parameters of the subscription are:
401  *
402  *    TODO type: string:  choose between CAN and OBDII messages formats.
403  *
404  * returns an object with 2 fields:
405  *
406  *    name:   string:  the name of the event without its prefix
407  *    id:     integer: a numeric identifier of the event to be used for unsubscribing
408  */
409 static void subscribe(struct afb_req req)
410 {
411         enum type type;
412         const char *period;
413         struct event *event;
414         struct json_object *json;
415
416         if (get_type_for_req(req, &type))
417         {
418                 event = event_get(type);
419                 if (event == NULL)
420                         afb_req_fail(req, "out-of-memory", NULL);
421                 else if (afb_req_subscribe(req, event->event) != 0)
422                         afb_req_fail_f(req, "failed", "afb_req_subscribe returned an error: %m");
423                 else
424                 {
425                         json = json_object_new_object();
426                         json_object_object_add(json, "name", json_object_new_string(event->name));
427                         json_object_object_add(json, "id", json_object_new_int(event->id));
428                         afb_req_success(req, json, NULL);
429                 }
430         }
431 }
432
433 /*
434  * unsubscribe a previous subscription
435  *
436  * parameters of the unsubscription are:
437  *
438  *    id:   integer: the numeric identifier of the event as returned when subscribing
439  */
440 static void unsubscribe(struct afb_req req)
441 {
442         const char *id;
443         struct event *event;
444
445         id = afb_req_value(req, "id");
446         if (id == NULL)
447                 afb_req_fail(req, "missing-id", NULL);
448         else
449         {
450                 event = event_of_id(atoi(id));
451                 if (event == NULL)
452                         afb_req_fail(req, "bad-id", NULL);
453                 else
454                 {
455                         afb_req_unsubscribe(req, event->event);
456                         afb_req_success(req, NULL, NULL);
457                 }
458         }
459 }
460
461 static int connect_to_event_loop()
462 {
463         sd_event_source *source;
464         int rc;
465
466         retry(open_can_dev);
467
468         if (can_handler.socket < 0)
469         {
470                 return can_handler.socket;
471         }
472
473         rc = sd_event_add_io(afb_daemon_get_event_loop(interface->daemon), &source, can_handler.socket, EPOLLIN, on_event, NULL);
474         if (rc < 0)
475         {
476                 close(can_handler.socket);
477                 ERROR(interface, "Can't connect CAN bus %s to the event loop", can_handler.device);
478         } else
479         {
480                 NOTICE(interface, "Connected CAN bus %s to the event loop", can_handler.device);
481         }
482
483         return rc;
484 }
485
486
487 // TODO: Have to change session management flag to AFB_SESSION_CHECK to use token auth
488 static const struct afb_verb_desc_v1 verbs[]=
489 {
490   { .name= "subscribe",    .session= AFB_SESSION_NONE, .callback= subscribe,    .info= "subscribe to notification of CAN bus messages." },
491   { .name= "unsubscribe",  .session= AFB_SESSION_NONE, .callback= unsubscribe,  .info= "unsubscribe a previous subscription." },
492         {NULL}
493 };
494
495 static const struct afb_binding binding_desc = {
496         .type = AFB_BINDING_VERSION_1,
497         .v1 = {
498                 .info = "CAN bus service",
499                 .prefix = "can",
500                 .verbs = verbs
501         }
502 };
503
504 const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf)
505 {
506         interface = itf;
507
508         return &binding_desc;
509 }
510
511 int afbBindingV1ServiceInit(struct afb_service service)
512 {
513         return connect_to_event_loop();
514 }