NFC: Export a new attribute nfcid1 in target info
[linux-2.6.git] / net / nfc / netlink.c
1 /*
2  * Copyright (C) 2011 Instituto Nokia de Tecnologia
3  *
4  * Authors:
5  *    Lauro Ramos Venancio <lauro.venancio@openbossa.org>
6  *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the
20  * Free Software Foundation, Inc.,
21  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
25
26 #include <net/genetlink.h>
27 #include <linux/nfc.h>
28 #include <linux/slab.h>
29
30 #include "nfc.h"
31
32 static struct genl_multicast_group nfc_genl_event_mcgrp = {
33         .name = NFC_GENL_MCAST_EVENT_NAME,
34 };
35
36 struct genl_family nfc_genl_family = {
37         .id = GENL_ID_GENERATE,
38         .hdrsize = 0,
39         .name = NFC_GENL_NAME,
40         .version = NFC_GENL_VERSION,
41         .maxattr = NFC_ATTR_MAX,
42 };
43
44 static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
45         [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
46         [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
47                                 .len = NFC_DEVICE_NAME_MAXSIZE },
48         [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
49         [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
50         [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
51 };
52
53 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
54                                         struct netlink_callback *cb, int flags)
55 {
56         void *hdr;
57
58         hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
59                                 &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
60         if (!hdr)
61                 return -EMSGSIZE;
62
63         genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
64
65         NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
66         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS,
67                                 target->supported_protocols);
68         NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
69         NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
70         if (target->nfcid1_len > 0)
71                 NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
72                                 target->nfcid1);
73
74         return genlmsg_end(msg, hdr);
75
76 nla_put_failure:
77         genlmsg_cancel(msg, hdr);
78         return -EMSGSIZE;
79 }
80
81 static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
82 {
83         struct nfc_dev *dev;
84         int rc;
85         u32 idx;
86
87         rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
88                                                 nfc_genl_family.attrbuf,
89                                                 nfc_genl_family.maxattr,
90                                                 nfc_genl_policy);
91         if (rc < 0)
92                 return ERR_PTR(rc);
93
94         if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
95                 return ERR_PTR(-EINVAL);
96
97         idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
98
99         dev = nfc_get_device(idx);
100         if (!dev)
101                 return ERR_PTR(-ENODEV);
102
103         return dev;
104 }
105
106 static int nfc_genl_dump_targets(struct sk_buff *skb,
107                                 struct netlink_callback *cb)
108 {
109         int i = cb->args[0];
110         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
111         int rc;
112
113         if (!dev) {
114                 dev = __get_device_from_cb(cb);
115                 if (IS_ERR(dev))
116                         return PTR_ERR(dev);
117
118                 cb->args[1] = (long) dev;
119         }
120
121         spin_lock_bh(&dev->targets_lock);
122
123         cb->seq = dev->targets_generation;
124
125         while (i < dev->n_targets) {
126                 rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
127                                                                 NLM_F_MULTI);
128                 if (rc < 0)
129                         break;
130
131                 i++;
132         }
133
134         spin_unlock_bh(&dev->targets_lock);
135
136         cb->args[0] = i;
137
138         return skb->len;
139 }
140
141 static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
142 {
143         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
144
145         if (dev)
146                 nfc_put_device(dev);
147
148         return 0;
149 }
150
151 int nfc_genl_targets_found(struct nfc_dev *dev)
152 {
153         struct sk_buff *msg;
154         void *hdr;
155
156         dev->genl_data.poll_req_pid = 0;
157
158         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
159         if (!msg)
160                 return -ENOMEM;
161
162         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
163                                 NFC_EVENT_TARGETS_FOUND);
164         if (!hdr)
165                 goto free_msg;
166
167         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
168
169         genlmsg_end(msg, hdr);
170
171         return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
172
173 nla_put_failure:
174         genlmsg_cancel(msg, hdr);
175 free_msg:
176         nlmsg_free(msg);
177         return -EMSGSIZE;
178 }
179
180 int nfc_genl_device_added(struct nfc_dev *dev)
181 {
182         struct sk_buff *msg;
183         void *hdr;
184
185         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
186         if (!msg)
187                 return -ENOMEM;
188
189         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
190                                 NFC_EVENT_DEVICE_ADDED);
191         if (!hdr)
192                 goto free_msg;
193
194         NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
195         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
196         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
197
198         genlmsg_end(msg, hdr);
199
200         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
201
202         return 0;
203
204 nla_put_failure:
205         genlmsg_cancel(msg, hdr);
206 free_msg:
207         nlmsg_free(msg);
208         return -EMSGSIZE;
209 }
210
211 int nfc_genl_device_removed(struct nfc_dev *dev)
212 {
213         struct sk_buff *msg;
214         void *hdr;
215
216         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
217         if (!msg)
218                 return -ENOMEM;
219
220         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
221                                 NFC_EVENT_DEVICE_REMOVED);
222         if (!hdr)
223                 goto free_msg;
224
225         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
226
227         genlmsg_end(msg, hdr);
228
229         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
230
231         return 0;
232
233 nla_put_failure:
234         genlmsg_cancel(msg, hdr);
235 free_msg:
236         nlmsg_free(msg);
237         return -EMSGSIZE;
238 }
239
240 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
241                                                 u32 pid, u32 seq,
242                                                 struct netlink_callback *cb,
243                                                 int flags)
244 {
245         void *hdr;
246
247         hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
248                                                         NFC_CMD_GET_DEVICE);
249         if (!hdr)
250                 return -EMSGSIZE;
251
252         if (cb)
253                 genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
254
255         NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
256         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
257         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
258
259         return genlmsg_end(msg, hdr);
260
261 nla_put_failure:
262         genlmsg_cancel(msg, hdr);
263         return -EMSGSIZE;
264 }
265
266 static int nfc_genl_dump_devices(struct sk_buff *skb,
267                                 struct netlink_callback *cb)
268 {
269         struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
270         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
271         bool first_call = false;
272
273         if (!iter) {
274                 first_call = true;
275                 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
276                 if (!iter)
277                         return -ENOMEM;
278                 cb->args[0] = (long) iter;
279         }
280
281         mutex_lock(&nfc_devlist_mutex);
282
283         cb->seq = nfc_devlist_generation;
284
285         if (first_call) {
286                 nfc_device_iter_init(iter);
287                 dev = nfc_device_iter_next(iter);
288         }
289
290         while (dev) {
291                 int rc;
292
293                 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
294                                                         cb->nlh->nlmsg_seq,
295                                                         cb, NLM_F_MULTI);
296                 if (rc < 0)
297                         break;
298
299                 dev = nfc_device_iter_next(iter);
300         }
301
302         mutex_unlock(&nfc_devlist_mutex);
303
304         cb->args[1] = (long) dev;
305
306         return skb->len;
307 }
308
309 static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
310 {
311         struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
312
313         nfc_device_iter_exit(iter);
314         kfree(iter);
315
316         return 0;
317 }
318
319 int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
320                                                 u8 comm_mode, u8 rf_mode)
321 {
322         struct sk_buff *msg;
323         void *hdr;
324
325         pr_debug("DEP link is up\n");
326
327         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
328         if (!msg)
329                 return -ENOMEM;
330
331         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
332                                 NFC_CMD_DEP_LINK_UP);
333         if (!hdr)
334                 goto free_msg;
335
336         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
337         if (rf_mode == NFC_RF_INITIATOR)
338                 NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
339         NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode);
340         NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode);
341
342         genlmsg_end(msg, hdr);
343
344         dev->dep_link_up = true;
345
346         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
347
348         return 0;
349
350 nla_put_failure:
351         genlmsg_cancel(msg, hdr);
352 free_msg:
353         nlmsg_free(msg);
354         return -EMSGSIZE;
355 }
356
357 int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
358 {
359         struct sk_buff *msg;
360         void *hdr;
361
362         pr_debug("DEP link is down\n");
363
364         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
365         if (!msg)
366                 return -ENOMEM;
367
368         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
369                                 NFC_CMD_DEP_LINK_DOWN);
370         if (!hdr)
371                 goto free_msg;
372
373         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
374
375         genlmsg_end(msg, hdr);
376
377         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
378
379         return 0;
380
381 nla_put_failure:
382         genlmsg_cancel(msg, hdr);
383 free_msg:
384         nlmsg_free(msg);
385         return -EMSGSIZE;
386 }
387
388 static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
389 {
390         struct sk_buff *msg;
391         struct nfc_dev *dev;
392         u32 idx;
393         int rc = -ENOBUFS;
394
395         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
396                 return -EINVAL;
397
398         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
399
400         dev = nfc_get_device(idx);
401         if (!dev)
402                 return -ENODEV;
403
404         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
405         if (!msg) {
406                 rc = -ENOMEM;
407                 goto out_putdev;
408         }
409
410         rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
411                                                                 NULL, 0);
412         if (rc < 0)
413                 goto out_free;
414
415         nfc_put_device(dev);
416
417         return genlmsg_reply(msg, info);
418
419 out_free:
420         nlmsg_free(msg);
421 out_putdev:
422         nfc_put_device(dev);
423         return rc;
424 }
425
426 static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
427 {
428         struct nfc_dev *dev;
429         int rc;
430         u32 idx;
431
432         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
433                 return -EINVAL;
434
435         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
436
437         dev = nfc_get_device(idx);
438         if (!dev)
439                 return -ENODEV;
440
441         rc = nfc_dev_up(dev);
442
443         nfc_put_device(dev);
444         return rc;
445 }
446
447 static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
448 {
449         struct nfc_dev *dev;
450         int rc;
451         u32 idx;
452
453         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
454                 return -EINVAL;
455
456         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
457
458         dev = nfc_get_device(idx);
459         if (!dev)
460                 return -ENODEV;
461
462         rc = nfc_dev_down(dev);
463
464         nfc_put_device(dev);
465         return rc;
466 }
467
468 static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
469 {
470         struct nfc_dev *dev;
471         int rc;
472         u32 idx;
473         u32 protocols;
474
475         pr_debug("Poll start\n");
476
477         if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
478                 !info->attrs[NFC_ATTR_PROTOCOLS])
479                 return -EINVAL;
480
481         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
482         protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
483
484         dev = nfc_get_device(idx);
485         if (!dev)
486                 return -ENODEV;
487
488         mutex_lock(&dev->genl_data.genl_data_mutex);
489
490         rc = nfc_start_poll(dev, protocols);
491         if (!rc)
492                 dev->genl_data.poll_req_pid = info->snd_pid;
493
494         mutex_unlock(&dev->genl_data.genl_data_mutex);
495
496         nfc_put_device(dev);
497         return rc;
498 }
499
500 static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
501 {
502         struct nfc_dev *dev;
503         int rc;
504         u32 idx;
505
506         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
507                 return -EINVAL;
508
509         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
510
511         dev = nfc_get_device(idx);
512         if (!dev)
513                 return -ENODEV;
514
515         mutex_lock(&dev->genl_data.genl_data_mutex);
516
517         if (dev->genl_data.poll_req_pid != info->snd_pid) {
518                 rc = -EBUSY;
519                 goto out;
520         }
521
522         rc = nfc_stop_poll(dev);
523         dev->genl_data.poll_req_pid = 0;
524
525 out:
526         mutex_unlock(&dev->genl_data.genl_data_mutex);
527         nfc_put_device(dev);
528         return rc;
529 }
530
531 static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
532 {
533         struct nfc_dev *dev;
534         int rc, tgt_idx;
535         u32 idx;
536         u8 comm, rf;
537
538         pr_debug("DEP link up\n");
539
540         if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
541                         !info->attrs[NFC_ATTR_COMM_MODE] ||
542                         !info->attrs[NFC_ATTR_RF_MODE])
543                 return -EINVAL;
544
545         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
546         if (!info->attrs[NFC_ATTR_TARGET_INDEX])
547                 tgt_idx = NFC_TARGET_IDX_ANY;
548         else
549                 tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
550
551         comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
552         rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]);
553
554         if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
555                 return -EINVAL;
556
557         if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET)
558                 return -EINVAL;
559
560         dev = nfc_get_device(idx);
561         if (!dev)
562                 return -ENODEV;
563
564         rc = nfc_dep_link_up(dev, tgt_idx, comm, rf);
565
566         nfc_put_device(dev);
567
568         return rc;
569 }
570
571 static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
572 {
573         struct nfc_dev *dev;
574         int rc;
575         u32 idx;
576
577         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
578                 return -EINVAL;
579
580         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
581
582         dev = nfc_get_device(idx);
583         if (!dev)
584                 return -ENODEV;
585
586         rc = nfc_dep_link_down(dev);
587
588         nfc_put_device(dev);
589         return rc;
590 }
591
592 static struct genl_ops nfc_genl_ops[] = {
593         {
594                 .cmd = NFC_CMD_GET_DEVICE,
595                 .doit = nfc_genl_get_device,
596                 .dumpit = nfc_genl_dump_devices,
597                 .done = nfc_genl_dump_devices_done,
598                 .policy = nfc_genl_policy,
599         },
600         {
601                 .cmd = NFC_CMD_DEV_UP,
602                 .doit = nfc_genl_dev_up,
603                 .policy = nfc_genl_policy,
604         },
605         {
606                 .cmd = NFC_CMD_DEV_DOWN,
607                 .doit = nfc_genl_dev_down,
608                 .policy = nfc_genl_policy,
609         },
610         {
611                 .cmd = NFC_CMD_START_POLL,
612                 .doit = nfc_genl_start_poll,
613                 .policy = nfc_genl_policy,
614         },
615         {
616                 .cmd = NFC_CMD_STOP_POLL,
617                 .doit = nfc_genl_stop_poll,
618                 .policy = nfc_genl_policy,
619         },
620         {
621                 .cmd = NFC_CMD_DEP_LINK_UP,
622                 .doit = nfc_genl_dep_link_up,
623                 .policy = nfc_genl_policy,
624         },
625         {
626                 .cmd = NFC_CMD_DEP_LINK_DOWN,
627                 .doit = nfc_genl_dep_link_down,
628                 .policy = nfc_genl_policy,
629         },
630         {
631                 .cmd = NFC_CMD_GET_TARGET,
632                 .dumpit = nfc_genl_dump_targets,
633                 .done = nfc_genl_dump_targets_done,
634                 .policy = nfc_genl_policy,
635         },
636 };
637
638 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
639                                                 unsigned long event, void *ptr)
640 {
641         struct netlink_notify *n = ptr;
642         struct class_dev_iter iter;
643         struct nfc_dev *dev;
644
645         if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
646                 goto out;
647
648         pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
649
650         nfc_device_iter_init(&iter);
651         dev = nfc_device_iter_next(&iter);
652
653         while (dev) {
654                 if (dev->genl_data.poll_req_pid == n->pid) {
655                         nfc_stop_poll(dev);
656                         dev->genl_data.poll_req_pid = 0;
657                 }
658                 dev = nfc_device_iter_next(&iter);
659         }
660
661         nfc_device_iter_exit(&iter);
662
663 out:
664         return NOTIFY_DONE;
665 }
666
667 void nfc_genl_data_init(struct nfc_genl_data *genl_data)
668 {
669         genl_data->poll_req_pid = 0;
670         mutex_init(&genl_data->genl_data_mutex);
671 }
672
673 void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
674 {
675         mutex_destroy(&genl_data->genl_data_mutex);
676 }
677
678 static struct notifier_block nl_notifier = {
679         .notifier_call  = nfc_genl_rcv_nl_event,
680 };
681
682 /**
683  * nfc_genl_init() - Initialize netlink interface
684  *
685  * This initialization function registers the nfc netlink family.
686  */
687 int __init nfc_genl_init(void)
688 {
689         int rc;
690
691         rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
692                                         ARRAY_SIZE(nfc_genl_ops));
693         if (rc)
694                 return rc;
695
696         rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
697
698         netlink_register_notifier(&nl_notifier);
699
700         return rc;
701 }
702
703 /**
704  * nfc_genl_exit() - Deinitialize netlink interface
705  *
706  * This exit function unregisters the nfc netlink family.
707  */
708 void nfc_genl_exit(void)
709 {
710         netlink_unregister_notifier(&nl_notifier);
711         genl_unregister_family(&nfc_genl_family);
712 }