7 #include <sys/socket.h>
9 #include <netinet/in.h>
12 #include <arpa/inet.h>
24 #include <sys/ioctl.h>
29 /* Navdata constant */
30 #define NAVDATA_SEQUENCE_DEFAULT 1
31 #define NAVDATA_PORT 5554
32 #define NAVDATA_HEADER 0x55667788
33 #define NAVDATA_BUFFER_SIZE 2048
35 typedef enum _navdata_tag_t {
37 NAVDATA_VISION_DETECT_TAG = 16,
38 NAVDATA_IPHONE_ANGLES_TAG = 18,
39 NAVDATA_CKS_TAG = 0xFFFF
42 typedef struct _matrix33_t
55 typedef struct _vector31_t {
67 typedef struct _navdata_option_t {
73 typedef struct _navdata_t {
75 uint32_t mykonos_state;
79 navdata_option_t options[1];
80 } __attribute__ ((packed)) navdata_t;
82 typedef struct _navdata_cks_t {
86 // Checksum for all navdatas (including options)
88 } __attribute__ ((packed)) navdata_cks_t;
90 typedef struct _navdata_demo_t {
94 uint32_t ctrl_state; /*!< instance of #def_mykonos_state_mask_t */
95 uint32_t vbat_flying_percentage; /*!< battery voltage filtered (mV) */
97 float32_t theta; /*!< UAV's attitude */
98 float32_t phi; /*!< UAV's attitude */
99 float32_t psi; /*!< UAV's attitude */
101 int32_t altitude; /*!< UAV's altitude */
103 float32_t vx; /*!< UAV's estimated linear velocity */
104 float32_t vy; /*!< UAV's estimated linear velocity */
105 float32_t vz; /*!< UAV's estimated linear velocity */
107 uint32_t num_frames; /*!< streamed frame index */
109 // Camera parameters compute by detection
110 matrix33_t detection_camera_rot;
111 matrix33_t detection_camera_homo;
112 vector31_t detection_camera_trans;
114 // Camera parameters compute by drone
115 matrix33_t drone_camera_rot;
116 vector31_t drone_camera_trans;
117 } __attribute__ ((packed)) navdata_demo_t;
119 typedef struct _navdata_iphone_angles_t {
128 } __attribute__ ((packed)) navdata_iphone_angles_t;
130 typedef struct _navdata_time_t {
135 } __attribute__ ((packed)) navdata_time_t;
137 typedef struct _navdata_vision_detect_t {
141 uint32_t nb_detected;
148 } __attribute__ ((packed)) navdata_vision_detect_t;
150 typedef struct _navdata_unpacked_t {
151 uint32_t mykonos_state;
154 navdata_demo_t navdata_demo;
155 navdata_iphone_angles_t navdata_iphone_angles;
156 navdata_vision_detect_t navdata_vision_detect;
157 } navdata_unpacked_t;
159 static inline uint8_t* navdata_unpack_option( uint8_t* navdata_ptr, uint8_t* data, uint32_t size )
161 memcpy(data, navdata_ptr, size);
163 return (navdata_ptr + size);
166 static inline navdata_option_t* navdata_next_option( navdata_option_t* navdata_options_ptr )
170 ptr = (uint8_t*) navdata_options_ptr;
171 ptr += navdata_options_ptr->size;
173 return (navdata_option_t*) ptr;
176 navdata_option_t* navdata_search_option( navdata_option_t* navdata_options_ptr, uint32_t tag );
179 static inline uint32_t navdata_compute_cks( uint8_t* nv, int32_t size )
187 for( i = 0; i < size; i++ )
196 #define navdata_unpack( navdata_ptr, option ) (navdata_option_t*) navdata_unpack_option( (uint8_t*) navdata_ptr, \
197 (uint8_t*) &option, \
200 void mykonos_navdata_unpack_all(navdata_unpacked_t* navdata_unpacked, navdata_t* navdata, uint32_t* cks)
202 navdata_cks_t navdata_cks = { 0 };
203 navdata_option_t* navdata_option_ptr;
205 navdata_option_ptr = (navdata_option_t*) &navdata->options[0];
207 memset( navdata_unpacked, 0, sizeof(*navdata_unpacked) );
209 navdata_unpacked->mykonos_state = navdata->mykonos_state;
210 navdata_unpacked->vision_defined = navdata->vision_defined;
212 while( navdata_option_ptr != NULL )
214 // Check if we have a valid option
215 if( navdata_option_ptr->size == 0 )
217 INFO ("One option is not a valid because its size is zero\n");
218 navdata_option_ptr = NULL;
222 switch( navdata_option_ptr->tag )
224 case NAVDATA_DEMO_TAG:
225 //INFO ("Demo tag\n");
226 navdata_option_ptr = navdata_unpack( navdata_option_ptr, navdata_unpacked->navdata_demo );
229 case NAVDATA_IPHONE_ANGLES_TAG:
230 navdata_option_ptr = navdata_unpack( navdata_option_ptr, navdata_unpacked->navdata_iphone_angles );
233 case NAVDATA_VISION_DETECT_TAG:
234 navdata_option_ptr = navdata_unpack( navdata_option_ptr, navdata_unpacked->navdata_vision_detect );
237 case NAVDATA_CKS_TAG:
238 navdata_option_ptr = navdata_unpack( navdata_option_ptr, navdata_cks );
239 *cks = navdata_cks.cks;
240 navdata_option_ptr = NULL; // End of structure
244 INFO ("Tag %d is not a valid navdata option tag\n", (int) navdata_option_ptr->tag);
245 navdata_option_ptr = NULL;
252 static int navdata_udp_socket = -1;
253 void navdata_write (int8_t *buffer, int32_t len)
255 struct sockaddr_in to;
258 if (navdata_udp_socket < 0)
260 /// Open udp socket to broadcast at commands to other mykonos
261 struct sockaddr_in navdata_udp_addr;
263 memset( (char*)&navdata_udp_addr, 0, sizeof(navdata_udp_addr) );
265 navdata_udp_addr.sin_family = AF_INET;
266 navdata_udp_addr.sin_addr.s_addr = INADDR_ANY;
267 navdata_udp_addr.sin_port = htons(NAVDATA_PORT + 100);
269 navdata_udp_socket = socket( AF_INET, SOCK_DGRAM, 0 );
271 if( navdata_udp_socket >= 0 )
273 flags = fcntl(navdata_udp_socket, F_GETFL, 0);
278 flags = fcntl(navdata_udp_socket, F_SETFL, flags );
282 INFO("Get Socket Options failed\n");
285 if (bind(navdata_udp_socket, (struct sockaddr*)&navdata_udp_addr, sizeof(struct sockaddr)) < 0) {
286 INFO ("navdata_write:bind: %s\n", strerror(errno));
290 if( navdata_udp_socket >= 0 ) {
293 memset( (char*)&to, 0, sizeof(to) );
294 to.sin_family = AF_INET;
295 to.sin_addr.s_addr = inet_addr(WIFI_MYKONOS_IP); // BROADCAST address for subnet 192.168.1.xxx
296 to.sin_port = htons( NAVDATA_PORT );
298 res = sendto( navdata_udp_socket, (char*)buffer, len, 0, (struct sockaddr*)&to, sizeof(to) );
302 void navdata_open_server (void)
305 navdata_write ((int8_t*)&one, sizeof( one ));
308 static inline int get_mask_from_state( uint32_t state, uint32_t mask )
310 return state & mask ? TRUE : FALSE;
313 DEFINE_THREAD_ROUTINE( navdata_loop, data )
315 uint8_t msg[NAVDATA_BUFFER_SIZE];
316 navdata_unpacked_t navdata_unpacked;
317 unsigned int cks, navdata_cks, sequence = NAVDATA_SEQUENCE_DEFAULT-1;
318 int sockfd = -1, addr_in_size;
319 struct sockaddr_in *my_addr, *from;
321 INFO("NAVDATA thread starting (thread=%d)...\n", (int)pthread_self());
323 navdata_open_server();
325 addr_in_size = sizeof(struct sockaddr_in);
327 navdata_t* navdata = (navdata_t*) &msg[0];
329 from = (struct sockaddr_in *)malloc(addr_in_size);
330 my_addr = (struct sockaddr_in *)malloc(addr_in_size);
334 memset((char *)my_addr,(char)0,addr_in_size);
335 my_addr->sin_family = AF_INET;
336 my_addr->sin_addr.s_addr = htonl(INADDR_ANY);
337 my_addr->sin_port = htons( NAVDATA_PORT );
339 if((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0){
340 INFO ("socket: %s\n", strerror(errno));
344 if(bind(sockfd, (struct sockaddr *)my_addr, addr_in_size) < 0){
345 INFO ("bind: %s\n", strerror(errno));
354 setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
357 INFO("Ready to receive\n");
361 size = recvfrom (sockfd, &msg[0], NAVDATA_BUFFER_SIZE, 0, (struct sockaddr *)from,
362 (socklen_t *)&addr_in_size);
366 INFO ("Lost connection \n");
367 navdata_open_server();
368 sequence = NAVDATA_SEQUENCE_DEFAULT-1;
370 if( navdata->header == NAVDATA_HEADER )
372 mykonos_state = navdata->mykonos_state;
374 if( get_mask_from_state(navdata->mykonos_state, MYKONOS_COM_WATCHDOG_MASK) )
377 INFO ("[NAVDATA] Detect com watchdog\n");
378 sequence = NAVDATA_SEQUENCE_DEFAULT-1;
380 if( get_mask_from_state(navdata->mykonos_state, MYKONOS_NAVDATA_BOOTSTRAP) == FALSE )
382 const char cmds[] = "AT*COMWDG\r";
383 #warning Ivan: locking missing here ?
384 at_write ((int8_t*)cmds, strlen( cmds ));
388 if( navdata->sequence > sequence )
390 if ( get_mask_from_state( mykonos_state, MYKONOS_NAVDATA_DEMO_MASK ))
392 mykonos_navdata_unpack_all(&navdata_unpacked, navdata, &navdata_cks);
393 cks = navdata_compute_cks( &msg[0], size - sizeof(navdata_cks_t) );
395 if( cks == navdata_cks )
397 //INFO ("Unpack navdata\n");
403 INFO ("[Navdata] Sequence pb : %d (distant) / %d (local)\n", navdata->sequence, sequence);
406 sequence = navdata->sequence;
417 if (navdata_udp_socket >= 0){
418 close(navdata_udp_socket);
419 navdata_udp_socket = -1;
422 INFO("NAVDATA thread stopping\n");