{"id":13497193,"url":"https://github.com/cjhdev/wic","last_synced_at":"2026-03-11T00:03:00.370Z","repository":{"id":48274331,"uuid":"278076743","full_name":"cjhdev/wic","owner":"cjhdev","description":"WebSockets in C for Embedded Applications","archived":false,"fork":false,"pushed_at":"2023-05-01T13:54:39.000Z","size":135,"stargazers_count":77,"open_issues_count":3,"forks_count":19,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-22T04:45:30.042Z","etag":null,"topics":["embedded","portable","rfc6455","websocket"],"latest_commit_sha":null,"homepage":"https://cjhdev.github.io/wic_api/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cjhdev.png","metadata":{"files":{"readme":"readme.md","changelog":"history.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-08T11:57:24.000Z","updated_at":"2025-07-07T21:19:04.000Z","dependencies_parsed_at":"2024-07-31T23:09:55.328Z","dependency_job_id":null,"html_url":"https://github.com/cjhdev/wic","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/cjhdev/wic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjhdev%2Fwic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjhdev%2Fwic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjhdev%2Fwic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjhdev%2Fwic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cjhdev","download_url":"https://codeload.github.com/cjhdev/wic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjhdev%2Fwic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30362721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"ssl_error","status_checked_at":"2026-03-10T21:40:59.357Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedded","portable","rfc6455","websocket"],"created_at":"2024-07-31T20:00:26.277Z","updated_at":"2026-03-11T00:03:00.350Z","avatar_url":"https://github.com/cjhdev.png","language":"C","readme":"WebSockets in C\n===============\n\nWIC is a C99 implementation of [rfc6455](https://tools.ietf.org/html/rfc6455)\nwebsockets designed for embedded applications.\n\nWIC decouples the websocket protocol from the transport layer. This makes\nit possible to use WIC over any transport layer assuming that you are prepared\nto do the integration work.\n\nWIC is a work in progress. This means that:\n\n- server role is not supported yet\n- handshake implementation is not very robust\n- interfaces may change\n\n## Features\n\n- doesn't call malloc\n- handshake header fields passed through to application\n- convenience functions for dissecting URLs\n- convenience functions for implementing redirection\n- works with any transport layer you like\n- automatic payload fragmentation on receive\n- trivial to integrate with an existing build system\n\n## Limitations\n\n- interfaces are not thread-safe (provide your own solution)\n- handshake headers are only accessible at the moment a websocket\n  becomes connected (i.e. wic_get_state() == WIC_STATE_READY)\n- doesn't support extensions\n- there are a bewildering number of function pointers\n\nThe handshake field limitation is a consequence of storing header\nfields in the same buffer as used for receiving websocket frames. Applications\nthat require header fields to persist beyond WIC_STATE_READY will need\nto copy the fields when they are available.\n\n## Integrations\n\n- [mbed wrapper](port/mbed)\n\n## Compiling\n\n- add `include` to the search path\n- compile sources in `src`\n\nThere are some macros you can define. These listed at the top of [include/wic.h](include/wic.h) and\nin the [API documentation](https://cjhdev.github.io/wic_api/).\n\nThe WIC_PORT_HEADER macro can be used to define a filename which\nwill be included into wic.h. This might be the most\nconvenient place to define/redefine other macros.\n\n## Usage\n\nBelow is an example of a client that:\n\n- connects\n- sends a \"hello world\" text\n- closes normally\n\n~~~ c\n#include \"wic.h\"\n\nint main(int argc, char **argv)\n{\n    int s;\n    static uint8_t rx[1000];\n    struct wic_inst inst;\n    struct wic_init_arg arg = {0};\n\n    arg.rx = rx; arg.rx_max = sizeof(rx);    \n\n    arg.on_send = on_send_handler;    \n    arg.on_open = on_open_handler;        \n    arg.on_message = on_message_handler;        \n    arg.on_close_transport = on_close_transport_handler;        \n    arg.on_buffer = on_buffer_handler;        \n\n    arg.app = \u0026s;\n    arg.url = \"ws://echo.websocket.org/\";\n    arg.role = WIC_ROLE_CLIENT;\n\n    if(!wic_init(\u0026inst, \u0026arg)){\n\n        exit(EXIT_FAILURE);\n    };\n\n    if(transport_open_client(wic_get_url_schema(\u0026inst),\n            wic_get_url_hostname(\u0026inst), wic_get_url_port(\u0026inst), \u0026s)){\n\n        if(wic_start(\u0026inst) == WIC_STATUS_SUCCESS){\n\n            while(transport_recv(s, \u0026inst));\n        }\n        else{\n\n            transport_close(\u0026s);\n        }\n    }\n    \n    exit(EXIT_SUCCESS);\n}\n\nstatic void on_open_handler(struct wic_inst *inst)\n{\n    const char msg[] = \"hello world\";\n\n    wic_send_text(inst, true, msg, strlen(msg));    \n} \n\nstatic void on_close_transport_handler(struct wic_inst *inst)\n{\n    transport_close((int *)wic_get_app(inst));\n}\n\nstatic void on_send_handler(struct wic_inst *inst, const void *data,\n        size_t size, enum wic_frame_type type)\n{\n    transport_write(*(int *)wic_get_app(inst), data, size);\n}\n\nstatic void *on_buffer_handler(struct wic_inst *inst, size_t min_size,\n        enum wic_frame_type type, size_t *max_size)\n{\n    static uint8_t tx[1000U];\n\n    *max_size = sizeof(tx);\n\n    return (min_size \u003c= sizeof(tx)) ? tx : NULL;\n}\n\nstatic bool on_message_handler(struct wic_inst *inst, enum wic_encoding encoding, bool fin, const char *data, uint16_t size)\n{\n    if(encoding == WIC_ENCODING_UTF8){\n\n        printf(\"received text: %.*s\\n\", size, data);\n    }\n\n    wic_close(inst);\n\n    return true;\n}\n~~~\n\n## Acknowledgements\n\nWIC integrates code from the following projects:\n\n- Joyent/Node-JS http-parser\n- Bjoern Hoehrmann's UTF8 parser\n- MBED TLS SHA1 (modified to suit this project)\n\nThe Autobahn Test Suite has been used for verification.\n\n\n\n\n\n","funding_links":[],"categories":["Tools per Language"],"sub_categories":["C"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjhdev%2Fwic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjhdev%2Fwic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjhdev%2Fwic/lists"}