C

Simple C Function Pointer Example

Blog tags: 

Here is a simple function pointer example I wrote for one of my friends just learning to program in C - it should be easy to follow:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef void (*ledFuncPtr) (int[], int);

void myFunctionTest(int pins[], int size)
{

        int i = 0;
        for (i = 0; i <= size; i++) {
                printf("val: %d\n", pins[i]);
        }
}

Simple C fread and fseek to bulk read lines separated with a \n

Blog tags: 

Here is simple file chunker that writes only complete complete records read in from a file to another file. For example, there are JSON records delimited with a '\' character and because they are variable in size, the buffer size WILL not align and therefore needs us to read X bytes, then walk backwards until we find the last complete record.

This requires us to use fseek (fseek(fp,i-tmp_bytes_read,SEEK_CUR);) to re-adjust the filepointer such that the next read will begin at the correct point.

Simple cross array of sizes

Blog tags: 

I recently coded this in less than 30 seconds for a student showing how you can create a simple 2D array to return sizes of structs to be used inside of buffer array function. This should be explanatory by itself... the use - its up to you.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct type1_s {
    int data;
}type1_t;

typedef struct type2_s {
    int data;
    int data2;
}type2_t;

Bluez RFCOMM Gotcha

Blog tags: 

We spent some time looking at RFCOMM sockets in C using libbluetooth (bluez)... and we found this treat:

If you use the same channel for both the src and dest struct sockaddr_rc, or rather both as zero - it will never work. Apparently according to documentation on the internet - 0 - means, pick a free one. It actually doesn't and it will result in:

  • Connection refused
  • Host down
  • Permission denied (rarely)
int rfcomm_socket_for_client(char *src_address, char *dst_address)
{
        int s;
        s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

        // src addressing and binding
        struct sockaddr_rc loc_addr = { 0 };
        loc_addr.rc_family = AF_BLUETOOTH;
        loc_addr.rc_channel = 0;
        str2ba(src_address, &loc_addr.rc_bdaddr);
       
        // set the connection parameters (who to connect to)
        struct sockaddr_rc addr = { 0 };
        addr.rc_family = AF_BLUETOOTH;
        addr.rc_channel = (uint8_t) 1; 
        str2ba(dst_address, &addr.rc_bdaddr);

        // connect to server
        bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
        status = connect(s, (struct sockaddr *)&addr, sizeof(addr));

        if (status == 0) {
                printf("\nConnection established.");
                write(s, "Hello Master!", 6);
                return (0);
        } else {
                printf("\nConnection Failed.");
                close(s);
                return(-1);
        }

        return (0);
}

The other gotcha is PSCAN - you should either write the HCI code to enable it OR just use:

hciconfig hci[x] PSCAN

/**
 * enable_scanmode(char *mac_address, char *opt)
 * @brief Enables scanmode which allows you to actually have a working RFCOMM host
 * @param mac_address
 * @param opt
 * @return 0 for success, -1 for error
 * @note Borrowed some of this from the bluez hciconfig tool
 */
int enable_scanmode(char *mac_address, char *opt)
{

        /* Open HCI socket  */
        int ctl = 0;
        struct hci_dev_req dr = { 0 };
        dr.dev_id = hci_devid(mac_address);
        dr.dev_opt = SCAN_DISABLED;

        if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
                perror("Can't open HCI socket.");
                return (-1);
        }

        if (strcmp(opt, "iscan") == 0) {
                dr.dev_opt = SCAN_INQUIRY;
        } else if (strcmp(opt, "pscan") == 0) {
                dr.dev_opt = SCAN_PAGE;
        } else if (strcmp(opt, "piscan") == 0) {
                dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
        } else if (strcmp(opt, "noscan") == 0) {
                dr.dev_opt = SCAN_DISABLED;
        } else {
                printf("unknown scan option to set\n");
                close(ctl);
                return (-1);
        }

        if (ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0) {
                printf("Can't set scan mode on hci: %s %s-%d\n", mac_address, strerror(errno), errno);
                close(ctl);
                return (-1);
        }
        close(ctl);
        return (0);
}

Pages

Subscribe to RSS - C