*
* return can_event
*/
-static can_event *get_event_of_id(uint32_t id)
+static can_event *get_event_list_of_id(uint32_t id)
{
can_event *current;
* object.
*
* return : json object
- *
- *
*/
static json_object* create_json_from_openxc_CanMessage(event *event)
{
struct json_object *json;
- openxc_CanMessage can_message;
/*
* TODO: process the openxc_CanMessage struct. Should be a call to a
* decoder function relative to that msg
- */
+
+ openxc_CanMessage can_message;
can_message = event->can_message;
+ */
json = json_object_new_object();
json_object_object_add(json, "name", json_object_new_string(event->name));
return rc;
}
+/*
+ * Parse the CAN frame data payload as a CAN packet
+ * TODO: parse as an OpenXC Can Message. Don't translate as ASCII and put bytes
+ * directly into openxc_CanMessage
+ */
+static int parse_can_frame(openxc_CanMessage *can_message, struct canfd_frame *canfd_frame, int maxdlen)
+{
+ int i, len;
+ //size_t n_msg;
+
+ len = (canfd_frame->len > maxdlen) ? maxdlen : canfd_frame->len;
+
+ can_message->has_id = true;
+ if (canfd_frame->can_id & CAN_ERR_FLAG)
+ can_message->id = canfd_frame->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG);
+ else if (canfd_frame->can_id & CAN_EFF_FLAG)
+ {
+ can_message->has_frame_format = true;
+ can_message->frame_format = openxc_CanMessage_FrameFormat_EXTENDED;
+ can_message->id = canfd_frame->can_id & CAN_EFF_MASK;
+ } else
+ {
+ can_message->has_frame_format = true;
+ can_message->frame_format = openxc_CanMessage_FrameFormat_STANDARD;
+ can_message->id = canfd_frame->can_id & CAN_SFF_MASK;
+ }
+
+ /* Don't know what to do with that for now as we haven't
+ * len fields in openxc_CanMessage struct
+
+ * standard CAN frames may have RTR enabled. There are no ERR frames with RTR
+ if (maxdlen == CAN_MAX_DLEN && canfd_frame->can_id & CAN_RTR_FLAG)
+ {
+ // print a given CAN 2.0B DLC if it's not zero
+ if (canfd_frame->len && canfd_frame->len <= CAN_MAX_DLC)
+ buf[offset++] = hex_asc_upper[canfd_frame->len & 0xF];
+
+ buf[offset] = 0;
+ return NULL;
+ }
+ */
+
+ /* Doesn't handle real canfd_frame for now
+ if (maxdlen == CANFD_MAX_DLEN)
+ {
+ // add CAN FD specific escape char and flags
+ canfd_frame->flags & 0xF;
+ } */
+
+ if (sizeof(canfd_frame->data) <= sizeof(can_message->data.bytes))
+ {
+ for (i = 0; i < len; i++)
+ can_message->data.bytes[i] = canfd_frame->data[i];
+ return 0;
+ } else if (sizeof(canfd_frame->data) <= CAN_MAX_DLEN)
+ {
+ ERROR(interface, "parse_can_frame: can_frame data too long to be stored into openxc_CanMessage data field");
+ return -1;
+ /* TODO create as many as needed openxc_CanMessage into an array to store all data from canfd_frame
+ n_msg = CAN_MAX_DLEN / sizeof(canfd_frame->data.bytes);
+ for (i = 0; i < len; i++)
+ can_message->data.bytes[i] = canfd_frame->data[i]; */
+ } else
+ {
+ ERROR(interface, "parse_can_frame: can_frame is really too long here. Size of data greater than canfd maximum 64bytes size. Is it a CAN message ?");
+ return -2;
+ }
+
+ /* You should not reach this return statement */
+ return -3;
+}
+
+
/*
* Read on CAN bus and return how much bytes has been read.
*/
int maxdlen;
/* Test that socket is really opened */
- if ( socket_test < 0)
+ if ( socket_test() < 0)
{
if (retry(open_can_dev) < 0)
{
return -3;
}
- parse_can_frame(can_message, &canfd_frame, maxdlen);
-}
-
-/*
- * Parse the CAN frame data payload as a CAN packet
- * TODO: parse as an OpenXC Can Message. Don't translate as ASCII and put bytes
- * directly into openxc_CanMessage
- */
-static void parse_can_frame(openxc_CanMessage *can_message, struct canfd_frame *canfd_frame, int maxdlen)
-{
- int i,offset;
- int len = (canfd_frame->len > maxdlen) ? maxdlen : canfd_frame->len;
-
- can_message->has_id = true;
- if (canfd_frame->can_id & CAN_ERR_FLAG)
- can_message->id = canfd_frame->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG);
- else if (canfd_frame->can_id & CAN_EFF_FLAG)
+ if (parse_can_frame(can_message, &canfd_frame, maxdlen))
{
- can_message->has_frame_format = true;
- can_message->frame_format = openxc_CanMessage_FrameFormat_EXTENDED;
- can_message->id = canfd_frame->can_id & CAN_EFF_MASK;
- } else
- {
- can_message->has_frame_format = true;
- can_message->frame_format = openxc_CanMessage_FrameFormat_STANDARD;
- can_message->id = canfd_frame->can_id & CAN_SFF_MASK;
- }
-
- /* standard CAN frames may have RTR enabled. There are no ERR frames with RTR */
- if (maxdlen == CAN_MAX_DLEN && canfd_frame->can_id & CAN_RTR_FLAG)
- {
- /* Don't know what to do with that for now as we haven't
- * len fields in openxc_CanMessage struct
- *
- * print a given CAN 2.0B DLC if it's not zero
- if (canfd_frame->len && canfd_frame->len <= CAN_MAX_DLC)
- buf[offset++] = hex_asc_upper[canfd_frame->len & 0xF];
-
- buf[offset] = 0;*/
- return;
+ ERROR(interface, "read_can: Can't parse the can frame. ID: %i, DLC: %i, DATA: %s",
+ canfd_frame.can_id, canfd_frame.len, canfd_frame.data);
+ return -4;
}
- if (maxdlen == CANFD_MAX_DLEN)
- {
- /* add CAN FD specific escape char and flags */
- canfd_frame->flags & 0xF;
- }
-
- for (i = 0; i < len; i++)
- {
- //put_hex_byte(buf + offset, canfd_frame->data[i]);
- //offset += 2;
- }
-
-// buf[offset] = 0;
- return;
+ return 0;
}
-
/*************************************************************************/
/*************************************************************************/
/** **/
/** **/
/*************************************************************************/
/*************************************************************************/
+static int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata);
+
/*
- * called on an event on the CAN bus
+ * Get the event loop running.
+ * Will trigger on_event function on EPOLLIN event on socket
+ *
+ * Return 0 or positive value on success. Else negative value for failure.
*/
-static int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata)
+static int connect_to_event_loop()
{
- openxc_CanMessage can_message;
+ sd_event *event_loop;
+ sd_event_source *source;
+ int rc;
- /* read available data */
- if ((revents & EPOLLIN) != 0)
+ if (can_handler.socket < 0)
{
- read_can(&can_message);
- send_event();
+ return can_handler.socket;
}
- /* check if error or hangup */
- if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0)
+ event_loop = afb_daemon_get_event_loop(interface->daemon);
+ rc = sd_event_add_io(event_loop, &source, can_handler.socket, EPOLLIN, on_event, NULL);
+ if (rc < 0)
{
- sd_event_source_unref(s);
- close(fd);
- connect_to_event_loop();
+ close(can_handler.socket);
+ ERROR(interface, "Can't connect CAN bus %s to the event loop", can_handler.device);
+ } else
+ {
+ NOTICE(interface, "Connected CAN bus %s to the event loop", can_handler.device);
}
- return 0;
-}
-
-/*
- * get or create an event handler for the type
- * TODO: implement function and handle retrieve or create an event as needed
- */
-static event *get_event(uint32_t id, enum type type)
-{
- event *event;
- can_event *list;
-
- /* find the can list by id */
- list = get_event_of_id(id);
-
- /* make the new event */
- event = (can_event*)calloc(1, sizeof(can_event));
- event->next = event;
- list->events = event;
- event->name = create_name(id);
- event->afb_event = afb_daemon_make_event(interface->daemon, event->name);
-
- return event;
+ return rc;
}
-
/*
* Send all events
*/
}
/*
- * Get the event loop running.
- * Will trigger on_event function on EPOLLIN event on socket
- *
- * Return 0 or positive value on success. Else negative value for failure.
+ * called on an event on the CAN bus
*/
-static int connect_to_event_loop()
+static int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata)
{
- sd_event *event_loop;
- sd_event_source *source;
- int rc;
+ openxc_CanMessage can_message;
- if (can_handler.socket < 0)
+ can_message = openxc_CanMessage_init_default;
+
+ /* read available data */
+ if ((revents & EPOLLIN) != 0)
{
- return can_handler.socket;
+ read_can(&can_message);
+ send_event();
}
- event_loop = afb_daemon_get_event_loop(interface->daemon);
- rc = sd_event_add_io(event_loop, &source, can_handler.socket, EPOLLIN, on_event, NULL);
- if (rc < 0)
- {
- close(can_handler.socket);
- ERROR(interface, "Can't connect CAN bus %s to the event loop", can_handler.device);
- } else
+ /* check if error or hangup */
+ if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0)
{
- NOTICE(interface, "Connected CAN bus %s to the event loop", can_handler.device);
+ sd_event_source_unref(s);
+ close(fd);
+ connect_to_event_loop();
}
- return rc;
+ return 0;
+}
+
+/*
+ * get or create an event handler for the type
+ */
+static event *get_event(uint32_t id, enum type type)
+{
+ event *event_elt;
+ can_event *list;
+
+ /* find the can list by id */
+ list = get_event_list_of_id(id);
+
+ /* make the new event */
+ event_elt = (event*)calloc(1, sizeof(event));
+ event_elt->next = event_elt;
+ list->events = event_elt;
+ event_elt->name = create_name(id);
+ event_elt->afb_event = afb_daemon_make_event(interface->daemon, event_elt->name);
+
+ return event_elt;
}
/*************************************************************************/
static void subscribe(struct afb_req req)
{
enum type type;
- const char *period;
event *event;
uint32_t id;
struct json_object *json;
static void unsubscribe(struct afb_req req)
{
const char *id;
+ can_event *events_list;
event *event;
id = afb_req_value(req, "id");
afb_req_fail(req, "missing-id", NULL);
else
{
- event = get_event_of_id(atoi(id));
- if (event == NULL)
- afb_req_fail(req, "bad-id", NULL);
- else
+ events_list = get_event_list_of_id((uint32_t)atoi(id));
+ event = events_list->events;
+ while(event)
{
- afb_req_unsubscribe(req, event->afb_event);
- afb_req_success(req, NULL, NULL);
+ if (event == NULL)
+ afb_req_fail(req, "bad-id", NULL);
+ else
+ {
+ afb_req_unsubscribe(req, event->afb_event);
+ afb_req_success(req, NULL, NULL);
+ }
+ event = event->next;
}
}
}
-// TODO: Have to change session management flag to AFB_SESSION_CHECK to use token auth
static const struct afb_verb_desc_v1 verbs[]=
{
{ .name= "subscribe", .session= AFB_SESSION_NONE, .callback= subscribe, .info= "subscribe to notification of CAN bus messages." },